diff --git a/.travis.yml b/.travis.yml index 6c16bdad821f0d..77694bddf3b05e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,3 @@ -x-ccache-setup-steps: &ccache-setup-steps - - export CCACHE_NOSTATS=1 - - export CCACHE_SLOPPINESS="file_macro,include_file_mtime,include_file_ctime,time_macros,file_stat_matches" - - export CC='ccache gcc-6' - - export CXX='ccache g++-6' - os: linux language: cpp env: @@ -13,7 +7,7 @@ env: jobs: include: - stage: "Compile" - name: "Compile V8" + name: "Compile Node.js" cache: ccache addons: apt: @@ -21,25 +15,16 @@ jobs: - ubuntu-toolchain-r-test packages: - g++-6 - install: *ccache-setup-steps - script: - - pyenv global ${PYTHON_VERSION} - - ./configure - - make -j2 -C out V=1 v8 - - - name: "Compile Node.js" - cache: ccache - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-6 - install: *ccache-setup-steps + install: + - export CCACHE_NOSTATS=1 + - export CCACHE_SLOPPINESS="file_macro,include_file_mtime,include_file_ctime,time_macros,file_stat_matches" + - export CC='ccache gcc-6' + - export CXX='ccache g++-6' script: - pyenv global ${PYTHON_VERSION} - ./configure - - make -j2 V=1 + - timeout --preserve-status 45m make -j2 V=1 + before_cache: - cp out/Release/node /home/travis/.ccache - cp out/Release/cctest /home/travis/.ccache diff --git a/BUILDING.md b/BUILDING.md index 0df731b099e5c5..08b75855ea6ee0 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -69,17 +69,14 @@ There are three support tiers: * **Tier 1**: These platforms represent the majority of Node.js users. The Node.js Build Working Group maintains infrastructure for full test coverage. - Maintenance is supported by the Node.js core team. All commits to the - Node.js repository are tested on multiple variants of these platforms. Test + All commits to the Node.js repository are tested on these platforms. Test failures on tier 1 platforms will block releases. * **Tier 2**: These platforms represent smaller segments of the Node.js user base. The Node.js Build Working Group maintains infrastructure for full test - coverage. Maintenance is supported by smaller groups or individuals within - the Node.js core team, or the vendor of the platform itself. All commits to - the Node.js repository are tested on multiple variants of these platforms - where practical. Test failures on tier 2 platforms will block releases. - Delays in release of binaries for these platforms are acceptable - where necessary due to infrastructure concerns. + coverage. All commits to the Node.js repository are tested on these platforms. + Test failures on tier 2 platforms will block releases. Delays in release of + binaries for these platforms are acceptable where necessary due to + infrastructure concerns. * **Experimental**: May not compile or test suite may not pass. The core team does not create releases for these platforms. Test failures on experimental platforms do not block releases. Contributions to improve support for these @@ -371,6 +368,10 @@ loopback interface on Ubuntu: sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0 ``` +You can use +[node-code-ide-configs](https://github.com/nodejs/node-code-ide-configs) +to run/debug tests, if your IDE configs are present. + #### Running Coverage It's good practice to ensure any code you add or change is covered by tests. @@ -475,7 +476,7 @@ To use the debug build with all the normal dependencies overwrite the release version in the install directory: ``` console -$ make install --prefix=/opt/node-debug/ +$ make install PREFIX=/opt/node-debug/ $ cp -a -f out/Debug/node /opt/node-debug/node ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5817827fd274..b5c8f757eb7f80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,8 @@ release. -13.1.0
+13.2.0
+13.1.0
13.0.1
13.0.0
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 0315a2dbb83001..0c5711fe8a85c5 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -172,8 +172,16 @@ the comment anyway to avoid any doubt. All fixes must have a test case which demonstrates the defect. The test should fail before the change, and pass after the change. -All pull requests must pass continuous integration tests on the -[project CI server](https://ci.nodejs.org/). +All pull requests must pass continuous integration tests. Code changes must pass +on [project CI server](https://ci.nodejs.org/). Pull requests that only change +documentation and comments can use Travis CI results. + +Travis CI jobs have a fixed running time limit that building Node.js sometimes +exceeds. If the `Compile Node.js` Travis CI job has timed out it will fail after +around 45 minutes. The exit code will be 143, indicating that a `SIGTERM` signal +terminated the `make` command. When this happens, restart the timed out job. It +will reuse built artifacts from the previous timed-out run, and thus take less +time to complete. Do not land any pull requests without passing (green or yellow) CI runs. If there are CI failures unrelated to the change in the pull request, try "Resume @@ -181,16 +189,18 @@ Build". It is in the left navigation of the relevant `node-test-pull-request` job. It will preserve all the green results from the current job but re-run everything else. +Some of the CI Jobs may require `GIT_REMOTE_REF` which is the remote portion +of Git refspec. To specify the branch this way `refs/heads/BRANCH` is used +(i.e for `master` -> `refs/heads/master`). +For pull requests it will look like `refs/pull/PR_NUMBER/head` +(i.e. for PR#42 -> `refs/pull/42/head`). + #### Useful CI Jobs * [`node-test-pull-request`](https://ci.nodejs.org/job/node-test-pull-request/) is the CI job to test pull requests. It runs the `build-ci` and `test-ci` targets on all supported platforms. -* [`node-test-pull-request-lite-pipeline`](https://ci.nodejs.org/job/node-test-pull-request-lite-pipeline/) -runs the linter job. It also runs the tests on a very fast host. This is useful -for changes that only affect comments or documentation. - * [`citgm-smoker`](https://ci.nodejs.org/job/citgm-smoker/) uses [`CitGM`](https://github.com/nodejs/citgm) to allow you to run `npm install && npm test` on a large selection of common modules. This is diff --git a/GOVERNANCE.md b/GOVERNANCE.md index c8560291164f36..d7cb6e321e16cb 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -15,22 +15,21 @@ ## Collaborators Node.js Core Collaborators maintain the [nodejs/node][] GitHub repository. -The GitHub team for Node.js Core Collaborators is @nodejs/collaborators. Their -privileges include but are not limited to: +The GitHub team for Node.js Core Collaborators is @nodejs/collaborators. +Collaborators have: * Commit access to the [nodejs/node][] repository * Access to the Node.js continuous integration (CI) jobs Both Collaborators and non-Collaborators may propose changes to the Node.js source code. The mechanism to propose such a change is a GitHub pull request. -Collaborators are responsible for reviewing and merging (_landing_) -pull requests. +Collaborators review and merge (_land_) pull requests. -At least two Collaborators must approve a pull request before the pull request -can land. (One Collaborator approval is enough if the pull request has been open -for more than 7 days.) Approving a pull request indicates that the Collaborator -accepts responsibility for the change. Approval must be from Collaborators who -are not authors of the change. +Two Collaborators must approve a pull request before the pull request can land. +(One Collaborator approval is enough if the pull request has been open for more +than 7 days.) Approving a pull request indicates that the Collaborator accepts +responsibility for the change. Approval must be from Collaborators who are not +authors of the change. If a Collaborator opposes a proposed change, then the change cannot land. The exception is if the TSC votes to approve the change despite the opposition. @@ -39,13 +38,11 @@ result in Collaborators removing their opposition. See: -* [Current list of Collaborators](./README.md#current-project-team-members) +* [List of Collaborators](./README.md#current-project-team-members) * [A guide for Collaborators](./COLLABORATOR_GUIDE.md) ### Collaborator Activities -Typical activities of a Collaborator include: - * Helping users and novice contributors * Contributing code and documentation changes that improve the project * Reviewing and commenting on issues and pull requests @@ -71,7 +68,7 @@ The current list of TSC members is in [the project README](./README.md#current-project-team-members). The [TSC Charter][] governs the operations of the TSC. All changes to the -Charter need approval by the Node.js Board of Directors. +Charter need approval by the OpenJS Foundation Board of Directors. ### TSC Meetings @@ -124,7 +121,7 @@ Provide a summary of the nominee's contributions. For example: * Use the link `https://github.com/nodejs/node/issues?q=commenter:GITHUB_ID` * Reviews on pull requests in the [nodejs/node][] repository * Use the link `https://github.com/nodejs/node/pulls?q=reviewed-by:GITHUB_ID` -* Help provided to end users and novice contributors +* Help provided to end-users and novice contributors * Pull requests and issues opened throughout the Node.js organization * Use the link `https://github.com/search?q=author:GITHUB_ID+org:nodejs` * Comments on pull requests and issues throughout the Node.js organization @@ -144,16 +141,15 @@ frictionless as possible. Use the [Collaborators discussion page][] to request feedback from other Collaborators in private. A nominator may also work with the nominee to improve their contribution profile. -It is possible that Collaborators will overlook someone with valuable -contributions. In that case, the contributor may open an issue or contact a -Collaborator to request a nomination. +Collaborators might overlook someone with valuable contributions. In that case, +the contributor may open an issue or contact a Collaborator to request a +nomination. ### Onboarding After the nomination passes, a TSC member onboards the new Collaborator. See -[the onboarding guide](./doc/onboarding.md) on details of the onboarding -process. In general, the onboarding should occur within a month after the -nomination passes. +[the onboarding guide](./doc/onboarding.md) for details of the onboarding +process. ## Consensus Seeking Process diff --git a/Makefile b/Makefile index 8d4e6bbe6474b9..d46b4a0c18a3d6 100644 --- a/Makefile +++ b/Makefile @@ -300,7 +300,7 @@ jstest: build-addons build-js-native-api-tests build-node-api-tests ## Runs addo .PHONY: tooltest tooltest: - @$(PYTHON) test/tools/test-js2c.py + @$(PYTHON) -m unittest discover -s ./test/tools .PHONY: coverage-run-js coverage-run-js: diff --git a/README.md b/README.md index aa5ca6d6595170..e200d25eb133d6 100644 --- a/README.md +++ b/README.md @@ -256,8 +256,6 @@ For information about the governance of the Node.js project, see **Ben Noordhuis** <info@bnoordhuis.nl> * [boneskull](https://github.com/boneskull) - **Christopher Hiller** <boneskull@boneskull.com> (he/him) -* [brendanashworth](https://github.com/brendanashworth) - -**Brendan Ashworth** <brendan.ashworth@me.com> * [BridgeAR](https://github.com/BridgeAR) - **Ruben Bridgewater** <ruben@bridgewater.de> (he/him) * [bzoz](https://github.com/bzoz) - @@ -276,8 +274,6 @@ For information about the governance of the Node.js project, see **Shelley Vohr** <codebytere@gmail.com> (she/her) * [danbev](https://github.com/danbev) - **Daniel Bevenius** <daniel.bevenius@gmail.com> (he/him) -* [DavidCai1993](https://github.com/DavidCai1993) - -**David Cai** <davidcai1993@yahoo.com> (he/him) * [davisjam](https://github.com/davisjam) - **Jamie Davis** <davisjam@vt.edu> (he/him) * [devnexen](https://github.com/devnexen) - @@ -318,8 +314,6 @@ For information about the governance of the Node.js project, see **Yuta Hiroto** <hello@hiroppy.me> (he/him) * [iarna](https://github.com/iarna) - **Rebecca Turner** <me@re-becca.org> -* [imyller](https://github.com/imyller) - -**Ilkka Myller** <ilkka.myller@nodefield.com> * [indutny](https://github.com/indutny) - **Fedor Indutny** <fedor.indutny@gmail.com> * [italoacasas](https://github.com/italoacasas) - @@ -328,8 +322,6 @@ For information about the governance of the Node.js project, see **Jackson Tian** <shyvo1987@gmail.com> * [jasnell](https://github.com/jasnell) - **James M Snell** <jasnell@gmail.com> (he/him) -* [jasongin](https://github.com/jasongin) - -**Jason Ginchereau** <jasongin@microsoft.com> * [jbergstroem](https://github.com/jbergstroem) - **Johan Bergström** <bugs@bergstroem.nu> * [jdalton](https://github.com/jdalton) - @@ -392,8 +384,6 @@ For information about the governance of the Node.js project, see **Richard Lau** <riclau@uk.ibm.com> * [ronkorving](https://github.com/ronkorving) - **Ron Korving** <ron@ronkorving.nl> -* [RReverser](https://github.com/RReverser) - -**Ingvar Stepanyan** <me@rreverser.com> * [rubys](https://github.com/rubys) - **Sam Ruby** <rubys@intertwingly.net> * [rvagg](https://github.com/rvagg) - @@ -461,16 +451,24 @@ For information about the governance of the Node.js project, see **Andras** <andras@kinvey.com> * [AnnaMag](https://github.com/AnnaMag) - **Anna M. Kedzierska** <anna.m.kedzierska@gmail.com> +* [brendanashworth](https://github.com/brendanashworth) - +**Brendan Ashworth** <brendan.ashworth@me.com> * [estliberitas](https://github.com/estliberitas) - **Alexander Makarenko** <estliberitas@gmail.com> * [chrisdickinson](https://github.com/chrisdickinson) - **Chris Dickinson** <christopher.s.dickinson@gmail.com> +* [DavidCai1993](https://github.com/DavidCai1993) - +**David Cai** <davidcai1993@yahoo.com> (he/him) * [firedfox](https://github.com/firedfox) - **Daniel Wang** <wangyang0123@gmail.com> * [imran-iq](https://github.com/imran-iq) - **Imran Iqbal** <imran@imraniqbal.org> +* [imyller](https://github.com/imyller) - +**Ilkka Myller** <ilkka.myller@nodefield.com> * [isaacs](https://github.com/isaacs) - **Isaac Z. Schlueter** <i@izs.me> +* [jasongin](https://github.com/jasongin) - +**Jason Ginchereau** <jasongin@microsoft.com> * [jhamhader](https://github.com/jhamhader) - **Yuval Brik** <yuval@brik.org.il> * [joshgav](https://github.com/joshgav) - @@ -511,6 +509,8 @@ For information about the governance of the Node.js project, see **Robert Kowalski** <rok@kowalski.gd> * [romankl](https://github.com/romankl) - **Roman Klauke** <romaaan.git@gmail.com> +* [RReverser](https://github.com/RReverser) - +**Ingvar Stepanyan** <me@rreverser.com> * [stefanmb](https://github.com/stefanmb) - **Stefan Budeanu** <stefan@budeanu.com> * [tellnes](https://github.com/tellnes) - diff --git a/benchmark/assert/deepequal-buffer.js b/benchmark/assert/deepequal-buffer.js index b8d7529ebc3291..6d9162f15173f9 100644 --- a/benchmark/assert/deepequal-buffer.js +++ b/benchmark/assert/deepequal-buffer.js @@ -27,7 +27,7 @@ function main({ len, n, method, strict }) { const value2 = method.includes('not') ? expectedWrong : expected; bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { fn(actual, value2); } bench.end(n); diff --git a/benchmark/assert/deepequal-map.js b/benchmark/assert/deepequal-map.js index ea1b73cec0e522..b88ecf7ce127f9 100644 --- a/benchmark/assert/deepequal-map.js +++ b/benchmark/assert/deepequal-map.js @@ -24,7 +24,7 @@ function benchmark(method, n, values, values2) { const deepCopy = JSON.parse(JSON.stringify(values2 ? values2 : values)); const expected = new Map(deepCopy); bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { method(actual, expected); } bench.end(n); @@ -32,41 +32,50 @@ function benchmark(method, n, values, values2) { function main({ n, len, method, strict }) { const array = Array(len).fill(1); - var values, values2; switch (method) { case '': // Empty string falls through to next line as default, mostly for tests. - case 'deepEqual_primitiveOnly': - values = array.map((_, i) => [`str_${i}`, 123]); + case 'deepEqual_primitiveOnly': { + const values = array.map((_, i) => [`str_${i}`, 123]); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'deepEqual_objectOnly': - values = array.map((_, i) => [[`str_${i}`, 1], 123]); + } + case 'deepEqual_objectOnly': { + const values = array.map((_, i) => [[`str_${i}`, 1], 123]); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'deepEqual_mixed': - values = array.map((_, i) => [i % 2 ? [`str_${i}`, 1] : `str_${i}`, 123]); + } + case 'deepEqual_mixed': { + const values = array.map( + (_, i) => [i % 2 ? [`str_${i}`, 1] : `str_${i}`, 123] + ); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'notDeepEqual_primitiveOnly': - values = array.map((_, i) => [`str_${i}`, 123]); - values2 = values.slice(0); + } + case 'notDeepEqual_primitiveOnly': { + const values = array.map((_, i) => [`str_${i}`, 123]); + const values2 = values.slice(0); values2[Math.floor(len / 2)] = ['w00t', 123]; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; - case 'notDeepEqual_objectOnly': - values = array.map((_, i) => [[`str_${i}`, 1], 123]); - values2 = values.slice(0); + } + case 'notDeepEqual_objectOnly': { + const values = array.map((_, i) => [[`str_${i}`, 1], 123]); + const values2 = values.slice(0); values2[Math.floor(len / 2)] = [['w00t'], 123]; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; - case 'notDeepEqual_mixed': - values = array.map((_, i) => [i % 2 ? [`str_${i}`, 1] : `str_${i}`, 123]); - values2 = values.slice(0); + } + case 'notDeepEqual_mixed': { + const values = array.map( + (_, i) => [i % 2 ? [`str_${i}`, 1] : `str_${i}`, 123] + ); + const values2 = values.slice(0); values2[0] = ['w00t', 123]; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; + } default: throw new Error(`Unsupported method ${method}`); } diff --git a/benchmark/assert/deepequal-object.js b/benchmark/assert/deepequal-object.js index 240da23d244039..e23f6692b3decd 100644 --- a/benchmark/assert/deepequal-object.js +++ b/benchmark/assert/deepequal-object.js @@ -42,7 +42,7 @@ function main({ size, n, method, strict }) { const value2 = method.includes('not') ? expectedWrong : expected; bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { fn(actual, value2); } bench.end(n); diff --git a/benchmark/assert/deepequal-prims-and-objs-big-array-set.js b/benchmark/assert/deepequal-prims-and-objs-big-array-set.js index 981ec3f0e90fac..0e0ce450bb1a98 100644 --- a/benchmark/assert/deepequal-prims-and-objs-big-array-set.js +++ b/benchmark/assert/deepequal-prims-and-objs-big-array-set.js @@ -26,7 +26,7 @@ const bench = common.createBenchmark(main, { function run(fn, n, actual, expected) { bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { fn(actual, expected); } bench.end(n); @@ -38,7 +38,7 @@ function main({ n, len, primitive, method, strict }) { const expected = []; const expectedWrong = []; - for (var x = 0; x < len; x++) { + for (let x = 0; x < len; x++) { actual.push(prim); expected.push(prim); expectedWrong.push(prim); diff --git a/benchmark/assert/deepequal-prims-and-objs-big-loop.js b/benchmark/assert/deepequal-prims-and-objs-big-loop.js index 00b3c785a4dc71..32140f08ded6fb 100644 --- a/benchmark/assert/deepequal-prims-and-objs-big-loop.js +++ b/benchmark/assert/deepequal-prims-and-objs-big-loop.js @@ -31,7 +31,7 @@ function main({ n, primitive, method, strict }) { const value2 = method.includes('not') ? expectedWrong : expected; bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { fn([actual], [value2]); } bench.end(n); diff --git a/benchmark/assert/deepequal-set.js b/benchmark/assert/deepequal-set.js index b4406b2600f2b1..561a951e6834cc 100644 --- a/benchmark/assert/deepequal-set.js +++ b/benchmark/assert/deepequal-set.js @@ -24,7 +24,7 @@ function benchmark(method, n, values, values2) { const deepCopy = JSON.parse(JSON.stringify(values2 ? values2 : values)); const expected = new Set(deepCopy); bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { method(actual, expected); } bench.end(n); @@ -33,45 +33,49 @@ function benchmark(method, n, values, values2) { function main({ n, len, method, strict }) { const array = Array(len).fill(1); - var values, values2; - switch (method) { case '': // Empty string falls through to next line as default, mostly for tests. - case 'deepEqual_primitiveOnly': - values = array.map((_, i) => `str_${i}`); + case 'deepEqual_primitiveOnly': { + const values = array.map((_, i) => `str_${i}`); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'deepEqual_objectOnly': - values = array.map((_, i) => [`str_${i}`, null]); + } + case 'deepEqual_objectOnly': { + const values = array.map((_, i) => [`str_${i}`, null]); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'deepEqual_mixed': - values = array.map((_, i) => { + } + case 'deepEqual_mixed': { + const values = array.map((_, i) => { return i % 2 ? [`str_${i}`, null] : `str_${i}`; }); benchmark(strict ? deepStrictEqual : deepEqual, n, values); break; - case 'notDeepEqual_primitiveOnly': - values = array.map((_, i) => `str_${i}`); - values2 = values.slice(0); + } + case 'notDeepEqual_primitiveOnly': { + const values = array.map((_, i) => `str_${i}`); + const values2 = values.slice(0); values2[Math.floor(len / 2)] = 'w00t'; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; - case 'notDeepEqual_objectOnly': - values = array.map((_, i) => [`str_${i}`, null]); - values2 = values.slice(0); + } + case 'notDeepEqual_objectOnly': { + const values = array.map((_, i) => [`str_${i}`, null]); + const values2 = values.slice(0); values2[Math.floor(len / 2)] = ['w00t']; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; - case 'notDeepEqual_mixed': - values = array.map((_, i) => { + } + case 'notDeepEqual_mixed': { + const values = array.map((_, i) => { return i % 2 ? [`str_${i}`, null] : `str_${i}`; }); - values2 = values.slice(); + const values2 = values.slice(); values2[0] = 'w00t'; benchmark(strict ? notDeepStrictEqual : notDeepEqual, n, values, values2); break; + } default: throw new Error(`Unsupported method "${method}"`); } diff --git a/benchmark/assert/deepequal-typedarrays.js b/benchmark/assert/deepequal-typedarrays.js index 9acf83711efb0d..10ba21a25759e2 100644 --- a/benchmark/assert/deepequal-typedarrays.js +++ b/benchmark/assert/deepequal-typedarrays.js @@ -36,7 +36,7 @@ function main({ type, n, len, method, strict }) { const value2 = method.includes('not') ? expectedWrong : expected; bench.start(); - for (var i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { actual[0] = i; value2[0] = i; fn(actual, value2); diff --git a/benchmark/assert/ok.js b/benchmark/assert/ok.js index c50c0e069f42cf..42fd2e89b78d1e 100644 --- a/benchmark/assert/ok.js +++ b/benchmark/assert/ok.js @@ -6,9 +6,8 @@ const assert = require('assert'); const bench = common.createBenchmark(main, { n: [1e5] }); function main({ n }) { - var i; bench.start(); - for (i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { if (i % 2 === 0) assert(true); else diff --git a/benchmark/assert/throws.js b/benchmark/assert/throws.js index 3a6326371dc872..c80518377a8742 100644 --- a/benchmark/assert/throws.js +++ b/benchmark/assert/throws.js @@ -13,28 +13,27 @@ function main({ n, method }) { const doNotThrowError = () => { return 'foobar'; }; const regExp = /foobar/; const message = 'failure'; - var i; switch (method) { case '': // Empty string falls through to next line as default, mostly for tests. case 'doesNotThrow': bench.start(); - for (i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { doesNotThrow(doNotThrowError); } bench.end(n); break; case 'throws_TypeError': bench.start(); - for (i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { throws(throwError, TypeError, message); } bench.end(n); break; case 'throws_RegExp': bench.start(); - for (i = 0; i < n; ++i) { + for (let i = 0; i < n; ++i) { throws(throwError, regExp, message); } bench.end(n); diff --git a/benchmark/async_hooks/gc-tracking.js b/benchmark/async_hooks/gc-tracking.js index d74b2bac463e28..030b5f8e1934f8 100644 --- a/benchmark/async_hooks/gc-tracking.js +++ b/benchmark/async_hooks/gc-tracking.js @@ -22,18 +22,17 @@ function endAfterGC(n) { } function main({ n, method }) { - var i; switch (method) { case 'trackingEnabled': bench.start(); - for (i = 0; i < n; i++) { + for (let i = 0; i < n; i++) { new AsyncResource('foobar'); } endAfterGC(n); break; case 'trackingDisabled': bench.start(); - for (i = 0; i < n; i++) { + for (let i = 0; i < n; i++) { new AsyncResource('foobar', { requireManualDestroy: true }); } endAfterGC(n); diff --git a/benchmark/cluster/echo.js b/benchmark/cluster/echo.js index 73c5971cd41eb2..152f2c42f10f2b 100644 --- a/benchmark/cluster/echo.js +++ b/benchmark/cluster/echo.js @@ -7,16 +7,25 @@ if (cluster.isMaster) { workers: [1], payload: ['string', 'object'], sendsPerBroadcast: [1, 10], + serialization: ['json', 'advanced'], n: [1e5] }); - function main({ n, workers, sendsPerBroadcast, payload }) { + function main({ + n, + workers, + sendsPerBroadcast, + payload, + serialization + }) { const expectedPerBroadcast = sendsPerBroadcast * workers; var readies = 0; var broadcasts = 0; var msgCount = 0; var data; + cluster.settings.serialization = serialization; + switch (payload) { case 'string': data = 'hello world!'; diff --git a/common.gypi b/common.gypi index b5df26fd2be34f..2e59636b1718f1 100644 --- a/common.gypi +++ b/common.gypi @@ -39,13 +39,10 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.19', + 'v8_embedder_string': '-node.20', ##### V8 defaults for Node.js ##### - # Old time default, now explicitly stated. - 'v8_use_snapshot': 1, - # Turn on SipHash for hash seed generation, addresses HashWick 'v8_use_siphash': 'true', @@ -76,52 +73,27 @@ # TODO(refack): make v8-perfetto happen 'v8_use_perfetto': 0, + 'v8_enable_pointer_compression': 0, + 'v8_enable_31bit_smis_on_64bit_arch': 0, + ##### end V8 defaults ##### 'conditions': [ ['OS == "win"', { 'os_posix': 0, 'v8_postmortem_support%': 0, + 'obj_dir': '<(PRODUCT_DIR)/obj', + 'v8_base': '<(PRODUCT_DIR)/lib/libv8_snapshot.a', }, { 'os_posix': 1, 'v8_postmortem_support%': 1, }], - ['v8_use_snapshot==1', { - 'conditions': [ - ['GENERATOR == "ninja"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_snapshot.a', - }, { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', - }], - ['OS == "win"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/lib/libv8_snapshot.a', - }], - ['OS == "mac"', { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a', - }], - ], + ['GENERATOR == "ninja"', { + 'obj_dir': '<(PRODUCT_DIR)/obj', + 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_snapshot.a', }, { - 'conditions': [ - ['GENERATOR == "ninja"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/obj/tools/v8_gypfiles/libv8_nosnapshot.a', - }, { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_nosnapshot.a', - }], - ['OS == "win"', { - 'obj_dir': '<(PRODUCT_DIR)/obj', - 'v8_base': '<(PRODUCT_DIR)/lib/libv8_nosnapshot.a', - }], - ['OS == "mac"', { - 'obj_dir%': '<(PRODUCT_DIR)/obj.target', - 'v8_base': '<(PRODUCT_DIR)/libv8_nosnapshot.a', - }], - ], + 'obj_dir%': '<(PRODUCT_DIR)/obj.target', + 'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a', }], ['openssl_fips != ""', { 'openssl_product': '<(STATIC_LIB_PREFIX)crypto<(STATIC_LIB_SUFFIX)', @@ -130,6 +102,8 @@ }], ['OS=="mac"', { 'clang%': 1, + 'obj_dir%': '<(PRODUCT_DIR)/obj.target', + 'v8_base': '<(PRODUCT_DIR)/libv8_snapshot.a', }], ], }, @@ -334,6 +308,12 @@ }], ], }], + ['v8_enable_pointer_compression == 1', { + 'defines': ['V8_COMPRESS_POINTERS'], + }], + ['v8_enable_pointer_compression == 1 or v8_enable_31bit_smis_on_64bit_arch == 1', { + 'defines': ['V8_31BIT_SMIS_ON_64BIT_ARCH'], + }], ['OS == "win"', { 'defines': [ 'WIN32', diff --git a/deps/icu-small/source/data/in/icudt64l.dat.bz2 b/deps/icu-small/source/data/in/icudt64l.dat.bz2 index 5676ffb70f8b9d..962fe59750de58 100644 Binary files a/deps/icu-small/source/data/in/icudt64l.dat.bz2 and b/deps/icu-small/source/data/in/icudt64l.dat.bz2 differ diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt index c27ee99bb7fa46..4e3f5da0f9f00a 100644 --- a/deps/nghttp2/lib/CMakeLists.txt +++ b/deps/nghttp2/lib/CMakeLists.txt @@ -62,7 +62,7 @@ if(HAVE_CUNIT OR ENABLE_STATIC_LIB) set_target_properties(nghttp2_static PROPERTIES COMPILE_FLAGS "${WARNCFLAGS}" VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION} - ARCHIVE_OUTPUT_NAME nghttp2 + ARCHIVE_OUTPUT_NAME nghttp2_static ) target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB") if(ENABLE_STATIC_LIB) diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h index 313fb23daa7449..e3aeb9fed31ecc 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h @@ -4769,6 +4769,19 @@ NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len); */ NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len); +/** + * @function + * + * Returns nonzero if the |value| which is supposed to the value of + * :authority or host header field is valid according to + * https://tools.ietf.org/html/rfc3986#section-3.2 + * + * |value| is valid if it merely consists of the allowed characters. + * In particular, it does not check whether |value| follows the syntax + * of authority. + */ +NGHTTP2_EXTERN int nghttp2_check_authority(const uint8_t *value, size_t len); + /* HPACK API */ struct nghttp2_hd_deflater; diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h index 45bb0c9102cb05..45d21e2645c6cf 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h @@ -29,7 +29,7 @@ * @macro * Version number of the nghttp2 library release */ -#define NGHTTP2_VERSION "1.39.2" +#define NGHTTP2_VERSION "1.40.0" /** * @macro @@ -37,6 +37,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define NGHTTP2_VERSION_NUM 0x012702 +#define NGHTTP2_VERSION_NUM 0x012800 #endif /* NGHTTP2VER_H */ diff --git a/deps/nghttp2/lib/nghttp2_hd.c b/deps/nghttp2/lib/nghttp2_hd.c index 11ca3345f3c6b3..5e869315259921 100644 --- a/deps/nghttp2/lib/nghttp2_hd.c +++ b/deps/nghttp2/lib/nghttp2_hd.c @@ -1694,6 +1694,11 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater, DEBUGF("inflatehd: huffman decoding failed\n"); return readlen; } + if (nghttp2_hd_huff_decode_failure_state(&inflater->huff_decode_ctx)) { + DEBUGF("inflatehd: huffman decoding failed\n"); + return NGHTTP2_ERR_HEADER_COMP; + } + inflater->left -= (size_t)readlen; return readlen; } diff --git a/deps/nghttp2/lib/nghttp2_hd.h b/deps/nghttp2/lib/nghttp2_hd.h index 14ae98078957af..267402881f4258 100644 --- a/deps/nghttp2/lib/nghttp2_hd.h +++ b/deps/nghttp2/lib/nghttp2_hd.h @@ -430,4 +430,10 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, nghttp2_buf *buf, const uint8_t *src, size_t srclen, int fin); +/* + * nghttp2_hd_huff_decode_failure_state returns nonzero if |ctx| + * indicates that huffman decoding context is in failure state. + */ +int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx); + #endif /* NGHTTP2_HD_H */ diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.c b/deps/nghttp2/lib/nghttp2_hd_huffman.c index 8881aacb2e6e90..ac90f49c44f147 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman.c +++ b/deps/nghttp2/lib/nghttp2_hd_huffman.c @@ -29,114 +29,7 @@ #include #include "nghttp2_hd.h" - -/* - * Encodes huffman code |sym| into |*dest_ptr|, whose least |rembits| - * bits are not filled yet. The |rembits| must be in range [1, 8], - * inclusive. At the end of the process, the |*dest_ptr| is updated - * and points where next output should be placed. The number of - * unfilled bits in the pointed location is returned. - */ -static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr, - size_t rembits, const nghttp2_huff_sym *sym) { - int rv; - size_t nbits = sym->nbits; - uint32_t code = sym->code; - - /* We assume that sym->nbits <= 32 */ - if (rembits > nbits) { - nghttp2_bufs_fast_orb_hold(bufs, (uint8_t)(code << (rembits - nbits))); - return (ssize_t)(rembits - nbits); - } - - if (rembits == nbits) { - nghttp2_bufs_fast_orb(bufs, (uint8_t)code); - --*avail_ptr; - return 8; - } - - nghttp2_bufs_fast_orb(bufs, (uint8_t)(code >> (nbits - rembits))); - --*avail_ptr; - - nbits -= rembits; - if (nbits & 0x7) { - /* align code to MSB byte boundary */ - code <<= 8 - (nbits & 0x7); - } - - if (*avail_ptr < (nbits + 7) / 8) { - /* slow path */ - if (nbits > 24) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits > 16) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits > 8) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8)); - if (rv != 0) { - return rv; - } - nbits -= 8; - } - if (nbits == 8) { - rv = nghttp2_bufs_addb(bufs, (uint8_t)code); - if (rv != 0) { - return rv; - } - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return 8; - } - - rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code); - if (rv != 0) { - return rv; - } - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); - } - - /* fast path, since most code is less than 8 */ - if (nbits < 8) { - nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); - } - - /* handle longer code path */ - if (nbits > 24) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 24)); - nbits -= 8; - } - - if (nbits > 16) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 16)); - nbits -= 8; - } - - if (nbits > 8) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)(code >> 8)); - nbits -= 8; - } - - if (nbits == 8) { - nghttp2_bufs_fast_addb(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return 8; - } - - nghttp2_bufs_fast_addb_hold(bufs, (uint8_t)code); - *avail_ptr = nghttp2_bufs_cur_avail(bufs); - return (ssize_t)(8 - nbits); -} +#include "nghttp2_net.h" size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) { size_t i; @@ -151,81 +44,101 @@ size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len) { int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src, size_t srclen) { - int rv; - ssize_t rembits = 8; - size_t i; + const nghttp2_huff_sym *sym; + const uint8_t *end = src + srclen; + uint64_t code = 0; + uint32_t x; + size_t nbits = 0; size_t avail; + int rv; avail = nghttp2_bufs_cur_avail(bufs); - for (i = 0; i < srclen; ++i) { - const nghttp2_huff_sym *sym = &huff_sym_table[src[i]]; - if (rembits == 8) { - if (avail) { - nghttp2_bufs_fast_addb_hold(bufs, 0); - } else { - rv = nghttp2_bufs_addb_hold(bufs, 0); - if (rv != 0) { - return rv; - } - avail = nghttp2_bufs_cur_avail(bufs); + for (; src != end;) { + sym = &huff_sym_table[*src++]; + code |= (uint64_t)sym->code << (32 - nbits); + nbits += sym->nbits; + if (nbits < 32) { + continue; + } + if (avail >= 4) { + x = htonl((uint32_t)(code >> 32)); + memcpy(bufs->cur->buf.last, &x, 4); + bufs->cur->buf.last += 4; + avail -= 4; + code <<= 32; + nbits -= 32; + continue; + } + + for (; nbits >= 8;) { + rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); + if (rv != 0) { + return rv; } + code <<= 8; + nbits -= 8; } - rembits = huff_encode_sym(bufs, &avail, (size_t)rembits, sym); - if (rembits < 0) { - return (int)rembits; + + avail = nghttp2_bufs_cur_avail(bufs); + } + + for (; nbits >= 8;) { + rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 56)); + if (rv != 0) { + return rv; } + code <<= 8; + nbits -= 8; } - /* 256 is special terminal symbol, pad with its prefix */ - if (rembits < 8) { - /* if rembits < 8, we should have at least 1 buffer space - available */ - const nghttp2_huff_sym *sym = &huff_sym_table[256]; - assert(avail); - /* Caution we no longer adjust avail here */ - nghttp2_bufs_fast_orb( - bufs, (uint8_t)(sym->code >> (sym->nbits - (size_t)rembits))); + + if (nbits) { + rv = nghttp2_bufs_addb( + bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1))); + if (rv != 0) { + return rv; + } } return 0; } void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) { - ctx->state = 0; - ctx->accept = 1; + ctx->fstate = NGHTTP2_HUFF_ACCEPTED; } ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx, nghttp2_buf *buf, const uint8_t *src, size_t srclen, int final) { - size_t i; + const uint8_t *end = src + srclen; + nghttp2_huff_decode node = {ctx->fstate, 0}; + const nghttp2_huff_decode *t = &node; + uint8_t c; /* We use the decoding algorithm described in http://graphics.ics.uci.edu/pub/Prefix.pdf */ - for (i = 0; i < srclen; ++i) { - const nghttp2_huff_decode *t; - - t = &huff_decode_table[ctx->state][src[i] >> 4]; - if (t->flags & NGHTTP2_HUFF_FAIL) { - return NGHTTP2_ERR_HEADER_COMP; - } - if (t->flags & NGHTTP2_HUFF_SYM) { + for (; src != end;) { + c = *src++; + t = &huff_decode_table[t->fstate & 0x1ff][c >> 4]; + if (t->fstate & NGHTTP2_HUFF_SYM) { *buf->last++ = t->sym; } - t = &huff_decode_table[t->state][src[i] & 0xf]; - if (t->flags & NGHTTP2_HUFF_FAIL) { - return NGHTTP2_ERR_HEADER_COMP; - } - if (t->flags & NGHTTP2_HUFF_SYM) { + t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf]; + if (t->fstate & NGHTTP2_HUFF_SYM) { *buf->last++ = t->sym; } - - ctx->state = t->state; - ctx->accept = (t->flags & NGHTTP2_HUFF_ACCEPTED) != 0; } - if (final && !ctx->accept) { + + ctx->fstate = t->fstate; + + if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) { return NGHTTP2_ERR_HEADER_COMP; } - return (ssize_t)i; + + return (ssize_t)srclen; +} + +int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) { + return ctx->fstate == 0x100; } diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.h b/deps/nghttp2/lib/nghttp2_hd_huffman.h index c6e3942e95f4fc..2bfd5318165f28 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman.h +++ b/deps/nghttp2/lib/nghttp2_hd_huffman.h @@ -34,21 +34,20 @@ typedef enum { /* FSA accepts this state as the end of huffman encoding sequence. */ - NGHTTP2_HUFF_ACCEPTED = 1, + NGHTTP2_HUFF_ACCEPTED = 1 << 14, /* This state emits symbol */ - NGHTTP2_HUFF_SYM = (1 << 1), - /* If state machine reaches this state, decoding fails. */ - NGHTTP2_HUFF_FAIL = (1 << 2) + NGHTTP2_HUFF_SYM = 1 << 15, } nghttp2_huff_decode_flag; typedef struct { - /* huffman decoding state, which is actually the node ID of internal - huffman tree. We have 257 leaf nodes, but they are identical to - root node other than emitting a symbol, so we have 256 internal - nodes [1..255], inclusive. */ - uint8_t state; - /* bitwise OR of zero or more of the nghttp2_huff_decode_flag */ - uint8_t flags; + /* fstate is the current huffman decoding state, which is actually + the node ID of internal huffman tree with + nghttp2_huff_decode_flag OR-ed. We have 257 leaf nodes, but they + are identical to root node other than emitting a symbol, so we + have 256 internal nodes [1..255], inclusive. The node ID 256 is + a special node and it is a terminal state that means decoding + failed. */ + uint16_t fstate; /* symbol if NGHTTP2_HUFF_SYM flag set */ uint8_t sym; } nghttp2_huff_decode; @@ -56,12 +55,8 @@ typedef struct { typedef nghttp2_huff_decode huff_decode_table_type[16]; typedef struct { - /* Current huffman decoding state. We stripped leaf nodes, so the - value range is [0..255], inclusive. */ - uint8_t state; - /* nonzero if we can say that the decoding process succeeds at this - state */ - uint8_t accept; + /* fstate is the current huffman decoding state. */ + uint16_t fstate; } nghttp2_hd_huff_decode_context; typedef struct { diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman_data.c b/deps/nghttp2/lib/nghttp2_hd_huffman_data.c index 5ef4a956b93891..2e2e13f7bee0ff 100644 --- a/deps/nghttp2/lib/nghttp2_hd_huffman_data.c +++ b/deps/nghttp2/lib/nghttp2_hd_huffman_data.c @@ -27,4935 +27,4954 @@ /* Generated by mkhufftbl.py */ const nghttp2_huff_sym huff_sym_table[] = { - {13, 0x1ff8u}, {23, 0x7fffd8u}, {28, 0xfffffe2u}, {28, 0xfffffe3u}, - {28, 0xfffffe4u}, {28, 0xfffffe5u}, {28, 0xfffffe6u}, {28, 0xfffffe7u}, - {28, 0xfffffe8u}, {24, 0xffffeau}, {30, 0x3ffffffcu}, {28, 0xfffffe9u}, - {28, 0xfffffeau}, {30, 0x3ffffffdu}, {28, 0xfffffebu}, {28, 0xfffffecu}, - {28, 0xfffffedu}, {28, 0xfffffeeu}, {28, 0xfffffefu}, {28, 0xffffff0u}, - {28, 0xffffff1u}, {28, 0xffffff2u}, {30, 0x3ffffffeu}, {28, 0xffffff3u}, - {28, 0xffffff4u}, {28, 0xffffff5u}, {28, 0xffffff6u}, {28, 0xffffff7u}, - {28, 0xffffff8u}, {28, 0xffffff9u}, {28, 0xffffffau}, {28, 0xffffffbu}, - {6, 0x14u}, {10, 0x3f8u}, {10, 0x3f9u}, {12, 0xffau}, - {13, 0x1ff9u}, {6, 0x15u}, {8, 0xf8u}, {11, 0x7fau}, - {10, 0x3fau}, {10, 0x3fbu}, {8, 0xf9u}, {11, 0x7fbu}, - {8, 0xfau}, {6, 0x16u}, {6, 0x17u}, {6, 0x18u}, - {5, 0x0u}, {5, 0x1u}, {5, 0x2u}, {6, 0x19u}, - {6, 0x1au}, {6, 0x1bu}, {6, 0x1cu}, {6, 0x1du}, - {6, 0x1eu}, {6, 0x1fu}, {7, 0x5cu}, {8, 0xfbu}, - {15, 0x7ffcu}, {6, 0x20u}, {12, 0xffbu}, {10, 0x3fcu}, - {13, 0x1ffau}, {6, 0x21u}, {7, 0x5du}, {7, 0x5eu}, - {7, 0x5fu}, {7, 0x60u}, {7, 0x61u}, {7, 0x62u}, - {7, 0x63u}, {7, 0x64u}, {7, 0x65u}, {7, 0x66u}, - {7, 0x67u}, {7, 0x68u}, {7, 0x69u}, {7, 0x6au}, - {7, 0x6bu}, {7, 0x6cu}, {7, 0x6du}, {7, 0x6eu}, - {7, 0x6fu}, {7, 0x70u}, {7, 0x71u}, {7, 0x72u}, - {8, 0xfcu}, {7, 0x73u}, {8, 0xfdu}, {13, 0x1ffbu}, - {19, 0x7fff0u}, {13, 0x1ffcu}, {14, 0x3ffcu}, {6, 0x22u}, - {15, 0x7ffdu}, {5, 0x3u}, {6, 0x23u}, {5, 0x4u}, - {6, 0x24u}, {5, 0x5u}, {6, 0x25u}, {6, 0x26u}, - {6, 0x27u}, {5, 0x6u}, {7, 0x74u}, {7, 0x75u}, - {6, 0x28u}, {6, 0x29u}, {6, 0x2au}, {5, 0x7u}, - {6, 0x2bu}, {7, 0x76u}, {6, 0x2cu}, {5, 0x8u}, - {5, 0x9u}, {6, 0x2du}, {7, 0x77u}, {7, 0x78u}, - {7, 0x79u}, {7, 0x7au}, {7, 0x7bu}, {15, 0x7ffeu}, - {11, 0x7fcu}, {14, 0x3ffdu}, {13, 0x1ffdu}, {28, 0xffffffcu}, - {20, 0xfffe6u}, {22, 0x3fffd2u}, {20, 0xfffe7u}, {20, 0xfffe8u}, - {22, 0x3fffd3u}, {22, 0x3fffd4u}, {22, 0x3fffd5u}, {23, 0x7fffd9u}, - {22, 0x3fffd6u}, {23, 0x7fffdau}, {23, 0x7fffdbu}, {23, 0x7fffdcu}, - {23, 0x7fffddu}, {23, 0x7fffdeu}, {24, 0xffffebu}, {23, 0x7fffdfu}, - {24, 0xffffecu}, {24, 0xffffedu}, {22, 0x3fffd7u}, {23, 0x7fffe0u}, - {24, 0xffffeeu}, {23, 0x7fffe1u}, {23, 0x7fffe2u}, {23, 0x7fffe3u}, - {23, 0x7fffe4u}, {21, 0x1fffdcu}, {22, 0x3fffd8u}, {23, 0x7fffe5u}, - {22, 0x3fffd9u}, {23, 0x7fffe6u}, {23, 0x7fffe7u}, {24, 0xffffefu}, - {22, 0x3fffdau}, {21, 0x1fffddu}, {20, 0xfffe9u}, {22, 0x3fffdbu}, - {22, 0x3fffdcu}, {23, 0x7fffe8u}, {23, 0x7fffe9u}, {21, 0x1fffdeu}, - {23, 0x7fffeau}, {22, 0x3fffddu}, {22, 0x3fffdeu}, {24, 0xfffff0u}, - {21, 0x1fffdfu}, {22, 0x3fffdfu}, {23, 0x7fffebu}, {23, 0x7fffecu}, - {21, 0x1fffe0u}, {21, 0x1fffe1u}, {22, 0x3fffe0u}, {21, 0x1fffe2u}, - {23, 0x7fffedu}, {22, 0x3fffe1u}, {23, 0x7fffeeu}, {23, 0x7fffefu}, - {20, 0xfffeau}, {22, 0x3fffe2u}, {22, 0x3fffe3u}, {22, 0x3fffe4u}, - {23, 0x7ffff0u}, {22, 0x3fffe5u}, {22, 0x3fffe6u}, {23, 0x7ffff1u}, - {26, 0x3ffffe0u}, {26, 0x3ffffe1u}, {20, 0xfffebu}, {19, 0x7fff1u}, - {22, 0x3fffe7u}, {23, 0x7ffff2u}, {22, 0x3fffe8u}, {25, 0x1ffffecu}, - {26, 0x3ffffe2u}, {26, 0x3ffffe3u}, {26, 0x3ffffe4u}, {27, 0x7ffffdeu}, - {27, 0x7ffffdfu}, {26, 0x3ffffe5u}, {24, 0xfffff1u}, {25, 0x1ffffedu}, - {19, 0x7fff2u}, {21, 0x1fffe3u}, {26, 0x3ffffe6u}, {27, 0x7ffffe0u}, - {27, 0x7ffffe1u}, {26, 0x3ffffe7u}, {27, 0x7ffffe2u}, {24, 0xfffff2u}, - {21, 0x1fffe4u}, {21, 0x1fffe5u}, {26, 0x3ffffe8u}, {26, 0x3ffffe9u}, - {28, 0xffffffdu}, {27, 0x7ffffe3u}, {27, 0x7ffffe4u}, {27, 0x7ffffe5u}, - {20, 0xfffecu}, {24, 0xfffff3u}, {20, 0xfffedu}, {21, 0x1fffe6u}, - {22, 0x3fffe9u}, {21, 0x1fffe7u}, {21, 0x1fffe8u}, {23, 0x7ffff3u}, - {22, 0x3fffeau}, {22, 0x3fffebu}, {25, 0x1ffffeeu}, {25, 0x1ffffefu}, - {24, 0xfffff4u}, {24, 0xfffff5u}, {26, 0x3ffffeau}, {23, 0x7ffff4u}, - {26, 0x3ffffebu}, {27, 0x7ffffe6u}, {26, 0x3ffffecu}, {26, 0x3ffffedu}, - {27, 0x7ffffe7u}, {27, 0x7ffffe8u}, {27, 0x7ffffe9u}, {27, 0x7ffffeau}, - {27, 0x7ffffebu}, {28, 0xffffffeu}, {27, 0x7ffffecu}, {27, 0x7ffffedu}, - {27, 0x7ffffeeu}, {27, 0x7ffffefu}, {27, 0x7fffff0u}, {26, 0x3ffffeeu}, - {30, 0x3fffffffu}}; + {13, 0xffc00000u}, {23, 0xffffb000u}, {28, 0xfffffe20u}, {28, 0xfffffe30u}, + {28, 0xfffffe40u}, {28, 0xfffffe50u}, {28, 0xfffffe60u}, {28, 0xfffffe70u}, + {28, 0xfffffe80u}, {24, 0xffffea00u}, {30, 0xfffffff0u}, {28, 0xfffffe90u}, + {28, 0xfffffea0u}, {30, 0xfffffff4u}, {28, 0xfffffeb0u}, {28, 0xfffffec0u}, + {28, 0xfffffed0u}, {28, 0xfffffee0u}, {28, 0xfffffef0u}, {28, 0xffffff00u}, + {28, 0xffffff10u}, {28, 0xffffff20u}, {30, 0xfffffff8u}, {28, 0xffffff30u}, + {28, 0xffffff40u}, {28, 0xffffff50u}, {28, 0xffffff60u}, {28, 0xffffff70u}, + {28, 0xffffff80u}, {28, 0xffffff90u}, {28, 0xffffffa0u}, {28, 0xffffffb0u}, + {6, 0x50000000u}, {10, 0xfe000000u}, {10, 0xfe400000u}, {12, 0xffa00000u}, + {13, 0xffc80000u}, {6, 0x54000000u}, {8, 0xf8000000u}, {11, 0xff400000u}, + {10, 0xfe800000u}, {10, 0xfec00000u}, {8, 0xf9000000u}, {11, 0xff600000u}, + {8, 0xfa000000u}, {6, 0x58000000u}, {6, 0x5c000000u}, {6, 0x60000000u}, + {5, 0x0u}, {5, 0x8000000u}, {5, 0x10000000u}, {6, 0x64000000u}, + {6, 0x68000000u}, {6, 0x6c000000u}, {6, 0x70000000u}, {6, 0x74000000u}, + {6, 0x78000000u}, {6, 0x7c000000u}, {7, 0xb8000000u}, {8, 0xfb000000u}, + {15, 0xfff80000u}, {6, 0x80000000u}, {12, 0xffb00000u}, {10, 0xff000000u}, + {13, 0xffd00000u}, {6, 0x84000000u}, {7, 0xba000000u}, {7, 0xbc000000u}, + {7, 0xbe000000u}, {7, 0xc0000000u}, {7, 0xc2000000u}, {7, 0xc4000000u}, + {7, 0xc6000000u}, {7, 0xc8000000u}, {7, 0xca000000u}, {7, 0xcc000000u}, + {7, 0xce000000u}, {7, 0xd0000000u}, {7, 0xd2000000u}, {7, 0xd4000000u}, + {7, 0xd6000000u}, {7, 0xd8000000u}, {7, 0xda000000u}, {7, 0xdc000000u}, + {7, 0xde000000u}, {7, 0xe0000000u}, {7, 0xe2000000u}, {7, 0xe4000000u}, + {8, 0xfc000000u}, {7, 0xe6000000u}, {8, 0xfd000000u}, {13, 0xffd80000u}, + {19, 0xfffe0000u}, {13, 0xffe00000u}, {14, 0xfff00000u}, {6, 0x88000000u}, + {15, 0xfffa0000u}, {5, 0x18000000u}, {6, 0x8c000000u}, {5, 0x20000000u}, + {6, 0x90000000u}, {5, 0x28000000u}, {6, 0x94000000u}, {6, 0x98000000u}, + {6, 0x9c000000u}, {5, 0x30000000u}, {7, 0xe8000000u}, {7, 0xea000000u}, + {6, 0xa0000000u}, {6, 0xa4000000u}, {6, 0xa8000000u}, {5, 0x38000000u}, + {6, 0xac000000u}, {7, 0xec000000u}, {6, 0xb0000000u}, {5, 0x40000000u}, + {5, 0x48000000u}, {6, 0xb4000000u}, {7, 0xee000000u}, {7, 0xf0000000u}, + {7, 0xf2000000u}, {7, 0xf4000000u}, {7, 0xf6000000u}, {15, 0xfffc0000u}, + {11, 0xff800000u}, {14, 0xfff40000u}, {13, 0xffe80000u}, {28, 0xffffffc0u}, + {20, 0xfffe6000u}, {22, 0xffff4800u}, {20, 0xfffe7000u}, {20, 0xfffe8000u}, + {22, 0xffff4c00u}, {22, 0xffff5000u}, {22, 0xffff5400u}, {23, 0xffffb200u}, + {22, 0xffff5800u}, {23, 0xffffb400u}, {23, 0xffffb600u}, {23, 0xffffb800u}, + {23, 0xffffba00u}, {23, 0xffffbc00u}, {24, 0xffffeb00u}, {23, 0xffffbe00u}, + {24, 0xffffec00u}, {24, 0xffffed00u}, {22, 0xffff5c00u}, {23, 0xffffc000u}, + {24, 0xffffee00u}, {23, 0xffffc200u}, {23, 0xffffc400u}, {23, 0xffffc600u}, + {23, 0xffffc800u}, {21, 0xfffee000u}, {22, 0xffff6000u}, {23, 0xffffca00u}, + {22, 0xffff6400u}, {23, 0xffffcc00u}, {23, 0xffffce00u}, {24, 0xffffef00u}, + {22, 0xffff6800u}, {21, 0xfffee800u}, {20, 0xfffe9000u}, {22, 0xffff6c00u}, + {22, 0xffff7000u}, {23, 0xffffd000u}, {23, 0xffffd200u}, {21, 0xfffef000u}, + {23, 0xffffd400u}, {22, 0xffff7400u}, {22, 0xffff7800u}, {24, 0xfffff000u}, + {21, 0xfffef800u}, {22, 0xffff7c00u}, {23, 0xffffd600u}, {23, 0xffffd800u}, + {21, 0xffff0000u}, {21, 0xffff0800u}, {22, 0xffff8000u}, {21, 0xffff1000u}, + {23, 0xffffda00u}, {22, 0xffff8400u}, {23, 0xffffdc00u}, {23, 0xffffde00u}, + {20, 0xfffea000u}, {22, 0xffff8800u}, {22, 0xffff8c00u}, {22, 0xffff9000u}, + {23, 0xffffe000u}, {22, 0xffff9400u}, {22, 0xffff9800u}, {23, 0xffffe200u}, + {26, 0xfffff800u}, {26, 0xfffff840u}, {20, 0xfffeb000u}, {19, 0xfffe2000u}, + {22, 0xffff9c00u}, {23, 0xffffe400u}, {22, 0xffffa000u}, {25, 0xfffff600u}, + {26, 0xfffff880u}, {26, 0xfffff8c0u}, {26, 0xfffff900u}, {27, 0xfffffbc0u}, + {27, 0xfffffbe0u}, {26, 0xfffff940u}, {24, 0xfffff100u}, {25, 0xfffff680u}, + {19, 0xfffe4000u}, {21, 0xffff1800u}, {26, 0xfffff980u}, {27, 0xfffffc00u}, + {27, 0xfffffc20u}, {26, 0xfffff9c0u}, {27, 0xfffffc40u}, {24, 0xfffff200u}, + {21, 0xffff2000u}, {21, 0xffff2800u}, {26, 0xfffffa00u}, {26, 0xfffffa40u}, + {28, 0xffffffd0u}, {27, 0xfffffc60u}, {27, 0xfffffc80u}, {27, 0xfffffca0u}, + {20, 0xfffec000u}, {24, 0xfffff300u}, {20, 0xfffed000u}, {21, 0xffff3000u}, + {22, 0xffffa400u}, {21, 0xffff3800u}, {21, 0xffff4000u}, {23, 0xffffe600u}, + {22, 0xffffa800u}, {22, 0xffffac00u}, {25, 0xfffff700u}, {25, 0xfffff780u}, + {24, 0xfffff400u}, {24, 0xfffff500u}, {26, 0xfffffa80u}, {23, 0xffffe800u}, + {26, 0xfffffac0u}, {27, 0xfffffcc0u}, {26, 0xfffffb00u}, {26, 0xfffffb40u}, + {27, 0xfffffce0u}, {27, 0xfffffd00u}, {27, 0xfffffd20u}, {27, 0xfffffd40u}, + {27, 0xfffffd60u}, {28, 0xffffffe0u}, {27, 0xfffffd80u}, {27, 0xfffffda0u}, + {27, 0xfffffdc0u}, {27, 0xfffffde0u}, {27, 0xfffffe00u}, {26, 0xfffffb80u}, + {30, 0xfffffffcu}}; const nghttp2_huff_decode huff_decode_table[][16] = { /* 0 */ { - {4, 0x00, 0}, - {5, 0x00, 0}, - {7, 0x00, 0}, - {8, 0x00, 0}, - {11, 0x00, 0}, - {12, 0x00, 0}, - {16, 0x00, 0}, - {19, 0x00, 0}, - {25, 0x00, 0}, - {28, 0x00, 0}, - {32, 0x00, 0}, - {35, 0x00, 0}, - {42, 0x00, 0}, - {49, 0x00, 0}, - {57, 0x00, 0}, - {64, 0x01, 0}, + {0x04, 0}, + {0x05, 0}, + {0x07, 0}, + {0x08, 0}, + {0x0b, 0}, + {0x0c, 0}, + {0x10, 0}, + {0x13, 0}, + {0x19, 0}, + {0x1c, 0}, + {0x20, 0}, + {0x23, 0}, + {0x2a, 0}, + {0x31, 0}, + {0x39, 0}, + {0x4040, 0}, }, /* 1 */ { - {0, 0x03, 48}, - {0, 0x03, 49}, - {0, 0x03, 50}, - {0, 0x03, 97}, - {0, 0x03, 99}, - {0, 0x03, 101}, - {0, 0x03, 105}, - {0, 0x03, 111}, - {0, 0x03, 115}, - {0, 0x03, 116}, - {13, 0x00, 0}, - {14, 0x00, 0}, - {17, 0x00, 0}, - {18, 0x00, 0}, - {20, 0x00, 0}, - {21, 0x00, 0}, + {0xc000, 48}, + {0xc000, 49}, + {0xc000, 50}, + {0xc000, 97}, + {0xc000, 99}, + {0xc000, 101}, + {0xc000, 105}, + {0xc000, 111}, + {0xc000, 115}, + {0xc000, 116}, + {0x0d, 0}, + {0x0e, 0}, + {0x11, 0}, + {0x12, 0}, + {0x14, 0}, + {0x15, 0}, }, /* 2 */ { - {1, 0x02, 48}, - {22, 0x03, 48}, - {1, 0x02, 49}, - {22, 0x03, 49}, - {1, 0x02, 50}, - {22, 0x03, 50}, - {1, 0x02, 97}, - {22, 0x03, 97}, - {1, 0x02, 99}, - {22, 0x03, 99}, - {1, 0x02, 101}, - {22, 0x03, 101}, - {1, 0x02, 105}, - {22, 0x03, 105}, - {1, 0x02, 111}, - {22, 0x03, 111}, + {0x8001, 48}, + {0xc016, 48}, + {0x8001, 49}, + {0xc016, 49}, + {0x8001, 50}, + {0xc016, 50}, + {0x8001, 97}, + {0xc016, 97}, + {0x8001, 99}, + {0xc016, 99}, + {0x8001, 101}, + {0xc016, 101}, + {0x8001, 105}, + {0xc016, 105}, + {0x8001, 111}, + {0xc016, 111}, }, /* 3 */ { - {2, 0x02, 48}, - {9, 0x02, 48}, - {23, 0x02, 48}, - {40, 0x03, 48}, - {2, 0x02, 49}, - {9, 0x02, 49}, - {23, 0x02, 49}, - {40, 0x03, 49}, - {2, 0x02, 50}, - {9, 0x02, 50}, - {23, 0x02, 50}, - {40, 0x03, 50}, - {2, 0x02, 97}, - {9, 0x02, 97}, - {23, 0x02, 97}, - {40, 0x03, 97}, + {0x8002, 48}, + {0x8009, 48}, + {0x8017, 48}, + {0xc028, 48}, + {0x8002, 49}, + {0x8009, 49}, + {0x8017, 49}, + {0xc028, 49}, + {0x8002, 50}, + {0x8009, 50}, + {0x8017, 50}, + {0xc028, 50}, + {0x8002, 97}, + {0x8009, 97}, + {0x8017, 97}, + {0xc028, 97}, }, /* 4 */ { - {3, 0x02, 48}, - {6, 0x02, 48}, - {10, 0x02, 48}, - {15, 0x02, 48}, - {24, 0x02, 48}, - {31, 0x02, 48}, - {41, 0x02, 48}, - {56, 0x03, 48}, - {3, 0x02, 49}, - {6, 0x02, 49}, - {10, 0x02, 49}, - {15, 0x02, 49}, - {24, 0x02, 49}, - {31, 0x02, 49}, - {41, 0x02, 49}, - {56, 0x03, 49}, + {0x8003, 48}, + {0x8006, 48}, + {0x800a, 48}, + {0x800f, 48}, + {0x8018, 48}, + {0x801f, 48}, + {0x8029, 48}, + {0xc038, 48}, + {0x8003, 49}, + {0x8006, 49}, + {0x800a, 49}, + {0x800f, 49}, + {0x8018, 49}, + {0x801f, 49}, + {0x8029, 49}, + {0xc038, 49}, }, /* 5 */ { - {3, 0x02, 50}, - {6, 0x02, 50}, - {10, 0x02, 50}, - {15, 0x02, 50}, - {24, 0x02, 50}, - {31, 0x02, 50}, - {41, 0x02, 50}, - {56, 0x03, 50}, - {3, 0x02, 97}, - {6, 0x02, 97}, - {10, 0x02, 97}, - {15, 0x02, 97}, - {24, 0x02, 97}, - {31, 0x02, 97}, - {41, 0x02, 97}, - {56, 0x03, 97}, + {0x8003, 50}, + {0x8006, 50}, + {0x800a, 50}, + {0x800f, 50}, + {0x8018, 50}, + {0x801f, 50}, + {0x8029, 50}, + {0xc038, 50}, + {0x8003, 97}, + {0x8006, 97}, + {0x800a, 97}, + {0x800f, 97}, + {0x8018, 97}, + {0x801f, 97}, + {0x8029, 97}, + {0xc038, 97}, }, /* 6 */ { - {2, 0x02, 99}, - {9, 0x02, 99}, - {23, 0x02, 99}, - {40, 0x03, 99}, - {2, 0x02, 101}, - {9, 0x02, 101}, - {23, 0x02, 101}, - {40, 0x03, 101}, - {2, 0x02, 105}, - {9, 0x02, 105}, - {23, 0x02, 105}, - {40, 0x03, 105}, - {2, 0x02, 111}, - {9, 0x02, 111}, - {23, 0x02, 111}, - {40, 0x03, 111}, + {0x8002, 99}, + {0x8009, 99}, + {0x8017, 99}, + {0xc028, 99}, + {0x8002, 101}, + {0x8009, 101}, + {0x8017, 101}, + {0xc028, 101}, + {0x8002, 105}, + {0x8009, 105}, + {0x8017, 105}, + {0xc028, 105}, + {0x8002, 111}, + {0x8009, 111}, + {0x8017, 111}, + {0xc028, 111}, }, /* 7 */ { - {3, 0x02, 99}, - {6, 0x02, 99}, - {10, 0x02, 99}, - {15, 0x02, 99}, - {24, 0x02, 99}, - {31, 0x02, 99}, - {41, 0x02, 99}, - {56, 0x03, 99}, - {3, 0x02, 101}, - {6, 0x02, 101}, - {10, 0x02, 101}, - {15, 0x02, 101}, - {24, 0x02, 101}, - {31, 0x02, 101}, - {41, 0x02, 101}, - {56, 0x03, 101}, + {0x8003, 99}, + {0x8006, 99}, + {0x800a, 99}, + {0x800f, 99}, + {0x8018, 99}, + {0x801f, 99}, + {0x8029, 99}, + {0xc038, 99}, + {0x8003, 101}, + {0x8006, 101}, + {0x800a, 101}, + {0x800f, 101}, + {0x8018, 101}, + {0x801f, 101}, + {0x8029, 101}, + {0xc038, 101}, }, /* 8 */ { - {3, 0x02, 105}, - {6, 0x02, 105}, - {10, 0x02, 105}, - {15, 0x02, 105}, - {24, 0x02, 105}, - {31, 0x02, 105}, - {41, 0x02, 105}, - {56, 0x03, 105}, - {3, 0x02, 111}, - {6, 0x02, 111}, - {10, 0x02, 111}, - {15, 0x02, 111}, - {24, 0x02, 111}, - {31, 0x02, 111}, - {41, 0x02, 111}, - {56, 0x03, 111}, + {0x8003, 105}, + {0x8006, 105}, + {0x800a, 105}, + {0x800f, 105}, + {0x8018, 105}, + {0x801f, 105}, + {0x8029, 105}, + {0xc038, 105}, + {0x8003, 111}, + {0x8006, 111}, + {0x800a, 111}, + {0x800f, 111}, + {0x8018, 111}, + {0x801f, 111}, + {0x8029, 111}, + {0xc038, 111}, }, /* 9 */ { - {1, 0x02, 115}, - {22, 0x03, 115}, - {1, 0x02, 116}, - {22, 0x03, 116}, - {0, 0x03, 32}, - {0, 0x03, 37}, - {0, 0x03, 45}, - {0, 0x03, 46}, - {0, 0x03, 47}, - {0, 0x03, 51}, - {0, 0x03, 52}, - {0, 0x03, 53}, - {0, 0x03, 54}, - {0, 0x03, 55}, - {0, 0x03, 56}, - {0, 0x03, 57}, + {0x8001, 115}, + {0xc016, 115}, + {0x8001, 116}, + {0xc016, 116}, + {0xc000, 32}, + {0xc000, 37}, + {0xc000, 45}, + {0xc000, 46}, + {0xc000, 47}, + {0xc000, 51}, + {0xc000, 52}, + {0xc000, 53}, + {0xc000, 54}, + {0xc000, 55}, + {0xc000, 56}, + {0xc000, 57}, }, /* 10 */ { - {2, 0x02, 115}, - {9, 0x02, 115}, - {23, 0x02, 115}, - {40, 0x03, 115}, - {2, 0x02, 116}, - {9, 0x02, 116}, - {23, 0x02, 116}, - {40, 0x03, 116}, - {1, 0x02, 32}, - {22, 0x03, 32}, - {1, 0x02, 37}, - {22, 0x03, 37}, - {1, 0x02, 45}, - {22, 0x03, 45}, - {1, 0x02, 46}, - {22, 0x03, 46}, + {0x8002, 115}, + {0x8009, 115}, + {0x8017, 115}, + {0xc028, 115}, + {0x8002, 116}, + {0x8009, 116}, + {0x8017, 116}, + {0xc028, 116}, + {0x8001, 32}, + {0xc016, 32}, + {0x8001, 37}, + {0xc016, 37}, + {0x8001, 45}, + {0xc016, 45}, + {0x8001, 46}, + {0xc016, 46}, }, /* 11 */ { - {3, 0x02, 115}, - {6, 0x02, 115}, - {10, 0x02, 115}, - {15, 0x02, 115}, - {24, 0x02, 115}, - {31, 0x02, 115}, - {41, 0x02, 115}, - {56, 0x03, 115}, - {3, 0x02, 116}, - {6, 0x02, 116}, - {10, 0x02, 116}, - {15, 0x02, 116}, - {24, 0x02, 116}, - {31, 0x02, 116}, - {41, 0x02, 116}, - {56, 0x03, 116}, + {0x8003, 115}, + {0x8006, 115}, + {0x800a, 115}, + {0x800f, 115}, + {0x8018, 115}, + {0x801f, 115}, + {0x8029, 115}, + {0xc038, 115}, + {0x8003, 116}, + {0x8006, 116}, + {0x800a, 116}, + {0x800f, 116}, + {0x8018, 116}, + {0x801f, 116}, + {0x8029, 116}, + {0xc038, 116}, }, /* 12 */ { - {2, 0x02, 32}, - {9, 0x02, 32}, - {23, 0x02, 32}, - {40, 0x03, 32}, - {2, 0x02, 37}, - {9, 0x02, 37}, - {23, 0x02, 37}, - {40, 0x03, 37}, - {2, 0x02, 45}, - {9, 0x02, 45}, - {23, 0x02, 45}, - {40, 0x03, 45}, - {2, 0x02, 46}, - {9, 0x02, 46}, - {23, 0x02, 46}, - {40, 0x03, 46}, + {0x8002, 32}, + {0x8009, 32}, + {0x8017, 32}, + {0xc028, 32}, + {0x8002, 37}, + {0x8009, 37}, + {0x8017, 37}, + {0xc028, 37}, + {0x8002, 45}, + {0x8009, 45}, + {0x8017, 45}, + {0xc028, 45}, + {0x8002, 46}, + {0x8009, 46}, + {0x8017, 46}, + {0xc028, 46}, }, /* 13 */ { - {3, 0x02, 32}, - {6, 0x02, 32}, - {10, 0x02, 32}, - {15, 0x02, 32}, - {24, 0x02, 32}, - {31, 0x02, 32}, - {41, 0x02, 32}, - {56, 0x03, 32}, - {3, 0x02, 37}, - {6, 0x02, 37}, - {10, 0x02, 37}, - {15, 0x02, 37}, - {24, 0x02, 37}, - {31, 0x02, 37}, - {41, 0x02, 37}, - {56, 0x03, 37}, + {0x8003, 32}, + {0x8006, 32}, + {0x800a, 32}, + {0x800f, 32}, + {0x8018, 32}, + {0x801f, 32}, + {0x8029, 32}, + {0xc038, 32}, + {0x8003, 37}, + {0x8006, 37}, + {0x800a, 37}, + {0x800f, 37}, + {0x8018, 37}, + {0x801f, 37}, + {0x8029, 37}, + {0xc038, 37}, }, /* 14 */ { - {3, 0x02, 45}, - {6, 0x02, 45}, - {10, 0x02, 45}, - {15, 0x02, 45}, - {24, 0x02, 45}, - {31, 0x02, 45}, - {41, 0x02, 45}, - {56, 0x03, 45}, - {3, 0x02, 46}, - {6, 0x02, 46}, - {10, 0x02, 46}, - {15, 0x02, 46}, - {24, 0x02, 46}, - {31, 0x02, 46}, - {41, 0x02, 46}, - {56, 0x03, 46}, + {0x8003, 45}, + {0x8006, 45}, + {0x800a, 45}, + {0x800f, 45}, + {0x8018, 45}, + {0x801f, 45}, + {0x8029, 45}, + {0xc038, 45}, + {0x8003, 46}, + {0x8006, 46}, + {0x800a, 46}, + {0x800f, 46}, + {0x8018, 46}, + {0x801f, 46}, + {0x8029, 46}, + {0xc038, 46}, }, /* 15 */ { - {1, 0x02, 47}, - {22, 0x03, 47}, - {1, 0x02, 51}, - {22, 0x03, 51}, - {1, 0x02, 52}, - {22, 0x03, 52}, - {1, 0x02, 53}, - {22, 0x03, 53}, - {1, 0x02, 54}, - {22, 0x03, 54}, - {1, 0x02, 55}, - {22, 0x03, 55}, - {1, 0x02, 56}, - {22, 0x03, 56}, - {1, 0x02, 57}, - {22, 0x03, 57}, + {0x8001, 47}, + {0xc016, 47}, + {0x8001, 51}, + {0xc016, 51}, + {0x8001, 52}, + {0xc016, 52}, + {0x8001, 53}, + {0xc016, 53}, + {0x8001, 54}, + {0xc016, 54}, + {0x8001, 55}, + {0xc016, 55}, + {0x8001, 56}, + {0xc016, 56}, + {0x8001, 57}, + {0xc016, 57}, }, /* 16 */ { - {2, 0x02, 47}, - {9, 0x02, 47}, - {23, 0x02, 47}, - {40, 0x03, 47}, - {2, 0x02, 51}, - {9, 0x02, 51}, - {23, 0x02, 51}, - {40, 0x03, 51}, - {2, 0x02, 52}, - {9, 0x02, 52}, - {23, 0x02, 52}, - {40, 0x03, 52}, - {2, 0x02, 53}, - {9, 0x02, 53}, - {23, 0x02, 53}, - {40, 0x03, 53}, + {0x8002, 47}, + {0x8009, 47}, + {0x8017, 47}, + {0xc028, 47}, + {0x8002, 51}, + {0x8009, 51}, + {0x8017, 51}, + {0xc028, 51}, + {0x8002, 52}, + {0x8009, 52}, + {0x8017, 52}, + {0xc028, 52}, + {0x8002, 53}, + {0x8009, 53}, + {0x8017, 53}, + {0xc028, 53}, }, /* 17 */ { - {3, 0x02, 47}, - {6, 0x02, 47}, - {10, 0x02, 47}, - {15, 0x02, 47}, - {24, 0x02, 47}, - {31, 0x02, 47}, - {41, 0x02, 47}, - {56, 0x03, 47}, - {3, 0x02, 51}, - {6, 0x02, 51}, - {10, 0x02, 51}, - {15, 0x02, 51}, - {24, 0x02, 51}, - {31, 0x02, 51}, - {41, 0x02, 51}, - {56, 0x03, 51}, + {0x8003, 47}, + {0x8006, 47}, + {0x800a, 47}, + {0x800f, 47}, + {0x8018, 47}, + {0x801f, 47}, + {0x8029, 47}, + {0xc038, 47}, + {0x8003, 51}, + {0x8006, 51}, + {0x800a, 51}, + {0x800f, 51}, + {0x8018, 51}, + {0x801f, 51}, + {0x8029, 51}, + {0xc038, 51}, }, /* 18 */ { - {3, 0x02, 52}, - {6, 0x02, 52}, - {10, 0x02, 52}, - {15, 0x02, 52}, - {24, 0x02, 52}, - {31, 0x02, 52}, - {41, 0x02, 52}, - {56, 0x03, 52}, - {3, 0x02, 53}, - {6, 0x02, 53}, - {10, 0x02, 53}, - {15, 0x02, 53}, - {24, 0x02, 53}, - {31, 0x02, 53}, - {41, 0x02, 53}, - {56, 0x03, 53}, + {0x8003, 52}, + {0x8006, 52}, + {0x800a, 52}, + {0x800f, 52}, + {0x8018, 52}, + {0x801f, 52}, + {0x8029, 52}, + {0xc038, 52}, + {0x8003, 53}, + {0x8006, 53}, + {0x800a, 53}, + {0x800f, 53}, + {0x8018, 53}, + {0x801f, 53}, + {0x8029, 53}, + {0xc038, 53}, }, /* 19 */ { - {2, 0x02, 54}, - {9, 0x02, 54}, - {23, 0x02, 54}, - {40, 0x03, 54}, - {2, 0x02, 55}, - {9, 0x02, 55}, - {23, 0x02, 55}, - {40, 0x03, 55}, - {2, 0x02, 56}, - {9, 0x02, 56}, - {23, 0x02, 56}, - {40, 0x03, 56}, - {2, 0x02, 57}, - {9, 0x02, 57}, - {23, 0x02, 57}, - {40, 0x03, 57}, + {0x8002, 54}, + {0x8009, 54}, + {0x8017, 54}, + {0xc028, 54}, + {0x8002, 55}, + {0x8009, 55}, + {0x8017, 55}, + {0xc028, 55}, + {0x8002, 56}, + {0x8009, 56}, + {0x8017, 56}, + {0xc028, 56}, + {0x8002, 57}, + {0x8009, 57}, + {0x8017, 57}, + {0xc028, 57}, }, /* 20 */ { - {3, 0x02, 54}, - {6, 0x02, 54}, - {10, 0x02, 54}, - {15, 0x02, 54}, - {24, 0x02, 54}, - {31, 0x02, 54}, - {41, 0x02, 54}, - {56, 0x03, 54}, - {3, 0x02, 55}, - {6, 0x02, 55}, - {10, 0x02, 55}, - {15, 0x02, 55}, - {24, 0x02, 55}, - {31, 0x02, 55}, - {41, 0x02, 55}, - {56, 0x03, 55}, + {0x8003, 54}, + {0x8006, 54}, + {0x800a, 54}, + {0x800f, 54}, + {0x8018, 54}, + {0x801f, 54}, + {0x8029, 54}, + {0xc038, 54}, + {0x8003, 55}, + {0x8006, 55}, + {0x800a, 55}, + {0x800f, 55}, + {0x8018, 55}, + {0x801f, 55}, + {0x8029, 55}, + {0xc038, 55}, }, /* 21 */ { - {3, 0x02, 56}, - {6, 0x02, 56}, - {10, 0x02, 56}, - {15, 0x02, 56}, - {24, 0x02, 56}, - {31, 0x02, 56}, - {41, 0x02, 56}, - {56, 0x03, 56}, - {3, 0x02, 57}, - {6, 0x02, 57}, - {10, 0x02, 57}, - {15, 0x02, 57}, - {24, 0x02, 57}, - {31, 0x02, 57}, - {41, 0x02, 57}, - {56, 0x03, 57}, + {0x8003, 56}, + {0x8006, 56}, + {0x800a, 56}, + {0x800f, 56}, + {0x8018, 56}, + {0x801f, 56}, + {0x8029, 56}, + {0xc038, 56}, + {0x8003, 57}, + {0x8006, 57}, + {0x800a, 57}, + {0x800f, 57}, + {0x8018, 57}, + {0x801f, 57}, + {0x8029, 57}, + {0xc038, 57}, }, /* 22 */ { - {26, 0x00, 0}, - {27, 0x00, 0}, - {29, 0x00, 0}, - {30, 0x00, 0}, - {33, 0x00, 0}, - {34, 0x00, 0}, - {36, 0x00, 0}, - {37, 0x00, 0}, - {43, 0x00, 0}, - {46, 0x00, 0}, - {50, 0x00, 0}, - {53, 0x00, 0}, - {58, 0x00, 0}, - {61, 0x00, 0}, - {65, 0x00, 0}, - {68, 0x01, 0}, + {0x1a, 0}, + {0x1b, 0}, + {0x1d, 0}, + {0x1e, 0}, + {0x21, 0}, + {0x22, 0}, + {0x24, 0}, + {0x25, 0}, + {0x2b, 0}, + {0x2e, 0}, + {0x32, 0}, + {0x35, 0}, + {0x3a, 0}, + {0x3d, 0}, + {0x41, 0}, + {0x4044, 0}, }, /* 23 */ { - {0, 0x03, 61}, - {0, 0x03, 65}, - {0, 0x03, 95}, - {0, 0x03, 98}, - {0, 0x03, 100}, - {0, 0x03, 102}, - {0, 0x03, 103}, - {0, 0x03, 104}, - {0, 0x03, 108}, - {0, 0x03, 109}, - {0, 0x03, 110}, - {0, 0x03, 112}, - {0, 0x03, 114}, - {0, 0x03, 117}, - {38, 0x00, 0}, - {39, 0x00, 0}, + {0xc000, 61}, + {0xc000, 65}, + {0xc000, 95}, + {0xc000, 98}, + {0xc000, 100}, + {0xc000, 102}, + {0xc000, 103}, + {0xc000, 104}, + {0xc000, 108}, + {0xc000, 109}, + {0xc000, 110}, + {0xc000, 112}, + {0xc000, 114}, + {0xc000, 117}, + {0x26, 0}, + {0x27, 0}, }, /* 24 */ { - {1, 0x02, 61}, - {22, 0x03, 61}, - {1, 0x02, 65}, - {22, 0x03, 65}, - {1, 0x02, 95}, - {22, 0x03, 95}, - {1, 0x02, 98}, - {22, 0x03, 98}, - {1, 0x02, 100}, - {22, 0x03, 100}, - {1, 0x02, 102}, - {22, 0x03, 102}, - {1, 0x02, 103}, - {22, 0x03, 103}, - {1, 0x02, 104}, - {22, 0x03, 104}, + {0x8001, 61}, + {0xc016, 61}, + {0x8001, 65}, + {0xc016, 65}, + {0x8001, 95}, + {0xc016, 95}, + {0x8001, 98}, + {0xc016, 98}, + {0x8001, 100}, + {0xc016, 100}, + {0x8001, 102}, + {0xc016, 102}, + {0x8001, 103}, + {0xc016, 103}, + {0x8001, 104}, + {0xc016, 104}, }, /* 25 */ { - {2, 0x02, 61}, - {9, 0x02, 61}, - {23, 0x02, 61}, - {40, 0x03, 61}, - {2, 0x02, 65}, - {9, 0x02, 65}, - {23, 0x02, 65}, - {40, 0x03, 65}, - {2, 0x02, 95}, - {9, 0x02, 95}, - {23, 0x02, 95}, - {40, 0x03, 95}, - {2, 0x02, 98}, - {9, 0x02, 98}, - {23, 0x02, 98}, - {40, 0x03, 98}, + {0x8002, 61}, + {0x8009, 61}, + {0x8017, 61}, + {0xc028, 61}, + {0x8002, 65}, + {0x8009, 65}, + {0x8017, 65}, + {0xc028, 65}, + {0x8002, 95}, + {0x8009, 95}, + {0x8017, 95}, + {0xc028, 95}, + {0x8002, 98}, + {0x8009, 98}, + {0x8017, 98}, + {0xc028, 98}, }, /* 26 */ { - {3, 0x02, 61}, - {6, 0x02, 61}, - {10, 0x02, 61}, - {15, 0x02, 61}, - {24, 0x02, 61}, - {31, 0x02, 61}, - {41, 0x02, 61}, - {56, 0x03, 61}, - {3, 0x02, 65}, - {6, 0x02, 65}, - {10, 0x02, 65}, - {15, 0x02, 65}, - {24, 0x02, 65}, - {31, 0x02, 65}, - {41, 0x02, 65}, - {56, 0x03, 65}, + {0x8003, 61}, + {0x8006, 61}, + {0x800a, 61}, + {0x800f, 61}, + {0x8018, 61}, + {0x801f, 61}, + {0x8029, 61}, + {0xc038, 61}, + {0x8003, 65}, + {0x8006, 65}, + {0x800a, 65}, + {0x800f, 65}, + {0x8018, 65}, + {0x801f, 65}, + {0x8029, 65}, + {0xc038, 65}, }, /* 27 */ { - {3, 0x02, 95}, - {6, 0x02, 95}, - {10, 0x02, 95}, - {15, 0x02, 95}, - {24, 0x02, 95}, - {31, 0x02, 95}, - {41, 0x02, 95}, - {56, 0x03, 95}, - {3, 0x02, 98}, - {6, 0x02, 98}, - {10, 0x02, 98}, - {15, 0x02, 98}, - {24, 0x02, 98}, - {31, 0x02, 98}, - {41, 0x02, 98}, - {56, 0x03, 98}, + {0x8003, 95}, + {0x8006, 95}, + {0x800a, 95}, + {0x800f, 95}, + {0x8018, 95}, + {0x801f, 95}, + {0x8029, 95}, + {0xc038, 95}, + {0x8003, 98}, + {0x8006, 98}, + {0x800a, 98}, + {0x800f, 98}, + {0x8018, 98}, + {0x801f, 98}, + {0x8029, 98}, + {0xc038, 98}, }, /* 28 */ { - {2, 0x02, 100}, - {9, 0x02, 100}, - {23, 0x02, 100}, - {40, 0x03, 100}, - {2, 0x02, 102}, - {9, 0x02, 102}, - {23, 0x02, 102}, - {40, 0x03, 102}, - {2, 0x02, 103}, - {9, 0x02, 103}, - {23, 0x02, 103}, - {40, 0x03, 103}, - {2, 0x02, 104}, - {9, 0x02, 104}, - {23, 0x02, 104}, - {40, 0x03, 104}, + {0x8002, 100}, + {0x8009, 100}, + {0x8017, 100}, + {0xc028, 100}, + {0x8002, 102}, + {0x8009, 102}, + {0x8017, 102}, + {0xc028, 102}, + {0x8002, 103}, + {0x8009, 103}, + {0x8017, 103}, + {0xc028, 103}, + {0x8002, 104}, + {0x8009, 104}, + {0x8017, 104}, + {0xc028, 104}, }, /* 29 */ { - {3, 0x02, 100}, - {6, 0x02, 100}, - {10, 0x02, 100}, - {15, 0x02, 100}, - {24, 0x02, 100}, - {31, 0x02, 100}, - {41, 0x02, 100}, - {56, 0x03, 100}, - {3, 0x02, 102}, - {6, 0x02, 102}, - {10, 0x02, 102}, - {15, 0x02, 102}, - {24, 0x02, 102}, - {31, 0x02, 102}, - {41, 0x02, 102}, - {56, 0x03, 102}, + {0x8003, 100}, + {0x8006, 100}, + {0x800a, 100}, + {0x800f, 100}, + {0x8018, 100}, + {0x801f, 100}, + {0x8029, 100}, + {0xc038, 100}, + {0x8003, 102}, + {0x8006, 102}, + {0x800a, 102}, + {0x800f, 102}, + {0x8018, 102}, + {0x801f, 102}, + {0x8029, 102}, + {0xc038, 102}, }, /* 30 */ { - {3, 0x02, 103}, - {6, 0x02, 103}, - {10, 0x02, 103}, - {15, 0x02, 103}, - {24, 0x02, 103}, - {31, 0x02, 103}, - {41, 0x02, 103}, - {56, 0x03, 103}, - {3, 0x02, 104}, - {6, 0x02, 104}, - {10, 0x02, 104}, - {15, 0x02, 104}, - {24, 0x02, 104}, - {31, 0x02, 104}, - {41, 0x02, 104}, - {56, 0x03, 104}, + {0x8003, 103}, + {0x8006, 103}, + {0x800a, 103}, + {0x800f, 103}, + {0x8018, 103}, + {0x801f, 103}, + {0x8029, 103}, + {0xc038, 103}, + {0x8003, 104}, + {0x8006, 104}, + {0x800a, 104}, + {0x800f, 104}, + {0x8018, 104}, + {0x801f, 104}, + {0x8029, 104}, + {0xc038, 104}, }, /* 31 */ { - {1, 0x02, 108}, - {22, 0x03, 108}, - {1, 0x02, 109}, - {22, 0x03, 109}, - {1, 0x02, 110}, - {22, 0x03, 110}, - {1, 0x02, 112}, - {22, 0x03, 112}, - {1, 0x02, 114}, - {22, 0x03, 114}, - {1, 0x02, 117}, - {22, 0x03, 117}, - {0, 0x03, 58}, - {0, 0x03, 66}, - {0, 0x03, 67}, - {0, 0x03, 68}, + {0x8001, 108}, + {0xc016, 108}, + {0x8001, 109}, + {0xc016, 109}, + {0x8001, 110}, + {0xc016, 110}, + {0x8001, 112}, + {0xc016, 112}, + {0x8001, 114}, + {0xc016, 114}, + {0x8001, 117}, + {0xc016, 117}, + {0xc000, 58}, + {0xc000, 66}, + {0xc000, 67}, + {0xc000, 68}, }, /* 32 */ { - {2, 0x02, 108}, - {9, 0x02, 108}, - {23, 0x02, 108}, - {40, 0x03, 108}, - {2, 0x02, 109}, - {9, 0x02, 109}, - {23, 0x02, 109}, - {40, 0x03, 109}, - {2, 0x02, 110}, - {9, 0x02, 110}, - {23, 0x02, 110}, - {40, 0x03, 110}, - {2, 0x02, 112}, - {9, 0x02, 112}, - {23, 0x02, 112}, - {40, 0x03, 112}, + {0x8002, 108}, + {0x8009, 108}, + {0x8017, 108}, + {0xc028, 108}, + {0x8002, 109}, + {0x8009, 109}, + {0x8017, 109}, + {0xc028, 109}, + {0x8002, 110}, + {0x8009, 110}, + {0x8017, 110}, + {0xc028, 110}, + {0x8002, 112}, + {0x8009, 112}, + {0x8017, 112}, + {0xc028, 112}, }, /* 33 */ { - {3, 0x02, 108}, - {6, 0x02, 108}, - {10, 0x02, 108}, - {15, 0x02, 108}, - {24, 0x02, 108}, - {31, 0x02, 108}, - {41, 0x02, 108}, - {56, 0x03, 108}, - {3, 0x02, 109}, - {6, 0x02, 109}, - {10, 0x02, 109}, - {15, 0x02, 109}, - {24, 0x02, 109}, - {31, 0x02, 109}, - {41, 0x02, 109}, - {56, 0x03, 109}, + {0x8003, 108}, + {0x8006, 108}, + {0x800a, 108}, + {0x800f, 108}, + {0x8018, 108}, + {0x801f, 108}, + {0x8029, 108}, + {0xc038, 108}, + {0x8003, 109}, + {0x8006, 109}, + {0x800a, 109}, + {0x800f, 109}, + {0x8018, 109}, + {0x801f, 109}, + {0x8029, 109}, + {0xc038, 109}, }, /* 34 */ { - {3, 0x02, 110}, - {6, 0x02, 110}, - {10, 0x02, 110}, - {15, 0x02, 110}, - {24, 0x02, 110}, - {31, 0x02, 110}, - {41, 0x02, 110}, - {56, 0x03, 110}, - {3, 0x02, 112}, - {6, 0x02, 112}, - {10, 0x02, 112}, - {15, 0x02, 112}, - {24, 0x02, 112}, - {31, 0x02, 112}, - {41, 0x02, 112}, - {56, 0x03, 112}, + {0x8003, 110}, + {0x8006, 110}, + {0x800a, 110}, + {0x800f, 110}, + {0x8018, 110}, + {0x801f, 110}, + {0x8029, 110}, + {0xc038, 110}, + {0x8003, 112}, + {0x8006, 112}, + {0x800a, 112}, + {0x800f, 112}, + {0x8018, 112}, + {0x801f, 112}, + {0x8029, 112}, + {0xc038, 112}, }, /* 35 */ { - {2, 0x02, 114}, - {9, 0x02, 114}, - {23, 0x02, 114}, - {40, 0x03, 114}, - {2, 0x02, 117}, - {9, 0x02, 117}, - {23, 0x02, 117}, - {40, 0x03, 117}, - {1, 0x02, 58}, - {22, 0x03, 58}, - {1, 0x02, 66}, - {22, 0x03, 66}, - {1, 0x02, 67}, - {22, 0x03, 67}, - {1, 0x02, 68}, - {22, 0x03, 68}, + {0x8002, 114}, + {0x8009, 114}, + {0x8017, 114}, + {0xc028, 114}, + {0x8002, 117}, + {0x8009, 117}, + {0x8017, 117}, + {0xc028, 117}, + {0x8001, 58}, + {0xc016, 58}, + {0x8001, 66}, + {0xc016, 66}, + {0x8001, 67}, + {0xc016, 67}, + {0x8001, 68}, + {0xc016, 68}, }, /* 36 */ { - {3, 0x02, 114}, - {6, 0x02, 114}, - {10, 0x02, 114}, - {15, 0x02, 114}, - {24, 0x02, 114}, - {31, 0x02, 114}, - {41, 0x02, 114}, - {56, 0x03, 114}, - {3, 0x02, 117}, - {6, 0x02, 117}, - {10, 0x02, 117}, - {15, 0x02, 117}, - {24, 0x02, 117}, - {31, 0x02, 117}, - {41, 0x02, 117}, - {56, 0x03, 117}, + {0x8003, 114}, + {0x8006, 114}, + {0x800a, 114}, + {0x800f, 114}, + {0x8018, 114}, + {0x801f, 114}, + {0x8029, 114}, + {0xc038, 114}, + {0x8003, 117}, + {0x8006, 117}, + {0x800a, 117}, + {0x800f, 117}, + {0x8018, 117}, + {0x801f, 117}, + {0x8029, 117}, + {0xc038, 117}, }, /* 37 */ { - {2, 0x02, 58}, - {9, 0x02, 58}, - {23, 0x02, 58}, - {40, 0x03, 58}, - {2, 0x02, 66}, - {9, 0x02, 66}, - {23, 0x02, 66}, - {40, 0x03, 66}, - {2, 0x02, 67}, - {9, 0x02, 67}, - {23, 0x02, 67}, - {40, 0x03, 67}, - {2, 0x02, 68}, - {9, 0x02, 68}, - {23, 0x02, 68}, - {40, 0x03, 68}, + {0x8002, 58}, + {0x8009, 58}, + {0x8017, 58}, + {0xc028, 58}, + {0x8002, 66}, + {0x8009, 66}, + {0x8017, 66}, + {0xc028, 66}, + {0x8002, 67}, + {0x8009, 67}, + {0x8017, 67}, + {0xc028, 67}, + {0x8002, 68}, + {0x8009, 68}, + {0x8017, 68}, + {0xc028, 68}, }, /* 38 */ { - {3, 0x02, 58}, - {6, 0x02, 58}, - {10, 0x02, 58}, - {15, 0x02, 58}, - {24, 0x02, 58}, - {31, 0x02, 58}, - {41, 0x02, 58}, - {56, 0x03, 58}, - {3, 0x02, 66}, - {6, 0x02, 66}, - {10, 0x02, 66}, - {15, 0x02, 66}, - {24, 0x02, 66}, - {31, 0x02, 66}, - {41, 0x02, 66}, - {56, 0x03, 66}, + {0x8003, 58}, + {0x8006, 58}, + {0x800a, 58}, + {0x800f, 58}, + {0x8018, 58}, + {0x801f, 58}, + {0x8029, 58}, + {0xc038, 58}, + {0x8003, 66}, + {0x8006, 66}, + {0x800a, 66}, + {0x800f, 66}, + {0x8018, 66}, + {0x801f, 66}, + {0x8029, 66}, + {0xc038, 66}, }, /* 39 */ { - {3, 0x02, 67}, - {6, 0x02, 67}, - {10, 0x02, 67}, - {15, 0x02, 67}, - {24, 0x02, 67}, - {31, 0x02, 67}, - {41, 0x02, 67}, - {56, 0x03, 67}, - {3, 0x02, 68}, - {6, 0x02, 68}, - {10, 0x02, 68}, - {15, 0x02, 68}, - {24, 0x02, 68}, - {31, 0x02, 68}, - {41, 0x02, 68}, - {56, 0x03, 68}, + {0x8003, 67}, + {0x8006, 67}, + {0x800a, 67}, + {0x800f, 67}, + {0x8018, 67}, + {0x801f, 67}, + {0x8029, 67}, + {0xc038, 67}, + {0x8003, 68}, + {0x8006, 68}, + {0x800a, 68}, + {0x800f, 68}, + {0x8018, 68}, + {0x801f, 68}, + {0x8029, 68}, + {0xc038, 68}, }, /* 40 */ { - {44, 0x00, 0}, - {45, 0x00, 0}, - {47, 0x00, 0}, - {48, 0x00, 0}, - {51, 0x00, 0}, - {52, 0x00, 0}, - {54, 0x00, 0}, - {55, 0x00, 0}, - {59, 0x00, 0}, - {60, 0x00, 0}, - {62, 0x00, 0}, - {63, 0x00, 0}, - {66, 0x00, 0}, - {67, 0x00, 0}, - {69, 0x00, 0}, - {72, 0x01, 0}, + {0x2c, 0}, + {0x2d, 0}, + {0x2f, 0}, + {0x30, 0}, + {0x33, 0}, + {0x34, 0}, + {0x36, 0}, + {0x37, 0}, + {0x3b, 0}, + {0x3c, 0}, + {0x3e, 0}, + {0x3f, 0}, + {0x42, 0}, + {0x43, 0}, + {0x45, 0}, + {0x4048, 0}, }, /* 41 */ { - {0, 0x03, 69}, - {0, 0x03, 70}, - {0, 0x03, 71}, - {0, 0x03, 72}, - {0, 0x03, 73}, - {0, 0x03, 74}, - {0, 0x03, 75}, - {0, 0x03, 76}, - {0, 0x03, 77}, - {0, 0x03, 78}, - {0, 0x03, 79}, - {0, 0x03, 80}, - {0, 0x03, 81}, - {0, 0x03, 82}, - {0, 0x03, 83}, - {0, 0x03, 84}, + {0xc000, 69}, + {0xc000, 70}, + {0xc000, 71}, + {0xc000, 72}, + {0xc000, 73}, + {0xc000, 74}, + {0xc000, 75}, + {0xc000, 76}, + {0xc000, 77}, + {0xc000, 78}, + {0xc000, 79}, + {0xc000, 80}, + {0xc000, 81}, + {0xc000, 82}, + {0xc000, 83}, + {0xc000, 84}, }, /* 42 */ { - {1, 0x02, 69}, - {22, 0x03, 69}, - {1, 0x02, 70}, - {22, 0x03, 70}, - {1, 0x02, 71}, - {22, 0x03, 71}, - {1, 0x02, 72}, - {22, 0x03, 72}, - {1, 0x02, 73}, - {22, 0x03, 73}, - {1, 0x02, 74}, - {22, 0x03, 74}, - {1, 0x02, 75}, - {22, 0x03, 75}, - {1, 0x02, 76}, - {22, 0x03, 76}, + {0x8001, 69}, + {0xc016, 69}, + {0x8001, 70}, + {0xc016, 70}, + {0x8001, 71}, + {0xc016, 71}, + {0x8001, 72}, + {0xc016, 72}, + {0x8001, 73}, + {0xc016, 73}, + {0x8001, 74}, + {0xc016, 74}, + {0x8001, 75}, + {0xc016, 75}, + {0x8001, 76}, + {0xc016, 76}, }, /* 43 */ { - {2, 0x02, 69}, - {9, 0x02, 69}, - {23, 0x02, 69}, - {40, 0x03, 69}, - {2, 0x02, 70}, - {9, 0x02, 70}, - {23, 0x02, 70}, - {40, 0x03, 70}, - {2, 0x02, 71}, - {9, 0x02, 71}, - {23, 0x02, 71}, - {40, 0x03, 71}, - {2, 0x02, 72}, - {9, 0x02, 72}, - {23, 0x02, 72}, - {40, 0x03, 72}, + {0x8002, 69}, + {0x8009, 69}, + {0x8017, 69}, + {0xc028, 69}, + {0x8002, 70}, + {0x8009, 70}, + {0x8017, 70}, + {0xc028, 70}, + {0x8002, 71}, + {0x8009, 71}, + {0x8017, 71}, + {0xc028, 71}, + {0x8002, 72}, + {0x8009, 72}, + {0x8017, 72}, + {0xc028, 72}, }, /* 44 */ { - {3, 0x02, 69}, - {6, 0x02, 69}, - {10, 0x02, 69}, - {15, 0x02, 69}, - {24, 0x02, 69}, - {31, 0x02, 69}, - {41, 0x02, 69}, - {56, 0x03, 69}, - {3, 0x02, 70}, - {6, 0x02, 70}, - {10, 0x02, 70}, - {15, 0x02, 70}, - {24, 0x02, 70}, - {31, 0x02, 70}, - {41, 0x02, 70}, - {56, 0x03, 70}, + {0x8003, 69}, + {0x8006, 69}, + {0x800a, 69}, + {0x800f, 69}, + {0x8018, 69}, + {0x801f, 69}, + {0x8029, 69}, + {0xc038, 69}, + {0x8003, 70}, + {0x8006, 70}, + {0x800a, 70}, + {0x800f, 70}, + {0x8018, 70}, + {0x801f, 70}, + {0x8029, 70}, + {0xc038, 70}, }, /* 45 */ { - {3, 0x02, 71}, - {6, 0x02, 71}, - {10, 0x02, 71}, - {15, 0x02, 71}, - {24, 0x02, 71}, - {31, 0x02, 71}, - {41, 0x02, 71}, - {56, 0x03, 71}, - {3, 0x02, 72}, - {6, 0x02, 72}, - {10, 0x02, 72}, - {15, 0x02, 72}, - {24, 0x02, 72}, - {31, 0x02, 72}, - {41, 0x02, 72}, - {56, 0x03, 72}, + {0x8003, 71}, + {0x8006, 71}, + {0x800a, 71}, + {0x800f, 71}, + {0x8018, 71}, + {0x801f, 71}, + {0x8029, 71}, + {0xc038, 71}, + {0x8003, 72}, + {0x8006, 72}, + {0x800a, 72}, + {0x800f, 72}, + {0x8018, 72}, + {0x801f, 72}, + {0x8029, 72}, + {0xc038, 72}, }, /* 46 */ { - {2, 0x02, 73}, - {9, 0x02, 73}, - {23, 0x02, 73}, - {40, 0x03, 73}, - {2, 0x02, 74}, - {9, 0x02, 74}, - {23, 0x02, 74}, - {40, 0x03, 74}, - {2, 0x02, 75}, - {9, 0x02, 75}, - {23, 0x02, 75}, - {40, 0x03, 75}, - {2, 0x02, 76}, - {9, 0x02, 76}, - {23, 0x02, 76}, - {40, 0x03, 76}, + {0x8002, 73}, + {0x8009, 73}, + {0x8017, 73}, + {0xc028, 73}, + {0x8002, 74}, + {0x8009, 74}, + {0x8017, 74}, + {0xc028, 74}, + {0x8002, 75}, + {0x8009, 75}, + {0x8017, 75}, + {0xc028, 75}, + {0x8002, 76}, + {0x8009, 76}, + {0x8017, 76}, + {0xc028, 76}, }, /* 47 */ { - {3, 0x02, 73}, - {6, 0x02, 73}, - {10, 0x02, 73}, - {15, 0x02, 73}, - {24, 0x02, 73}, - {31, 0x02, 73}, - {41, 0x02, 73}, - {56, 0x03, 73}, - {3, 0x02, 74}, - {6, 0x02, 74}, - {10, 0x02, 74}, - {15, 0x02, 74}, - {24, 0x02, 74}, - {31, 0x02, 74}, - {41, 0x02, 74}, - {56, 0x03, 74}, + {0x8003, 73}, + {0x8006, 73}, + {0x800a, 73}, + {0x800f, 73}, + {0x8018, 73}, + {0x801f, 73}, + {0x8029, 73}, + {0xc038, 73}, + {0x8003, 74}, + {0x8006, 74}, + {0x800a, 74}, + {0x800f, 74}, + {0x8018, 74}, + {0x801f, 74}, + {0x8029, 74}, + {0xc038, 74}, }, /* 48 */ { - {3, 0x02, 75}, - {6, 0x02, 75}, - {10, 0x02, 75}, - {15, 0x02, 75}, - {24, 0x02, 75}, - {31, 0x02, 75}, - {41, 0x02, 75}, - {56, 0x03, 75}, - {3, 0x02, 76}, - {6, 0x02, 76}, - {10, 0x02, 76}, - {15, 0x02, 76}, - {24, 0x02, 76}, - {31, 0x02, 76}, - {41, 0x02, 76}, - {56, 0x03, 76}, + {0x8003, 75}, + {0x8006, 75}, + {0x800a, 75}, + {0x800f, 75}, + {0x8018, 75}, + {0x801f, 75}, + {0x8029, 75}, + {0xc038, 75}, + {0x8003, 76}, + {0x8006, 76}, + {0x800a, 76}, + {0x800f, 76}, + {0x8018, 76}, + {0x801f, 76}, + {0x8029, 76}, + {0xc038, 76}, }, /* 49 */ { - {1, 0x02, 77}, - {22, 0x03, 77}, - {1, 0x02, 78}, - {22, 0x03, 78}, - {1, 0x02, 79}, - {22, 0x03, 79}, - {1, 0x02, 80}, - {22, 0x03, 80}, - {1, 0x02, 81}, - {22, 0x03, 81}, - {1, 0x02, 82}, - {22, 0x03, 82}, - {1, 0x02, 83}, - {22, 0x03, 83}, - {1, 0x02, 84}, - {22, 0x03, 84}, + {0x8001, 77}, + {0xc016, 77}, + {0x8001, 78}, + {0xc016, 78}, + {0x8001, 79}, + {0xc016, 79}, + {0x8001, 80}, + {0xc016, 80}, + {0x8001, 81}, + {0xc016, 81}, + {0x8001, 82}, + {0xc016, 82}, + {0x8001, 83}, + {0xc016, 83}, + {0x8001, 84}, + {0xc016, 84}, }, /* 50 */ { - {2, 0x02, 77}, - {9, 0x02, 77}, - {23, 0x02, 77}, - {40, 0x03, 77}, - {2, 0x02, 78}, - {9, 0x02, 78}, - {23, 0x02, 78}, - {40, 0x03, 78}, - {2, 0x02, 79}, - {9, 0x02, 79}, - {23, 0x02, 79}, - {40, 0x03, 79}, - {2, 0x02, 80}, - {9, 0x02, 80}, - {23, 0x02, 80}, - {40, 0x03, 80}, + {0x8002, 77}, + {0x8009, 77}, + {0x8017, 77}, + {0xc028, 77}, + {0x8002, 78}, + {0x8009, 78}, + {0x8017, 78}, + {0xc028, 78}, + {0x8002, 79}, + {0x8009, 79}, + {0x8017, 79}, + {0xc028, 79}, + {0x8002, 80}, + {0x8009, 80}, + {0x8017, 80}, + {0xc028, 80}, }, /* 51 */ { - {3, 0x02, 77}, - {6, 0x02, 77}, - {10, 0x02, 77}, - {15, 0x02, 77}, - {24, 0x02, 77}, - {31, 0x02, 77}, - {41, 0x02, 77}, - {56, 0x03, 77}, - {3, 0x02, 78}, - {6, 0x02, 78}, - {10, 0x02, 78}, - {15, 0x02, 78}, - {24, 0x02, 78}, - {31, 0x02, 78}, - {41, 0x02, 78}, - {56, 0x03, 78}, + {0x8003, 77}, + {0x8006, 77}, + {0x800a, 77}, + {0x800f, 77}, + {0x8018, 77}, + {0x801f, 77}, + {0x8029, 77}, + {0xc038, 77}, + {0x8003, 78}, + {0x8006, 78}, + {0x800a, 78}, + {0x800f, 78}, + {0x8018, 78}, + {0x801f, 78}, + {0x8029, 78}, + {0xc038, 78}, }, /* 52 */ { - {3, 0x02, 79}, - {6, 0x02, 79}, - {10, 0x02, 79}, - {15, 0x02, 79}, - {24, 0x02, 79}, - {31, 0x02, 79}, - {41, 0x02, 79}, - {56, 0x03, 79}, - {3, 0x02, 80}, - {6, 0x02, 80}, - {10, 0x02, 80}, - {15, 0x02, 80}, - {24, 0x02, 80}, - {31, 0x02, 80}, - {41, 0x02, 80}, - {56, 0x03, 80}, + {0x8003, 79}, + {0x8006, 79}, + {0x800a, 79}, + {0x800f, 79}, + {0x8018, 79}, + {0x801f, 79}, + {0x8029, 79}, + {0xc038, 79}, + {0x8003, 80}, + {0x8006, 80}, + {0x800a, 80}, + {0x800f, 80}, + {0x8018, 80}, + {0x801f, 80}, + {0x8029, 80}, + {0xc038, 80}, }, /* 53 */ { - {2, 0x02, 81}, - {9, 0x02, 81}, - {23, 0x02, 81}, - {40, 0x03, 81}, - {2, 0x02, 82}, - {9, 0x02, 82}, - {23, 0x02, 82}, - {40, 0x03, 82}, - {2, 0x02, 83}, - {9, 0x02, 83}, - {23, 0x02, 83}, - {40, 0x03, 83}, - {2, 0x02, 84}, - {9, 0x02, 84}, - {23, 0x02, 84}, - {40, 0x03, 84}, + {0x8002, 81}, + {0x8009, 81}, + {0x8017, 81}, + {0xc028, 81}, + {0x8002, 82}, + {0x8009, 82}, + {0x8017, 82}, + {0xc028, 82}, + {0x8002, 83}, + {0x8009, 83}, + {0x8017, 83}, + {0xc028, 83}, + {0x8002, 84}, + {0x8009, 84}, + {0x8017, 84}, + {0xc028, 84}, }, /* 54 */ { - {3, 0x02, 81}, - {6, 0x02, 81}, - {10, 0x02, 81}, - {15, 0x02, 81}, - {24, 0x02, 81}, - {31, 0x02, 81}, - {41, 0x02, 81}, - {56, 0x03, 81}, - {3, 0x02, 82}, - {6, 0x02, 82}, - {10, 0x02, 82}, - {15, 0x02, 82}, - {24, 0x02, 82}, - {31, 0x02, 82}, - {41, 0x02, 82}, - {56, 0x03, 82}, + {0x8003, 81}, + {0x8006, 81}, + {0x800a, 81}, + {0x800f, 81}, + {0x8018, 81}, + {0x801f, 81}, + {0x8029, 81}, + {0xc038, 81}, + {0x8003, 82}, + {0x8006, 82}, + {0x800a, 82}, + {0x800f, 82}, + {0x8018, 82}, + {0x801f, 82}, + {0x8029, 82}, + {0xc038, 82}, }, /* 55 */ { - {3, 0x02, 83}, - {6, 0x02, 83}, - {10, 0x02, 83}, - {15, 0x02, 83}, - {24, 0x02, 83}, - {31, 0x02, 83}, - {41, 0x02, 83}, - {56, 0x03, 83}, - {3, 0x02, 84}, - {6, 0x02, 84}, - {10, 0x02, 84}, - {15, 0x02, 84}, - {24, 0x02, 84}, - {31, 0x02, 84}, - {41, 0x02, 84}, - {56, 0x03, 84}, + {0x8003, 83}, + {0x8006, 83}, + {0x800a, 83}, + {0x800f, 83}, + {0x8018, 83}, + {0x801f, 83}, + {0x8029, 83}, + {0xc038, 83}, + {0x8003, 84}, + {0x8006, 84}, + {0x800a, 84}, + {0x800f, 84}, + {0x8018, 84}, + {0x801f, 84}, + {0x8029, 84}, + {0xc038, 84}, }, /* 56 */ { - {0, 0x03, 85}, - {0, 0x03, 86}, - {0, 0x03, 87}, - {0, 0x03, 89}, - {0, 0x03, 106}, - {0, 0x03, 107}, - {0, 0x03, 113}, - {0, 0x03, 118}, - {0, 0x03, 119}, - {0, 0x03, 120}, - {0, 0x03, 121}, - {0, 0x03, 122}, - {70, 0x00, 0}, - {71, 0x00, 0}, - {73, 0x00, 0}, - {74, 0x01, 0}, + {0xc000, 85}, + {0xc000, 86}, + {0xc000, 87}, + {0xc000, 89}, + {0xc000, 106}, + {0xc000, 107}, + {0xc000, 113}, + {0xc000, 118}, + {0xc000, 119}, + {0xc000, 120}, + {0xc000, 121}, + {0xc000, 122}, + {0x46, 0}, + {0x47, 0}, + {0x49, 0}, + {0x404a, 0}, }, /* 57 */ { - {1, 0x02, 85}, - {22, 0x03, 85}, - {1, 0x02, 86}, - {22, 0x03, 86}, - {1, 0x02, 87}, - {22, 0x03, 87}, - {1, 0x02, 89}, - {22, 0x03, 89}, - {1, 0x02, 106}, - {22, 0x03, 106}, - {1, 0x02, 107}, - {22, 0x03, 107}, - {1, 0x02, 113}, - {22, 0x03, 113}, - {1, 0x02, 118}, - {22, 0x03, 118}, + {0x8001, 85}, + {0xc016, 85}, + {0x8001, 86}, + {0xc016, 86}, + {0x8001, 87}, + {0xc016, 87}, + {0x8001, 89}, + {0xc016, 89}, + {0x8001, 106}, + {0xc016, 106}, + {0x8001, 107}, + {0xc016, 107}, + {0x8001, 113}, + {0xc016, 113}, + {0x8001, 118}, + {0xc016, 118}, }, /* 58 */ { - {2, 0x02, 85}, - {9, 0x02, 85}, - {23, 0x02, 85}, - {40, 0x03, 85}, - {2, 0x02, 86}, - {9, 0x02, 86}, - {23, 0x02, 86}, - {40, 0x03, 86}, - {2, 0x02, 87}, - {9, 0x02, 87}, - {23, 0x02, 87}, - {40, 0x03, 87}, - {2, 0x02, 89}, - {9, 0x02, 89}, - {23, 0x02, 89}, - {40, 0x03, 89}, + {0x8002, 85}, + {0x8009, 85}, + {0x8017, 85}, + {0xc028, 85}, + {0x8002, 86}, + {0x8009, 86}, + {0x8017, 86}, + {0xc028, 86}, + {0x8002, 87}, + {0x8009, 87}, + {0x8017, 87}, + {0xc028, 87}, + {0x8002, 89}, + {0x8009, 89}, + {0x8017, 89}, + {0xc028, 89}, }, /* 59 */ { - {3, 0x02, 85}, - {6, 0x02, 85}, - {10, 0x02, 85}, - {15, 0x02, 85}, - {24, 0x02, 85}, - {31, 0x02, 85}, - {41, 0x02, 85}, - {56, 0x03, 85}, - {3, 0x02, 86}, - {6, 0x02, 86}, - {10, 0x02, 86}, - {15, 0x02, 86}, - {24, 0x02, 86}, - {31, 0x02, 86}, - {41, 0x02, 86}, - {56, 0x03, 86}, + {0x8003, 85}, + {0x8006, 85}, + {0x800a, 85}, + {0x800f, 85}, + {0x8018, 85}, + {0x801f, 85}, + {0x8029, 85}, + {0xc038, 85}, + {0x8003, 86}, + {0x8006, 86}, + {0x800a, 86}, + {0x800f, 86}, + {0x8018, 86}, + {0x801f, 86}, + {0x8029, 86}, + {0xc038, 86}, }, /* 60 */ { - {3, 0x02, 87}, - {6, 0x02, 87}, - {10, 0x02, 87}, - {15, 0x02, 87}, - {24, 0x02, 87}, - {31, 0x02, 87}, - {41, 0x02, 87}, - {56, 0x03, 87}, - {3, 0x02, 89}, - {6, 0x02, 89}, - {10, 0x02, 89}, - {15, 0x02, 89}, - {24, 0x02, 89}, - {31, 0x02, 89}, - {41, 0x02, 89}, - {56, 0x03, 89}, + {0x8003, 87}, + {0x8006, 87}, + {0x800a, 87}, + {0x800f, 87}, + {0x8018, 87}, + {0x801f, 87}, + {0x8029, 87}, + {0xc038, 87}, + {0x8003, 89}, + {0x8006, 89}, + {0x800a, 89}, + {0x800f, 89}, + {0x8018, 89}, + {0x801f, 89}, + {0x8029, 89}, + {0xc038, 89}, }, /* 61 */ { - {2, 0x02, 106}, - {9, 0x02, 106}, - {23, 0x02, 106}, - {40, 0x03, 106}, - {2, 0x02, 107}, - {9, 0x02, 107}, - {23, 0x02, 107}, - {40, 0x03, 107}, - {2, 0x02, 113}, - {9, 0x02, 113}, - {23, 0x02, 113}, - {40, 0x03, 113}, - {2, 0x02, 118}, - {9, 0x02, 118}, - {23, 0x02, 118}, - {40, 0x03, 118}, + {0x8002, 106}, + {0x8009, 106}, + {0x8017, 106}, + {0xc028, 106}, + {0x8002, 107}, + {0x8009, 107}, + {0x8017, 107}, + {0xc028, 107}, + {0x8002, 113}, + {0x8009, 113}, + {0x8017, 113}, + {0xc028, 113}, + {0x8002, 118}, + {0x8009, 118}, + {0x8017, 118}, + {0xc028, 118}, }, /* 62 */ { - {3, 0x02, 106}, - {6, 0x02, 106}, - {10, 0x02, 106}, - {15, 0x02, 106}, - {24, 0x02, 106}, - {31, 0x02, 106}, - {41, 0x02, 106}, - {56, 0x03, 106}, - {3, 0x02, 107}, - {6, 0x02, 107}, - {10, 0x02, 107}, - {15, 0x02, 107}, - {24, 0x02, 107}, - {31, 0x02, 107}, - {41, 0x02, 107}, - {56, 0x03, 107}, + {0x8003, 106}, + {0x8006, 106}, + {0x800a, 106}, + {0x800f, 106}, + {0x8018, 106}, + {0x801f, 106}, + {0x8029, 106}, + {0xc038, 106}, + {0x8003, 107}, + {0x8006, 107}, + {0x800a, 107}, + {0x800f, 107}, + {0x8018, 107}, + {0x801f, 107}, + {0x8029, 107}, + {0xc038, 107}, }, /* 63 */ { - {3, 0x02, 113}, - {6, 0x02, 113}, - {10, 0x02, 113}, - {15, 0x02, 113}, - {24, 0x02, 113}, - {31, 0x02, 113}, - {41, 0x02, 113}, - {56, 0x03, 113}, - {3, 0x02, 118}, - {6, 0x02, 118}, - {10, 0x02, 118}, - {15, 0x02, 118}, - {24, 0x02, 118}, - {31, 0x02, 118}, - {41, 0x02, 118}, - {56, 0x03, 118}, + {0x8003, 113}, + {0x8006, 113}, + {0x800a, 113}, + {0x800f, 113}, + {0x8018, 113}, + {0x801f, 113}, + {0x8029, 113}, + {0xc038, 113}, + {0x8003, 118}, + {0x8006, 118}, + {0x800a, 118}, + {0x800f, 118}, + {0x8018, 118}, + {0x801f, 118}, + {0x8029, 118}, + {0xc038, 118}, }, /* 64 */ { - {1, 0x02, 119}, - {22, 0x03, 119}, - {1, 0x02, 120}, - {22, 0x03, 120}, - {1, 0x02, 121}, - {22, 0x03, 121}, - {1, 0x02, 122}, - {22, 0x03, 122}, - {0, 0x03, 38}, - {0, 0x03, 42}, - {0, 0x03, 44}, - {0, 0x03, 59}, - {0, 0x03, 88}, - {0, 0x03, 90}, - {75, 0x00, 0}, - {78, 0x00, 0}, + {0x8001, 119}, + {0xc016, 119}, + {0x8001, 120}, + {0xc016, 120}, + {0x8001, 121}, + {0xc016, 121}, + {0x8001, 122}, + {0xc016, 122}, + {0xc000, 38}, + {0xc000, 42}, + {0xc000, 44}, + {0xc000, 59}, + {0xc000, 88}, + {0xc000, 90}, + {0x4b, 0}, + {0x4e, 0}, }, /* 65 */ { - {2, 0x02, 119}, - {9, 0x02, 119}, - {23, 0x02, 119}, - {40, 0x03, 119}, - {2, 0x02, 120}, - {9, 0x02, 120}, - {23, 0x02, 120}, - {40, 0x03, 120}, - {2, 0x02, 121}, - {9, 0x02, 121}, - {23, 0x02, 121}, - {40, 0x03, 121}, - {2, 0x02, 122}, - {9, 0x02, 122}, - {23, 0x02, 122}, - {40, 0x03, 122}, + {0x8002, 119}, + {0x8009, 119}, + {0x8017, 119}, + {0xc028, 119}, + {0x8002, 120}, + {0x8009, 120}, + {0x8017, 120}, + {0xc028, 120}, + {0x8002, 121}, + {0x8009, 121}, + {0x8017, 121}, + {0xc028, 121}, + {0x8002, 122}, + {0x8009, 122}, + {0x8017, 122}, + {0xc028, 122}, }, /* 66 */ { - {3, 0x02, 119}, - {6, 0x02, 119}, - {10, 0x02, 119}, - {15, 0x02, 119}, - {24, 0x02, 119}, - {31, 0x02, 119}, - {41, 0x02, 119}, - {56, 0x03, 119}, - {3, 0x02, 120}, - {6, 0x02, 120}, - {10, 0x02, 120}, - {15, 0x02, 120}, - {24, 0x02, 120}, - {31, 0x02, 120}, - {41, 0x02, 120}, - {56, 0x03, 120}, + {0x8003, 119}, + {0x8006, 119}, + {0x800a, 119}, + {0x800f, 119}, + {0x8018, 119}, + {0x801f, 119}, + {0x8029, 119}, + {0xc038, 119}, + {0x8003, 120}, + {0x8006, 120}, + {0x800a, 120}, + {0x800f, 120}, + {0x8018, 120}, + {0x801f, 120}, + {0x8029, 120}, + {0xc038, 120}, }, /* 67 */ { - {3, 0x02, 121}, - {6, 0x02, 121}, - {10, 0x02, 121}, - {15, 0x02, 121}, - {24, 0x02, 121}, - {31, 0x02, 121}, - {41, 0x02, 121}, - {56, 0x03, 121}, - {3, 0x02, 122}, - {6, 0x02, 122}, - {10, 0x02, 122}, - {15, 0x02, 122}, - {24, 0x02, 122}, - {31, 0x02, 122}, - {41, 0x02, 122}, - {56, 0x03, 122}, + {0x8003, 121}, + {0x8006, 121}, + {0x800a, 121}, + {0x800f, 121}, + {0x8018, 121}, + {0x801f, 121}, + {0x8029, 121}, + {0xc038, 121}, + {0x8003, 122}, + {0x8006, 122}, + {0x800a, 122}, + {0x800f, 122}, + {0x8018, 122}, + {0x801f, 122}, + {0x8029, 122}, + {0xc038, 122}, }, /* 68 */ { - {1, 0x02, 38}, - {22, 0x03, 38}, - {1, 0x02, 42}, - {22, 0x03, 42}, - {1, 0x02, 44}, - {22, 0x03, 44}, - {1, 0x02, 59}, - {22, 0x03, 59}, - {1, 0x02, 88}, - {22, 0x03, 88}, - {1, 0x02, 90}, - {22, 0x03, 90}, - {76, 0x00, 0}, - {77, 0x00, 0}, - {79, 0x00, 0}, - {81, 0x00, 0}, + {0x8001, 38}, + {0xc016, 38}, + {0x8001, 42}, + {0xc016, 42}, + {0x8001, 44}, + {0xc016, 44}, + {0x8001, 59}, + {0xc016, 59}, + {0x8001, 88}, + {0xc016, 88}, + {0x8001, 90}, + {0xc016, 90}, + {0x4c, 0}, + {0x4d, 0}, + {0x4f, 0}, + {0x51, 0}, }, /* 69 */ { - {2, 0x02, 38}, - {9, 0x02, 38}, - {23, 0x02, 38}, - {40, 0x03, 38}, - {2, 0x02, 42}, - {9, 0x02, 42}, - {23, 0x02, 42}, - {40, 0x03, 42}, - {2, 0x02, 44}, - {9, 0x02, 44}, - {23, 0x02, 44}, - {40, 0x03, 44}, - {2, 0x02, 59}, - {9, 0x02, 59}, - {23, 0x02, 59}, - {40, 0x03, 59}, + {0x8002, 38}, + {0x8009, 38}, + {0x8017, 38}, + {0xc028, 38}, + {0x8002, 42}, + {0x8009, 42}, + {0x8017, 42}, + {0xc028, 42}, + {0x8002, 44}, + {0x8009, 44}, + {0x8017, 44}, + {0xc028, 44}, + {0x8002, 59}, + {0x8009, 59}, + {0x8017, 59}, + {0xc028, 59}, }, /* 70 */ { - {3, 0x02, 38}, - {6, 0x02, 38}, - {10, 0x02, 38}, - {15, 0x02, 38}, - {24, 0x02, 38}, - {31, 0x02, 38}, - {41, 0x02, 38}, - {56, 0x03, 38}, - {3, 0x02, 42}, - {6, 0x02, 42}, - {10, 0x02, 42}, - {15, 0x02, 42}, - {24, 0x02, 42}, - {31, 0x02, 42}, - {41, 0x02, 42}, - {56, 0x03, 42}, + {0x8003, 38}, + {0x8006, 38}, + {0x800a, 38}, + {0x800f, 38}, + {0x8018, 38}, + {0x801f, 38}, + {0x8029, 38}, + {0xc038, 38}, + {0x8003, 42}, + {0x8006, 42}, + {0x800a, 42}, + {0x800f, 42}, + {0x8018, 42}, + {0x801f, 42}, + {0x8029, 42}, + {0xc038, 42}, }, /* 71 */ { - {3, 0x02, 44}, - {6, 0x02, 44}, - {10, 0x02, 44}, - {15, 0x02, 44}, - {24, 0x02, 44}, - {31, 0x02, 44}, - {41, 0x02, 44}, - {56, 0x03, 44}, - {3, 0x02, 59}, - {6, 0x02, 59}, - {10, 0x02, 59}, - {15, 0x02, 59}, - {24, 0x02, 59}, - {31, 0x02, 59}, - {41, 0x02, 59}, - {56, 0x03, 59}, + {0x8003, 44}, + {0x8006, 44}, + {0x800a, 44}, + {0x800f, 44}, + {0x8018, 44}, + {0x801f, 44}, + {0x8029, 44}, + {0xc038, 44}, + {0x8003, 59}, + {0x8006, 59}, + {0x800a, 59}, + {0x800f, 59}, + {0x8018, 59}, + {0x801f, 59}, + {0x8029, 59}, + {0xc038, 59}, }, /* 72 */ { - {2, 0x02, 88}, - {9, 0x02, 88}, - {23, 0x02, 88}, - {40, 0x03, 88}, - {2, 0x02, 90}, - {9, 0x02, 90}, - {23, 0x02, 90}, - {40, 0x03, 90}, - {0, 0x03, 33}, - {0, 0x03, 34}, - {0, 0x03, 40}, - {0, 0x03, 41}, - {0, 0x03, 63}, - {80, 0x00, 0}, - {82, 0x00, 0}, - {84, 0x00, 0}, + {0x8002, 88}, + {0x8009, 88}, + {0x8017, 88}, + {0xc028, 88}, + {0x8002, 90}, + {0x8009, 90}, + {0x8017, 90}, + {0xc028, 90}, + {0xc000, 33}, + {0xc000, 34}, + {0xc000, 40}, + {0xc000, 41}, + {0xc000, 63}, + {0x50, 0}, + {0x52, 0}, + {0x54, 0}, }, /* 73 */ { - {3, 0x02, 88}, - {6, 0x02, 88}, - {10, 0x02, 88}, - {15, 0x02, 88}, - {24, 0x02, 88}, - {31, 0x02, 88}, - {41, 0x02, 88}, - {56, 0x03, 88}, - {3, 0x02, 90}, - {6, 0x02, 90}, - {10, 0x02, 90}, - {15, 0x02, 90}, - {24, 0x02, 90}, - {31, 0x02, 90}, - {41, 0x02, 90}, - {56, 0x03, 90}, + {0x8003, 88}, + {0x8006, 88}, + {0x800a, 88}, + {0x800f, 88}, + {0x8018, 88}, + {0x801f, 88}, + {0x8029, 88}, + {0xc038, 88}, + {0x8003, 90}, + {0x8006, 90}, + {0x800a, 90}, + {0x800f, 90}, + {0x8018, 90}, + {0x801f, 90}, + {0x8029, 90}, + {0xc038, 90}, }, /* 74 */ { - {1, 0x02, 33}, - {22, 0x03, 33}, - {1, 0x02, 34}, - {22, 0x03, 34}, - {1, 0x02, 40}, - {22, 0x03, 40}, - {1, 0x02, 41}, - {22, 0x03, 41}, - {1, 0x02, 63}, - {22, 0x03, 63}, - {0, 0x03, 39}, - {0, 0x03, 43}, - {0, 0x03, 124}, - {83, 0x00, 0}, - {85, 0x00, 0}, - {88, 0x00, 0}, + {0x8001, 33}, + {0xc016, 33}, + {0x8001, 34}, + {0xc016, 34}, + {0x8001, 40}, + {0xc016, 40}, + {0x8001, 41}, + {0xc016, 41}, + {0x8001, 63}, + {0xc016, 63}, + {0xc000, 39}, + {0xc000, 43}, + {0xc000, 124}, + {0x53, 0}, + {0x55, 0}, + {0x58, 0}, }, /* 75 */ { - {2, 0x02, 33}, - {9, 0x02, 33}, - {23, 0x02, 33}, - {40, 0x03, 33}, - {2, 0x02, 34}, - {9, 0x02, 34}, - {23, 0x02, 34}, - {40, 0x03, 34}, - {2, 0x02, 40}, - {9, 0x02, 40}, - {23, 0x02, 40}, - {40, 0x03, 40}, - {2, 0x02, 41}, - {9, 0x02, 41}, - {23, 0x02, 41}, - {40, 0x03, 41}, + {0x8002, 33}, + {0x8009, 33}, + {0x8017, 33}, + {0xc028, 33}, + {0x8002, 34}, + {0x8009, 34}, + {0x8017, 34}, + {0xc028, 34}, + {0x8002, 40}, + {0x8009, 40}, + {0x8017, 40}, + {0xc028, 40}, + {0x8002, 41}, + {0x8009, 41}, + {0x8017, 41}, + {0xc028, 41}, }, /* 76 */ { - {3, 0x02, 33}, - {6, 0x02, 33}, - {10, 0x02, 33}, - {15, 0x02, 33}, - {24, 0x02, 33}, - {31, 0x02, 33}, - {41, 0x02, 33}, - {56, 0x03, 33}, - {3, 0x02, 34}, - {6, 0x02, 34}, - {10, 0x02, 34}, - {15, 0x02, 34}, - {24, 0x02, 34}, - {31, 0x02, 34}, - {41, 0x02, 34}, - {56, 0x03, 34}, + {0x8003, 33}, + {0x8006, 33}, + {0x800a, 33}, + {0x800f, 33}, + {0x8018, 33}, + {0x801f, 33}, + {0x8029, 33}, + {0xc038, 33}, + {0x8003, 34}, + {0x8006, 34}, + {0x800a, 34}, + {0x800f, 34}, + {0x8018, 34}, + {0x801f, 34}, + {0x8029, 34}, + {0xc038, 34}, }, /* 77 */ { - {3, 0x02, 40}, - {6, 0x02, 40}, - {10, 0x02, 40}, - {15, 0x02, 40}, - {24, 0x02, 40}, - {31, 0x02, 40}, - {41, 0x02, 40}, - {56, 0x03, 40}, - {3, 0x02, 41}, - {6, 0x02, 41}, - {10, 0x02, 41}, - {15, 0x02, 41}, - {24, 0x02, 41}, - {31, 0x02, 41}, - {41, 0x02, 41}, - {56, 0x03, 41}, + {0x8003, 40}, + {0x8006, 40}, + {0x800a, 40}, + {0x800f, 40}, + {0x8018, 40}, + {0x801f, 40}, + {0x8029, 40}, + {0xc038, 40}, + {0x8003, 41}, + {0x8006, 41}, + {0x800a, 41}, + {0x800f, 41}, + {0x8018, 41}, + {0x801f, 41}, + {0x8029, 41}, + {0xc038, 41}, }, /* 78 */ { - {2, 0x02, 63}, - {9, 0x02, 63}, - {23, 0x02, 63}, - {40, 0x03, 63}, - {1, 0x02, 39}, - {22, 0x03, 39}, - {1, 0x02, 43}, - {22, 0x03, 43}, - {1, 0x02, 124}, - {22, 0x03, 124}, - {0, 0x03, 35}, - {0, 0x03, 62}, - {86, 0x00, 0}, - {87, 0x00, 0}, - {89, 0x00, 0}, - {90, 0x00, 0}, + {0x8002, 63}, + {0x8009, 63}, + {0x8017, 63}, + {0xc028, 63}, + {0x8001, 39}, + {0xc016, 39}, + {0x8001, 43}, + {0xc016, 43}, + {0x8001, 124}, + {0xc016, 124}, + {0xc000, 35}, + {0xc000, 62}, + {0x56, 0}, + {0x57, 0}, + {0x59, 0}, + {0x5a, 0}, }, /* 79 */ { - {3, 0x02, 63}, - {6, 0x02, 63}, - {10, 0x02, 63}, - {15, 0x02, 63}, - {24, 0x02, 63}, - {31, 0x02, 63}, - {41, 0x02, 63}, - {56, 0x03, 63}, - {2, 0x02, 39}, - {9, 0x02, 39}, - {23, 0x02, 39}, - {40, 0x03, 39}, - {2, 0x02, 43}, - {9, 0x02, 43}, - {23, 0x02, 43}, - {40, 0x03, 43}, + {0x8003, 63}, + {0x8006, 63}, + {0x800a, 63}, + {0x800f, 63}, + {0x8018, 63}, + {0x801f, 63}, + {0x8029, 63}, + {0xc038, 63}, + {0x8002, 39}, + {0x8009, 39}, + {0x8017, 39}, + {0xc028, 39}, + {0x8002, 43}, + {0x8009, 43}, + {0x8017, 43}, + {0xc028, 43}, }, /* 80 */ { - {3, 0x02, 39}, - {6, 0x02, 39}, - {10, 0x02, 39}, - {15, 0x02, 39}, - {24, 0x02, 39}, - {31, 0x02, 39}, - {41, 0x02, 39}, - {56, 0x03, 39}, - {3, 0x02, 43}, - {6, 0x02, 43}, - {10, 0x02, 43}, - {15, 0x02, 43}, - {24, 0x02, 43}, - {31, 0x02, 43}, - {41, 0x02, 43}, - {56, 0x03, 43}, + {0x8003, 39}, + {0x8006, 39}, + {0x800a, 39}, + {0x800f, 39}, + {0x8018, 39}, + {0x801f, 39}, + {0x8029, 39}, + {0xc038, 39}, + {0x8003, 43}, + {0x8006, 43}, + {0x800a, 43}, + {0x800f, 43}, + {0x8018, 43}, + {0x801f, 43}, + {0x8029, 43}, + {0xc038, 43}, }, /* 81 */ { - {2, 0x02, 124}, - {9, 0x02, 124}, - {23, 0x02, 124}, - {40, 0x03, 124}, - {1, 0x02, 35}, - {22, 0x03, 35}, - {1, 0x02, 62}, - {22, 0x03, 62}, - {0, 0x03, 0}, - {0, 0x03, 36}, - {0, 0x03, 64}, - {0, 0x03, 91}, - {0, 0x03, 93}, - {0, 0x03, 126}, - {91, 0x00, 0}, - {92, 0x00, 0}, + {0x8002, 124}, + {0x8009, 124}, + {0x8017, 124}, + {0xc028, 124}, + {0x8001, 35}, + {0xc016, 35}, + {0x8001, 62}, + {0xc016, 62}, + {0xc000, 0}, + {0xc000, 36}, + {0xc000, 64}, + {0xc000, 91}, + {0xc000, 93}, + {0xc000, 126}, + {0x5b, 0}, + {0x5c, 0}, }, /* 82 */ { - {3, 0x02, 124}, - {6, 0x02, 124}, - {10, 0x02, 124}, - {15, 0x02, 124}, - {24, 0x02, 124}, - {31, 0x02, 124}, - {41, 0x02, 124}, - {56, 0x03, 124}, - {2, 0x02, 35}, - {9, 0x02, 35}, - {23, 0x02, 35}, - {40, 0x03, 35}, - {2, 0x02, 62}, - {9, 0x02, 62}, - {23, 0x02, 62}, - {40, 0x03, 62}, + {0x8003, 124}, + {0x8006, 124}, + {0x800a, 124}, + {0x800f, 124}, + {0x8018, 124}, + {0x801f, 124}, + {0x8029, 124}, + {0xc038, 124}, + {0x8002, 35}, + {0x8009, 35}, + {0x8017, 35}, + {0xc028, 35}, + {0x8002, 62}, + {0x8009, 62}, + {0x8017, 62}, + {0xc028, 62}, }, /* 83 */ { - {3, 0x02, 35}, - {6, 0x02, 35}, - {10, 0x02, 35}, - {15, 0x02, 35}, - {24, 0x02, 35}, - {31, 0x02, 35}, - {41, 0x02, 35}, - {56, 0x03, 35}, - {3, 0x02, 62}, - {6, 0x02, 62}, - {10, 0x02, 62}, - {15, 0x02, 62}, - {24, 0x02, 62}, - {31, 0x02, 62}, - {41, 0x02, 62}, - {56, 0x03, 62}, + {0x8003, 35}, + {0x8006, 35}, + {0x800a, 35}, + {0x800f, 35}, + {0x8018, 35}, + {0x801f, 35}, + {0x8029, 35}, + {0xc038, 35}, + {0x8003, 62}, + {0x8006, 62}, + {0x800a, 62}, + {0x800f, 62}, + {0x8018, 62}, + {0x801f, 62}, + {0x8029, 62}, + {0xc038, 62}, }, /* 84 */ { - {1, 0x02, 0}, - {22, 0x03, 0}, - {1, 0x02, 36}, - {22, 0x03, 36}, - {1, 0x02, 64}, - {22, 0x03, 64}, - {1, 0x02, 91}, - {22, 0x03, 91}, - {1, 0x02, 93}, - {22, 0x03, 93}, - {1, 0x02, 126}, - {22, 0x03, 126}, - {0, 0x03, 94}, - {0, 0x03, 125}, - {93, 0x00, 0}, - {94, 0x00, 0}, + {0x8001, 0}, + {0xc016, 0}, + {0x8001, 36}, + {0xc016, 36}, + {0x8001, 64}, + {0xc016, 64}, + {0x8001, 91}, + {0xc016, 91}, + {0x8001, 93}, + {0xc016, 93}, + {0x8001, 126}, + {0xc016, 126}, + {0xc000, 94}, + {0xc000, 125}, + {0x5d, 0}, + {0x5e, 0}, }, /* 85 */ { - {2, 0x02, 0}, - {9, 0x02, 0}, - {23, 0x02, 0}, - {40, 0x03, 0}, - {2, 0x02, 36}, - {9, 0x02, 36}, - {23, 0x02, 36}, - {40, 0x03, 36}, - {2, 0x02, 64}, - {9, 0x02, 64}, - {23, 0x02, 64}, - {40, 0x03, 64}, - {2, 0x02, 91}, - {9, 0x02, 91}, - {23, 0x02, 91}, - {40, 0x03, 91}, + {0x8002, 0}, + {0x8009, 0}, + {0x8017, 0}, + {0xc028, 0}, + {0x8002, 36}, + {0x8009, 36}, + {0x8017, 36}, + {0xc028, 36}, + {0x8002, 64}, + {0x8009, 64}, + {0x8017, 64}, + {0xc028, 64}, + {0x8002, 91}, + {0x8009, 91}, + {0x8017, 91}, + {0xc028, 91}, }, /* 86 */ { - {3, 0x02, 0}, - {6, 0x02, 0}, - {10, 0x02, 0}, - {15, 0x02, 0}, - {24, 0x02, 0}, - {31, 0x02, 0}, - {41, 0x02, 0}, - {56, 0x03, 0}, - {3, 0x02, 36}, - {6, 0x02, 36}, - {10, 0x02, 36}, - {15, 0x02, 36}, - {24, 0x02, 36}, - {31, 0x02, 36}, - {41, 0x02, 36}, - {56, 0x03, 36}, + {0x8003, 0}, + {0x8006, 0}, + {0x800a, 0}, + {0x800f, 0}, + {0x8018, 0}, + {0x801f, 0}, + {0x8029, 0}, + {0xc038, 0}, + {0x8003, 36}, + {0x8006, 36}, + {0x800a, 36}, + {0x800f, 36}, + {0x8018, 36}, + {0x801f, 36}, + {0x8029, 36}, + {0xc038, 36}, }, /* 87 */ { - {3, 0x02, 64}, - {6, 0x02, 64}, - {10, 0x02, 64}, - {15, 0x02, 64}, - {24, 0x02, 64}, - {31, 0x02, 64}, - {41, 0x02, 64}, - {56, 0x03, 64}, - {3, 0x02, 91}, - {6, 0x02, 91}, - {10, 0x02, 91}, - {15, 0x02, 91}, - {24, 0x02, 91}, - {31, 0x02, 91}, - {41, 0x02, 91}, - {56, 0x03, 91}, + {0x8003, 64}, + {0x8006, 64}, + {0x800a, 64}, + {0x800f, 64}, + {0x8018, 64}, + {0x801f, 64}, + {0x8029, 64}, + {0xc038, 64}, + {0x8003, 91}, + {0x8006, 91}, + {0x800a, 91}, + {0x800f, 91}, + {0x8018, 91}, + {0x801f, 91}, + {0x8029, 91}, + {0xc038, 91}, }, /* 88 */ { - {2, 0x02, 93}, - {9, 0x02, 93}, - {23, 0x02, 93}, - {40, 0x03, 93}, - {2, 0x02, 126}, - {9, 0x02, 126}, - {23, 0x02, 126}, - {40, 0x03, 126}, - {1, 0x02, 94}, - {22, 0x03, 94}, - {1, 0x02, 125}, - {22, 0x03, 125}, - {0, 0x03, 60}, - {0, 0x03, 96}, - {0, 0x03, 123}, - {95, 0x00, 0}, + {0x8002, 93}, + {0x8009, 93}, + {0x8017, 93}, + {0xc028, 93}, + {0x8002, 126}, + {0x8009, 126}, + {0x8017, 126}, + {0xc028, 126}, + {0x8001, 94}, + {0xc016, 94}, + {0x8001, 125}, + {0xc016, 125}, + {0xc000, 60}, + {0xc000, 96}, + {0xc000, 123}, + {0x5f, 0}, }, /* 89 */ { - {3, 0x02, 93}, - {6, 0x02, 93}, - {10, 0x02, 93}, - {15, 0x02, 93}, - {24, 0x02, 93}, - {31, 0x02, 93}, - {41, 0x02, 93}, - {56, 0x03, 93}, - {3, 0x02, 126}, - {6, 0x02, 126}, - {10, 0x02, 126}, - {15, 0x02, 126}, - {24, 0x02, 126}, - {31, 0x02, 126}, - {41, 0x02, 126}, - {56, 0x03, 126}, + {0x8003, 93}, + {0x8006, 93}, + {0x800a, 93}, + {0x800f, 93}, + {0x8018, 93}, + {0x801f, 93}, + {0x8029, 93}, + {0xc038, 93}, + {0x8003, 126}, + {0x8006, 126}, + {0x800a, 126}, + {0x800f, 126}, + {0x8018, 126}, + {0x801f, 126}, + {0x8029, 126}, + {0xc038, 126}, }, /* 90 */ { - {2, 0x02, 94}, - {9, 0x02, 94}, - {23, 0x02, 94}, - {40, 0x03, 94}, - {2, 0x02, 125}, - {9, 0x02, 125}, - {23, 0x02, 125}, - {40, 0x03, 125}, - {1, 0x02, 60}, - {22, 0x03, 60}, - {1, 0x02, 96}, - {22, 0x03, 96}, - {1, 0x02, 123}, - {22, 0x03, 123}, - {96, 0x00, 0}, - {110, 0x00, 0}, + {0x8002, 94}, + {0x8009, 94}, + {0x8017, 94}, + {0xc028, 94}, + {0x8002, 125}, + {0x8009, 125}, + {0x8017, 125}, + {0xc028, 125}, + {0x8001, 60}, + {0xc016, 60}, + {0x8001, 96}, + {0xc016, 96}, + {0x8001, 123}, + {0xc016, 123}, + {0x60, 0}, + {0x6e, 0}, }, /* 91 */ { - {3, 0x02, 94}, - {6, 0x02, 94}, - {10, 0x02, 94}, - {15, 0x02, 94}, - {24, 0x02, 94}, - {31, 0x02, 94}, - {41, 0x02, 94}, - {56, 0x03, 94}, - {3, 0x02, 125}, - {6, 0x02, 125}, - {10, 0x02, 125}, - {15, 0x02, 125}, - {24, 0x02, 125}, - {31, 0x02, 125}, - {41, 0x02, 125}, - {56, 0x03, 125}, + {0x8003, 94}, + {0x8006, 94}, + {0x800a, 94}, + {0x800f, 94}, + {0x8018, 94}, + {0x801f, 94}, + {0x8029, 94}, + {0xc038, 94}, + {0x8003, 125}, + {0x8006, 125}, + {0x800a, 125}, + {0x800f, 125}, + {0x8018, 125}, + {0x801f, 125}, + {0x8029, 125}, + {0xc038, 125}, }, /* 92 */ { - {2, 0x02, 60}, - {9, 0x02, 60}, - {23, 0x02, 60}, - {40, 0x03, 60}, - {2, 0x02, 96}, - {9, 0x02, 96}, - {23, 0x02, 96}, - {40, 0x03, 96}, - {2, 0x02, 123}, - {9, 0x02, 123}, - {23, 0x02, 123}, - {40, 0x03, 123}, - {97, 0x00, 0}, - {101, 0x00, 0}, - {111, 0x00, 0}, - {133, 0x00, 0}, + {0x8002, 60}, + {0x8009, 60}, + {0x8017, 60}, + {0xc028, 60}, + {0x8002, 96}, + {0x8009, 96}, + {0x8017, 96}, + {0xc028, 96}, + {0x8002, 123}, + {0x8009, 123}, + {0x8017, 123}, + {0xc028, 123}, + {0x61, 0}, + {0x65, 0}, + {0x6f, 0}, + {0x85, 0}, }, /* 93 */ { - {3, 0x02, 60}, - {6, 0x02, 60}, - {10, 0x02, 60}, - {15, 0x02, 60}, - {24, 0x02, 60}, - {31, 0x02, 60}, - {41, 0x02, 60}, - {56, 0x03, 60}, - {3, 0x02, 96}, - {6, 0x02, 96}, - {10, 0x02, 96}, - {15, 0x02, 96}, - {24, 0x02, 96}, - {31, 0x02, 96}, - {41, 0x02, 96}, - {56, 0x03, 96}, + {0x8003, 60}, + {0x8006, 60}, + {0x800a, 60}, + {0x800f, 60}, + {0x8018, 60}, + {0x801f, 60}, + {0x8029, 60}, + {0xc038, 60}, + {0x8003, 96}, + {0x8006, 96}, + {0x800a, 96}, + {0x800f, 96}, + {0x8018, 96}, + {0x801f, 96}, + {0x8029, 96}, + {0xc038, 96}, }, /* 94 */ { - {3, 0x02, 123}, - {6, 0x02, 123}, - {10, 0x02, 123}, - {15, 0x02, 123}, - {24, 0x02, 123}, - {31, 0x02, 123}, - {41, 0x02, 123}, - {56, 0x03, 123}, - {98, 0x00, 0}, - {99, 0x00, 0}, - {102, 0x00, 0}, - {105, 0x00, 0}, - {112, 0x00, 0}, - {119, 0x00, 0}, - {134, 0x00, 0}, - {153, 0x00, 0}, + {0x8003, 123}, + {0x8006, 123}, + {0x800a, 123}, + {0x800f, 123}, + {0x8018, 123}, + {0x801f, 123}, + {0x8029, 123}, + {0xc038, 123}, + {0x62, 0}, + {0x63, 0}, + {0x66, 0}, + {0x69, 0}, + {0x70, 0}, + {0x77, 0}, + {0x86, 0}, + {0x99, 0}, }, /* 95 */ { - {0, 0x03, 92}, - {0, 0x03, 195}, - {0, 0x03, 208}, - {100, 0x00, 0}, - {103, 0x00, 0}, - {104, 0x00, 0}, - {106, 0x00, 0}, - {107, 0x00, 0}, - {113, 0x00, 0}, - {116, 0x00, 0}, - {120, 0x00, 0}, - {126, 0x00, 0}, - {135, 0x00, 0}, - {142, 0x00, 0}, - {154, 0x00, 0}, - {169, 0x00, 0}, + {0xc000, 92}, + {0xc000, 195}, + {0xc000, 208}, + {0x64, 0}, + {0x67, 0}, + {0x68, 0}, + {0x6a, 0}, + {0x6b, 0}, + {0x71, 0}, + {0x74, 0}, + {0x78, 0}, + {0x7e, 0}, + {0x87, 0}, + {0x8e, 0}, + {0x9a, 0}, + {0xa9, 0}, }, /* 96 */ { - {1, 0x02, 92}, - {22, 0x03, 92}, - {1, 0x02, 195}, - {22, 0x03, 195}, - {1, 0x02, 208}, - {22, 0x03, 208}, - {0, 0x03, 128}, - {0, 0x03, 130}, - {0, 0x03, 131}, - {0, 0x03, 162}, - {0, 0x03, 184}, - {0, 0x03, 194}, - {0, 0x03, 224}, - {0, 0x03, 226}, - {108, 0x00, 0}, - {109, 0x00, 0}, + {0x8001, 92}, + {0xc016, 92}, + {0x8001, 195}, + {0xc016, 195}, + {0x8001, 208}, + {0xc016, 208}, + {0xc000, 128}, + {0xc000, 130}, + {0xc000, 131}, + {0xc000, 162}, + {0xc000, 184}, + {0xc000, 194}, + {0xc000, 224}, + {0xc000, 226}, + {0x6c, 0}, + {0x6d, 0}, }, /* 97 */ { - {2, 0x02, 92}, - {9, 0x02, 92}, - {23, 0x02, 92}, - {40, 0x03, 92}, - {2, 0x02, 195}, - {9, 0x02, 195}, - {23, 0x02, 195}, - {40, 0x03, 195}, - {2, 0x02, 208}, - {9, 0x02, 208}, - {23, 0x02, 208}, - {40, 0x03, 208}, - {1, 0x02, 128}, - {22, 0x03, 128}, - {1, 0x02, 130}, - {22, 0x03, 130}, + {0x8002, 92}, + {0x8009, 92}, + {0x8017, 92}, + {0xc028, 92}, + {0x8002, 195}, + {0x8009, 195}, + {0x8017, 195}, + {0xc028, 195}, + {0x8002, 208}, + {0x8009, 208}, + {0x8017, 208}, + {0xc028, 208}, + {0x8001, 128}, + {0xc016, 128}, + {0x8001, 130}, + {0xc016, 130}, }, /* 98 */ { - {3, 0x02, 92}, - {6, 0x02, 92}, - {10, 0x02, 92}, - {15, 0x02, 92}, - {24, 0x02, 92}, - {31, 0x02, 92}, - {41, 0x02, 92}, - {56, 0x03, 92}, - {3, 0x02, 195}, - {6, 0x02, 195}, - {10, 0x02, 195}, - {15, 0x02, 195}, - {24, 0x02, 195}, - {31, 0x02, 195}, - {41, 0x02, 195}, - {56, 0x03, 195}, + {0x8003, 92}, + {0x8006, 92}, + {0x800a, 92}, + {0x800f, 92}, + {0x8018, 92}, + {0x801f, 92}, + {0x8029, 92}, + {0xc038, 92}, + {0x8003, 195}, + {0x8006, 195}, + {0x800a, 195}, + {0x800f, 195}, + {0x8018, 195}, + {0x801f, 195}, + {0x8029, 195}, + {0xc038, 195}, }, /* 99 */ { - {3, 0x02, 208}, - {6, 0x02, 208}, - {10, 0x02, 208}, - {15, 0x02, 208}, - {24, 0x02, 208}, - {31, 0x02, 208}, - {41, 0x02, 208}, - {56, 0x03, 208}, - {2, 0x02, 128}, - {9, 0x02, 128}, - {23, 0x02, 128}, - {40, 0x03, 128}, - {2, 0x02, 130}, - {9, 0x02, 130}, - {23, 0x02, 130}, - {40, 0x03, 130}, + {0x8003, 208}, + {0x8006, 208}, + {0x800a, 208}, + {0x800f, 208}, + {0x8018, 208}, + {0x801f, 208}, + {0x8029, 208}, + {0xc038, 208}, + {0x8002, 128}, + {0x8009, 128}, + {0x8017, 128}, + {0xc028, 128}, + {0x8002, 130}, + {0x8009, 130}, + {0x8017, 130}, + {0xc028, 130}, }, /* 100 */ { - {3, 0x02, 128}, - {6, 0x02, 128}, - {10, 0x02, 128}, - {15, 0x02, 128}, - {24, 0x02, 128}, - {31, 0x02, 128}, - {41, 0x02, 128}, - {56, 0x03, 128}, - {3, 0x02, 130}, - {6, 0x02, 130}, - {10, 0x02, 130}, - {15, 0x02, 130}, - {24, 0x02, 130}, - {31, 0x02, 130}, - {41, 0x02, 130}, - {56, 0x03, 130}, + {0x8003, 128}, + {0x8006, 128}, + {0x800a, 128}, + {0x800f, 128}, + {0x8018, 128}, + {0x801f, 128}, + {0x8029, 128}, + {0xc038, 128}, + {0x8003, 130}, + {0x8006, 130}, + {0x800a, 130}, + {0x800f, 130}, + {0x8018, 130}, + {0x801f, 130}, + {0x8029, 130}, + {0xc038, 130}, }, /* 101 */ { - {1, 0x02, 131}, - {22, 0x03, 131}, - {1, 0x02, 162}, - {22, 0x03, 162}, - {1, 0x02, 184}, - {22, 0x03, 184}, - {1, 0x02, 194}, - {22, 0x03, 194}, - {1, 0x02, 224}, - {22, 0x03, 224}, - {1, 0x02, 226}, - {22, 0x03, 226}, - {0, 0x03, 153}, - {0, 0x03, 161}, - {0, 0x03, 167}, - {0, 0x03, 172}, + {0x8001, 131}, + {0xc016, 131}, + {0x8001, 162}, + {0xc016, 162}, + {0x8001, 184}, + {0xc016, 184}, + {0x8001, 194}, + {0xc016, 194}, + {0x8001, 224}, + {0xc016, 224}, + {0x8001, 226}, + {0xc016, 226}, + {0xc000, 153}, + {0xc000, 161}, + {0xc000, 167}, + {0xc000, 172}, }, /* 102 */ { - {2, 0x02, 131}, - {9, 0x02, 131}, - {23, 0x02, 131}, - {40, 0x03, 131}, - {2, 0x02, 162}, - {9, 0x02, 162}, - {23, 0x02, 162}, - {40, 0x03, 162}, - {2, 0x02, 184}, - {9, 0x02, 184}, - {23, 0x02, 184}, - {40, 0x03, 184}, - {2, 0x02, 194}, - {9, 0x02, 194}, - {23, 0x02, 194}, - {40, 0x03, 194}, + {0x8002, 131}, + {0x8009, 131}, + {0x8017, 131}, + {0xc028, 131}, + {0x8002, 162}, + {0x8009, 162}, + {0x8017, 162}, + {0xc028, 162}, + {0x8002, 184}, + {0x8009, 184}, + {0x8017, 184}, + {0xc028, 184}, + {0x8002, 194}, + {0x8009, 194}, + {0x8017, 194}, + {0xc028, 194}, }, /* 103 */ { - {3, 0x02, 131}, - {6, 0x02, 131}, - {10, 0x02, 131}, - {15, 0x02, 131}, - {24, 0x02, 131}, - {31, 0x02, 131}, - {41, 0x02, 131}, - {56, 0x03, 131}, - {3, 0x02, 162}, - {6, 0x02, 162}, - {10, 0x02, 162}, - {15, 0x02, 162}, - {24, 0x02, 162}, - {31, 0x02, 162}, - {41, 0x02, 162}, - {56, 0x03, 162}, + {0x8003, 131}, + {0x8006, 131}, + {0x800a, 131}, + {0x800f, 131}, + {0x8018, 131}, + {0x801f, 131}, + {0x8029, 131}, + {0xc038, 131}, + {0x8003, 162}, + {0x8006, 162}, + {0x800a, 162}, + {0x800f, 162}, + {0x8018, 162}, + {0x801f, 162}, + {0x8029, 162}, + {0xc038, 162}, }, /* 104 */ { - {3, 0x02, 184}, - {6, 0x02, 184}, - {10, 0x02, 184}, - {15, 0x02, 184}, - {24, 0x02, 184}, - {31, 0x02, 184}, - {41, 0x02, 184}, - {56, 0x03, 184}, - {3, 0x02, 194}, - {6, 0x02, 194}, - {10, 0x02, 194}, - {15, 0x02, 194}, - {24, 0x02, 194}, - {31, 0x02, 194}, - {41, 0x02, 194}, - {56, 0x03, 194}, + {0x8003, 184}, + {0x8006, 184}, + {0x800a, 184}, + {0x800f, 184}, + {0x8018, 184}, + {0x801f, 184}, + {0x8029, 184}, + {0xc038, 184}, + {0x8003, 194}, + {0x8006, 194}, + {0x800a, 194}, + {0x800f, 194}, + {0x8018, 194}, + {0x801f, 194}, + {0x8029, 194}, + {0xc038, 194}, }, /* 105 */ { - {2, 0x02, 224}, - {9, 0x02, 224}, - {23, 0x02, 224}, - {40, 0x03, 224}, - {2, 0x02, 226}, - {9, 0x02, 226}, - {23, 0x02, 226}, - {40, 0x03, 226}, - {1, 0x02, 153}, - {22, 0x03, 153}, - {1, 0x02, 161}, - {22, 0x03, 161}, - {1, 0x02, 167}, - {22, 0x03, 167}, - {1, 0x02, 172}, - {22, 0x03, 172}, + {0x8002, 224}, + {0x8009, 224}, + {0x8017, 224}, + {0xc028, 224}, + {0x8002, 226}, + {0x8009, 226}, + {0x8017, 226}, + {0xc028, 226}, + {0x8001, 153}, + {0xc016, 153}, + {0x8001, 161}, + {0xc016, 161}, + {0x8001, 167}, + {0xc016, 167}, + {0x8001, 172}, + {0xc016, 172}, }, /* 106 */ { - {3, 0x02, 224}, - {6, 0x02, 224}, - {10, 0x02, 224}, - {15, 0x02, 224}, - {24, 0x02, 224}, - {31, 0x02, 224}, - {41, 0x02, 224}, - {56, 0x03, 224}, - {3, 0x02, 226}, - {6, 0x02, 226}, - {10, 0x02, 226}, - {15, 0x02, 226}, - {24, 0x02, 226}, - {31, 0x02, 226}, - {41, 0x02, 226}, - {56, 0x03, 226}, + {0x8003, 224}, + {0x8006, 224}, + {0x800a, 224}, + {0x800f, 224}, + {0x8018, 224}, + {0x801f, 224}, + {0x8029, 224}, + {0xc038, 224}, + {0x8003, 226}, + {0x8006, 226}, + {0x800a, 226}, + {0x800f, 226}, + {0x8018, 226}, + {0x801f, 226}, + {0x8029, 226}, + {0xc038, 226}, }, /* 107 */ { - {2, 0x02, 153}, - {9, 0x02, 153}, - {23, 0x02, 153}, - {40, 0x03, 153}, - {2, 0x02, 161}, - {9, 0x02, 161}, - {23, 0x02, 161}, - {40, 0x03, 161}, - {2, 0x02, 167}, - {9, 0x02, 167}, - {23, 0x02, 167}, - {40, 0x03, 167}, - {2, 0x02, 172}, - {9, 0x02, 172}, - {23, 0x02, 172}, - {40, 0x03, 172}, + {0x8002, 153}, + {0x8009, 153}, + {0x8017, 153}, + {0xc028, 153}, + {0x8002, 161}, + {0x8009, 161}, + {0x8017, 161}, + {0xc028, 161}, + {0x8002, 167}, + {0x8009, 167}, + {0x8017, 167}, + {0xc028, 167}, + {0x8002, 172}, + {0x8009, 172}, + {0x8017, 172}, + {0xc028, 172}, }, /* 108 */ { - {3, 0x02, 153}, - {6, 0x02, 153}, - {10, 0x02, 153}, - {15, 0x02, 153}, - {24, 0x02, 153}, - {31, 0x02, 153}, - {41, 0x02, 153}, - {56, 0x03, 153}, - {3, 0x02, 161}, - {6, 0x02, 161}, - {10, 0x02, 161}, - {15, 0x02, 161}, - {24, 0x02, 161}, - {31, 0x02, 161}, - {41, 0x02, 161}, - {56, 0x03, 161}, + {0x8003, 153}, + {0x8006, 153}, + {0x800a, 153}, + {0x800f, 153}, + {0x8018, 153}, + {0x801f, 153}, + {0x8029, 153}, + {0xc038, 153}, + {0x8003, 161}, + {0x8006, 161}, + {0x800a, 161}, + {0x800f, 161}, + {0x8018, 161}, + {0x801f, 161}, + {0x8029, 161}, + {0xc038, 161}, }, /* 109 */ { - {3, 0x02, 167}, - {6, 0x02, 167}, - {10, 0x02, 167}, - {15, 0x02, 167}, - {24, 0x02, 167}, - {31, 0x02, 167}, - {41, 0x02, 167}, - {56, 0x03, 167}, - {3, 0x02, 172}, - {6, 0x02, 172}, - {10, 0x02, 172}, - {15, 0x02, 172}, - {24, 0x02, 172}, - {31, 0x02, 172}, - {41, 0x02, 172}, - {56, 0x03, 172}, + {0x8003, 167}, + {0x8006, 167}, + {0x800a, 167}, + {0x800f, 167}, + {0x8018, 167}, + {0x801f, 167}, + {0x8029, 167}, + {0xc038, 167}, + {0x8003, 172}, + {0x8006, 172}, + {0x800a, 172}, + {0x800f, 172}, + {0x8018, 172}, + {0x801f, 172}, + {0x8029, 172}, + {0xc038, 172}, }, /* 110 */ { - {114, 0x00, 0}, - {115, 0x00, 0}, - {117, 0x00, 0}, - {118, 0x00, 0}, - {121, 0x00, 0}, - {123, 0x00, 0}, - {127, 0x00, 0}, - {130, 0x00, 0}, - {136, 0x00, 0}, - {139, 0x00, 0}, - {143, 0x00, 0}, - {146, 0x00, 0}, - {155, 0x00, 0}, - {162, 0x00, 0}, - {170, 0x00, 0}, - {180, 0x00, 0}, + {0x72, 0}, + {0x73, 0}, + {0x75, 0}, + {0x76, 0}, + {0x79, 0}, + {0x7b, 0}, + {0x7f, 0}, + {0x82, 0}, + {0x88, 0}, + {0x8b, 0}, + {0x8f, 0}, + {0x92, 0}, + {0x9b, 0}, + {0xa2, 0}, + {0xaa, 0}, + {0xb4, 0}, }, /* 111 */ { - {0, 0x03, 176}, - {0, 0x03, 177}, - {0, 0x03, 179}, - {0, 0x03, 209}, - {0, 0x03, 216}, - {0, 0x03, 217}, - {0, 0x03, 227}, - {0, 0x03, 229}, - {0, 0x03, 230}, - {122, 0x00, 0}, - {124, 0x00, 0}, - {125, 0x00, 0}, - {128, 0x00, 0}, - {129, 0x00, 0}, - {131, 0x00, 0}, - {132, 0x00, 0}, + {0xc000, 176}, + {0xc000, 177}, + {0xc000, 179}, + {0xc000, 209}, + {0xc000, 216}, + {0xc000, 217}, + {0xc000, 227}, + {0xc000, 229}, + {0xc000, 230}, + {0x7a, 0}, + {0x7c, 0}, + {0x7d, 0}, + {0x80, 0}, + {0x81, 0}, + {0x83, 0}, + {0x84, 0}, }, /* 112 */ { - {1, 0x02, 176}, - {22, 0x03, 176}, - {1, 0x02, 177}, - {22, 0x03, 177}, - {1, 0x02, 179}, - {22, 0x03, 179}, - {1, 0x02, 209}, - {22, 0x03, 209}, - {1, 0x02, 216}, - {22, 0x03, 216}, - {1, 0x02, 217}, - {22, 0x03, 217}, - {1, 0x02, 227}, - {22, 0x03, 227}, - {1, 0x02, 229}, - {22, 0x03, 229}, + {0x8001, 176}, + {0xc016, 176}, + {0x8001, 177}, + {0xc016, 177}, + {0x8001, 179}, + {0xc016, 179}, + {0x8001, 209}, + {0xc016, 209}, + {0x8001, 216}, + {0xc016, 216}, + {0x8001, 217}, + {0xc016, 217}, + {0x8001, 227}, + {0xc016, 227}, + {0x8001, 229}, + {0xc016, 229}, }, /* 113 */ { - {2, 0x02, 176}, - {9, 0x02, 176}, - {23, 0x02, 176}, - {40, 0x03, 176}, - {2, 0x02, 177}, - {9, 0x02, 177}, - {23, 0x02, 177}, - {40, 0x03, 177}, - {2, 0x02, 179}, - {9, 0x02, 179}, - {23, 0x02, 179}, - {40, 0x03, 179}, - {2, 0x02, 209}, - {9, 0x02, 209}, - {23, 0x02, 209}, - {40, 0x03, 209}, + {0x8002, 176}, + {0x8009, 176}, + {0x8017, 176}, + {0xc028, 176}, + {0x8002, 177}, + {0x8009, 177}, + {0x8017, 177}, + {0xc028, 177}, + {0x8002, 179}, + {0x8009, 179}, + {0x8017, 179}, + {0xc028, 179}, + {0x8002, 209}, + {0x8009, 209}, + {0x8017, 209}, + {0xc028, 209}, }, /* 114 */ { - {3, 0x02, 176}, - {6, 0x02, 176}, - {10, 0x02, 176}, - {15, 0x02, 176}, - {24, 0x02, 176}, - {31, 0x02, 176}, - {41, 0x02, 176}, - {56, 0x03, 176}, - {3, 0x02, 177}, - {6, 0x02, 177}, - {10, 0x02, 177}, - {15, 0x02, 177}, - {24, 0x02, 177}, - {31, 0x02, 177}, - {41, 0x02, 177}, - {56, 0x03, 177}, + {0x8003, 176}, + {0x8006, 176}, + {0x800a, 176}, + {0x800f, 176}, + {0x8018, 176}, + {0x801f, 176}, + {0x8029, 176}, + {0xc038, 176}, + {0x8003, 177}, + {0x8006, 177}, + {0x800a, 177}, + {0x800f, 177}, + {0x8018, 177}, + {0x801f, 177}, + {0x8029, 177}, + {0xc038, 177}, }, /* 115 */ { - {3, 0x02, 179}, - {6, 0x02, 179}, - {10, 0x02, 179}, - {15, 0x02, 179}, - {24, 0x02, 179}, - {31, 0x02, 179}, - {41, 0x02, 179}, - {56, 0x03, 179}, - {3, 0x02, 209}, - {6, 0x02, 209}, - {10, 0x02, 209}, - {15, 0x02, 209}, - {24, 0x02, 209}, - {31, 0x02, 209}, - {41, 0x02, 209}, - {56, 0x03, 209}, + {0x8003, 179}, + {0x8006, 179}, + {0x800a, 179}, + {0x800f, 179}, + {0x8018, 179}, + {0x801f, 179}, + {0x8029, 179}, + {0xc038, 179}, + {0x8003, 209}, + {0x8006, 209}, + {0x800a, 209}, + {0x800f, 209}, + {0x8018, 209}, + {0x801f, 209}, + {0x8029, 209}, + {0xc038, 209}, }, /* 116 */ { - {2, 0x02, 216}, - {9, 0x02, 216}, - {23, 0x02, 216}, - {40, 0x03, 216}, - {2, 0x02, 217}, - {9, 0x02, 217}, - {23, 0x02, 217}, - {40, 0x03, 217}, - {2, 0x02, 227}, - {9, 0x02, 227}, - {23, 0x02, 227}, - {40, 0x03, 227}, - {2, 0x02, 229}, - {9, 0x02, 229}, - {23, 0x02, 229}, - {40, 0x03, 229}, + {0x8002, 216}, + {0x8009, 216}, + {0x8017, 216}, + {0xc028, 216}, + {0x8002, 217}, + {0x8009, 217}, + {0x8017, 217}, + {0xc028, 217}, + {0x8002, 227}, + {0x8009, 227}, + {0x8017, 227}, + {0xc028, 227}, + {0x8002, 229}, + {0x8009, 229}, + {0x8017, 229}, + {0xc028, 229}, }, /* 117 */ { - {3, 0x02, 216}, - {6, 0x02, 216}, - {10, 0x02, 216}, - {15, 0x02, 216}, - {24, 0x02, 216}, - {31, 0x02, 216}, - {41, 0x02, 216}, - {56, 0x03, 216}, - {3, 0x02, 217}, - {6, 0x02, 217}, - {10, 0x02, 217}, - {15, 0x02, 217}, - {24, 0x02, 217}, - {31, 0x02, 217}, - {41, 0x02, 217}, - {56, 0x03, 217}, + {0x8003, 216}, + {0x8006, 216}, + {0x800a, 216}, + {0x800f, 216}, + {0x8018, 216}, + {0x801f, 216}, + {0x8029, 216}, + {0xc038, 216}, + {0x8003, 217}, + {0x8006, 217}, + {0x800a, 217}, + {0x800f, 217}, + {0x8018, 217}, + {0x801f, 217}, + {0x8029, 217}, + {0xc038, 217}, }, /* 118 */ { - {3, 0x02, 227}, - {6, 0x02, 227}, - {10, 0x02, 227}, - {15, 0x02, 227}, - {24, 0x02, 227}, - {31, 0x02, 227}, - {41, 0x02, 227}, - {56, 0x03, 227}, - {3, 0x02, 229}, - {6, 0x02, 229}, - {10, 0x02, 229}, - {15, 0x02, 229}, - {24, 0x02, 229}, - {31, 0x02, 229}, - {41, 0x02, 229}, - {56, 0x03, 229}, + {0x8003, 227}, + {0x8006, 227}, + {0x800a, 227}, + {0x800f, 227}, + {0x8018, 227}, + {0x801f, 227}, + {0x8029, 227}, + {0xc038, 227}, + {0x8003, 229}, + {0x8006, 229}, + {0x800a, 229}, + {0x800f, 229}, + {0x8018, 229}, + {0x801f, 229}, + {0x8029, 229}, + {0xc038, 229}, }, /* 119 */ { - {1, 0x02, 230}, - {22, 0x03, 230}, - {0, 0x03, 129}, - {0, 0x03, 132}, - {0, 0x03, 133}, - {0, 0x03, 134}, - {0, 0x03, 136}, - {0, 0x03, 146}, - {0, 0x03, 154}, - {0, 0x03, 156}, - {0, 0x03, 160}, - {0, 0x03, 163}, - {0, 0x03, 164}, - {0, 0x03, 169}, - {0, 0x03, 170}, - {0, 0x03, 173}, + {0x8001, 230}, + {0xc016, 230}, + {0xc000, 129}, + {0xc000, 132}, + {0xc000, 133}, + {0xc000, 134}, + {0xc000, 136}, + {0xc000, 146}, + {0xc000, 154}, + {0xc000, 156}, + {0xc000, 160}, + {0xc000, 163}, + {0xc000, 164}, + {0xc000, 169}, + {0xc000, 170}, + {0xc000, 173}, }, /* 120 */ { - {2, 0x02, 230}, - {9, 0x02, 230}, - {23, 0x02, 230}, - {40, 0x03, 230}, - {1, 0x02, 129}, - {22, 0x03, 129}, - {1, 0x02, 132}, - {22, 0x03, 132}, - {1, 0x02, 133}, - {22, 0x03, 133}, - {1, 0x02, 134}, - {22, 0x03, 134}, - {1, 0x02, 136}, - {22, 0x03, 136}, - {1, 0x02, 146}, - {22, 0x03, 146}, + {0x8002, 230}, + {0x8009, 230}, + {0x8017, 230}, + {0xc028, 230}, + {0x8001, 129}, + {0xc016, 129}, + {0x8001, 132}, + {0xc016, 132}, + {0x8001, 133}, + {0xc016, 133}, + {0x8001, 134}, + {0xc016, 134}, + {0x8001, 136}, + {0xc016, 136}, + {0x8001, 146}, + {0xc016, 146}, }, /* 121 */ { - {3, 0x02, 230}, - {6, 0x02, 230}, - {10, 0x02, 230}, - {15, 0x02, 230}, - {24, 0x02, 230}, - {31, 0x02, 230}, - {41, 0x02, 230}, - {56, 0x03, 230}, - {2, 0x02, 129}, - {9, 0x02, 129}, - {23, 0x02, 129}, - {40, 0x03, 129}, - {2, 0x02, 132}, - {9, 0x02, 132}, - {23, 0x02, 132}, - {40, 0x03, 132}, + {0x8003, 230}, + {0x8006, 230}, + {0x800a, 230}, + {0x800f, 230}, + {0x8018, 230}, + {0x801f, 230}, + {0x8029, 230}, + {0xc038, 230}, + {0x8002, 129}, + {0x8009, 129}, + {0x8017, 129}, + {0xc028, 129}, + {0x8002, 132}, + {0x8009, 132}, + {0x8017, 132}, + {0xc028, 132}, }, /* 122 */ { - {3, 0x02, 129}, - {6, 0x02, 129}, - {10, 0x02, 129}, - {15, 0x02, 129}, - {24, 0x02, 129}, - {31, 0x02, 129}, - {41, 0x02, 129}, - {56, 0x03, 129}, - {3, 0x02, 132}, - {6, 0x02, 132}, - {10, 0x02, 132}, - {15, 0x02, 132}, - {24, 0x02, 132}, - {31, 0x02, 132}, - {41, 0x02, 132}, - {56, 0x03, 132}, + {0x8003, 129}, + {0x8006, 129}, + {0x800a, 129}, + {0x800f, 129}, + {0x8018, 129}, + {0x801f, 129}, + {0x8029, 129}, + {0xc038, 129}, + {0x8003, 132}, + {0x8006, 132}, + {0x800a, 132}, + {0x800f, 132}, + {0x8018, 132}, + {0x801f, 132}, + {0x8029, 132}, + {0xc038, 132}, }, /* 123 */ { - {2, 0x02, 133}, - {9, 0x02, 133}, - {23, 0x02, 133}, - {40, 0x03, 133}, - {2, 0x02, 134}, - {9, 0x02, 134}, - {23, 0x02, 134}, - {40, 0x03, 134}, - {2, 0x02, 136}, - {9, 0x02, 136}, - {23, 0x02, 136}, - {40, 0x03, 136}, - {2, 0x02, 146}, - {9, 0x02, 146}, - {23, 0x02, 146}, - {40, 0x03, 146}, + {0x8002, 133}, + {0x8009, 133}, + {0x8017, 133}, + {0xc028, 133}, + {0x8002, 134}, + {0x8009, 134}, + {0x8017, 134}, + {0xc028, 134}, + {0x8002, 136}, + {0x8009, 136}, + {0x8017, 136}, + {0xc028, 136}, + {0x8002, 146}, + {0x8009, 146}, + {0x8017, 146}, + {0xc028, 146}, }, /* 124 */ { - {3, 0x02, 133}, - {6, 0x02, 133}, - {10, 0x02, 133}, - {15, 0x02, 133}, - {24, 0x02, 133}, - {31, 0x02, 133}, - {41, 0x02, 133}, - {56, 0x03, 133}, - {3, 0x02, 134}, - {6, 0x02, 134}, - {10, 0x02, 134}, - {15, 0x02, 134}, - {24, 0x02, 134}, - {31, 0x02, 134}, - {41, 0x02, 134}, - {56, 0x03, 134}, + {0x8003, 133}, + {0x8006, 133}, + {0x800a, 133}, + {0x800f, 133}, + {0x8018, 133}, + {0x801f, 133}, + {0x8029, 133}, + {0xc038, 133}, + {0x8003, 134}, + {0x8006, 134}, + {0x800a, 134}, + {0x800f, 134}, + {0x8018, 134}, + {0x801f, 134}, + {0x8029, 134}, + {0xc038, 134}, }, /* 125 */ { - {3, 0x02, 136}, - {6, 0x02, 136}, - {10, 0x02, 136}, - {15, 0x02, 136}, - {24, 0x02, 136}, - {31, 0x02, 136}, - {41, 0x02, 136}, - {56, 0x03, 136}, - {3, 0x02, 146}, - {6, 0x02, 146}, - {10, 0x02, 146}, - {15, 0x02, 146}, - {24, 0x02, 146}, - {31, 0x02, 146}, - {41, 0x02, 146}, - {56, 0x03, 146}, + {0x8003, 136}, + {0x8006, 136}, + {0x800a, 136}, + {0x800f, 136}, + {0x8018, 136}, + {0x801f, 136}, + {0x8029, 136}, + {0xc038, 136}, + {0x8003, 146}, + {0x8006, 146}, + {0x800a, 146}, + {0x800f, 146}, + {0x8018, 146}, + {0x801f, 146}, + {0x8029, 146}, + {0xc038, 146}, }, /* 126 */ { - {1, 0x02, 154}, - {22, 0x03, 154}, - {1, 0x02, 156}, - {22, 0x03, 156}, - {1, 0x02, 160}, - {22, 0x03, 160}, - {1, 0x02, 163}, - {22, 0x03, 163}, - {1, 0x02, 164}, - {22, 0x03, 164}, - {1, 0x02, 169}, - {22, 0x03, 169}, - {1, 0x02, 170}, - {22, 0x03, 170}, - {1, 0x02, 173}, - {22, 0x03, 173}, + {0x8001, 154}, + {0xc016, 154}, + {0x8001, 156}, + {0xc016, 156}, + {0x8001, 160}, + {0xc016, 160}, + {0x8001, 163}, + {0xc016, 163}, + {0x8001, 164}, + {0xc016, 164}, + {0x8001, 169}, + {0xc016, 169}, + {0x8001, 170}, + {0xc016, 170}, + {0x8001, 173}, + {0xc016, 173}, }, /* 127 */ { - {2, 0x02, 154}, - {9, 0x02, 154}, - {23, 0x02, 154}, - {40, 0x03, 154}, - {2, 0x02, 156}, - {9, 0x02, 156}, - {23, 0x02, 156}, - {40, 0x03, 156}, - {2, 0x02, 160}, - {9, 0x02, 160}, - {23, 0x02, 160}, - {40, 0x03, 160}, - {2, 0x02, 163}, - {9, 0x02, 163}, - {23, 0x02, 163}, - {40, 0x03, 163}, + {0x8002, 154}, + {0x8009, 154}, + {0x8017, 154}, + {0xc028, 154}, + {0x8002, 156}, + {0x8009, 156}, + {0x8017, 156}, + {0xc028, 156}, + {0x8002, 160}, + {0x8009, 160}, + {0x8017, 160}, + {0xc028, 160}, + {0x8002, 163}, + {0x8009, 163}, + {0x8017, 163}, + {0xc028, 163}, }, /* 128 */ { - {3, 0x02, 154}, - {6, 0x02, 154}, - {10, 0x02, 154}, - {15, 0x02, 154}, - {24, 0x02, 154}, - {31, 0x02, 154}, - {41, 0x02, 154}, - {56, 0x03, 154}, - {3, 0x02, 156}, - {6, 0x02, 156}, - {10, 0x02, 156}, - {15, 0x02, 156}, - {24, 0x02, 156}, - {31, 0x02, 156}, - {41, 0x02, 156}, - {56, 0x03, 156}, + {0x8003, 154}, + {0x8006, 154}, + {0x800a, 154}, + {0x800f, 154}, + {0x8018, 154}, + {0x801f, 154}, + {0x8029, 154}, + {0xc038, 154}, + {0x8003, 156}, + {0x8006, 156}, + {0x800a, 156}, + {0x800f, 156}, + {0x8018, 156}, + {0x801f, 156}, + {0x8029, 156}, + {0xc038, 156}, }, /* 129 */ { - {3, 0x02, 160}, - {6, 0x02, 160}, - {10, 0x02, 160}, - {15, 0x02, 160}, - {24, 0x02, 160}, - {31, 0x02, 160}, - {41, 0x02, 160}, - {56, 0x03, 160}, - {3, 0x02, 163}, - {6, 0x02, 163}, - {10, 0x02, 163}, - {15, 0x02, 163}, - {24, 0x02, 163}, - {31, 0x02, 163}, - {41, 0x02, 163}, - {56, 0x03, 163}, + {0x8003, 160}, + {0x8006, 160}, + {0x800a, 160}, + {0x800f, 160}, + {0x8018, 160}, + {0x801f, 160}, + {0x8029, 160}, + {0xc038, 160}, + {0x8003, 163}, + {0x8006, 163}, + {0x800a, 163}, + {0x800f, 163}, + {0x8018, 163}, + {0x801f, 163}, + {0x8029, 163}, + {0xc038, 163}, }, /* 130 */ { - {2, 0x02, 164}, - {9, 0x02, 164}, - {23, 0x02, 164}, - {40, 0x03, 164}, - {2, 0x02, 169}, - {9, 0x02, 169}, - {23, 0x02, 169}, - {40, 0x03, 169}, - {2, 0x02, 170}, - {9, 0x02, 170}, - {23, 0x02, 170}, - {40, 0x03, 170}, - {2, 0x02, 173}, - {9, 0x02, 173}, - {23, 0x02, 173}, - {40, 0x03, 173}, + {0x8002, 164}, + {0x8009, 164}, + {0x8017, 164}, + {0xc028, 164}, + {0x8002, 169}, + {0x8009, 169}, + {0x8017, 169}, + {0xc028, 169}, + {0x8002, 170}, + {0x8009, 170}, + {0x8017, 170}, + {0xc028, 170}, + {0x8002, 173}, + {0x8009, 173}, + {0x8017, 173}, + {0xc028, 173}, }, /* 131 */ { - {3, 0x02, 164}, - {6, 0x02, 164}, - {10, 0x02, 164}, - {15, 0x02, 164}, - {24, 0x02, 164}, - {31, 0x02, 164}, - {41, 0x02, 164}, - {56, 0x03, 164}, - {3, 0x02, 169}, - {6, 0x02, 169}, - {10, 0x02, 169}, - {15, 0x02, 169}, - {24, 0x02, 169}, - {31, 0x02, 169}, - {41, 0x02, 169}, - {56, 0x03, 169}, + {0x8003, 164}, + {0x8006, 164}, + {0x800a, 164}, + {0x800f, 164}, + {0x8018, 164}, + {0x801f, 164}, + {0x8029, 164}, + {0xc038, 164}, + {0x8003, 169}, + {0x8006, 169}, + {0x800a, 169}, + {0x800f, 169}, + {0x8018, 169}, + {0x801f, 169}, + {0x8029, 169}, + {0xc038, 169}, }, /* 132 */ { - {3, 0x02, 170}, - {6, 0x02, 170}, - {10, 0x02, 170}, - {15, 0x02, 170}, - {24, 0x02, 170}, - {31, 0x02, 170}, - {41, 0x02, 170}, - {56, 0x03, 170}, - {3, 0x02, 173}, - {6, 0x02, 173}, - {10, 0x02, 173}, - {15, 0x02, 173}, - {24, 0x02, 173}, - {31, 0x02, 173}, - {41, 0x02, 173}, - {56, 0x03, 173}, + {0x8003, 170}, + {0x8006, 170}, + {0x800a, 170}, + {0x800f, 170}, + {0x8018, 170}, + {0x801f, 170}, + {0x8029, 170}, + {0xc038, 170}, + {0x8003, 173}, + {0x8006, 173}, + {0x800a, 173}, + {0x800f, 173}, + {0x8018, 173}, + {0x801f, 173}, + {0x8029, 173}, + {0xc038, 173}, }, /* 133 */ { - {137, 0x00, 0}, - {138, 0x00, 0}, - {140, 0x00, 0}, - {141, 0x00, 0}, - {144, 0x00, 0}, - {145, 0x00, 0}, - {147, 0x00, 0}, - {150, 0x00, 0}, - {156, 0x00, 0}, - {159, 0x00, 0}, - {163, 0x00, 0}, - {166, 0x00, 0}, - {171, 0x00, 0}, - {174, 0x00, 0}, - {181, 0x00, 0}, - {190, 0x00, 0}, + {0x89, 0}, + {0x8a, 0}, + {0x8c, 0}, + {0x8d, 0}, + {0x90, 0}, + {0x91, 0}, + {0x93, 0}, + {0x96, 0}, + {0x9c, 0}, + {0x9f, 0}, + {0xa3, 0}, + {0xa6, 0}, + {0xab, 0}, + {0xae, 0}, + {0xb5, 0}, + {0xbe, 0}, }, /* 134 */ { - {0, 0x03, 178}, - {0, 0x03, 181}, - {0, 0x03, 185}, - {0, 0x03, 186}, - {0, 0x03, 187}, - {0, 0x03, 189}, - {0, 0x03, 190}, - {0, 0x03, 196}, - {0, 0x03, 198}, - {0, 0x03, 228}, - {0, 0x03, 232}, - {0, 0x03, 233}, - {148, 0x00, 0}, - {149, 0x00, 0}, - {151, 0x00, 0}, - {152, 0x00, 0}, + {0xc000, 178}, + {0xc000, 181}, + {0xc000, 185}, + {0xc000, 186}, + {0xc000, 187}, + {0xc000, 189}, + {0xc000, 190}, + {0xc000, 196}, + {0xc000, 198}, + {0xc000, 228}, + {0xc000, 232}, + {0xc000, 233}, + {0x94, 0}, + {0x95, 0}, + {0x97, 0}, + {0x98, 0}, }, /* 135 */ { - {1, 0x02, 178}, - {22, 0x03, 178}, - {1, 0x02, 181}, - {22, 0x03, 181}, - {1, 0x02, 185}, - {22, 0x03, 185}, - {1, 0x02, 186}, - {22, 0x03, 186}, - {1, 0x02, 187}, - {22, 0x03, 187}, - {1, 0x02, 189}, - {22, 0x03, 189}, - {1, 0x02, 190}, - {22, 0x03, 190}, - {1, 0x02, 196}, - {22, 0x03, 196}, + {0x8001, 178}, + {0xc016, 178}, + {0x8001, 181}, + {0xc016, 181}, + {0x8001, 185}, + {0xc016, 185}, + {0x8001, 186}, + {0xc016, 186}, + {0x8001, 187}, + {0xc016, 187}, + {0x8001, 189}, + {0xc016, 189}, + {0x8001, 190}, + {0xc016, 190}, + {0x8001, 196}, + {0xc016, 196}, }, /* 136 */ { - {2, 0x02, 178}, - {9, 0x02, 178}, - {23, 0x02, 178}, - {40, 0x03, 178}, - {2, 0x02, 181}, - {9, 0x02, 181}, - {23, 0x02, 181}, - {40, 0x03, 181}, - {2, 0x02, 185}, - {9, 0x02, 185}, - {23, 0x02, 185}, - {40, 0x03, 185}, - {2, 0x02, 186}, - {9, 0x02, 186}, - {23, 0x02, 186}, - {40, 0x03, 186}, + {0x8002, 178}, + {0x8009, 178}, + {0x8017, 178}, + {0xc028, 178}, + {0x8002, 181}, + {0x8009, 181}, + {0x8017, 181}, + {0xc028, 181}, + {0x8002, 185}, + {0x8009, 185}, + {0x8017, 185}, + {0xc028, 185}, + {0x8002, 186}, + {0x8009, 186}, + {0x8017, 186}, + {0xc028, 186}, }, /* 137 */ { - {3, 0x02, 178}, - {6, 0x02, 178}, - {10, 0x02, 178}, - {15, 0x02, 178}, - {24, 0x02, 178}, - {31, 0x02, 178}, - {41, 0x02, 178}, - {56, 0x03, 178}, - {3, 0x02, 181}, - {6, 0x02, 181}, - {10, 0x02, 181}, - {15, 0x02, 181}, - {24, 0x02, 181}, - {31, 0x02, 181}, - {41, 0x02, 181}, - {56, 0x03, 181}, + {0x8003, 178}, + {0x8006, 178}, + {0x800a, 178}, + {0x800f, 178}, + {0x8018, 178}, + {0x801f, 178}, + {0x8029, 178}, + {0xc038, 178}, + {0x8003, 181}, + {0x8006, 181}, + {0x800a, 181}, + {0x800f, 181}, + {0x8018, 181}, + {0x801f, 181}, + {0x8029, 181}, + {0xc038, 181}, }, /* 138 */ { - {3, 0x02, 185}, - {6, 0x02, 185}, - {10, 0x02, 185}, - {15, 0x02, 185}, - {24, 0x02, 185}, - {31, 0x02, 185}, - {41, 0x02, 185}, - {56, 0x03, 185}, - {3, 0x02, 186}, - {6, 0x02, 186}, - {10, 0x02, 186}, - {15, 0x02, 186}, - {24, 0x02, 186}, - {31, 0x02, 186}, - {41, 0x02, 186}, - {56, 0x03, 186}, + {0x8003, 185}, + {0x8006, 185}, + {0x800a, 185}, + {0x800f, 185}, + {0x8018, 185}, + {0x801f, 185}, + {0x8029, 185}, + {0xc038, 185}, + {0x8003, 186}, + {0x8006, 186}, + {0x800a, 186}, + {0x800f, 186}, + {0x8018, 186}, + {0x801f, 186}, + {0x8029, 186}, + {0xc038, 186}, }, /* 139 */ { - {2, 0x02, 187}, - {9, 0x02, 187}, - {23, 0x02, 187}, - {40, 0x03, 187}, - {2, 0x02, 189}, - {9, 0x02, 189}, - {23, 0x02, 189}, - {40, 0x03, 189}, - {2, 0x02, 190}, - {9, 0x02, 190}, - {23, 0x02, 190}, - {40, 0x03, 190}, - {2, 0x02, 196}, - {9, 0x02, 196}, - {23, 0x02, 196}, - {40, 0x03, 196}, + {0x8002, 187}, + {0x8009, 187}, + {0x8017, 187}, + {0xc028, 187}, + {0x8002, 189}, + {0x8009, 189}, + {0x8017, 189}, + {0xc028, 189}, + {0x8002, 190}, + {0x8009, 190}, + {0x8017, 190}, + {0xc028, 190}, + {0x8002, 196}, + {0x8009, 196}, + {0x8017, 196}, + {0xc028, 196}, }, /* 140 */ { - {3, 0x02, 187}, - {6, 0x02, 187}, - {10, 0x02, 187}, - {15, 0x02, 187}, - {24, 0x02, 187}, - {31, 0x02, 187}, - {41, 0x02, 187}, - {56, 0x03, 187}, - {3, 0x02, 189}, - {6, 0x02, 189}, - {10, 0x02, 189}, - {15, 0x02, 189}, - {24, 0x02, 189}, - {31, 0x02, 189}, - {41, 0x02, 189}, - {56, 0x03, 189}, + {0x8003, 187}, + {0x8006, 187}, + {0x800a, 187}, + {0x800f, 187}, + {0x8018, 187}, + {0x801f, 187}, + {0x8029, 187}, + {0xc038, 187}, + {0x8003, 189}, + {0x8006, 189}, + {0x800a, 189}, + {0x800f, 189}, + {0x8018, 189}, + {0x801f, 189}, + {0x8029, 189}, + {0xc038, 189}, }, /* 141 */ { - {3, 0x02, 190}, - {6, 0x02, 190}, - {10, 0x02, 190}, - {15, 0x02, 190}, - {24, 0x02, 190}, - {31, 0x02, 190}, - {41, 0x02, 190}, - {56, 0x03, 190}, - {3, 0x02, 196}, - {6, 0x02, 196}, - {10, 0x02, 196}, - {15, 0x02, 196}, - {24, 0x02, 196}, - {31, 0x02, 196}, - {41, 0x02, 196}, - {56, 0x03, 196}, + {0x8003, 190}, + {0x8006, 190}, + {0x800a, 190}, + {0x800f, 190}, + {0x8018, 190}, + {0x801f, 190}, + {0x8029, 190}, + {0xc038, 190}, + {0x8003, 196}, + {0x8006, 196}, + {0x800a, 196}, + {0x800f, 196}, + {0x8018, 196}, + {0x801f, 196}, + {0x8029, 196}, + {0xc038, 196}, }, /* 142 */ { - {1, 0x02, 198}, - {22, 0x03, 198}, - {1, 0x02, 228}, - {22, 0x03, 228}, - {1, 0x02, 232}, - {22, 0x03, 232}, - {1, 0x02, 233}, - {22, 0x03, 233}, - {0, 0x03, 1}, - {0, 0x03, 135}, - {0, 0x03, 137}, - {0, 0x03, 138}, - {0, 0x03, 139}, - {0, 0x03, 140}, - {0, 0x03, 141}, - {0, 0x03, 143}, + {0x8001, 198}, + {0xc016, 198}, + {0x8001, 228}, + {0xc016, 228}, + {0x8001, 232}, + {0xc016, 232}, + {0x8001, 233}, + {0xc016, 233}, + {0xc000, 1}, + {0xc000, 135}, + {0xc000, 137}, + {0xc000, 138}, + {0xc000, 139}, + {0xc000, 140}, + {0xc000, 141}, + {0xc000, 143}, }, /* 143 */ { - {2, 0x02, 198}, - {9, 0x02, 198}, - {23, 0x02, 198}, - {40, 0x03, 198}, - {2, 0x02, 228}, - {9, 0x02, 228}, - {23, 0x02, 228}, - {40, 0x03, 228}, - {2, 0x02, 232}, - {9, 0x02, 232}, - {23, 0x02, 232}, - {40, 0x03, 232}, - {2, 0x02, 233}, - {9, 0x02, 233}, - {23, 0x02, 233}, - {40, 0x03, 233}, + {0x8002, 198}, + {0x8009, 198}, + {0x8017, 198}, + {0xc028, 198}, + {0x8002, 228}, + {0x8009, 228}, + {0x8017, 228}, + {0xc028, 228}, + {0x8002, 232}, + {0x8009, 232}, + {0x8017, 232}, + {0xc028, 232}, + {0x8002, 233}, + {0x8009, 233}, + {0x8017, 233}, + {0xc028, 233}, }, /* 144 */ { - {3, 0x02, 198}, - {6, 0x02, 198}, - {10, 0x02, 198}, - {15, 0x02, 198}, - {24, 0x02, 198}, - {31, 0x02, 198}, - {41, 0x02, 198}, - {56, 0x03, 198}, - {3, 0x02, 228}, - {6, 0x02, 228}, - {10, 0x02, 228}, - {15, 0x02, 228}, - {24, 0x02, 228}, - {31, 0x02, 228}, - {41, 0x02, 228}, - {56, 0x03, 228}, + {0x8003, 198}, + {0x8006, 198}, + {0x800a, 198}, + {0x800f, 198}, + {0x8018, 198}, + {0x801f, 198}, + {0x8029, 198}, + {0xc038, 198}, + {0x8003, 228}, + {0x8006, 228}, + {0x800a, 228}, + {0x800f, 228}, + {0x8018, 228}, + {0x801f, 228}, + {0x8029, 228}, + {0xc038, 228}, }, /* 145 */ { - {3, 0x02, 232}, - {6, 0x02, 232}, - {10, 0x02, 232}, - {15, 0x02, 232}, - {24, 0x02, 232}, - {31, 0x02, 232}, - {41, 0x02, 232}, - {56, 0x03, 232}, - {3, 0x02, 233}, - {6, 0x02, 233}, - {10, 0x02, 233}, - {15, 0x02, 233}, - {24, 0x02, 233}, - {31, 0x02, 233}, - {41, 0x02, 233}, - {56, 0x03, 233}, + {0x8003, 232}, + {0x8006, 232}, + {0x800a, 232}, + {0x800f, 232}, + {0x8018, 232}, + {0x801f, 232}, + {0x8029, 232}, + {0xc038, 232}, + {0x8003, 233}, + {0x8006, 233}, + {0x800a, 233}, + {0x800f, 233}, + {0x8018, 233}, + {0x801f, 233}, + {0x8029, 233}, + {0xc038, 233}, }, /* 146 */ { - {1, 0x02, 1}, - {22, 0x03, 1}, - {1, 0x02, 135}, - {22, 0x03, 135}, - {1, 0x02, 137}, - {22, 0x03, 137}, - {1, 0x02, 138}, - {22, 0x03, 138}, - {1, 0x02, 139}, - {22, 0x03, 139}, - {1, 0x02, 140}, - {22, 0x03, 140}, - {1, 0x02, 141}, - {22, 0x03, 141}, - {1, 0x02, 143}, - {22, 0x03, 143}, + {0x8001, 1}, + {0xc016, 1}, + {0x8001, 135}, + {0xc016, 135}, + {0x8001, 137}, + {0xc016, 137}, + {0x8001, 138}, + {0xc016, 138}, + {0x8001, 139}, + {0xc016, 139}, + {0x8001, 140}, + {0xc016, 140}, + {0x8001, 141}, + {0xc016, 141}, + {0x8001, 143}, + {0xc016, 143}, }, /* 147 */ { - {2, 0x02, 1}, - {9, 0x02, 1}, - {23, 0x02, 1}, - {40, 0x03, 1}, - {2, 0x02, 135}, - {9, 0x02, 135}, - {23, 0x02, 135}, - {40, 0x03, 135}, - {2, 0x02, 137}, - {9, 0x02, 137}, - {23, 0x02, 137}, - {40, 0x03, 137}, - {2, 0x02, 138}, - {9, 0x02, 138}, - {23, 0x02, 138}, - {40, 0x03, 138}, + {0x8002, 1}, + {0x8009, 1}, + {0x8017, 1}, + {0xc028, 1}, + {0x8002, 135}, + {0x8009, 135}, + {0x8017, 135}, + {0xc028, 135}, + {0x8002, 137}, + {0x8009, 137}, + {0x8017, 137}, + {0xc028, 137}, + {0x8002, 138}, + {0x8009, 138}, + {0x8017, 138}, + {0xc028, 138}, }, /* 148 */ { - {3, 0x02, 1}, - {6, 0x02, 1}, - {10, 0x02, 1}, - {15, 0x02, 1}, - {24, 0x02, 1}, - {31, 0x02, 1}, - {41, 0x02, 1}, - {56, 0x03, 1}, - {3, 0x02, 135}, - {6, 0x02, 135}, - {10, 0x02, 135}, - {15, 0x02, 135}, - {24, 0x02, 135}, - {31, 0x02, 135}, - {41, 0x02, 135}, - {56, 0x03, 135}, + {0x8003, 1}, + {0x8006, 1}, + {0x800a, 1}, + {0x800f, 1}, + {0x8018, 1}, + {0x801f, 1}, + {0x8029, 1}, + {0xc038, 1}, + {0x8003, 135}, + {0x8006, 135}, + {0x800a, 135}, + {0x800f, 135}, + {0x8018, 135}, + {0x801f, 135}, + {0x8029, 135}, + {0xc038, 135}, }, /* 149 */ { - {3, 0x02, 137}, - {6, 0x02, 137}, - {10, 0x02, 137}, - {15, 0x02, 137}, - {24, 0x02, 137}, - {31, 0x02, 137}, - {41, 0x02, 137}, - {56, 0x03, 137}, - {3, 0x02, 138}, - {6, 0x02, 138}, - {10, 0x02, 138}, - {15, 0x02, 138}, - {24, 0x02, 138}, - {31, 0x02, 138}, - {41, 0x02, 138}, - {56, 0x03, 138}, + {0x8003, 137}, + {0x8006, 137}, + {0x800a, 137}, + {0x800f, 137}, + {0x8018, 137}, + {0x801f, 137}, + {0x8029, 137}, + {0xc038, 137}, + {0x8003, 138}, + {0x8006, 138}, + {0x800a, 138}, + {0x800f, 138}, + {0x8018, 138}, + {0x801f, 138}, + {0x8029, 138}, + {0xc038, 138}, }, /* 150 */ { - {2, 0x02, 139}, - {9, 0x02, 139}, - {23, 0x02, 139}, - {40, 0x03, 139}, - {2, 0x02, 140}, - {9, 0x02, 140}, - {23, 0x02, 140}, - {40, 0x03, 140}, - {2, 0x02, 141}, - {9, 0x02, 141}, - {23, 0x02, 141}, - {40, 0x03, 141}, - {2, 0x02, 143}, - {9, 0x02, 143}, - {23, 0x02, 143}, - {40, 0x03, 143}, + {0x8002, 139}, + {0x8009, 139}, + {0x8017, 139}, + {0xc028, 139}, + {0x8002, 140}, + {0x8009, 140}, + {0x8017, 140}, + {0xc028, 140}, + {0x8002, 141}, + {0x8009, 141}, + {0x8017, 141}, + {0xc028, 141}, + {0x8002, 143}, + {0x8009, 143}, + {0x8017, 143}, + {0xc028, 143}, }, /* 151 */ { - {3, 0x02, 139}, - {6, 0x02, 139}, - {10, 0x02, 139}, - {15, 0x02, 139}, - {24, 0x02, 139}, - {31, 0x02, 139}, - {41, 0x02, 139}, - {56, 0x03, 139}, - {3, 0x02, 140}, - {6, 0x02, 140}, - {10, 0x02, 140}, - {15, 0x02, 140}, - {24, 0x02, 140}, - {31, 0x02, 140}, - {41, 0x02, 140}, - {56, 0x03, 140}, + {0x8003, 139}, + {0x8006, 139}, + {0x800a, 139}, + {0x800f, 139}, + {0x8018, 139}, + {0x801f, 139}, + {0x8029, 139}, + {0xc038, 139}, + {0x8003, 140}, + {0x8006, 140}, + {0x800a, 140}, + {0x800f, 140}, + {0x8018, 140}, + {0x801f, 140}, + {0x8029, 140}, + {0xc038, 140}, }, /* 152 */ { - {3, 0x02, 141}, - {6, 0x02, 141}, - {10, 0x02, 141}, - {15, 0x02, 141}, - {24, 0x02, 141}, - {31, 0x02, 141}, - {41, 0x02, 141}, - {56, 0x03, 141}, - {3, 0x02, 143}, - {6, 0x02, 143}, - {10, 0x02, 143}, - {15, 0x02, 143}, - {24, 0x02, 143}, - {31, 0x02, 143}, - {41, 0x02, 143}, - {56, 0x03, 143}, + {0x8003, 141}, + {0x8006, 141}, + {0x800a, 141}, + {0x800f, 141}, + {0x8018, 141}, + {0x801f, 141}, + {0x8029, 141}, + {0xc038, 141}, + {0x8003, 143}, + {0x8006, 143}, + {0x800a, 143}, + {0x800f, 143}, + {0x8018, 143}, + {0x801f, 143}, + {0x8029, 143}, + {0xc038, 143}, }, /* 153 */ { - {157, 0x00, 0}, - {158, 0x00, 0}, - {160, 0x00, 0}, - {161, 0x00, 0}, - {164, 0x00, 0}, - {165, 0x00, 0}, - {167, 0x00, 0}, - {168, 0x00, 0}, - {172, 0x00, 0}, - {173, 0x00, 0}, - {175, 0x00, 0}, - {177, 0x00, 0}, - {182, 0x00, 0}, - {185, 0x00, 0}, - {191, 0x00, 0}, - {207, 0x00, 0}, + {0x9d, 0}, + {0x9e, 0}, + {0xa0, 0}, + {0xa1, 0}, + {0xa4, 0}, + {0xa5, 0}, + {0xa7, 0}, + {0xa8, 0}, + {0xac, 0}, + {0xad, 0}, + {0xaf, 0}, + {0xb1, 0}, + {0xb6, 0}, + {0xb9, 0}, + {0xbf, 0}, + {0xcf, 0}, }, /* 154 */ { - {0, 0x03, 147}, - {0, 0x03, 149}, - {0, 0x03, 150}, - {0, 0x03, 151}, - {0, 0x03, 152}, - {0, 0x03, 155}, - {0, 0x03, 157}, - {0, 0x03, 158}, - {0, 0x03, 165}, - {0, 0x03, 166}, - {0, 0x03, 168}, - {0, 0x03, 174}, - {0, 0x03, 175}, - {0, 0x03, 180}, - {0, 0x03, 182}, - {0, 0x03, 183}, + {0xc000, 147}, + {0xc000, 149}, + {0xc000, 150}, + {0xc000, 151}, + {0xc000, 152}, + {0xc000, 155}, + {0xc000, 157}, + {0xc000, 158}, + {0xc000, 165}, + {0xc000, 166}, + {0xc000, 168}, + {0xc000, 174}, + {0xc000, 175}, + {0xc000, 180}, + {0xc000, 182}, + {0xc000, 183}, }, /* 155 */ { - {1, 0x02, 147}, - {22, 0x03, 147}, - {1, 0x02, 149}, - {22, 0x03, 149}, - {1, 0x02, 150}, - {22, 0x03, 150}, - {1, 0x02, 151}, - {22, 0x03, 151}, - {1, 0x02, 152}, - {22, 0x03, 152}, - {1, 0x02, 155}, - {22, 0x03, 155}, - {1, 0x02, 157}, - {22, 0x03, 157}, - {1, 0x02, 158}, - {22, 0x03, 158}, + {0x8001, 147}, + {0xc016, 147}, + {0x8001, 149}, + {0xc016, 149}, + {0x8001, 150}, + {0xc016, 150}, + {0x8001, 151}, + {0xc016, 151}, + {0x8001, 152}, + {0xc016, 152}, + {0x8001, 155}, + {0xc016, 155}, + {0x8001, 157}, + {0xc016, 157}, + {0x8001, 158}, + {0xc016, 158}, }, /* 156 */ { - {2, 0x02, 147}, - {9, 0x02, 147}, - {23, 0x02, 147}, - {40, 0x03, 147}, - {2, 0x02, 149}, - {9, 0x02, 149}, - {23, 0x02, 149}, - {40, 0x03, 149}, - {2, 0x02, 150}, - {9, 0x02, 150}, - {23, 0x02, 150}, - {40, 0x03, 150}, - {2, 0x02, 151}, - {9, 0x02, 151}, - {23, 0x02, 151}, - {40, 0x03, 151}, + {0x8002, 147}, + {0x8009, 147}, + {0x8017, 147}, + {0xc028, 147}, + {0x8002, 149}, + {0x8009, 149}, + {0x8017, 149}, + {0xc028, 149}, + {0x8002, 150}, + {0x8009, 150}, + {0x8017, 150}, + {0xc028, 150}, + {0x8002, 151}, + {0x8009, 151}, + {0x8017, 151}, + {0xc028, 151}, }, /* 157 */ { - {3, 0x02, 147}, - {6, 0x02, 147}, - {10, 0x02, 147}, - {15, 0x02, 147}, - {24, 0x02, 147}, - {31, 0x02, 147}, - {41, 0x02, 147}, - {56, 0x03, 147}, - {3, 0x02, 149}, - {6, 0x02, 149}, - {10, 0x02, 149}, - {15, 0x02, 149}, - {24, 0x02, 149}, - {31, 0x02, 149}, - {41, 0x02, 149}, - {56, 0x03, 149}, + {0x8003, 147}, + {0x8006, 147}, + {0x800a, 147}, + {0x800f, 147}, + {0x8018, 147}, + {0x801f, 147}, + {0x8029, 147}, + {0xc038, 147}, + {0x8003, 149}, + {0x8006, 149}, + {0x800a, 149}, + {0x800f, 149}, + {0x8018, 149}, + {0x801f, 149}, + {0x8029, 149}, + {0xc038, 149}, }, /* 158 */ { - {3, 0x02, 150}, - {6, 0x02, 150}, - {10, 0x02, 150}, - {15, 0x02, 150}, - {24, 0x02, 150}, - {31, 0x02, 150}, - {41, 0x02, 150}, - {56, 0x03, 150}, - {3, 0x02, 151}, - {6, 0x02, 151}, - {10, 0x02, 151}, - {15, 0x02, 151}, - {24, 0x02, 151}, - {31, 0x02, 151}, - {41, 0x02, 151}, - {56, 0x03, 151}, + {0x8003, 150}, + {0x8006, 150}, + {0x800a, 150}, + {0x800f, 150}, + {0x8018, 150}, + {0x801f, 150}, + {0x8029, 150}, + {0xc038, 150}, + {0x8003, 151}, + {0x8006, 151}, + {0x800a, 151}, + {0x800f, 151}, + {0x8018, 151}, + {0x801f, 151}, + {0x8029, 151}, + {0xc038, 151}, }, /* 159 */ { - {2, 0x02, 152}, - {9, 0x02, 152}, - {23, 0x02, 152}, - {40, 0x03, 152}, - {2, 0x02, 155}, - {9, 0x02, 155}, - {23, 0x02, 155}, - {40, 0x03, 155}, - {2, 0x02, 157}, - {9, 0x02, 157}, - {23, 0x02, 157}, - {40, 0x03, 157}, - {2, 0x02, 158}, - {9, 0x02, 158}, - {23, 0x02, 158}, - {40, 0x03, 158}, + {0x8002, 152}, + {0x8009, 152}, + {0x8017, 152}, + {0xc028, 152}, + {0x8002, 155}, + {0x8009, 155}, + {0x8017, 155}, + {0xc028, 155}, + {0x8002, 157}, + {0x8009, 157}, + {0x8017, 157}, + {0xc028, 157}, + {0x8002, 158}, + {0x8009, 158}, + {0x8017, 158}, + {0xc028, 158}, }, /* 160 */ { - {3, 0x02, 152}, - {6, 0x02, 152}, - {10, 0x02, 152}, - {15, 0x02, 152}, - {24, 0x02, 152}, - {31, 0x02, 152}, - {41, 0x02, 152}, - {56, 0x03, 152}, - {3, 0x02, 155}, - {6, 0x02, 155}, - {10, 0x02, 155}, - {15, 0x02, 155}, - {24, 0x02, 155}, - {31, 0x02, 155}, - {41, 0x02, 155}, - {56, 0x03, 155}, + {0x8003, 152}, + {0x8006, 152}, + {0x800a, 152}, + {0x800f, 152}, + {0x8018, 152}, + {0x801f, 152}, + {0x8029, 152}, + {0xc038, 152}, + {0x8003, 155}, + {0x8006, 155}, + {0x800a, 155}, + {0x800f, 155}, + {0x8018, 155}, + {0x801f, 155}, + {0x8029, 155}, + {0xc038, 155}, }, /* 161 */ { - {3, 0x02, 157}, - {6, 0x02, 157}, - {10, 0x02, 157}, - {15, 0x02, 157}, - {24, 0x02, 157}, - {31, 0x02, 157}, - {41, 0x02, 157}, - {56, 0x03, 157}, - {3, 0x02, 158}, - {6, 0x02, 158}, - {10, 0x02, 158}, - {15, 0x02, 158}, - {24, 0x02, 158}, - {31, 0x02, 158}, - {41, 0x02, 158}, - {56, 0x03, 158}, + {0x8003, 157}, + {0x8006, 157}, + {0x800a, 157}, + {0x800f, 157}, + {0x8018, 157}, + {0x801f, 157}, + {0x8029, 157}, + {0xc038, 157}, + {0x8003, 158}, + {0x8006, 158}, + {0x800a, 158}, + {0x800f, 158}, + {0x8018, 158}, + {0x801f, 158}, + {0x8029, 158}, + {0xc038, 158}, }, /* 162 */ { - {1, 0x02, 165}, - {22, 0x03, 165}, - {1, 0x02, 166}, - {22, 0x03, 166}, - {1, 0x02, 168}, - {22, 0x03, 168}, - {1, 0x02, 174}, - {22, 0x03, 174}, - {1, 0x02, 175}, - {22, 0x03, 175}, - {1, 0x02, 180}, - {22, 0x03, 180}, - {1, 0x02, 182}, - {22, 0x03, 182}, - {1, 0x02, 183}, - {22, 0x03, 183}, + {0x8001, 165}, + {0xc016, 165}, + {0x8001, 166}, + {0xc016, 166}, + {0x8001, 168}, + {0xc016, 168}, + {0x8001, 174}, + {0xc016, 174}, + {0x8001, 175}, + {0xc016, 175}, + {0x8001, 180}, + {0xc016, 180}, + {0x8001, 182}, + {0xc016, 182}, + {0x8001, 183}, + {0xc016, 183}, }, /* 163 */ { - {2, 0x02, 165}, - {9, 0x02, 165}, - {23, 0x02, 165}, - {40, 0x03, 165}, - {2, 0x02, 166}, - {9, 0x02, 166}, - {23, 0x02, 166}, - {40, 0x03, 166}, - {2, 0x02, 168}, - {9, 0x02, 168}, - {23, 0x02, 168}, - {40, 0x03, 168}, - {2, 0x02, 174}, - {9, 0x02, 174}, - {23, 0x02, 174}, - {40, 0x03, 174}, + {0x8002, 165}, + {0x8009, 165}, + {0x8017, 165}, + {0xc028, 165}, + {0x8002, 166}, + {0x8009, 166}, + {0x8017, 166}, + {0xc028, 166}, + {0x8002, 168}, + {0x8009, 168}, + {0x8017, 168}, + {0xc028, 168}, + {0x8002, 174}, + {0x8009, 174}, + {0x8017, 174}, + {0xc028, 174}, }, /* 164 */ { - {3, 0x02, 165}, - {6, 0x02, 165}, - {10, 0x02, 165}, - {15, 0x02, 165}, - {24, 0x02, 165}, - {31, 0x02, 165}, - {41, 0x02, 165}, - {56, 0x03, 165}, - {3, 0x02, 166}, - {6, 0x02, 166}, - {10, 0x02, 166}, - {15, 0x02, 166}, - {24, 0x02, 166}, - {31, 0x02, 166}, - {41, 0x02, 166}, - {56, 0x03, 166}, + {0x8003, 165}, + {0x8006, 165}, + {0x800a, 165}, + {0x800f, 165}, + {0x8018, 165}, + {0x801f, 165}, + {0x8029, 165}, + {0xc038, 165}, + {0x8003, 166}, + {0x8006, 166}, + {0x800a, 166}, + {0x800f, 166}, + {0x8018, 166}, + {0x801f, 166}, + {0x8029, 166}, + {0xc038, 166}, }, /* 165 */ { - {3, 0x02, 168}, - {6, 0x02, 168}, - {10, 0x02, 168}, - {15, 0x02, 168}, - {24, 0x02, 168}, - {31, 0x02, 168}, - {41, 0x02, 168}, - {56, 0x03, 168}, - {3, 0x02, 174}, - {6, 0x02, 174}, - {10, 0x02, 174}, - {15, 0x02, 174}, - {24, 0x02, 174}, - {31, 0x02, 174}, - {41, 0x02, 174}, - {56, 0x03, 174}, + {0x8003, 168}, + {0x8006, 168}, + {0x800a, 168}, + {0x800f, 168}, + {0x8018, 168}, + {0x801f, 168}, + {0x8029, 168}, + {0xc038, 168}, + {0x8003, 174}, + {0x8006, 174}, + {0x800a, 174}, + {0x800f, 174}, + {0x8018, 174}, + {0x801f, 174}, + {0x8029, 174}, + {0xc038, 174}, }, /* 166 */ { - {2, 0x02, 175}, - {9, 0x02, 175}, - {23, 0x02, 175}, - {40, 0x03, 175}, - {2, 0x02, 180}, - {9, 0x02, 180}, - {23, 0x02, 180}, - {40, 0x03, 180}, - {2, 0x02, 182}, - {9, 0x02, 182}, - {23, 0x02, 182}, - {40, 0x03, 182}, - {2, 0x02, 183}, - {9, 0x02, 183}, - {23, 0x02, 183}, - {40, 0x03, 183}, + {0x8002, 175}, + {0x8009, 175}, + {0x8017, 175}, + {0xc028, 175}, + {0x8002, 180}, + {0x8009, 180}, + {0x8017, 180}, + {0xc028, 180}, + {0x8002, 182}, + {0x8009, 182}, + {0x8017, 182}, + {0xc028, 182}, + {0x8002, 183}, + {0x8009, 183}, + {0x8017, 183}, + {0xc028, 183}, }, /* 167 */ { - {3, 0x02, 175}, - {6, 0x02, 175}, - {10, 0x02, 175}, - {15, 0x02, 175}, - {24, 0x02, 175}, - {31, 0x02, 175}, - {41, 0x02, 175}, - {56, 0x03, 175}, - {3, 0x02, 180}, - {6, 0x02, 180}, - {10, 0x02, 180}, - {15, 0x02, 180}, - {24, 0x02, 180}, - {31, 0x02, 180}, - {41, 0x02, 180}, - {56, 0x03, 180}, + {0x8003, 175}, + {0x8006, 175}, + {0x800a, 175}, + {0x800f, 175}, + {0x8018, 175}, + {0x801f, 175}, + {0x8029, 175}, + {0xc038, 175}, + {0x8003, 180}, + {0x8006, 180}, + {0x800a, 180}, + {0x800f, 180}, + {0x8018, 180}, + {0x801f, 180}, + {0x8029, 180}, + {0xc038, 180}, }, /* 168 */ { - {3, 0x02, 182}, - {6, 0x02, 182}, - {10, 0x02, 182}, - {15, 0x02, 182}, - {24, 0x02, 182}, - {31, 0x02, 182}, - {41, 0x02, 182}, - {56, 0x03, 182}, - {3, 0x02, 183}, - {6, 0x02, 183}, - {10, 0x02, 183}, - {15, 0x02, 183}, - {24, 0x02, 183}, - {31, 0x02, 183}, - {41, 0x02, 183}, - {56, 0x03, 183}, + {0x8003, 182}, + {0x8006, 182}, + {0x800a, 182}, + {0x800f, 182}, + {0x8018, 182}, + {0x801f, 182}, + {0x8029, 182}, + {0xc038, 182}, + {0x8003, 183}, + {0x8006, 183}, + {0x800a, 183}, + {0x800f, 183}, + {0x8018, 183}, + {0x801f, 183}, + {0x8029, 183}, + {0xc038, 183}, }, /* 169 */ { - {0, 0x03, 188}, - {0, 0x03, 191}, - {0, 0x03, 197}, - {0, 0x03, 231}, - {0, 0x03, 239}, - {176, 0x00, 0}, - {178, 0x00, 0}, - {179, 0x00, 0}, - {183, 0x00, 0}, - {184, 0x00, 0}, - {186, 0x00, 0}, - {187, 0x00, 0}, - {192, 0x00, 0}, - {199, 0x00, 0}, - {208, 0x00, 0}, - {223, 0x00, 0}, + {0xc000, 188}, + {0xc000, 191}, + {0xc000, 197}, + {0xc000, 231}, + {0xc000, 239}, + {0xb0, 0}, + {0xb2, 0}, + {0xb3, 0}, + {0xb7, 0}, + {0xb8, 0}, + {0xba, 0}, + {0xbb, 0}, + {0xc0, 0}, + {0xc7, 0}, + {0xd0, 0}, + {0xdf, 0}, }, /* 170 */ { - {1, 0x02, 188}, - {22, 0x03, 188}, - {1, 0x02, 191}, - {22, 0x03, 191}, - {1, 0x02, 197}, - {22, 0x03, 197}, - {1, 0x02, 231}, - {22, 0x03, 231}, - {1, 0x02, 239}, - {22, 0x03, 239}, - {0, 0x03, 9}, - {0, 0x03, 142}, - {0, 0x03, 144}, - {0, 0x03, 145}, - {0, 0x03, 148}, - {0, 0x03, 159}, + {0x8001, 188}, + {0xc016, 188}, + {0x8001, 191}, + {0xc016, 191}, + {0x8001, 197}, + {0xc016, 197}, + {0x8001, 231}, + {0xc016, 231}, + {0x8001, 239}, + {0xc016, 239}, + {0xc000, 9}, + {0xc000, 142}, + {0xc000, 144}, + {0xc000, 145}, + {0xc000, 148}, + {0xc000, 159}, }, /* 171 */ { - {2, 0x02, 188}, - {9, 0x02, 188}, - {23, 0x02, 188}, - {40, 0x03, 188}, - {2, 0x02, 191}, - {9, 0x02, 191}, - {23, 0x02, 191}, - {40, 0x03, 191}, - {2, 0x02, 197}, - {9, 0x02, 197}, - {23, 0x02, 197}, - {40, 0x03, 197}, - {2, 0x02, 231}, - {9, 0x02, 231}, - {23, 0x02, 231}, - {40, 0x03, 231}, + {0x8002, 188}, + {0x8009, 188}, + {0x8017, 188}, + {0xc028, 188}, + {0x8002, 191}, + {0x8009, 191}, + {0x8017, 191}, + {0xc028, 191}, + {0x8002, 197}, + {0x8009, 197}, + {0x8017, 197}, + {0xc028, 197}, + {0x8002, 231}, + {0x8009, 231}, + {0x8017, 231}, + {0xc028, 231}, }, /* 172 */ { - {3, 0x02, 188}, - {6, 0x02, 188}, - {10, 0x02, 188}, - {15, 0x02, 188}, - {24, 0x02, 188}, - {31, 0x02, 188}, - {41, 0x02, 188}, - {56, 0x03, 188}, - {3, 0x02, 191}, - {6, 0x02, 191}, - {10, 0x02, 191}, - {15, 0x02, 191}, - {24, 0x02, 191}, - {31, 0x02, 191}, - {41, 0x02, 191}, - {56, 0x03, 191}, + {0x8003, 188}, + {0x8006, 188}, + {0x800a, 188}, + {0x800f, 188}, + {0x8018, 188}, + {0x801f, 188}, + {0x8029, 188}, + {0xc038, 188}, + {0x8003, 191}, + {0x8006, 191}, + {0x800a, 191}, + {0x800f, 191}, + {0x8018, 191}, + {0x801f, 191}, + {0x8029, 191}, + {0xc038, 191}, }, /* 173 */ { - {3, 0x02, 197}, - {6, 0x02, 197}, - {10, 0x02, 197}, - {15, 0x02, 197}, - {24, 0x02, 197}, - {31, 0x02, 197}, - {41, 0x02, 197}, - {56, 0x03, 197}, - {3, 0x02, 231}, - {6, 0x02, 231}, - {10, 0x02, 231}, - {15, 0x02, 231}, - {24, 0x02, 231}, - {31, 0x02, 231}, - {41, 0x02, 231}, - {56, 0x03, 231}, + {0x8003, 197}, + {0x8006, 197}, + {0x800a, 197}, + {0x800f, 197}, + {0x8018, 197}, + {0x801f, 197}, + {0x8029, 197}, + {0xc038, 197}, + {0x8003, 231}, + {0x8006, 231}, + {0x800a, 231}, + {0x800f, 231}, + {0x8018, 231}, + {0x801f, 231}, + {0x8029, 231}, + {0xc038, 231}, }, /* 174 */ { - {2, 0x02, 239}, - {9, 0x02, 239}, - {23, 0x02, 239}, - {40, 0x03, 239}, - {1, 0x02, 9}, - {22, 0x03, 9}, - {1, 0x02, 142}, - {22, 0x03, 142}, - {1, 0x02, 144}, - {22, 0x03, 144}, - {1, 0x02, 145}, - {22, 0x03, 145}, - {1, 0x02, 148}, - {22, 0x03, 148}, - {1, 0x02, 159}, - {22, 0x03, 159}, + {0x8002, 239}, + {0x8009, 239}, + {0x8017, 239}, + {0xc028, 239}, + {0x8001, 9}, + {0xc016, 9}, + {0x8001, 142}, + {0xc016, 142}, + {0x8001, 144}, + {0xc016, 144}, + {0x8001, 145}, + {0xc016, 145}, + {0x8001, 148}, + {0xc016, 148}, + {0x8001, 159}, + {0xc016, 159}, }, /* 175 */ { - {3, 0x02, 239}, - {6, 0x02, 239}, - {10, 0x02, 239}, - {15, 0x02, 239}, - {24, 0x02, 239}, - {31, 0x02, 239}, - {41, 0x02, 239}, - {56, 0x03, 239}, - {2, 0x02, 9}, - {9, 0x02, 9}, - {23, 0x02, 9}, - {40, 0x03, 9}, - {2, 0x02, 142}, - {9, 0x02, 142}, - {23, 0x02, 142}, - {40, 0x03, 142}, + {0x8003, 239}, + {0x8006, 239}, + {0x800a, 239}, + {0x800f, 239}, + {0x8018, 239}, + {0x801f, 239}, + {0x8029, 239}, + {0xc038, 239}, + {0x8002, 9}, + {0x8009, 9}, + {0x8017, 9}, + {0xc028, 9}, + {0x8002, 142}, + {0x8009, 142}, + {0x8017, 142}, + {0xc028, 142}, }, /* 176 */ { - {3, 0x02, 9}, - {6, 0x02, 9}, - {10, 0x02, 9}, - {15, 0x02, 9}, - {24, 0x02, 9}, - {31, 0x02, 9}, - {41, 0x02, 9}, - {56, 0x03, 9}, - {3, 0x02, 142}, - {6, 0x02, 142}, - {10, 0x02, 142}, - {15, 0x02, 142}, - {24, 0x02, 142}, - {31, 0x02, 142}, - {41, 0x02, 142}, - {56, 0x03, 142}, + {0x8003, 9}, + {0x8006, 9}, + {0x800a, 9}, + {0x800f, 9}, + {0x8018, 9}, + {0x801f, 9}, + {0x8029, 9}, + {0xc038, 9}, + {0x8003, 142}, + {0x8006, 142}, + {0x800a, 142}, + {0x800f, 142}, + {0x8018, 142}, + {0x801f, 142}, + {0x8029, 142}, + {0xc038, 142}, }, /* 177 */ { - {2, 0x02, 144}, - {9, 0x02, 144}, - {23, 0x02, 144}, - {40, 0x03, 144}, - {2, 0x02, 145}, - {9, 0x02, 145}, - {23, 0x02, 145}, - {40, 0x03, 145}, - {2, 0x02, 148}, - {9, 0x02, 148}, - {23, 0x02, 148}, - {40, 0x03, 148}, - {2, 0x02, 159}, - {9, 0x02, 159}, - {23, 0x02, 159}, - {40, 0x03, 159}, + {0x8002, 144}, + {0x8009, 144}, + {0x8017, 144}, + {0xc028, 144}, + {0x8002, 145}, + {0x8009, 145}, + {0x8017, 145}, + {0xc028, 145}, + {0x8002, 148}, + {0x8009, 148}, + {0x8017, 148}, + {0xc028, 148}, + {0x8002, 159}, + {0x8009, 159}, + {0x8017, 159}, + {0xc028, 159}, }, /* 178 */ { - {3, 0x02, 144}, - {6, 0x02, 144}, - {10, 0x02, 144}, - {15, 0x02, 144}, - {24, 0x02, 144}, - {31, 0x02, 144}, - {41, 0x02, 144}, - {56, 0x03, 144}, - {3, 0x02, 145}, - {6, 0x02, 145}, - {10, 0x02, 145}, - {15, 0x02, 145}, - {24, 0x02, 145}, - {31, 0x02, 145}, - {41, 0x02, 145}, - {56, 0x03, 145}, + {0x8003, 144}, + {0x8006, 144}, + {0x800a, 144}, + {0x800f, 144}, + {0x8018, 144}, + {0x801f, 144}, + {0x8029, 144}, + {0xc038, 144}, + {0x8003, 145}, + {0x8006, 145}, + {0x800a, 145}, + {0x800f, 145}, + {0x8018, 145}, + {0x801f, 145}, + {0x8029, 145}, + {0xc038, 145}, }, /* 179 */ { - {3, 0x02, 148}, - {6, 0x02, 148}, - {10, 0x02, 148}, - {15, 0x02, 148}, - {24, 0x02, 148}, - {31, 0x02, 148}, - {41, 0x02, 148}, - {56, 0x03, 148}, - {3, 0x02, 159}, - {6, 0x02, 159}, - {10, 0x02, 159}, - {15, 0x02, 159}, - {24, 0x02, 159}, - {31, 0x02, 159}, - {41, 0x02, 159}, - {56, 0x03, 159}, + {0x8003, 148}, + {0x8006, 148}, + {0x800a, 148}, + {0x800f, 148}, + {0x8018, 148}, + {0x801f, 148}, + {0x8029, 148}, + {0xc038, 148}, + {0x8003, 159}, + {0x8006, 159}, + {0x800a, 159}, + {0x800f, 159}, + {0x8018, 159}, + {0x801f, 159}, + {0x8029, 159}, + {0xc038, 159}, }, /* 180 */ { - {0, 0x03, 171}, - {0, 0x03, 206}, - {0, 0x03, 215}, - {0, 0x03, 225}, - {0, 0x03, 236}, - {0, 0x03, 237}, - {188, 0x00, 0}, - {189, 0x00, 0}, - {193, 0x00, 0}, - {196, 0x00, 0}, - {200, 0x00, 0}, - {203, 0x00, 0}, - {209, 0x00, 0}, - {216, 0x00, 0}, - {224, 0x00, 0}, - {238, 0x00, 0}, + {0xc000, 171}, + {0xc000, 206}, + {0xc000, 215}, + {0xc000, 225}, + {0xc000, 236}, + {0xc000, 237}, + {0xbc, 0}, + {0xbd, 0}, + {0xc1, 0}, + {0xc4, 0}, + {0xc8, 0}, + {0xcb, 0}, + {0xd1, 0}, + {0xd8, 0}, + {0xe0, 0}, + {0xee, 0}, }, /* 181 */ { - {1, 0x02, 171}, - {22, 0x03, 171}, - {1, 0x02, 206}, - {22, 0x03, 206}, - {1, 0x02, 215}, - {22, 0x03, 215}, - {1, 0x02, 225}, - {22, 0x03, 225}, - {1, 0x02, 236}, - {22, 0x03, 236}, - {1, 0x02, 237}, - {22, 0x03, 237}, - {0, 0x03, 199}, - {0, 0x03, 207}, - {0, 0x03, 234}, - {0, 0x03, 235}, + {0x8001, 171}, + {0xc016, 171}, + {0x8001, 206}, + {0xc016, 206}, + {0x8001, 215}, + {0xc016, 215}, + {0x8001, 225}, + {0xc016, 225}, + {0x8001, 236}, + {0xc016, 236}, + {0x8001, 237}, + {0xc016, 237}, + {0xc000, 199}, + {0xc000, 207}, + {0xc000, 234}, + {0xc000, 235}, }, /* 182 */ { - {2, 0x02, 171}, - {9, 0x02, 171}, - {23, 0x02, 171}, - {40, 0x03, 171}, - {2, 0x02, 206}, - {9, 0x02, 206}, - {23, 0x02, 206}, - {40, 0x03, 206}, - {2, 0x02, 215}, - {9, 0x02, 215}, - {23, 0x02, 215}, - {40, 0x03, 215}, - {2, 0x02, 225}, - {9, 0x02, 225}, - {23, 0x02, 225}, - {40, 0x03, 225}, + {0x8002, 171}, + {0x8009, 171}, + {0x8017, 171}, + {0xc028, 171}, + {0x8002, 206}, + {0x8009, 206}, + {0x8017, 206}, + {0xc028, 206}, + {0x8002, 215}, + {0x8009, 215}, + {0x8017, 215}, + {0xc028, 215}, + {0x8002, 225}, + {0x8009, 225}, + {0x8017, 225}, + {0xc028, 225}, }, /* 183 */ { - {3, 0x02, 171}, - {6, 0x02, 171}, - {10, 0x02, 171}, - {15, 0x02, 171}, - {24, 0x02, 171}, - {31, 0x02, 171}, - {41, 0x02, 171}, - {56, 0x03, 171}, - {3, 0x02, 206}, - {6, 0x02, 206}, - {10, 0x02, 206}, - {15, 0x02, 206}, - {24, 0x02, 206}, - {31, 0x02, 206}, - {41, 0x02, 206}, - {56, 0x03, 206}, + {0x8003, 171}, + {0x8006, 171}, + {0x800a, 171}, + {0x800f, 171}, + {0x8018, 171}, + {0x801f, 171}, + {0x8029, 171}, + {0xc038, 171}, + {0x8003, 206}, + {0x8006, 206}, + {0x800a, 206}, + {0x800f, 206}, + {0x8018, 206}, + {0x801f, 206}, + {0x8029, 206}, + {0xc038, 206}, }, /* 184 */ { - {3, 0x02, 215}, - {6, 0x02, 215}, - {10, 0x02, 215}, - {15, 0x02, 215}, - {24, 0x02, 215}, - {31, 0x02, 215}, - {41, 0x02, 215}, - {56, 0x03, 215}, - {3, 0x02, 225}, - {6, 0x02, 225}, - {10, 0x02, 225}, - {15, 0x02, 225}, - {24, 0x02, 225}, - {31, 0x02, 225}, - {41, 0x02, 225}, - {56, 0x03, 225}, + {0x8003, 215}, + {0x8006, 215}, + {0x800a, 215}, + {0x800f, 215}, + {0x8018, 215}, + {0x801f, 215}, + {0x8029, 215}, + {0xc038, 215}, + {0x8003, 225}, + {0x8006, 225}, + {0x800a, 225}, + {0x800f, 225}, + {0x8018, 225}, + {0x801f, 225}, + {0x8029, 225}, + {0xc038, 225}, }, /* 185 */ { - {2, 0x02, 236}, - {9, 0x02, 236}, - {23, 0x02, 236}, - {40, 0x03, 236}, - {2, 0x02, 237}, - {9, 0x02, 237}, - {23, 0x02, 237}, - {40, 0x03, 237}, - {1, 0x02, 199}, - {22, 0x03, 199}, - {1, 0x02, 207}, - {22, 0x03, 207}, - {1, 0x02, 234}, - {22, 0x03, 234}, - {1, 0x02, 235}, - {22, 0x03, 235}, + {0x8002, 236}, + {0x8009, 236}, + {0x8017, 236}, + {0xc028, 236}, + {0x8002, 237}, + {0x8009, 237}, + {0x8017, 237}, + {0xc028, 237}, + {0x8001, 199}, + {0xc016, 199}, + {0x8001, 207}, + {0xc016, 207}, + {0x8001, 234}, + {0xc016, 234}, + {0x8001, 235}, + {0xc016, 235}, }, /* 186 */ { - {3, 0x02, 236}, - {6, 0x02, 236}, - {10, 0x02, 236}, - {15, 0x02, 236}, - {24, 0x02, 236}, - {31, 0x02, 236}, - {41, 0x02, 236}, - {56, 0x03, 236}, - {3, 0x02, 237}, - {6, 0x02, 237}, - {10, 0x02, 237}, - {15, 0x02, 237}, - {24, 0x02, 237}, - {31, 0x02, 237}, - {41, 0x02, 237}, - {56, 0x03, 237}, + {0x8003, 236}, + {0x8006, 236}, + {0x800a, 236}, + {0x800f, 236}, + {0x8018, 236}, + {0x801f, 236}, + {0x8029, 236}, + {0xc038, 236}, + {0x8003, 237}, + {0x8006, 237}, + {0x800a, 237}, + {0x800f, 237}, + {0x8018, 237}, + {0x801f, 237}, + {0x8029, 237}, + {0xc038, 237}, }, /* 187 */ { - {2, 0x02, 199}, - {9, 0x02, 199}, - {23, 0x02, 199}, - {40, 0x03, 199}, - {2, 0x02, 207}, - {9, 0x02, 207}, - {23, 0x02, 207}, - {40, 0x03, 207}, - {2, 0x02, 234}, - {9, 0x02, 234}, - {23, 0x02, 234}, - {40, 0x03, 234}, - {2, 0x02, 235}, - {9, 0x02, 235}, - {23, 0x02, 235}, - {40, 0x03, 235}, + {0x8002, 199}, + {0x8009, 199}, + {0x8017, 199}, + {0xc028, 199}, + {0x8002, 207}, + {0x8009, 207}, + {0x8017, 207}, + {0xc028, 207}, + {0x8002, 234}, + {0x8009, 234}, + {0x8017, 234}, + {0xc028, 234}, + {0x8002, 235}, + {0x8009, 235}, + {0x8017, 235}, + {0xc028, 235}, }, /* 188 */ { - {3, 0x02, 199}, - {6, 0x02, 199}, - {10, 0x02, 199}, - {15, 0x02, 199}, - {24, 0x02, 199}, - {31, 0x02, 199}, - {41, 0x02, 199}, - {56, 0x03, 199}, - {3, 0x02, 207}, - {6, 0x02, 207}, - {10, 0x02, 207}, - {15, 0x02, 207}, - {24, 0x02, 207}, - {31, 0x02, 207}, - {41, 0x02, 207}, - {56, 0x03, 207}, + {0x8003, 199}, + {0x8006, 199}, + {0x800a, 199}, + {0x800f, 199}, + {0x8018, 199}, + {0x801f, 199}, + {0x8029, 199}, + {0xc038, 199}, + {0x8003, 207}, + {0x8006, 207}, + {0x800a, 207}, + {0x800f, 207}, + {0x8018, 207}, + {0x801f, 207}, + {0x8029, 207}, + {0xc038, 207}, }, /* 189 */ { - {3, 0x02, 234}, - {6, 0x02, 234}, - {10, 0x02, 234}, - {15, 0x02, 234}, - {24, 0x02, 234}, - {31, 0x02, 234}, - {41, 0x02, 234}, - {56, 0x03, 234}, - {3, 0x02, 235}, - {6, 0x02, 235}, - {10, 0x02, 235}, - {15, 0x02, 235}, - {24, 0x02, 235}, - {31, 0x02, 235}, - {41, 0x02, 235}, - {56, 0x03, 235}, + {0x8003, 234}, + {0x8006, 234}, + {0x800a, 234}, + {0x800f, 234}, + {0x8018, 234}, + {0x801f, 234}, + {0x8029, 234}, + {0xc038, 234}, + {0x8003, 235}, + {0x8006, 235}, + {0x800a, 235}, + {0x800f, 235}, + {0x8018, 235}, + {0x801f, 235}, + {0x8029, 235}, + {0xc038, 235}, }, /* 190 */ { - {194, 0x00, 0}, - {195, 0x00, 0}, - {197, 0x00, 0}, - {198, 0x00, 0}, - {201, 0x00, 0}, - {202, 0x00, 0}, - {204, 0x00, 0}, - {205, 0x00, 0}, - {210, 0x00, 0}, - {213, 0x00, 0}, - {217, 0x00, 0}, - {220, 0x00, 0}, - {225, 0x00, 0}, - {231, 0x00, 0}, - {239, 0x00, 0}, - {246, 0x00, 0}, + {0xc2, 0}, + {0xc3, 0}, + {0xc5, 0}, + {0xc6, 0}, + {0xc9, 0}, + {0xca, 0}, + {0xcc, 0}, + {0xcd, 0}, + {0xd2, 0}, + {0xd5, 0}, + {0xd9, 0}, + {0xdc, 0}, + {0xe1, 0}, + {0xe7, 0}, + {0xef, 0}, + {0xf6, 0}, }, /* 191 */ { - {0, 0x03, 192}, - {0, 0x03, 193}, - {0, 0x03, 200}, - {0, 0x03, 201}, - {0, 0x03, 202}, - {0, 0x03, 205}, - {0, 0x03, 210}, - {0, 0x03, 213}, - {0, 0x03, 218}, - {0, 0x03, 219}, - {0, 0x03, 238}, - {0, 0x03, 240}, - {0, 0x03, 242}, - {0, 0x03, 243}, - {0, 0x03, 255}, - {206, 0x00, 0}, + {0xc000, 192}, + {0xc000, 193}, + {0xc000, 200}, + {0xc000, 201}, + {0xc000, 202}, + {0xc000, 205}, + {0xc000, 210}, + {0xc000, 213}, + {0xc000, 218}, + {0xc000, 219}, + {0xc000, 238}, + {0xc000, 240}, + {0xc000, 242}, + {0xc000, 243}, + {0xc000, 255}, + {0xce, 0}, }, /* 192 */ { - {1, 0x02, 192}, - {22, 0x03, 192}, - {1, 0x02, 193}, - {22, 0x03, 193}, - {1, 0x02, 200}, - {22, 0x03, 200}, - {1, 0x02, 201}, - {22, 0x03, 201}, - {1, 0x02, 202}, - {22, 0x03, 202}, - {1, 0x02, 205}, - {22, 0x03, 205}, - {1, 0x02, 210}, - {22, 0x03, 210}, - {1, 0x02, 213}, - {22, 0x03, 213}, + {0x8001, 192}, + {0xc016, 192}, + {0x8001, 193}, + {0xc016, 193}, + {0x8001, 200}, + {0xc016, 200}, + {0x8001, 201}, + {0xc016, 201}, + {0x8001, 202}, + {0xc016, 202}, + {0x8001, 205}, + {0xc016, 205}, + {0x8001, 210}, + {0xc016, 210}, + {0x8001, 213}, + {0xc016, 213}, }, /* 193 */ { - {2, 0x02, 192}, - {9, 0x02, 192}, - {23, 0x02, 192}, - {40, 0x03, 192}, - {2, 0x02, 193}, - {9, 0x02, 193}, - {23, 0x02, 193}, - {40, 0x03, 193}, - {2, 0x02, 200}, - {9, 0x02, 200}, - {23, 0x02, 200}, - {40, 0x03, 200}, - {2, 0x02, 201}, - {9, 0x02, 201}, - {23, 0x02, 201}, - {40, 0x03, 201}, + {0x8002, 192}, + {0x8009, 192}, + {0x8017, 192}, + {0xc028, 192}, + {0x8002, 193}, + {0x8009, 193}, + {0x8017, 193}, + {0xc028, 193}, + {0x8002, 200}, + {0x8009, 200}, + {0x8017, 200}, + {0xc028, 200}, + {0x8002, 201}, + {0x8009, 201}, + {0x8017, 201}, + {0xc028, 201}, }, /* 194 */ { - {3, 0x02, 192}, - {6, 0x02, 192}, - {10, 0x02, 192}, - {15, 0x02, 192}, - {24, 0x02, 192}, - {31, 0x02, 192}, - {41, 0x02, 192}, - {56, 0x03, 192}, - {3, 0x02, 193}, - {6, 0x02, 193}, - {10, 0x02, 193}, - {15, 0x02, 193}, - {24, 0x02, 193}, - {31, 0x02, 193}, - {41, 0x02, 193}, - {56, 0x03, 193}, + {0x8003, 192}, + {0x8006, 192}, + {0x800a, 192}, + {0x800f, 192}, + {0x8018, 192}, + {0x801f, 192}, + {0x8029, 192}, + {0xc038, 192}, + {0x8003, 193}, + {0x8006, 193}, + {0x800a, 193}, + {0x800f, 193}, + {0x8018, 193}, + {0x801f, 193}, + {0x8029, 193}, + {0xc038, 193}, }, /* 195 */ { - {3, 0x02, 200}, - {6, 0x02, 200}, - {10, 0x02, 200}, - {15, 0x02, 200}, - {24, 0x02, 200}, - {31, 0x02, 200}, - {41, 0x02, 200}, - {56, 0x03, 200}, - {3, 0x02, 201}, - {6, 0x02, 201}, - {10, 0x02, 201}, - {15, 0x02, 201}, - {24, 0x02, 201}, - {31, 0x02, 201}, - {41, 0x02, 201}, - {56, 0x03, 201}, + {0x8003, 200}, + {0x8006, 200}, + {0x800a, 200}, + {0x800f, 200}, + {0x8018, 200}, + {0x801f, 200}, + {0x8029, 200}, + {0xc038, 200}, + {0x8003, 201}, + {0x8006, 201}, + {0x800a, 201}, + {0x800f, 201}, + {0x8018, 201}, + {0x801f, 201}, + {0x8029, 201}, + {0xc038, 201}, }, /* 196 */ { - {2, 0x02, 202}, - {9, 0x02, 202}, - {23, 0x02, 202}, - {40, 0x03, 202}, - {2, 0x02, 205}, - {9, 0x02, 205}, - {23, 0x02, 205}, - {40, 0x03, 205}, - {2, 0x02, 210}, - {9, 0x02, 210}, - {23, 0x02, 210}, - {40, 0x03, 210}, - {2, 0x02, 213}, - {9, 0x02, 213}, - {23, 0x02, 213}, - {40, 0x03, 213}, + {0x8002, 202}, + {0x8009, 202}, + {0x8017, 202}, + {0xc028, 202}, + {0x8002, 205}, + {0x8009, 205}, + {0x8017, 205}, + {0xc028, 205}, + {0x8002, 210}, + {0x8009, 210}, + {0x8017, 210}, + {0xc028, 210}, + {0x8002, 213}, + {0x8009, 213}, + {0x8017, 213}, + {0xc028, 213}, }, /* 197 */ { - {3, 0x02, 202}, - {6, 0x02, 202}, - {10, 0x02, 202}, - {15, 0x02, 202}, - {24, 0x02, 202}, - {31, 0x02, 202}, - {41, 0x02, 202}, - {56, 0x03, 202}, - {3, 0x02, 205}, - {6, 0x02, 205}, - {10, 0x02, 205}, - {15, 0x02, 205}, - {24, 0x02, 205}, - {31, 0x02, 205}, - {41, 0x02, 205}, - {56, 0x03, 205}, + {0x8003, 202}, + {0x8006, 202}, + {0x800a, 202}, + {0x800f, 202}, + {0x8018, 202}, + {0x801f, 202}, + {0x8029, 202}, + {0xc038, 202}, + {0x8003, 205}, + {0x8006, 205}, + {0x800a, 205}, + {0x800f, 205}, + {0x8018, 205}, + {0x801f, 205}, + {0x8029, 205}, + {0xc038, 205}, }, /* 198 */ { - {3, 0x02, 210}, - {6, 0x02, 210}, - {10, 0x02, 210}, - {15, 0x02, 210}, - {24, 0x02, 210}, - {31, 0x02, 210}, - {41, 0x02, 210}, - {56, 0x03, 210}, - {3, 0x02, 213}, - {6, 0x02, 213}, - {10, 0x02, 213}, - {15, 0x02, 213}, - {24, 0x02, 213}, - {31, 0x02, 213}, - {41, 0x02, 213}, - {56, 0x03, 213}, + {0x8003, 210}, + {0x8006, 210}, + {0x800a, 210}, + {0x800f, 210}, + {0x8018, 210}, + {0x801f, 210}, + {0x8029, 210}, + {0xc038, 210}, + {0x8003, 213}, + {0x8006, 213}, + {0x800a, 213}, + {0x800f, 213}, + {0x8018, 213}, + {0x801f, 213}, + {0x8029, 213}, + {0xc038, 213}, }, /* 199 */ { - {1, 0x02, 218}, - {22, 0x03, 218}, - {1, 0x02, 219}, - {22, 0x03, 219}, - {1, 0x02, 238}, - {22, 0x03, 238}, - {1, 0x02, 240}, - {22, 0x03, 240}, - {1, 0x02, 242}, - {22, 0x03, 242}, - {1, 0x02, 243}, - {22, 0x03, 243}, - {1, 0x02, 255}, - {22, 0x03, 255}, - {0, 0x03, 203}, - {0, 0x03, 204}, + {0x8001, 218}, + {0xc016, 218}, + {0x8001, 219}, + {0xc016, 219}, + {0x8001, 238}, + {0xc016, 238}, + {0x8001, 240}, + {0xc016, 240}, + {0x8001, 242}, + {0xc016, 242}, + {0x8001, 243}, + {0xc016, 243}, + {0x8001, 255}, + {0xc016, 255}, + {0xc000, 203}, + {0xc000, 204}, }, /* 200 */ { - {2, 0x02, 218}, - {9, 0x02, 218}, - {23, 0x02, 218}, - {40, 0x03, 218}, - {2, 0x02, 219}, - {9, 0x02, 219}, - {23, 0x02, 219}, - {40, 0x03, 219}, - {2, 0x02, 238}, - {9, 0x02, 238}, - {23, 0x02, 238}, - {40, 0x03, 238}, - {2, 0x02, 240}, - {9, 0x02, 240}, - {23, 0x02, 240}, - {40, 0x03, 240}, + {0x8002, 218}, + {0x8009, 218}, + {0x8017, 218}, + {0xc028, 218}, + {0x8002, 219}, + {0x8009, 219}, + {0x8017, 219}, + {0xc028, 219}, + {0x8002, 238}, + {0x8009, 238}, + {0x8017, 238}, + {0xc028, 238}, + {0x8002, 240}, + {0x8009, 240}, + {0x8017, 240}, + {0xc028, 240}, }, /* 201 */ { - {3, 0x02, 218}, - {6, 0x02, 218}, - {10, 0x02, 218}, - {15, 0x02, 218}, - {24, 0x02, 218}, - {31, 0x02, 218}, - {41, 0x02, 218}, - {56, 0x03, 218}, - {3, 0x02, 219}, - {6, 0x02, 219}, - {10, 0x02, 219}, - {15, 0x02, 219}, - {24, 0x02, 219}, - {31, 0x02, 219}, - {41, 0x02, 219}, - {56, 0x03, 219}, + {0x8003, 218}, + {0x8006, 218}, + {0x800a, 218}, + {0x800f, 218}, + {0x8018, 218}, + {0x801f, 218}, + {0x8029, 218}, + {0xc038, 218}, + {0x8003, 219}, + {0x8006, 219}, + {0x800a, 219}, + {0x800f, 219}, + {0x8018, 219}, + {0x801f, 219}, + {0x8029, 219}, + {0xc038, 219}, }, /* 202 */ { - {3, 0x02, 238}, - {6, 0x02, 238}, - {10, 0x02, 238}, - {15, 0x02, 238}, - {24, 0x02, 238}, - {31, 0x02, 238}, - {41, 0x02, 238}, - {56, 0x03, 238}, - {3, 0x02, 240}, - {6, 0x02, 240}, - {10, 0x02, 240}, - {15, 0x02, 240}, - {24, 0x02, 240}, - {31, 0x02, 240}, - {41, 0x02, 240}, - {56, 0x03, 240}, + {0x8003, 238}, + {0x8006, 238}, + {0x800a, 238}, + {0x800f, 238}, + {0x8018, 238}, + {0x801f, 238}, + {0x8029, 238}, + {0xc038, 238}, + {0x8003, 240}, + {0x8006, 240}, + {0x800a, 240}, + {0x800f, 240}, + {0x8018, 240}, + {0x801f, 240}, + {0x8029, 240}, + {0xc038, 240}, }, /* 203 */ { - {2, 0x02, 242}, - {9, 0x02, 242}, - {23, 0x02, 242}, - {40, 0x03, 242}, - {2, 0x02, 243}, - {9, 0x02, 243}, - {23, 0x02, 243}, - {40, 0x03, 243}, - {2, 0x02, 255}, - {9, 0x02, 255}, - {23, 0x02, 255}, - {40, 0x03, 255}, - {1, 0x02, 203}, - {22, 0x03, 203}, - {1, 0x02, 204}, - {22, 0x03, 204}, + {0x8002, 242}, + {0x8009, 242}, + {0x8017, 242}, + {0xc028, 242}, + {0x8002, 243}, + {0x8009, 243}, + {0x8017, 243}, + {0xc028, 243}, + {0x8002, 255}, + {0x8009, 255}, + {0x8017, 255}, + {0xc028, 255}, + {0x8001, 203}, + {0xc016, 203}, + {0x8001, 204}, + {0xc016, 204}, }, /* 204 */ { - {3, 0x02, 242}, - {6, 0x02, 242}, - {10, 0x02, 242}, - {15, 0x02, 242}, - {24, 0x02, 242}, - {31, 0x02, 242}, - {41, 0x02, 242}, - {56, 0x03, 242}, - {3, 0x02, 243}, - {6, 0x02, 243}, - {10, 0x02, 243}, - {15, 0x02, 243}, - {24, 0x02, 243}, - {31, 0x02, 243}, - {41, 0x02, 243}, - {56, 0x03, 243}, + {0x8003, 242}, + {0x8006, 242}, + {0x800a, 242}, + {0x800f, 242}, + {0x8018, 242}, + {0x801f, 242}, + {0x8029, 242}, + {0xc038, 242}, + {0x8003, 243}, + {0x8006, 243}, + {0x800a, 243}, + {0x800f, 243}, + {0x8018, 243}, + {0x801f, 243}, + {0x8029, 243}, + {0xc038, 243}, }, /* 205 */ { - {3, 0x02, 255}, - {6, 0x02, 255}, - {10, 0x02, 255}, - {15, 0x02, 255}, - {24, 0x02, 255}, - {31, 0x02, 255}, - {41, 0x02, 255}, - {56, 0x03, 255}, - {2, 0x02, 203}, - {9, 0x02, 203}, - {23, 0x02, 203}, - {40, 0x03, 203}, - {2, 0x02, 204}, - {9, 0x02, 204}, - {23, 0x02, 204}, - {40, 0x03, 204}, + {0x8003, 255}, + {0x8006, 255}, + {0x800a, 255}, + {0x800f, 255}, + {0x8018, 255}, + {0x801f, 255}, + {0x8029, 255}, + {0xc038, 255}, + {0x8002, 203}, + {0x8009, 203}, + {0x8017, 203}, + {0xc028, 203}, + {0x8002, 204}, + {0x8009, 204}, + {0x8017, 204}, + {0xc028, 204}, }, /* 206 */ { - {3, 0x02, 203}, - {6, 0x02, 203}, - {10, 0x02, 203}, - {15, 0x02, 203}, - {24, 0x02, 203}, - {31, 0x02, 203}, - {41, 0x02, 203}, - {56, 0x03, 203}, - {3, 0x02, 204}, - {6, 0x02, 204}, - {10, 0x02, 204}, - {15, 0x02, 204}, - {24, 0x02, 204}, - {31, 0x02, 204}, - {41, 0x02, 204}, - {56, 0x03, 204}, + {0x8003, 203}, + {0x8006, 203}, + {0x800a, 203}, + {0x800f, 203}, + {0x8018, 203}, + {0x801f, 203}, + {0x8029, 203}, + {0xc038, 203}, + {0x8003, 204}, + {0x8006, 204}, + {0x800a, 204}, + {0x800f, 204}, + {0x8018, 204}, + {0x801f, 204}, + {0x8029, 204}, + {0xc038, 204}, }, /* 207 */ { - {211, 0x00, 0}, - {212, 0x00, 0}, - {214, 0x00, 0}, - {215, 0x00, 0}, - {218, 0x00, 0}, - {219, 0x00, 0}, - {221, 0x00, 0}, - {222, 0x00, 0}, - {226, 0x00, 0}, - {228, 0x00, 0}, - {232, 0x00, 0}, - {235, 0x00, 0}, - {240, 0x00, 0}, - {243, 0x00, 0}, - {247, 0x00, 0}, - {250, 0x00, 0}, + {0xd3, 0}, + {0xd4, 0}, + {0xd6, 0}, + {0xd7, 0}, + {0xda, 0}, + {0xdb, 0}, + {0xdd, 0}, + {0xde, 0}, + {0xe2, 0}, + {0xe4, 0}, + {0xe8, 0}, + {0xeb, 0}, + {0xf0, 0}, + {0xf3, 0}, + {0xf7, 0}, + {0xfa, 0}, }, /* 208 */ { - {0, 0x03, 211}, - {0, 0x03, 212}, - {0, 0x03, 214}, - {0, 0x03, 221}, - {0, 0x03, 222}, - {0, 0x03, 223}, - {0, 0x03, 241}, - {0, 0x03, 244}, - {0, 0x03, 245}, - {0, 0x03, 246}, - {0, 0x03, 247}, - {0, 0x03, 248}, - {0, 0x03, 250}, - {0, 0x03, 251}, - {0, 0x03, 252}, - {0, 0x03, 253}, + {0xc000, 211}, + {0xc000, 212}, + {0xc000, 214}, + {0xc000, 221}, + {0xc000, 222}, + {0xc000, 223}, + {0xc000, 241}, + {0xc000, 244}, + {0xc000, 245}, + {0xc000, 246}, + {0xc000, 247}, + {0xc000, 248}, + {0xc000, 250}, + {0xc000, 251}, + {0xc000, 252}, + {0xc000, 253}, }, /* 209 */ { - {1, 0x02, 211}, - {22, 0x03, 211}, - {1, 0x02, 212}, - {22, 0x03, 212}, - {1, 0x02, 214}, - {22, 0x03, 214}, - {1, 0x02, 221}, - {22, 0x03, 221}, - {1, 0x02, 222}, - {22, 0x03, 222}, - {1, 0x02, 223}, - {22, 0x03, 223}, - {1, 0x02, 241}, - {22, 0x03, 241}, - {1, 0x02, 244}, - {22, 0x03, 244}, + {0x8001, 211}, + {0xc016, 211}, + {0x8001, 212}, + {0xc016, 212}, + {0x8001, 214}, + {0xc016, 214}, + {0x8001, 221}, + {0xc016, 221}, + {0x8001, 222}, + {0xc016, 222}, + {0x8001, 223}, + {0xc016, 223}, + {0x8001, 241}, + {0xc016, 241}, + {0x8001, 244}, + {0xc016, 244}, }, /* 210 */ { - {2, 0x02, 211}, - {9, 0x02, 211}, - {23, 0x02, 211}, - {40, 0x03, 211}, - {2, 0x02, 212}, - {9, 0x02, 212}, - {23, 0x02, 212}, - {40, 0x03, 212}, - {2, 0x02, 214}, - {9, 0x02, 214}, - {23, 0x02, 214}, - {40, 0x03, 214}, - {2, 0x02, 221}, - {9, 0x02, 221}, - {23, 0x02, 221}, - {40, 0x03, 221}, + {0x8002, 211}, + {0x8009, 211}, + {0x8017, 211}, + {0xc028, 211}, + {0x8002, 212}, + {0x8009, 212}, + {0x8017, 212}, + {0xc028, 212}, + {0x8002, 214}, + {0x8009, 214}, + {0x8017, 214}, + {0xc028, 214}, + {0x8002, 221}, + {0x8009, 221}, + {0x8017, 221}, + {0xc028, 221}, }, /* 211 */ { - {3, 0x02, 211}, - {6, 0x02, 211}, - {10, 0x02, 211}, - {15, 0x02, 211}, - {24, 0x02, 211}, - {31, 0x02, 211}, - {41, 0x02, 211}, - {56, 0x03, 211}, - {3, 0x02, 212}, - {6, 0x02, 212}, - {10, 0x02, 212}, - {15, 0x02, 212}, - {24, 0x02, 212}, - {31, 0x02, 212}, - {41, 0x02, 212}, - {56, 0x03, 212}, + {0x8003, 211}, + {0x8006, 211}, + {0x800a, 211}, + {0x800f, 211}, + {0x8018, 211}, + {0x801f, 211}, + {0x8029, 211}, + {0xc038, 211}, + {0x8003, 212}, + {0x8006, 212}, + {0x800a, 212}, + {0x800f, 212}, + {0x8018, 212}, + {0x801f, 212}, + {0x8029, 212}, + {0xc038, 212}, }, /* 212 */ { - {3, 0x02, 214}, - {6, 0x02, 214}, - {10, 0x02, 214}, - {15, 0x02, 214}, - {24, 0x02, 214}, - {31, 0x02, 214}, - {41, 0x02, 214}, - {56, 0x03, 214}, - {3, 0x02, 221}, - {6, 0x02, 221}, - {10, 0x02, 221}, - {15, 0x02, 221}, - {24, 0x02, 221}, - {31, 0x02, 221}, - {41, 0x02, 221}, - {56, 0x03, 221}, + {0x8003, 214}, + {0x8006, 214}, + {0x800a, 214}, + {0x800f, 214}, + {0x8018, 214}, + {0x801f, 214}, + {0x8029, 214}, + {0xc038, 214}, + {0x8003, 221}, + {0x8006, 221}, + {0x800a, 221}, + {0x800f, 221}, + {0x8018, 221}, + {0x801f, 221}, + {0x8029, 221}, + {0xc038, 221}, }, /* 213 */ { - {2, 0x02, 222}, - {9, 0x02, 222}, - {23, 0x02, 222}, - {40, 0x03, 222}, - {2, 0x02, 223}, - {9, 0x02, 223}, - {23, 0x02, 223}, - {40, 0x03, 223}, - {2, 0x02, 241}, - {9, 0x02, 241}, - {23, 0x02, 241}, - {40, 0x03, 241}, - {2, 0x02, 244}, - {9, 0x02, 244}, - {23, 0x02, 244}, - {40, 0x03, 244}, + {0x8002, 222}, + {0x8009, 222}, + {0x8017, 222}, + {0xc028, 222}, + {0x8002, 223}, + {0x8009, 223}, + {0x8017, 223}, + {0xc028, 223}, + {0x8002, 241}, + {0x8009, 241}, + {0x8017, 241}, + {0xc028, 241}, + {0x8002, 244}, + {0x8009, 244}, + {0x8017, 244}, + {0xc028, 244}, }, /* 214 */ { - {3, 0x02, 222}, - {6, 0x02, 222}, - {10, 0x02, 222}, - {15, 0x02, 222}, - {24, 0x02, 222}, - {31, 0x02, 222}, - {41, 0x02, 222}, - {56, 0x03, 222}, - {3, 0x02, 223}, - {6, 0x02, 223}, - {10, 0x02, 223}, - {15, 0x02, 223}, - {24, 0x02, 223}, - {31, 0x02, 223}, - {41, 0x02, 223}, - {56, 0x03, 223}, + {0x8003, 222}, + {0x8006, 222}, + {0x800a, 222}, + {0x800f, 222}, + {0x8018, 222}, + {0x801f, 222}, + {0x8029, 222}, + {0xc038, 222}, + {0x8003, 223}, + {0x8006, 223}, + {0x800a, 223}, + {0x800f, 223}, + {0x8018, 223}, + {0x801f, 223}, + {0x8029, 223}, + {0xc038, 223}, }, /* 215 */ { - {3, 0x02, 241}, - {6, 0x02, 241}, - {10, 0x02, 241}, - {15, 0x02, 241}, - {24, 0x02, 241}, - {31, 0x02, 241}, - {41, 0x02, 241}, - {56, 0x03, 241}, - {3, 0x02, 244}, - {6, 0x02, 244}, - {10, 0x02, 244}, - {15, 0x02, 244}, - {24, 0x02, 244}, - {31, 0x02, 244}, - {41, 0x02, 244}, - {56, 0x03, 244}, + {0x8003, 241}, + {0x8006, 241}, + {0x800a, 241}, + {0x800f, 241}, + {0x8018, 241}, + {0x801f, 241}, + {0x8029, 241}, + {0xc038, 241}, + {0x8003, 244}, + {0x8006, 244}, + {0x800a, 244}, + {0x800f, 244}, + {0x8018, 244}, + {0x801f, 244}, + {0x8029, 244}, + {0xc038, 244}, }, /* 216 */ { - {1, 0x02, 245}, - {22, 0x03, 245}, - {1, 0x02, 246}, - {22, 0x03, 246}, - {1, 0x02, 247}, - {22, 0x03, 247}, - {1, 0x02, 248}, - {22, 0x03, 248}, - {1, 0x02, 250}, - {22, 0x03, 250}, - {1, 0x02, 251}, - {22, 0x03, 251}, - {1, 0x02, 252}, - {22, 0x03, 252}, - {1, 0x02, 253}, - {22, 0x03, 253}, + {0x8001, 245}, + {0xc016, 245}, + {0x8001, 246}, + {0xc016, 246}, + {0x8001, 247}, + {0xc016, 247}, + {0x8001, 248}, + {0xc016, 248}, + {0x8001, 250}, + {0xc016, 250}, + {0x8001, 251}, + {0xc016, 251}, + {0x8001, 252}, + {0xc016, 252}, + {0x8001, 253}, + {0xc016, 253}, }, /* 217 */ { - {2, 0x02, 245}, - {9, 0x02, 245}, - {23, 0x02, 245}, - {40, 0x03, 245}, - {2, 0x02, 246}, - {9, 0x02, 246}, - {23, 0x02, 246}, - {40, 0x03, 246}, - {2, 0x02, 247}, - {9, 0x02, 247}, - {23, 0x02, 247}, - {40, 0x03, 247}, - {2, 0x02, 248}, - {9, 0x02, 248}, - {23, 0x02, 248}, - {40, 0x03, 248}, + {0x8002, 245}, + {0x8009, 245}, + {0x8017, 245}, + {0xc028, 245}, + {0x8002, 246}, + {0x8009, 246}, + {0x8017, 246}, + {0xc028, 246}, + {0x8002, 247}, + {0x8009, 247}, + {0x8017, 247}, + {0xc028, 247}, + {0x8002, 248}, + {0x8009, 248}, + {0x8017, 248}, + {0xc028, 248}, }, /* 218 */ { - {3, 0x02, 245}, - {6, 0x02, 245}, - {10, 0x02, 245}, - {15, 0x02, 245}, - {24, 0x02, 245}, - {31, 0x02, 245}, - {41, 0x02, 245}, - {56, 0x03, 245}, - {3, 0x02, 246}, - {6, 0x02, 246}, - {10, 0x02, 246}, - {15, 0x02, 246}, - {24, 0x02, 246}, - {31, 0x02, 246}, - {41, 0x02, 246}, - {56, 0x03, 246}, + {0x8003, 245}, + {0x8006, 245}, + {0x800a, 245}, + {0x800f, 245}, + {0x8018, 245}, + {0x801f, 245}, + {0x8029, 245}, + {0xc038, 245}, + {0x8003, 246}, + {0x8006, 246}, + {0x800a, 246}, + {0x800f, 246}, + {0x8018, 246}, + {0x801f, 246}, + {0x8029, 246}, + {0xc038, 246}, }, /* 219 */ { - {3, 0x02, 247}, - {6, 0x02, 247}, - {10, 0x02, 247}, - {15, 0x02, 247}, - {24, 0x02, 247}, - {31, 0x02, 247}, - {41, 0x02, 247}, - {56, 0x03, 247}, - {3, 0x02, 248}, - {6, 0x02, 248}, - {10, 0x02, 248}, - {15, 0x02, 248}, - {24, 0x02, 248}, - {31, 0x02, 248}, - {41, 0x02, 248}, - {56, 0x03, 248}, + {0x8003, 247}, + {0x8006, 247}, + {0x800a, 247}, + {0x800f, 247}, + {0x8018, 247}, + {0x801f, 247}, + {0x8029, 247}, + {0xc038, 247}, + {0x8003, 248}, + {0x8006, 248}, + {0x800a, 248}, + {0x800f, 248}, + {0x8018, 248}, + {0x801f, 248}, + {0x8029, 248}, + {0xc038, 248}, }, /* 220 */ { - {2, 0x02, 250}, - {9, 0x02, 250}, - {23, 0x02, 250}, - {40, 0x03, 250}, - {2, 0x02, 251}, - {9, 0x02, 251}, - {23, 0x02, 251}, - {40, 0x03, 251}, - {2, 0x02, 252}, - {9, 0x02, 252}, - {23, 0x02, 252}, - {40, 0x03, 252}, - {2, 0x02, 253}, - {9, 0x02, 253}, - {23, 0x02, 253}, - {40, 0x03, 253}, + {0x8002, 250}, + {0x8009, 250}, + {0x8017, 250}, + {0xc028, 250}, + {0x8002, 251}, + {0x8009, 251}, + {0x8017, 251}, + {0xc028, 251}, + {0x8002, 252}, + {0x8009, 252}, + {0x8017, 252}, + {0xc028, 252}, + {0x8002, 253}, + {0x8009, 253}, + {0x8017, 253}, + {0xc028, 253}, }, /* 221 */ { - {3, 0x02, 250}, - {6, 0x02, 250}, - {10, 0x02, 250}, - {15, 0x02, 250}, - {24, 0x02, 250}, - {31, 0x02, 250}, - {41, 0x02, 250}, - {56, 0x03, 250}, - {3, 0x02, 251}, - {6, 0x02, 251}, - {10, 0x02, 251}, - {15, 0x02, 251}, - {24, 0x02, 251}, - {31, 0x02, 251}, - {41, 0x02, 251}, - {56, 0x03, 251}, + {0x8003, 250}, + {0x8006, 250}, + {0x800a, 250}, + {0x800f, 250}, + {0x8018, 250}, + {0x801f, 250}, + {0x8029, 250}, + {0xc038, 250}, + {0x8003, 251}, + {0x8006, 251}, + {0x800a, 251}, + {0x800f, 251}, + {0x8018, 251}, + {0x801f, 251}, + {0x8029, 251}, + {0xc038, 251}, }, /* 222 */ { - {3, 0x02, 252}, - {6, 0x02, 252}, - {10, 0x02, 252}, - {15, 0x02, 252}, - {24, 0x02, 252}, - {31, 0x02, 252}, - {41, 0x02, 252}, - {56, 0x03, 252}, - {3, 0x02, 253}, - {6, 0x02, 253}, - {10, 0x02, 253}, - {15, 0x02, 253}, - {24, 0x02, 253}, - {31, 0x02, 253}, - {41, 0x02, 253}, - {56, 0x03, 253}, + {0x8003, 252}, + {0x8006, 252}, + {0x800a, 252}, + {0x800f, 252}, + {0x8018, 252}, + {0x801f, 252}, + {0x8029, 252}, + {0xc038, 252}, + {0x8003, 253}, + {0x8006, 253}, + {0x800a, 253}, + {0x800f, 253}, + {0x8018, 253}, + {0x801f, 253}, + {0x8029, 253}, + {0xc038, 253}, }, /* 223 */ { - {0, 0x03, 254}, - {227, 0x00, 0}, - {229, 0x00, 0}, - {230, 0x00, 0}, - {233, 0x00, 0}, - {234, 0x00, 0}, - {236, 0x00, 0}, - {237, 0x00, 0}, - {241, 0x00, 0}, - {242, 0x00, 0}, - {244, 0x00, 0}, - {245, 0x00, 0}, - {248, 0x00, 0}, - {249, 0x00, 0}, - {251, 0x00, 0}, - {252, 0x00, 0}, + {0xc000, 254}, + {0xe3, 0}, + {0xe5, 0}, + {0xe6, 0}, + {0xe9, 0}, + {0xea, 0}, + {0xec, 0}, + {0xed, 0}, + {0xf1, 0}, + {0xf2, 0}, + {0xf4, 0}, + {0xf5, 0}, + {0xf8, 0}, + {0xf9, 0}, + {0xfb, 0}, + {0xfc, 0}, }, /* 224 */ { - {1, 0x02, 254}, - {22, 0x03, 254}, - {0, 0x03, 2}, - {0, 0x03, 3}, - {0, 0x03, 4}, - {0, 0x03, 5}, - {0, 0x03, 6}, - {0, 0x03, 7}, - {0, 0x03, 8}, - {0, 0x03, 11}, - {0, 0x03, 12}, - {0, 0x03, 14}, - {0, 0x03, 15}, - {0, 0x03, 16}, - {0, 0x03, 17}, - {0, 0x03, 18}, + {0x8001, 254}, + {0xc016, 254}, + {0xc000, 2}, + {0xc000, 3}, + {0xc000, 4}, + {0xc000, 5}, + {0xc000, 6}, + {0xc000, 7}, + {0xc000, 8}, + {0xc000, 11}, + {0xc000, 12}, + {0xc000, 14}, + {0xc000, 15}, + {0xc000, 16}, + {0xc000, 17}, + {0xc000, 18}, }, /* 225 */ { - {2, 0x02, 254}, - {9, 0x02, 254}, - {23, 0x02, 254}, - {40, 0x03, 254}, - {1, 0x02, 2}, - {22, 0x03, 2}, - {1, 0x02, 3}, - {22, 0x03, 3}, - {1, 0x02, 4}, - {22, 0x03, 4}, - {1, 0x02, 5}, - {22, 0x03, 5}, - {1, 0x02, 6}, - {22, 0x03, 6}, - {1, 0x02, 7}, - {22, 0x03, 7}, + {0x8002, 254}, + {0x8009, 254}, + {0x8017, 254}, + {0xc028, 254}, + {0x8001, 2}, + {0xc016, 2}, + {0x8001, 3}, + {0xc016, 3}, + {0x8001, 4}, + {0xc016, 4}, + {0x8001, 5}, + {0xc016, 5}, + {0x8001, 6}, + {0xc016, 6}, + {0x8001, 7}, + {0xc016, 7}, }, /* 226 */ { - {3, 0x02, 254}, - {6, 0x02, 254}, - {10, 0x02, 254}, - {15, 0x02, 254}, - {24, 0x02, 254}, - {31, 0x02, 254}, - {41, 0x02, 254}, - {56, 0x03, 254}, - {2, 0x02, 2}, - {9, 0x02, 2}, - {23, 0x02, 2}, - {40, 0x03, 2}, - {2, 0x02, 3}, - {9, 0x02, 3}, - {23, 0x02, 3}, - {40, 0x03, 3}, + {0x8003, 254}, + {0x8006, 254}, + {0x800a, 254}, + {0x800f, 254}, + {0x8018, 254}, + {0x801f, 254}, + {0x8029, 254}, + {0xc038, 254}, + {0x8002, 2}, + {0x8009, 2}, + {0x8017, 2}, + {0xc028, 2}, + {0x8002, 3}, + {0x8009, 3}, + {0x8017, 3}, + {0xc028, 3}, }, /* 227 */ { - {3, 0x02, 2}, - {6, 0x02, 2}, - {10, 0x02, 2}, - {15, 0x02, 2}, - {24, 0x02, 2}, - {31, 0x02, 2}, - {41, 0x02, 2}, - {56, 0x03, 2}, - {3, 0x02, 3}, - {6, 0x02, 3}, - {10, 0x02, 3}, - {15, 0x02, 3}, - {24, 0x02, 3}, - {31, 0x02, 3}, - {41, 0x02, 3}, - {56, 0x03, 3}, + {0x8003, 2}, + {0x8006, 2}, + {0x800a, 2}, + {0x800f, 2}, + {0x8018, 2}, + {0x801f, 2}, + {0x8029, 2}, + {0xc038, 2}, + {0x8003, 3}, + {0x8006, 3}, + {0x800a, 3}, + {0x800f, 3}, + {0x8018, 3}, + {0x801f, 3}, + {0x8029, 3}, + {0xc038, 3}, }, /* 228 */ { - {2, 0x02, 4}, - {9, 0x02, 4}, - {23, 0x02, 4}, - {40, 0x03, 4}, - {2, 0x02, 5}, - {9, 0x02, 5}, - {23, 0x02, 5}, - {40, 0x03, 5}, - {2, 0x02, 6}, - {9, 0x02, 6}, - {23, 0x02, 6}, - {40, 0x03, 6}, - {2, 0x02, 7}, - {9, 0x02, 7}, - {23, 0x02, 7}, - {40, 0x03, 7}, + {0x8002, 4}, + {0x8009, 4}, + {0x8017, 4}, + {0xc028, 4}, + {0x8002, 5}, + {0x8009, 5}, + {0x8017, 5}, + {0xc028, 5}, + {0x8002, 6}, + {0x8009, 6}, + {0x8017, 6}, + {0xc028, 6}, + {0x8002, 7}, + {0x8009, 7}, + {0x8017, 7}, + {0xc028, 7}, }, /* 229 */ { - {3, 0x02, 4}, - {6, 0x02, 4}, - {10, 0x02, 4}, - {15, 0x02, 4}, - {24, 0x02, 4}, - {31, 0x02, 4}, - {41, 0x02, 4}, - {56, 0x03, 4}, - {3, 0x02, 5}, - {6, 0x02, 5}, - {10, 0x02, 5}, - {15, 0x02, 5}, - {24, 0x02, 5}, - {31, 0x02, 5}, - {41, 0x02, 5}, - {56, 0x03, 5}, + {0x8003, 4}, + {0x8006, 4}, + {0x800a, 4}, + {0x800f, 4}, + {0x8018, 4}, + {0x801f, 4}, + {0x8029, 4}, + {0xc038, 4}, + {0x8003, 5}, + {0x8006, 5}, + {0x800a, 5}, + {0x800f, 5}, + {0x8018, 5}, + {0x801f, 5}, + {0x8029, 5}, + {0xc038, 5}, }, /* 230 */ { - {3, 0x02, 6}, - {6, 0x02, 6}, - {10, 0x02, 6}, - {15, 0x02, 6}, - {24, 0x02, 6}, - {31, 0x02, 6}, - {41, 0x02, 6}, - {56, 0x03, 6}, - {3, 0x02, 7}, - {6, 0x02, 7}, - {10, 0x02, 7}, - {15, 0x02, 7}, - {24, 0x02, 7}, - {31, 0x02, 7}, - {41, 0x02, 7}, - {56, 0x03, 7}, + {0x8003, 6}, + {0x8006, 6}, + {0x800a, 6}, + {0x800f, 6}, + {0x8018, 6}, + {0x801f, 6}, + {0x8029, 6}, + {0xc038, 6}, + {0x8003, 7}, + {0x8006, 7}, + {0x800a, 7}, + {0x800f, 7}, + {0x8018, 7}, + {0x801f, 7}, + {0x8029, 7}, + {0xc038, 7}, }, /* 231 */ { - {1, 0x02, 8}, - {22, 0x03, 8}, - {1, 0x02, 11}, - {22, 0x03, 11}, - {1, 0x02, 12}, - {22, 0x03, 12}, - {1, 0x02, 14}, - {22, 0x03, 14}, - {1, 0x02, 15}, - {22, 0x03, 15}, - {1, 0x02, 16}, - {22, 0x03, 16}, - {1, 0x02, 17}, - {22, 0x03, 17}, - {1, 0x02, 18}, - {22, 0x03, 18}, + {0x8001, 8}, + {0xc016, 8}, + {0x8001, 11}, + {0xc016, 11}, + {0x8001, 12}, + {0xc016, 12}, + {0x8001, 14}, + {0xc016, 14}, + {0x8001, 15}, + {0xc016, 15}, + {0x8001, 16}, + {0xc016, 16}, + {0x8001, 17}, + {0xc016, 17}, + {0x8001, 18}, + {0xc016, 18}, }, /* 232 */ { - {2, 0x02, 8}, - {9, 0x02, 8}, - {23, 0x02, 8}, - {40, 0x03, 8}, - {2, 0x02, 11}, - {9, 0x02, 11}, - {23, 0x02, 11}, - {40, 0x03, 11}, - {2, 0x02, 12}, - {9, 0x02, 12}, - {23, 0x02, 12}, - {40, 0x03, 12}, - {2, 0x02, 14}, - {9, 0x02, 14}, - {23, 0x02, 14}, - {40, 0x03, 14}, + {0x8002, 8}, + {0x8009, 8}, + {0x8017, 8}, + {0xc028, 8}, + {0x8002, 11}, + {0x8009, 11}, + {0x8017, 11}, + {0xc028, 11}, + {0x8002, 12}, + {0x8009, 12}, + {0x8017, 12}, + {0xc028, 12}, + {0x8002, 14}, + {0x8009, 14}, + {0x8017, 14}, + {0xc028, 14}, }, /* 233 */ { - {3, 0x02, 8}, - {6, 0x02, 8}, - {10, 0x02, 8}, - {15, 0x02, 8}, - {24, 0x02, 8}, - {31, 0x02, 8}, - {41, 0x02, 8}, - {56, 0x03, 8}, - {3, 0x02, 11}, - {6, 0x02, 11}, - {10, 0x02, 11}, - {15, 0x02, 11}, - {24, 0x02, 11}, - {31, 0x02, 11}, - {41, 0x02, 11}, - {56, 0x03, 11}, + {0x8003, 8}, + {0x8006, 8}, + {0x800a, 8}, + {0x800f, 8}, + {0x8018, 8}, + {0x801f, 8}, + {0x8029, 8}, + {0xc038, 8}, + {0x8003, 11}, + {0x8006, 11}, + {0x800a, 11}, + {0x800f, 11}, + {0x8018, 11}, + {0x801f, 11}, + {0x8029, 11}, + {0xc038, 11}, }, /* 234 */ { - {3, 0x02, 12}, - {6, 0x02, 12}, - {10, 0x02, 12}, - {15, 0x02, 12}, - {24, 0x02, 12}, - {31, 0x02, 12}, - {41, 0x02, 12}, - {56, 0x03, 12}, - {3, 0x02, 14}, - {6, 0x02, 14}, - {10, 0x02, 14}, - {15, 0x02, 14}, - {24, 0x02, 14}, - {31, 0x02, 14}, - {41, 0x02, 14}, - {56, 0x03, 14}, + {0x8003, 12}, + {0x8006, 12}, + {0x800a, 12}, + {0x800f, 12}, + {0x8018, 12}, + {0x801f, 12}, + {0x8029, 12}, + {0xc038, 12}, + {0x8003, 14}, + {0x8006, 14}, + {0x800a, 14}, + {0x800f, 14}, + {0x8018, 14}, + {0x801f, 14}, + {0x8029, 14}, + {0xc038, 14}, }, /* 235 */ { - {2, 0x02, 15}, - {9, 0x02, 15}, - {23, 0x02, 15}, - {40, 0x03, 15}, - {2, 0x02, 16}, - {9, 0x02, 16}, - {23, 0x02, 16}, - {40, 0x03, 16}, - {2, 0x02, 17}, - {9, 0x02, 17}, - {23, 0x02, 17}, - {40, 0x03, 17}, - {2, 0x02, 18}, - {9, 0x02, 18}, - {23, 0x02, 18}, - {40, 0x03, 18}, + {0x8002, 15}, + {0x8009, 15}, + {0x8017, 15}, + {0xc028, 15}, + {0x8002, 16}, + {0x8009, 16}, + {0x8017, 16}, + {0xc028, 16}, + {0x8002, 17}, + {0x8009, 17}, + {0x8017, 17}, + {0xc028, 17}, + {0x8002, 18}, + {0x8009, 18}, + {0x8017, 18}, + {0xc028, 18}, }, /* 236 */ { - {3, 0x02, 15}, - {6, 0x02, 15}, - {10, 0x02, 15}, - {15, 0x02, 15}, - {24, 0x02, 15}, - {31, 0x02, 15}, - {41, 0x02, 15}, - {56, 0x03, 15}, - {3, 0x02, 16}, - {6, 0x02, 16}, - {10, 0x02, 16}, - {15, 0x02, 16}, - {24, 0x02, 16}, - {31, 0x02, 16}, - {41, 0x02, 16}, - {56, 0x03, 16}, + {0x8003, 15}, + {0x8006, 15}, + {0x800a, 15}, + {0x800f, 15}, + {0x8018, 15}, + {0x801f, 15}, + {0x8029, 15}, + {0xc038, 15}, + {0x8003, 16}, + {0x8006, 16}, + {0x800a, 16}, + {0x800f, 16}, + {0x8018, 16}, + {0x801f, 16}, + {0x8029, 16}, + {0xc038, 16}, }, /* 237 */ { - {3, 0x02, 17}, - {6, 0x02, 17}, - {10, 0x02, 17}, - {15, 0x02, 17}, - {24, 0x02, 17}, - {31, 0x02, 17}, - {41, 0x02, 17}, - {56, 0x03, 17}, - {3, 0x02, 18}, - {6, 0x02, 18}, - {10, 0x02, 18}, - {15, 0x02, 18}, - {24, 0x02, 18}, - {31, 0x02, 18}, - {41, 0x02, 18}, - {56, 0x03, 18}, + {0x8003, 17}, + {0x8006, 17}, + {0x800a, 17}, + {0x800f, 17}, + {0x8018, 17}, + {0x801f, 17}, + {0x8029, 17}, + {0xc038, 17}, + {0x8003, 18}, + {0x8006, 18}, + {0x800a, 18}, + {0x800f, 18}, + {0x8018, 18}, + {0x801f, 18}, + {0x8029, 18}, + {0xc038, 18}, }, /* 238 */ { - {0, 0x03, 19}, - {0, 0x03, 20}, - {0, 0x03, 21}, - {0, 0x03, 23}, - {0, 0x03, 24}, - {0, 0x03, 25}, - {0, 0x03, 26}, - {0, 0x03, 27}, - {0, 0x03, 28}, - {0, 0x03, 29}, - {0, 0x03, 30}, - {0, 0x03, 31}, - {0, 0x03, 127}, - {0, 0x03, 220}, - {0, 0x03, 249}, - {253, 0x00, 0}, + {0xc000, 19}, + {0xc000, 20}, + {0xc000, 21}, + {0xc000, 23}, + {0xc000, 24}, + {0xc000, 25}, + {0xc000, 26}, + {0xc000, 27}, + {0xc000, 28}, + {0xc000, 29}, + {0xc000, 30}, + {0xc000, 31}, + {0xc000, 127}, + {0xc000, 220}, + {0xc000, 249}, + {0xfd, 0}, }, /* 239 */ { - {1, 0x02, 19}, - {22, 0x03, 19}, - {1, 0x02, 20}, - {22, 0x03, 20}, - {1, 0x02, 21}, - {22, 0x03, 21}, - {1, 0x02, 23}, - {22, 0x03, 23}, - {1, 0x02, 24}, - {22, 0x03, 24}, - {1, 0x02, 25}, - {22, 0x03, 25}, - {1, 0x02, 26}, - {22, 0x03, 26}, - {1, 0x02, 27}, - {22, 0x03, 27}, + {0x8001, 19}, + {0xc016, 19}, + {0x8001, 20}, + {0xc016, 20}, + {0x8001, 21}, + {0xc016, 21}, + {0x8001, 23}, + {0xc016, 23}, + {0x8001, 24}, + {0xc016, 24}, + {0x8001, 25}, + {0xc016, 25}, + {0x8001, 26}, + {0xc016, 26}, + {0x8001, 27}, + {0xc016, 27}, }, /* 240 */ { - {2, 0x02, 19}, - {9, 0x02, 19}, - {23, 0x02, 19}, - {40, 0x03, 19}, - {2, 0x02, 20}, - {9, 0x02, 20}, - {23, 0x02, 20}, - {40, 0x03, 20}, - {2, 0x02, 21}, - {9, 0x02, 21}, - {23, 0x02, 21}, - {40, 0x03, 21}, - {2, 0x02, 23}, - {9, 0x02, 23}, - {23, 0x02, 23}, - {40, 0x03, 23}, + {0x8002, 19}, + {0x8009, 19}, + {0x8017, 19}, + {0xc028, 19}, + {0x8002, 20}, + {0x8009, 20}, + {0x8017, 20}, + {0xc028, 20}, + {0x8002, 21}, + {0x8009, 21}, + {0x8017, 21}, + {0xc028, 21}, + {0x8002, 23}, + {0x8009, 23}, + {0x8017, 23}, + {0xc028, 23}, }, /* 241 */ { - {3, 0x02, 19}, - {6, 0x02, 19}, - {10, 0x02, 19}, - {15, 0x02, 19}, - {24, 0x02, 19}, - {31, 0x02, 19}, - {41, 0x02, 19}, - {56, 0x03, 19}, - {3, 0x02, 20}, - {6, 0x02, 20}, - {10, 0x02, 20}, - {15, 0x02, 20}, - {24, 0x02, 20}, - {31, 0x02, 20}, - {41, 0x02, 20}, - {56, 0x03, 20}, + {0x8003, 19}, + {0x8006, 19}, + {0x800a, 19}, + {0x800f, 19}, + {0x8018, 19}, + {0x801f, 19}, + {0x8029, 19}, + {0xc038, 19}, + {0x8003, 20}, + {0x8006, 20}, + {0x800a, 20}, + {0x800f, 20}, + {0x8018, 20}, + {0x801f, 20}, + {0x8029, 20}, + {0xc038, 20}, }, /* 242 */ { - {3, 0x02, 21}, - {6, 0x02, 21}, - {10, 0x02, 21}, - {15, 0x02, 21}, - {24, 0x02, 21}, - {31, 0x02, 21}, - {41, 0x02, 21}, - {56, 0x03, 21}, - {3, 0x02, 23}, - {6, 0x02, 23}, - {10, 0x02, 23}, - {15, 0x02, 23}, - {24, 0x02, 23}, - {31, 0x02, 23}, - {41, 0x02, 23}, - {56, 0x03, 23}, + {0x8003, 21}, + {0x8006, 21}, + {0x800a, 21}, + {0x800f, 21}, + {0x8018, 21}, + {0x801f, 21}, + {0x8029, 21}, + {0xc038, 21}, + {0x8003, 23}, + {0x8006, 23}, + {0x800a, 23}, + {0x800f, 23}, + {0x8018, 23}, + {0x801f, 23}, + {0x8029, 23}, + {0xc038, 23}, }, /* 243 */ { - {2, 0x02, 24}, - {9, 0x02, 24}, - {23, 0x02, 24}, - {40, 0x03, 24}, - {2, 0x02, 25}, - {9, 0x02, 25}, - {23, 0x02, 25}, - {40, 0x03, 25}, - {2, 0x02, 26}, - {9, 0x02, 26}, - {23, 0x02, 26}, - {40, 0x03, 26}, - {2, 0x02, 27}, - {9, 0x02, 27}, - {23, 0x02, 27}, - {40, 0x03, 27}, + {0x8002, 24}, + {0x8009, 24}, + {0x8017, 24}, + {0xc028, 24}, + {0x8002, 25}, + {0x8009, 25}, + {0x8017, 25}, + {0xc028, 25}, + {0x8002, 26}, + {0x8009, 26}, + {0x8017, 26}, + {0xc028, 26}, + {0x8002, 27}, + {0x8009, 27}, + {0x8017, 27}, + {0xc028, 27}, }, /* 244 */ { - {3, 0x02, 24}, - {6, 0x02, 24}, - {10, 0x02, 24}, - {15, 0x02, 24}, - {24, 0x02, 24}, - {31, 0x02, 24}, - {41, 0x02, 24}, - {56, 0x03, 24}, - {3, 0x02, 25}, - {6, 0x02, 25}, - {10, 0x02, 25}, - {15, 0x02, 25}, - {24, 0x02, 25}, - {31, 0x02, 25}, - {41, 0x02, 25}, - {56, 0x03, 25}, + {0x8003, 24}, + {0x8006, 24}, + {0x800a, 24}, + {0x800f, 24}, + {0x8018, 24}, + {0x801f, 24}, + {0x8029, 24}, + {0xc038, 24}, + {0x8003, 25}, + {0x8006, 25}, + {0x800a, 25}, + {0x800f, 25}, + {0x8018, 25}, + {0x801f, 25}, + {0x8029, 25}, + {0xc038, 25}, }, /* 245 */ { - {3, 0x02, 26}, - {6, 0x02, 26}, - {10, 0x02, 26}, - {15, 0x02, 26}, - {24, 0x02, 26}, - {31, 0x02, 26}, - {41, 0x02, 26}, - {56, 0x03, 26}, - {3, 0x02, 27}, - {6, 0x02, 27}, - {10, 0x02, 27}, - {15, 0x02, 27}, - {24, 0x02, 27}, - {31, 0x02, 27}, - {41, 0x02, 27}, - {56, 0x03, 27}, + {0x8003, 26}, + {0x8006, 26}, + {0x800a, 26}, + {0x800f, 26}, + {0x8018, 26}, + {0x801f, 26}, + {0x8029, 26}, + {0xc038, 26}, + {0x8003, 27}, + {0x8006, 27}, + {0x800a, 27}, + {0x800f, 27}, + {0x8018, 27}, + {0x801f, 27}, + {0x8029, 27}, + {0xc038, 27}, }, /* 246 */ { - {1, 0x02, 28}, - {22, 0x03, 28}, - {1, 0x02, 29}, - {22, 0x03, 29}, - {1, 0x02, 30}, - {22, 0x03, 30}, - {1, 0x02, 31}, - {22, 0x03, 31}, - {1, 0x02, 127}, - {22, 0x03, 127}, - {1, 0x02, 220}, - {22, 0x03, 220}, - {1, 0x02, 249}, - {22, 0x03, 249}, - {254, 0x00, 0}, - {255, 0x00, 0}, + {0x8001, 28}, + {0xc016, 28}, + {0x8001, 29}, + {0xc016, 29}, + {0x8001, 30}, + {0xc016, 30}, + {0x8001, 31}, + {0xc016, 31}, + {0x8001, 127}, + {0xc016, 127}, + {0x8001, 220}, + {0xc016, 220}, + {0x8001, 249}, + {0xc016, 249}, + {0xfe, 0}, + {0xff, 0}, }, /* 247 */ { - {2, 0x02, 28}, - {9, 0x02, 28}, - {23, 0x02, 28}, - {40, 0x03, 28}, - {2, 0x02, 29}, - {9, 0x02, 29}, - {23, 0x02, 29}, - {40, 0x03, 29}, - {2, 0x02, 30}, - {9, 0x02, 30}, - {23, 0x02, 30}, - {40, 0x03, 30}, - {2, 0x02, 31}, - {9, 0x02, 31}, - {23, 0x02, 31}, - {40, 0x03, 31}, + {0x8002, 28}, + {0x8009, 28}, + {0x8017, 28}, + {0xc028, 28}, + {0x8002, 29}, + {0x8009, 29}, + {0x8017, 29}, + {0xc028, 29}, + {0x8002, 30}, + {0x8009, 30}, + {0x8017, 30}, + {0xc028, 30}, + {0x8002, 31}, + {0x8009, 31}, + {0x8017, 31}, + {0xc028, 31}, }, /* 248 */ { - {3, 0x02, 28}, - {6, 0x02, 28}, - {10, 0x02, 28}, - {15, 0x02, 28}, - {24, 0x02, 28}, - {31, 0x02, 28}, - {41, 0x02, 28}, - {56, 0x03, 28}, - {3, 0x02, 29}, - {6, 0x02, 29}, - {10, 0x02, 29}, - {15, 0x02, 29}, - {24, 0x02, 29}, - {31, 0x02, 29}, - {41, 0x02, 29}, - {56, 0x03, 29}, + {0x8003, 28}, + {0x8006, 28}, + {0x800a, 28}, + {0x800f, 28}, + {0x8018, 28}, + {0x801f, 28}, + {0x8029, 28}, + {0xc038, 28}, + {0x8003, 29}, + {0x8006, 29}, + {0x800a, 29}, + {0x800f, 29}, + {0x8018, 29}, + {0x801f, 29}, + {0x8029, 29}, + {0xc038, 29}, }, /* 249 */ { - {3, 0x02, 30}, - {6, 0x02, 30}, - {10, 0x02, 30}, - {15, 0x02, 30}, - {24, 0x02, 30}, - {31, 0x02, 30}, - {41, 0x02, 30}, - {56, 0x03, 30}, - {3, 0x02, 31}, - {6, 0x02, 31}, - {10, 0x02, 31}, - {15, 0x02, 31}, - {24, 0x02, 31}, - {31, 0x02, 31}, - {41, 0x02, 31}, - {56, 0x03, 31}, + {0x8003, 30}, + {0x8006, 30}, + {0x800a, 30}, + {0x800f, 30}, + {0x8018, 30}, + {0x801f, 30}, + {0x8029, 30}, + {0xc038, 30}, + {0x8003, 31}, + {0x8006, 31}, + {0x800a, 31}, + {0x800f, 31}, + {0x8018, 31}, + {0x801f, 31}, + {0x8029, 31}, + {0xc038, 31}, }, /* 250 */ { - {2, 0x02, 127}, - {9, 0x02, 127}, - {23, 0x02, 127}, - {40, 0x03, 127}, - {2, 0x02, 220}, - {9, 0x02, 220}, - {23, 0x02, 220}, - {40, 0x03, 220}, - {2, 0x02, 249}, - {9, 0x02, 249}, - {23, 0x02, 249}, - {40, 0x03, 249}, - {0, 0x03, 10}, - {0, 0x03, 13}, - {0, 0x03, 22}, - {0, 0x04, 0}, + {0x8002, 127}, + {0x8009, 127}, + {0x8017, 127}, + {0xc028, 127}, + {0x8002, 220}, + {0x8009, 220}, + {0x8017, 220}, + {0xc028, 220}, + {0x8002, 249}, + {0x8009, 249}, + {0x8017, 249}, + {0xc028, 249}, + {0xc000, 10}, + {0xc000, 13}, + {0xc000, 22}, + {0x100, 0}, }, /* 251 */ { - {3, 0x02, 127}, - {6, 0x02, 127}, - {10, 0x02, 127}, - {15, 0x02, 127}, - {24, 0x02, 127}, - {31, 0x02, 127}, - {41, 0x02, 127}, - {56, 0x03, 127}, - {3, 0x02, 220}, - {6, 0x02, 220}, - {10, 0x02, 220}, - {15, 0x02, 220}, - {24, 0x02, 220}, - {31, 0x02, 220}, - {41, 0x02, 220}, - {56, 0x03, 220}, + {0x8003, 127}, + {0x8006, 127}, + {0x800a, 127}, + {0x800f, 127}, + {0x8018, 127}, + {0x801f, 127}, + {0x8029, 127}, + {0xc038, 127}, + {0x8003, 220}, + {0x8006, 220}, + {0x800a, 220}, + {0x800f, 220}, + {0x8018, 220}, + {0x801f, 220}, + {0x8029, 220}, + {0xc038, 220}, }, /* 252 */ { - {3, 0x02, 249}, - {6, 0x02, 249}, - {10, 0x02, 249}, - {15, 0x02, 249}, - {24, 0x02, 249}, - {31, 0x02, 249}, - {41, 0x02, 249}, - {56, 0x03, 249}, - {1, 0x02, 10}, - {22, 0x03, 10}, - {1, 0x02, 13}, - {22, 0x03, 13}, - {1, 0x02, 22}, - {22, 0x03, 22}, - {0, 0x04, 0}, - {0, 0x04, 0}, + {0x8003, 249}, + {0x8006, 249}, + {0x800a, 249}, + {0x800f, 249}, + {0x8018, 249}, + {0x801f, 249}, + {0x8029, 249}, + {0xc038, 249}, + {0x8001, 10}, + {0xc016, 10}, + {0x8001, 13}, + {0xc016, 13}, + {0x8001, 22}, + {0xc016, 22}, + {0x100, 0}, + {0x100, 0}, }, /* 253 */ { - {2, 0x02, 10}, - {9, 0x02, 10}, - {23, 0x02, 10}, - {40, 0x03, 10}, - {2, 0x02, 13}, - {9, 0x02, 13}, - {23, 0x02, 13}, - {40, 0x03, 13}, - {2, 0x02, 22}, - {9, 0x02, 22}, - {23, 0x02, 22}, - {40, 0x03, 22}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, + {0x8002, 10}, + {0x8009, 10}, + {0x8017, 10}, + {0xc028, 10}, + {0x8002, 13}, + {0x8009, 13}, + {0x8017, 13}, + {0xc028, 13}, + {0x8002, 22}, + {0x8009, 22}, + {0x8017, 22}, + {0xc028, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, }, /* 254 */ { - {3, 0x02, 10}, - {6, 0x02, 10}, - {10, 0x02, 10}, - {15, 0x02, 10}, - {24, 0x02, 10}, - {31, 0x02, 10}, - {41, 0x02, 10}, - {56, 0x03, 10}, - {3, 0x02, 13}, - {6, 0x02, 13}, - {10, 0x02, 13}, - {15, 0x02, 13}, - {24, 0x02, 13}, - {31, 0x02, 13}, - {41, 0x02, 13}, - {56, 0x03, 13}, + {0x8003, 10}, + {0x8006, 10}, + {0x800a, 10}, + {0x800f, 10}, + {0x8018, 10}, + {0x801f, 10}, + {0x8029, 10}, + {0xc038, 10}, + {0x8003, 13}, + {0x8006, 13}, + {0x800a, 13}, + {0x800f, 13}, + {0x8018, 13}, + {0x801f, 13}, + {0x8029, 13}, + {0xc038, 13}, }, /* 255 */ { - {3, 0x02, 22}, - {6, 0x02, 22}, - {10, 0x02, 22}, - {15, 0x02, 22}, - {24, 0x02, 22}, - {31, 0x02, 22}, - {41, 0x02, 22}, - {56, 0x03, 22}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, - {0, 0x04, 0}, + {0x8003, 22}, + {0x8006, 22}, + {0x800a, 22}, + {0x800f, 22}, + {0x8018, 22}, + {0x801f, 22}, + {0x8029, 22}, + {0xc038, 22}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + }, + /* 256 */ + { + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, + {0x100, 0}, }, }; diff --git a/deps/nghttp2/lib/nghttp2_helper.c b/deps/nghttp2/lib/nghttp2_helper.c index 81a8a0cf99971a..91136a61986014 100644 --- a/deps/nghttp2/lib/nghttp2_helper.c +++ b/deps/nghttp2/lib/nghttp2_helper.c @@ -505,6 +505,84 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) { return 1; } +/* Generated by genauthroitychartbl.py */ +static char VALID_AUTHORITY_CHARS[] = { + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, + 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ +}; + +int nghttp2_check_authority(const uint8_t *value, size_t len) { + const uint8_t *last; + for (last = value + len; value != last; ++value) { + if (!VALID_AUTHORITY_CHARS[*value]) { + return 0; + } + } + return 1; +} + uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) { if (len == 0) { return dest; diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c index 8d990299838193..62f57b6aec779c 100644 --- a/deps/nghttp2/lib/nghttp2_http.c +++ b/deps/nghttp2/lib/nghttp2_http.c @@ -305,84 +305,6 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, return 0; } -/* Generated by genauthroitychartbl.py */ -static char VALID_AUTHORITY_CHARS[] = { - 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, - 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, - 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, - 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, - 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, - 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, - 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, - 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, - 0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */, - 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, - 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, - 1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, - 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, - 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, - 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, - 0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, - 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, - 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, - 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, - 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, - 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, - 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, - 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, - 0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */, - 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, - 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, - 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, - 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, - 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, - 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, - 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, - 0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, - 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, - 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, - 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, - 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, - 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, - 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, - 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, - 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, - 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, - 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, - 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, - 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, - 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, - 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, - 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, - 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, - 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, - 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, - 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, - 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, - 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, - 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, - 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, - 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, - 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, - 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, - 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, - 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, - 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, - 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, - 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, - 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ -}; - -static int check_authority(const uint8_t *value, size_t len) { - const uint8_t *last; - for (last = value + len; value != last; ++value) { - if (!VALID_AUTHORITY_CHARS[*value]) { - return 0; - } - } - return 1; -} - static int check_scheme(const uint8_t *value, size_t len) { const uint8_t *last; if (len == 0) { @@ -440,7 +362,7 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, if (nv->token == NGHTTP2_TOKEN__AUTHORITY || nv->token == NGHTTP2_TOKEN_HOST) { - rv = check_authority(nv->value->base, nv->value->len); + rv = nghttp2_check_authority(nv->value->base, nv->value->len); } else if (nv->token == NGHTTP2_TOKEN__SCHEME) { rv = check_scheme(nv->value->base, nv->value->len); } else { diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c index 3420cfa2f1c653..9df3d6f32938a6 100644 --- a/deps/nghttp2/lib/nghttp2_session.c +++ b/deps/nghttp2/lib/nghttp2_session.c @@ -3735,7 +3735,6 @@ static int session_end_stream_headers_received(nghttp2_session *session, static int session_after_header_block_received(nghttp2_session *session) { int rv = 0; - int call_cb = 1; nghttp2_frame *frame = &session->iframe.frame; nghttp2_stream *stream; @@ -3789,21 +3788,25 @@ static int session_after_header_block_received(nghttp2_session *session) { stream_id = frame->hd.stream_id; } - call_cb = 0; - rv = session_handle_invalid_stream2(session, stream_id, frame, NGHTTP2_ERR_HTTP_MESSAGING); if (nghttp2_is_fatal(rv)) { return rv; } + + if (frame->hd.type == NGHTTP2_HEADERS && + (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { + nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); + /* Don't call nghttp2_session_close_stream_if_shut_rdwr + because RST_STREAM has been submitted. */ + } + return 0; } } - if (call_cb) { - rv = session_call_on_frame_received(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } + rv = session_call_on_frame_received(session, frame); + if (nghttp2_is_fatal(rv)) { + return rv; } if (frame->hd.type != NGHTTP2_HEADERS) { @@ -4942,7 +4945,6 @@ static int session_process_extension_frame(nghttp2_session *session) { int nghttp2_session_on_data_received(nghttp2_session *session, nghttp2_frame *frame) { int rv = 0; - int call_cb = 1; nghttp2_stream *stream; /* We don't call on_frame_recv_callback if stream has been closed @@ -4958,20 +4960,22 @@ int nghttp2_session_on_data_received(nghttp2_session *session, if (session_enforce_http_messaging(session) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { if (nghttp2_http_on_remote_end_stream(stream) != 0) { - call_cb = 0; rv = nghttp2_session_add_rst_stream(session, stream->stream_id, NGHTTP2_PROTOCOL_ERROR); if (nghttp2_is_fatal(rv)) { return rv; } + + nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD); + /* Don't call nghttp2_session_close_stream_if_shut_rdwr because + RST_STREAM has been submitted. */ + return 0; } } - if (call_cb) { - rv = session_call_on_frame_received(session, frame); - if (nghttp2_is_fatal(rv)) { - return rv; - } + rv = session_call_on_frame_received(session, frame); + if (nghttp2_is_fatal(rv)) { + return rv; } if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { @@ -5409,8 +5413,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, case NGHTTP2_IB_READ_CLIENT_MAGIC: readlen = nghttp2_min(inlen, iframe->payloadleft); - if (memcmp(NGHTTP2_CLIENT_MAGIC + NGHTTP2_CLIENT_MAGIC_LEN - - iframe->payloadleft, + if (memcmp(&NGHTTP2_CLIENT_MAGIC[NGHTTP2_CLIENT_MAGIC_LEN - + iframe->payloadleft], in, readlen) != 0) { return NGHTTP2_ERR_BAD_CLIENT_MAGIC; } diff --git a/deps/npm/.npmignore b/deps/npm/.npmignore index 12efef27852da6..c42aaf956257d5 100644 --- a/deps/npm/.npmignore +++ b/deps/npm/.npmignore @@ -1,11 +1,13 @@ *.swp .*.swp +netlify.toml npm-debug.log /.github /test node_modules/marked node_modules/marked-man node_modules/tap +tap-snapshots node_modules/.bin node_modules/npm-registry-mock /npmrc diff --git a/deps/npm/AUTHORS b/deps/npm/AUTHORS index 14356c0d919b5a..eef45f2df19be2 100644 --- a/deps/npm/AUTHORS +++ b/deps/npm/AUTHORS @@ -663,3 +663,12 @@ Christian Clauss Nikita Lebedev Henrik Gemal Philip Harrison +Jason Etcovitch +Darcy Clarke +orion +NoDocCat +joan xie +Amal Hussein +Brett Zamir +Menelaos Kotsollaris +Mehdi Hasan Khan diff --git a/deps/npm/CHANGELOG.md b/deps/npm/CHANGELOG.md index ea7bfdb3a98437..d83c57f6d9a772 100644 --- a/deps/npm/CHANGELOG.md +++ b/deps/npm/CHANGELOG.md @@ -1,3 +1,110 @@ +## 6.13.1 (2019-11-18) + +### BUG FIXES + +* [`938d6124d`](https://github.com/npm/cli/commit/938d6124d6d15d96b5a69d0ae32ef59fceb8ceab) + [#472](https://github.com/npm/cli/pull/472) + fix(fund): support funding string shorthand + ([@ruyadorno](https://github.com/ruyadorno)) +* [`b49c5535b`](https://github.com/npm/cli/commit/b49c5535b7c41729a8d167b035924c3c66b36de0) + [#471](https://github.com/npm/cli/pull/471) + should not publish tap-snapshot folder + ([@ruyadorno](https://github.com/ruyadorno)) +* [`3471d5200`](https://github.com/npm/cli/commit/3471d5200217bfa612b1a262e36c9c043a52eb09) + [#253](https://github.com/npm/cli/pull/253) + Add preliminary WSL support for npm and npx + ([@infinnie](https://github.com/infinnie)) +* [`3ef295f23`](https://github.com/npm/cli/commit/3ef295f23ee1b2300abf13ec19e935c47a455179) + [#486](https://github.com/npm/cli/pull/486) + print quick audit report for human output + ([@isaacs](https://github.com/isaacs)) + +### TESTING + +* [`dbbf977ac`](https://github.com/npm/cli/commit/dbbf977acd1e74bcdec859c562ea4a2bc0536442) + [#278](https://github.com/npm/cli/pull/278) + added workflow to trigger and run benchmarks + ([@mikemimik](https://github.com/mikemimik)) +* [`b4f5e3825`](https://github.com/npm/cli/commit/b4f5e3825535256aaada09c5e8f104570a3d96a4) + [#457](https://github.com/npm/cli/pull/457) + feat(docs): adding tests and updating docs to reflect changes in registry teams API. + ([@nomadtechie](https://github.com/nomadtechie)) +* [`454c7dd60`](https://github.com/npm/cli/commit/454c7dd60c78371bf606f11a17ed0299025bc37c) + [#456](https://github.com/npm/cli/pull/456) + fix git configs for git 2.23 and above + ([@isaacs](https://github.com/isaacs)) + +### DOCUMENTATION + +* [`b8c1576a4`](https://github.com/npm/cli/commit/b8c1576a448566397c721655b95fc90bf202b35a) [`30b013ae8`](https://github.com/npm/cli/commit/30b013ae8eacd04b1b8a41ce2ed0dd50c8ebae25) [`26c1b2ef6`](https://github.com/npm/cli/commit/26c1b2ef6be1595d28d935d35faa8ec72daae544) [`9f943a765`](https://github.com/npm/cli/commit/9f943a765faf6ebb8a442e862b808dbb630e018d) [`c0346b158`](https://github.com/npm/cli/commit/c0346b158fc25ab6ca9954d4dd78d9e62f573a41) [`8e09d5ad6`](https://github.com/npm/cli/commit/8e09d5ad67d4f142241193cecbce61c659389be3) [`4a2f551ee`](https://github.com/npm/cli/commit/4a2f551eeb3285f6f200534da33644789715a41a) [`87d67258c`](https://github.com/npm/cli/commit/87d67258c213d9ea9a49ce1804294a718f08ff13) [`5c3b32722`](https://github.com/npm/cli/commit/5c3b3272234764c8b4d2d798b69af077b5a529c7) [`b150eaeff`](https://github.com/npm/cli/commit/b150eaeff428180bfa03be53fd741d5625897758) [`7555a743c`](https://github.com/npm/cli/commit/7555a743ce4c3146d6245dd63f91503c7f439a6c) [`b89423e2f`](https://github.com/npm/cli/commit/b89423e2f6a09b290b15254e7ff7e8033b434d83) + [#463](https://github.com/npm/cli/pull/463) + [#285](https://github.com/npm/cli/pull/285) + [#268](https://github.com/npm/cli/pull/268) + [#232](https://github.com/npm/cli/pull/232) + [#485](https://github.com/npm/cli/pull/485) + [#453](https://github.com/npm/cli/pull/453) + docs cleanup: typos, styling and content + ([@claudiahdz](https://github.com/claudiahdz)) + ([@XhmikosR](https://github.com/XhmikosR)) + ([@mugli](https://github.com/mugli)) + ([@brettz9](https://github.com/brettz9)) + ([@mkotsollaris](https://github.com/mkotsollaris)) + +### DEPENDENCIES + +* [`661d86cd2`](https://github.com/npm/cli/commit/661d86cd229b14ddf687b7f25a66941a79d233e7) + `make-fetch-happen@5.0.2` + ([@claudiahdz](https://github.com/claudiahdz)) + +## 6.13.0 (2019-11-05) + +### NEW FEATURES + +* [`4414b06d9`](https://github.com/npm/cli/commit/4414b06d944c56bee05ccfb85260055a767ee334) + [#273](https://github.com/npm/cli/pull/273) + add fund command + ([@ruyadorno](https://github.com/ruyadorno)) + +### DOCUMENTATION + +* [`ae4c74d04`](https://github.com/npm/cli/commit/ae4c74d04f820a0255a92bdfe77ecf97af134fae) + [#274](https://github.com/npm/cli/pull/274) + migrate existing docs to gatsby + ([@claudiahdz](https://github.com/claudiahdz)) +* [`4ff1bb180`](https://github.com/npm/cli/commit/4ff1bb180b1db8c72e51b3d57bd4e268b738e049) + [#277](https://github.com/npm/cli/pull/277) + updated documentation copy + ([@oletizi](https://github.com/oletizi)) + +### BUG FIXES + +* [`e4455409f`](https://github.com/npm/cli/commit/e4455409fe6fe9c198b250b488129171f0b4624a) + [#281](https://github.com/npm/cli/pull/281) + delete ps1 files on package removal + ([@NoDocCat](https://github.com/NoDocCat)) +* [`cd14d4701`](https://github.com/npm/cli/commit/cd14d47014e8c96ffd6a18791e8752028b19d637) + [#279](https://github.com/npm/cli/pull/279) + update supported node list to remove v6.0, v6.1, v9.0 - v9.2 + ([@ljharb](https://github.com/ljharb)) + +### DEPENDENCIES + +* [`a37296b20`](https://github.com/npm/cli/commit/a37296b20ca3e19c2bbfa78fedcfe695e03fda69) + `pacote@9.5.9` +* [`d3cb3abe8`](https://github.com/npm/cli/commit/d3cb3abe8cee54bd2624acdcf8043932ef0d660a) + `read-cmd-shim@1.0.5` + +### TESTING + +* [`688cd97be`](https://github.com/npm/cli/commit/688cd97be94ca949719424ff69ff515a68c5caba) + [#272](https://github.com/npm/cli/pull/272) + use github actions for CI + ([@JasonEtco](https://github.com/JasonEtco)) +* [`9a2d8af84`](https://github.com/npm/cli/commit/9a2d8af84f7328f13d8f578cf4b150b9d5f09517) + [#240](https://github.com/npm/cli/pull/240) + Clean up some flakiness and inconsistency + ([@isaacs](https://github.com/isaacs)) + ## 6.12.1 (2019-10-29) ### BUG FIXES diff --git a/deps/npm/Makefile b/deps/npm/Makefile index 4e00647a19cf08..11e656c43a458f 100644 --- a/deps/npm/Makefile +++ b/deps/npm/Makefile @@ -4,51 +4,25 @@ SHELL = bash PUBLISHTAG = $(shell node scripts/publish-tag.js) BRANCH = $(shell git rev-parse --abbrev-ref HEAD) -markdowns = $(shell find doc -name '*.md' | grep -v 'index') README.md +markdowns = $(shell find docs -name '*.md' | grep -v 'index') README.md -html_docdeps = html/dochead.html \ - html/docfoot.html \ - scripts/doc-build.sh \ - package.json - -cli_mandocs = $(shell find doc/cli -name '*.md' \ +cli_mandocs = $(shell find docs/content/cli-commands -name '*.md' \ |sed 's|.md|.1|g' \ - |sed 's|doc/cli/|man/man1/|g' ) \ + |sed 's|docs/content/cli-commands/|man/man1/|g' ) \ man/man1/npm-README.1 \ man/man1/npx.1 -files_mandocs = $(shell find doc/files -name '*.md' \ +files_mandocs = $(shell find docs/content/configuring-npm -name '*.md' \ |sed 's|.md|.5|g' \ - |sed 's|doc/files/|man/man5/|g' ) \ - man/man5/npm-json.5 \ - man/man5/npm-global.5 + |sed 's|docs/content/configuring-npm/|man/man5/|g' ) \ -misc_mandocs = $(shell find doc/misc -name '*.md' \ +misc_mandocs = $(shell find docs/content/using-npm -name '*.md' \ |sed 's|.md|.7|g' \ - |sed 's|doc/misc/|man/man7/|g' ) \ - man/man7/npm-index.7 - -cli_htmldocs = $(shell find doc/cli -name '*.md' \ - |sed 's|.md|.html|g' \ - |sed 's|doc/cli/|html/doc/cli/|g' ) \ - html/doc/README.html - -files_htmldocs = $(shell find doc/files -name '*.md' \ - |sed 's|.md|.html|g' \ - |sed 's|doc/files/|html/doc/files/|g' ) \ - html/doc/files/npm-json.html \ - html/doc/files/npm-global.html - -misc_htmldocs = $(shell find doc/misc -name '*.md' \ - |sed 's|.md|.html|g' \ - |sed 's|doc/misc/|html/doc/misc/|g' ) \ - html/doc/index.html + |sed 's|docs/content/using-npm/|man/man7/|g' ) \ mandocs = $(cli_mandocs) $(files_mandocs) $(misc_mandocs) -htmldocs = $(cli_htmldocs) $(files_htmldocs) $(misc_htmldocs) - -all: doc +all: docs latest: @echo "Installing latest published npm" @@ -65,14 +39,21 @@ dev: install link: uninstall node bin/npm-cli.js link -f -clean: markedclean marked-manclean doc-clean +clean: markedclean marked-manclean docs-clean rm -rf npmrc node bin/npm-cli.js cache clean --force uninstall: node bin/npm-cli.js rm npm -g -f -doc: $(mandocs) $(htmldocs) +mandocs: $(mandocs) + +htmldocs: + cd docs && node ../bin/npm-cli.js install && \ + node ../bin/npm-cli.js run build:static echo>&2 && \ + rm -rf node_modules .cache public/*js public/*json public/404* public/page-data public/manifest* + +docs: mandocs htmldocs markedclean: rm -rf node_modules/marked node_modules/.bin/marked .building_marked @@ -80,26 +61,28 @@ markedclean: marked-manclean: rm -rf node_modules/marked-man node_modules/.bin/marked-man .building_marked-man -docclean: doc-clean -doc-clean: +docsclean: docs-clean +docs-clean: rm -rf \ .building_marked \ .building_marked-man \ - html/doc \ - man + man \ + docs/node_modules \ + docs/public \ + docs/.cache ## build-time tools for the documentation build-doc-tools := node_modules/.bin/marked \ node_modules/.bin/marked-man # use `npm install marked-man` for this to work. -man/man1/npm-README.1: README.md scripts/doc-build.sh package.json $(build-doc-tools) +man/man1/npm-README.1: README.md scripts/docs-build.js package.json $(build-doc-tools) @[ -d man/man1 ] || mkdir -p man/man1 - scripts/doc-build.sh $< $@ + node scripts/docs-build.js $< $@ -man/man1/%.1: doc/cli/%.md scripts/doc-build.sh package.json $(build-doc-tools) +man/man1/%.1: docs/content/cli-commands/%.md scripts/docs-build.js package.json $(build-doc-tools) @[ -d man/man1 ] || mkdir -p man/man1 - scripts/doc-build.sh $< $@ + node scripts/docs-build.js $< $@ man/man1/npx.1: node_modules/libnpx/libnpx.1 cat $< | sed s/libnpx/npx/ > $@ @@ -107,46 +90,16 @@ man/man1/npx.1: node_modules/libnpx/libnpx.1 man/man5/npm-json.5: man/man5/package.json.5 cp $< $@ -man/man5/npm-global.5: man/man5/npm-folders.5 +man/man5/npm-global.5: man/man5/folders.5 cp $< $@ -man/man5/%.5: doc/files/%.md scripts/doc-build.sh package.json $(build-doc-tools) +man/man5/%.5: docs/content/configuring-npm/%.md scripts/docs-build.js package.json $(build-doc-tools) @[ -d man/man5 ] || mkdir -p man/man5 - scripts/doc-build.sh $< $@ - -doc/misc/npm-index.md: scripts/index-build.js package.json $(build-doc-tools) - node scripts/index-build.js > $@ + node scripts/docs-build.js $< $@ -html/doc/index.html: doc/misc/npm-index.md $(html_docdeps) $(build-doc-tools) - @[ -d html/doc ] || mkdir -p html/doc - scripts/doc-build.sh $< $@ - -man/man7/%.7: doc/misc/%.md scripts/doc-build.sh package.json $(build-doc-tools) +man/man7/%.7: docs/content/using-npm/%.md scripts/docs-build.js package.json $(build-doc-tools) @[ -d man/man7 ] || mkdir -p man/man7 - scripts/doc-build.sh $< $@ - -html/doc/README.html: README.md $(html_docdeps) $(build-doc-tools) - @[ -d html/doc ] || mkdir -p html/doc - scripts/doc-build.sh $< $@ - -html/doc/cli/%.html: doc/cli/%.md $(html_docdeps) $(build-doc-tools) - @[ -d html/doc/cli ] || mkdir -p html/doc/cli - scripts/doc-build.sh $< $@ - -html/doc/files/npm-json.html: html/doc/files/package.json.html - cp $< $@ - -html/doc/files/npm-global.html: html/doc/files/npm-folders.html - cp $< $@ - -html/doc/files/%.html: doc/files/%.md $(html_docdeps) $(build-doc-tools) - @[ -d html/doc/files ] || mkdir -p html/doc/files - scripts/doc-build.sh $< $@ - -html/doc/misc/%.html: doc/misc/%.md $(html_docdeps) $(build-doc-tools) - @[ -d html/doc/misc ] || mkdir -p html/doc/misc - scripts/doc-build.sh $< $@ - + node scripts/docs-build.js $< $@ marked: node_modules/.bin/marked @@ -158,11 +111,7 @@ marked-man: node_modules/.bin/marked-man node_modules/.bin/marked-man: node bin/npm-cli.js install marked-man --no-global --no-timing --no-save -doc: man - -man: $(cli_docs) - -test: doc +test: docs node bin/npm-cli.js test tag: @@ -174,17 +123,17 @@ ls-ok: gitclean: git clean -fd -publish: gitclean ls-ok link doc-clean doc +publish: gitclean ls-ok link docs-clean docs @git push origin :v$(shell node bin/npm-cli.js --no-timing -v) 2>&1 || true git push origin $(BRANCH) &&\ git push origin --tags &&\ node bin/npm-cli.js publish --tag=$(PUBLISHTAG) -release: gitclean ls-ok markedclean marked-manclean doc-clean doc +release: gitclean ls-ok markedclean marked-manclean docs-clean doc node bin/npm-cli.js prune --production --no-save @bash scripts/release.sh sandwich: @[ $$(whoami) = "root" ] && (echo "ok"; echo "ham" > sandwich) || (echo "make it yourself" && exit 13) -.PHONY: all latest install dev link doc clean uninstall test man doc-clean docclean release ls-ok realclean +.PHONY: all latest install dev link doc clean uninstall test man docs-clean docclean release ls-ok realclean diff --git a/deps/npm/README.md b/deps/npm/README.md index bb33879fd0118f..16c7e4b18cdf00 100644 --- a/deps/npm/README.md +++ b/deps/npm/README.md @@ -163,4 +163,3 @@ doubt tell you to put the output in a gist or email. * npm(1) * npm-help(1) -* npm-index(7) diff --git a/deps/npm/bin/npm b/deps/npm/bin/npm index 4183703a7857e9..737d1f17064890 100755 --- a/deps/npm/bin/npm +++ b/deps/npm/bin/npm @@ -8,6 +8,10 @@ case `uname` in esac NODE_EXE="$basedir/node.exe" +if [ -x "$NODE_EXE" ] && [ -f "/bin/wslpath" ]; then # run the corresponding command prompt when Node for Windows is executed within WSL + cmd.exe /c `wslpath -w "$basedir/npm.cmd"` "$@" + exit $? +fi if ! [ -x "$NODE_EXE" ]; then NODE_EXE="$basedir/node" fi diff --git a/deps/npm/bin/npx b/deps/npm/bin/npx index 261e339850da5e..3516c8c415dba2 100644 --- a/deps/npm/bin/npx +++ b/deps/npm/bin/npx @@ -8,6 +8,10 @@ case `uname` in esac NODE_EXE="$basedir/node.exe" +if [ -x "$NODE_EXE" ] && [ -f "/bin/wslpath" ]; then # run the corresponding command prompt when Node for Windows is executed within WSL + cmd.exe /c `wslpath -w "$basedir/npx.cmd"` "$@" + exit $? +fi if ! [ -x "$NODE_EXE" ]; then NODE_EXE=node fi diff --git a/deps/npm/changelogs/CHANGELOG-3.md b/deps/npm/changelogs/CHANGELOG-3.md index c13159a5c9dcb2..fc55a696fb22a7 100644 --- a/deps/npm/changelogs/CHANGELOG-3.md +++ b/deps/npm/changelogs/CHANGELOG-3.md @@ -47,7 +47,7 @@ This is gonna be a much, MUCH smaller major version than 3.x was. Maybe even smaller than 2.x was. I can't tell you everything that'll be in there just yet, but at the very least it's going to have what's in our [4.x milestone](https://github.com/npm/npm/pulls?q=is%3Aopen+is%3Apr+milestone%3A4.x), -PLUS, the first steps in +PLUS, the first steps in [making `prepublish` work](https://github.com/npm/npm/issues/10074) the way people expect it to. diff --git a/deps/npm/changelogs/CHANGELOG-5.md b/deps/npm/changelogs/CHANGELOG-5.md index b4c75b3d819064..57496984913d6f 100644 --- a/deps/npm/changelogs/CHANGELOG-5.md +++ b/deps/npm/changelogs/CHANGELOG-5.md @@ -225,7 +225,7 @@ as `https://` URLs instead of versions. zeros deleted resulted in authentication failures. ([@iarna](https://github.com/iarna)) * [`6eaa860ea`](https://github.com/npm/npm/commit/6eaa860ead3222a6dbd6d370b4271e7bf242b30b) - Eliminate direct use of `new Buffer` in `npm`. While the use of it in `npm` was safe, there + Eliminate direct use of `new Buffer` in `npm`. While the use of it in `npm` was safe, there are two other reasons for this change: 1. Node 10 emits warnings about its use. @@ -341,7 +341,7 @@ and a handful of bug fixes! Let's get right in! ### NEW PACKAGE VIEW -There's a new `npm view` in town. You might it as `npm info` or `npm show`. +There's a new `npm view` in town. You might it as `npm info` or `npm show`. The new output gives you a nicely summarized view that for most packages fits on one screen. If you ask it for `--json` you'll still get the same results, so your scripts should still work fine. @@ -377,7 +377,7 @@ you can double check your `.npmignore` settings before doing a publish. ### MERGE CONFLICT, SMERGE CONFLICT If you resolve a `package-lock.json` merge conflict with `npm install` we -now suggest you setup a merge driver to handle these automatically for you. +now suggest you setup a merge driver to handle these automatically for you. If you're reading this and you'd like to set it up now, run: ```console diff --git a/deps/npm/doc/cli/npm-bin.md b/deps/npm/doc/cli/npm-bin.md deleted file mode 100644 index 9b76ec529e30a0..00000000000000 --- a/deps/npm/doc/cli/npm-bin.md +++ /dev/null @@ -1,19 +0,0 @@ -npm-bin(1) -- Display npm bin folder -==================================== - -## SYNOPSIS - - npm bin [-g|--global] - -## DESCRIPTION - -Print the folder where npm will install executables. - -## SEE ALSO - -* npm-prefix(1) -* npm-root(1) -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) diff --git a/deps/npm/doc/cli/npm-bugs.md b/deps/npm/doc/cli/npm-bugs.md deleted file mode 100644 index 55bce12f23fa37..00000000000000 --- a/deps/npm/doc/cli/npm-bugs.md +++ /dev/null @@ -1,43 +0,0 @@ -npm-bugs(1) -- Bugs for a package in a web browser maybe -======================================================== - -## SYNOPSIS - - npm bugs [] - - aliases: issues - -## DESCRIPTION - -This command tries to guess at the likely location of a package's -bug tracker URL, and then tries to open it using the `--browser` -config param. If no package name is provided, it will search for -a `package.json` in the current folder and use the `name` property. - -## CONFIGURATION - -### browser - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: String - -The browser that is called by the `npm bugs` command to open websites. - -### registry - -* Default: https://registry.npmjs.org/ -* Type: url - -The base URL of the npm package registry. - - -## SEE ALSO - -* npm-docs(1) -* npm-view(1) -* npm-publish(1) -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* package.json(5) diff --git a/deps/npm/doc/cli/npm-build.md b/deps/npm/doc/cli/npm-build.md deleted file mode 100644 index 019f225850dc04..00000000000000 --- a/deps/npm/doc/cli/npm-build.md +++ /dev/null @@ -1,25 +0,0 @@ -npm-build(1) -- Build a package -=============================== - -## SYNOPSIS - - npm build [] - -* ``: - A folder containing a `package.json` file in its root. - -## DESCRIPTION - -This is the plumbing command called by `npm link` and `npm install`. - -It should generally be called during installation, but if you need to run it -directly, run: - - npm run-script build - -## SEE ALSO - -* npm-install(1) -* npm-link(1) -* npm-scripts(7) -* package.json(5) diff --git a/deps/npm/doc/cli/npm-config.md b/deps/npm/doc/cli/npm-config.md deleted file mode 100644 index c60afc167c7420..00000000000000 --- a/deps/npm/doc/cli/npm-config.md +++ /dev/null @@ -1,73 +0,0 @@ -npm-config(1) -- Manage the npm configuration files -=================================================== - -## SYNOPSIS - - npm config set [-g|--global] - npm config get - npm config delete - npm config list [-l] [--json] - npm config edit - npm get - npm set [-g|--global] - - aliases: c - -## DESCRIPTION - -npm gets its config settings from the command line, environment -variables, `npmrc` files, and in some cases, the `package.json` file. - -See npmrc(5) for more information about the npmrc files. - -See `npm-config(7)` for a more thorough discussion of the mechanisms -involved. - -The `npm config` command can be used to update and edit the contents -of the user and global npmrc files. - -## Sub-commands - -Config supports the following sub-commands: - -### set - - npm config set key value - -Sets the config key to the value. - -If value is omitted, then it sets it to "true". - -### get - - npm config get key - -Echo the config value to stdout. - -### list - - npm config list - -Show all the config settings. Use `-l` to also show defaults. Use `--json` -to show the settings in json format. - -### delete - - npm config delete key - -Deletes the key from all configuration files. - -### edit - - npm config edit - -Opens the config file in an editor. Use the `--global` flag to edit the -global config. - -## SEE ALSO - -* npm-folders(5) -* npm-config(7) -* package.json(5) -* npmrc(5) -* npm(1) diff --git a/deps/npm/doc/cli/npm-docs.md b/deps/npm/doc/cli/npm-docs.md deleted file mode 100644 index f5064c55e2829a..00000000000000 --- a/deps/npm/doc/cli/npm-docs.md +++ /dev/null @@ -1,44 +0,0 @@ -npm-docs(1) -- Docs for a package in a web browser maybe -======================================================== - -## SYNOPSIS - - npm docs [ [ ...]] - npm docs . - npm home [ [ ...]] - npm home . - -## DESCRIPTION - -This command tries to guess at the likely location of a package's -documentation URL, and then tries to open it using the `--browser` -config param. You can pass multiple package names at once. If no -package name is provided, it will search for a `package.json` in -the current folder and use the `name` property. - -## CONFIGURATION - -### browser - -* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` -* Type: String - -The browser that is called by the `npm docs` command to open websites. - -### registry - -* Default: https://registry.npmjs.org/ -* Type: url - -The base URL of the npm package registry. - - -## SEE ALSO - -* npm-view(1) -* npm-publish(1) -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* package.json(5) diff --git a/deps/npm/doc/cli/npm-install-ci-test.md b/deps/npm/doc/cli/npm-install-ci-test.md deleted file mode 100644 index 4cbab9144e48fa..00000000000000 --- a/deps/npm/doc/cli/npm-install-ci-test.md +++ /dev/null @@ -1,16 +0,0 @@ -# npm install-ci-test(1) -- Install a project with a clean slate and run tests - -## SYNOPSIS - - npm install-ci-test - - alias: npm cit - -## DESCRIPTION - -This command runs an `npm ci` followed immediately by an `npm test`. - -## SEE ALSO - -- npm-ci(1) -- npm-test(1) diff --git a/deps/npm/doc/cli/npm-install-test.md b/deps/npm/doc/cli/npm-install-test.md deleted file mode 100644 index 471b36f16b565d..00000000000000 --- a/deps/npm/doc/cli/npm-install-test.md +++ /dev/null @@ -1,25 +0,0 @@ -# npm install-test(1) -- Install package(s) and run tests - -## SYNOPSIS - - npm install-test (with no args, in package dir) - npm install-test [<@scope>/] - npm install-test [<@scope>/]@ - npm install-test [<@scope>/]@ - npm install-test [<@scope>/]@ - npm install-test - npm install-test - npm install-test - - alias: npm it - common options: [--save|--save-dev|--save-optional] [--save-exact] [--dry-run] - -## DESCRIPTION - -This command runs an `npm install` followed immediately by an `npm test`. It -takes exactly the same arguments as `npm install`. - -## SEE ALSO - -- npm-install(1) -- npm-test(1) diff --git a/deps/npm/doc/cli/npm-ping.md b/deps/npm/doc/cli/npm-ping.md deleted file mode 100644 index 3b2da9944bb242..00000000000000 --- a/deps/npm/doc/cli/npm-ping.md +++ /dev/null @@ -1,24 +0,0 @@ -npm-ping(1) -- Ping npm registry -================================ - -## SYNOPSIS - - npm ping [--registry ] - -## DESCRIPTION - -Ping the configured or given npm registry and verify authentication. -If it works it will output something like: -``` -Ping success: {*Details about registry*} -``` -otherwise you will get: -``` -Ping error: {*Detail about error} -``` - -## SEE ALSO - -* npm-config(1) -* npm-config(7) -* npmrc(5) diff --git a/deps/npm/doc/cli/npm-prefix.md b/deps/npm/doc/cli/npm-prefix.md deleted file mode 100644 index d36e538132fb26..00000000000000 --- a/deps/npm/doc/cli/npm-prefix.md +++ /dev/null @@ -1,24 +0,0 @@ -npm-prefix(1) -- Display prefix -=============================== - -## SYNOPSIS - - npm prefix [-g] - -## DESCRIPTION - -Print the local prefix to standard out. This is the closest parent directory -to contain a `package.json` file or `node_modules` directory, unless `-g` is -also specified. - -If `-g` is specified, this will be the value of the global prefix. See -`npm-config(7)` for more detail. - -## SEE ALSO - -* npm-root(1) -* npm-bin(1) -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) diff --git a/deps/npm/doc/cli/npm-rebuild.md b/deps/npm/doc/cli/npm-rebuild.md deleted file mode 100644 index 437737d9f4b563..00000000000000 --- a/deps/npm/doc/cli/npm-rebuild.md +++ /dev/null @@ -1,19 +0,0 @@ -npm-rebuild(1) -- Rebuild a package -=================================== - -## SYNOPSIS - - npm rebuild [[<@scope>/]...] - - alias: npm rb - -## DESCRIPTION - -This command runs the `npm build` command on the matched folders. This is useful -when you install a new version of node, and must recompile all your C++ addons with -the new binary. - -## SEE ALSO - -* npm-build(1) -* npm-install(1) diff --git a/deps/npm/doc/cli/npm-root.md b/deps/npm/doc/cli/npm-root.md deleted file mode 100644 index a1d5bf8629913b..00000000000000 --- a/deps/npm/doc/cli/npm-root.md +++ /dev/null @@ -1,19 +0,0 @@ -npm-root(1) -- Display npm root -=============================== - -## SYNOPSIS - - npm root [-g] - -## DESCRIPTION - -Print the effective `node_modules` folder to standard out. - -## SEE ALSO - -* npm-prefix(1) -* npm-bin(1) -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) diff --git a/deps/npm/doc/cli/npm-shrinkwrap.md b/deps/npm/doc/cli/npm-shrinkwrap.md deleted file mode 100644 index 4c223a86cc1b75..00000000000000 --- a/deps/npm/doc/cli/npm-shrinkwrap.md +++ /dev/null @@ -1,25 +0,0 @@ -npm-shrinkwrap(1) -- Lock down dependency versions for publication -===================================================== - -## SYNOPSIS - - npm shrinkwrap - -## DESCRIPTION - -This command repurposes `package-lock.json` into a publishable -`npm-shrinkwrap.json` or simply creates a new one. The file created and updated -by this command will then take precedence over any other existing or future -`package-lock.json` files. For a detailed explanation of the design and purpose -of package locks in npm, see npm-package-locks(5). - -## SEE ALSO - -* npm-install(1) -* npm-run-script(1) -* npm-scripts(7) -* package.json(5) -* npm-package-locks(5) -* package-lock.json(5) -* npm-shrinkwrap.json(5) -* npm-ls(1) diff --git a/deps/npm/doc/cli/npm-star.md b/deps/npm/doc/cli/npm-star.md deleted file mode 100644 index 87d90b560c2027..00000000000000 --- a/deps/npm/doc/cli/npm-star.md +++ /dev/null @@ -1,22 +0,0 @@ -npm-star(1) -- Mark your favorite packages -========================================== - -## SYNOPSIS - - npm star [...] - npm unstar [...] - -## DESCRIPTION - -"Starring" a package means that you have some interest in it. It's -a vaguely positive way to show that you care. - -"Unstarring" is the same thing, but in reverse. - -It's a boolean thing. Starring repeatedly has no additional effect. - -## SEE ALSO - -* npm-view(1) -* npm-whoami(1) -* npm-adduser(1) diff --git a/deps/npm/doc/cli/npm-stars.md b/deps/npm/doc/cli/npm-stars.md deleted file mode 100644 index 1e225be29f3eda..00000000000000 --- a/deps/npm/doc/cli/npm-stars.md +++ /dev/null @@ -1,21 +0,0 @@ -npm-stars(1) -- View packages marked as favorites -================================================= - -## SYNOPSIS - - npm stars [] - -## DESCRIPTION - -If you have starred a lot of neat things and want to find them again -quickly this command lets you do just that. - -You may also want to see your friend's favorite packages, in this case -you will most certainly enjoy this command. - -## SEE ALSO - -* npm-star(1) -* npm-view(1) -* npm-whoami(1) -* npm-adduser(1) diff --git a/deps/npm/doc/cli/npm-start.md b/deps/npm/doc/cli/npm-start.md deleted file mode 100644 index e43f02149935a9..00000000000000 --- a/deps/npm/doc/cli/npm-start.md +++ /dev/null @@ -1,24 +0,0 @@ -npm-start(1) -- Start a package -=============================== - -## SYNOPSIS - - npm start [-- ] - -## DESCRIPTION - -This runs an arbitrary command specified in the package's `"start"` property of -its `"scripts"` object. If no `"start"` property is specified on the -`"scripts"` object, it will run `node server.js`. - -As of [`npm@2.0.0`](https://blog.npmjs.org/post/98131109725/npm-2-0-0), you can -use custom arguments when executing scripts. Refer to npm-run-script(1) for -more details. - -## SEE ALSO - -* npm-run-script(1) -* npm-scripts(7) -* npm-test(1) -* npm-restart(1) -* npm-stop(1) diff --git a/deps/npm/doc/cli/npm-stop.md b/deps/npm/doc/cli/npm-stop.md deleted file mode 100644 index 92b14b417962bd..00000000000000 --- a/deps/npm/doc/cli/npm-stop.md +++ /dev/null @@ -1,18 +0,0 @@ -npm-stop(1) -- Stop a package -============================= - -## SYNOPSIS - - npm stop [-- ] - -## DESCRIPTION - -This runs a package's "stop" script, if one was provided. - -## SEE ALSO - -* npm-run-script(1) -* npm-scripts(7) -* npm-test(1) -* npm-start(1) -* npm-restart(1) diff --git a/deps/npm/doc/cli/npm-test.md b/deps/npm/doc/cli/npm-test.md deleted file mode 100644 index 8a379e2efd0988..00000000000000 --- a/deps/npm/doc/cli/npm-test.md +++ /dev/null @@ -1,20 +0,0 @@ -npm-test(1) -- Test a package -============================= - -## SYNOPSIS - - npm test [-- ] - - aliases: t, tst - -## DESCRIPTION - -This runs a package's "test" script, if one was provided. - -## SEE ALSO - -* npm-run-script(1) -* npm-scripts(7) -* npm-start(1) -* npm-restart(1) -* npm-stop(1) diff --git a/deps/npm/doc/cli/npm-uninstall.md b/deps/npm/doc/cli/npm-uninstall.md deleted file mode 100644 index 38302b20d61fcd..00000000000000 --- a/deps/npm/doc/cli/npm-uninstall.md +++ /dev/null @@ -1,53 +0,0 @@ -npm-uninstall(1) -- Remove a package -============================= - -## SYNOPSIS - - npm uninstall [<@scope>/][@]... [-S|--save|-D|--save-dev|-O|--save-optional|--no-save] - - aliases: remove, rm, r, un, unlink - -## DESCRIPTION - -This uninstalls a package, completely removing everything npm installed -on its behalf. - -Example: - - npm uninstall sax - -In global mode (ie, with `-g` or `--global` appended to the command), -it uninstalls the current package context as a global package. - -`npm uninstall` takes 3 exclusive, optional flags which save or update -the package version in your main package.json: - -* `-S, --save`: Package will be removed from your `dependencies`. - -* `-D, --save-dev`: Package will be removed from your `devDependencies`. - -* `-O, --save-optional`: Package will be removed from your `optionalDependencies`. - -* `--no-save`: Package will not be removed from your `package.json` file. - -Further, if you have an `npm-shrinkwrap.json` then it will be updated as -well. - -Scope is optional and follows the usual rules for `npm-scope(7)`. - -Examples: - - npm uninstall sax --save - npm uninstall @myorg/privatepackage --save - npm uninstall node-tap --save-dev - npm uninstall dtrace-provider --save-optional - npm uninstall lodash --no-save - -## SEE ALSO - -* npm-prune(1) -* npm-install(1) -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) diff --git a/deps/npm/doc/cli/npm-whoami.md b/deps/npm/doc/cli/npm-whoami.md deleted file mode 100644 index 70b6a48f44671c..00000000000000 --- a/deps/npm/doc/cli/npm-whoami.md +++ /dev/null @@ -1,17 +0,0 @@ -npm-whoami(1) -- Display npm username -===================================== - -## SYNOPSIS - - npm whoami [--registry ] - -## DESCRIPTION - -Print the `username` config to standard output. - -## SEE ALSO - -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-adduser(1) diff --git a/deps/npm/doc/misc/npm-coding-style.md b/deps/npm/doc/misc/npm-coding-style.md deleted file mode 100644 index 1199f63fcc3f03..00000000000000 --- a/deps/npm/doc/misc/npm-coding-style.md +++ /dev/null @@ -1,192 +0,0 @@ -npm-coding-style(7) -- npm's "funny" coding style -================================================= - -## DESCRIPTION - -npm's coding style is a bit unconventional. It is not different for -difference's sake, but rather a carefully crafted style that is -designed to reduce visual clutter and make bugs more apparent. - -If you want to contribute to npm (which is very encouraged), you should -make your code conform to npm's style. - -Note: this concerns npm's code not the specific packages that you can download from the npm registry. - -## Line Length - -Keep lines shorter than 80 characters. It's better for lines to be -too short than to be too long. Break up long lists, objects, and other -statements onto multiple lines. - -## Indentation - -Two-spaces. Tabs are better, but they look like hell in web browsers -(and on GitHub), and node uses 2 spaces, so that's that. - -Configure your editor appropriately. - -## Curly braces - -Curly braces belong on the same line as the thing that necessitates them. - -Bad: - - function () - { - -Good: - - function () { - -If a block needs to wrap to the next line, use a curly brace. Don't -use it if it doesn't. - -Bad: - - if (foo) { bar() } - while (foo) - bar() - -Good: - - if (foo) bar() - while (foo) { - bar() - } - -## Semicolons - -Don't use them except in four situations: - -* `for (;;)` loops. They're actually required. -* null loops like: `while (something) ;` (But you'd better have a good - reason for doing that.) -* `case 'foo': doSomething(); break` -* In front of a leading `(` or `[` at the start of the line. - This prevents the expression from being interpreted - as a function call or property access, respectively. - -Some examples of good semicolon usage: - - ;(x || y).doSomething() - ;[a, b, c].forEach(doSomething) - for (var i = 0; i < 10; i ++) { - switch (state) { - case 'begin': start(); continue - case 'end': finish(); break - default: throw new Error('unknown state') - } - end() - } - -Note that starting lines with `-` and `+` also should be prefixed -with a semicolon, but this is much less common. - -## Comma First - -If there is a list of things separated by commas, and it wraps -across multiple lines, put the comma at the start of the next -line, directly below the token that starts the list. Put the -final token in the list on a line by itself. For example: - - var magicWords = [ 'abracadabra' - , 'gesundheit' - , 'ventrilo' - ] - , spells = { 'fireball' : function () { setOnFire() } - , 'water' : function () { putOut() } - } - , a = 1 - , b = 'abc' - , etc - , somethingElse - -## Quotes -Use single quotes for strings except to avoid escaping. - -Bad: - - var notOk = "Just double quotes" - -Good: - - var ok = 'String contains "double" quotes' - var alsoOk = "String contains 'single' quotes or apostrophe" - -## Whitespace - -Put a single space in front of `(` for anything other than a function call. -Also use a single space wherever it makes things more readable. - -Don't leave trailing whitespace at the end of lines. Don't indent empty -lines. Don't use more spaces than are helpful. - -## Functions - -Use named functions. They make stack traces a lot easier to read. - -## Callbacks, Sync/async Style - -Use the asynchronous/non-blocking versions of things as much as possible. -It might make more sense for npm to use the synchronous fs APIs, but this -way, the fs and http and child process stuff all uses the same callback-passing -methodology. - -The callback should always be the last argument in the list. Its first -argument is the Error or null. - -Be very careful never to ever ever throw anything. It's worse than useless. -Just send the error message back as the first argument to the callback. - -## Errors - -Always create a new Error object with your message. Don't just return a -string message to the callback. Stack traces are handy. - -## Logging - -Logging is done using the [npmlog](https://github.com/npm/npmlog) -utility. - -Please clean up logs when they are no longer helpful. In particular, -logging the same object over and over again is not helpful. Logs should -report what's happening so that it's easier to track down where a fault -occurs. - -Use appropriate log levels. See `npm-config(7)` and search for -"loglevel". - -## Case, naming, etc. - -Use `lowerCamelCase` for multiword identifiers when they refer to objects, -functions, methods, properties, or anything not specified in this section. - -Use `UpperCamelCase` for class names (things that you'd pass to "new"). - -Use `all-lower-hyphen-css-case` for multiword filenames and config keys. - -Use named functions. They make stack traces easier to follow. - -Use `CAPS_SNAKE_CASE` for constants, things that should never change -and are rarely used. - -Use a single uppercase letter for function names where the function -would normally be anonymous, but needs to call itself recursively. It -makes it clear that it's a "throwaway" function. - -## null, undefined, false, 0 - -Boolean variables and functions should always be either `true` or -`false`. Don't set it to 0 unless it's supposed to be a number. - -When something is intentionally missing or removed, set it to `null`. - -Don't set things to `undefined`. Reserve that value to mean "not yet -set to anything." - -Boolean objects are forbidden. - -## SEE ALSO - -* npm-developers(7) -* npm(1) diff --git a/deps/npm/doc/misc/npm-index.md b/deps/npm/doc/misc/npm-index.md deleted file mode 100644 index e6f9d1e49ce6f8..00000000000000 --- a/deps/npm/doc/misc/npm-index.md +++ /dev/null @@ -1,323 +0,0 @@ -npm-index(7) -- Index of all npm documentation -============================================== - -### README(1) - -a JavaScript package manager - -## Command Line Documentation - -Using npm on the command line - -### npm(1) - -javascript package manager - -### npm-access(1) - -Set access level on published packages - -### npm-adduser(1) - -Add a registry user account - -### npm-audit(1) - -Run a security audit - -### npm-bin(1) - -Display npm bin folder - -### npm-bugs(1) - -Bugs for a package in a web browser maybe - -### npm-build(1) - -Build a package - -### npm-bundle(1) - -REMOVED - -### npm-cache(1) - -Manipulates packages cache - -### npm-ci(1) - -Install a project with a clean slate - -### npm-completion(1) - -Tab Completion for npm - -### npm-config(1) - -Manage the npm configuration files - -### npm-dedupe(1) - -Reduce duplication - -### npm-deprecate(1) - -Deprecate a version of a package - -### npm-dist-tag(1) - -Modify package distribution tags - -### npm-docs(1) - -Docs for a package in a web browser maybe - -### npm-doctor(1) - -Check your environments - -### npm-edit(1) - -Edit an installed package - -### npm-explore(1) - -Browse an installed package - -### npm-help-search(1) - -Search npm help documentation - -### npm-help(1) - -Get help on npm - -### npm-hook(1) - -Manage registry hooks - -### npm-init(1) - -create a package.json file - -### npm-install-ci-test(1) - -Install a project with a clean slate and run tests - -### npm-install-test(1) - -Install package(s) and run tests - -### npm-install(1) - -Install a package - -### npm-link(1) - -Symlink a package folder - -### npm-logout(1) - -Log out of the registry - -### npm-ls(1) - -List installed packages - -### npm-org(1) - -Manage orgs - -### npm-outdated(1) - -Check for outdated packages - -### npm-owner(1) - -Manage package owners - -### npm-pack(1) - -Create a tarball from a package - -### npm-ping(1) - -Ping npm registry - -### npm-prefix(1) - -Display prefix - -### npm-profile(1) - -Change settings on your registry profile - -### npm-prune(1) - -Remove extraneous packages - -### npm-publish(1) - -Publish a package - -### npm-rebuild(1) - -Rebuild a package - -### npm-repo(1) - -Open package repository page in the browser - -### npm-restart(1) - -Restart a package - -### npm-root(1) - -Display npm root - -### npm-run-script(1) - -Run arbitrary package scripts - -### npm-search(1) - -Search for packages - -### npm-shrinkwrap(1) - -Lock down dependency versions for publication - -### npm-star(1) - -Mark your favorite packages - -### npm-stars(1) - -View packages marked as favorites - -### npm-start(1) - -Start a package - -### npm-stop(1) - -Stop a package - -### npm-team(1) - -Manage organization teams and team memberships - -### npm-test(1) - -Test a package - -### npm-token(1) - -Manage your authentication tokens - -### npm-uninstall(1) - -Remove a package - -### npm-unpublish(1) - -Remove a package from the registry - -### npm-update(1) - -Update a package - -### npm-version(1) - -Bump a package version - -### npm-view(1) - -View registry info - -### npm-whoami(1) - -Display npm username - -## API Documentation - -Using npm in your Node programs - -## Files - -File system structures npm uses - -### npm-folders(5) - -Folder Structures Used by npm - -### npm-package-locks(5) - -An explanation of npm lockfiles - -### npm-shrinkwrap.json(5) - -A publishable lockfile - -### npmrc(5) - -The npm config files - -### package-lock.json(5) - -A manifestation of the manifest - -### package.json(5) - -Specifics of npm's package.json handling - -## Misc - -Various other bits and bobs - -### npm-coding-style(7) - -npm's "funny" coding style - -### npm-config(7) - -More than you probably want to know about npm configuration - -### npm-developers(7) - -Developer Guide - -### npm-disputes(7) - -Handling Module Name Disputes - -### npm-index(7) - -Index of all npm documentation - -### npm-orgs(7) - -Working with Teams & Orgs - -### npm-registry(7) - -The JavaScript Package Registry - -### npm-scope(7) - -Scoped packages - -### npm-scripts(7) - -How npm handles the "scripts" field - -### removing-npm(7) - -Cleaning the Slate - -### semver(7) - -The semantic versioner for npm - diff --git a/deps/npm/doc/spec/file-specifiers.md b/deps/npm/doc/spec/file-specifiers.md deleted file mode 100644 index e737909db52579..00000000000000 --- a/deps/npm/doc/spec/file-specifiers.md +++ /dev/null @@ -1,151 +0,0 @@ -# `file:` specifiers - -`specifier` refers to the value part of the `package.json`'s `dependencies` -object. This is a semver expression for registry dependencies and -URLs and URL-like strings for other types. - -### Dependency Specifiers - -* A `file:` specifier is either an absolute path (eg `/path/to/thing`, `d:\path\to\thing`): - * An absolute `file:///absolute/path` with any number of leading slashes - being treated as a single slash. That is, `file:/foo/bar` and - `file:///foo/bar` reference the same package. -* … or a relative path (eg `../path/to/thing`, `path\to\subdir`). Leading - slashes on a file specifier will be removed, that is 'file://../foo/bar` - references the same package as same as `file:../foo/bar`. The latter is - considered canonical. -* Attempting to install a specifier that has a windows drive letter will - produce an error on non-Windows systems. -* A valid `file:` specifier points is: - * a valid package file. That is, a `.tar`, `.tar.gz` or `.tgz` containing - `/package.json`. - * OR, a directory that contains a `package.json` - -Relative specifiers are relative to the file they were found in, or, if -provided on the command line, the CWD that the command was run from. - -An absolute specifier found in a `package.json` or `npm-shrinkwrap.json` is -probably an error as it's unlikely to be portable between computers and -should warn. - -A specifier provided as a command line argument that is on a different drive -is an error. That is, `npm install file:d:/foo/bar` is an error if the -current drive is `c`. The point of this rule is that if we can't produce a -relative path then it's an error. - -### Specifier Disambiguation - -On the command line, plain paths are allowed. These paths can be ambiguous -as they could be a path, a plain package name or a github shortcut. This -ambiguity is resolved by checking to see if either a directory exists that -contains a `package.json`. If either is the case then the specifier is a -file specifier, otherwise it's a registry or github specifier. - -### Specifier Matching - -A specifier is considered to match a dependency on disk when the `realpath` -of the fully resolved specifier matches the `realpath` of the package on disk. - -### Saving File Specifiers - -When saving to both `package.json` and `npm-shrinkwrap.json` they will be -saved using the `file:../relative/path` form, and the relative path will be -relative to the project's root folder. This is particularly important to -note for the `npm-shrinkwrap.json` as it means the specifier there will -be different then the original `package.json` (where it was relative to that -`package.json`). - -When shrinkwrapping file specifiers, the contents of the destination -package's `node_modules` WILL NOT be included in the shrinkwrap. If you want to lock -down the destination package's `node_modules` you should create a shrinkwrap for it -separately. - -This is necessary to support the mono repo use case where many projects file -to the same package. If each project included its own `npm-shrinkwrap.json` -then they would each have their own distinct set of transitive dependencies -and they'd step on each other any time you ran an install in one or the other. - -NOTE: This should not have an effect on shrinkwrapping of other sorts of -shrinkwrapped packages. - -### Installation - -#### File type specifiers pointing at tarballs - -File-type specifiers pointing at a `.tgz` or `.tar.gz` or `.tar` file will -install it as a package file in the same way we would a remote tarball. The -checksum of the package file should be recorded so that we can check for updates. - -#### File type specifers pointing at directories - -File-type specifiers that point at directories will necessarily not do -anything for `fetch` and `extract` phases. - -The symlink should be created during the `finalize` phase. - -The `preinstall` for file-type specifiers MUST be run AFTER the -`finalize` phase as the symlink may be a relative path reaching outside the -current project root and a symlink that resolves in `.staging` won't resolve -in the package's final resting place. - -If the module is inside the package root that we're running the install for then -dependencies of the linked package will be hoisted to the top level as usual. - -If the module is outside the package root then dependencies will be installed inside -the linked module's `node_modules` folder. - -### Removal - -Removal should remove the symlink. - -Removal MUST NOT remove the transitive dependencies IF they're installed in -the linked module's `node_modules` folder. - -### Listing - -In listings they should not include a version as the version is not -something `npm` is concerned about. This also makes them easily -distinguishable from symlinks of packages that have other dependency -specifiers. - -If you had run: - -``` -npm install --save file:../a -``` - -And then run: -``` -npm ls -``` - -You would see: - -``` -example-package@1.0.0 /path/to/example-package -└── a → file:../a -``` - -``` -example-package@1.0.0 /path/to/example-package -+-- a -> file:../a -``` - -Of note here: No version is included as the relevant detail is WHERE the -package came from, not what version happened to be in that path. - -### Outdated - -Local specifiers should only show up in `npm outdated` if they're missing -and when they do, they should be reported as: - -``` -Package Current Wanted Latest Location -a MISSING LOCAL LOCAL example-package -``` - -### Updating - -If a dependency with a local specifier is already installed then `npm -update` shouldn't do anything. If one is missing then it should be -installed as if you ran `npm install`. diff --git a/deps/npm/doc/spec/package-lock.md b/deps/npm/doc/spec/package-lock.md deleted file mode 100644 index 87d5c223537cfe..00000000000000 --- a/deps/npm/doc/spec/package-lock.md +++ /dev/null @@ -1,294 +0,0 @@ -# package-lock and npm-shrinkwrap - -`npm` can have one of two different lock files: - -* `package-lock.json`, which is ordinarily always present and is never published. -* `npm-shrinkwrap.json`, which is created with `npm shrinkwrap` and usually published. - -You can only have one of them and in the event that you have both, -`npm-shrinkwrap.json` takes precedence. The files are exactly the same -format and in fact all the `npm shrinkwrap` command does is rename your -`package-lock.json`. - -Through the rest of this document we will refer to the package-lock and -`package-lock.json` but everything also applies to `npm-shrinkwrap.json`. - -## File Format - -### name - -The name of the package this is a package-lock for. This must match what's in `package.json`. - -### version - -The version of the package this is a package-lock for. This must match what's in `package.json`. - -### lockfileVersion *(new)* - -An integer version, starting at `1` with the version number of this document -whose semantics were used when generating this `package-lock.json`. - -### preserveSymlinks *(new)* - -Indicates that the install was done with the environment variable -`NODE_PRESERVE_SYMLINKS` enabled. The installer should insist that the value of this -property match that environment variable. - -### dependencies - -These are the modules installed in the `node_modules`. Some of these are -dependencies some of these are transitive dependencies (that is, -dependencies of our dependencies). - -This is a mapping of package name to dependency object. Dependency objects have the -following properties: - -#### version *(changed)* - -This is a specifier that uniquely identifies this package and should be -usable in fetching a new copy of it. - -* bundled dependencies: Regardless of source, this is a version number that is purely for informational purposes. -* registry sources: This is a version number. (eg, `1.2.3`) -* git sources: This is a git specifier with resolved committish. (eg, `git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e`) -* http tarball sources: This is the URL of the tarball. (eg, `https://example.com/example-1.3.0.tgz`) -* local tarball sources: This is the file URL of the tarball. (eg `file:///opt/storage/example-1.3.0.tgz`) -* local link sources: This is the file URL of the link. (eg `file:libs/our-module`) - -#### integrity *(new)* - -This is a [Standard Subresource -Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) for -this resource. - -* For bundled dependencies this is not included, regardless of source. -* For registry sources, this is the `integrity` that the registry provided, or if one wasn't provided the SHA1 in `shasum`. -* For git sources this is the specific commit hash we cloned from. -* For remote tarball sources this is an integrity based on a SHA512 of - the file. -* For local tarball sources: This is an integrity field based on the SHA512 of the file. - -#### resolved - -* For bundled dependencies this is not included, regardless of source. -* For registry sources this is path of the tarball relative to the registry - URL. If the tarball URL isn't on the same server as the registry URL then - this is a complete URL. - - eg, Given a `package-lock.json` file containing: - - ``` - "resolved": "https://registry.npmjs.org/example/-/example-1.0.0.tgz" - ``` - - and a registry source configuring a custom value: - - ``` - npm install --registry https://registry.example.com - ``` - - the package will be fetched from the custom-defined registry: - - ``` - https://registry.example.com/example/-/example-1.0.0.tgz - ``` - -#### link *(new)* - -If this module was symlinked in development but had semver in the -`package.json` then this is the relative path of that link. - -Discussion of the semantics of this will go in the symlinks RFC. - -Implementation note: To be implemented post npm@5. - -#### bundled *(new)* - -If true, this is the bundled dependency and will be installed by the parent -module. When installing, this module will be extracted from the parent -module during the extract phase, not installed as a separate dependency. - -#### dev - -If true then this dependency is either a development dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both a development dependency of the top level and a -transitive dependency of a non-development dependency of the top level. - -#### optional - -If true then this dependency is either an optional dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both an optional dependency of the top level and a -transitive dependency of a non-optional dependency of the top level. - -All optional dependencies should be included even if they're uninstallable -on the current platform. - -#### from - -This is a record of what specifier was used to originally install this -package. This should be used only for git dependencies. - -#### requires - -This is a mapping of module name to version. This is a list of everything -this module requires, regardless of where it will be installed. The version -should match via normal matching rules a dependency either in our -`dependencies` or in a level higher than us. - -#### dependencies - -Exactly like `dependencies` at the top level, this is a list of modules to -install in the `node_modules` of this module. - -## Generating - -### `npm init` - -If neither a `package-lock.json` nor an `npm-shrinkwrap.json` exist then -`npm init` will create a `package-lock.json`. This is functionally -equivalent to running `npm shrinkwrap` after the current init completes and -renaming the result to `package-lock.json`. - -### `npm install --save` - -If either an `npm-shrinkwrap.json` or a `package-lock.json` exists then it -will be updated. - -If neither exist then a `package-lock.json` should be generated. - -If a `package.json` does not exist, it should be generated. The generated -`package.json` should be empty, as in: - -``` -{ - "dependencies": { - } -} -``` - -If the user wants to get a default package name/version added they can run `npm init`. - -### `npm shrinkwrap` - -If a `package-lock.json` exists, rename it to `npm-shrinkwrap.json`. -Refresh the data from the installer's ideal tree. - -The top level `name` and `version` come from the `package.json`. It is an -error if either are missing or invalid. - -#### dependencies.dev - -This is `true` if this dependency is ONLY installed to fulfill either a top -level development dependency, or one of its transitive dependencies. - -Given: -``` -B (Dev) → C -``` - -Then both B and C would be `dev: true`. - -Given: -``` -A → B → C -B (Dev) -> C -``` - -Then all dependencies would be `dev: false`. - -#### dependencies.optional - -This is `true` if this dependency is ONLY ever either an optional dependency -or a transitive dependency of optional dependencies. - -Given: -``` -A (Opt) → B → C -``` - -Then all three of A, B and C would be flagged as optional. - -Given: -``` -A (Opt) → B → C -D → C -``` - -Then A and B would be flagged as optional, but C would not be. - -Given: -``` -A (Opt) → B → C -D → A -``` - -Then none would be flagged as optional. - -## Installing - -If the `packageIntegrity` in the `package-lock.json` differs from the one -computed from the `package.json` then places where the `package.json` is -incompatible with the `package-lock.json` a new module should be installed. -That is, while the `package-lock.json` ordinarily defines the state of your -project, if your `package.json` is edited independently it will take -precedence. - -The `package-lock.json` describes the exact tree that `npm` should create. -Any deviation between the `package.json` and the shrinkwrap/lock should -result in a warning be issued. This includes: - -* Modules in `package.json` but missing from the `package-lock.json` -* Modules in the `package-lock.json` but missing from the `package.json`. -* Modules in `package.json` whose specifiers don't match the version in `package-lock.json`. - -Warn if the `lockfileVersion` in the `package-lock.json` is for a different -major version than we implement. - -Module resolution from package-lock data works as such: - -* If install was run with `--resolve-links` and a dependency has a `link` - property then a symlink is made using that. If the version of the - destination can not be matched to the package-lock and/or the package.json - then a warning will be issued. - -* Otherwise, if a `integrity` is available then we try to install it from the cache using it. - -If `integrity` is unavailable or we are unable to locate a module from the `integrity` then: - -* If `lockfileVersion` is set: - * Install using the value of `version` and validate the result against the - `integrity`. -* Otherwise, try these in turn and validate the result against the `integrity`: - * `resolved`, then `from`, then `version. - * `from` can be either `package@specifier` or just `specifier`. - -Regardless of how the module is installed the metadata in the installed -module should be identical to what it would have been if the module were -installed w/o a package-lock. - -## Implied Changes To Other Commands - -### `npm rm --save` - -Currently if you ask to remove a package that's both a direct and a -transitive dependency, we'll remove the package from `node_modules` even if -this results in a broken tree. This was chosen at the time because we felt -that users would expect `npm rm pkgname` to be equivalent of -`rm -rf node_modules/pkgname`. - -As you are no longer going to be allowed to put your `node_modules` in a -state that's not a valid package-lock, this means this behavior is no longer -valid. Instead we should follow normal rules, removing it from the -dependencies for the top level but only removing the module on disk if -nothing requires it any more. - -## Additional fields / Adding new fields - -Installers should ignore any field they aren't aware of. It's not an error -to have additional properties in the package-lock or lock file. - -Installers that want to add new fields should either have one added via RFC -in the npm issue tracker and an accompanying documentation PR, or should prefix -it with the name of their project. diff --git a/deps/npm/docs/LICENSE b/deps/npm/docs/LICENSE new file mode 100644 index 00000000000000..5169a5e4135e9f --- /dev/null +++ b/deps/npm/docs/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 gatsbyjs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/deps/npm/doc/cli/npm-access.md b/deps/npm/docs/content/cli-commands/npm-access.md similarity index 74% rename from deps/npm/doc/cli/npm-access.md rename to deps/npm/docs/content/cli-commands/npm-access.md index aeea0178ec66d7..0fbce9c0759d12 100644 --- a/deps/npm/doc/cli/npm-access.md +++ b/deps/npm/docs/content/cli-commands/npm-access.md @@ -1,22 +1,31 @@ -npm-access(1) -- Set access level on published packages -======================================================= +--- +section: cli-commands +title: npm-access +description: Set access level on published packages +--- -## SYNOPSIS +# npm-access(1) - npm access public [] - npm access restricted [] +## Set access level on published packages - npm access grant [] - npm access revoke [] +### Synopsis - npm access 2fa-required [] - npm access 2fa-not-required [] +```bash +npm access public [] +npm access restricted [] - npm access ls-packages [||] - npm access ls-collaborators [ []] - npm access edit [] +npm access grant [] +npm access revoke [] -## DESCRIPTION +npm access 2fa-required [] +npm access 2fa-not-required [] + +npm access ls-packages [||] +npm access ls-collaborators [ []] +npm access edit [] +``` + +### Description Used to set access controls on private packages. @@ -48,7 +57,7 @@ subcommand. * edit: Set the access privileges for a package at once using `$EDITOR`. -## DETAILS +### Details `npm access` always operates directly on the current registry, configurable from the command line using `--registry=`. @@ -75,10 +84,10 @@ with an HTTP 402 status code (logically enough), unless you use Management of teams and team memberships is done with the `npm team` command. -## SEE ALSO +### See Also * [`libnpmaccess`](https://npm.im/libnpmaccess) -* npm-team(1) -* npm-publish(1) -* npm-config(7) -* npm-registry(7) +* [npm team](/cli-commands/npm-team) +* [npm publish](/cli-commands/npm-publish) +* [npm config](/cli-commands/npm-config) +* [npm registry](/using-npm/registry) diff --git a/deps/npm/doc/cli/npm-adduser.md b/deps/npm/docs/content/cli-commands/npm-adduser.md similarity index 66% rename from deps/npm/doc/cli/npm-adduser.md rename to deps/npm/docs/content/cli-commands/npm-adduser.md index 72433e00f74832..2df35e45fc550e 100644 --- a/deps/npm/doc/cli/npm-adduser.md +++ b/deps/npm/docs/content/cli-commands/npm-adduser.md @@ -1,17 +1,26 @@ -npm-adduser(1) -- Add a registry user account -============================================= + --- +section: cli-commands +title: npm-adduser +description: Set access level on published packages +--- -## SYNOPSIS +# npm-adduser(1) - npm adduser [--registry=url] [--scope=@orgname] [--always-auth] [--auth-type=legacy] +## Add a registry user account - aliases: login, add-user +### Synopsis -## DESCRIPTION +```bash +npm adduser [--registry=url] [--scope=@orgname] [--always-auth] [--auth-type=legacy] + +aliases: login, add-user +``` + +### Description Create or verify a user named `` in the specified registry, and save the credentials to the `.npmrc` file. If no registry is specified, -the default registry will be used (see `npm-config(7)`). +the default registry will be used (see [`config`](/using-npm/config)). The username, password, and email are read in from prompts. @@ -26,30 +35,32 @@ your existing record. `npm login` is an alias to `adduser` and behaves exactly the same way. -## CONFIGURATION +### Configuration -### registry +#### registry Default: https://registry.npmjs.org/ The base URL of the npm package registry. If `scope` is also specified, this registry will only be used for packages with that scope. `scope` defaults -to the scope of the project directory you're currently in, if any. See `npm-scope(7)`. +to the scope of the project directory you're currently in, if any. See [`scope`](/using-npm/scope). -### scope +#### scope Default: none If specified, the user and login credentials given will be associated -with the specified scope. See `npm-scope(7)`. You can use both at the same time, +with the specified scope. See [`scope`](/using-npm/scope). You can use both at the same time, e.g. +```bash npm adduser --registry=http://myregistry.example.com --scope=@myco +``` This will set a registry for the given scope and login or create a user for that registry at the same time. -### always-auth +#### always-auth Default: false @@ -57,16 +68,16 @@ If specified, save configuration indicating that all requests to the given registry should include authorization information. Useful for private registries. Can be used with `--registry` and / or `--scope`, e.g. +```bash npm adduser --registry=http://private-registry.example.com --always-auth +``` This will ensure that all requests to that registry (including for tarballs) include an authorization header. This setting may be necessary for use with private registries where metadata and package tarballs are stored on hosts with -different hostnames. See `always-auth` in `npm-config(7)` for more details on -always-auth. Registry-specific configuration of `always-auth` takes precedence -over any global configuration. +different hostnames. See `always-auth` in [`config`](/using-npm/config) for more details on always-auth. Registry-specific configuration of `always-auth` takes precedence over any global configuration. -### auth-type +#### auth-type * Default: `'legacy'` * Type: `'legacy'`, `'sso'`, `'saml'`, `'oauth'` @@ -75,11 +86,10 @@ What authentication strategy to use with `adduser`/`login`. Some npm registries (for example, npmE) might support alternative auth strategies besides classic username/password entry in legacy npm. -## SEE ALSO +### See Also -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-owner(1) -* npm-whoami(1) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm owner](/cli-commands/npm-owner) +* [npm whoami](/cli-commands/npm-whoami) diff --git a/deps/npm/doc/cli/npm-audit.md b/deps/npm/docs/content/cli-commands/npm-audit.md similarity index 85% rename from deps/npm/doc/cli/npm-audit.md rename to deps/npm/docs/content/cli-commands/npm-audit.md index 10039ea09cbc1d..0aba874f96df8d 100644 --- a/deps/npm/doc/cli/npm-audit.md +++ b/deps/npm/docs/content/cli-commands/npm-audit.md @@ -1,73 +1,82 @@ -npm-audit(1) -- Run a security audit -==================================== +--- +section: cli-commands +title: npm-audit +description: Run a security audit +--- -## SYNOPSIS +# npm-audit(1) - npm audit [--json|--parseable|--audit-level=(low|moderate|high|critical)] - npm audit fix [--force|--package-lock-only|--dry-run] +## Run a security audit - common options: [--production] [--only=(dev|prod)] +### Synopsis -## EXAMPLES +```bash +npm audit [--json|--parseable|--audit-level=(low|moderate|high|critical)] +npm audit fix [--force|--package-lock-only|--dry-run] + +common options: [--production] [--only=(dev|prod)] +``` + +### Examples Scan your project for vulnerabilities and automatically install any compatible updates to vulnerable dependencies: -``` +```bash $ npm audit fix ``` Run `audit fix` without modifying `node_modules`, but still updating the pkglock: -``` +```bash $ npm audit fix --package-lock-only ``` Skip updating `devDependencies`: -``` +```bash $ npm audit fix --only=prod ``` Have `audit fix` install semver-major updates to toplevel dependencies, not just semver-compatible ones: -``` +```bash $ npm audit fix --force ``` Do a dry run to get an idea of what `audit fix` will do, and _also_ output install information in JSON format: -``` +```bash $ npm audit fix --dry-run --json ``` Scan your project for vulnerabilities and just show the details, without fixing anything: -``` +```bash $ npm audit ``` Get the detailed audit report in JSON format: -``` +```bash $ npm audit --json ``` Get the detailed audit report in plain text result, separated by tab characters, allowing for future reuse in scripting or command line post processing, like for example, selecting some of the columns printed: -``` +```bash $ npm audit --parseable ``` To parse columns, you can use for example `awk`, and just print some of them: -``` +```bash $ npm audit --parseable | awk -F $'\t' '{print $1,$4}' ``` Fail an audit only if the results include a vulnerability with a level of moderate or higher: -``` +```bash $ npm audit --audit-level=moderate ``` -## DESCRIPTION +### Description The audit command submits a description of the dependencies configured in your project to your default registry and asks for a report of known @@ -88,7 +97,7 @@ to specify the minimum vulnerability level that will cause the command to fail. option does not filter the report output, it simply changes the command's failure threshold. -## CONTENT SUBMITTED +### Content Submitted * npm_version * node_version @@ -96,7 +105,7 @@ threshold. * node_env * A scrubbed version of your package-lock.json or npm-shrinkwrap.json -### SCRUBBING +#### Scrubbing In order to ensure that potentially sensitive information is not included in the audit data bundle, some dependencies may have their names (and sometimes @@ -113,15 +122,15 @@ The non-reversible identifiers are a sha256 of a session-specific UUID and the value being replaced, ensuring a consistent value within the payload that is different between runs. -## EXIT CODE +### Exit Code The `npm audit` command will exit with a 0 exit code if no vulnerabilities were found. If vulnerabilities were found the exit code will depend on the `audit-level` configuration setting. -## SEE ALSO +### See Also -* npm-install(1) -* package-locks(5) -* config(7) +* [npm install](/cli-commands/npm-install) +* [package-locks](/configuring-npm/package-locks) +* [config](/using-npm/config) diff --git a/deps/npm/docs/content/cli-commands/npm-bin.md b/deps/npm/docs/content/cli-commands/npm-bin.md new file mode 100644 index 00000000000000..6c7ce0eee54e21 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-bin.md @@ -0,0 +1,26 @@ +--- +section: cli-commands +title: npm-bin +description: Display npm bin folder +--- + +# npm-bin(1) + +## Display npm bin folder + +### Synopsis +```bash +npm bin [-g|--global] +``` + +### Description + +Print the folder where npm will install executables. + +### See Also + +* [npm prefix](/cli-commands/npm-prefix) +* [npm root](/cli-commands/npm-root) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/docs/content/cli-commands/npm-bugs.md b/deps/npm/docs/content/cli-commands/npm-bugs.md new file mode 100644 index 00000000000000..dcc9c358df14d8 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-bugs.md @@ -0,0 +1,50 @@ +--- +section: cli-commands +title: npm-bugs +description: Bugs for a package in a web browser maybe +--- + +# npm-bugs(1) + +## Bugs for a package in a web browser maybe + +### Synopsis +```bash +npm bugs [] + +aliases: issues +``` + +### Description + +This command tries to guess at the likely location of a package's +bug tracker URL, and then tries to open it using the `--browser` +config param. If no package name is provided, it will search for +a `package.json` in the current folder and use the `name` property. + +### Configuration + +#### browser + +* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` +* Type: String + +The browser that is called by the `npm bugs` command to open websites. + +#### registry + +* Default: https://registry.npmjs.org/ +* Type: url + +The base URL of the npm package registry. + + +### See Also + +* [npm docs](/cli-commands/npm-docs) +* [npm view](/cli-commands/npm-view) +* [npm publish](/cli-commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) diff --git a/deps/npm/docs/content/cli-commands/npm-build.md b/deps/npm/docs/content/cli-commands/npm-build.md new file mode 100644 index 00000000000000..b657129787663d --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-build.md @@ -0,0 +1,34 @@ +--- +section: cli-commands +title: npm-build +description: Build a package +--- + +# npm-build(1) + +## Build a package + +### Synopsis +```shell +npm build [] +``` + +* ``: + A folder containing a `package.json` file in its root. + +### Description + +This is the plumbing command called by `npm link` and `npm install`. + +It should generally be called during installation, but if you need to run it +directly, run: +```bash + npm run-script build +``` + +### See Also + +* [npm install](/cli-commands/npm-install) +* [npm link](/cli-commands/npm-link) +* [npm scripts](/using-npm/scripts) +* [package.json](/configuring-npm/package-json) diff --git a/deps/npm/doc/cli/npm-bundle.md b/deps/npm/docs/content/cli-commands/npm-bundle.md similarity index 58% rename from deps/npm/doc/cli/npm-bundle.md rename to deps/npm/docs/content/cli-commands/npm-bundle.md index 69b3d83e458d7e..76417ac8b0b0c7 100644 --- a/deps/npm/doc/cli/npm-bundle.md +++ b/deps/npm/docs/content/cli-commands/npm-bundle.md @@ -1,7 +1,14 @@ -npm-bundle(1) -- REMOVED -======================== +--- +section: cli-commands +title: npm-bundle +description: REMOVED +--- -## DESCRIPTION +# npm-bundle(1) + +## REMOVED + +### Description The `npm bundle` command has been removed in 1.0, for the simple reason that it is no longer necessary, as the default behavior is now to @@ -9,6 +16,6 @@ install packages into the local space. Just use `npm install` now to do what `npm bundle` used to do. -## SEE ALSO +### See Also -* npm-install(1) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/cli/npm-cache.md b/deps/npm/docs/content/cli-commands/npm-cache.md similarity index 75% rename from deps/npm/doc/cli/npm-cache.md rename to deps/npm/docs/content/cli-commands/npm-cache.md index 92a6236c0c9e90..ed31a320421b0c 100644 --- a/deps/npm/doc/cli/npm-cache.md +++ b/deps/npm/docs/content/cli-commands/npm-cache.md @@ -1,19 +1,28 @@ -npm-cache(1) -- Manipulates packages cache -========================================== +--- +section: cli-commands +title: npm-cache +description: Manipulates packages cache +--- -## SYNOPSIS +# npm-cache(1) - npm cache add - npm cache add - npm cache add - npm cache add @ +## Manipulates packages cache - npm cache clean [] - aliases: npm cache clear, npm cache rm +### Synopsis - npm cache verify +```bash +npm cache add +npm cache add +npm cache add +npm cache add @ -## DESCRIPTION +npm cache clean [] +aliases: npm cache clear, npm cache rm + +npm cache verify +``` + +### Description Used to add, list, or clean the npm cache folder. @@ -29,7 +38,7 @@ Used to add, list, or clean the npm cache folder. Verify the contents of the cache folder, garbage collecting any unneeded data, and verifying the integrity of the cache index and all cached data. -## DETAILS +### Details npm stores cache data in an opaque directory within the configured `cache`, named `_cacache`. This directory is a `cacache`-based content-addressable cache @@ -51,7 +60,7 @@ directly. npm will not remove data by itself: the cache will grow as new packages are installed. -## A NOTE ABOUT THE CACHE'S DESIGN +### A note about the cache's design The npm cache is strictly a cache: it should not be relied upon as a persistent and reliable data store for package data. npm makes no guarantee that a @@ -62,22 +71,21 @@ if it does return data, that data will be exactly the data that was inserted. To run an offline verification of existing cache contents, use `npm cache verify`. -## CONFIGURATION +### Configuration -### cache +#### cache Default: `~/.npm` on Posix, or `%AppData%/npm-cache` on Windows. The root cache folder. -## SEE ALSO +### See Also -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-install(1) -* npm-publish(1) -* npm-pack(1) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm install](/cli-commands/npm-install) +* [npm publish](/cli-commands/npm-publish) +* [npm pack](/cli-commands/npm-pack) * https://npm.im/cacache * https://npm.im/pacote diff --git a/deps/npm/doc/cli/npm-ci.md b/deps/npm/docs/content/cli-commands/npm-ci.md similarity index 77% rename from deps/npm/doc/cli/npm-ci.md rename to deps/npm/docs/content/cli-commands/npm-ci.md index 289bb7c195a9ee..357ba16cf6ade1 100644 --- a/deps/npm/doc/cli/npm-ci.md +++ b/deps/npm/docs/content/cli-commands/npm-ci.md @@ -1,15 +1,23 @@ -npm-ci(1) -- Install a project with a clean slate -=================================== +--- +section: cli-commands +title: npm-ci +description: Install a project with a clean slate +--- -## SYNOPSIS +# npm-ci(1) - npm ci +## Install a project with a clean slate -## EXAMPLE +### Synopsis +```bash +npm ci +``` + +### Example Make sure you have a package-lock and an up-to-date install: -``` +```bash $ cd ./my/npm/project $ npm install added 154 packages in 10s @@ -18,14 +26,14 @@ $ ls | grep package-lock Run `npm ci` in that project -``` +```bash $ npm ci added 154 packages in 5s ``` Configure Travis to build using `npm ci` instead of `npm install`: -``` +```bash # .travis.yml install: - npm ci @@ -35,9 +43,9 @@ cache: - "$HOME/.npm" ``` -## DESCRIPTION +### Description -This command is similar to `npm-install(1)`, except it's meant to be used in +This command is similar to [`npm install`](/cli-commands/npm-install), except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies. It can be significantly faster than a regular npm @@ -53,7 +61,7 @@ In short, the main differences between using `npm install` and `npm ci` are: * If a `node_modules` is already present, it will be automatically removed before `npm ci` begins its install. * It will never write to `package.json` or any of the package-locks: installs are essentially frozen. -## SEE ALSO +### See Also -* npm-install(1) -* npm-package-locks(5) +* [npm install](/cli-commands/npm-install) +* [package-locks](/configuring-npm/package-locks) diff --git a/deps/npm/doc/cli/npm-completion.md b/deps/npm/docs/content/cli-commands/npm-completion.md similarity index 56% rename from deps/npm/doc/cli/npm-completion.md rename to deps/npm/docs/content/cli-commands/npm-completion.md index 1c675d96021833..59bfca503e0846 100644 --- a/deps/npm/doc/cli/npm-completion.md +++ b/deps/npm/docs/content/cli-commands/npm-completion.md @@ -1,11 +1,19 @@ -npm-completion(1) -- Tab Completion for npm -=========================================== +--- +section: cli-commands +title: npm-completion +description: Tab Completion for npm +--- -## SYNOPSIS +# npm-completion(1) - source <(npm completion) +## Tab Completion for npm -## DESCRIPTION +### Synopsis +```bash +source <(npm completion) +``` + +### Description Enables tab-completion in all npm commands. @@ -14,19 +22,21 @@ loads the completions into your current shell. Adding it to your ~/.bashrc or ~/.zshrc will make the completions available everywhere: - npm completion >> ~/.bashrc - npm completion >> ~/.zshrc +```bash +npm completion >> ~/.bashrc +npm completion >> ~/.zshrc +``` You may of course also pipe the output of `npm completion` to a file -such as `/usr/local/etc/bash_completion.d/npm` or -`/etc/bash_completion.d/npm` if you have a system that will read +such as `/usr/local/etc/bash_completion.d/npm` or +`/etc/bash_completion.d/npm` if you have a system that will read that file for you. When `COMP_CWORD`, `COMP_LINE`, and `COMP_POINT` are defined in the environment, `npm completion` acts in "plumbing mode", and outputs completions based on the arguments. -## SEE ALSO +### See Also -* npm-developers(7) -* npm(1) +* [npm developers](/using-npm/developers) +* [npm](/cli-commands/npm) diff --git a/deps/npm/docs/content/cli-commands/npm-config.md b/deps/npm/docs/content/cli-commands/npm-config.md new file mode 100644 index 00000000000000..c2f2033b066d29 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-config.md @@ -0,0 +1,85 @@ +--- +section: cli-commands +title: npm-config +description: Manage the npm configuration files +--- + +# npm-config(1) + +## Manage the npm configuration files + +### Synopsis +```bash +npm config set [-g|--global] +npm config get +npm config delete +npm config list [-l] [--json] +npm config edit +npm get +npm set [-g|--global] + +aliases: c +``` + +### Description + +npm gets its config settings from the command line, environment +variables, `npmrc` files, and in some cases, the `package.json` file. + +See [npmrc](/configuring-npm/npmrc) for more information about the npmrc files. + +See [config](/using-npm/config) for a more thorough discussion of the mechanisms +involved. + +The `npm config` command can be used to update and edit the contents +of the user and global npmrc files. + +### Sub-commands + +Config supports the following sub-commands: + +#### set +```bash +npm config set key value +``` +Sets the config key to the value. + +If value is omitted, then it sets it to "true". + +#### get +```bash +npm config get key +``` + +Echo the config value to stdout. + +#### list +```bash +npm config list +``` + +Show all the config settings. Use `-l` to also show defaults. Use `--json` +to show the settings in json format. + +#### delete +```bash +npm config delete key +``` + +Deletes the key from all configuration files. + +#### edit +```bash +npm config edit +``` + +Opens the config file in an editor. Use the `--global` flag to edit the +global config. + +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [package.json](/configuring-npm/package-json) +* [npmrc](/configuring-npm/npmrc) +* [npm](/cli-commands/npm) diff --git a/deps/npm/doc/cli/npm-dedupe.md b/deps/npm/docs/content/cli-commands/npm-dedupe.md similarity index 64% rename from deps/npm/doc/cli/npm-dedupe.md rename to deps/npm/docs/content/cli-commands/npm-dedupe.md index d68832145f0a56..e15a12ba7c18a3 100644 --- a/deps/npm/doc/cli/npm-dedupe.md +++ b/deps/npm/docs/content/cli-commands/npm-dedupe.md @@ -1,14 +1,22 @@ -npm-dedupe(1) -- Reduce duplication -=================================== +--- +section: cli-commands +title: npm-dedupe +description: Reduce duplication +--- -## SYNOPSIS +# npm-dedupe(1) - npm dedupe - npm ddp +## Reduce duplication - aliases: find-dupes, ddp +### Synopsis +```bash +npm dedupe +npm ddp -## DESCRIPTION +aliases: find-dupes, ddp +``` + +### Description Searches the local package tree and attempts to simplify the overall structure by moving dependencies further up the tree, where they can @@ -16,18 +24,22 @@ be more effectively shared by multiple dependent packages. For example, consider this dependency graph: - a - +-- b <-- depends on c@1.0.x - | `-- c@1.0.3 - `-- d <-- depends on c@~1.0.9 - `-- c@1.0.10 +```bash +a ++-- b <-- depends on c@1.0.x +| `-- c@1.0.3 +`-- d <-- depends on c@~1.0.9 + `-- c@1.0.10 +``` -In this case, `npm-dedupe(1)` will transform the tree to: +In this case, `npm dedupe` will transform the tree to: - a - +-- b - +-- d - `-- c@1.0.10 +```bash +a ++-- b ++-- d +`-- c@1.0.10 +``` Because of the hierarchical nature of node's module lookup, b and d will both get their dependency met by the single c package at the root @@ -48,8 +60,8 @@ Modules Note that this operation transforms the dependency tree, but will never result in new modules being installed. -## SEE ALSO +### See Also -* npm-ls(1) -* npm-update(1) -* npm-install(1) +* [npm ls](/cli-commands/npm-ls) +* [npm update](/cli-commands/npm-update) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/cli/npm-deprecate.md b/deps/npm/docs/content/cli-commands/npm-deprecate.md similarity index 53% rename from deps/npm/doc/cli/npm-deprecate.md rename to deps/npm/docs/content/cli-commands/npm-deprecate.md index ea1ab3a2aef52d..d2d9613f653c6c 100644 --- a/deps/npm/doc/cli/npm-deprecate.md +++ b/deps/npm/docs/content/cli-commands/npm-deprecate.md @@ -1,28 +1,36 @@ -npm-deprecate(1) -- Deprecate a version of a package -==================================================== +--- +section: cli-commands +title: npm-deprecate +description: Deprecate a version of a package +--- +# npm-deprecate(1) -## SYNOPSIS +## Deprecate a version of a package - npm deprecate [@] +### Synopsis +```bash +npm deprecate [@] +``` -## DESCRIPTION +### Description This command will update the npm registry entry for a package, providing a deprecation warning to all who attempt to install it. -It works on [version ranges](https://semver.npmjs.com/) as well as specific +It works on [version ranges](https://semver.npmjs.com/) as well as specific versions, so you can do something like this: - - npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3" +```bash +npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3" +``` Note that you must be the package owner to deprecate something. See the `owner` and `adduser` help topics. -To un-deprecate a package, specify an empty string (`""`) for the `message` -argument. Note that you must use double quotes with no space between them to +To un-deprecate a package, specify an empty string (`""`) for the `message` +argument. Note that you must use double quotes with no space between them to format an empty string. -## SEE ALSO +### See Also -* npm-publish(1) -* npm-registry(7) +* [npm publish](/cli-commands/npm-publish) +* [npm registry](/using-npm/registry) diff --git a/deps/npm/doc/cli/npm-dist-tag.md b/deps/npm/docs/content/cli-commands/npm-dist-tag.md similarity index 75% rename from deps/npm/doc/cli/npm-dist-tag.md rename to deps/npm/docs/content/cli-commands/npm-dist-tag.md index 7de3c828fb215b..c7921c7f739d72 100644 --- a/deps/npm/doc/cli/npm-dist-tag.md +++ b/deps/npm/docs/content/cli-commands/npm-dist-tag.md @@ -1,15 +1,24 @@ -npm-dist-tag(1) -- Modify package distribution tags -=================================================== + --- +section: cli-commands +title: npm-dist-tag +description: Modify package distribution tags +--- -## SYNOPSIS +# npm-dist-tag(1) - npm dist-tag add @ [] - npm dist-tag rm - npm dist-tag ls [] +## Modify package distribution tags - aliases: dist-tags -## DESCRIPTION +### Synopsis +```bash +npm dist-tag add @ [] +npm dist-tag rm +npm dist-tag ls [] + +aliases: dist-tags +``` + +### Description Add, remove, and enumerate distribution tags on a package: @@ -24,18 +33,20 @@ Add, remove, and enumerate distribution tags on a package: * ls: Show all of the dist-tags for a package, defaulting to the package in - the current prefix. - - This is the default action if none is specified. + the current prefix. This is the default action if none is specified. A tag can be used when installing packages as a reference to a version instead of using a specific version number: - npm install @ +```bash +npm install @ +``` When installing dependencies, a preferred tagged version may be specified: - npm install --tag +```bash +npm install --tag +``` This also applies to `npm dedupe`. @@ -45,7 +56,7 @@ Publishing a package sets the `latest` tag to the published version unless the By default, `npm install ` (without any `@` or `@` specifier) installs the `latest` tag. -## PURPOSE +### Purpose Tags can be used to provide an alias instead of version numbers. @@ -64,7 +75,7 @@ The `next` tag is used by some projects to identify the upcoming version. By default, other than `latest`, no tag has any special significance to npm itself. -## CAVEATS +### Caveats This command used to be known as `npm tag`, which only created new tags, and so had a different syntax. @@ -79,12 +90,11 @@ example, `v1.4` cannot be used as a tag, because it is interpreted by semver as The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter `v`. -## SEE ALSO +### See Also -* npm-publish(1) -* npm-install(1) -* npm-dedupe(1) -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) +* [npm publish](/cli-commands/npm-publish) +* [npm install](/cli-commands/npm-install) +* [npm dedupe](/cli-commands/npm-dedupe) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/docs/content/cli-commands/npm-docs.md b/deps/npm/docs/content/cli-commands/npm-docs.md new file mode 100644 index 00000000000000..46f5cd0d900a47 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-docs.md @@ -0,0 +1,52 @@ +--- +section: cli-commands +title: npm-docs +description: Docs for a package in a web browser maybe +--- + +# npm-docs(1) + +## Docs for a package in a web browser maybe + +### Synopsis + +```bash +npm docs [ [ ...]] +npm docs . +npm home [ [ ...]] +npm home . +``` + +### Description + +This command tries to guess at the likely location of a package's +documentation URL, and then tries to open it using the `--browser` +config param. You can pass multiple package names at once. If no +package name is provided, it will search for a `package.json` in +the current folder and use the `name` property. + +### Configuration + +#### browser + +* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` +* Type: String + +The browser that is called by the `npm docs` command to open websites. + +#### registry + +* Default: https://registry.npmjs.org/ +* Type: url + +The base URL of the npm package registry. + + +### See Also + +* [npm view](/cli-commands/npm-view) +* [npm publish](/cli-commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) diff --git a/deps/npm/doc/cli/npm-doctor.md b/deps/npm/docs/content/cli-commands/npm-doctor.md similarity index 90% rename from deps/npm/doc/cli/npm-doctor.md rename to deps/npm/docs/content/cli-commands/npm-doctor.md index 1a5738505cefee..7cec349e5a8145 100644 --- a/deps/npm/doc/cli/npm-doctor.md +++ b/deps/npm/docs/content/cli-commands/npm-doctor.md @@ -1,11 +1,20 @@ -npm-doctor(1) -- Check your environments -======================================================== +--- +section: cli-commands +title: npm-doctor +description: Check your environments +--- -## SYNOPSIS +# npm-doctor(1) - npm doctor +## Check your environments -## DESCRIPTION +### Synopsis + +```bash +npm doctor +``` + +### Description `npm doctor` runs a set of checks to ensure that your npm installation has what it needs to manage your JavaScript packages. npm is mostly a standalone tool, but it does @@ -29,7 +38,7 @@ better than an old version. `npm doctor` verifies the following items in your environment, and if there are any recommended changes, it will display them. -### `npm ping` +#### `npm ping` By default, npm installs from the primary npm registry, `registry.npmjs.org`. `npm doctor` hits a special ping endpoint within the registry. This can also be @@ -42,7 +51,7 @@ what that is by running `npm config get registry`), and if you're using a private registry that doesn't support the `/whoami` endpoint supported by the primary registry, this check may fail. -### `npm -v` +#### `npm -v` While Node.js may come bundled with a particular version of npm, it's the policy of the CLI team that we recommend all users run `npm@latest` if they @@ -52,7 +61,7 @@ releases typically only receive critical security and regression fixes. The team believes that the latest tested version of npm is almost always likely to be the most functional and defect-free version of npm. -### `node -v` +#### `node -v` For most users, in most circumstances, the best version of Node will be the latest long-term support (LTS) release. Those of you who want access to new @@ -61,7 +70,7 @@ running a newer version, and some of you may be required to run an older version of Node because of enterprise change control policies. That's OK! But in general, the npm team recommends that most users run Node.js LTS. -### `npm config get registry` +#### `npm config get registry` Some of you may be installing from private package registries for your project or company. That's great! Others of you may be following tutorials or @@ -70,7 +79,7 @@ having. Sometimes, this may entail changing the registry you're pointing at. This part of `npm doctor` just lets you, and maybe whoever's helping you with support, know that you're not using the default registry. -### `which git` +#### `which git` While it's documented in the README, it may not be obvious that npm needs Git installed to do many of the things that it does. Also, in some cases @@ -78,14 +87,14 @@ installed to do many of the things that it does. Also, in some cases accessible via your `PATH` so that npm can find it. This check ensures that Git is available. -### Permissions checks +#### Permissions checks * Your cache must be readable and writable by the user running npm. * Global package binaries must be writable by the user running npm. * Your local `node_modules` path, if you're running `npm doctor` with a project directory, must be readable and writable by the user running npm. -### Validate the checksums of cached packages +#### Validate the checksums of cached packages When an npm package is published, the publishing process generates a checksum that npm uses at install time to verify that the package didn't get corrupted @@ -95,8 +104,8 @@ get cache`, and see what's in that cache with `npm cache ls` – probably more than you were expecting!). In the event that there are corrupt packages in your cache, you should probably run `npm cache clean` and reset the cache. -## SEE ALSO +### See Also -* npm-bugs(1) -* npm-help(1) -* npm-ping(1) +* [npm bugs](/cli-commands/npm-bugs) +* [npm help](/cli-commands/npm-help) +* [npm ping](/cli-commands/npm-ping) diff --git a/deps/npm/doc/cli/npm-edit.md b/deps/npm/docs/content/cli-commands/npm-edit.md similarity index 56% rename from deps/npm/doc/cli/npm-edit.md rename to deps/npm/docs/content/cli-commands/npm-edit.md index f9913a015ad3bf..94b6a087fa102f 100644 --- a/deps/npm/doc/cli/npm-edit.md +++ b/deps/npm/docs/content/cli-commands/npm-edit.md @@ -1,16 +1,25 @@ -npm-edit(1) -- Edit an installed package -======================================== +--- +section: cli-commands +title: npm-edit +description: Edit an installed package +--- -## SYNOPSIS +# npm-edit(1) - npm edit [/...] +## Edit an installed package -## DESCRIPTION +### Synopsis + +```bash +npm edit [/...] +``` + +### Description Selects a (sub)dependency in the current working directory and opens the package folder in the default editor (or whatever you've configured as the npm `editor` config -- see -`npm-config(7)`.) +[`npm-config`](npm-config).) After it has been edited, the package is rebuilt so as to pick up any changes in compiled packages. @@ -19,9 +28,9 @@ For instance, you can do `npm install connect` to install connect into your package, and then `npm edit connect` to make a few changes to your locally installed copy. -## CONFIGURATION +### Configuration -### editor +#### editor * Default: `EDITOR` environment variable if set, or `"vi"` on Posix, or `"notepad"` on Windows. @@ -29,11 +38,10 @@ changes to your locally installed copy. The command to run for `npm edit` or `npm config edit`. -## SEE ALSO +### See Also -* npm-folders(5) -* npm-explore(1) -* npm-install(1) -* npm-config(1) -* npm-config(7) -* npmrc(5) +* [npm folders](/configuring-npm/folders) +* [npm explore](/cli-commands/npm-explore) +* [npm install](/cli-commands/npm-install) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/cli/npm-explore.md b/deps/npm/docs/content/cli-commands/npm-explore.md similarity index 50% rename from deps/npm/doc/cli/npm-explore.md rename to deps/npm/docs/content/cli-commands/npm-explore.md index 44b77f94340d60..8ded96d40984fe 100644 --- a/deps/npm/doc/cli/npm-explore.md +++ b/deps/npm/docs/content/cli-commands/npm-explore.md @@ -1,11 +1,20 @@ -npm-explore(1) -- Browse an installed package -============================================= + --- +section: cli-commands +title: npm-explore +description: Browse an installed package +--- -## SYNOPSIS +# npm-explore(1) - npm explore [ -- ] +## Browse an installed package -## DESCRIPTION +### Synopsis + +```bash +npm explore [ -- ] +``` + +### Description Spawn a subshell in the directory of the installed package specified. @@ -15,14 +24,16 @@ immediately terminates. This is particularly handy in the case of git submodules in the `node_modules` folder: - npm explore some-dependency -- git pull origin master +```bash +npm explore some-dependency -- git pull origin master +``` Note that the package is *not* automatically rebuilt afterwards, so be sure to use `npm rebuild ` if you make any changes. -## CONFIGURATION +### Configuration -### shell +#### shell * Default: SHELL environment variable, or "bash" on Posix, or "cmd" on Windows @@ -30,10 +41,10 @@ sure to use `npm rebuild ` if you make any changes. The shell to run for the `npm explore` command. -## SEE ALSO +### See Also -* npm-folders(5) -* npm-edit(1) -* npm-rebuild(1) -* npm-build(1) -* npm-install(1) +* [npm folders](/configuring-npm/folders) +* [npm edit](/cli-commands/npm-edit) +* [npm rebuild](/cli-commands/npm-rebuild) +* [npm build](/cli-commands/npm-build) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/docs/content/cli-commands/npm-fund.md b/deps/npm/docs/content/cli-commands/npm-fund.md new file mode 100644 index 00000000000000..64894e291fc4f6 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-fund.md @@ -0,0 +1,60 @@ +--- +section: cli-commands +title: npm-fund +description: Retrieve funding information +--- + +# npm-fund(1) + +## Retrieve funding information + +### Synopsis + +```bash + npm fund [] +``` + +### Description + +This command retrieves information on how to fund the dependencies of +a given project. If no package name is provided, it will list all +dependencies that are looking for funding in a tree-structure in which +are listed the type of funding and the url to visit. If a package name +is provided then it tries to open its funding url using the `--browser` +config param. + +The list will avoid duplicated entries and will stack all packages +that share the same type/url as a single entry. Given this nature the +list is not going to have the same shape of the output from `npm ls`. + +### Configuration + +#### browser + +* Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` +* Type: String + +The browser that is called by the `npm fund` command to open websites. + +#### json + +* Default: false +* Type: Boolean + +Show information in JSON format. + +#### unicode + +* Type: Boolean +* Default: true + +Whether to represent the tree structure using unicode characters. +Set it to `false` in order to use all-ansi output. + +## See Also + +* [npm docs](/cli-commands/npm-docs) +* [npm config](/cli-commands/npm-config) +* [npm install](/cli-commands/npm-install) +* [npm ls](/cli-commands/npm-ls) + diff --git a/deps/npm/doc/cli/npm-help-search.md b/deps/npm/docs/content/cli-commands/npm-help-search.md similarity index 64% rename from deps/npm/doc/cli/npm-help-search.md rename to deps/npm/docs/content/cli-commands/npm-help-search.md index 74e1011ab00679..69d005cb160ed7 100644 --- a/deps/npm/doc/cli/npm-help-search.md +++ b/deps/npm/docs/content/cli-commands/npm-help-search.md @@ -1,11 +1,20 @@ -npm-help-search(1) -- Search npm help documentation -=================================================== +--- +section: cli-commands +title: npm-help-search +description: Search npm help documentation +--- -## SYNOPSIS +# npm-help-search(1) - npm help-search +## Search npm help documentation -## DESCRIPTION +### Synopsis + +```bash +npm help-search +``` + +### Description This command will search the npm markdown documentation files for the terms provided, and then list the results, sorted by relevance. @@ -16,9 +25,9 @@ If the argument to `npm help` is not a known help topic, then it will call `help-search`. It is rarely if ever necessary to call this command directly. -## CONFIGURATION +### Configuration -### long +#### long * Type: Boolean * Default: false @@ -28,7 +37,7 @@ where the terms were found in the documentation. If false, then help-search will just list out the help topics found. -## SEE ALSO +### See Also -* npm(1) -* npm-help(1) +* [npm](/cli-commands/npm) +* [npm help](/cli-commands/npm-help) diff --git a/deps/npm/doc/cli/npm-help.md b/deps/npm/docs/content/cli-commands/npm-help.md similarity index 52% rename from deps/npm/doc/cli/npm-help.md rename to deps/npm/docs/content/cli-commands/npm-help.md index 5230082b923fa9..c47676ffcac1d3 100644 --- a/deps/npm/doc/cli/npm-help.md +++ b/deps/npm/docs/content/cli-commands/npm-help.md @@ -1,11 +1,20 @@ -npm-help(1) -- Get help on npm -============================== +--- +section: cli-commands +title: npm-help +description: Get help on npm +--- -## SYNOPSIS +# npm-help(1) - npm help [] +## Get help on npm -## DESCRIPTION +### Synopsis + +```bash +npm help [] +``` + +### Description If supplied a topic, then show the appropriate documentation page. @@ -14,9 +23,9 @@ the `help-search` command to find a match. Note that, if `help-search` finds a single subject, then it will run `help` on that topic, so unique matches are equivalent to specifying a topic name. -## CONFIGURATION +### Configuration -### viewer +#### viewer * Default: "man" on Posix, "browser" on Windows * Type: path @@ -25,14 +34,11 @@ The program to use to view help content. Set to `"browser"` to view html help content in the default web browser. -## SEE ALSO - -* npm(1) -* README -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* package.json(5) -* npm-help-search(1) -* npm-index(7) +### See Also + +* [npm](/cli-commands/npm) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [package.json](/configuring-npm/package-json) +* [npm help-search](/cli-commands/npm-help-search) diff --git a/deps/npm/doc/cli/npm-hook.md b/deps/npm/docs/content/cli-commands/npm-hook.md similarity index 75% rename from deps/npm/doc/cli/npm-hook.md rename to deps/npm/docs/content/cli-commands/npm-hook.md index 519287242574a0..ce4bbccb3593b3 100644 --- a/deps/npm/doc/cli/npm-hook.md +++ b/deps/npm/docs/content/cli-commands/npm-hook.md @@ -1,54 +1,62 @@ -npm-hook(1) -- Manage registry hooks -=================================== +--- +section: cli-commands +title: npm-hook +description: Manage registry hooks +--- -## SYNOPSIS +# npm-hook(1) - npm hook ls [pkg] - npm hook add - npm hook update [secret] - npm hook rm +## Manage registry hooks -## EXAMPLE +### Synopsis -Add a hook to watch a package for changes: +```bash +npm hook ls [pkg] +npm hook add +npm hook update [secret] +npm hook rm ``` + +### Example + +Add a hook to watch a package for changes: +```bash $ npm hook add lodash https://example.com/ my-shared-secret ``` Add a hook to watch packages belonging to the user `substack`: -``` +```bash $ npm hook add ~substack https://example.com/ my-shared-secret ``` Add a hook to watch packages in the scope `@npm` -``` +```bash $ npm hook add @npm https://example.com/ my-shared-secret ``` List all your active hooks: -``` +```bash $ npm hook ls ``` List your active hooks for the `lodash` package: -``` +```bash $ npm hook ls lodash ``` Update an existing hook's url: -``` +```bash $ npm hook update id-deadbeef https://my-new-website.here/ ``` Remove a hook: -``` +```bash $ npm hook rm id-deadbeef ``` -## DESCRIPTION +### Description -Allows you to manage [npm -hooks](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm), +Allows you to manage [npm hooks](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm), including adding, removing, listing, and updating. Hooks allow you to configure URL endpoints that will be notified whenever a @@ -67,6 +75,6 @@ that particular hook. The shared secret will be sent along to the URL endpoint so you can verify the request came from your own configured hook. -## SEE ALSO +### See Also * ["Introducing Hooks" blog post](https://blog.npmjs.org/post/145260155635/introducing-hooks-get-notifications-of-npm) diff --git a/deps/npm/doc/cli/npm-init.md b/deps/npm/docs/content/cli-commands/npm-init.md similarity index 73% rename from deps/npm/doc/cli/npm-init.md rename to deps/npm/docs/content/cli-commands/npm-init.md index b91bcafae83774..73ad74b23ea998 100644 --- a/deps/npm/doc/cli/npm-init.md +++ b/deps/npm/docs/content/cli-commands/npm-init.md @@ -1,43 +1,51 @@ -npm-init(1) -- create a package.json file -======================================================= +--- +section: cli-commands +title: npm-init +description: create a package.json file +--- -## SYNOPSIS +# npm-init(1) - npm init [--force|-f|--yes|-y|--scope] - npm init <@scope> (same as `npx <@scope>/create`) - npm init [<@scope>/] (same as `npx [<@scope>/]create-`) +## create a package.json file -## EXAMPLES +### Synopsis +```bash +npm init [--force|-f|--yes|-y|--scope] +npm init <@scope> (same as `npx <@scope>/create`) +npm init [<@scope>/] (same as `npx [<@scope>/]create-`) +``` + +### Examples Create a new React-based project using [`create-react-app`](https://npm.im/create-react-app): -``` +```bash $ npm init react-app ./my-react-app ``` Create a new `esm`-compatible package using [`create-esm`](https://npm.im/create-esm): -``` +```bash $ mkdir my-esm-lib && cd my-esm-lib $ npm init esm --yes ``` Generate a plain old package.json using legacy init: -``` +```bash $ mkdir my-npm-pkg && cd my-npm-pkg $ git init $ npm init ``` Generate it without having it ask any questions: -``` +```bash $ npm init -y ``` -## DESCRIPTION +### Description `npm init ` can be used to set up a new or existing npm package. `initializer` in this case is an npm package named `create-`, which -will be installed by [`npx(1)`](https://npm.im/npx), and then have its main bin +will be installed by [`npx`](https://npm.im/npx), and then have its main bin executed -- presumably creating or updating `package.json` and running any other initialization-related operations. @@ -58,9 +66,9 @@ it will keep any fields and values that were already set. You can also use `-y`/`--yes` to skip the questionnaire altogether. If you pass `--scope`, it will create a scoped package. -## SEE ALSO +### See Also * -* package.json(5) -* npm-version(1) -* npm-scope(7) +* [package.json](/configuring-npm/package-json) +* [npm version](/cli-commands/npm-version) +* [npm scope](/using-npm/scope) diff --git a/deps/npm/docs/content/cli-commands/npm-install-ci-test.md b/deps/npm/docs/content/cli-commands/npm-install-ci-test.md new file mode 100644 index 00000000000000..98e40f4b27a77d --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-install-ci-test.md @@ -0,0 +1,26 @@ +--- +section: cli-commands +title: npm-install-ci-test +description: Install a project with a clean slate and run tests +--- + +# npm install-ci-test(1) + +## Install a project with a clean slate and run tests + +### Synopsis + +```bash +npm install-ci-test + +alias: npm cit +``` + +### Description + +This command runs an `npm ci` followed immediately by an `npm test`. + +### See Also + +* [npm ci](/cli-commands/npm-ci) +* [npm test](/cli-commands/npm-test) diff --git a/deps/npm/docs/content/cli-commands/npm-install-test.md b/deps/npm/docs/content/cli-commands/npm-install-test.md new file mode 100644 index 00000000000000..b86a5199117c4a --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-install-test.md @@ -0,0 +1,35 @@ +--- +section: cli-commands +title: npm-install-test +description: Install package(s) and run tests +--- + +# npm install-test(1) + +## Install package(s) and run tests + +### Synopsis + +```bash +npm install-test (with no args, in package dir) +npm install-test [<@scope>/] +npm install-test [<@scope>/]@ +npm install-test [<@scope>/]@ +npm install-test [<@scope>/]@ +npm install-test +npm install-test +npm install-test + +alias: npm it +common options: [--save|--save-dev|--save-optional] [--save-exact] [--dry-run] +``` + +### Description + +This command runs an `npm install` followed immediately by an `npm test`. It +takes exactly the same arguments as `npm install`. + +### See Also + +* [npm install](/cli-commands/npm-install) +* [npm test](/cli-commands/npm-test) diff --git a/deps/npm/doc/cli/npm-install.md b/deps/npm/docs/content/cli-commands/npm-install.md similarity index 71% rename from deps/npm/doc/cli/npm-install.md rename to deps/npm/docs/content/cli-commands/npm-install.md index 4ff4a47cbcf4ee..8e661bf643f394 100644 --- a/deps/npm/doc/cli/npm-install.md +++ b/deps/npm/docs/content/cli-commands/npm-install.md @@ -1,36 +1,46 @@ -npm-install(1) -- Install a package -=================================== +--- +section: cli-commands +title: npm-install +description: Install a package +--- -## SYNOPSIS +# npm-install(1) - npm install (with no args, in package dir) - npm install [<@scope>/] - npm install [<@scope>/]@ - npm install [<@scope>/]@ - npm install [<@scope>/]@ - npm install :/ - npm install - npm install - npm install - npm install +## Install a package - aliases: npm i, npm add - common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [-B|--save-bundle] [--no-save] [--dry-run] +### Synopsis -## DESCRIPTION +```bash +npm install (with no args, in package dir) +npm install [<@scope>/] +npm install [<@scope>/]@ +npm install [<@scope>/]@ +npm install [<@scope>/]@ +npm install @npm: +npm install :/ +npm install +npm install +npm install +npm install + +aliases: npm i, npm add +common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [-B|--save-bundle] [--no-save] [--dry-run] +``` + +### Description This command installs a package, and any packages that it depends on. If the package has a package-lock or shrinkwrap file, the installation of dependencies will be driven by that, with an `npm-shrinkwrap.json` taking precedence if both -files exist. See package-lock.json(5) and npm-shrinkwrap(1). +files exist. See [package-lock.json](/configuring-npm/package-lock-json) and [`npm shrinkwrap`](/cli-commands/npm-shrinkwrap). A `package` is: -* a) a folder containing a program described by a `package.json(5)` file +* a) a folder containing a program described by a [`package.json`](/configuring-npm/package-json) file * b) a gzipped tarball containing (a) * c) a url that resolves to (b) -* d) a `@` that is published on the registry (see `npm-registry(7)`) with (c) -* e) a `@` (see `npm-dist-tag(1)`) that points to (d) +* d) a `@` that is published on the registry (see [`registry`](/using-npm/registry)) with (c) +* e) a `@` (see [`npm dist-tag`](/cli-commands/npm-dist-tag)) that points to (d) * f) a `` that has a "latest" tag satisfying (e) * g) a `` that resolves to (a) @@ -49,11 +59,13 @@ after packing it up into a tarball (b). directory) as a global package. By default, `npm install` will install all modules listed as dependencies - in `package.json(5)`. + in [`package.json`](/configuring-npm/package-json). With the `--production` flag (or when the `NODE_ENV` environment variable is set to `production`), npm will not install modules listed in - `devDependencies`. + `devDependencies`. To install all modules listed in both `dependencies` + and `devDependencies` when `NODE_ENV` environment variable is set to `production`, + you can use `--production=false`. > NOTE: The `--production` flag has no particular meaning when adding a dependency to a project. @@ -93,7 +105,7 @@ after packing it up into a tarball (b). * `npm install [<@scope>/]`: Do a `@` install, where `` is the "tag" config. (See - `npm-config(7)`. The config's default value is `latest`.) + [`config`](/using-npm/config). The config's default value is `latest`.) In most cases, this will install the version of the modules tagged as `latest` on the npm registry. @@ -102,6 +114,24 @@ after packing it up into a tarball (b). npm install sax +* `npm install @npm:`: + + Install a package under a custom alias. Allows multiple versions of + a same-name package side-by-side, more convenient import names for + packages with otherwise long ones and using git forks replacements + or forked npm packages as replacements. Aliasing works only on your + project and does not rename packages in transitive dependencies. + Aliases should follow the naming conventions stated in + [`validate-npm-package-name`](https://www.npmjs.com/package/validate-npm-package-name#naming-rules). + + Examples: + + npm install my-react@npm:react + npm install jquery2@npm:jquery@2 + npm install jquery3@npm:jquery@3 + npm install npa@npm:npm-package-arg + + `npm install` saves any specified packages into `dependencies` by default. Additionally, you can control where and how they get saved with some additional flags: @@ -129,7 +159,7 @@ after packing it up into a tarball (b). `` is optional. The package will be downloaded from the registry associated with the specified scope. If no registry is associated with - the given scope the default registry is assumed. See `npm-scope(7)`. + the given scope the default registry is assumed. See [`scope`](/using-npm/scope). Note: if you do not include the @-symbol on your scope name, npm will interpret this as a GitHub repository instead, see below. Scopes names @@ -137,14 +167,15 @@ after packing it up into a tarball (b). Examples: - npm install sax - npm install githubname/reponame - npm install @myorg/privatepackage - npm install node-tap --save-dev - npm install dtrace-provider --save-optional - npm install readable-stream --save-exact - npm install ansi-regex --save-bundle - + ```bash + npm install sax + npm install githubname/reponame + npm install @myorg/privatepackage + npm install node-tap --save-dev + npm install dtrace-provider --save-optional + npm install readable-stream --save-exact + npm install ansi-regex --save-bundle + ``` **Note**: If there is a file or folder named `` in the current working directory, then it will try to install that, and only try to @@ -158,8 +189,10 @@ after packing it up into a tarball (b). Example: - npm install sax@latest - npm install @myorg/mypackage@latest + ```bash + npm install sax@latest + npm install @myorg/mypackage@latest + ``` * `npm install [<@scope>/]@`: @@ -168,28 +201,33 @@ after packing it up into a tarball (b). Example: - npm install sax@0.1.1 - npm install @myorg/privatepackage@1.5.0 + ```bash + npm install sax@0.1.1 + npm install @myorg/privatepackage@1.5.0 + ``` * `npm install [<@scope>/]@`: Install a version of the package matching the specified version range. This - will follow the same rules for resolving dependencies described in `package.json(5)`. + will follow the same rules for resolving dependencies described in [`package.json`](/configuring-npm/package-json). Note that most version ranges must be put in quotes so that your shell will treat it as a single argument. Example: - - npm install sax@">=0.1.0 <0.2.0" - npm install @myorg/privatepackage@">=0.1.0 <0.2.0" + ```bash + npm install sax@">=0.1.0 <0.2.0" + npm install @myorg/privatepackage@">=0.1.0 <0.2.0" + ``` * `npm install `: Installs the package from the hosted git provider, cloning it with `git`. For a full git remote url, only that URL will be attempted. - ://[[:]@][:][:][/][# | #semver:] + ```bash + ://[[:]@][:][:][/][# | #semver:] + ``` `` is one of `git`, `git+ssh`, `git+http`, `git+https`, or `git+file`. @@ -223,11 +261,13 @@ after packing it up into a tarball (b). Examples: - npm install git+ssh://git@github.com:npm/cli.git#v1.0.27 - npm install git+ssh://git@github.com:npm/cli#semver:^5.0 - npm install git+https://isaacs@github.com/npm/cli.git - npm install git://github.com/npm/cli.git#v1.0.27 - GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git + ```bash + npm install git+ssh://git@github.com:npm/cli.git#v1.0.27 + npm install git+ssh://git@github.com:npm/cli#semver:^5.0 + npm install git+https://isaacs@github.com/npm/cli.git + npm install git://github.com/npm/cli.git#v1.0.27 + GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git + ``` * `npm install /[#]`: * `npm install github:/[#]`: @@ -247,9 +287,11 @@ after packing it up into a tarball (b). done installing. Examples: - - npm install mygithubuser/myproject - npm install github:mygithubuser/myproject + + ```bash + npm install mygithubuser/myproject + npm install github:mygithubuser/myproject + ``` * `npm install gist:[/][#|#semver:]`: @@ -262,8 +304,10 @@ after packing it up into a tarball (b). done installing. Example: - - npm install gist:101a11beef + + ```bash + npm install gist:101a11beef + ``` * `npm install bitbucket:/[#]`: @@ -282,8 +326,10 @@ after packing it up into a tarball (b). done installing. Example: - - npm install bitbucket:mybitbucketuser/myproject + + ```bash + npm install bitbucket:mybitbucketuser/myproject + ``` * `npm install gitlab:/[#]`: @@ -302,14 +348,18 @@ after packing it up into a tarball (b). done installing. Example: - - npm install gitlab:mygitlabuser/myproject - npm install gitlab:myusr/myproj#semver:^5.0 + + ```bash + npm install gitlab:mygitlabuser/myproject + npm install gitlab:myusr/myproj#semver:^5.0 + ``` You may combine multiple arguments, and even multiple types of arguments. For example: - npm install sax@">=0.1.0 <0.2.0" bench supervisor +```bash +npm install sax@">=0.1.0 <0.2.0" bench supervisor +``` The `--tag` argument will apply to all of the specified install targets. If a tag with the given name exists, the tagged version is preferred over newer @@ -324,10 +374,16 @@ instead of checking `node_modules` and downloading dependencies. The `-f` or `--force` argument will force npm to fetch remote resources even if a local copy exists on disk. - npm install sax --force +```bash +npm install sax --force +``` + +The `--no-fund` argument will hide the message displayed at the end of each +install that acknowledges the number of dependencies looking for funding. +See `npm-fund(1)` The `-g` or `--global` argument will cause npm to install the package globally -rather than locally. See `npm-folders(5)`. +rather than locally. See [folders](/configuring-npm/folders). The `--global-style` argument will cause npm to install the package into your local `node_modules` folder with the same layout it uses with the @@ -336,7 +392,7 @@ global `node_modules` folder. Only your direct dependencies will show in `node_modules` folders. This obviously will eliminate some deduping. The `--ignore-scripts` argument will cause npm to not execute any -scripts defined in the package.json. See `npm-scripts(7)`. +scripts defined in the package.json. See [`scripts`](/using-npm/scripts). The `--legacy-bundling` argument will cause npm to install the package such that versions of npm prior to 1.4, such as the one included with node 0.8, @@ -365,33 +421,36 @@ The `--only={prod[uction]|dev[elopment]}` argument will cause either only `devDependencies` or only non-`devDependencies` to be installed regardless of the `NODE_ENV`. The `--no-audit` argument can be used to disable sending of audit reports to -the configured registries. See `npm-audit(1)` for details on what is sent. +the configured registries. See [`npm-audit`](npm-audit) for details on what is sent. -See `npm-config(7)`. Many of the configuration params have some +See [`config`](/using-npm/config). Many of the configuration params have some effect on installation, since that's most of what npm does. -## ALGORITHM +#### Algorithm To install a package, npm uses the following algorithm: - - load the existing node_modules tree from disk - clone the tree - fetch the package.json and assorted metadata and add it to the clone - walk the clone and add any missing dependencies - dependencies will be added as close to the top as is possible - without breaking any other modules - compare the original tree with the cloned tree and make a list of - actions to take to convert one to the other - execute all of the actions, deepest first - kinds of actions are install, update, remove and move +```bash +load the existing node_modules tree from disk +clone the tree +fetch the package.json and assorted metadata and add it to the clone +walk the clone and add any missing dependencies + dependencies will be added as close to the top as is possible + without breaking any other modules +compare the original tree with the cloned tree and make a list of +actions to take to convert one to the other +execute all of the actions, deepest first + kinds of actions are install, update, remove and move +``` For this `package{dep}` structure: `A{B,C}, B{C}, C{D}`, this algorithm produces: - A - +-- B - +-- C - +-- D +```bash +A ++-- B ++-- C ++-- D +``` That is, the dependency from B to C is satisfied by the fact that A already caused C to be installed at a higher level. D is still installed @@ -399,19 +458,20 @@ at the top level because nothing conflicts with it. For `A{B,C}, B{C,D@1}, C{D@2}`, this algorithm produces: - A - +-- B - +-- C - `-- D@2 - +-- D@1 +```bash +A ++-- B ++-- C + `-- D@2 ++-- D@1 +``` Because B's D@1 will be installed in the top level, C now has to install D@2 privately for itself. This algorithm is deterministic, but different trees may be produced if two dependencies are requested for installation in a different order. -See npm-folders(5) for a more detailed description of the specific -folder structures that npm creates. +See [folders](/configuring-npm/folders) for a more detailed description of the specific folder structures that npm creates. ### Limitations of npm's Install Algorithm @@ -423,7 +483,9 @@ There are some very rare and pathological edge-cases where a cycle can cause npm to try to install a never-ending tree of packages. Here is the simplest case: - A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ... +```bash +A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ... +``` where `A` is some version of a package, and `A'` is a different version of the same package. Because `B` depends on a different version of `A` @@ -438,20 +500,20 @@ folder ancestors. A more correct, but more complex, solution would be to symlink the existing version into the new location. If this ever affects a real use-case, it will be investigated. -## SEE ALSO - -* npm-folders(5) -* npm-update(1) -* npm-audit(1) -* npm-link(1) -* npm-rebuild(1) -* npm-scripts(7) -* npm-build(1) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-registry(7) -* npm-dist-tag(1) -* npm-uninstall(1) -* npm-shrinkwrap(1) -* package.json(5) +### See Also + +* [npm folders](/configuring-npm/folders) +* [npm update](/cli-commands/npm-update) +* [npm audit](/cli-commands/npm-audit) +* [npm fund](/cli-commands/npm-fund) +* [npm link](/cli-commands/npm-link) +* [npm rebuild](/cli-commands/npm-rebuild) +* [npm scripts](/using-npm/scripts) +* [npm build](/cli-commands/npm-build) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm registry](/using-npm/registry) +* [npm dist-tag](/cli-commands/npm-dist-tag) +* [npm uninstall](/cli-commands/npm-uninstall) +* [npm shrinkwrap](/cli-commands/npm-shrinkwrap) +* [package.json](/configuring-npm/package-json) diff --git a/deps/npm/doc/cli/npm-link.md b/deps/npm/docs/content/cli-commands/npm-link.md similarity index 61% rename from deps/npm/doc/cli/npm-link.md rename to deps/npm/docs/content/cli-commands/npm-link.md index 3f6dc6e5bde7ec..5c417dd143778d 100644 --- a/deps/npm/doc/cli/npm-link.md +++ b/deps/npm/docs/content/cli-commands/npm-link.md @@ -1,20 +1,29 @@ -npm-link(1) -- Symlink a package folder -======================================= +--- +section: cli-commands +title: npm-link +description: Symlink a package folder +--- -## SYNOPSIS +# npm-link(1) - npm link (in package dir) - npm link [<@scope>/][@] +## Symlink a package folder - alias: npm ln +### Synopsis -## DESCRIPTION +```bash +npm link (in package dir) +npm link [<@scope>/][@] + +alias: npm ln +``` + +### Description Package linking is a two-step process. First, `npm link` in a package folder will create a symlink in the global folder `{prefix}/lib/node_modules/` that links to the package where the `npm -link` command was executed. (see `npm-config(7)` for the value of `prefix`). It +link` command was executed. (see [`npm-config`](npm-config) for the value of `prefix`). It will also link any bins in the package to `{prefix}/bin/{name}`. Next, in some other location, `npm link package-name` will create a @@ -24,7 +33,7 @@ of the current folder. Note that `package-name` is taken from `package.json`, not from directory name. -The package name can be optionally prefixed with a scope. See `npm-scope(7)`. +The package name can be optionally prefixed with a scope. See [`scope`](/using-npm/npm-scope). The scope must be preceded by an @-symbol and followed by a slash. When creating tarballs for `npm publish`, the linked packages are @@ -35,10 +44,12 @@ test it iteratively without having to continually rebuild. For example: +```bash cd ~/projects/node-redis # go into the package directory npm link # creates global link cd ~/projects/node-bloggy # go into some other package directory. npm link redis # link-install the package +``` Now, any changes to ~/projects/node-redis will be reflected in ~/projects/node-bloggy/node_modules/node-redis/. Note that the link should @@ -47,13 +58,17 @@ be to the package name, not the directory name for that package. You may also shortcut the two steps in one. For example, to do the above use-case in a shorter way: - cd ~/projects/node-bloggy # go into the dir of your main project - npm link ../node-redis # link the dir of your dependency +```bash +cd ~/projects/node-bloggy # go into the dir of your main project +npm link ../node-redis # link the dir of your dependency +``` The second line is the equivalent of doing: - (cd ../node-redis; npm link) - npm link redis +```bash +(cd ../node-redis; npm link) +npm link redis +``` That is, it first creates a global link, and then links the global installation target into your project's `node_modules` folder. @@ -61,17 +76,17 @@ installation target into your project's `node_modules` folder. Note that in this case, you are referring to the directory name, `node-redis`, rather than the package name `redis`. -If your linked package is scoped (see `npm-scope(7)`) your link command must -include that scope, e.g. +If your linked package is scoped (see [`scope`](/using-npm/npm-scope)) your link command must include that scope, e.g. - npm link @myorg/privatepackage +```bash +npm link @myorg/privatepackage +``` -## SEE ALSO +### See Also -* npm-developers(7) -* package.json(5) -* npm-install(1) -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* npmrc(5) +* [npm developers](/using-npm/developers) +* [package.json](/configuring-npm/package-json) +* [npm- nstall](/cli-commands/npm-install) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/cli/npm-logout.md b/deps/npm/docs/content/cli-commands/npm-logout.md similarity index 61% rename from deps/npm/doc/cli/npm-logout.md rename to deps/npm/docs/content/cli-commands/npm-logout.md index fe6e7b990a2893..ca7d86f2d1960e 100644 --- a/deps/npm/doc/cli/npm-logout.md +++ b/deps/npm/docs/content/cli-commands/npm-logout.md @@ -1,11 +1,20 @@ -npm-logout(1) -- Log out of the registry -======================================== +--- +section: cli-commands +title: npm-logout +description: Log out of the registry +--- -## SYNOPSIS +# npm-logout(1) - npm logout [--registry=] [--scope=<@scope>] +## Log out of the registry -## DESCRIPTION +### Synopsis + +```bash +npm logout [--registry=] [--scope=<@scope>] +``` + +### Description When logged into a registry that supports token-based authentication, tell the server to end this token's session. This will invalidate the token everywhere @@ -18,28 +27,28 @@ the current environment. If `--scope` is provided, this will find the credentials for the registry connected to that scope, if set. -## CONFIGURATION +### Configuration -### registry +#### registry Default: https://registry.npmjs.org/ The base URL of the npm package registry. If `scope` is also specified, it takes precedence. -### scope +#### scope Default: The scope of your current project, if any, otherwise none. -If specified, you will be logged out of the specified scope. See `npm-scope(7)`. +If specified, you will be logged out of the specified scope. See [`scope`](/using-npm/npm-scope). - npm logout --scope=@myco +```bash +npm logout --scope=@myco +``` -## SEE ALSO +### See Also -* npm-adduser(1) -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-whoami(1) +* [npm adduser](/cli-commands/npm-adduser) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npm whoami](/cli-commands/npm-whoami) diff --git a/deps/npm/doc/cli/npm-ls.md b/deps/npm/docs/content/cli-commands/npm-ls.md similarity index 66% rename from deps/npm/doc/cli/npm-ls.md rename to deps/npm/docs/content/cli-commands/npm-ls.md index 7b10a19d69b2c9..64a399155ff601 100644 --- a/deps/npm/doc/cli/npm-ls.md +++ b/deps/npm/docs/content/cli-commands/npm-ls.md @@ -1,13 +1,22 @@ -npm-ls(1) -- List installed packages -====================================== +--- +section: cli-commands +title: npm-ls +description: List installed packages +--- -## SYNOPSIS +# npm-ls(1) - npm ls [[<@scope>/] ...] +## List installed packages - aliases: list, la, ll +### Synopsis -## DESCRIPTION +```bash +npm ls [[<@scope>/] ...] + +aliases: list, la, ll +``` + +### Description This command will print to stdout all the versions of packages that are installed, as well as their dependencies, in a tree-structure. @@ -17,9 +26,11 @@ limit the results to only the paths to the packages named. Note that nested packages will *also* show the paths to the specified packages. For example, running `npm ls promzard` in npm's source tree will show: +```bash npm@@VERSION@ /path/to/npm └─┬ init-package-json@0.0.4 └── promzard@0.1.5 +``` It will print out extraneous, missing, and invalid packages. @@ -32,30 +43,30 @@ dependencies, not the physical layout of your node_modules folder. When run as `ll` or `la`, it shows extended information by default. -## CONFIGURATION +### Configuration -### json +#### json * Default: false * Type: Boolean Show information in JSON format. -### long +#### long * Default: false * Type: Boolean Show extended information. -### parseable +#### parseable * Default: false * Type: Boolean Show parseable output instead of tree view. -### global +#### global * Default: false * Type: Boolean @@ -63,27 +74,27 @@ Show parseable output instead of tree view. List packages in the global install prefix instead of in the current project. -### depth +#### depth * Type: Int Max display depth of the dependency tree. -### prod / production +#### prod / production * Type: Boolean * Default: false Display only the dependency tree for packages in `dependencies`. -### dev / development +#### dev / development * Type: Boolean * Default: false Display only the dependency tree for packages in `devDependencies`. -### only +#### only * Type: String @@ -91,21 +102,28 @@ When "dev" or "development", is an alias to `dev`. When "prod" or "production", is an alias to `production`. -### link +#### link * Type: Boolean * Default: false Display only dependencies which are linked -## SEE ALSO - -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-folders(5) -* npm-install(1) -* npm-link(1) -* npm-prune(1) -* npm-outdated(1) -* npm-update(1) +#### unicode + +* Type: Boolean +* Default: true + +Whether to represent the tree structure using unicode characters. +Set it to false in order to use all-ansi output. + +### See Also + +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm folders](/configuring-npm/folders) +* [npm install](/cli-commands/npm-install) +* [npm link](/cli-commands/npm-link) +* [npm prune](/cli-commands/npm-prune) +* [npm outdated](/cli-commands/npm-outdated) +* [npm update](/cli-commands/npm-update) diff --git a/deps/npm/doc/cli/npm-org.md b/deps/npm/docs/content/cli-commands/npm-org.md similarity index 66% rename from deps/npm/doc/cli/npm-org.md rename to deps/npm/docs/content/cli-commands/npm-org.md index 802df4df57da74..33db38d0f82a5f 100644 --- a/deps/npm/doc/cli/npm-org.md +++ b/deps/npm/docs/content/cli-commands/npm-org.md @@ -1,50 +1,65 @@ -npm-org(1) -- Manage orgs -=================================== +--- +section: cli-commands +title: npm-org +description: Manage orgs +--- -## SYNOPSIS +# npm-org(1) - npm org set [developer | admin | owner] - npm org rm - npm org ls [] +## Manage orgs -## EXAMPLE +### Synopsis -Add a new developer to an org: +```bash +npm org set [developer | admin | owner] +npm org rm +npm org ls [] ``` + +### Example + +Add a new developer to an org: + +```bash $ npm org set my-org @mx-smith ``` Add a new admin to an org (or change a developer to an admin): -``` + +```bash $ npm org set my-org @mx-santos admin ``` Remove a user from an org: -``` + +```bash $ npm org rm my-org mx-santos ``` List all users in an org: -``` + +```bash $ npm org ls my-org ``` List all users in JSON format: -``` + +```bash $ npm org ls my-org --json ``` See what role a user has in an org: -``` + +```bash $ npm org ls my-org @mx-santos ``` -## DESCRIPTION +### Description You can use the `npm org` commands to manage and view users of an organization. It supports adding and removing users, changing their roles, listing them, and finding specific ones and their roles. -## SEE ALSO +### See Also * [Documentation on npm Orgs](https://docs.npmjs.com/orgs/) diff --git a/deps/npm/doc/cli/npm-outdated.md b/deps/npm/docs/content/cli-commands/npm-outdated.md similarity index 85% rename from deps/npm/doc/cli/npm-outdated.md rename to deps/npm/docs/content/cli-commands/npm-outdated.md index 045586a40a7288..c7934109dca370 100644 --- a/deps/npm/doc/cli/npm-outdated.md +++ b/deps/npm/docs/content/cli-commands/npm-outdated.md @@ -1,11 +1,20 @@ -npm-outdated(1) -- Check for outdated packages -============================================== +--- +section: cli-commands +title: npm-outdated +description: Check for outdated packages +--- -## SYNOPSIS +# npm-outdated(1) - npm outdated [[<@scope>/] ...] +## Check for outdated packages -## DESCRIPTION +### Synopsis + +```bash +npm outdated [[<@scope>/] ...] +``` + +### Description This command will check the registry to see if any (or, specific) installed packages are currently outdated. @@ -20,7 +29,7 @@ In the output: Running `npm publish` with no special configuration will publish the package with a dist-tag of `latest`. This may or may not be the maximum version of the package, or the most-recently published version of the package, depending - on how the package's developer manages the latest dist-tag(1). + on how the package's developer manages the latest [dist-tag](npm-dist-tag). * `location` is where in the dependency tree the package is located. Note that `npm outdated` defaults to a depth of 0, so unless you override that, you'll always be seeing only top-level dependencies that are outdated. @@ -33,7 +42,7 @@ In the output: ### An example -``` +```bash $ npm outdated Package Current Wanted Latest Location glob 5.0.15 5.0.15 6.0.1 test-outdated-output @@ -69,30 +78,30 @@ A few things to note: * `once` is just plain out of date. Reinstalling `node_modules` from scratch or running `npm update` will bring it up to spec. -## CONFIGURATION +### Configuration -### json +#### json * Default: false * Type: Boolean Show information in JSON format. -### long +#### long * Default: false * Type: Boolean Show extended information. -### parseable +#### parseable * Default: false * Type: Boolean Show parseable output instead of tree view. -### global +#### global * Default: false * Type: Boolean @@ -100,16 +109,16 @@ Show parseable output instead of tree view. Check packages in the global install prefix instead of in the current project. -### depth +#### depth * Default: 0 * Type: Int Max depth for checking dependency tree. -## SEE ALSO +### See Also -* npm-update(1) -* npm-dist-tag(1) -* npm-registry(7) -* npm-folders(5) +* [npm update](/cli-commands/npm-update) +* [npm dist-tag](/cli-commands/npm-dist-tag) +* [npm registry](/using-npm/registry) +* [npm folders](/configuring-npm/folders) diff --git a/deps/npm/doc/cli/npm-owner.md b/deps/npm/docs/content/cli-commands/npm-owner.md similarity index 63% rename from deps/npm/doc/cli/npm-owner.md rename to deps/npm/docs/content/cli-commands/npm-owner.md index 94010298c18ef5..bc2fbc82fb280e 100644 --- a/deps/npm/doc/cli/npm-owner.md +++ b/deps/npm/docs/content/cli-commands/npm-owner.md @@ -1,15 +1,23 @@ -npm-owner(1) -- Manage package owners -===================================== +--- +section: cli-commands +title: npm-owner +description: Manage package owners +--- -## SYNOPSIS +# npm-owner(1) +## Manage package owners - npm owner add [<@scope>/] - npm owner rm [<@scope>/] - npm owner ls [<@scope>/] +### Synopsis - aliases: author +```bash +npm owner add [<@scope>/] +npm owner rm [<@scope>/] +npm owner ls [<@scope>/] -## DESCRIPTION +aliases: author +``` + +### Description Manage ownership of published packages. @@ -31,9 +39,9 @@ If you have two-factor authentication enabled with `auth-and-writes` then you'll need to include an otp on the command line when changing ownership with `--otp`. -## SEE ALSO +### See Also -* npm-publish(1) -* npm-registry(7) -* npm-adduser(1) -* npm-disputes(7) +* [npm publish](/cli-commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm adduser](/cli-commands/npm-adduser) +* [npm disputes](/using-npm/disputes) diff --git a/deps/npm/doc/cli/npm-pack.md b/deps/npm/docs/content/cli-commands/npm-pack.md similarity index 61% rename from deps/npm/doc/cli/npm-pack.md rename to deps/npm/docs/content/cli-commands/npm-pack.md index 807663ac210fe9..acf18559c14e00 100644 --- a/deps/npm/doc/cli/npm-pack.md +++ b/deps/npm/docs/content/cli-commands/npm-pack.md @@ -1,11 +1,20 @@ -npm-pack(1) -- Create a tarball from a package -============================================== +--- +section: cli-commands +title: npm-pack +description: Create a tarball from a package +--- -## SYNOPSIS +# npm-pack(1) - npm pack [[<@scope>/]...] [--dry-run] +## Create a tarball from a package -## DESCRIPTION +### Synopsis + +```bash +npm pack [[<@scope>/]...] [--dry-run] +``` + +### Description For anything that's installable (that is, a package folder, tarball, tarball url, name@tag, name@version, name, or scoped name), this @@ -21,10 +30,9 @@ If no arguments are supplied, then npm packs the current package folder. The `--dry-run` argument will do everything that pack usually does without actually packing anything. Reports on what would have gone into the tarball. -## SEE ALSO +### See Also -* npm-cache(1) -* npm-publish(1) -* npm-config(1) -* npm-config(7) -* npmrc(5) +* [npm cache](/cli-commands/npm-cache) +* [npm publish](/cli-commands/npm-publish) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/docs/content/cli-commands/npm-ping.md b/deps/npm/docs/content/cli-commands/npm-ping.md new file mode 100644 index 00000000000000..93d18b57f840b0 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-ping.md @@ -0,0 +1,33 @@ +--- +section: cli-commands +title: npm-ping +description: Ping npm registry +--- + +# npm-ping(1) + +## Ping npm registry + +### Synopsis + +```bash +npm ping [--registry ] +``` + +### Description + +Ping the configured or given npm registry and verify authentication. +If it works it will output something like: + +```bash +Ping success: {*Details about registry*} +``` +otherwise you will get: +```bash +Ping error: {*Detail about error} +``` + +### See Also + +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/docs/content/cli-commands/npm-prefix.md b/deps/npm/docs/content/cli-commands/npm-prefix.md new file mode 100644 index 00000000000000..b82fec663a147d --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-prefix.md @@ -0,0 +1,32 @@ +--- +section: cli-commands +title: npm-prefix +description: Display prefix +--- + +# npm-prefix(1) + +## Display prefix + +### Synopsis + +```bash +npm prefix [-g] +``` + +### Description + +Print the local prefix to standard out. This is the closest parent directory +to contain a `package.json` file or `node_modules` directory, unless `-g` is +also specified. + +If `-g` is specified, this will be the value of the global prefix. See +[`npm config`](/cli-commands/npm-config) for more detail. + +### See Also + +* [npm root](/cli-commands/npm-root) +* [npm bin](/cli-commands/npm-bin) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/cli/npm-profile.md b/deps/npm/docs/content/cli-commands/npm-profile.md similarity index 83% rename from deps/npm/doc/cli/npm-profile.md rename to deps/npm/docs/content/cli-commands/npm-profile.md index 31e8b7e8ef8afa..9fe82cd2d3a952 100644 --- a/deps/npm/doc/cli/npm-profile.md +++ b/deps/npm/docs/content/cli-commands/npm-profile.md @@ -1,15 +1,23 @@ -npm-profile(1) -- Change settings on your registry profile -========================================================== +--- +section: cli-commands +title: npm-profile +description: Change settings on your registry profile +--- -## SYNOPSIS +# npm-profile(1) +## Change settings on your registry profile - npm profile get [--json|--parseable] [] - npm profile set [--json|--parseable] - npm profile set password - npm profile enable-2fa [auth-and-writes|auth-only] - npm profile disable-2fa +### Synopsis -## DESCRIPTION +```bash +npm profile get [--json|--parseable] [] +npm profile set [--json|--parseable] +npm profile set password +npm profile enable-2fa [auth-and-writes|auth-only] +npm profile disable-2fa +``` + +### Description Change your profile information on the registry. This not be available if you're using a non-npmjs registry. @@ -18,7 +26,7 @@ you're using a non-npmjs registry. Display all of the properties of your profile, or one or more specific properties. It looks like: -``` +```bash +-----------------+---------------------------+ | name | example | +-----------------+---------------------------+ @@ -41,7 +49,7 @@ you're using a non-npmjs registry. | updated | 2017-10-02T21:29:45.922Z | +-----------------+---------------------------+ ``` - + * `npm profile set `: Set the value of a profile property. You can set the following properties this way: email, fullname, homepage, freenode, twitter, github @@ -63,12 +71,12 @@ you're using a non-npmjs registry. * `npm profile disable-2fa`: Disables two-factor authentication. -## DETAILS +### Details All of the `npm profile` subcommands accept `--json` and `--parseable` and will tailor their output based on those. Some of these commands may not be available on non npmjs.com registries. -## SEE ALSO +### See Also -* npm-config(7) +* [npm config](/cli-commands/npm-config) diff --git a/deps/npm/doc/cli/npm-prune.md b/deps/npm/docs/content/cli-commands/npm-prune.md similarity index 73% rename from deps/npm/doc/cli/npm-prune.md rename to deps/npm/docs/content/cli-commands/npm-prune.md index 0dde2442511228..c6b61e62f828a2 100644 --- a/deps/npm/doc/cli/npm-prune.md +++ b/deps/npm/docs/content/cli-commands/npm-prune.md @@ -1,11 +1,19 @@ -npm-prune(1) -- Remove extraneous packages -========================================== +--- +section: cli-commands +title: npm-prune +description: Remove extraneous packages +--- -## SYNOPSIS +# npm-prune(1) +## Remove extraneous packages - npm prune [[<@scope>/]...] [--production] [--dry-run] [--json] +### Synopsis -## DESCRIPTION +```bash +npm prune [[<@scope>/]...] [--production] [--dry-run] [--json] +``` + +### Description This command removes "extraneous" packages. If a package name is provided, then only packages matching one of the supplied names are @@ -31,8 +39,8 @@ this command with the `--production` flag. If you've disabled package-locks then extraneous modules will not be removed and it's up to you to run `npm prune` from time-to-time to remove them. -## SEE ALSO +### See Also -* npm-uninstall(1) -* npm-folders(5) -* npm-ls(1) +* [npm uninstall](/cli-commands/npm-uninstall) +* [npm folders](/configuring-npm/folders) +* [npm ls](/cli-commands/npm-ls) diff --git a/deps/npm/doc/cli/npm-publish.md b/deps/npm/docs/content/cli-commands/npm-publish.md similarity index 61% rename from deps/npm/doc/cli/npm-publish.md rename to deps/npm/docs/content/cli-commands/npm-publish.md index c582ad8470c2a9..b9d0cf1449e760 100644 --- a/deps/npm/doc/cli/npm-publish.md +++ b/deps/npm/docs/content/cli-commands/npm-publish.md @@ -1,26 +1,31 @@ -npm-publish(1) -- Publish a package -=================================== +--- +section: cli-commands +title: npm-publish +description: Publish a package +--- +# npm-publish(1) -## SYNOPSIS +## Publish a package - npm publish [|] [--tag ] [--access ] [--otp otpcode] [--dry-run] +### Synopsis +```bash +npm publish [|] [--tag ] [--access ] [--otp otpcode] [--dry-run] - Publishes '.' if no argument supplied - Sets tag 'latest' if no --tag specified +Publishes '.' if no argument supplied +Sets tag 'latest' if no --tag specified +``` -## DESCRIPTION +### Description Publishes a package to the registry so that it can be installed by name. All files in the package directory are included if no local `.gitignore` or `.npmignore` file exists. If both files exist and a file is ignored by `.gitignore` but not by `.npmignore` then it will be included. See -`npm-developers(7)` for full details on what's included in the published -package, as well as details on how the package is built. +[`developers`](/using-npm/developers) for full details on what's included in the published package, as well as details on how the package is built. By default npm will publish to the public registry. This can be overridden by -specifying a different default registry or using a `npm-scope(7)` in the name -(see `package.json(5)`). +specifying a different default registry or using a [`scope`](/using-npm/npm-scope) in the name (see [`package.json`](/configuring-npm/package-json)). * ``: A folder containing a package.json file @@ -32,7 +37,7 @@ specifying a different default registry or using a `npm-scope(7)` in the name * `[--tag ]` Registers the published package with the given tag, such that `npm install @` will install this version. By default, `npm publish` updates - and `npm install` installs the `latest` tag. See `npm-dist-tag(1)` for + and `npm install` installs the `latest` tag. See [`npm-dist-tag`](npm-dist-tag) for details about tags. * `[--access ]` @@ -55,22 +60,22 @@ the specified registry. Once a package is published with a given name and version, that specific name and version combination can never be used again, even if -it is removed with npm-unpublish(1). +it is removed with [`npm unpublish`](/cli-commands/npm-unpublish). As of `npm@5`, both a sha1sum and an integrity field with a sha512sum of the tarball will be submitted to the registry during publication. Subsequent installs will use the strongest supported algorithm to verify downloads. -Similar to `--dry-run` see `npm-pack(1)`, which figures out the files to be +Similar to `--dry-run` see [`npm pack`](/cli-commands/npm-pack), which figures out the files to be included and packs them into a tarball to be uploaded to the registry. -## SEE ALSO +### See Also -* npm-registry(7) -* npm-scope(7) -* npm-adduser(1) -* npm-owner(1) -* npm-deprecate(1) -* npm-dist-tag(1) -* npm-pack(1) -* npm-profile(1) +* [npm registry](/using-npm/registry) +* [npm scope](/using-npm/scope) +* [npm adduser](/cli-commands/npm-adduser) +* [npm owner](/cli-commands/npm-owner) +* [npm deprecate](/cli-commands/npm-deprecate) +* [npm dist-tag](/cli-commands/npm-dist-tag) +* [npm pack](/cli-commands/npm-pack) +* [npm profile](/cli-commands/npm-profile) diff --git a/deps/npm/docs/content/cli-commands/npm-rebuild.md b/deps/npm/docs/content/cli-commands/npm-rebuild.md new file mode 100644 index 00000000000000..414b9ca55a1932 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-rebuild.md @@ -0,0 +1,26 @@ +--- +section: cli-commands +title: npm-rebuild +description: Rebuild a package +--- + +# npm-rebuild(1) + +## Rebuild a package + +### Synopsis + +```bash +npm rebuild [[<@scope>/]...] + +alias: npm rb +``` + +### Description + +This command runs the `npm build` command on the matched folders. This is useful when you install a new version of node, and must recompile all your C++ addons with the new binary. + +### See Also + +* [npm build](/cli-commands/npm-build) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/cli/npm-repo.md b/deps/npm/docs/content/cli-commands/npm-repo.md similarity index 55% rename from deps/npm/doc/cli/npm-repo.md rename to deps/npm/docs/content/cli-commands/npm-repo.md index 523e135e8cc31f..ad41ea571253fd 100644 --- a/deps/npm/doc/cli/npm-repo.md +++ b/deps/npm/docs/content/cli-commands/npm-repo.md @@ -1,27 +1,36 @@ -npm-repo(1) -- Open package repository page in the browser -======================================================== +--- +section: cli-commands +title: npm-repo +description: Open package repository page in the browser +--- -## SYNOPSIS +# npm-repo(1) - npm repo [] +## Open package repository page in the browser -## DESCRIPTION +### Synopsis + +```bash +npm repo [] +``` + +### Description This command tries to guess at the likely location of a package's repository URL, and then tries to open it using the `--browser` config param. If no package name is provided, it will search for a `package.json` in the current folder and use the `name` property. -## CONFIGURATION +### Configuration -### browser +#### browser * Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` * Type: String The browser that is called by the `npm repo` command to open websites. -## SEE ALSO +### See Also -* npm-docs(1) -* npm-config(1) +* [npm docs](/cli-commands/npm-docs) +* [npm config](/cli-commands/npm-config) diff --git a/deps/npm/doc/cli/npm-restart.md b/deps/npm/docs/content/cli-commands/npm-restart.md similarity index 53% rename from deps/npm/doc/cli/npm-restart.md rename to deps/npm/docs/content/cli-commands/npm-restart.md index 1aa0c57a6829eb..d6d388b224ab1f 100644 --- a/deps/npm/doc/cli/npm-restart.md +++ b/deps/npm/docs/content/cli-commands/npm-restart.md @@ -1,11 +1,20 @@ -npm-restart(1) -- Restart a package -=================================== +--- +section: cli-commands +title: npm-restart +description: Restart a package +--- -## SYNOPSIS +# npm-restart(1) - npm restart [-- ] +## Restart a package -## DESCRIPTION +### Synopsis + +```bash +npm restart [-- ] +``` + +### Description This restarts a package. @@ -22,7 +31,7 @@ pre- and post- scripts, in the order given below: 8. poststart 9. postrestart -## NOTE +### Note Note that the "restart" script is run **in addition to** the "stop" and "start" scripts, not instead of them. @@ -30,11 +39,11 @@ and "start" scripts, not instead of them. This is the behavior as of `npm` major version 2. A change in this behavior will be accompanied by an increase in major version number -## SEE ALSO +### See Also -* npm-run-script(1) -* npm-scripts(7) -* npm-test(1) -* npm-start(1) -* npm-stop(1) -* npm-restart(3) \ No newline at end of file +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [npm test](/cli-commands/npm-test) +* [npm start](/cli-commands/npm-start) +* [npm stop](/cli-commands/npm-stop) +* [npm restart](/cli-commands/npm-restart) \ No newline at end of file diff --git a/deps/npm/docs/content/cli-commands/npm-root.md b/deps/npm/docs/content/cli-commands/npm-root.md new file mode 100644 index 00000000000000..2b27878af4c6dc --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-root.md @@ -0,0 +1,26 @@ +--- +section: cli-commands +title: npm-root +description: Display npm root +--- + +# npm-root(1) + +## Display npm root + +### Synopsis +```bash +npm root [-g] +``` + +### Description + +Print the effective `node_modules` folder to standard out. + +### See Also + +* [npm prefix](/cli-commands/npm-prefix) +* [npm bin](/cli-commands/npm-bin) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/cli/npm-run-script.md b/deps/npm/docs/content/cli-commands/npm-run-script.md similarity index 81% rename from deps/npm/doc/cli/npm-run-script.md rename to deps/npm/docs/content/cli-commands/npm-run-script.md index 18c5736604fa79..51def74c3c4c33 100644 --- a/deps/npm/doc/cli/npm-run-script.md +++ b/deps/npm/docs/content/cli-commands/npm-run-script.md @@ -1,13 +1,22 @@ -npm-run-script(1) -- Run arbitrary package scripts -================================================== +--- +section: cli-commands +title: npm-run-script +description: Run arbitrary package scripts +--- -## SYNOPSIS +# npm-run-script(1) - npm run-script [--silent] [-- ...] +## Run arbitrary package scripts - alias: npm run +### Synopsis -## DESCRIPTION +```bash +npm run-script [--silent] [-- ...] + +alias: npm run +``` + +### Description This runs an arbitrary command from a package's `"scripts"` object. If no `"command"` is provided, it will list the available scripts. `run[-script]` is @@ -20,7 +29,9 @@ use custom arguments when executing scripts. The special option `--` is used by [getopt](https://goo.gl/KxMmtG) to delimit the end of the options. npm will pass all the arguments after the `--` directly to your script: - npm run test -- --grep="pattern" +```bash +npm run test -- --grep="pattern" +``` The arguments will only be passed to the script specified after ```npm run``` and not to any pre or post script. @@ -36,11 +47,15 @@ locally-installed dependencies can be used without the `node_modules/.bin` prefix. For example, if there is a `devDependency` on `tap` in your package, you should write: - "scripts": {"test": "tap test/\*.js"} +```bash +"scripts": {"test": "tap test/\*.js"} +``` instead of - "scripts": {"test": "node_modules/.bin/tap test/\*.js"} +```bash +"scripts": {"test": "node_modules/.bin/tap test/\*.js"} +``` to run your tests. @@ -72,11 +87,11 @@ You can use the `--if-present` flag to avoid exiting with a non-zero exit code when the script is undefined. This lets you run potentially undefined scripts without breaking the execution chain. -## SEE ALSO +### See Also -* npm-scripts(7) -* npm-test(1) -* npm-start(1) -* npm-restart(1) -* npm-stop(1) -* npm-config(7) +* [npm scripts](/using-npm/scripts) +* [npm test](/cli-commands/npm-test) +* [npm start](/cli-commands/npm-start) +* [npm restart](/cli-commands/npm-restart) +* [npm stop](/cli-commands/npm-stop) +* [npm config](/cli-commands/npm-config) diff --git a/deps/npm/doc/cli/npm-search.md b/deps/npm/docs/content/cli-commands/npm-search.md similarity index 80% rename from deps/npm/doc/cli/npm-search.md rename to deps/npm/docs/content/cli-commands/npm-search.md index c1107d79b735b5..e066106faf71f4 100644 --- a/deps/npm/doc/cli/npm-search.md +++ b/deps/npm/docs/content/cli-commands/npm-search.md @@ -1,13 +1,22 @@ -npm-search(1) -- Search for packages -==================================== +--- +section: cli-commands +title: npm-search +description: Search for packages +--- -## SYNOPSIS +# npm-search(1) - npm search [-l|--long] [--json] [--parseable] [--no-description] [search terms ...] +## Search for packages - aliases: s, se, find +### Synopsis -## DESCRIPTION +```bash +npm search [-l|--long] [--json] [--parseable] [--no-description] [search terms ...] + +aliases: s, se, find +``` + +### Description Search the registry for packages matching the search terms. `npm search` performs a linear, incremental, lexically-ordered search through package @@ -31,9 +40,9 @@ quoted in most shells.) ### A Note on caching -## CONFIGURATION +### Configuration -### description +#### description * Default: true * Type: Boolean @@ -41,21 +50,21 @@ quoted in most shells.) Used as `--no-description`, disables search matching in package descriptions and suppresses display of that field in results. -### json +#### json * Default: false * Type: Boolean Output search results as a JSON array. -### parseable +#### parseable * Default: false * Type: Boolean Output search results as lines with tab-separated columns. -### long +#### long * Default: false * Type: Boolean @@ -65,28 +74,28 @@ lines. When disabled (default) search results are truncated to fit neatly on a single line. Modules with extremely long names will fall on multiple lines. -### searchopts +#### searchopts * Default: "" * Type: String Space-separated options that are always passed to search. -### searchexclude +#### searchexclude * Default: "" * Type: String Space-separated options that limit the results from search. -### searchstaleness +#### searchstaleness * Default: 900 (15 minutes) * Type: Number The age of the cache, in seconds, before another registry request is made. -### registry +#### registry * Default: https://registry.npmjs.org/ * Type: url @@ -97,10 +106,9 @@ repository, `npm search` will default to that registry when searching. Pass a different registry url such as the default above in order to override this setting. -## SEE ALSO +### See Also -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-view(1) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm view](/cli-commands/npm-view) diff --git a/deps/npm/docs/content/cli-commands/npm-shrinkwrap.md b/deps/npm/docs/content/cli-commands/npm-shrinkwrap.md new file mode 100644 index 00000000000000..342fb001675ab3 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-shrinkwrap.md @@ -0,0 +1,34 @@ +--- +section: cli-commands +title: npm-shrinkwrap +description: Lock down dependency versions for publication +--- + +# npm-shrinkwrap(1) + +## Lock down dependency versions for publication + +### Synopsis + +```bash +npm shrinkwrap +``` + +### Description + +This command repurposes `package-lock.json` into a publishable +`npm-shrinkwrap.json` or simply creates a new one. The file created and updated +by this command will then take precedence over any other existing or future +`package-lock.json` files. For a detailed explanation of the design and purpose +of package locks in npm, see [package-locks](/configuring-npm/package-locks). + +### See Also + +* [npm install](/cli-commands/npm-install) +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [package.js](/configuring-npm/package-json) +* [package-locks](/configuring-npm/package-locks) +* [package-lock.json](/configuring-npm/package-lock-json) +* [shrinkwrap.json](/configuring-npm/shrinkwrap-json) +* [npm ls](/cli-commands/npm-ls) diff --git a/deps/npm/docs/content/cli-commands/npm-star.md b/deps/npm/docs/content/cli-commands/npm-star.md new file mode 100644 index 00000000000000..1912e9c654bc28 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-star.md @@ -0,0 +1,31 @@ +--- +section: cli-commands +title: npm-star +description: Mark your favorite packages +--- + +# npm-star(1) + +## Mark your favorite packages + +### Synopsis + +```bash +npm star [...] +npm unstar [...] +``` + +### Description + +"Starring" a package means that you have some interest in it. It's +a vaguely positive way to show that you care. + +"Unstarring" is the same thing, but in reverse. + +It's a boolean thing. Starring repeatedly has no additional effect. + +### See Also + +* [npm view](/cli-commands/npm-view) +* [npm whoami](/cli-commands/npm-whoami) +* [npm adduser](/cli-commands/npm-adduser) diff --git a/deps/npm/docs/content/cli-commands/npm-stars.md b/deps/npm/docs/content/cli-commands/npm-stars.md new file mode 100644 index 00000000000000..475547bb4b7f2f --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-stars.md @@ -0,0 +1,29 @@ +--- +section: cli-commands +title: npm-stars +description: View packages marked as favorites +--- + +# npm-stars(1) + +## View packages marked as favorites + +### Synopsis +```bash +npm stars [] +``` + +### Description + +If you have starred a lot of neat things and want to find them again +quickly this command lets you do just that. + +You may also want to see your friend's favorite packages, in this case +you will most certainly enjoy this command. + +### See Also + +* [npm star](/cli-commands/npm-star) +* [npm view](/cli-commands/npm-view) +* [npm whoami](/cli-commands/npm-whoami) +* [npm adduser](/cli-commands/npm-adduser) diff --git a/deps/npm/docs/content/cli-commands/npm-start.md b/deps/npm/docs/content/cli-commands/npm-start.md new file mode 100644 index 00000000000000..839528257b6d95 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-start.md @@ -0,0 +1,32 @@ +--- +section: cli-commands +title: npm-start +description: Start a package +--- + +# npm-start(1) + +## Start a package + +### Synopsis + +```bash +npm start [-- ] +``` + +### Description + +This runs an arbitrary command specified in the package's `"start"` property of +its `"scripts"` object. If no `"start"` property is specified on the +`"scripts"` object, it will run `node server.js`. + +As of [`npm@2.0.0`](https://blog.npmjs.org/post/98131109725/npm-2-0-0), you can +use custom arguments when executing scripts. Refer to [`npm run-script`](/cli-commands/npm-run-script) for more details. + +### See Also + +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [npm test](/cli-commands/npm-test) +* [npm restart](/cli-commands/npm-restart) +* [npm stop](/cli-commands/npm-stop) diff --git a/deps/npm/docs/content/cli-commands/npm-stop.md b/deps/npm/docs/content/cli-commands/npm-stop.md new file mode 100644 index 00000000000000..da759047cb19a5 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-stop.md @@ -0,0 +1,27 @@ +--- +section: cli-commands +title: npm-stop +description: Stop a package +--- + +# npm-stop(1) + +## Stop a package + +### Synopsis + +```bash +npm stop [-- ] +``` + +### Description + +This runs a package's "stop" script, if one was provided. + +### See Also + +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [npm test](/cli-commands/npm-test) +* [npm start](/cli-commands/npm-start) +* [npm restart](/cli-commands/npm-restart) diff --git a/deps/npm/doc/cli/npm-team.md b/deps/npm/docs/content/cli-commands/npm-team.md similarity index 60% rename from deps/npm/doc/cli/npm-team.md rename to deps/npm/docs/content/cli-commands/npm-team.md index 9e01a451c7945a..9a63b10c26f325 100644 --- a/deps/npm/doc/cli/npm-team.md +++ b/deps/npm/docs/content/cli-commands/npm-team.md @@ -1,31 +1,37 @@ -npm-team(1) -- Manage organization teams and team memberships -============================================================= +--- +section: cli-commands +title: npm-team +description: Manage organization teams and team memberships +--- -## SYNOPSIS +# npm-team(1) - npm team create - npm team destroy +## Manage organization teams and team memberships - npm team add - npm team rm +### Synopsis - npm team ls | +```bash +npm team create +npm team destroy - npm team edit +npm team add +npm team rm -## DESCRIPTION +npm team ls | + +npm team edit +``` + +### Description Used to manage teams in organizations, and change team memberships. Does not handle permissions for packages. Teams must always be fully qualified with the organization/scope they belong to -when operating on them, separated by a colon (`:`). That is, if you have a -`developers` team on a `foo` organization, you must always refer to that team as -`foo:developers` in these commands. +when operating on them, separated by a colon (`:`). That is, if you have a `wombats` team in a `wisdom` organization, you must always refer to that team as `wisdom:wombats` in these commands. * create / destroy: - Create a new team, or destroy an existing one. - + Create a new team, or destroy an existing one. Note: You cannot remove the `developers` team, learn more. * add / rm: Add a user to an existing team, or remove a user from a team they belong to. @@ -37,7 +43,7 @@ when operating on them, separated by a colon (`:`). That is, if you have a * edit: Edit a current team. -## DETAILS +### Details `npm team` always operates directly on the current registry, configurable from the command line using `--registry=`. @@ -52,7 +58,7 @@ is done through the website, not the npm CLI. To use teams to manage permissions on packages belonging to your organization, use the `npm access` command to grant or revoke the appropriate permissions. -## SEE ALSO +### See Also -* npm-access(1) -* npm-registry(7) +* [npm access](/cli-commands/npm-access) +* [npm registry](/using-npm/registry) diff --git a/deps/npm/docs/content/cli-commands/npm-test.md b/deps/npm/docs/content/cli-commands/npm-test.md new file mode 100644 index 00000000000000..99c027e3e057af --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-test.md @@ -0,0 +1,29 @@ +--- +section: cli-commands +title: npm-test +description: Test a package +--- + +# npm-test(1) + +## Test a package + +### Synopsis + +```bash +npm test [-- ] + +aliases: t, tst +``` + +### Description + +This runs a package's "test" script, if one was provided. + +### See Also + +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [npm start](/cli-commands/npm-start) +* [npm restart](/cli-commands/npm-restart) +* [npm stop](/cli-commands/npm-stop) diff --git a/deps/npm/doc/cli/npm-token.md b/deps/npm/docs/content/cli-commands/npm-token.md similarity index 87% rename from deps/npm/doc/cli/npm-token.md rename to deps/npm/docs/content/cli-commands/npm-token.md index 29dac392db4762..37a74083d2a12d 100644 --- a/deps/npm/doc/cli/npm-token.md +++ b/deps/npm/docs/content/cli-commands/npm-token.md @@ -1,20 +1,29 @@ -npm-token(1) -- Manage your authentication tokens -================================================= +--- +section: cli-commands +title: npm-token +description: Manage your authentication tokens +--- -## SYNOPSIS +# npm-token(1) - npm token list [--json|--parseable] - npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] - npm token revoke +## Manage your authentication tokens -## DESCRIPTION +### Synopsis +```bash + npm token list [--json|--parseable] + npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16] + npm token revoke + ``` + +### Description This lets you list, create and revoke authentication tokens. * `npm token list`: Shows a table of all active authentication tokens. You can request this as JSON with `--json` or tab-separated values with `--parseable`. -``` + +```bash +--------+---------+------------+----------+----------------+ | id | token | created | read-only | CIDR whitelist | +--------+---------+------------+----------+----------------+ @@ -40,7 +49,7 @@ This lets you list, create and revoke authentication tokens. limit use of this token to. This will prompt you for your password, and, if you have two-factor authentication enabled, an otp. -``` +```bash +----------------+--------------------------------------+ | token | a73c9572-f1b9-8983-983d-ba3ac3cc913d | +----------------+--------------------------------------+ @@ -55,5 +64,5 @@ This lets you list, create and revoke authentication tokens. * `npm token revoke `: This removes an authentication token, making it immediately unusable. This can accept both complete tokens (as you get back from `npm token create` and will - find in your `.npmrc`) and ids as seen in the `npm token list` output. + find in your `.npmrc`) and ids as seen in the `npm token list` output. This will NOT accept the truncated token found in `npm token list` output. diff --git a/deps/npm/docs/content/cli-commands/npm-uninstall.md b/deps/npm/docs/content/cli-commands/npm-uninstall.md new file mode 100644 index 00000000000000..96fdc4ebe05ba9 --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-uninstall.md @@ -0,0 +1,64 @@ +--- +section: cli-commands +title: npm-uninstall +description: Remove a package +--- + +# npm-uninstall(1) + +## Remove a package + +### Synopsis + +```bash +npm uninstall [<@scope>/][@]... [-S|--save|-D|--save-dev|-O|--save-optional|--no-save] + +aliases: remove, rm, r, un, unlink +``` + +### Description + +This uninstalls a package, completely removing everything npm installed +on its behalf. + +Example: + +```bash +npm uninstall sax +``` + +In global mode (ie, with `-g` or `--global` appended to the command), +it uninstalls the current package context as a global package. + +`npm uninstall` takes 3 exclusive, optional flags which save or update +the package version in your main package.json: + +* `-S, --save`: Package will be removed from your `dependencies`. + +* `-D, --save-dev`: Package will be removed from your `devDependencies`. + +* `-O, --save-optional`: Package will be removed from your `optionalDependencies`. + +* `--no-save`: Package will not be removed from your `package.json` file. + +Further, if you have an `npm-shrinkwrap.json` then it will be updated as +well. + +Scope is optional and follows the usual rules for [`scope`](/using-npm/scope). + +Examples: +```bash +npm uninstall sax --save +npm uninstall @myorg/privatepackage --save +npm uninstall node-tap --save-dev +npm uninstall dtrace-provider --save-optional +npm uninstall lodash --no-save +``` + +### See Also + +* [npm prune](/cli-commands/npm-prune) +* [npm install](/cli-commands/npm-install) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/cli/npm-unpublish.md b/deps/npm/docs/content/cli-commands/npm-unpublish.md similarity index 64% rename from deps/npm/doc/cli/npm-unpublish.md rename to deps/npm/docs/content/cli-commands/npm-unpublish.md index b5b02154e93092..5348023d9a8400 100644 --- a/deps/npm/doc/cli/npm-unpublish.md +++ b/deps/npm/docs/content/cli-commands/npm-unpublish.md @@ -1,11 +1,20 @@ -npm-unpublish(1) -- Remove a package from the registry -====================================================== +--- +section: cli-commands +title: npm-unpublish +description: Remove a package from the registry +--- -## SYNOPSIS +# npm-unpublish(1) - npm unpublish [<@scope>/][@] +## Remove a package from the registry -## WARNING +### Synopsis + +```bash +npm unpublish [<@scope>/][@] +``` + +### Warning **It is generally considered bad behavior to remove versions of a library that others are depending on!** @@ -15,7 +24,7 @@ instead, if your intent is to encourage users to upgrade. There is plenty of room on the registry. -## DESCRIPTION +### Description This removes a package version from the registry, deleting its entry and removing the tarball. @@ -34,12 +43,12 @@ only allowed with versions published in the last 72 hours. If you are trying to unpublish a version published longer ago than that, contact support@npmjs.com. -The scope is optional and follows the usual rules for `npm-scope(7)`. +The scope is optional and follows the usual rules for [`scope`](/using-npm/scope). -## SEE ALSO +### See Also -* npm-deprecate(1) -* npm-publish(1) -* npm-registry(7) -* npm-adduser(1) -* npm-owner(1) +* [npm deprecate](/cli-commands/npm-deprecate) +* [npm publish](/cli-commands/npm-publish) +* [npm registry](/using-npm/registry) +* [npm adduser](/cli-commands/npm-adduser) +* [npm owner](/cli-commands/npm-owner) diff --git a/deps/npm/doc/cli/npm-update.md b/deps/npm/docs/content/cli-commands/npm-update.md similarity index 79% rename from deps/npm/doc/cli/npm-update.md rename to deps/npm/docs/content/cli-commands/npm-update.md index b6cf2af78b815b..f2e93b6dc33df1 100644 --- a/deps/npm/doc/cli/npm-update.md +++ b/deps/npm/docs/content/cli-commands/npm-update.md @@ -1,13 +1,22 @@ -npm-update(1) -- Update a package -================================= +--- +section: cli-commands +title: npm-update +description: Update a package +--- -## SYNOPSIS +# npm-update(1) - npm update [-g] [...] +## Update a package - aliases: up, upgrade +### Synopsis -## DESCRIPTION +```bash +npm update [-g] [...] + +aliases: up, upgrade +``` + +### Description This command will update all the packages listed to the latest version (specified by the `tag` config), respecting semver. @@ -26,11 +35,11 @@ As of `npm@2.6.1`, the `npm update` will only inspect top-level packages. Prior versions of `npm` would also recursively inspect all dependencies. To get the old behavior, use `npm --depth 9999 update`. -As of `npm@5.0.0`, the `npm update` will change `package.json` to save the -new version as the minimum required dependency. To get the old behavior, +As of `npm@5.0.0`, the `npm update` will change `package.json` to save the +new version as the minimum required dependency. To get the old behavior, use `npm update --no-save`. -## EXAMPLES +### Example IMPORTANT VERSION NOTE: these examples assume `npm@2.6.1` or later. For older versions of `npm`, you must specify `--depth 0` to get the behavior @@ -39,7 +48,7 @@ described below. For the examples below, assume that the current package is `app` and it depends on dependencies, `dep1` (`dep2`, .. etc.). The published versions of `dep1` are: -``` +```json { "dist-tags": { "latest": "1.2.2" }, "versions": [ @@ -56,11 +65,11 @@ on dependencies, `dep1` (`dep2`, .. etc.). The published versions of `dep1` are } ``` -### Caret Dependencies +#### Caret Dependencies If `app`'s `package.json` contains: -``` +```json "dependencies": { "dep1": "^1.1.1" } @@ -69,11 +78,11 @@ If `app`'s `package.json` contains: Then `npm update` will install `dep1@1.2.2`, because `1.2.2` is `latest` and `1.2.2` satisfies `^1.1.1`. -### Tilde Dependencies +#### Tilde Dependencies However, if `app`'s `package.json` contains: -``` +```json "dependencies": { "dep1": "~1.1.1" } @@ -84,11 +93,11 @@ tag points to `1.2.2`, this version does not satisfy `~1.1.1`, which is equivale to `>=1.1.1 <1.2.0`. So the highest-sorting version that satisfies `~1.1.1` is used, which is `1.1.2`. -### Caret Dependencies below 1.0.0 +#### Caret Dependencies below 1.0.0 Suppose `app` has a caret dependency on a version below `1.0.0`, for example: -``` +```json "dependencies": { "dep1": "^0.2.0" } @@ -99,7 +108,7 @@ versions which satisfy `^0.2.0`. If the dependence were on `^0.4.0`: -``` +```json "dependencies": { "dep1": "^0.4.0" } @@ -109,7 +118,7 @@ Then `npm update` will install `dep1@0.4.1`, because that is the highest-sorting version that satisfies `^0.4.0` (`>= 0.4.0 <0.5.0`) -### Updating Globally-Installed Packages +#### Updating Globally-Installed Packages `npm update -g` will apply the `update` action to each globally installed package that is `outdated` -- that is, has a version that is different from @@ -119,11 +128,11 @@ NOTE: If a package has been upgraded to a version newer than `latest`, it will be _downgraded_. -## SEE ALSO +### See Also -* npm-install(1) -* npm-outdated(1) -* npm-shrinkwrap(1) -* npm-registry(7) -* npm-folders(5) -* npm-ls(1) +* [npm install](/cli-commands/npm-install) +* [npm outdated](/cli-commands/npm-outdated) +* [npm shrinkwrap](/cli-commands/npm-shrinkwrap) +* [npm registry](/using-npm/registry) +* [npm folders](/configuring-npm/folders) +* [npm ls](/cli-commands/npm-ls) diff --git a/deps/npm/doc/cli/npm-version.md b/deps/npm/docs/content/cli-commands/npm-version.md similarity index 75% rename from deps/npm/doc/cli/npm-version.md rename to deps/npm/docs/content/cli-commands/npm-version.md index 4cbc51eddd030b..a47e9e33326acf 100644 --- a/deps/npm/doc/cli/npm-version.md +++ b/deps/npm/docs/content/cli-commands/npm-version.md @@ -1,15 +1,24 @@ -npm-version(1) -- Bump a package version -======================================== +--- +section: cli-commands +title: npm-version +description: Bump a package version +--- -## SYNOPSIS +# npm-version(1) - npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=] | from-git] +## Bump a package version - 'npm [-v | --version]' to print npm version - 'npm view version' to view a package's published version - 'npm ls' to inspect current package/dependency versions +### Synopsis -## DESCRIPTION +```bash +npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=] | from-git] + +'npm [-v | --version]' to print npm version +'npm view version' to view a package's published version +'npm ls' to inspect current package/dependency versions +``` + +### Description Run this in a package directory to bump the version and write the new data back to `package.json`, `package-lock.json`, and, if present, `npm-shrinkwrap.json`. @@ -31,20 +40,24 @@ use it as a commit message when creating a version commit. If the `message` config contains `%s` then that will be replaced with the resulting version number. For example: - npm version patch -m "Upgrade to %s for reasons" +```bash +npm version patch -m "Upgrade to %s for reasons" +``` If the `sign-git-tag` config is set, then the tag will be signed using the `-s` flag to git. Note that you must have a default GPG key set up in your git config for this to work properly. For example: - $ npm config set sign-git-tag true - $ npm version patch +```bash +$ npm config set sign-git-tag true +$ npm version patch - You need a passphrase to unlock the secret key for - user: "isaacs (http://blog.izs.me/) " - 2048-bit RSA key, ID 6C481CF6, created 2010-08-31 +You need a passphrase to unlock the secret key for +user: "isaacs (http://blog.izs.me/) " +2048-bit RSA key, ID 6C481CF6, created 2010-08-31 - Enter passphrase: +Enter passphrase: +``` If `preversion`, `version`, or `postversion` are in the `scripts` property of the package.json, they will be executed as part of running `npm version`. @@ -66,41 +79,43 @@ The exact order of execution is as follows: Take the following example: +```json "scripts": { "preversion": "npm test", "version": "npm run build && git add -A dist", "postversion": "git push && git push --tags && rm -rf build/temp" } +``` This runs all your tests, and proceeds only if they pass. Then runs your `build` script, and adds everything in the `dist` directory to the commit. After the commit, it pushes the new commit and tag up to the server, and deletes the `build/temp` directory. -## CONFIGURATION +### Configuration -### allow-same-version +#### allow-same-version * Default: false * Type: Boolean -Prevents throwing an error when `npm version` is used to set the new version +Prevents throwing an error when `npm version` is used to set the new version to the same value as the current version. -### git-tag-version +#### git-tag-version * Default: true * Type: Boolean Commit and tag the version change. -### commit-hooks +#### commit-hooks * Default: true * Type: Boolean Run git commit hooks when committing the version change. -### sign-git-tag +#### sign-git-tag * Default: false * Type: Boolean @@ -109,11 +124,11 @@ Pass the `-s` flag to git to sign the tag. Note that you must have a default GPG key set up in your git config for this to work properly. -## SEE ALSO +### See Also -* npm-init(1) -* npm-run-script(1) -* npm-scripts(7) -* package.json(5) -* semver(7) -* config(7) +* [npm init](/cli-commands/npm-init) +* [npm run-script](/cli-commands/npm-run-script) +* [npm scripts](/using-npm/scripts) +* [package.json](/configuring-npm/package-json) +* [semver](/using-npm/semver) +* [config](/using-npm/config) diff --git a/deps/npm/doc/cli/npm-view.md b/deps/npm/docs/content/cli-commands/npm-view.md similarity index 68% rename from deps/npm/doc/cli/npm-view.md rename to deps/npm/docs/content/cli-commands/npm-view.md index 35e42adf9af8f5..0c108e6f566154 100644 --- a/deps/npm/doc/cli/npm-view.md +++ b/deps/npm/docs/content/cli-commands/npm-view.md @@ -1,13 +1,22 @@ -npm-view(1) -- View registry info -================================= +--- +section: cli-commands +title: npm-view +description: View registry info +--- -## SYNOPSIS +# npm-view(1) - npm view [<@scope>/][@] [[.]...] +## View registry info - aliases: info, show, v +### Synopsis -## DESCRIPTION +```bash +npm view [<@scope>/][@] [[.]...] + +aliases: info, show, v +``` + +### Description This command shows data about a package and prints it to the stream referenced by the `outfd` config, which defaults to stdout. @@ -15,7 +24,9 @@ referenced by the `outfd` config, which defaults to stdout. To show the package registry entry for the `connect` package, you can do this: - npm view connect +```bash +npm view connect +``` The default version is "latest" if unspecified. @@ -23,56 +34,74 @@ Field names can be specified after the package descriptor. For example, to show the dependencies of the `ronn` package at version 0.3.5, you could do the following: - npm view ronn@0.3.5 dependencies +```bash +npm view ronn@0.3.5 dependencies +``` You can view child fields by separating them with a period. To view the git repository URL for the latest version of npm, you could do this: - npm view npm repository.url +```bash +npm view npm repository.url +``` This makes it easy to view information about a dependency with a bit of shell scripting. For example, to view all the data about the version of opts that ronn depends on, you can do this: - npm view opts@$(npm view ronn dependencies.opts) +```bash +npm view opts@$(npm view ronn dependencies.opts) +``` For fields that are arrays, requesting a non-numeric field will return all of the values from the objects in the list. For example, to get all the contributor names for the "express" project, you can do this: - npm view express contributors.email +```bash +npm view express contributors.email +``` You may also use numeric indices in square braces to specifically select an item in an array field. To just get the email address of the first contributor in the list, you can do this: - npm view express contributors[0].email +```bash +npm view express contributors[0].email +``` Multiple fields may be specified, and will be printed one after another. For example, to get all the contributor names and email addresses, you can do this: - npm view express contributors.name contributors.email +```bash +npm view express contributors.name contributors.email +``` "Person" fields are shown as a string if they would be shown as an object. So, for example, this will show the list of npm contributors in -the shortened string format. (See `package.json(5)` for more on this.) +the shortened string format. (See [`package.json`](/configuring-npm/package.json) for more on this.) - npm view npm contributors +```bash +npm view npm contributors +``` If a version range is provided, then data will be printed for every matching version of the package. This will show which version of jsdom was required by each matching version of yui3: - npm view yui3@'>0.5.4' dependencies.jsdom +```bash +npm view yui3@'>0.5.4' dependencies.jsdom +``` To show the `connect` package version history, you can do this: - npm view connect versions +```bash +npm view connect versions +``` -## OUTPUT +### Output If only a single string field for a single version is output, then it will not be colorized or quoted, so as to enable piping the output to @@ -86,11 +115,10 @@ will be prefixed with the version it applies to. If multiple fields are requested, than each of them are prefixed with the field name. -## SEE ALSO +### See Also -* npm-search(1) -* npm-registry(7) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-docs(1) +* [npm search](/cli-commands/npm-search) +* [npm registry](/using-npm/registry) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm docs](/cli-commands/npm-docs) diff --git a/deps/npm/docs/content/cli-commands/npm-whoami.md b/deps/npm/docs/content/cli-commands/npm-whoami.md new file mode 100644 index 00000000000000..b0eda4e46aa61b --- /dev/null +++ b/deps/npm/docs/content/cli-commands/npm-whoami.md @@ -0,0 +1,24 @@ +--- +section: cli-commands +title: npm-whoami +description: Display npm username +--- + +# npm-whoami(1) +## Display npm username + +### Synopsis + +```bash +npm whoami [--registry ] +``` + +### Description + +Print the `username` config to standard output. + +### See Also + +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm adduser](/cli-commands/npm-adduser) diff --git a/deps/npm/doc/cli/npm.md b/deps/npm/docs/content/cli-commands/npm.md similarity index 83% rename from deps/npm/doc/cli/npm.md rename to deps/npm/docs/content/cli-commands/npm.md index 32384547bcb0bd..01a9308204d196 100644 --- a/deps/npm/doc/cli/npm.md +++ b/deps/npm/docs/content/cli-commands/npm.md @@ -1,15 +1,24 @@ -npm(1) -- javascript package manager -==================================== +--- +section: cli-commands +title: npm +description: javascript package manager +--- -## SYNOPSIS +# npm(1) - npm [args] +## javascript package manager -## VERSION +### Synopsis + +```bash +npm [args] +``` + +### Version @VERSION@ -## DESCRIPTION +### Description npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency @@ -21,7 +30,7 @@ programs. Run `npm help` to get a list of available commands. -## IMPORTANT +### Important npm is configured to use npm, Inc.'s public registry at https://registry.npmjs.org by default. Use of the npm public registry is @@ -31,17 +40,17 @@ You can configure npm to use any compatible registry you like, and even run your own registry. Use of someone else's registry may be governed by their terms of use. -## INTRODUCTION +### Introduction You probably got npm because you want to install stuff. Use `npm install blerg` to install the latest version of "blerg". Check out -`npm-install(1)` for more info. It can do a lot of stuff. +[`npm install`](/cli-commands/npm-install) for more info. It can do a lot of stuff. Use the `npm search` command to show everything that's available. Use `npm ls` to show everything you've installed. -## DEPENDENCIES +### Dependencies If a package references to another package with a git URL, npm depends on a preinstalled git. @@ -57,9 +66,9 @@ For more information visit [the node-gyp repository](https://github.com/TooTallNate/node-gyp) and the [node-gyp Wiki](https://github.com/TooTallNate/node-gyp/wiki). -## DIRECTORIES +### Directories -See `npm-folders(5)` to learn about where npm puts stuff. +See [`folders`](/configuring-npm/folders) to learn about where npm puts stuff. In particular, npm has two modes of operation: @@ -74,13 +83,13 @@ In particular, npm has two modes of operation: Local mode is the default. Use `-g` or `--global` on any command to operate in global mode instead. -## DEVELOPER USAGE +### Developer Usage If you're using npm to develop and publish your code, check out the following help topics: * json: - Make a package.json file. See `package.json(5)`. + Make a package.json file. See [`package.json`](/configuring-npm/package.json). * link: For linking your current working code into Node's path, so that you don't have to reinstall every time you make a change. Use @@ -95,7 +104,7 @@ following help topics: * publish: Use the `npm publish` command to upload your code to the registry. -## CONFIGURATION +#### Configuration npm is extremely configurable. It reads its configuration options from 5 places. @@ -121,9 +130,9 @@ npm is extremely configurable. It reads its configuration options from npm's default configuration options are defined in lib/utils/config-defs.js. These must not be changed. -See `npm-config(7)` for much much more information. +See [`config`](/using-npm/config) for much much more information. -## CONTRIBUTIONS +### Contributions Patches welcome! @@ -131,10 +140,9 @@ If you would like to contribute, but don't know what to work on, read the contributing guidelines and check the issues list. * [CONTRIBUTING.md](https://github.com/npm/cli/blob/latest/CONTRIBUTING.md) -* [Bug tracker](https://npm.community/c/bugs) -* [Support tracker](https://npm.community/c/support) +* [Bug tracker](https://github.com/npm/cli/issues) -## BUGS +### Bugs When you find issues, please report them: @@ -146,20 +154,16 @@ for help in the [support forum](https://npm.community/c/support) if you're unsure if it's actually a bug or are having trouble coming up with a detailed reproduction to report. -## AUTHOR +### Author [Isaac Z. Schlueter](http://blog.izs.me/) :: [isaacs](https://github.com/isaacs/) :: [@izs](https://twitter.com/izs) :: -## SEE ALSO - -* npm-help(1) -* README -* package.json(5) -* npm-install(1) -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-index(7) +### See Also +* [npm help](/cli-commands/npm-help) +* [package.json](/configuring-npm/package-json) +* [npm install](/cli-commands/npm-install) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) diff --git a/deps/npm/doc/files/npm-folders.md b/deps/npm/docs/content/configuring-npm/folders.md similarity index 80% rename from deps/npm/doc/files/npm-folders.md rename to deps/npm/docs/content/configuring-npm/folders.md index 456cb58bc89e1d..96a8f4783d719b 100644 --- a/deps/npm/doc/files/npm-folders.md +++ b/deps/npm/docs/content/configuring-npm/folders.md @@ -1,13 +1,20 @@ -npm-folders(5) -- Folder Structures Used by npm -=============================================== +--- +section: configuring-npm +title: folders +description: Folder Structures Used by npm +--- -## DESCRIPTION +# folders(5) + +## Folder Structures Used by npm + +### Description npm puts various things on your computer. That's its job. This document will tell you what it puts where. -### tl;dr +#### tl;dr * Local install (default): puts stuff in `./node_modules` of the current package root. @@ -17,7 +24,7 @@ This document will tell you what it puts where. * Install it **globally** if you're going to run it on the command line. * If you need both, then install it in both places, or use `npm link`. -### prefix Configuration +#### prefix Configuration The `prefix` config defaults to the location where node is installed. On most systems, this is `/usr/local`. On Windows, it's `%AppData%\npm`. @@ -28,7 +35,7 @@ When the `global` flag is set, npm installs things into this prefix. When it is not set, it uses the root of the current package, or the current working directory if not in a package already. -### Node Modules +#### Node Modules Packages are dropped into the `node_modules` folder under the `prefix`. When installing locally, this means that you can @@ -42,12 +49,11 @@ Global installs on Windows go to `{prefix}/node_modules` (that is, no Scoped packages are installed the same way, except they are grouped together in a sub-folder of the relevant `node_modules` folder with the name of that scope prefix by the @ symbol, e.g. `npm install @myorg/package` would place -the package in `{prefix}/node_modules/@myorg/package`. See `scope(7)` for -more details. +the package in `{prefix}/node_modules/@myorg/package`. See [`scope`](/using-npm/scope) for more details. If you wish to `require()` a package, then install it locally. -### Executables +#### Executables When in global mode, executables are linked into `{prefix}/bin` on Unix, or directly into `{prefix}` on Windows. @@ -57,7 +63,7 @@ When in local mode, executables are linked into through npm. (For example, so that a test runner will be in the path when you run `npm test`.) -### Man Pages +#### Man Pages When in global mode, man pages are linked into `{prefix}/share/man`. @@ -65,14 +71,14 @@ When in local mode, man pages are not installed. Man pages are not installed on Windows systems. -### Cache +#### Cache -See `npm-cache(1)`. Cache files are stored in `~/.npm` on Posix, or +See [`npm cache`](/cli-commands/npm-cache). Cache files are stored in `~/.npm` on Posix, or `%AppData%/npm-cache` on Windows. This is controlled by the `cache` configuration param. -### Temp Files +#### Temp Files Temporary files are stored by default in the folder specified by the `tmp` config, which defaults to the TMPDIR, TMP, or TEMP environment @@ -81,7 +87,7 @@ variables, or `/tmp` on Unix and `c:\windows\temp` on Windows. Temp files are given a unique folder under this root for each run of the program, and are deleted upon successful exit. -## More Information +### More Information When installing locally, npm first tries to find an appropriate `prefix` folder. This is so that `npm install foo@1.2.3` will install @@ -105,7 +111,7 @@ foo's dependencies are similarly unpacked into Any bin files are symlinked to `./node_modules/.bin/`, so that they may be found by npm scripts when necessary. -### Global Installation +#### Global Installation If the `global` configuration is set to true, then npm will install packages "globally". @@ -113,7 +119,7 @@ install packages "globally". For global installation, packages are installed roughly the same way, but using the folders described above. -### Cycles, Conflicts, and Folder Parsimony +#### Cycles, Conflicts, and Folder Parsimony Cycles are handled using the property of node's module system that it walks up the directories looking for `node_modules` folders. So, at every @@ -142,32 +148,36 @@ highest level possible, below the localized "target" folder. Consider this dependency graph: - foo - +-- blerg@1.2.5 - +-- bar@1.2.3 - | +-- blerg@1.x (latest=1.3.7) - | +-- baz@2.x - | | `-- quux@3.x - | | `-- bar@1.2.3 (cycle) - | `-- asdf@* - `-- baz@1.2.3 - `-- quux@3.x - `-- bar +```bash +foo ++-- blerg@1.2.5 ++-- bar@1.2.3 +| +-- blerg@1.x (latest=1.3.7) +| +-- baz@2.x +| | `-- quux@3.x +| | `-- bar@1.2.3 (cycle) +| `-- asdf@* +`-- baz@1.2.3 + `-- quux@3.x + `-- bar +``` In this case, we might expect a folder structure like this: - foo - +-- node_modules - +-- blerg (1.2.5) <---[A] - +-- bar (1.2.3) <---[B] - | `-- node_modules - | +-- baz (2.0.2) <---[C] - | | `-- node_modules - | | `-- quux (3.2.0) - | `-- asdf (2.3.4) - `-- baz (1.2.3) <---[D] - `-- node_modules - `-- quux (3.2.0) <---[E] +```bash +foo ++-- node_modules + +-- blerg (1.2.5) <---[A] + +-- bar (1.2.3) <---[B] + | `-- node_modules + | +-- baz (2.0.2) <---[C] + | | `-- node_modules + | | `-- quux (3.2.0) + | `-- asdf (2.3.4) + `-- baz (1.2.3) <---[D] + `-- node_modules + `-- quux (3.2.0) <---[E] +``` Since foo depends directly on `bar@1.2.3` and `baz@1.2.3`, those are installed in foo's `node_modules` folder. @@ -191,7 +201,7 @@ dependency on bar is satisfied by the parent folder copy installed at [B]. For a graphical breakdown of what is installed where, use `npm ls`. -### Publishing +#### Publishing Upon publishing, npm will look in the `node_modules` folder. If any of the items there are not in the `bundledDependencies` array, then they will @@ -199,15 +209,15 @@ not be included in the package tarball. This allows a package maintainer to install all of their dependencies (and dev dependencies) locally, but only re-publish those items that -cannot be found elsewhere. See `package.json(5)` for more information. - -## SEE ALSO - -* package.json(5) -* npm-install(1) -* npm-pack(1) -* npm-cache(1) -* npm-config(1) -* npmrc(5) -* npm-config(7) -* npm-publish(1) +cannot be found elsewhere. See [`package.json`](/configuring-npm/package.json) for more information. + +### See also + +* [package.json](/configuring-npm/package-json) +* [npm install](/cli-commands/npm-install) +* [npm pack](/cli-commands/npm-pack) +* [npm cache](/cli-commands/npm-cache) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [config](/using-npm/config) +* [npm publish](/cli-commands/npm-publish) diff --git a/deps/npm/docs/content/configuring-npm/install.md b/deps/npm/docs/content/configuring-npm/install.md new file mode 100644 index 00000000000000..31a316f8e06304 --- /dev/null +++ b/deps/npm/docs/content/configuring-npm/install.md @@ -0,0 +1,70 @@ +--- +section: configuring-npm +title: install +description: Download and install node and npm +--- + +# install(5) + +## Download and Install npm + +### Description + +To publish and install packages to and from the public npm registry, you must install Node.js and the npm command line interface using either a Node version manager or a Node installer. **We strongly recommend using a Node version manager to install Node.js and npm.** We do not recommend using a Node installer, since the Node installation process installs npm in a directory with local permissions and can cause permissions errors when you run npm packages globally. + +### Overview + +- [Checking your version of npm and Node.js](#checking-your-version-of-npm-and-node-js) +- [Using a Node version manager to install Node.js and npm](#using-a-node-version-manager-to-install-node-js-and-npm) +- [Using a Node installer to install Node.js and npm](#using-a-node-installer-to-install-node-js-and-npm) + +### Checking your version of npm and Node.js + +To see if you already have Node.js and npm installed and check the installed version, run the following commands: + +``` +node -v +npm -v +``` + +### Using a Node version manager to install Node.js and npm + +Node version managers allow you to install and switch between multiple versions of Node.js and npm on your system so you can test your applications on multiple versions of npm to ensure they work for users on different versions. + +#### OSX or Linux Node version managers + +* [nvm](https://github.com/creationix/nvm) +* [n](https://github.com/tj/n) + +#### Windows Node version managers + +* [nodist](https://github.com/marcelklehr/nodist) +* [nvm-windows](https://github.com/coreybutler/nvm-windows) + +### Using a Node installer to install Node.js and npm + +If you are unable to use a Node version manager, you can use a Node installer to install both Node.js and npm on your system. + +* [Node.js installer](https://nodejs.org/en/download/) +* [NodeSource installer](https://github.com/nodesource/distributions). If you use Linux, we recommend that you use a NodeSource installer. + +#### OS X or Windows Node installers + +If you're using OS X or Windows, use one of the installers from the [Node.js download page](https://nodejs.org/en/download/). Be sure to install the version labeled **LTS**. Other versions have not yet been tested with npm. + +#### Linux or other operating systems Node installers + +If you're using Linux or another operating system, use one of the following installers: + +- [NodeSource installer](https://github.com/nodesource/distributions) (recommended) +- One of the installers on the [Node.js download page](https://nodejs.org/en/download/) + +Or see [this page](https://nodejs.org/en/download/package-manager/) to install npm for Linux in the way many Linux developers prefer. + + +#### Less-common operating systems + +For more information on installing Node.js on a variety of operating systems, see [this page][pkg-mgr]. + + +[pkg-mgr]: https://nodejs.org/en/download/package-manager/ diff --git a/deps/npm/doc/files/npmrc.md b/deps/npm/docs/content/configuring-npm/npmrc.md similarity index 73% rename from deps/npm/doc/files/npmrc.md rename to deps/npm/docs/content/configuring-npm/npmrc.md index 0980c1090ad4c8..090ed5944fcce5 100644 --- a/deps/npm/doc/files/npmrc.md +++ b/deps/npm/docs/content/configuring-npm/npmrc.md @@ -1,7 +1,14 @@ -npmrc(5) -- The npm config files -================================ +--- +section: configuring-npm +title: npmrc +description: The npm config files +--- -## DESCRIPTION +# npmrc(5) + +## The npm config files + +### Description npm gets its config settings from the command line, environment variables, and `npmrc` files. @@ -9,9 +16,9 @@ variables, and `npmrc` files. The `npm config` command can be used to update and edit the contents of the user and global npmrc files. -For a list of available configuration options, see npm-config(7). +For a list of available configuration options, see [config](/using-npm/config). -## FILES +### Files The four relevant files are: @@ -24,7 +31,9 @@ All npm config files are an ini-formatted list of `key = value` parameters. Environment variables can be replaced using `${VARIABLE_NAME}`. For example: - prefix = ${HOME}/.npm-packages +```bash +prefix = ${HOME}/.npm-packages +``` Each of these files is loaded, and config options are resolved in priority order. For example, a setting in the userconfig file would @@ -33,8 +42,10 @@ override the setting in the globalconfig file. Array values are specified by adding "[]" after the key name. For example: - key[] = "first value" - key[] = "second value" +```bash +key[] = "first value" +key[] = "second value" +``` #### Comments @@ -42,11 +53,13 @@ Lines in `.npmrc` files are interpreted as comments when they begin with a `;` o For example: - # last modified: 01 Jan 2016 - ; Set a new registry for a scoped package - @myscope:registry=https://mycustomregistry.example.org +```bash +# last modified: 01 Jan 2016 +; Set a new registry for a scoped package +@myscope:registry=https://mycustomregistry.example.org +``` -### Per-project config file +#### Per-project config file When working locally in a project, a `.npmrc` file in the root of the project (ie, a sibling of `node_modules` and `package.json`) will set @@ -60,18 +73,18 @@ globally, or in a different location. Additionally, this file is not read in global mode, such as when running `npm install -g`. -### Per-user config file +#### Per-user config file `$HOME/.npmrc` (or the `userconfig` param, if set in the environment or on the command line) -### Global config file +#### Global config file `$PREFIX/etc/npmrc` (or the `globalconfig` param, if set above): This file is an ini-file formatted list of `key = value` parameters. Environment variables can be replaced as above. -### Built-in config file +#### Built-in config file `path/to/npm/itself/npmrc` @@ -81,10 +94,10 @@ script that comes with npm. This is primarily for distribution maintainers to override default configs in a standard and consistent manner. -## SEE ALSO +### See also -* npm-folders(5) -* npm-config(1) -* npm-config(7) -* package.json(5) -* npm(1) +* [npm folders](/configuring-npm/folders) +* [npm config](/cli-commands/npm-config) +* [config](/using-npm/config) +* [package.json](/configuring-npm/package-json) +* [npm](/cli-commands/npm) diff --git a/deps/npm/doc/files/package.json.md b/deps/npm/docs/content/configuring-npm/package-json.md similarity index 74% rename from deps/npm/doc/files/package.json.md rename to deps/npm/docs/content/configuring-npm/package-json.md index 6324caf64a5179..b7759f482f914a 100644 --- a/deps/npm/doc/files/package.json.md +++ b/deps/npm/docs/content/configuring-npm/package-json.md @@ -1,15 +1,22 @@ -package.json(5) -- Specifics of npm's package.json handling -=========================================================== +--- +section: configuring-npm +title: package.json +description: Specifics of npm's package.json handling +--- -## DESCRIPTION +# package.json(5) + +## Specifics of npm's package.json handling + +### Description This document is all you need to know about what's required in your package.json file. It must be actual JSON, not just a JavaScript object literal. A lot of the behavior described in this document is affected by the config -settings described in `npm-config(7)`. +settings described in [`config`](/using-npm/config). -## name +### name If you plan to publish your package, the *most* important things in your package.json are the name and version fields as they will be required. The name @@ -23,7 +30,7 @@ Some rules: * The name must be less than or equal to 214 characters. This includes the scope for scoped packages. -* The name can't start with a dot or an underscore. +* The names of scoped packages can begin with a dot or an underscore. This is not permitted without a scope. * New packages must not have uppercase letters in the name. * The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can't contain any non-URL-safe characters. @@ -40,9 +47,9 @@ Some tips: already, before you get too attached to it. A name can be optionally prefixed by a scope, e.g. `@myorg/mypackage`. See -`npm-scope(7)` for more detail. +[`scope`](/using-npm/scope) for more detail. -## version +### version If you plan to publish your package, the *most* important things in your package.json are the name and version fields as they will be required. The name @@ -54,27 +61,29 @@ Version must be parseable by [node-semver](https://github.com/isaacs/node-semver), which is bundled with npm as a dependency. (`npm install semver` to use it yourself.) -More on version numbers and ranges at semver(7). +More on version numbers and ranges at [semver](/using-npm/semver). -## description +### description Put a description in it. It's a string. This helps people discover your package, as it's listed in `npm search`. -## keywords +### keywords Put keywords in it. It's an array of strings. This helps people discover your package as it's listed in `npm search`. -## homepage +### homepage The url to the project homepage. Example: - "homepage": "https://github.com/owner/project#readme" +```json +"homepage": "https://github.com/owner/project#readme" +``` -## bugs +### bugs The url to your project's issue tracker and / or the email address to which issues should be reported. These are helpful for people who encounter issues @@ -82,16 +91,18 @@ with your package. It should look like this: - { "url" : "https://github.com/owner/project/issues" - , "email" : "project@hostname.com" - } +```json +{ "url" : "https://github.com/owner/project/issues" +, "email" : "project@hostname.com" +} +``` You can specify either one or both values. If you want to provide only a url, you can specify the value for "bugs" as a simple string instead of an object. If a url is provided, it will be used by the `npm bugs` command. -## license +### license You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you're placing on it. @@ -99,7 +110,9 @@ permitted to use it, and any restrictions you're placing on it. If you're using a common license such as BSD-2-Clause or MIT, add a current SPDX license identifier for the license you're using, like this: - { "license" : "BSD-3-Clause" } +```json +{ "license" : "BSD-3-Clause" } +``` You can check [the full list of SPDX license IDs](https://spdx.org/licenses/). Ideally you should pick one that is @@ -108,69 +121,100 @@ Ideally you should pick one that is If your package is licensed under multiple common licenses, use an [SPDX license expression syntax version 2.0 string](https://www.npmjs.com/package/spdx), like this: - { "license" : "(ISC OR GPL-3.0)" } - +```json +{ "license" : "(ISC OR GPL-3.0)" } +``` If you are using a license that hasn't been assigned an SPDX identifier, or if you are using a custom license, use a string value like this one: - { "license" : "SEE LICENSE IN " } - +```json +{ "license" : "SEE LICENSE IN " } +``` Then include a file named `` at the top level of the package. Some old packages used license objects or a "licenses" property containing an array of license objects: - // Not valid metadata - { "license" : - { "type" : "ISC" - , "url" : "https://opensource.org/licenses/ISC" - } - } +```json +// Not valid metadata +{ "license" : + { "type" : "ISC" + , "url" : "https://opensource.org/licenses/ISC" + } +} - // Not valid metadata - { "licenses" : - [ - { "type": "MIT" - , "url": "https://www.opensource.org/licenses/mit-license.php" - } - , { "type": "Apache-2.0" - , "url": "https://opensource.org/licenses/apache2.0.php" - } - ] +// Not valid metadata +{ "licenses" : + [ + { "type": "MIT" + , "url": "https://www.opensource.org/licenses/mit-license.php" + } + , { "type": "Apache-2.0" + , "url": "https://opensource.org/licenses/apache2.0.php" } + ] +} +``` Those styles are now deprecated. Instead, use SPDX expressions, like this: - { "license": "ISC" } +```json +{ "license": "ISC" } - { "license": "(MIT OR Apache-2.0)" } +{ "license": "(MIT OR Apache-2.0)" } +``` Finally, if you do not wish to grant others the right to use a private or unpublished package under any terms: - { "license": "UNLICENSED" } - +```json +{ "license": "UNLICENSED" } +``` Consider also setting `"private": true` to prevent accidental publication. -## people fields: author, contributors +### people fields: author, contributors The "author" is one person. "contributors" is an array of people. A "person" is an object with a "name" field and optionally "url" and "email", like this: - { "name" : "Barney Rubble" - , "email" : "b@rubble.com" - , "url" : "http://barnyrubble.tumblr.com/" - } +```json +{ "name" : "Barney Rubble" +, "email" : "b@rubble.com" +, "url" : "http://barnyrubble.tumblr.com/" +} +``` Or you can shorten that all into a single string, and npm will parse it for you: - "Barney Rubble (http://barnyrubble.tumblr.com/)" +```json +"Barney Rubble (http://barnyrubble.tumblr.com/)" +``` Both email and url are optional either way. npm also sets a top-level "maintainers" field with your npm user info. -## files +### funding + +You can specify an object containing an URL that provides up-to-date +information about ways to help fund development of your package: + + "funding": { + "type" : "individual", + "url" : "http://example.com/donate" + } + + "funding": { + "type" : "patreon", + "url" : "https://www.patreon.com/my-account" + } + +Users can use the `npm fund` subcommand to list the `funding` URLs of all +dependencies of their project, direct and indirect. A shortcut to visit each +funding url is also available when providing the project name such as: +`npm fund `. + +### files The optional `files` field is an array of file patterns that describes the entries to be included when your package is installed as a @@ -221,7 +265,7 @@ Conversely, some files are always ignored: * `*.orig` * `package-lock.json` (use shrinkwrap instead) -## main +### main The main field is a module ID that is the primary entry point to your program. That is, if your package is named `foo`, and a user installs it, and then does @@ -232,13 +276,13 @@ This should be a module ID relative to the root of your package folder. For most modules, it makes the most sense to have a main script and often not much else. -## browser +### browser If your module is meant to be used client-side the browser field should be used instead of the main field. This is helpful to hint users that it might rely on primitives that aren't available in Node.js modules. (e.g. `window`) -## bin +### bin A lot of packages have one or more executable files that they'd like to install into the PATH. npm makes this pretty easy (in fact, it uses this @@ -252,7 +296,9 @@ installs. For example, myapp could have this: - { "bin" : { "myapp" : "./cli.js" } } +```json +{ "bin" : { "myapp" : "./cli.js" } } +``` So, when you install myapp, it'll create a symlink from the `cli.js` script to `/usr/local/bin/myapp`. @@ -260,21 +306,25 @@ So, when you install myapp, it'll create a symlink from the `cli.js` script to If you have a single executable, and its name should be the name of the package, then you can just supply it as a string. For example: - { "name": "my-program" - , "version": "1.2.5" - , "bin": "./path/to/program" } +```json +{ "name": "my-program" +, "version": "1.2.5" +, "bin": "./path/to/program" } +``` would be the same as this: - { "name": "my-program" - , "version": "1.2.5" - , "bin" : { "my-program" : "./path/to/program" } } +```json +{ "name": "my-program" +, "version": "1.2.5" +, "bin" : { "my-program" : "./path/to/program" } } +``` Please make sure that your file(s) referenced in `bin` starts with `#!/usr/bin/env node`, otherwise the scripts are started without the node executable! -## man +### man Specify either a single file or an array of filenames to put in place for the `man` program to find. @@ -282,40 +332,45 @@ Specify either a single file or an array of filenames to put in place for the If only a single file is provided, then it's installed such that it is the result from `man `, regardless of its actual filename. For example: - { "name" : "foo" - , "version" : "1.2.3" - , "description" : "A packaged foo fooer for fooing foos" - , "main" : "foo.js" - , "man" : "./man/doc.1" - } +```json +{ "name" : "foo" +, "version" : "1.2.3" +, "description" : "A packaged foo fooer for fooing foos" +, "main" : "foo.js" +, "man" : "./man/doc.1" +} +``` would link the `./man/doc.1` file in such that it is the target for `man foo` If the filename doesn't start with the package name, then it's prefixed. So, this: - { "name" : "foo" - , "version" : "1.2.3" - , "description" : "A packaged foo fooer for fooing foos" - , "main" : "foo.js" - , "man" : [ "./man/foo.1", "./man/bar.1" ] - } +```json +{ "name" : "foo" +, "version" : "1.2.3" +, "description" : "A packaged foo fooer for fooing foos" +, "main" : "foo.js" +, "man" : [ "./man/foo.1", "./man/bar.1" ] +} +``` will create files to do `man foo` and `man foo-bar`. Man files must end with a number, and optionally a `.gz` suffix if they are compressed. The number dictates which man section the file is installed into. - { "name" : "foo" - , "version" : "1.2.3" - , "description" : "A packaged foo fooer for fooing foos" - , "main" : "foo.js" - , "man" : [ "./man/foo.1", "./man/foo.2" ] - } - +```json +{ "name" : "foo" +, "version" : "1.2.3" +, "description" : "A packaged foo fooer for fooing foos" +, "main" : "foo.js" +, "man" : [ "./man/foo.1", "./man/foo.2" ] +} +``` will create entries for `man foo` and `man 2 foo` -## directories +### directories The CommonJS [Packages](http://wiki.commonjs.org/wiki/Packages/1.0) spec details a few ways that you can indicate the structure of your package using a `directories` @@ -324,12 +379,12 @@ you'll see that it has directories for doc, lib, and man. In the future, this information may be used in other creative ways. -### directories.lib +#### directories.lib Tell people where the bulk of your library is. Nothing special is done with the lib folder in any way, but it's useful meta info. -### directories.bin +#### directories.bin If you specify a `bin` directory in `directories.bin`, all the files in that folder will be added. @@ -339,26 +394,26 @@ Because of the way the `bin` directive works, specifying both a specify individual files, use `bin`, and for all the files in an existing `bin` directory, use `directories.bin`. -### directories.man +#### directories.man A folder that is full of man pages. Sugar to generate a "man" array by walking the folder. -### directories.doc +#### directories.doc Put markdown files in here. Eventually, these will be displayed nicely, maybe, someday. -### directories.example +#### directories.example Put example scripts in here. Someday, it might be exposed in some clever way. -### directories.test +#### directories.test Put your tests in here. It is currently not exposed, but it might be in the future. -## repository +### repository Specify the place where your code lives. This is helpful for people who want to contribute. If the git repo is on GitHub, then the `npm docs` @@ -366,15 +421,17 @@ command will be able to find you. Do it like this: - "repository": { - "type" : "git", - "url" : "https://github.com/npm/cli.git" - } +```json +"repository": { + "type" : "git", + "url" : "https://github.com/npm/cli.git" +} - "repository": { - "type" : "svn", - "url" : "https://v8.googlecode.com/svn/trunk/" - } +"repository": { + "type" : "svn", + "url" : "https://v8.googlecode.com/svn/trunk/" +} +``` The URL should be a publicly available (perhaps read-only) url that can be handed directly to a VCS program without any modification. It should not be a url to an @@ -383,50 +440,56 @@ html project page that you put in your browser. It's for computers. For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same shortcut syntax you use for `npm install`: - "repository": "npm/npm" +```json +"repository": "npm/npm" - "repository": "github:user/repo" +"repository": "github:user/repo" - "repository": "gist:11081aaa281" +"repository": "gist:11081aaa281" - "repository": "bitbucket:user/repo" +"repository": "bitbucket:user/repo" - "repository": "gitlab:user/repo" +"repository": "gitlab:user/repo" +``` If the `package.json` for your package is not in the root directory (for example if it is part of a monorepo), you can specify the directory in which it lives: - "repository": { - "type" : "git", - "url" : "https://github.com/facebook/react.git", - "directory": "packages/react-dom" - } +```json +"repository": { + "type" : "git", + "url" : "https://github.com/facebook/react.git", + "directory": "packages/react-dom" +} +``` -## scripts +### scripts The "scripts" property is a dictionary containing script commands that are run at various times in the lifecycle of your package. The key is the lifecycle event, and the value is the command to run at that point. -See `npm-scripts(7)` to find out more about writing package scripts. +See [`scripts`](/using-npm/scripts) to find out more about writing package scripts. -## config +### config A "config" object can be used to set configuration parameters used in package scripts that persist across upgrades. For instance, if a package had the following: - { "name" : "foo" - , "config" : { "port" : "8080" } } +```json +{ "name" : "foo" +, "config" : { "port" : "8080" } } +``` and then had a "start" command that then referenced the `npm_package_config_port` environment variable, then the user could override that by doing `npm config set foo:port 8001`. -See `npm-config(7)` and `npm-scripts(7)` for more on package +See [`config`](/using-npm/config) and [`scripts`](/using-npm/scripts) for more on package configs. -## dependencies +### dependencies Dependencies are specified in a simple object that maps a package name to a version range. The version range is a string which has one or more @@ -436,15 +499,15 @@ tarball or git URL. **Please do not put test harnesses or transpilers in your `dependencies` object.** See `devDependencies`, below. -See semver(7) for more details about specifying version ranges. +See [semver](/using-npm/semver) for more details about specifying version ranges. * `version` Must match `version` exactly * `>version` Must be greater than `version` * `>=version` etc * `=1.0.2 <2.1.2" - , "baz" : ">1.0.2 <=2.3.4" - , "boo" : "2.0.1" - , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0" - , "asd" : "http://asdf.com/asdf.tar.gz" - , "til" : "~1.2" - , "elf" : "~1.2.3" - , "two" : "2.x" - , "thr" : "3.3.x" - , "lat" : "latest" - , "dyl" : "file:../dyl" - } - } +```json +{ "dependencies" : + { "foo" : "1.0.0 - 2.9999.9999" + , "bar" : ">=1.0.2 <2.1.2" + , "baz" : ">1.0.2 <=2.3.4" + , "boo" : "2.0.1" + , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0" + , "asd" : "http://asdf.com/asdf.tar.gz" + , "til" : "~1.2" + , "elf" : "~1.2.3" + , "two" : "2.x" + , "thr" : "3.3.x" + , "lat" : "latest" + , "dyl" : "file:../dyl" + } +} +``` -### URLs as Dependencies +#### URLs as Dependencies You may specify a tarball URL in place of a version range. This tarball will be downloaded and installed locally to your package at install time. -### Git URLs as Dependencies +#### Git URLs as Dependencies Git urls are of the form: - ://[[:]@][:][:][/][# | #semver:] +```bash +://[[:]@][:][:][/][# | #semver:] +``` `` is one of `git`, `git+ssh`, `git+http`, `git+https`, or `git+file`. @@ -499,54 +566,62 @@ specified, then `master` is used. Examples: - git+ssh://git@github.com:npm/cli.git#v1.0.27 - git+ssh://git@github.com:npm/cli#semver:^5.0 - git+https://isaacs@github.com/npm/cli.git - git://github.com/npm/cli.git#v1.0.27 +```bash +git+ssh://git@github.com:npm/cli.git#v1.0.27 +git+ssh://git@github.com:npm/cli#semver:^5.0 +git+https://isaacs@github.com/npm/cli.git +git://github.com/npm/cli.git#v1.0.27 +``` -### GitHub URLs +#### GitHub URLs As of version 1.1.65, you can refer to GitHub urls as just "foo": "user/foo-project". Just as with git URLs, a `commit-ish` suffix can be included. For example: - { - "name": "foo", - "version": "0.0.0", - "dependencies": { - "express": "expressjs/express", - "mocha": "mochajs/mocha#4727d357ea", - "module": "user/repo#feature\/branch" - } - } +```json +{ + "name": "foo", + "version": "0.0.0", + "dependencies": { + "express": "expressjs/express", + "mocha": "mochajs/mocha#4727d357ea", + "module": "user/repo#feature\/branch" + } +} +``` -### Local Paths +#### Local Paths As of version 2.0.0 you can provide a path to a local directory that contains a package. Local paths can be saved using `npm install -S` or `npm install --save`, using any of these forms: - ../foo/bar - ~/foo/bar - ./foo/bar - /foo/bar +```bash +../foo/bar +~/foo/bar +./foo/bar +/foo/bar +``` in which case they will be normalized to a relative path and added to your `package.json`. For example: - { - "name": "baz", - "dependencies": { - "bar": "file:../foo/bar" - } - } +```json +{ + "name": "baz", + "dependencies": { + "bar": "file:../foo/bar" + } +} +``` This feature is helpful for local offline development and creating tests that require npm installing where you don't want to hit an external server, but should not be used when publishing packages to the public registry. -## devDependencies +### devDependencies If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build @@ -557,7 +632,7 @@ object. These things will be installed when doing `npm link` or `npm install` from the root of a package, and can be managed like any other npm -configuration param. See `npm-config(7)` for more on the topic. +configuration param. See [`config`](/using-npm/config) for more on the topic. For build steps that are not platform-specific, such as compiling CoffeeScript or other languages to JavaScript, use the `prepare` @@ -565,24 +640,26 @@ script to do this, and make the required package a devDependency. For example: - { "name": "ethopia-waza", - "description": "a delightfully fruity coffee varietal", - "version": "1.2.3", - "devDependencies": { - "coffee-script": "~1.6.3" - }, - "scripts": { - "prepare": "coffee -o lib/ -c src/waza.coffee" - }, - "main": "lib/waza.js" - } +```json +{ "name": "ethopia-waza", + "description": "a delightfully fruity coffee varietal", + "version": "1.2.3", + "devDependencies": { + "coffee-script": "~1.6.3" + }, + "scripts": { + "prepare": "coffee -o lib/ -c src/waza.coffee" + }, + "main": "lib/waza.js" +} +``` The `prepare` script will be run before publishing, so that users can consume the functionality without requiring them to compile it themselves. In dev mode (ie, locally running `npm install`), it'll run this script as well, so that you can test it easily. -## peerDependencies +### peerDependencies In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a `require` of this host. @@ -591,20 +668,24 @@ a specific interface, expected and specified by the host documentation. For example: - { - "name": "tea-latte", - "version": "1.3.5", - "peerDependencies": { - "tea": "2.x" - } - } +```json +{ + "name": "tea-latte", + "version": "1.3.5", + "peerDependencies": { + "tea": "2.x" + } +} +``` This ensures your package `tea-latte` can be installed *along* with the second major version of the host package `tea` only. `npm install tea-latte` could possibly yield the following dependency graph: - ├── tea-latte@1.3.5 - └── tea@2.2.0 +```bash +├── tea-latte@1.3.5 +└── tea@2.2.0 +``` **NOTE: npm versions 1 and 2 will automatically install `peerDependencies` if they are not explicitly depended upon higher in the dependency tree. In the @@ -622,7 +703,7 @@ the host package's major version will break your plugin. Thus, if you've worked with every 1.x version of the host package, use `"^1.0"` or `"1.x"` to express this. If you depend on features introduced in 1.5.2, use `">= 1.5.2 < 2"`. -## bundledDependencies +### bundledDependencies This defines an array of package names that will be bundled when publishing the package. @@ -636,7 +717,7 @@ For example: If we define a package.json like this: -``` +```json { "name": "awesome-web-framework", "version": "1.0.0", @@ -653,7 +734,7 @@ any versions, as that information is specified in `dependencies`. If this is spelled `"bundleDependencies"`, then that is also honored. -## optionalDependencies +### optionalDependencies If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the `optionalDependencies` @@ -664,30 +745,34 @@ installation to fail. It is still your program's responsibility to handle the lack of the dependency. For example, something like this: - try { - var foo = require('foo') - var fooVersion = require('foo/package.json').version - } catch (er) { - foo = null - } - if ( notGoodFooVersion(fooVersion) ) { - foo = null - } +```js +try { + var foo = require('foo') + var fooVersion = require('foo/package.json').version +} catch (er) { + foo = null +} +if ( notGoodFooVersion(fooVersion) ) { + foo = null +} - // .. then later in your program .. +// .. then later in your program .. - if (foo) { - foo.doFooThings() - } +if (foo) { + foo.doFooThings() +} +``` Entries in `optionalDependencies` will override entries of the same name in `dependencies`, so it's usually best to only put in one place. -## engines +### engines You can specify the version of node that your stuff works on: - { "engines" : { "node" : ">=0.10.3 <0.12" } } +```json +{ "engines" : { "node" : ">=0.10.3 <0.12" } } +``` And, like with dependencies, if you don't specify the version (or if you specify "\*" as the version), then any version of node will do. @@ -699,49 +784,59 @@ that it works on node. You can also use the "engines" field to specify which versions of npm are capable of properly installing your program. For example: - { "engines" : { "npm" : "~1.0.20" } } +```json +{ "engines" : { "npm" : "~1.0.20" } } +``` Unless the user has set the `engine-strict` config flag, this field is advisory only and will only produce warnings when your package is installed as a dependency. -## engineStrict +### engineStrict **This feature was removed in npm 3.0.0** Prior to npm 3.0.0, this feature was used to treat this package as if the user had set `engine-strict`. It is no longer used. -## os +### os You can specify which operating systems your module will run on: - "os" : [ "darwin", "linux" ] +```json +"os" : [ "darwin", "linux" ] +``` You can also blacklist instead of whitelist operating systems, just prepend the blacklisted os with a '!': - "os" : [ "!win32" ] +```json +"os" : [ "!win32" ] +``` The host operating system is determined by `process.platform` It is allowed to both blacklist, and whitelist, although there isn't any good reason to do this. -## cpu +### cpu If your code only runs on certain cpu architectures, you can specify which ones. - "cpu" : [ "x64", "ia32" ] +```json +"cpu" : [ "x64", "ia32" ] +``` Like the `os` option, you can also blacklist architectures: - "cpu" : [ "!arm", "!mips" ] +```json +"cpu" : [ "!arm", "!mips" ] +``` The host architecture is determined by `process.arch` -## preferGlobal +### preferGlobal **DEPRECATED** @@ -749,7 +844,7 @@ This option used to trigger an npm warning, but it will no longer warn. It is purely there for informational purposes. It is now recommended that you install any binaries as local devDependencies wherever possible. -## private +### private If you set `"private": true` in your package.json, then npm will refuse to publish it. @@ -760,7 +855,7 @@ specific registry (for example, an internal registry), then use the `publishConfig` dictionary described below to override the `registry` config param at publish-time. -## publishConfig +### publishConfig This is a set of config values that will be used at publish-time. It's especially handy if you want to set the tag, registry or access, so that @@ -770,10 +865,10 @@ to the global public registry or that a scoped module is private by default. Any config values can be overridden, but only "tag", "registry" and "access" probably matter for the purposes of publishing. -See `npm-config(7)` to see the list of config options that can be +See [`config`](/using-npm/config) to see the list of config options that can be overridden. -## DEFAULT VALUES +### DEFAULT VALUES npm will default some values based on package contents. @@ -794,14 +889,13 @@ npm will default some values based on package contents. are optional. Lines which start with a `#` or are blank, will be ignored. -## SEE ALSO - -* semver(7) -* npm-init(1) -* npm-version(1) -* npm-config(1) -* npm-config(7) -* npm-help(1) -* npm-install(1) -* npm-publish(1) -* npm-uninstall(1) +### SEE ALSO + +* [semver](/using-npm/semver) +* [npm init](/cli-commands/npm-init) +* [npm version](/cli-commands/npm-version) +* [npm config](/cli-commands/npm-config) +* [npm help](/cli-commands/npm-help) +* [npm install](/cli-commands/npm-install) +* [npm publish](/cli-commands/npm-publish) +* [npm uninstall](/cli-commands/npm-uninstall) diff --git a/deps/npm/doc/files/package-lock.json.md b/deps/npm/docs/content/configuring-npm/package-lock-json.md similarity index 87% rename from deps/npm/doc/files/package-lock.json.md rename to deps/npm/docs/content/configuring-npm/package-lock-json.md index 1b4ba934971177..9f3ca4683defe7 100644 --- a/deps/npm/doc/files/package-lock.json.md +++ b/deps/npm/docs/content/configuring-npm/package-lock-json.md @@ -1,7 +1,14 @@ -package-lock.json(5) -- A manifestation of the manifest -===================================================== +--- +section: configuring-npm +title: package-lock.json +description: A manifestation of the manifest +--- -## DESCRIPTION +# package-lock.json(5) + +## A manifestation of the manifest + +### Description `package-lock.json` is automatically generated for any operations where npm modifies either the `node_modules` tree, or `package.json`. It describes the @@ -21,7 +28,7 @@ various purposes: One key detail about `package-lock.json` is that it cannot be published, and it will be ignored if found in any place other than the toplevel package. It shares -a format with npm-shrinkwrap.json(5), which is essentially the same file, but +a format with [npm-shrinkwrap.json](/configuring-npm/shrinkwrap-json), which is essentially the same file, but allows publication. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages. @@ -29,24 +36,24 @@ If both `package-lock.json` and `npm-shrinkwrap.json` are present in the root of a package, `package-lock.json` will be completely ignored. -## FILE FORMAT +### File Format -### name +#### name The name of the package this is a package-lock for. This must match what's in `package.json`. -### version +#### version The version of the package this is a package-lock for. This must match what's in `package.json`. -### lockfileVersion +#### lockfileVersion An integer version, starting at `1` with the version number of this document whose semantics were used when generating this `package-lock.json`. -### packageIntegrity +#### packageIntegrity This is a [subresource integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) value @@ -54,18 +61,18 @@ created from the `package.json`. No preprocessing of the `package.json` should be done. Subresource integrity strings can be produced by modules like [`ssri`](https://www.npmjs.com/package/ssri). -### preserveSymlinks +#### preserveSymlinks Indicates that the install was done with the environment variable `NODE_PRESERVE_SYMLINKS` enabled. The installer should insist that the value of this property match that environment variable. -### dependencies +#### dependencies A mapping of package name to dependency object. Dependency objects have the following properties: -#### version +##### version This is a specifier that uniquely identifies this package and should be usable in fetching a new copy of it. @@ -77,7 +84,7 @@ usable in fetching a new copy of it. * local tarball sources: This is the file URL of the tarball. (eg `file:///opt/storage/example-1.3.0.tgz`) * local link sources: This is the file URL of the link. (eg `file:libs/our-module`) -#### integrity +##### integrity This is a [Standard Subresource Integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) for this @@ -90,27 +97,27 @@ resource. the file. * For local tarball sources: This is an integrity field based on the SHA512 of the file. -#### resolved +##### resolved * For bundled dependencies this is not included, regardless of source. * For registry sources this is path of the tarball relative to the registry URL. If the tarball URL isn't on the same server as the registry URL then this is a complete URL. -#### bundled +##### bundled If true, this is the bundled dependency and will be installed by the parent module. When installing, this module will be extracted from the parent module during the extract phase, not installed as a separate dependency. -#### dev +##### dev If true then this dependency is either a development dependency ONLY of the top level module or a transitive dependency of one. This is false for dependencies that are both a development dependency of the top level and a transitive dependency of a non-development dependency of the top level. -#### optional +##### optional If true then this dependency is either an optional dependency ONLY of the top level module or a transitive dependency of one. This is false for @@ -121,7 +128,7 @@ All optional dependencies should be included even if they're uninstallable on the current platform. -#### requires +##### requires This is a mapping of module name to version. This is a list of everything this module requires, regardless of where it will be installed. The version @@ -129,14 +136,14 @@ should match via normal matching rules a dependency either in our `dependencies` or in a level higher than us. -#### dependencies +##### dependencies The dependencies of this dependency, exactly as at the top level. -## SEE ALSO +### See also -* npm-shrinkwrap(1) -* npm-shrinkwrap.json(5) -* npm-package-locks(5) -* package.json(5) -* npm-install(1) +* [npm shrinkwrap](/cli-commands/npm-shrinkwrap) +* [shrinkwrap.json](/configuring-npm/shrinkwrap-json) +* [package-locks](/configuring-npm/package-locks) +* [package.json](/configuring-npm/package-json) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/files/npm-package-locks.md b/deps/npm/docs/content/configuring-npm/package-locks.md similarity index 75% rename from deps/npm/doc/files/npm-package-locks.md rename to deps/npm/docs/content/configuring-npm/package-locks.md index cbb62bdc3841cb..de65e3c634f077 100644 --- a/deps/npm/doc/files/npm-package-locks.md +++ b/deps/npm/docs/content/configuring-npm/package-locks.md @@ -1,9 +1,16 @@ -npm-package-locks(5) -- An explanation of npm lockfiles -===================================================== +--- +section: configuring-npm +title: package-locks +description: An explanation of npm lockfiles +--- -## DESCRIPTION +# package-locks(5) -Conceptually, the "input" to npm-install(1) is a package.json(5), while its +## An explanation of npm lockfiles + +### Description + +Conceptually, the "input" to [`npm install`](/cli-commands/npm-install) is a [package.json](/configuring-npm/package-json), while its "output" is a fully-formed `node_modules` tree: a representation of the dependencies you declared. In an ideal world, npm would work like a pure function: the same `package.json` should produce the exact same `node_modules` @@ -20,44 +27,53 @@ unable to do this. There are multiple reasons for this: As an example, consider package A: - { - "name": "A", - "version": "0.1.0", - "dependencies": { - "B": "<0.1.0" - } - } +```json +{ + "name": "A", + "version": "0.1.0", + "dependencies": { + "B": "<0.1.0" + } +} +``` package B: - { - "name": "B", - "version": "0.0.1", - "dependencies": { - "C": "<0.1.0" - } - } +```json +{ + "name": "B", + "version": "0.0.1", + "dependencies": { + "C": "<0.1.0" + } +} +``` and package C: - - { - "name": "C", - "version": "0.0.1" - } +```json +{ + "name": "C", + "version": "0.0.1" +} +``` If these are the only versions of A, B, and C available in the registry, then a normal `npm install A` will install: - A@0.1.0 - `-- B@0.0.1 - `-- C@0.0.1 +```json +A@0.1.0 +`-- B@0.0.1 + `-- C@0.0.1 +``` However, if B@0.0.2 is published, then a fresh `npm install A` will install: - A@0.1.0 - `-- B@0.0.2 - `-- C@0.0.1 +```bash +A@0.1.0 +`-- B@0.0.2 + `-- C@0.0.1 +``` assuming the new version did not modify B's dependencies. Of course, the new version of B could include a new version of C and any number @@ -67,34 +83,35 @@ author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all. -To prevent this potential issue, npm uses package-lock.json(5) or, if present, -npm-shrinkwrap.json(5). These files are called package locks, or lockfiles. +To prevent this potential issue, npm uses [package-lock.json](/configuring-npm/package-lock-json) or, if present, [npm-shrinkwrap.json](/configuring-npm/shrinkwrap-json). These files are called package locks, or lockfiles. Whenever you run `npm install`, npm generates or updates your package lock, which will look something like this: - { - "name": "A", - "version": "0.1.0", - ...metadata fields... +```json +{ + "name": "A", + "version": "0.1.0", + ...metadata fields... + "dependencies": { + "B": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz", + "integrity": "sha512-DeAdb33F+" "dependencies": { - "B": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz", - "integrity": "sha512-DeAdb33F+" - "dependencies": { - "C": { - "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4" - } - } + "C": { + "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4" } } } + } +} +``` This file describes an *exact*, and more importantly *reproducible* `node_modules` tree. Once it's present, any future installation will base its work off this file, instead of recalculating dependency versions off -package.json(5). +[package.json](/configuring-npm/package-json). The presence of a package lock changes the installation behavior such that: @@ -113,12 +130,13 @@ executed afterwards. These scripts run for both `package-lock.json` and `npm-shrinkwrap.json`. For example to run some postprocessing on the generated file: - "scripts": { - "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\"" - } - +```json + "scripts": { + "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\"" + } +``` -### Using locked packages +#### Using locked packages Using a locked package is no different than using any package without a package lock: any commands that update `node_modules` and/or `package.json`'s @@ -136,7 +154,7 @@ on. Additionally, the diffs from these changes are human-readable and will inform you of any changes npm has made to your `node_modules`, so you can notice if any transitive dependencies were updated, hoisted, etc. -### Resolving lockfile conflicts +#### Resolving lockfile conflicts Occasionally, two separate npm install will create package locks that cause merge conflicts in source control systems. As of `npm@5.7.0`, these conflicts @@ -155,10 +173,10 @@ pre-`npm@5.7.0` versions of npm 5, albeit a bit more noisily. Note that if `package.json` itself conflicts, you will have to resolve that by hand and run `npm install` manually, even with the merge driver. -## SEE ALSO +### See Also * https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527 -* package.json(5) -* package-lock.json(5) -* npm-shrinkwrap.json(5) -* npm-shrinkwrap(1) +* [package.json](/configuring-npm/package-json) +* [package-lock.json](/configuring-npm/package-lock-json) +* [shrinkwrap.json](/configuring-npm/shrinkwrap-json) +* [npm shrinkwrap](/cli-commands/npm-shrinkwrap) diff --git a/deps/npm/doc/files/npm-shrinkwrap.json.md b/deps/npm/docs/content/configuring-npm/shrinkwrap-json.md similarity index 57% rename from deps/npm/doc/files/npm-shrinkwrap.json.md rename to deps/npm/docs/content/configuring-npm/shrinkwrap-json.md index 541a1f5a6d7656..bc5e061d55b095 100644 --- a/deps/npm/doc/files/npm-shrinkwrap.json.md +++ b/deps/npm/docs/content/configuring-npm/shrinkwrap-json.md @@ -1,9 +1,16 @@ -npm-shrinkwrap.json(5) -- A publishable lockfile -===================================================== +--- +section: configuring-npm +title: shrinkwrap.json +description: A publishable lockfile +--- -## DESCRIPTION +# npm-shrinkwrap.json(5) -`npm-shrinkwrap.json` is a file created by npm-shrinkwrap(1). It is identical to +## A publishable lockfile + +### Description + +`npm-shrinkwrap.json` is a file created by [`npm shrinkwrap`](/cli-commands/npm-shrinkwrap). It is identical to `package-lock.json`, with one major caveat: Unlike `package-lock.json`, `npm-shrinkwrap.json` may be included when publishing a package. @@ -17,11 +24,11 @@ Additionally, if both `package-lock.json` and `npm-shrinkwrap.json` are present in a package root, `package-lock.json` will be ignored in favor of this file. For full details and description of the `npm-shrinkwrap.json` file format, refer -to the manual page for package-lock.json(5). +to the manual page for [package-lock.json](/configuring-npm/package-lock-json). -## SEE ALSO +### See also -* npm-shrinkwrap(1) -* package-lock.json(5) -* package.json(5) -* npm-install(1) +* [npm shrinkwrap](/cli-commands/npm-shrinkwrap) +* [package-lock.json](/configuring-npm/package-lock-json) +* [package.json](/configuring-npm/package-json) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/misc/npm-config.md b/deps/npm/docs/content/using-npm/config.md similarity index 87% rename from deps/npm/doc/misc/npm-config.md rename to deps/npm/docs/content/using-npm/config.md index f1055a56edbc7b..a6947b17d58d15 100644 --- a/deps/npm/doc/misc/npm-config.md +++ b/deps/npm/docs/content/using-npm/config.md @@ -1,11 +1,18 @@ -npm-config(7) -- More than you probably want to know about npm configuration -============================================================================ +--- +section: using-npm +title: config +description: More than you probably want to know about npm configuration +--- -## DESCRIPTION +# config(7) + +## More than you probably want to know about npm configuration + +### Description npm gets its configuration values from the following sources, sorted by priority: -### Command Line Flags +#### Command Line Flags Putting `--foo bar` on the command line sets the `foo` configuration parameter to `"bar"`. A `--` argument tells the cli parser to stop @@ -18,7 +25,7 @@ and `flag2` to `bar`. Finally, `--flag1 --flag2 -- bar` will set both configuration parameters to `true`, and the `bar` is taken as a command argument. -### Environment Variables +#### Environment Variables Any environment variables that start with `npm_config_` will be interpreted as a configuration parameter. For example, putting @@ -26,7 +33,7 @@ interpreted as a configuration parameter. For example, putting configuration parameter to `bar`. Any environment configurations that are not given a value will be given the value of `true`. Config values are case-insensitive, so `NPM_CONFIG_FOO=bar` will work the -same. However, please note that inside [npm-scripts](/misc/scripts) +same. However, please note that inside [`scripts`](/using-npm/scripts) npm will set its own environment variables and Node will prefer those lowercase versions over any uppercase ones that you might set. For details see [this issue](https://github.com/npm/npm/issues/14528). @@ -34,7 +41,7 @@ For details see [this issue](https://github.com/npm/npm/issues/14528). Notice that you need to use underscores instead of dashes, so `--allow-same-version` would become `npm_config_allow_same_version=true`. -### npmrc Files +#### npmrc Files The four relevant files are: @@ -45,14 +52,14 @@ The four relevant files are: CLI option `--globalconfig` or environment variable `$NPM_CONFIG_GLOBALCONFIG`) * npm's built-in configuration file (`/path/to/npm/npmrc`) -See npmrc(5) for more details. +See [npmrc](/configuring-npm/npmrc) for more details. -### Default Configs +#### Default Configs Run `npm config ls -l` to see a set of configuration parameters that are internal to npm, and are defaults if nothing else is specified. -## Shorthands and Other CLI Niceties +### Shorthands and Other CLI Niceties The following shorthands are parsed on the command-line: @@ -85,43 +92,53 @@ If the specified configuration param resolves unambiguously to a known configuration parameter, then it is expanded to that configuration parameter. For example: - npm ls --par - # same as: - npm ls --parseable +```bash +npm ls --par +# same as: +npm ls --parseable +``` If multiple single-character shorthands are strung together, and the resulting combination is unambiguously not some other configuration param, then it is expanded to its various component pieces. For example: - npm ls -gpld - # same as: - npm ls --global --parseable --long --loglevel info +```bash +npm ls -gpld +# same as: +npm ls --global --parseable --long --loglevel info +``` -## Per-Package Config Settings +### Per-Package Config Settings -When running scripts (see `npm-scripts(7)`) the package.json "config" +When running scripts (see [`scripts`](/using-npm/scripts)) the package.json "config" keys are overwritten in the environment if there is a config param of `[@]:`. For example, if the package.json has this: - { "name" : "foo" - , "config" : { "port" : "8080" } - , "scripts" : { "start" : "node server.js" } } +```json +{ "name" : "foo" +, "config" : { "port" : "8080" } +, "scripts" : { "start" : "node server.js" } } +``` and the server.js is this: - http.createServer(...).listen(process.env.npm_package_config_port) +```javascript +http.createServer(...).listen(process.env.npm_package_config_port) +``` then the user could change the behavior by doing: - npm config set foo:port 80 +```bash +npm config set foo:port 80 +``` -See package.json(5) for more information. +See [package.json](/configuring-npm/package-json) for more information. -## Config Settings +### Config Settings -### access +#### access * Default: `restricted` * Type: Access @@ -131,7 +148,7 @@ you want your scoped package to be publicly viewable (and installable) set `--access=public`. The only valid values for `access` are `public` and `restricted`. Unscoped packages _always_ have an access level of `public`. -### allow-same-version +#### allow-same-version * Default: false * Type: Boolean @@ -139,7 +156,7 @@ you want your scoped package to be publicly viewable (and installable) set Prevents throwing an error when `npm version` is used to set the new version to the same value as the current version. -### always-auth +#### always-auth * Default: false * Type: Boolean @@ -147,7 +164,7 @@ to the same value as the current version. Force npm to always require authentication when accessing the registry, even for `GET` requests. -### also +#### also * Default: null * Type: String @@ -155,16 +172,16 @@ even for `GET` requests. When "dev" or "development" and running local `npm shrinkwrap`, `npm outdated`, or `npm update`, is an alias for `--dev`. -### audit +#### audit * Default: true * Type: Boolean When "true" submit audit reports alongside `npm install` runs to the default registry and all registries configured for scopes. See the documentation -for npm-audit(1) for details on what is submitted. +for [`npm audit`](/cli-commands/npm-audit) for details on what is submitted. -### audit-level +#### audit-level * Default: `"low"` * Type: `'low'`, `'moderate'`, `'high'`, `'critical'` @@ -172,14 +189,14 @@ for npm-audit(1) for details on what is submitted. The minimum level of vulnerability for `npm audit` to exit with a non-zero exit code. -### auth-type +#### auth-type * Default: `'legacy'` * Type: `'legacy'`, `'sso'`, `'saml'`, `'oauth'` What authentication strategy to use with `adduser`/`login`. -### before +#### before * Alias: enjoy-by * Default: null @@ -195,7 +212,7 @@ If the requested version is a `dist-tag` and the given tag does not pass the be used. For example, `foo@latest` might install `foo@1.2` even though `latest` is `2.0`. -### bin-links +#### bin-links * Default: `true` * Type: Boolean @@ -207,14 +224,14 @@ Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems. -### browser +#### browser * Default: OS X: `"open"`, Windows: `"start"`, Others: `"xdg-open"` * Type: String The browser that is called by the `npm docs` command to open websites. -### ca +#### ca * Default: The npm CA certificate * Type: String, Array or null @@ -223,19 +240,23 @@ The Certificate Authority signing certificate that is trusted for SSL connections to the registry. Values should be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the string "\n". For example: - ca="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" +```bash +ca="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" +``` Set to `null` to only allow "known" registrars, or to a specific CA cert to trust only that specific signing authority. Multiple CAs can be trusted by specifying an array of certificates: - ca[]="..." - ca[]="..." +```bash +ca[]="..." +ca[]="..." +``` See also the `strict-ssl` config. -### cafile +#### cafile * Default: `null` * Type: path @@ -244,35 +265,35 @@ A path to a file containing one or multiple Certificate Authority signing certificates. Similar to the `ca` setting, but allows for multiple CA's, as well as for the CA information to be stored in a file on disk. -### cache +#### cache * Default: Windows: `%AppData%\npm-cache`, Posix: `~/.npm` * Type: path -The location of npm's cache directory. See `npm-cache(1)` +The location of npm's cache directory. See [`npm cache`](/cli-commands/npm-cache) -### cache-lock-stale +#### cache-lock-stale * Default: 60000 (1 minute) * Type: Number The number of ms before cache folder lockfiles are considered stale. -### cache-lock-retries +#### cache-lock-retries * Default: 10 * Type: Number Number of times to retry to acquire a lock on cache folder lockfiles. -### cache-lock-wait +#### cache-lock-wait * Default: 10000 (10 seconds) * Type: Number Number of ms to wait for cache lock files to expire. -### cache-max +#### cache-max * Default: Infinity * Type: Number @@ -281,7 +302,7 @@ Number of ms to wait for cache lock files to expire. `--cache-max=0` is an alias for `--prefer-online`. -### cache-min +#### cache-min * Default: 10 * Type: Number @@ -290,7 +311,7 @@ Number of ms to wait for cache lock files to expire. `--cache-min=9999 (or bigger)` is an alias for `--prefer-offline`. -### cert +#### cert * Default: `null` * Type: String @@ -298,18 +319,20 @@ Number of ms to wait for cache lock files to expire. A client certificate to pass when accessing the registry. Values should be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the string "\n". For example: - cert="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" +```bash +cert="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----" +``` It is _not_ the path to a certificate file (and there is no "certfile" option). -### cidr +#### cidr * Default: `null` * Type: String, Array, null This is a list of CIDR address to be used when configuring limited access tokens with the `npm token create` command. -### color +#### color * Default: true * Type: Boolean or `"always"` @@ -320,7 +343,7 @@ If true, then only prints color codes for tty file descriptors. This option can also be changed using the environment: colors are disabled when the environment variable `NO_COLOR` is set to any value. -### depth +#### depth * Default: Infinity * Type: Number @@ -333,21 +356,21 @@ since that gives more useful information. To show the outdated status of all packages and dependents, use a large integer value, e.g., `npm outdated --depth 9999` -### description +#### description * Default: true * Type: Boolean Show the description in `npm search` -### dev +#### dev * Default: false * Type: Boolean Install `dev-dependencies` along with packages. -### dry-run +#### dry-run * Default: false * Type: Boolean @@ -358,7 +381,7 @@ commands that modify your local installation, eg, `install`, `update`, `dedupe`, `uninstall`. This is NOT currently honored by some network related commands, eg `dist-tags`, `owner`, etc. -### editor +#### editor * Default: `EDITOR` environment variable if set, or `"vi"` on Posix, or `"notepad"` on Windows. @@ -366,7 +389,7 @@ commands, eg `dist-tags`, `owner`, etc. The command to run for `npm edit` or `npm config edit`. -### engine-strict +#### engine-strict * Default: false * Type: Boolean @@ -375,7 +398,7 @@ If set to true, then npm will stubbornly refuse to install (or even consider installing) any package that claims to not be compatible with the current Node.js version. -### force +#### force * Default: false * Type: Boolean @@ -387,14 +410,14 @@ Makes various commands more forceful. * skips cache when requesting from the registry. * prevents checks against clobbering non-npm files. -### format-package-lock +#### format-package-lock * Default: true * Type: Boolean Format `package-lock.json` or `npm-shrinkwrap.json` as a human readable file. -### fetch-retries +#### fetch-retries * Default: 2 * Type: Number @@ -402,7 +425,7 @@ Format `package-lock.json` or `npm-shrinkwrap.json` as a human readable file. The "retries" config for the `retry` module to use when fetching packages from the registry. -### fetch-retry-factor +#### fetch-retry-factor * Default: 10 * Type: Number @@ -410,7 +433,7 @@ packages from the registry. The "factor" config for the `retry` module to use when fetching packages. -### fetch-retry-mintimeout +#### fetch-retry-mintimeout * Default: 10000 (10 seconds) * Type: Number @@ -418,7 +441,7 @@ packages. The "minTimeout" config for the `retry` module to use when fetching packages. -### fetch-retry-maxtimeout +#### fetch-retry-maxtimeout * Default: 60000 (1 minute) * Type: Number @@ -426,7 +449,16 @@ packages. The "maxTimeout" config for the `retry` module to use when fetching packages. -### git +#### fund + +* Default: true +* Type: Boolean + +When "true" displays the message at the end of each `npm install` +aknowledging the number of dependencies looking for funding. +See [`npm fund`](/cli-commands/npm-fund) for details. + +#### git * Default: `"git"` * Type: String @@ -435,42 +467,42 @@ The command to use for git commands. If git is installed on the computer, but is not in the `PATH`, then set this to the full path to the git binary. -### git-tag-version +#### git-tag-version * Default: `true` * Type: Boolean Tag the commit when using the `npm version` command. -### commit-hooks +#### commit-hooks * Default: `true` * Type: Boolean Run git commit hooks when using the `npm version` command. -### global +#### global * Default: false * Type: Boolean Operates in "global" mode, so that packages are installed into the `prefix` folder instead of the current working directory. See -`npm-folders(5)` for more on the differences in behavior. +[folders](/configuring-npm/folders) for more on the differences in behavior. * packages are installed into the `{prefix}/lib/node_modules` folder, instead of the current working directory. * bin files are linked to `{prefix}/bin` * man pages are linked to `{prefix}/share/man` -### globalconfig +#### globalconfig * Default: {prefix}/etc/npmrc * Type: path The config file to read for global config options. -### global-style +#### global-style * Default: false * Type: Boolean @@ -482,7 +514,7 @@ on will be flattened in their `node_modules` folders. This obviously will eliminate some deduping. If used with `legacy-bundling`, `legacy-bundling` will be preferred. -### group +#### group * Default: GID of the current process * Type: String or Number @@ -490,14 +522,14 @@ preferred. The group to use when running package scripts in global mode as the root user. -### heading +#### heading * Default: `"npm"` * Type: String The string that starts all the debugging log output. -### https-proxy +#### https-proxy * Default: null * Type: url @@ -506,7 +538,7 @@ A proxy to use for outgoing https requests. If the `HTTPS_PROXY` or `https_proxy` or `HTTP_PROXY` or `http_proxy` environment variables are set, proxy settings will be honored by the underlying `request` library. -### if-present +#### if-present * Default: false * Type: Boolean @@ -517,21 +549,21 @@ option can be used when it's desirable to optionally run a script when it's present and fail if the script fails. This is useful, for example, when running scripts that may only apply for some builds in an otherwise generic CI setup. -### ignore-prepublish +#### ignore-prepublish * Default: false * Type: Boolean If true, npm will not run `prepublish` scripts. -### ignore-scripts +#### ignore-scripts * Default: false * Type: Boolean If true, npm does not run scripts specified in package.json files. -### init-module +#### init-module * Default: ~/.npm-init.js * Type: path @@ -539,37 +571,37 @@ If true, npm does not run scripts specified in package.json files. A module that will be loaded by the `npm init` command. See the documentation for the [init-package-json](https://github.com/isaacs/init-package-json) module -for more information, or npm-init(1). +for more information, or [npm init](/cli-commands/npm-init). -### init-author-name +#### init-author-name * Default: "" * Type: String The value `npm init` should use by default for the package author's name. -### init-author-email +#### init-author-email * Default: "" * Type: String The value `npm init` should use by default for the package author's email. -### init-author-url +#### init-author-url * Default: "" * Type: String The value `npm init` should use by default for the package author's homepage. -### init-license +#### init-license * Default: "ISC" * Type: String The value `npm init` should use by default for the package license. -### init-version +#### init-version * Default: "1.0.0" * Type: semver @@ -577,7 +609,7 @@ The value `npm init` should use by default for the package license. The value that `npm init` should use by default for the package version number, if not already set in package.json. -### json +#### json * Default: false * Type: Boolean @@ -588,7 +620,7 @@ This feature is currently experimental, and the output data structures for many commands is either not implemented in JSON yet, or subject to change. Only the output from `npm ls --json` and `npm search --json` are currently valid. -### key +#### key * Default: `null` * Type: String @@ -596,11 +628,13 @@ output from `npm ls --json` and `npm search --json` are currently valid. A client key to pass when accessing the registry. Values should be in PEM format with newlines replaced by the string "\n". For example: - key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----" +```json +key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----" +``` It is _not_ the path to a key file (and there is no "keyfile" option). -### legacy-bundling +#### legacy-bundling * Default: false * Type: Boolean @@ -610,7 +644,7 @@ such as the one included with node 0.8, can install the package. This eliminates all automatic deduping. If used with `global-style` this option will be preferred. -### link +#### link * Default: false * Type: Boolean @@ -626,7 +660,7 @@ if one of the two conditions are met: * the globally installed version is identical to the version that is being installed locally. -### local-address +#### local-address * Default: undefined * Type: IP Address @@ -634,7 +668,7 @@ if one of the two conditions are met: The IP address of the local interface to use when making connections to the npm registry. Must be IPv4 in versions of Node prior to 0.12. -### loglevel +#### loglevel * Default: "notice" * Type: String @@ -646,7 +680,7 @@ What level of logs to report. On failure, *all* logs are written to Any logs of a higher level than the setting are shown. The default is "notice". -### logstream +#### logstream * Default: process.stderr * Type: Stream @@ -661,21 +695,21 @@ stderr. If the `color` config is set to true, then this stream will receive colored output if it is a TTY. -### logs-max +#### logs-max * Default: 10 * Type: Number The maximum number of log files to store. -### long +#### long * Default: false * Type: Boolean Show extended information in `npm ls` and `npm search`. -### maxsockets +#### maxsockets * Default: 50 * Type: Number @@ -683,7 +717,7 @@ Show extended information in `npm ls` and `npm search`. The maximum number of connections to use per origin (protocol/host/port combination). Passed to the `http` `Agent` used to make the request. -### message +#### message * Default: "%s" * Type: String @@ -692,14 +726,14 @@ Commit message which is used by `npm version` when creating version commit. Any "%s" in the message will be replaced with the version number. -### metrics-registry +#### metrics-registry * Default: The value of `registry` (which defaults to "https://registry.npmjs.org/") * Type: String The registry you want to send cli metrics to if `send-metrics` is true. -### node-options +#### node-options * Default: null * Type: String @@ -708,21 +742,21 @@ Options to pass through to Node.js via the `NODE_OPTIONS` environment variable. This does not impact how npm itself is executed but it does impact how lifecycle scripts are called. -### node-version +#### node-version * Default: process.version * Type: semver or false The node version to use when checking a package's `engines` map. -### noproxy +#### noproxy * Default: null * Type: String or Array A comma-separated string or an array of domain extensions that a proxy should not be used for. -### offline +#### offline * Default: false * Type: Boolean @@ -730,7 +764,7 @@ A comma-separated string or an array of domain extensions that a proxy should no Force offline mode: no network requests will be done during install. To allow the CLI to fill in missing cache data, see `--prefer-offline`. -### onload-script +#### onload-script * Default: false * Type: path @@ -738,7 +772,7 @@ the CLI to fill in missing cache data, see `--prefer-offline`. A node module to `require()` when npm loads. Useful for programmatic usage. -### only +#### only * Default: null * Type: String @@ -756,7 +790,7 @@ installed. When "prod" or "production" and running local `npm ls`, `npm outdated`, or `npm update`, is an alias for `--production`. -### optional +#### optional * Default: true * Type: Boolean @@ -765,7 +799,7 @@ Attempt to install packages in the `optionalDependencies` object. Note that if these packages fail to install, the overall installation process is not aborted. -### otp +#### otp * Default: null * Type: Number @@ -773,7 +807,7 @@ process is not aborted. This is a one-time password from a two-factor authenticator. It's needed when publishing or changing package permissions with `npm access`. -### package-lock +#### package-lock * Default: true * Type: Boolean @@ -787,7 +821,7 @@ package-locks disabled use `npm prune`. This option is an alias for `--shrinkwrap`. -### package-lock-only +#### package-lock-only * Default: false * Type: Boolean @@ -795,7 +829,7 @@ This option is an alias for `--shrinkwrap`. If set to true, it will update only the `package-lock.json`, instead of checking `node_modules` and downloading dependencies. -### parseable +#### parseable * Default: false * Type: Boolean @@ -803,7 +837,7 @@ instead of checking `node_modules` and downloading dependencies. Output parseable results from commands that write to standard output. For `npm search`, this will be tab-separated table format. -### prefer-offline +#### prefer-offline * Default: false * Type: Boolean @@ -813,7 +847,7 @@ will be requested from the server. To force full offline mode, use `--offline`. This option is effectively equivalent to `--cache-min=9999999`. -### prefer-online +#### prefer-online * Default: false * Type: Boolean @@ -821,15 +855,15 @@ This option is effectively equivalent to `--cache-min=9999999`. If true, staleness checks for cached data will be forced, making the CLI look for updates immediately even for fresh package data. -### prefix +#### prefix -* Default: see npm-folders(5) +* Default: see [folders](/configuring-npm/folders) * Type: path The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder. -### preid +#### preid * Default: "" * Type: String @@ -837,7 +871,7 @@ it forces non-global commands to run in the specified folder. The "prerelease identifier" to use as a prefix for the "prerelease" part of a semver. Like the `rc` in `1.2.0-rc.8`. -### production +#### production * Default: false * Type: Boolean @@ -848,7 +882,7 @@ Set to true to run in "production" mode. local `npm install` without any arguments. 2. Set the NODE_ENV="production" for lifecycle scripts. -### progress +#### progress * Default: true, unless TRAVIS or CI env vars set. * Type: Boolean @@ -858,7 +892,7 @@ operations, if `process.stderr` is a TTY. Set to `false` to suppress the progress bar. -### proxy +#### proxy * Default: null * Type: url @@ -867,35 +901,35 @@ A proxy to use for outgoing http requests. If the `HTTP_PROXY` or `http_proxy` environment variables are set, proxy settings will be honored by the underlying `request` library. -### read-only +#### read-only * Default: false * Type: Boolean This is used to mark a token as unable to publish when configuring limited access tokens with the `npm token create` command. -### rebuild-bundle +#### rebuild-bundle * Default: true * Type: Boolean Rebuild bundled dependencies after installation. -### registry +#### registry * Default: https://registry.npmjs.org/ * Type: url The base URL of the npm package registry. -### rollback +#### rollback * Default: true * Type: Boolean Remove failed installs. -### save +#### save * Default: true * Type: Boolean @@ -907,7 +941,7 @@ object. Only works if there is already a package.json file present. -### save-bundle +#### save-bundle * Default: false * Type: Boolean @@ -919,7 +953,7 @@ If a package would be saved at install time by the use of `--save`, When used with the `npm rm` command, it removes it from the bundledDependencies list. -### save-prod +#### save-prod * Default: false * Type: Boolean @@ -930,7 +964,7 @@ is useful if a package already exists in `devDependencies` or also the default behavior if `--save` is true, and neither `--save-dev` or `--save-optional` are true. -### save-dev +#### save-dev * Default: false * Type: Boolean @@ -942,7 +976,7 @@ When used with the `npm rm` command, it removes it from the Only works if there is already a package.json file present. -### save-exact +#### save-exact * Default: false * Type: Boolean @@ -951,7 +985,7 @@ Dependencies saved to package.json using `--save`, `--save-dev` or `--save-optional` will be configured with an exact version rather than using npm's default semver range operator. -### save-optional +#### save-optional * Default: false * Type: Boolean @@ -964,7 +998,7 @@ When used with the `npm rm` command, it removes it from the Only works if there is already a package.json file present. -### save-prefix +#### save-prefix * Default: '^' * Type: String @@ -977,7 +1011,7 @@ set to `^1.2.3` which allows minor upgrades for that package, but after `npm config set save-prefix='~'` it would be set to `~1.2.3` which only allows patch upgrades. -### scope +#### scope * Default: the scope of the current project, if any, or "" * Type: String @@ -988,14 +1022,14 @@ in to a private registry for the first time: will cause `@organization` to be mapped to the registry for future installation of packages specified according to the pattern `@organization/package`. -### script-shell +#### script-shell * Default: `null` * Type: path The shell to use for scripts run with the `npm run` command. -### scripts-prepend-node-path +#### scripts-prepend-node-path * Default: "warn-only" * Type: Boolean, `"auto"` or `"warn-only"` @@ -1015,21 +1049,21 @@ If set to `auto`, only add that directory to the `PATH` environment variable if the `node` executable with which `npm` was invoked and the one that is found first on the `PATH` are different. -### searchexclude +#### searchexclude * Default: "" * Type: String Space-separated options that limit the results from search. -### searchopts +#### searchopts * Default: "" * Type: String Space-separated options that are always passed to search. -### searchlimit +#### searchlimit * Default: 20 * Type: Number @@ -1037,7 +1071,7 @@ Space-separated options that are always passed to search. Number of items to limit search results to. Will not apply at all to legacy searches. -### searchstaleness +#### searchstaleness * Default: 900 (15 minutes) * Type: Number @@ -1045,7 +1079,7 @@ searches. The age of the cache, in seconds, before another registry request is made if using legacy search endpoint. -### send-metrics +#### send-metrics * Default: false * Type: Boolean @@ -1055,7 +1089,7 @@ If true, success/failure metrics will be reported to the registry stored in failing runs of the npm CLI and the time period overwhich those counts were gathered. No identifying information is included in these requests. -### shell +#### shell * Default: SHELL environment variable, or "bash" on Posix, or "cmd" on Windows @@ -1063,7 +1097,7 @@ gathered. No identifying information is included in these requests. The shell to run for the `npm explore` command. -### shrinkwrap +#### shrinkwrap * Default: true * Type: Boolean @@ -1073,7 +1107,7 @@ will also prevent _writing_ `npm-shrinkwrap.json` if `save` is true. This option is an alias for `--package-lock`. -### sign-git-commit +#### sign-git-commit * Default: false * Type: Boolean @@ -1084,7 +1118,7 @@ version using `-S` to add a signature. Note that git requires you to have set up GPG keys in your git configs for this to work properly. -### sign-git-tag +#### sign-git-tag * Default: false * Type: Boolean @@ -1095,7 +1129,7 @@ using `-s` to add a signature. Note that git requires you to have set up GPG keys in your git configs for this to work properly. -### sso-poll-frequency +#### sso-poll-frequency * Default: 500 * Type: Number @@ -1103,14 +1137,14 @@ for this to work properly. When used with SSO-enabled `auth-type`s, configures how regularly the registry should be polled while the user is completing authentication. -### sso-type +#### sso-type * Default: 'oauth' * Type: 'oauth', 'saml', or null If `--auth-type=sso`, the type of SSO type to use. -### strict-ssl +#### strict-ssl * Default: true * Type: Boolean @@ -1120,7 +1154,7 @@ registry via https. See also the `ca` config. -### tag +#### tag * Default: latest * Type: String @@ -1131,7 +1165,7 @@ it will install the specified tag. Also the tag that is added to the package@version specified by the `npm tag` command, if no explicit tag is given. -### tag-version-prefix +#### tag-version-prefix * Default: `"v"` * Type: String @@ -1144,7 +1178,7 @@ Because other tools may rely on the convention that npm version tags look like `v1.0.0`, _only use this property if it is absolutely necessary_. In particular, use care when overriding this setting for public packages. -### timing +#### timing * Default: `false` * Type: Boolean @@ -1155,7 +1189,7 @@ list of JSON objects. You can quickly view it with this [json](https://www.npmjs.com/package/json) command line: `json -g < ~/.npm/_timing.json`. -### tmp +#### tmp * Default: TMPDIR environment variable, or "/tmp" * Type: path @@ -1163,7 +1197,7 @@ list of JSON objects. You can quickly view it with this Where to store temporary files and folders. All temp files are deleted on success, but left behind on failure for forensic purposes. -### unicode +#### unicode * Default: false on windows, true on mac/unix systems with a unicode locale * Type: Boolean @@ -1171,7 +1205,7 @@ on success, but left behind on failure for forensic purposes. When set to true, npm uses unicode characters in the tree output. When false, it uses ascii characters to draw trees. -### unsafe-perm +#### unsafe-perm * Default: false if running as root, true otherwise * Type: Boolean @@ -1180,7 +1214,7 @@ Set to true to suppress the UID/GID switching when running package scripts. If set explicitly to false, then installing as a non-root user will fail. -### update-notifier +#### update-notifier * Default: true * Type: Boolean @@ -1188,29 +1222,29 @@ will fail. Set to false to suppress the update notification when using an older version of npm than the latest. -### usage +#### usage * Default: false * Type: Boolean Set to show short usage output (like the -H output) -instead of complete help when doing `npm-help(1)`. +instead of complete help when doing [`npm help`](/cli-commands/npm-help). -### user +#### user * Default: "nobody" * Type: String or Number The UID to set to when running package scripts as root. -### userconfig +#### userconfig * Default: ~/.npmrc * Type: path The location of user-level configuration settings. -### umask +#### umask * Default: 022 * Type: Octal numeric string in range 0000..0777 (0..511) @@ -1222,14 +1256,14 @@ Folders and executables are given a mode which is `0777` masked against this value. Other files are given a mode which is `0666` masked against this value. Thus, the defaults are `0755` and `0644` respectively. -### user-agent +#### user-agent * Default: node/{process.version} {process.platform} {process.arch} * Type: String Sets a User-Agent to the request header -### version +#### version * Default: false * Type: boolean @@ -1238,7 +1272,7 @@ If true, output the npm version and exit successfully. Only relevant when specified explicitly on the command line. -### versions +#### versions * Default: false * Type: boolean @@ -1248,7 +1282,7 @@ exit successfully. Only relevant when specified explicitly on the command line. -### viewer +#### viewer * Default: "man" on Posix, "browser" on Windows * Type: path @@ -1257,10 +1291,10 @@ The program to use to view help content. Set to `"browser"` to view html help content in the default web browser. -## SEE ALSO +### See also -* npm-config(1) -* npmrc(5) -* npm-scripts(7) -* npm-folders(5) -* npm(1) +* [npm config](/cli-commands/npm-config) +* [npmrc](/configuring-npm/npmrc) +* [npm scripts](/using-npm/scripts) +* [npm folders](/configuring-npm/folders) +* [npm](/cli-commands/npm) diff --git a/deps/npm/doc/misc/npm-developers.md b/deps/npm/docs/content/using-npm/developers.md similarity index 81% rename from deps/npm/doc/misc/npm-developers.md rename to deps/npm/docs/content/using-npm/developers.md index 55c8d9b08d1316..80b7fee6a544d4 100644 --- a/deps/npm/doc/misc/npm-developers.md +++ b/deps/npm/docs/content/using-npm/developers.md @@ -1,7 +1,14 @@ -npm-developers(7) -- Developer Guide -==================================== +--- +section: using-npm +title: developers +description: Developer Guide +--- -## DESCRIPTION +# developers(7) + +## Developer Guide + +### Description So, you've decided to use npm to develop (and maybe publish/deploy) your project. @@ -11,13 +18,13 @@ Fantastic! There are a few things that you need to do above the simple steps that your users will do to install your program. -## About These Documents +### About These Documents These are man pages. If you install npm, you should be able to then do `man npm-thing` to get the documentation on a particular topic, or `npm help thing` to see the same information. -## What is a `package` +### What is a package A package is: @@ -36,20 +43,22 @@ after packing it up into a tarball (b). Git urls can be of the form: - git://github.com/user/project.git#commit-ish - git+ssh://user@hostname:project.git#commit-ish - git+http://user@hostname/project/blah.git#commit-ish - git+https://user@hostname/project/blah.git#commit-ish +```bash +git://github.com/user/project.git#commit-ish +git+ssh://user@hostname:project.git#commit-ish +git+http://user@hostname/project/blah.git#commit-ish +git+https://user@hostname/project/blah.git#commit-ish +``` The `commit-ish` can be any tag, sha, or branch which can be supplied as an argument to `git checkout`. The default is `master`. -## The package.json File +### The package.json File You need to have a `package.json` file in the root of your project to do much of anything with npm. That is basically the whole interface. -See `package.json(5)` for details about what goes in that file. At the very +See [`package.json`](/configuring-npm/package-json) for details about what goes in that file. At the very least, you need: * name: @@ -78,7 +87,7 @@ least, you need: If you have a special compilation or installation script, then you should put it in the `scripts` object. You should definitely have at least a basic smoke-test command as the "scripts.test" field. - See npm-scripts(7). + See [scripts](/using-npm/scripts). * main: If you have a single module that serves as the entry point to your @@ -91,10 +100,10 @@ least, you need: they'll get installed just like these ones. You can use `npm init` in the root of your package in order to get you -started with a pretty basic package.json file. See `npm-init(1)` for +started with a pretty basic package.json file. See [`npm init`](/cli-commands/npm-init) for more info. -## Keeping files *out* of your package +### Keeping files *out* of your package Use a `.npmignore` file to keep stuff out of your package. If there's no `.npmignore` file, but there *is* a `.gitignore` file, then npm will @@ -146,23 +155,23 @@ property of `package.json`, which is an array of file or directory names that should be included in your package. Sometimes a whitelist is easier to manage than a blacklist. -### Testing whether your `.npmignore` or `files` config works +#### Testing whether your `.npmignore` or `files` config works If you want to double check that your package will include only the files you intend it to when published, you can run the `npm pack` command locally which will generate a tarball in the working directory, the same way it does for publishing. -## Link Packages +### Link Packages `npm link` is designed to install a development package and see the changes in real time without having to keep re-installing it. (You do need to either re-link or `npm rebuild -g` to update compiled packages, of course.) -More info at `npm-link(1)`. +More info at [`npm link`](/cli-commands/npm-link). -## Before Publishing: Make Sure Your Package Installs and Works +### Before Publishing: Make Sure Your Package Installs and Works **This is important.** @@ -173,40 +182,50 @@ So don't do that. In the root of your package, do this: - npm install . -g +```bash +npm install . -g +``` That'll show you that it's working. If you'd rather just create a symlink package that points to your working directory, then do this: - npm link +```bash +npm link +``` Use `npm ls -g` to see if it's there. To test a local install, go into some other folder, and then do: - cd ../some-other-folder - npm install ../my-package +```bash +cd ../some-other-folder +npm install ../my-package +``` to install it locally into the node_modules folder in that other place. Then go into the node-repl, and try using require("my-thing") to bring in your module's main module. -## Create a User Account +### Create a User Account Create a user with the adduser command. It works like this: - npm adduser +```bash +npm adduser +``` and then follow the prompts. -This is documented better in npm-adduser(1). +This is documented better in [npm adduser](/cli-commands/npm-adduser). -## Publish your package +### Publish your package This part's easy. In the root of your folder, do this: - npm publish +```bash +npm publish +``` You can give publish a url to a tarball, or a filename of a tarball, or a path to a folder. @@ -216,18 +235,18 @@ by default. So, if you have secret stuff in there, use a `.npmignore` file to list out the globs to ignore, or publish from a fresh checkout. -## Brag about it +### Brag about it Send emails, write blogs, blab in IRC. Tell the world how easy it is to install your program! -## SEE ALSO +### See also -* npm(1) -* npm-init(1) -* package.json(5) -* npm-scripts(7) -* npm-publish(1) -* npm-adduser(1) -* npm-registry(7) +* [npm](/cli-commands/npm) +* [npm init](/cli-commands/npm-init) +* [package.json](/configuring-npm/package-json) +* [npm scripts](/using-npm/scripts) +* [npm publish](/cli-commands/npm-publish) +* [npm adduser](/cli-commands/npm-adduser) +* [npm registry](/using-npm/registry) diff --git a/deps/npm/doc/misc/npm-disputes.md b/deps/npm/docs/content/using-npm/disputes.md similarity index 94% rename from deps/npm/doc/misc/npm-disputes.md rename to deps/npm/docs/content/using-npm/disputes.md index 8c9f0489f9238c..65751618cab8ae 100644 --- a/deps/npm/doc/misc/npm-disputes.md +++ b/deps/npm/docs/content/using-npm/disputes.md @@ -1,5 +1,12 @@ -npm-disputes(7) -- Handling Module Name Disputes -================================================ +--- +section: using-npm +title: disputes +description: Handling Module Name Disputes +--- + +# disputes(7) + +## Handling Module Name Disputes This document describes the steps that you should take to resolve module name disputes with other npm publishers. It also describes special steps you should @@ -10,7 +17,7 @@ This document is a clarification of the acceptable behavior outlined in the this document should be interpreted to contradict any aspect of the npm Code of Conduct. -## TL;DR +### TL;DR 1. Get the author email with `npm owner ls ` 2. Email the author, CC @@ -18,7 +25,7 @@ Conduct. Don't squat on package names. Publish code or move out of the way. -## DESCRIPTION +### Description There sometimes arise cases where a user publishes a module, and then later, some other user wants to use that name. Here are some common ways that happens @@ -57,7 +64,7 @@ some other user wants to use that name. Here are some common ways that happens and we'll sort it out. ("Reasonable" is usually at least 4 weeks.) -## REASONING +### Reasoning In almost every case so far, the parties involved have been able to reach an amicable resolution without any major intervention. Most people really do want @@ -69,7 +76,7 @@ is going to make most people quite upset, regardless of the justification. When humans solve their problems by talking to other humans with respect, everyone has the chance to end up feeling good about the interaction. -## EXCEPTIONS +### Exceptions Some things are not allowed, and will be removed without discussion if they are brought to the attention of the npm registry admins, including but not limited @@ -98,7 +105,7 @@ If you see bad behavior like this, please report it to right away. **You are never expected to resolve abusive behavior on your own. We are here to help.** -## TRADEMARKS +### Trademarkss If you think another npm publisher is infringing your trademark, such as by using a confusingly similar package name, email with a link to @@ -111,20 +118,20 @@ name to you. Otherwise, we will contact the package publisher and ask them to clear up any confusion with changes to their package's `README` file or metadata. -## CHANGES +### Changes This is a living document and may be updated from time to time. Please refer to the [git history for this document](https://github.com/npm/cli/commits/latest/doc/misc/npm-disputes.md) to view the changes. -## LICENSE +### License Copyright (C) npm, Inc., All rights reserved This document may be reused under a Creative Commons Attribution-ShareAlike License. -## SEE ALSO +### See also -* npm-registry(7) -* npm-owner(1) +* [npm registry](/using-npm/registry) +* [npm owner](/cli-commands/npm-owner) diff --git a/deps/npm/doc/misc/npm-orgs.md b/deps/npm/docs/content/using-npm/orgs.md similarity index 74% rename from deps/npm/doc/misc/npm-orgs.md rename to deps/npm/docs/content/using-npm/orgs.md index 3db22f8c7eab49..9709a12d726752 100644 --- a/deps/npm/doc/misc/npm-orgs.md +++ b/deps/npm/docs/content/using-npm/orgs.md @@ -1,7 +1,14 @@ -npm-orgs(7) -- Working with Teams & Orgs -======================================== +--- +section: using-npm +title: orgs +description: Working with Teams & Orgs +--- -## DESCRIPTION +# orgs(7) + +## Working with Teams & Orgs + +### Description There are three levels of org users: @@ -17,14 +24,14 @@ The developer will be able to access packages based on the teams they are on. Ac There are two main commands: -1. `npm team` see npm-team(1) for more details -2. `npm access` see npm-access(1) for more details +1. `npm team` see [npm team](/cli-commands/npm-team) for more details +2. `npm access` see [npm access](/cli-commands/npm-access) for more details -## Team Admins create teams +### Team Admins create teams * Check who you’ve added to your org: -``` +```bash npm team ls :developers ``` @@ -32,59 +39,59 @@ npm team ls :developers * Create a new team: -``` +```bash npm team create ``` * Add members to that team: -``` +```bash npm team add ``` -## Publish a package and adjust package access +### Publish a package and adjust package access * In package directory, run -``` +```bash npm init --scope= ``` to scope it for your org & publish as usual * Grant access: -``` +```bash npm access grant [] ``` * Revoke access: -``` +```bash npm access revoke [] ``` -## Monitor your package access +### Monitor your package access * See what org packages a team member can access: -``` +```bash npm access ls-packages ``` * See packages available to a specific team: -``` +```bash npm access ls-packages ``` * Check which teams are collaborating on a package: -``` +```bash npm access ls-collaborators ``` -## SEE ALSO +### See also -* npm-team(1) -* npm-access(1) -* npm-scope(7) +* [npm team](/cli-commands/npm-team) +* [npm access](/cli-commands/npm-access) +* [npm scope](/using-npm/scope) diff --git a/deps/npm/doc/misc/npm-registry.md b/deps/npm/docs/content/using-npm/registry.md similarity index 72% rename from deps/npm/doc/misc/npm-registry.md rename to deps/npm/docs/content/using-npm/registry.md index 03966007cad639..cd6a2e4d71eebc 100644 --- a/deps/npm/doc/misc/npm-registry.md +++ b/deps/npm/docs/content/using-npm/registry.md @@ -1,7 +1,14 @@ -npm-registry(7) -- The JavaScript Package Registry -================================================== +--- +section: using-npm +title: registry +description: The JavaScript Package Registry +--- -## DESCRIPTION +# registry(7) + +## The JavaScript Package Registry + +### Description To resolve packages by name and version, npm talks to a registry website that implements the CommonJS Package Registry specification for reading @@ -25,11 +32,11 @@ of which there is a public mirror at available at . The registry URL used is determined by the scope of the package (see -`npm-scope(7)`). If no scope is specified, the default registry is used, which is -supplied by the `registry` config parameter. See `npm-config(1)`, -`npmrc(5)`, and `npm-config(7)` for more on managing npm's configuration. +[`scope`](/using-npm/scope). If no scope is specified, the default registry is used, which is +supplied by the `registry` config parameter. See [`npm config`](/cli-commands/npm-config), +[`npmrc`](/configuring-npm/npmrc), and [`config`](/using-npm/config) for more on managing npm's configuration. -## Does npm send any information about me back to the registry? +### Does npm send any information about me back to the registry? Yes. @@ -52,7 +59,7 @@ about your environment: The npm registry does not try to correlate the information in these headers with any authenticated accounts that may be used in the same requests. -## Can I run my own private registry? +### Can I run my own private registry? Yes! @@ -67,34 +74,34 @@ default will only publish internally. If you then want to publish a package for the whole world to see, you can simply override the `--registry` option for that `publish` command. -## I don't want my package published in the official registry. It's private. +### I don't want my package published in the official registry. It's private. Set `"private": true` in your package.json to prevent it from being published at all, or `"publishConfig":{"registry":"http://my-internal-registry.local"}` to force it to be published only to your internal registry. -See `package.json(5)` for more info on what goes in the package.json file. +See [`package.json`](/configuring-npm/package-json) for more info on what goes in the package.json file. -## Will you replicate from my registry into the public one? +### Will you replicate from my registry into the public one? No. If you want things to be public, then publish them into the public registry using npm. What little security there is would be for nought otherwise. -## Do I have to use couchdb to build a registry that npm can talk to? +### Do I have to use couchdb to build a registry that npm can talk to? No, but it's way easier. Basically, yes, you do, or you have to effectively implement the entire CouchDB API anyway. -## Is there a website or something to see package docs and such? +### Is there a website or something to see package docs and such? Yes, head over to -## SEE ALSO +### See also -* npm-config(1) -* npm-config(7) -* npmrc(5) -* npm-developers(7) -* npm-disputes(7) +* [npm config](/cli-commands/npm-config) +* [config](/using-npm/config) +* [npmrc](/configuring-npm/npmrc) +* [npm developers](/using-npm/developers) +* [npm disputes](/using-npm/disputes) diff --git a/deps/npm/doc/misc/removing-npm.md b/deps/npm/docs/content/using-npm/removal.md similarity index 64% rename from deps/npm/doc/misc/removing-npm.md rename to deps/npm/docs/content/using-npm/removal.md index 84274522c22fef..7c836846732403 100644 --- a/deps/npm/doc/misc/removing-npm.md +++ b/deps/npm/docs/content/using-npm/removal.md @@ -1,17 +1,28 @@ -npm-removal(1) -- Cleaning the Slate -==================================== +--- +section: using-npm +title: removal +description: Cleaning the Slate +--- -## SYNOPSIS +# removal(7) + +## Cleaning the Slate + +### Synopsis So sad to see you go. - sudo npm uninstall npm -g +```bash +sudo npm uninstall npm -g +``` Or, if that fails, get the npm source code, and do: - sudo make uninstall +```bash +sudo make uninstall +``` -## More Severe Uninstalling +### More Severe Uninstalling Usually, the above instructions are sufficient. That will remove npm, but leave behind anything you've installed. @@ -21,7 +32,7 @@ continue reading. Note that this is only necessary for globally-installed packages. Local installs are completely contained within a project's `node_modules` -folder. Delete that folder, and everything is gone (unless a package's +folder. Delete that folder, and everything is gone less a package's install script is particularly ill-behaved). This assumes that you installed node and npm in the default place. If @@ -31,24 +42,29 @@ different prefix setting, then adjust the paths accordingly, replacing To remove everything npm-related manually: - rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm* +```bash +rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm* +``` If you installed things *with* npm, then your best bet is to uninstall them with npm first, and then install them again once you have a proper install. This can help find any symlinks that are lying around: - ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm +```bash +ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm +``` Prior to version 0.3, npm used shim files for executables and node modules. To track those down, you can do the following: - find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ; +```bash +find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ; +``` (This is also in the README file.) -## SEE ALSO +### See also -* README -* npm-uninstall(1) -* npm-prune(1) +* [npm uninstall](/cli-commands/npm-uninstall) +* [npm prune](/cli-commands/npm-prune) diff --git a/deps/npm/doc/misc/npm-scope.md b/deps/npm/docs/content/using-npm/scope.md similarity index 78% rename from deps/npm/doc/misc/npm-scope.md rename to deps/npm/docs/content/using-npm/scope.md index a65af92bcdcb69..2cbc108f0db92c 100644 --- a/deps/npm/doc/misc/npm-scope.md +++ b/deps/npm/docs/content/using-npm/scope.md @@ -1,14 +1,22 @@ -npm-scope(7) -- Scoped packages -=============================== +--- +section: using-npm +title: scope +description: Scoped packages +--- +# scope(7) -## DESCRIPTION +## Scoped packages + +### Description All npm packages have a name. Some package names also have a scope. A scope follows the usual rules for package names (URL-safe characters, no leading dots or underscores). When used in package names, scopes are preceded by an `@` symbol and followed by a slash, e.g. - @somescope/somepackagename +```bash +@somescope/somepackagename +``` Scopes are a way of grouping related packages together, and also affect a few things about the way npm treats the package. @@ -23,7 +31,7 @@ by the primary npm registry. Unscoped packages can depend on scoped packages and vice versa. The npm client is backwards-compatible with unscoped registries, so it can be used to work with scoped and unscoped registries at the same time. -## Installing scoped packages +### Installing scoped packages Scoped packages are installed to a sub-folder of the regular installation folder, e.g. if your other packages are installed in `node_modules/packagename`, @@ -34,28 +42,34 @@ contain any number of scoped packages. A scoped package is installed by referencing it by name, preceded by an `@` symbol, in `npm install`: - npm install @myorg/mypackage +```bash +npm install @myorg/mypackage +``` Or in `package.json`: - "dependencies": { - "@myorg/mypackage": "^1.3.0" - } +```json +"dependencies": { + "@myorg/mypackage": "^1.3.0" +} +``` Note that if the `@` symbol is omitted, in either case, npm will instead attempt to -install from GitHub; see `npm-install(1)`. +install from GitHub; see [`npm install`](/cli-commands/npm-install). -## Requiring scoped packages +### Requiring scoped packages Because scoped packages are installed into a scope folder, you have to include the name of the scope when requiring them in your code, e.g. - require('@myorg/mypackage') +```javascript +require('@myorg/mypackage') +``` There is nothing special about the way Node treats scope folders. This simply requires the `mypackage` module in the folder named `@myorg`. -## Publishing scoped packages +### Publishing scoped packages Scoped packages can be published from the CLI as of `npm@2` and can be published to any registry that supports them, including the primary npm @@ -66,13 +80,13 @@ registry. If you wish, you may associate a scope with a registry; see below. -### Publishing public scoped packages to the primary npm registry +#### Publishing public scoped packages to the primary npm registry To publish a public scoped package, you must specify `--access public` with the initial publication. This will publish the package and set access to `public` as if you had run `npm access public` after publishing. -### Publishing private scoped packages to the npm registry +#### Publishing private scoped packages to the npm registry To publish a private scoped package to the npm registry, you must have an [npm Private Modules](https://docs.npmjs.com/private-modules/intro) @@ -83,7 +97,7 @@ You can then publish the module with `npm publish` or `npm publish restricted access. You can then change the access permissions, if desired, with `npm access` or on the npmjs.com website. -## Associating a scope with a registry +### Associating a scope with a registry Scopes can be associated with a separate registry. This allows you to seamlessly use a mix of packages from the primary npm registry and one or more @@ -91,23 +105,27 @@ private registries, such as npm Enterprise. You can associate a scope with a registry at login, e.g. - npm login --registry=http://reg.example.com --scope=@myco +```bash +npm login --registry=http://reg.example.com --scope=@myco +``` Scopes have a many-to-one relationship with registries: one registry can host multiple scopes, but a scope only ever points to one registry. You can also associate a scope with a registry using `npm config`: - npm config set @myco:registry http://reg.example.com +```bash +npm config set @myco:registry http://reg.example.com +``` Once a scope is associated with a registry, any `npm install` for a package with that scope will request packages from that registry instead. Any `npm publish` for a package name that contains the scope will be published to that registry instead. -## SEE ALSO +### See also -* npm-install(1) -* npm-publish(1) -* npm-access(1) -* npm-registry(7) +* [npm install](/cli-commands/npm-install) +* [npm publish](/cli-commands/npm-publish) +* [npm access](/cli-commands/npm-access) +* [npm registry](/using-npm/registry) diff --git a/deps/npm/doc/misc/npm-scripts.md b/deps/npm/docs/content/using-npm/scripts.md similarity index 78% rename from deps/npm/doc/misc/npm-scripts.md rename to deps/npm/docs/content/using-npm/scripts.md index 43d610511e2b3e..6a2522fba43a77 100644 --- a/deps/npm/doc/misc/npm-scripts.md +++ b/deps/npm/docs/content/using-npm/scripts.md @@ -1,63 +1,70 @@ -npm-scripts(7) -- How npm handles the "scripts" field -===================================================== +--- +section: using-npm +title: scripts +description: How npm handles the "scripts" field +--- -## DESCRIPTION +# scripts(7) + +## How npm handles the "scripts" field + +### Description npm supports the "scripts" property of the package.json file, for the following scripts: -* prepublish: +* **prepublish** (_as of npm@5, `prepublish` is deprecated. Use `prepare` for build steps and `prepublishOnly` for upload-only._): Run BEFORE the package is packed and published, as well as on local `npm install` without any arguments. (See below) -* prepare: +* **prepare**: Run both BEFORE the package is packed and published, on local `npm install` without any arguments, and when installing git dependencies (See below). This is run AFTER `prepublish`, but BEFORE `prepublishOnly`. -* prepublishOnly: +* **prepublishOnly**: Run BEFORE the package is prepared and packed, ONLY on `npm publish`. (See below.) -* prepack: +* **prepack**: run BEFORE a tarball is packed (on `npm pack`, `npm publish`, and when installing git dependencies) -* postpack: +* **postpack**: Run AFTER the tarball has been generated and moved to its final destination. -* publish, postpublish: +* **publish**, **postpublish**: Run AFTER the package is published. -* preinstall: +* **preinstall**: Run BEFORE the package is installed -* install, postinstall: +* **install**, **postinstall**: Run AFTER the package is installed. -* preuninstall, uninstall: +* **preuninstall**, **uninstall**: Run BEFORE the package is uninstalled. -* postuninstall: +* **postuninstall**: Run AFTER the package is uninstalled. -* preversion: +* **preversion**: Run BEFORE bumping the package version. -* version: +* **version**: Run AFTER bumping the package version, but BEFORE commit. -* postversion: +* **postversion**: Run AFTER bumping the package version, and AFTER commit. -* pretest, test, posttest: +* **pretest**, **test**, **posttest**: Run by the `npm test` command. -* prestop, stop, poststop: +* **prestop**, **stop**, **poststop**: Run by the `npm stop` command. -* prestart, start, poststart: +* **prestart**, **start**, **poststart**: Run by the `npm start` command. -* prerestart, restart, postrestart: +* **prerestart**, **restart**, **postrestart**: Run by the `npm restart` command. Note: `npm restart` will run the stop and start scripts if no `restart` script is provided. -* preshrinkwrap, shrinkwrap, postshrinkwrap: +* **preshrinkwrap**, **shrinkwrap**, **postshrinkwrap**: Run by the `npm shrinkwrap` command. Additionally, arbitrary scripts can be executed by running `npm run-script `. *Pre* and *post* commands with matching names will be run for those as well (e.g. `premyscript`, `myscript`, -`postmyscript`). Scripts from dependencies can be run with +`postmyscript`). Scripts from dependencies can be run with `npm explore -- npm run `. -## PREPUBLISH AND PREPARE +#### Prepublish and Prepare -### DEPRECATION NOTE +#### Deprecation Note Since `npm@1.1.71`, the npm CLI has run the `prepublish` script for both `npm publish` and `npm install`, because it's a convenient way to prepare a package @@ -73,7 +80,7 @@ they're in good shape). See for a much lengthier justification, with further reading, for this change. -### USE CASES +#### Use Cases If you need to perform operations on your package before it is used, in a way that is not dependent on the operating system or architecture of the @@ -95,7 +102,7 @@ Additionally, this means that: * You don't need to rely on your users having `curl` or `wget` or other system tools on the target machines. -## DEFAULT VALUES +### Default Values npm will default some script values based on package contents. @@ -110,68 +117,76 @@ npm will default some script values based on package contents. haven't defined your own `install` or `preinstall` scripts, npm will default the `install` command to compile using node-gyp. -## USER +### User If npm was invoked with root privileges, then it will change the uid to the user account or uid specified by the `user` config, which defaults to `nobody`. Set the `unsafe-perm` flag to run scripts with root privileges. -## ENVIRONMENT +### Environment Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process. -### path +#### path If you depend on modules that define executable scripts, like test suites, then those executables will be added to the `PATH` for executing the scripts. So, if your package.json has this: - { "name" : "foo" - , "dependencies" : { "bar" : "0.1.x" } - , "scripts": { "start" : "bar ./test" } } +```json +{ "name" : "foo" +, "dependencies" : { "bar" : "0.1.x" } +, "scripts": { "start" : "bar ./test" } } +``` then you could run `npm start` to execute the `bar` script, which is exported into the `node_modules/.bin` directory on `npm install`. -### package.json vars +#### package.json vars The package.json fields are tacked onto the `npm_package_` prefix. So, for instance, if you had `{"name":"foo", "version":"1.2.5"}` in your package.json file, then your package scripts would have the `npm_package_name` environment variable set to "foo", and the -`npm_package_version` set to "1.2.5". You can access these variables -in your code with `process.env.npm_package_name` and +`npm_package_version` set to "1.2.5". You can access these variables +in your code with `process.env.npm_package_name` and `process.env.npm_package_version`, and so on for other fields. -### configuration +#### configuration Configuration parameters are put in the environment with the `npm_config_` prefix. For instance, you can view the effective `root` config by checking the `npm_config_root` environment variable. -### Special: package.json "config" object +#### Special: package.json "config" object The package.json "config" keys are overwritten in the environment if there is a config param of `[@]:`. For example, if the package.json has this: - { "name" : "foo" - , "config" : { "port" : "8080" } - , "scripts" : { "start" : "node server.js" } } +```json +{ "name" : "foo" +, "config" : { "port" : "8080" } +, "scripts" : { "start" : "node server.js" } } +``` and the server.js is this: - http.createServer(...).listen(process.env.npm_package_config_port) +```javascript +http.createServer(...).listen(process.env.npm_package_config_port) +``` then the user could change the behavior by doing: - npm config set foo:port 80 +```bash + npm config set foo:port 80 + ``` -### current lifecycle event +#### current lifecycle event Lastly, the `npm_lifecycle_event` environment variable is set to whichever stage of the cycle is being executed. So, you could have a @@ -182,18 +197,22 @@ Objects are flattened following this format, so if you had `{"scripts":{"install":"foo.js"}}` in your package.json, then you'd see this in the script: - process.env.npm_package_scripts_install === "foo.js" +```bash +process.env.npm_package_scripts_install === "foo.js" +``` -## EXAMPLES +### Examples For example, if your package.json contains this: - { "scripts" : - { "install" : "scripts/install.js" - , "postinstall" : "scripts/install.js" - , "uninstall" : "scripts/uninstall.js" - } - } +```json +{ "scripts" : + { "install" : "scripts/install.js" + , "postinstall" : "scripts/install.js" + , "uninstall" : "scripts/uninstall.js" + } +} +``` then `scripts/install.js` will be called for the install and post-install stages of the lifecycle, and `scripts/uninstall.js` @@ -205,14 +224,16 @@ variable. If you want to run a make command, you can do so. This works just fine: - { "scripts" : - { "preinstall" : "./configure" - , "install" : "make && make install" - , "test" : "make test" - } - } +```json +{ "scripts" : + { "preinstall" : "./configure" + , "install" : "make && make install" + , "test" : "make test" + } +} +``` -## EXITING +### Exiting Scripts are run by passing the line as a script argument to `sh`. @@ -223,7 +244,7 @@ Note that these script files don't have to be nodejs or even javascript programs. They just have to be some kind of executable file. -## HOOK SCRIPTS +### Hook Scripts If you want to run a specific script at a specific lifecycle event for ALL packages, then you can use a hook script. @@ -236,7 +257,7 @@ Hook scripts are run exactly the same way as package.json scripts. That is, they are in a separate child process, with the env described above. -## BEST PRACTICES +### Best Practices * Don't exit with a non-zero error code unless you *really* mean it. Except for uninstall scripts, this will cause the npm action to @@ -244,7 +265,7 @@ above. only will prevent some optional features, then it's better to just print a warning and exit successfully. * Try not to use scripts to do what npm can do for you. Read through - `package.json(5)` to see all the things that you can specify and enable + [`package.json`](/configuring-npm/package-json) to see all the things that you can specify and enable by simply describing your package appropriately. In general, this will lead to a more robust and consistent state. * Inspect the env to determine where to put things. For instance, if @@ -260,9 +281,9 @@ above. there is another option. The only valid use of `install` or `preinstall` scripts is for compilation which must be done on the target architecture. -## SEE ALSO +### See Also -* npm-run-script(1) -* package.json(5) -* npm-developers(7) -* npm-install(1) +* [npm run-script](/cli-commands/npm-run-script) +* [package.json](/configuring-npm/package-json) +* [npm developers](/using-npm/developers) +* [npm install](/cli-commands/npm-install) diff --git a/deps/npm/doc/misc/semver.md b/deps/npm/docs/content/using-npm/semver.md similarity index 100% rename from deps/npm/doc/misc/semver.md rename to deps/npm/docs/content/using-npm/semver.md diff --git a/deps/npm/docs/gatsby-browser.js b/deps/npm/docs/gatsby-browser.js new file mode 100644 index 00000000000000..b1425d1fb58cff --- /dev/null +++ b/deps/npm/docs/gatsby-browser.js @@ -0,0 +1,8 @@ +import React from 'react' +import Layout from './src/components/layout' +require('prismjs/themes/prism-tomorrow.css') +require('./src/main.css') + +export const wrapPageElement = ({ element, props }) => { + return {element} +} diff --git a/deps/npm/docs/gatsby-config.js b/deps/npm/docs/gatsby-config.js new file mode 100644 index 00000000000000..f44e1bc4edec4d --- /dev/null +++ b/deps/npm/docs/gatsby-config.js @@ -0,0 +1,96 @@ +const IS_STATIC = process.env.GATSBY_IS_STATIC + +const OPTS = { + siteMetadata: { + title: 'npm cli documentation', + description: 'Documentation for the npm cli.', + author: '@gatsbyjs' + }, + plugins: [ + 'gatsby-plugin-root-import', + 'gatsby-plugin-react-helmet', + 'gatsby-plugin-catch-links', + 'gatsby-plugin-styled-components', + { + resolve: 'gatsby-source-filesystem', + options: { + name: 'src', + path: `${__dirname}/content/` + } + }, + { + resolve: 'gatsby-plugin-no-sourcemaps' + }, + 'gatsby-plugin-sharp', + { + resolve: 'gatsby-plugin-manifest', + options: { + name: 'gatsby-starter-default', + short_name: 'starter', + start_url: '/', + background_color: '#663399', + theme_color: '#663399', + display: 'minimal-ui', + icon: 'src/images/npm-icon.png' // This path is relative to the root of the site. + } + }, + { + resolve: 'gatsby-plugin-prefetch-google-fonts', + options: { + fonts: [ + { + family: 'Poppins', + subsets: ['latin'], + variants: ['300', '400', '500'] + }, + { + family: 'Inconsolata', + subsets: ['latin'], + variants: ['400', '700'] + } + ] + } + }, + { + resolve: 'gatsby-transformer-remark', + options: { + // CommonMark mode (default: true) + commonmark: true, + // Footnotes mode (default: true) + footnotes: true, + // Pedantic mode (default: true) + pedantic: true, + // GitHub Flavored Markdown mode (default: true) + gfm: true, + // Plugins configs + plugins: [{ + resolve: 'gatsby-remark-autolink-headers', + options: { + offsetY: '100', + icon: '', + className: 'header-link-class', + maintainCase: false, + removeAccents: true + } + }, + { + resolve: 'gatsby-remark-prismjs', + options: { + classPrefix: 'language-', + inlineCodeMarker: null, + aliases: {}, + showLineNumbers: false, + noInlineHighlight: false + } + }] + } + } + ] +} + +const STATIC_OPTS = Object.assign({}, OPTS, { + pathPrefix: '__GATSBY_IPFS_PATH_PREFIX__', + plugins: OPTS.plugins.concat(['gatsby-plugin-ipfs']) +}) + +module.exports = IS_STATIC ? STATIC_OPTS : OPTS diff --git a/deps/npm/docs/gatsby-node.js b/deps/npm/docs/gatsby-node.js new file mode 100644 index 00000000000000..01affc6307f458 --- /dev/null +++ b/deps/npm/docs/gatsby-node.js @@ -0,0 +1,43 @@ +const {createFilePath} = require('gatsby-source-filesystem') +const path = require('path') + +exports.onCreateNode = ({node, getNode, actions}) => { + const {createNodeField} = actions + if (node.internal.type === 'MarkdownRemark') { + const slug = createFilePath({node, getNode, basePath: 'content', trailingSlash: false}) + createNodeField({ + node, + name: 'slug', + value: slug + }) + } +} + +exports.createPages = ({graphql, actions}) => { + const {createPage} = actions + return graphql(` + { + allMarkdownRemark { + edges { + node { + id + fields { + slug + } + html + } + } + } + } + `).then(result => { + result.data.allMarkdownRemark.edges.forEach(({node}) => { + createPage({ + path: node.fields.slug, + component: path.resolve('./src/templates/Page.js'), + context: { + slug: node.fields.slug + } + }) + }) + }) +} diff --git a/deps/npm/docs/gatsby-ssr.js b/deps/npm/docs/gatsby-ssr.js new file mode 100644 index 00000000000000..33361c0a38ca7c --- /dev/null +++ b/deps/npm/docs/gatsby-ssr.js @@ -0,0 +1,6 @@ +import React from 'react' +import Layout from './src/components/layout' + +export const wrapPageElement = ({ element, props }) => { + return {element} +} diff --git a/deps/npm/docs/package-lock.json b/deps/npm/docs/package-lock.json new file mode 100644 index 00000000000000..7fbff27b294df3 --- /dev/null +++ b/deps/npm/docs/package-lock.json @@ -0,0 +1,17622 @@ +{ + "name": "npm-cli-docs", + "version": "0.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", + "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", + "requires": { + "@babel/types": "^7.3.0", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz", + "integrity": "sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5", + "@babel/helper-split-export-declaration": "^7.4.4" + } + }, + "@babel/helper-define-map": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", + "integrity": "sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", + "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "requires": { + "@babel/types": "^7.5.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" + }, + "@babel/helper-regex": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", + "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.5.5", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", + "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.5", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", + "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", + "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz", + "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", + "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz", + "integrity": "sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz", + "integrity": "sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz", + "integrity": "sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz", + "integrity": "sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz", + "integrity": "sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==", + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz", + "integrity": "sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==", + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", + "requires": { + "regexp-tree": "^0.1.6" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz", + "integrity": "sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", + "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", + "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", + "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", + "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", + "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz", + "integrity": "sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/preset-env": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.5.5.tgz", + "integrity": "sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-dynamic-import": "^7.5.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.5.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.5.5", + "@babel/plugin-transform-classes": "^7.5.5", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-duplicate-keys": "^7.5.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.4.4", + "@babel/plugin-transform-function-name": "^7.4.4", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-member-expression-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.5.0", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/plugin-transform-modules-systemjs": "^7.5.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-new-target": "^7.4.4", + "@babel/plugin-transform-object-super": "^7.5.5", + "@babel/plugin-transform-parameters": "^7.4.4", + "@babel/plugin-transform-property-literals": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.4.5", + "@babel/plugin-transform-reserved-words": "^7.2.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.4.4", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/types": "^7.5.5", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + } + } + }, + "@babel/preset-react": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" + } + }, + "@babel/runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@emotion/cache": { + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.17.tgz", + "integrity": "sha512-442/miwbuwIDfSzfMqZNxuzxSEbskcz/bZ86QBYzEjFrr/oq9w+y5kJY1BHbGhDtr91GO232PZ5NN9XYMwr/Qg==", + "requires": { + "@emotion/sheet": "0.9.3", + "@emotion/stylis": "0.8.4", + "@emotion/utils": "0.11.2", + "@emotion/weak-memoize": "0.2.3" + } + }, + "@emotion/core": { + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.17.tgz", + "integrity": "sha512-gykyjjr0sxzVuZBVTVK4dUmYsorc2qLhdYgSiOVK+m7WXgcYTKZevGWZ7TLAgTZvMelCTvhNq8xnf8FR1IdTbg==", + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.17", + "@emotion/css": "^10.0.14", + "@emotion/serialize": "^0.11.10", + "@emotion/sheet": "0.9.3", + "@emotion/utils": "0.11.2" + } + }, + "@emotion/css": { + "version": "10.0.14", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.14.tgz", + "integrity": "sha512-MozgPkBEWvorcdpqHZE5x1D/PLEHUitALQCQYt2wayf4UNhpgQs2tN0UwHYS4FMy5ROBH+0ALyCFVYJ/ywmwlg==", + "requires": { + "@emotion/serialize": "^0.11.8", + "@emotion/utils": "0.11.2", + "babel-plugin-emotion": "^10.0.14" + } + }, + "@emotion/hash": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.7.2.tgz", + "integrity": "sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q==" + }, + "@emotion/is-prop-valid": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.2.tgz", + "integrity": "sha512-ZQIMAA2kLUWiUeMZNJDTeCwYRx1l8SQL0kHktze4COT22occKpDML1GDUXP5/sxhOMrZO8vZw773ni4H5Snrsg==", + "requires": { + "@emotion/memoize": "0.7.2" + } + }, + "@emotion/memoize": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.2.tgz", + "integrity": "sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w==" + }, + "@emotion/serialize": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.10.tgz", + "integrity": "sha512-04AB+wU00vv9jLgkWn13c/GJg2yXp3w7ZR3Q1O6mBSE6mbUmYeNX3OpBhfp//6r47lFyY0hBJJue+bA30iokHQ==", + "requires": { + "@emotion/hash": "0.7.2", + "@emotion/memoize": "0.7.2", + "@emotion/unitless": "0.7.4", + "@emotion/utils": "0.11.2", + "csstype": "^2.5.7" + } + }, + "@emotion/sheet": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.3.tgz", + "integrity": "sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A==" + }, + "@emotion/styled": { + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.17.tgz", + "integrity": "sha512-zHMgWjHDMNjD+ux64POtDnjLAObniu3znxFBLSdV/RiEhSLjHIowfvSbbd/C33/3uwtI6Uzs2KXnRZtka/PpAQ==", + "requires": { + "@emotion/styled-base": "^10.0.17", + "babel-plugin-emotion": "^10.0.17" + } + }, + "@emotion/styled-base": { + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.17.tgz", + "integrity": "sha512-vqQvxluZZKPByAB4zYZys0Qo/kVDP/03hAeg1K+TYpnZRwTi7WteOodc+/5669RPVNcfb93fphQpM5BYJnI1/g==", + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/is-prop-valid": "0.8.2", + "@emotion/serialize": "^0.11.10", + "@emotion/utils": "0.11.2" + } + }, + "@emotion/stylis": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.4.tgz", + "integrity": "sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ==" + }, + "@emotion/unitless": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.4.tgz", + "integrity": "sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ==" + }, + "@emotion/utils": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.2.tgz", + "integrity": "sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA==" + }, + "@emotion/weak-memoize": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.3.tgz", + "integrity": "sha512-zVgvPwGK7c1aVdUVc9Qv7SqepOGRDrqCw7KZPSZziWGxSlbII3gmvGLPzLX4d0n0BMbamBacUrN22zOMyFFEkQ==" + }, + "@gatsbyjs/relay-compiler": { + "version": "2.0.0-printer-fix.2", + "resolved": "https://registry.npmjs.org/@gatsbyjs/relay-compiler/-/relay-compiler-2.0.0-printer-fix.2.tgz", + "integrity": "sha512-7GeCCEQ7O15lMTT/SXy9HuRde4cv5vs465ZnLK2QCajSDLior+20yrMqHn1PGsJYK6nNZH7p3lw9qTCpqmuc7Q==", + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "babel-preset-fbjs": "^3.1.2", + "chalk": "^2.4.1", + "fast-glob": "^2.2.2", + "fb-watchman": "^2.0.0", + "fbjs": "^1.0.0", + "immutable": "~3.7.6", + "nullthrows": "^1.1.0", + "relay-runtime": "2.0.0", + "signedsource": "^1.0.0", + "yargs": "^9.0.0" + } + }, + "@hapi/address": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", + "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==" + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==" + }, + "@hapi/hoek": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.2.1.tgz", + "integrity": "sha512-JPiBy+oSmsq3St7XlipfN5pNA6bDJ1kpa73PrK/zR29CVClDVqy04AanM/M/qx5bSF+I61DdCfAvRrujau+zRg==" + }, + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.3.tgz", + "integrity": "sha512-JmS9/vQK6dcUYn7wc2YZTqzIKubAQcJKu2KCKAru6es482U5RT5fP1EXCPtlXpiK7PR0On/kpQKI4fRKkzpZBQ==", + "requires": { + "@hapi/hoek": "8.x.x" + } + }, + "@jimp/bmp": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.6.4.tgz", + "integrity": "sha512-dhKM7Cjw4XoOefx3/we2+vWyTP6hQPpM7mEsziGjtsrK2f/e3/+hhHbEsQNgO9BOA1FPJRXAOiYHts9IlMH1mg==", + "requires": { + "@jimp/utils": "^0.6.4", + "bmp-js": "^0.1.0", + "core-js": "^2.5.7" + } + }, + "@jimp/core": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.6.4.tgz", + "integrity": "sha512-nyiAXI8/uU54fGO53KrRB8pdn1s+IODZ+rj0jG2owsNJlTlagFrsZAy8IVTUCOiiXjh9TbwFo7D5XMrmi4KUww==", + "requires": { + "@jimp/utils": "^0.6.4", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "core-js": "^2.5.7", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + }, + "dependencies": { + "buffer": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.0.tgz", + "integrity": "sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==" + } + } + }, + "@jimp/custom": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.6.4.tgz", + "integrity": "sha512-sdBHrBoVr1+PFx4dlUAgXvvu4dG0esQobhg7qhpSLRje1ScavIgE2iXdJKpycgzrqwAOL8vW4/E5w2/rONlaoQ==", + "requires": { + "@jimp/core": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/gif": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.6.4.tgz", + "integrity": "sha512-14mLoyG0UrYJsGNRoXBFvSJdFtBD0BSBwQ1zCNeW+HpQqdl+Kh5E1Pz4nqT2KNylJe1jypyR51Q2yndgcfGVyg==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.6.4.tgz", + "integrity": "sha512-NrFla9fZC/Bhw1Aa9vJ6cBOqpB5ylEPb9jD+yZ0fzcAw5HwILguS//oXv9EWLApIY1XsOMFFe0XWpY653rv8hw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7", + "jpeg-js": "^0.3.4" + } + }, + "@jimp/plugin-blit": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.6.4.tgz", + "integrity": "sha512-suVznd4XozkQIuECX0u8kMl+cAQpZN3WcbWXUcJaVxRi+VBvHIetG1Qs5qGLzuEg9627+kE7ppv0UgZ5mkE6lg==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-blur": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.6.4.tgz", + "integrity": "sha512-M2fDMYUUtEKVNnCJZk5J0KSMzzISobmWfnG88RdHXJCkOn98kdawQFwTsYOfJJfCM8jWfhIxwZLFhC/2lkTN2w==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-color": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.6.4.tgz", + "integrity": "sha512-6Nfr2l9KSb6zH2fij8G6fQOw85TTkyRaBlqMvDmsQp/I1IlaDbXzA2C2Eh9jkQYZQDPu61B1MkmlEhJp/TUx6Q==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.6.4.tgz", + "integrity": "sha512-qI1MxU1noS6NbEPu/bDDeP405aMviuIsfpOz8J3En8IwIwrJV22qt6QIHmF+eyng8CYgivwIPjEPzFzLR566Nw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-cover": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.6.4.tgz", + "integrity": "sha512-z6eafPonj3LJY8cTEfRkXmOfCDi1+f0tbYaNvmiu+OrWJ3Ojw2hMt+BVVvJ8pKe1dWIFkCjxOjyjZWj1gEkaLw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-crop": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.6.4.tgz", + "integrity": "sha512-w9TR+pn+GeWbznscGe2HRkPxInge0whAF3TLPWhPwBVjZChTT8dSDXsUpUlxQqvI4SfzuKp8z3/0SBqYDCzxxA==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-displace": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.6.4.tgz", + "integrity": "sha512-MEvtBXOAio/3iGJkKBrTtFs3Q38ez2Wy/wTD0Ruas+L8fjJR7l4mDgV+zjRr57CqB5mpY+L48VEoa2/gNXh9cg==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-dither": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.6.4.tgz", + "integrity": "sha512-w+AGLcIMUeJZ4CI0FvFomahgKLcW+ICsLidUNOqyLzceluPAfug4X7vDhQ41pNkzKg0M1+Q1j0aWV8bdyF+LhA==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-flip": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.6.4.tgz", + "integrity": "sha512-ukINMegMUM9KYjyDCiyYKYdSsbhNRLHDwOJN0xVRalmOKqNaZmjNbiMbaVxKlYt6sHW76RhSMOekw9f6GQB9tQ==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.6.4.tgz", + "integrity": "sha512-C1P6ohzIddpNb7CX5X+ygbp+ow8Fpt64ZLoIgdjYPs/42HxKluvY62fVfMhY6m5zUGKIMbg0uYeAtz/9LRJPyw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-invert": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.6.4.tgz", + "integrity": "sha512-sleGz1jXaNEsP/5Ayqw8oez/6KesWcyCqovIuK4Z4kDmMc2ncuhsXIJQXDWtIF4tTQVzNEgrxUDNA4bi9xpCUA==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-mask": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.6.4.tgz", + "integrity": "sha512-3D4FbRxnpO9nzwa6cF8AImgO1aVReYbfRRO4I4bku4/iZ+kuU3fBLV+SRhB4c7di3ejG5u+rGsIfaNc94iYYvw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-normalize": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.6.4.tgz", + "integrity": "sha512-nOFMwOaVkOKArHkD/T6/1HKAPj3jlW6l0JduVDn1A5eIPCtlnyhlE9zdjgi5Q9IBR/gRjwW6tTzBKuJenS51kg==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-print": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.6.4.tgz", + "integrity": "sha512-3z5DLVCKg0NfZhHATEaYH/4XanIboPP1pOUoxIUeF++qOnGiGgH2giFJlRprHmx2l3E3DukR1v8pt54PGvfrFw==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.6.4.tgz", + "integrity": "sha512-fk2+KheUNClrOWj6aDNWj1r4byVQb6Qxy4aT1UHX5GXPHDA+nhlej7ghaYdzeWZYodeM3lpasYtByu1XE2qScQ==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-rotate": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.6.4.tgz", + "integrity": "sha512-44VgV5D4xQIYInJAVevdW9J3SOhGKyz0OEr2ciA8Q3ktonKx0O5Q1g2kbruiqxFSkK/u2CKPLeKXZzYCFrmJGQ==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-scale": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.6.4.tgz", + "integrity": "sha512-RAQRaDiCHmEz+A8QS5d/Z38EnlNsQizz3Mu3NsjA8uFtJsv1yMKWXZSQuzniofZw8tlMV6oI3VdM0eQVE07/5w==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "@jimp/plugins": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.6.4.tgz", + "integrity": "sha512-NpO/87CKnF4Q9r8gMl6w+jPKOM/C089qExkViD9cPvcFZEnyVOu7ucGzcMmTcabWOU62iQTOkRViPYr6XaK0LQ==", + "requires": { + "@jimp/plugin-blit": "^0.6.4", + "@jimp/plugin-blur": "^0.6.4", + "@jimp/plugin-color": "^0.6.4", + "@jimp/plugin-contain": "^0.6.4", + "@jimp/plugin-cover": "^0.6.4", + "@jimp/plugin-crop": "^0.6.4", + "@jimp/plugin-displace": "^0.6.4", + "@jimp/plugin-dither": "^0.6.4", + "@jimp/plugin-flip": "^0.6.4", + "@jimp/plugin-gaussian": "^0.6.4", + "@jimp/plugin-invert": "^0.6.4", + "@jimp/plugin-mask": "^0.6.4", + "@jimp/plugin-normalize": "^0.6.4", + "@jimp/plugin-print": "^0.6.4", + "@jimp/plugin-resize": "^0.6.4", + "@jimp/plugin-rotate": "^0.6.4", + "@jimp/plugin-scale": "^0.6.4", + "core-js": "^2.5.7", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.6.4.tgz", + "integrity": "sha512-qv3oo6ll3XWVIToBwVC1wQX0MFKwpxbe2o+1ld9B4ZDavqvAHzalzcmTd/iyooI85CVDAcC3RRDo66oiizGZCQ==", + "requires": { + "@jimp/utils": "^0.6.4", + "core-js": "^2.5.7", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.6.4.tgz", + "integrity": "sha512-8/vD4qleexmhPdppiu6fSstj/n/kGNTn8iIlf1emiqOuMN2PL9q5GOPDWU0xWdGNyJMMIDXJPgUFUkKfqXdg7w==", + "requires": { + "core-js": "^2.5.7", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.6.4.tgz", + "integrity": "sha512-/EMbipQDg5U6DnBAgcSiydlMBRYoKhnaK7MJRImeTzhDJ6xfgNOF7lYq66o0kmaezKdG/cIwZ1CLecn2y3D8SQ==", + "requires": { + "@jimp/bmp": "^0.6.4", + "@jimp/gif": "^0.6.4", + "@jimp/jpeg": "^0.6.4", + "@jimp/png": "^0.6.4", + "@jimp/tiff": "^0.6.4", + "core-js": "^2.5.7", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.6.4.tgz", + "integrity": "sha512-EFQurCyEnZLSM2Q1BYDTUmsOJPSOYEQd18Fvq8bGo8hnBHoGLWLWWyNi2l4cYhtpKmIXyhvQqa6/WaEpKPzvqA==", + "requires": { + "core-js": "^2.5.7" + } + }, + "@mikaelkristiansson/domready": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@mikaelkristiansson/domready/-/domready-1.0.9.tgz", + "integrity": "sha512-FOAjeRHULSWXd6JMuCDwf3zPbe11kP971+Bufrj9M8rQ33ZMtThgKd6IJgzj6tr/+1Rq3czzLI1LAa9x0IC92w==" + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" + }, + "@pieh/friendly-errors-webpack-plugin": { + "version": "1.7.0-chalk-2", + "resolved": "https://registry.npmjs.org/@pieh/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0-chalk-2.tgz", + "integrity": "sha512-65+vYGuDkHBCWWjqzzR/Ck318+d6yTI00EqII9qe3aPD1J3Olhvw0X38uM5moQb1PK/ksDXwSoPGt/5QhCiotw==", + "requires": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.0", + "string-width": "^2.0.0", + "strip-ansi": "^3" + } + }, + "@reach/router": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@reach/router/-/router-1.2.1.tgz", + "integrity": "sha512-kTaX08X4g27tzIFQGRukaHmNbtMYDS3LEWIS8+l6OayGIw6Oyo1HIF/JzeuR2FoF9z6oV+x/wJSVSq4v8tcUGQ==", + "requires": { + "create-react-context": "^0.2.1", + "invariant": "^2.2.3", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "warning": "^3.0.0" + } + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" + }, + "@styled-system/background": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/background/-/background-5.1.1.tgz", + "integrity": "sha512-AtcDYXVO3Rfui2jZGNBuFinqx25FQ54d6d8JKRPd4g/5wlyw24hgps6VvB3fqNgsA6JKwulIuZf9mfUX4RnPFg==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/border": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/border/-/border-5.1.1.tgz", + "integrity": "sha512-N4jSiyq18zfY2xg1G2+adGCQ3s+geRYZPJ4R/PT/rZM7kbzCRr8xqHNg+OWkDiDTqgZ0eU7OSsRQD/byQpziZg==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/color": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/color/-/color-5.1.1.tgz", + "integrity": "sha512-LHG5HQPZQdMNouXq9/cs/ovadNnnvPFkb6SkTqT9uxTUzTT416erGBaXZPGFqdwPpcDw4Y1MsmrAd1taeJEzvQ==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/core": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/core/-/core-5.1.1.tgz", + "integrity": "sha512-8doP1Uptn1nlNrG44O/DfiRtLvoh9OkPqxEv9Gp1YAKAD2RgRTTQou/wYw/4y4pqmV3Hjb3NA/5Nbp/Uo5eGUQ==", + "requires": { + "object-assign": "^4.1.1" + } + }, + "@styled-system/css": { + "version": "5.0.23", + "resolved": "https://registry.npmjs.org/@styled-system/css/-/css-5.0.23.tgz", + "integrity": "sha512-yC3S0Iox8OTPAyrP1t5yY9nURUICcUdhVYOkwffftuxa5+txxI4qkT2e9JNCc2aaem+DG8mlXTdnYefjqge5wg==" + }, + "@styled-system/flexbox": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/flexbox/-/flexbox-5.1.1.tgz", + "integrity": "sha512-r9kBiCpXJee4zUQJnBom/c8d2CfUXEqrnZ5sdH62RsisoAByJ6vF5a3jI3zQXc8diEHjvNaunZL+K3gQjwJQGg==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/grid": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/grid/-/grid-5.1.1.tgz", + "integrity": "sha512-vzBNBg62syA62jEpxS21QEIwgndtxFgpCWWpitytApAybEll0mZctB06eOFhFgSNgarzOyox+1NdETB5h9KGnw==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/layout": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/layout/-/layout-5.1.1.tgz", + "integrity": "sha512-a0YnXNlORdpfcxejQEwMGd1k+pamRj+VjnAIafRdFBxBXsw55T8eG0iqWEs8U/d3i0+isKcfIyw/9OrElsksBg==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/position": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/position/-/position-5.1.1.tgz", + "integrity": "sha512-75+EvQA5Juh+Zbq1Hkcm0QHx5GwEGoG7BABpG/n/K0Uz2aBGKVKJ4Y3NmPRvSS7fl1Ktl7azIGAPW9XOZ9TdHA==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/shadow": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/shadow/-/shadow-5.1.1.tgz", + "integrity": "sha512-axdgRJ0gU8Rbw/DS24G4AAQIxYjo/fMmqxiegWja2XZDpeljqjyiYfGc7Dad3fgc+DUMn3Jjc1fHcTziTGWA4g==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/should-forward-prop": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/should-forward-prop/-/should-forward-prop-5.1.1.tgz", + "integrity": "sha512-vWgA9qtmo+Cjg63UiLNbuIHUA+nUMvl2tAFtiYE8KKIAz+CB8D11spVXE4JL89HG77sjuuQFwI5D778CKz7q6Q==", + "requires": { + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/memoize": "^0.7.1", + "styled-system": "^5.1.1" + } + }, + "@styled-system/space": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/space/-/space-5.1.1.tgz", + "integrity": "sha512-hwF938Zx83YRZmk30HtBE2EPWT8Z8H3+Rvpkdg13Q6P93DpSNH8wIlIObFKSgcmbOcqXzvFlAYcQ3l6F6Hu3IA==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/typography": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/typography/-/typography-5.1.1.tgz", + "integrity": "sha512-zqrA9+nboPl5h/VhSKdlsUDUciHKb+Ly9YSCsvYb0Di1vI0lnYAtHzbBmI1xsfQW5us1BNflUpirCAQJshJMSQ==", + "requires": { + "@styled-system/core": "^5.1.1" + } + }, + "@styled-system/variant": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@styled-system/variant/-/variant-5.1.1.tgz", + "integrity": "sha512-Gh3iBqksx+cTx5drqazu56KL5cJrGEdxMFQ/6Yo4ravrZd0dRmzBhsUh0+UWtSvfWfN0M0ziE3m/Zu4ZKMHMaQ==", + "requires": { + "@styled-system/core": "^5.1.1", + "@styled-system/css": "^5.0.23" + } + }, + "@types/configstore": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", + "integrity": "sha1-zR6FU2M60xhcPy8jns/10mQ+krY=" + }, + "@types/debug": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.29.tgz", + "integrity": "sha1-oeUUrfvZLwOiJLpU1pMRHb8fN1Q=" + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" + }, + "@types/get-port": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-0.0.4.tgz", + "integrity": "sha1-62u3Qj2fiItjJmDcfS/T5po1ZD4=" + }, + "@types/glob": { + "version": "5.0.36", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.36.tgz", + "integrity": "sha512-KEzSKuP2+3oOjYYjujue6Z3Yqis5HKA1BsIC+jZ1v3lrRNdsqyNNtX0rQf6LSuI4DJJ2z5UV//zBZCcvM0xikg==", + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/history": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.2.tgz", + "integrity": "sha512-ui3WwXmjTaY73fOQ3/m3nnajU/Orhi6cEu5rzX+BrAAJxa3eITXZ5ch9suPqtM03OWhAHhPSyBGCN4UKoxO20Q==" + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + }, + "@types/mkdirp": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.3.29.tgz", + "integrity": "sha1-fyrX7FX5FEgvybHsS7GuYCjUYGY=" + }, + "@types/node": { + "version": "7.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.7.tgz", + "integrity": "sha512-4I7+hXKyq7e1deuzX9udu0hPIYqSSkdKXtjow6fMnQ3OR9qkxIErGHbGY08YrfZJrCS1ajK8lOuzd0k3n2WM4A==" + }, + "@types/prop-types": { + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", + "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==" + }, + "@types/q": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==" + }, + "@types/reach__router": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.4.tgz", + "integrity": "sha512-a+MFhebeSGi0LwHZ0UhH/ke77rWtNQnt8YmaHnquSaY3HmyEi+BPQi3GhPcUPnC9X5BLw/qORw3BPxGb1mCtEw==", + "requires": { + "@types/history": "*", + "@types/react": "*" + } + }, + "@types/react": { + "version": "16.9.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz", + "integrity": "sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, + "@types/tmp": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.32.tgz", + "integrity": "sha1-DTyzECL4Qn6ljACK8yuA2hJspOM=" + }, + "@types/unist": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", + "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + }, + "@types/vfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", + "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", + "requires": { + "@types/node": "*", + "@types/unist": "*", + "@types/vfile-message": "*" + } + }, + "@types/vfile-message": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz", + "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==", + "requires": { + "@types/node": "*", + "@types/unist": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", + "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", + "requires": { + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", + "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==" + }, + "@webassemblyjs/helper-api-error": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", + "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==" + }, + "@webassemblyjs/helper-buffer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", + "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==" + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", + "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", + "requires": { + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", + "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==" + }, + "@webassemblyjs/helper-module-context": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", + "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==" + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", + "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==" + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", + "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", + "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", + "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", + "requires": { + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/utf8": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", + "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==" + }, + "@webassemblyjs/wasm-edit": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", + "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/helper-wasm-section": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-opt": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "@webassemblyjs/wast-printer": "1.7.11" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", + "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", + "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-buffer": "1.7.11", + "@webassemblyjs/wasm-gen": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", + "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-wasm-bytecode": "1.7.11", + "@webassemblyjs/ieee754": "1.7.11", + "@webassemblyjs/leb128": "1.7.11", + "@webassemblyjs/utf8": "1.7.11" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", + "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/floating-point-hex-parser": "1.7.11", + "@webassemblyjs/helper-api-error": "1.7.11", + "@webassemblyjs/helper-code-frame": "1.7.11", + "@webassemblyjs/helper-fsm": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.7.11", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", + "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/wast-parser": "1.7.11", + "@xtuc/long": "4.2.1" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "@xtuc/long": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", + "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==" + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "requires": { + "acorn": "^5.0.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + } + } + }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==" + }, + "address": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.0.tgz", + "integrity": "sha512-4diPfzWbLEIElVG4AnqP+00SULlPzNuyJFNnmMrLgyaxG6tZXJ1sn7mjBu4fHrJE+Yp/jgylOweJn2xsLMFggQ==" + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==" + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==" + }, + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "requires": { + "type-fest": "^0.5.2" + } + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "arch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", + "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==" + }, + "archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "requires": { + "file-type": "^4.2.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=" + } + } + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=" + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-iterate": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.3.tgz", + "integrity": "sha512-7MIv7HE9MuzfK6B2UnWv07oSHBLOaY1UUXAxZ07bIeRM+4IkPTlveMDs9MY//qvxPZPSvCn2XV4bmtQgSkVodg==" + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "auto-bind": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-2.1.0.tgz", + "integrity": "sha512-qZuFvkes1eh9lB2mg8/HG18C+5GIO51r+RrCSst/lh+i5B1CtVlkhTE488M805Nr3dKl0sM/pIFKSKUIlg3zUg==", + "optional": true, + "requires": { + "@types/react": "^16.8.12" + } + }, + "autoprefixer": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz", + "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==", + "requires": { + "browserslist": "^4.6.3", + "caniuse-lite": "^1.0.30000980", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.17", + "postcss-value-parser": "^4.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + } + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "babel-core": { + "version": "7.0.0-bridge.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", + "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==" + }, + "babel-eslint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-9.0.0.tgz", + "integrity": "sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + } + }, + "babel-extract-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz", + "integrity": "sha512-qWWzi4TlddohA91bFwgt6zO/J0X+io7Qp184Fw0m2JYRSTZnJbFR8+07KmzudHCZgOiKRCrjhylwv9Xd8gfhVQ==", + "requires": { + "babylon": "^6.18.0" + } + }, + "babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "babel-plugin-add-module-exports": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.3.3.tgz", + "integrity": "sha512-hC37mm7aAdEb1n8SgggG8a1QuhZapsY/XLCi4ETSH6AVjXBCWEa50CXlOsAMPPWLnSx5Ns6mzz39uvuseh0Xjg==", + "requires": { + "chokidar": "^2.0.4" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.2.0.tgz", + "integrity": "sha512-yeDwKaLgGdTpXL7RgGt5r6T4LmnTza/hUn5Ul8uZSGGMtEjYo13Nxai7SQaGCTEzUtg9Zq9qJn0EjEr7SeSlTQ==", + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0" + } + }, + "babel-plugin-emotion": { + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.17.tgz", + "integrity": "sha512-KNuBadotqYWpQexHhHOu7M9EV1j2c+Oh/JJqBfEQDusD6mnORsCZKHkl+xYwK82CPQ/23wRrsBIEYnKjtbMQJw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.7.2", + "@emotion/memoize": "0.7.2", + "@emotion/serialize": "^0.11.10", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + } + }, + "babel-plugin-macros": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz", + "integrity": "sha512-6W2nwiXme6j1n2erPOnmRiWfObUhWH7Qw1LMi9XZy8cj+KtESu3T6asZvtk5bMQQjX8te35o7CFueiSdL/2NmQ==", + "requires": { + "@babel/runtime": "^7.4.2", + "cosmiconfig": "^5.2.0", + "resolve": "^1.10.0" + } + }, + "babel-plugin-remove-graphql-queries": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/babel-plugin-remove-graphql-queries/-/babel-plugin-remove-graphql-queries-2.7.3.tgz", + "integrity": "sha512-xuOzXil34XPhkIGE/1EmCyfPlMgX2sXBaNf3n+ico5pM3HNrKc8vHcng9CoK2jnSXEwoX5wASFfKZg1eNNdz1w==" + }, + "babel-plugin-styled-components": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.6.tgz", + "integrity": "sha512-gyQj/Zf1kQti66100PhrCRjI5ldjaze9O0M3emXRPAN80Zsf8+e1thpTpaXJXVHXtaM4/+dJEgZHyS9Its+8SA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-module-imports": "^7.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "babel-preset-fbjs": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz", + "integrity": "sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + } + }, + "babel-preset-gatsby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/babel-preset-gatsby/-/babel-preset-gatsby-0.2.10.tgz", + "integrity": "sha512-MQmh2nERGZvxhMSr5M00AK7mCWSIZBazX8vn75oUdbPQ9LI68xj3i1S0q01RJid+yFFI0k+oEAAKkYAa8TRyqA==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-spread": "^7.2.2", + "@babel/preset-env": "^7.4.1", + "@babel/preset-react": "^7.0.0", + "@babel/runtime": "^7.4.5", + "babel-plugin-dynamic-import-node": "^1.2.0", + "babel-plugin-macros": "^2.6.1", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "bail": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz", + "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "better-opn": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-0.1.4.tgz", + "integrity": "sha512-7V92EnOdjWOB9lKsVsthCcu1FdFT5qNJVTiOgGy5wPuTsSptMMxm2G1FGHgWu22MyX3tyDRzTWk4lxY2Ppdu7A==", + "requires": { + "opn": "^5.4.0" + } + }, + "better-queue": { + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/better-queue/-/better-queue-3.8.10.tgz", + "integrity": "sha512-e3gwNZgDCnNWl0An0Tz6sUjKDV9m6aB+K9Xg//vYeo8+KiH8pWhLFxkawcXhm6FpM//GfD9IQv/kmvWCAVVpKA==", + "requires": { + "better-queue-memory": "^1.0.1", + "node-eta": "^0.9.0", + "uuid": "^3.0.0" + } + }, + "better-queue-memory": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/better-queue-memory/-/better-queue-memory-1.0.4.tgz", + "integrity": "sha512-SWg5wFIShYffEmJpI6LgbL8/3Dqhku7xI1oEiy6FroP9DbcZlG0ZDjxvPdP9t7hTGW40IpIcC6zVoGT1oxjOuA==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + }, + "bin-build": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz", + "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==", + "requires": { + "decompress": "^4.0.0", + "download": "^6.2.2", + "execa": "^0.7.0", + "p-map-series": "^1.0.0", + "tempfile": "^2.0.0" + } + }, + "bin-check": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", + "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", + "requires": { + "execa": "^0.7.0", + "executable": "^4.1.0" + } + }, + "bin-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz", + "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==", + "requires": { + "execa": "^1.0.0", + "find-versions": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "bin-version-check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz", + "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==", + "requires": { + "bin-version": "^3.0.0", + "semver": "^5.6.0", + "semver-truncate": "^1.1.2" + } + }, + "bin-wrapper": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz", + "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==", + "requires": { + "bin-check": "^4.1.0", + "bin-version-check": "^4.0.0", + "download": "^7.1.0", + "import-lazy": "^3.1.0", + "os-filter-obj": "^2.0.0", + "pify": "^4.0.1" + }, + "dependencies": { + "download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "requires": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==" + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==" + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" + }, + "p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "requires": { + "p-timeout": "^2.0.1" + } + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + }, + "bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boxen": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz", + "integrity": "sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^2.4.2", + "cli-boxes": "^2.2.0", + "string-width": "^3.0.0", + "term-size": "^1.2.0", + "type-fest": "^0.3.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cacache": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", + "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cache-manager": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-2.10.0.tgz", + "integrity": "sha512-IuPx05r5L0uZyBDYicB2Llld1o+/1WYjoHUnrC0TNQejMAnkoYxYS9Y8Uwr+lIBytDiyu7dwwmBCup2M9KugwQ==", + "requires": { + "async": "1.5.2", + "lru-cache": "4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.0.tgz", + "integrity": "sha1-tcvwFVbBaWb+vlTO7A+03JDfbCg=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + } + } + }, + "cache-manager-fs-hash": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/cache-manager-fs-hash/-/cache-manager-fs-hash-0.0.7.tgz", + "integrity": "sha512-7X+FPItAJf1tKKqJx6ljDJQc0fgSR5B+KPxFQLj+vYSL4q9XdrCbZldgsNb6wueRuIooj01wt0FubB08zaefRg==", + "requires": { + "es6-promisify": "^6.0.0", + "lockfile": "^1.0.4" + } + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + } + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + } + } + }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + } + } + }, + "caniuse-lite": { + "version": "1.0.30000989", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", + "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==" + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "caw": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", + "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", + "requires": { + "get-proxy": "^2.0.0", + "isurl": "^1.0.0-alpha5", + "tunnel-agent": "^0.6.0", + "url-to-options": "^1.0.1" + } + }, + "ccount": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz", + "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "character-entities": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", + "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==" + }, + "character-entities-html4": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz", + "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==" + }, + "character-entities-legacy": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz", + "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==" + }, + "character-reference-invalid": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz", + "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==" + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "cheerio": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.1", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + }, + "dependencies": { + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + } + } + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + } + } + }, + "chownr": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "cli-boxes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", + "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "optional": true + }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, + "cli-truncate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz", + "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==", + "optional": true, + "requires": { + "slice-ansi": "^1.0.0", + "string-width": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "optional": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + } + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "clipboardy": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", + "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", + "requires": { + "arch": "^2.1.0", + "execa": "^0.8.0" + }, + "dependencies": { + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collapse-white-space": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz", + "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "optional": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "comma-separated-tokens": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.7.tgz", + "integrity": "sha512-Jrx3xsP4pPv4AwJUDWY9wOXGtwPXARej6Xd99h4TUGotmf8APuquKMpK+dnD3UgyxK7OEWaisjZz+3b5jtL6xQ==" + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "confusing-browser-globals": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", + "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==" + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "requires": { + "date-now": "^0.1.4" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "console-stream": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz", + "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=" + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-hrtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-2.0.0.tgz", + "integrity": "sha1-Gb+yyRYvnhHC8Ewsed4rfoCVxic=" + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "copyfiles": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-1.2.0.tgz", + "integrity": "sha1-qNo6xBqiIgrim9PFi2mEKU8sWTw=", + "requires": { + "glob": "^7.0.5", + "ltcdr": "^2.2.1", + "minimatch": "^3.0.3", + "mkdirp": "^0.5.1", + "noms": "0.0.0", + "through2": "^2.0.1" + } + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" + }, + "core-js-compat": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.2.1.tgz", + "integrity": "sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A==", + "requires": { + "browserslist": "^4.6.6", + "semver": "^6.3.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-react-context": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz", + "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + } + } + }, + "cross-fetch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", + "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", + "requires": { + "node-fetch": "2.1.2", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "node-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" + }, + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "css-selector-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.3.0.tgz", + "integrity": "sha1-XxrUPi2O77/cME/NOaUhZklD4+s=" + }, + "css-selector-tokenizer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "css-tree": { + "version": "1.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", + "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.5.3" + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=" + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=" + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=" + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==" + }, + "csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "requires": { + "css-tree": "1.0.0-alpha.29" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==" + } + } + }, + "csstype": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", + "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cwebp-bin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cwebp-bin/-/cwebp-bin-5.1.0.tgz", + "integrity": "sha512-BsPKStaNr98zfxwejWWLIGELbPERULJoD2v5ijvpeutSAGsegX7gmABgnkRK7MUucCPROXXfaPqkLAwI509JzA==", + "requires": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.1", + "logalot": "^2.1.0" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" + }, + "damerau-levenshtein": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", + "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + } + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + } + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + } + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz", + "integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==" + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detab": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.2.tgz", + "integrity": "sha512-Q57yPrxScy816TTE1P/uLRXLDKjXhvYTbfxS/e6lPD+YrqghbsMlGB9nQzj/zVtSPaF0DFPSdO916EWO4sQUyQ==", + "requires": { + "repeat-string": "^1.5.4" + } + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + }, + "detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "devcert-san": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/devcert-san/-/devcert-san-0.3.3.tgz", + "integrity": "sha1-qnckR0Gy2DF3HAEfIu4l45atS6k=", + "requires": { + "@types/configstore": "^2.1.1", + "@types/debug": "^0.0.29", + "@types/get-port": "^0.0.4", + "@types/glob": "^5.0.30", + "@types/mkdirp": "^0.3.29", + "@types/node": "^7.0.11", + "@types/tmp": "^0.0.32", + "command-exists": "^1.2.2", + "configstore": "^3.0.0", + "debug": "^2.6.3", + "eol": "^0.8.1", + "get-port": "^3.0.0", + "glob": "^7.1.1", + "mkdirp": "^0.5.1", + "tmp": "^0.0.31", + "tslib": "^1.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=" + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "dom-serializer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz", + "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==", + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==" + } + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "download": { + "version": "6.2.5", + "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", + "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", + "requires": { + "caw": "^2.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.0.0", + "ext-name": "^5.0.0", + "file-type": "5.2.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^7.0.0", + "make-dir": "^1.0.0", + "p-event": "^1.0.0", + "pify": "^3.0.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + }, + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.237", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.237.tgz", + "integrity": "sha512-SPAFjDr/7iiVK2kgTluwxela6eaWjjFkS9rO/iYpB/KGXgccUom5YC7OIf19c8m8GGptWxLU0Em8xM64A/N7Fg==" + }, + "elliptic": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz", + "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~6.1.0" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==" + }, + "envinfo": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.12.1.tgz", + "integrity": "sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==" + }, + "eol": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/eol/-/eol-0.8.1.tgz", + "integrity": "sha1-3vwyJJkMfspzuzRGGlbPncJHYdA=" + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.3.tgz", + "integrity": "sha512-vRC4rKv87twMZy92X4+TmUdv3iYMsmePbpG/YguHsfzmZ8bYJZYYep7yrXH09yFUaCEPKgNK5X79+Yq7hwLVOA==", + "requires": { + "stackframe": "^1.0.4" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promisify": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.1.tgz", + "integrity": "sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", + "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==" + } + } + }, + "eslint-config-react-app": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-3.0.8.tgz", + "integrity": "sha512-Ovi6Bva67OjXrom9Y/SLJRkrGqKhMAL0XCH8BizPhjEVEhYczl2ZKiNZI2CuqO5/CJwAfMwRXAVGY0KToWr1aA==", + "requires": { + "confusing-browser-globals": "^1.0.6" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-loader": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz", + "integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==", + "requires": { + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-flowtype": { + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "eslint-plugin-graphql": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-graphql/-/eslint-plugin-graphql-3.0.3.tgz", + "integrity": "sha512-hHwLyxSkC5rkakJ/SNTWwOswPdVhvfyMCnEOloevrLQIOHUNVIQBg1ljCaRe9C40HdzgcGUFUdG5BHLCKm8tuw==", + "requires": { + "graphql-config": "^2.0.1", + "lodash": "^4.11.1" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "requires": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + } + } + }, + "eslint-plugin-react": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.entries": "^1.1.0", + "object.fromentries": "^2.0.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==" + }, + "espree": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-source-polyfill": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.8.tgz", + "integrity": "sha512-wC9j5vjH9Xu9s8XhumgBoypdFJswraU1HXykqCCD/b7q+EH4P/avf5fM1e8IiHyHNZOeOiWwrki2775XFTYyeg==" + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" + }, + "eventsource": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", + "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", + "requires": { + "original": ">=0.0.5" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-buffer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz", + "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==", + "requires": { + "execa": "^0.7.0", + "p-finally": "^1.0.0", + "pify": "^3.0.0", + "rimraf": "^2.5.4", + "tempfile": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "requires": { + "pify": "^2.2.0" + } + }, + "exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, + "exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "express-graphql": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.7.1.tgz", + "integrity": "sha512-YpheAqTbSKpb5h57rV2yu2dPNUBi4FvZDspZ5iEV3ov34PBRgnM4lEBkv60+vZRJ6SweYL14N8AGYdov7g6ooQ==", + "requires": { + "accepts": "^1.3.5", + "content-type": "^1.0.4", + "http-errors": "^1.7.1", + "raw-body": "^2.3.3" + } + }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "^2.0.0" + } + }, + "fbjs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", + "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", + "requires": { + "core-js": "^2.4.1", + "fbjs-css-vars": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + }, + "figures": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", + "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-loader": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^0.4.5" + } + }, + "file-type": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", + "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==" + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz", + "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==", + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "filesize": { + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.5.11.tgz", + "integrity": "sha512-ZH7loueKBoDb7yG9esn1U+fgq7BzlzW6NRi5/rMdxIZ05dj7GFD/Xc5rq2CDt5Yq86CyfSYVyx4242QQNZbx1g==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "find-versions": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.1.0.tgz", + "integrity": "sha512-NCTfNiVzeE/xL+roNDffGuRbrWI6atI18lTJ22vKp7rs2OhYzMK3W1dIdO2TUndH/QMcacM4d1uWwgcZcHK69Q==", + "requires": { + "array-uniq": "^2.1.0", + "semver-regex": "^2.0.0" + }, + "dependencies": { + "array-uniq": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", + "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==" + } + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-copy-file-sync": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fs-copy-file-sync/-/fs-copy-file-sync-1.1.1.tgz", + "integrity": "sha512-2QY5eeqVv4m2PfyMiEuy9adxNP+ajf+8AR05cEi+OAzPcOj90hvFImeZhTmKLBgSd9EvG33jsD7ZRxsx9dThkQ==" + }, + "fs-exists-cached": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", + "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=" + }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", + "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gatsby": { + "version": "2.13.73", + "resolved": "https://registry.npmjs.org/gatsby/-/gatsby-2.13.73.tgz", + "integrity": "sha512-5zehGv6BGwOGpa/cX+QST/IH1jN3ebygcXMvb26S0ZoJGxIZyTY9jwGVYQtraoGP7XdQaAh24DF7htuqpjcGhA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@gatsbyjs/relay-compiler": "2.0.0-printer-fix.2", + "@hapi/joi": "^15.1.1", + "@mikaelkristiansson/domready": "^1.0.9", + "@pieh/friendly-errors-webpack-plugin": "1.7.0-chalk-2", + "@reach/router": "^1.2.1", + "address": "1.1.0", + "autoprefixer": "^9.6.1", + "axios": "^0.19.0", + "babel-core": "7.0.0-bridge.0", + "babel-eslint": "^9.0.0", + "babel-loader": "^8.0.0", + "babel-plugin-add-module-exports": "^0.3.3", + "babel-plugin-dynamic-import-node": "^1.2.0", + "babel-plugin-remove-graphql-queries": "^2.7.3", + "babel-preset-gatsby": "^0.2.10", + "better-opn": "0.1.4", + "better-queue": "^3.8.10", + "bluebird": "^3.5.0", + "browserslist": "3.2.8", + "cache-manager": "^2.9.0", + "cache-manager-fs-hash": "^0.0.7", + "chalk": "^2.3.2", + "chokidar": "2.1.6", + "common-tags": "^1.4.0", + "compression": "^1.7.4", + "convert-hrtime": "^2.0.0", + "copyfiles": "^1.2.0", + "core-js": "^2.5.0", + "cors": "^2.8.5", + "css-loader": "^1.0.0", + "debug": "^3.1.0", + "del": "^3.0.0", + "detect-port": "^1.2.1", + "devcert-san": "^0.3.3", + "dotenv": "^4.0.0", + "eslint": "^5.6.0", + "eslint-config-react-app": "^3.0.0", + "eslint-loader": "^2.1.0", + "eslint-plugin-flowtype": "^2.46.1", + "eslint-plugin-graphql": "^3.0.3", + "eslint-plugin-import": "^2.9.0", + "eslint-plugin-jsx-a11y": "^6.0.3", + "eslint-plugin-react": "^7.8.2", + "event-source-polyfill": "^1.0.5", + "express": "^4.16.3", + "express-graphql": "^0.7.1", + "fast-levenshtein": "^2.0.6", + "file-loader": "^1.1.11", + "flat": "^4.0.0", + "fs-exists-cached": "1.0.0", + "fs-extra": "^5.0.0", + "gatsby-cli": "^2.7.34", + "gatsby-core-utils": "^1.0.5", + "gatsby-graphiql-explorer": "^0.2.4", + "gatsby-link": "^2.2.6", + "gatsby-plugin-page-creator": "^2.1.7", + "gatsby-react-router-scroll": "^2.1.4", + "gatsby-telemetry": "^1.1.15", + "glob": "^7.1.1", + "got": "8.0.0", + "graphql": "^14.4.2", + "graphql-compose": "^6.3.2", + "graphql-playground-middleware-express": "^1.7.10", + "invariant": "^2.2.4", + "is-relative": "^1.0.0", + "is-relative-url": "^2.0.0", + "is-wsl": "^1.1.0", + "jest-worker": "^23.2.0", + "json-loader": "^0.5.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.14", + "lokijs": "^1.5.7", + "md5": "^2.2.1", + "md5-file": "^3.1.1", + "micromatch": "^3.1.10", + "mime": "^2.2.0", + "mini-css-extract-plugin": "^0.4.0", + "mitt": "^1.1.2", + "mkdirp": "^0.5.1", + "moment": "^2.21.0", + "name-all-modules-plugin": "^1.0.1", + "normalize-path": "^2.1.1", + "null-loader": "^0.1.1", + "opentracing": "^0.14.3", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "parseurl": "^1.3.2", + "physical-cpu-count": "^2.0.0", + "pnp-webpack-plugin": "^1.4.1", + "postcss-flexbugs-fixes": "^3.0.0", + "postcss-loader": "^2.1.3", + "prop-types": "^15.6.1", + "raw-loader": "^0.5.1", + "react-dev-utils": "^4.2.3", + "react-error-overlay": "^3.0.0", + "react-hot-loader": "^4.12.11", + "redux": "^4.0.0", + "redux-thunk": "^2.3.0", + "semver": "^5.6.0", + "shallow-compare": "^1.2.2", + "sift": "^5.1.0", + "signal-exit": "^3.0.2", + "slash": "^1.0.0", + "socket.io": "^2.0.3", + "stack-trace": "^0.0.10", + "string-similarity": "^1.2.0", + "style-loader": "^0.21.0", + "terser-webpack-plugin": "1.2.4", + "true-case-path": "^2.2.1", + "type-of": "^2.0.1", + "url-loader": "^1.0.1", + "util.promisify": "^1.0.0", + "uuid": "^3.1.0", + "v8-compile-cache": "^1.1.0", + "webpack": "~4.28.4", + "webpack-dev-middleware": "^3.0.1", + "webpack-dev-server": "^3.1.14", + "webpack-hot-middleware": "^2.21.0", + "webpack-merge": "^4.1.0", + "webpack-stats-plugin": "^0.1.5", + "xstate": "^4.3.2", + "yaml-loader": "^0.5.0" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "gatsby-cli": { + "version": "2.7.34", + "resolved": "https://registry.npmjs.org/gatsby-cli/-/gatsby-cli-2.7.34.tgz", + "integrity": "sha512-kc7+ne7cGC74KOv7dBmLC19m2nwYBsLoPZdX3qj9YLDjWsXR/GGGGU48eyADYY1gVpJacaMqk0Lu3dNbsfZBwQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/runtime": "^7.0.0", + "@hapi/joi": "^15.1.1", + "better-opn": "^0.1.4", + "bluebird": "^3.5.0", + "chalk": "^2.4.2", + "ci-info": "^2.0.0", + "clipboardy": "^1.2.3", + "common-tags": "^1.4.0", + "configstore": "^4.0.0", + "convert-hrtime": "^2.0.0", + "core-js": "^2.5.0", + "envinfo": "^5.8.1", + "execa": "^0.8.0", + "fs-exists-cached": "^1.0.0", + "fs-extra": "^4.0.1", + "gatsby-telemetry": "^1.1.15", + "hosted-git-info": "^2.6.0", + "ink": "^2.3.0", + "ink-spinner": "^3.0.1", + "is-valid-path": "^0.1.1", + "lodash": "^4.17.14", + "meant": "^1.0.1", + "node-fetch": "^2.6.0", + "object.entries": "^1.1.0", + "opentracing": "^0.14.3", + "pretty-error": "^2.1.1", + "progress": "^2.0.3", + "prompts": "^2.1.0", + "react": "^16.8.4", + "resolve-cwd": "^2.0.0", + "semver": "^6.3.0", + "source-map": "0.5.7", + "stack-trace": "^0.0.10", + "strip-ansi": "^5.2.0", + "update-notifier": "^2.3.0", + "uuid": "3.3.2", + "yargs": "^12.0.5", + "yurnalist": "^1.0.5" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "gatsby-core-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-1.0.5.tgz", + "integrity": "sha512-XRyZMduCP3yvV8AEKI4sAVWT+M1roW20SWhQwOKtZrYIkMCzlOe9nMOjNOZcJb2vCJsaUBxh2fxLT+OZg8+25A==" + }, + "gatsby-graphiql-explorer": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/gatsby-graphiql-explorer/-/gatsby-graphiql-explorer-0.2.4.tgz", + "integrity": "sha512-2e1HnBuC06L9LInA5mNKyiuaiUEnnRfpedGuuvNFR3nu8+7Q9OwVXuE3EcbWihtjiINyZH7HHD7Za0WRZV6SkQ==", + "requires": { + "@babel/runtime": "^7.0.0" + } + }, + "gatsby-image": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/gatsby-image/-/gatsby-image-2.2.10.tgz", + "integrity": "sha512-wvbxqYWxg7te7ui6RjCgohcVTvcI1b0PBZNor548Flg/0h+oSGnUXVDkz9HO8uS/vWlIbMpXonRxvnZCGu1Y8A==", + "requires": { + "@babel/runtime": "^7.0.0", + "object-fit-images": "^3.2.4", + "prop-types": "^15.6.1" + } + }, + "gatsby-link": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/gatsby-link/-/gatsby-link-2.2.6.tgz", + "integrity": "sha512-FnQ4Z+a5KDmAIoipfGqtELZ/WPB0W67I/jo4ekOPwEu14t6N/VWdTS0mOdJoNCeElNvnJ7cNqlNnEopdU4vbKw==", + "requires": { + "@babel/runtime": "^7.0.0", + "@types/reach__router": "^1.2.4", + "prop-types": "^15.6.1" + } + }, + "gatsby-page-utils": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/gatsby-page-utils/-/gatsby-page-utils-0.0.7.tgz", + "integrity": "sha512-WhZj+VvxWCWU/JRiVFg0SJCXSAnsMz3ABpMJxQv2ByUB0gUUFG90my4oYNEZKuY+mRMKyRiVoexQVuQcnAnoGA==", + "requires": { + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "chokidar": "2.1.6", + "fs-exists-cached": "^1.0.0", + "glob": "^7.1.1", + "lodash": "^4.17.14", + "micromatch": "^3.1.10", + "slash": "^1.0.0" + } + }, + "gatsby-plugin-catch-links": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/gatsby-plugin-catch-links/-/gatsby-plugin-catch-links-2.1.9.tgz", + "integrity": "sha512-UWOty2yuV2tINSv5ToKJfFXUYtaSKtP4zRVeZ3dx+m2v7WO61ap/o3JEMWUAG1n+VaN+TIq2T5Qc9Ln0emDloQ==", + "requires": { + "@babel/runtime": "^7.6.0", + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, + "gatsby-plugin-ipfs": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gatsby-plugin-ipfs/-/gatsby-plugin-ipfs-2.0.2.tgz", + "integrity": "sha512-Igh4K0axPzfvmP8T0w5Vvo789HTaaC0XHTkHG18jTkwW04J5TV+YPULCxVqRRCGL4cEJgpLuX9TR9iCgEu5igA==", + "requires": { + "globby": "^8.0.1", + "is-text-path": "^1.0.1", + "p-map": "^2.0.0" + }, + "dependencies": { + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "gatsby-plugin-manifest": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/gatsby-plugin-manifest/-/gatsby-plugin-manifest-2.2.6.tgz", + "integrity": "sha512-QjOKUOrtwbmiXBAcFi0uvzQEGJa5PELXriJjXNuDmn++72sCybgoluOrY4Ajed+WUf82865RIXq58isK3Dmmgw==", + "requires": { + "@babel/runtime": "^7.0.0", + "gatsby-core-utils": "^1.0.5", + "semver": "^5.6.0", + "sharp": "^0.22.1" + } + }, + "gatsby-plugin-no-sourcemaps": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/gatsby-plugin-no-sourcemaps/-/gatsby-plugin-no-sourcemaps-2.1.1.tgz", + "integrity": "sha512-IaRscMdXD8AFr922HlgftxN09gqmjsA1/RHuLgtJcv+bYhoGGs83XvSOrOq8Szs+5rLEixj3qdNJb59G0LnO8w==" + }, + "gatsby-plugin-offline": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/gatsby-plugin-offline/-/gatsby-plugin-offline-2.2.7.tgz", + "integrity": "sha512-AbX4kAEy8j+8P/kBITdzv/8JR1R+Lt5pAE49ICIzwb7tZDQB7fJisOSc1PGihhQTLuy+ppj9XJDgNhh205lETQ==", + "requires": { + "@babel/runtime": "^7.0.0", + "cheerio": "^1.0.0-rc.2", + "idb-keyval": "^3.1.0", + "lodash": "^4.17.14", + "slash": "^3.0.0", + "workbox-build": "^3.6.3" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + } + } + }, + "gatsby-plugin-page-creator": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-2.1.7.tgz", + "integrity": "sha512-2iRy0kLuAPcVev1VIv9eI05UKe3riiaVd5GMosAaGNI4oUJ9+LiPfXks3kWBSIqwRWv9CyCA6/GhOaVFjrzLLQ==", + "requires": { + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "fs-exists-cached": "^1.0.0", + "gatsby-page-utils": "^0.0.7", + "glob": "^7.1.1", + "lodash": "^4.17.14", + "micromatch": "^3.1.10" + } + }, + "gatsby-plugin-prefetch-google-fonts": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/gatsby-plugin-prefetch-google-fonts/-/gatsby-plugin-prefetch-google-fonts-1.4.3.tgz", + "integrity": "sha512-rrNGpdLkSEQWksM1A1cJnL/wuu9GLfAl8oPQgpn3cmpKd4jnXk+nbLyQOwKQlRYSrzpju59dY8oyf4UfSFbqPg==", + "requires": { + "@babel/runtime": "^7.2.0", + "clean-css": "^4.2.1", + "download": "^7.1.0", + "fs-extra": "^7.0.0", + "get-urls": "^8.0.0", + "globby": "^8.0.1", + "google-fonts-plugin": "2.0.2", + "object-hash": "^1.3.0" + }, + "dependencies": { + "download": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz", + "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==", + "requires": { + "archive-type": "^4.0.0", + "caw": "^2.0.1", + "content-disposition": "^0.5.2", + "decompress": "^4.2.0", + "ext-name": "^5.0.0", + "file-type": "^8.1.0", + "filenamify": "^2.0.0", + "get-stream": "^3.0.0", + "got": "^8.3.1", + "make-dir": "^1.2.0", + "p-event": "^2.1.0", + "pify": "^3.0.0" + } + }, + "file-type": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz", + "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" + }, + "p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "requires": { + "p-timeout": "^2.0.1" + } + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + } + } + }, + "gatsby-plugin-react-helmet": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-3.1.4.tgz", + "integrity": "sha512-L+nP4cv6zdxjKXN9eJJdni7JpPCCSN1V+KWBgID0FELKawFGegkI6zdvKhtBZHz5F+WHh+ak/qfOAYIuLO0eHA==", + "requires": { + "@babel/runtime": "^7.0.0" + } + }, + "gatsby-plugin-root-import": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/gatsby-plugin-root-import/-/gatsby-plugin-root-import-2.0.5.tgz", + "integrity": "sha512-/yA6rFjfjiFb8D6nCjfFrrGqYQMkOt4J3u2o6s7VYEF/zpA5dw2C9ENJ5fDKkJSCbbwLiEIGVMMee3vMEip2zA==" + }, + "gatsby-plugin-sharp": { + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-2.2.13.tgz", + "integrity": "sha512-Wzvwty3ho0T3FSFLDHGAf5D87hvqTsRvphnSP38HGFw0tHAbNtbJSrqr/HA1P5x7Cah4j5duQg4TNH6qtlkAZg==", + "requires": { + "@babel/runtime": "^7.0.0", + "async": "^2.6.3", + "bluebird": "^3.5.0", + "fs-extra": "^7.0.0", + "gatsby-core-utils": "^1.0.5", + "got": "^8.3.2", + "imagemin": "^6.0.0", + "imagemin-mozjpeg": "^8.0.0", + "imagemin-pngquant": "^6.0.0", + "imagemin-webp": "^5.0.0", + "lodash": "^4.17.14", + "mini-svg-data-uri": "^1.0.0", + "potrace": "^2.1.1", + "probe-image-size": "^4.0.0", + "progress": "^2.0.3", + "semver": "^5.6.0", + "sharp": "^0.22.1", + "svgo": "^1.2.0" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + } + } + }, + "gatsby-plugin-styled-components": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/gatsby-plugin-styled-components/-/gatsby-plugin-styled-components-3.1.11.tgz", + "integrity": "sha512-10RgU3FcXNctDfFHpiAKQOmYBZlbeZSOfG1mqjWjz/BmYqkLoIaQfTwEMmBpH40DGf72pG2PUOGoDVDrikPKOA==", + "requires": { + "@babel/runtime": "^7.6.3" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, + "gatsby-react-router-scroll": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/gatsby-react-router-scroll/-/gatsby-react-router-scroll-2.1.4.tgz", + "integrity": "sha512-p9HQ2GrIVmKL3UAk7jqKzOXaigj6tu1xQPAGguO+5+i5ZfD245TQq1UAj1bZr0dJ1DJqRLbTooxPiL7+K05pVg==", + "requires": { + "@babel/runtime": "^7.0.0", + "scroll-behavior": "^0.9.9", + "warning": "^3.0.0" + } + }, + "gatsby-remark-autolink-headers": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/gatsby-remark-autolink-headers/-/gatsby-remark-autolink-headers-2.1.10.tgz", + "integrity": "sha512-MXQuxgTurOXMYi3Rpywz2kMe4Px/H3B2OBy5ZphL9WwOFfaiRK10GkRNMNlHSDNA0K5151PnuSd5mKxLOCxbYw==", + "requires": { + "@babel/runtime": "^7.6.0", + "github-slugger": "^1.2.1", + "lodash": "^4.17.15", + "mdast-util-to-string": "^1.0.6", + "unist-util-visit": "^1.4.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, + "gatsby-remark-prismjs": { + "version": "3.3.13", + "resolved": "https://registry.npmjs.org/gatsby-remark-prismjs/-/gatsby-remark-prismjs-3.3.13.tgz", + "integrity": "sha512-m5EIH2D1PE6kpqaPbas8cd85rIdXoux5Q3FUo5gkKkiBefdTt3Kk1kA2eW/qzEs8hovHWmRigFzA/HsvK8A1/A==", + "requires": { + "@babel/runtime": "^7.6.0", + "parse-numeric-range": "^0.0.2", + "unist-util-visit": "^1.4.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + } + } + }, + "gatsby-source-filesystem": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-2.1.21.tgz", + "integrity": "sha512-CYkj95vp6kNcO/UFYCYmJ78djJZAX1zO2hQyptFNRhto4J5SWB7Zy8Jc0r7sCitMeakfvNOT72y3r7LjcA0dNw==", + "requires": { + "@babel/runtime": "^7.5.5", + "better-queue": "^3.8.10", + "bluebird": "^3.5.5", + "chokidar": "3.0.2", + "file-type": "^12.3.0", + "fs-extra": "^8.1.0", + "gatsby-core-utils": "^1.0.7", + "got": "^7.1.0", + "md5-file": "^3.2.3", + "mime": "^2.4.4", + "pretty-bytes": "^4.0.2", + "progress": "^2.0.3", + "read-chunk": "^3.2.0", + "valid-url": "^1.0.9", + "xstate": "^4.6.7" + }, + "dependencies": { + "anymatch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.0.tgz", + "integrity": "sha512-Ozz7l4ixzI7Oxj2+cw+p0tVUt27BpaJ+1+q1TCeANWxHpvyn2+Un+YamBdfKu0uh8xLodGhoa1v7595NhKDAuA==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", + "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", + "requires": { + "anymatch": "^3.0.1", + "braces": "^3.0.2", + "fsevents": "^2.0.6", + "glob-parent": "^5.0.0", + "is-binary-path": "^2.1.0", + "is-glob": "^4.0.1", + "normalize-path": "^3.0.0", + "readdirp": "^3.1.1" + } + }, + "file-type": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-12.3.0.tgz", + "integrity": "sha512-4E4Esq9KLwjYCY32E7qSmd0h7LefcniZHX+XcdJ4Wfx1uGJX7QCigiqw/U0yT7WOslm28yhxl87DJ0wHYv0RAA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fsevents": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", + "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "optional": true + }, + "gatsby-core-utils": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-1.0.7.tgz", + "integrity": "sha512-G4C/n8tzZVUgs+nLs8Gho7OfgcOWsoKij6az25vCATC9daqrCh1R0ouInqCtIBk7pBim/jt7UAtlClXpp6HyqQ==" + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "got": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", + "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", + "requires": { + "decompress-response": "^3.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "readdirp": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.2.tgz", + "integrity": "sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==", + "requires": { + "picomatch": "^2.0.4" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "gatsby-telemetry": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/gatsby-telemetry/-/gatsby-telemetry-1.1.15.tgz", + "integrity": "sha512-EnKKEiIvqME9hlQRJZXp1V7xOQtgqGLRWHxcIYtRAYS5NJse6rPNnYXIRD3eZn8jXnuBB4kuUeatJLiTHxGbwQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.0", + "boxen": "^3.2.0", + "ci-info": "2.0.0", + "configstore": "^4.0.0", + "envinfo": "^5.8.1", + "fs-extra": "^7.0.1", + "git-up": "4.0.1", + "is-docker": "1.1.0", + "lodash": "^4.17.14", + "node-fetch": "2.3.0", + "resolve-cwd": "^2.0.0", + "source-map": "^0.5.7", + "stack-trace": "^0.0.10", + "stack-utils": "1.0.2", + "uuid": "3.3.2" + }, + "dependencies": { + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "gatsby-transformer-remark": { + "version": "2.6.22", + "resolved": "https://registry.npmjs.org/gatsby-transformer-remark/-/gatsby-transformer-remark-2.6.22.tgz", + "integrity": "sha512-WONmnxXJ86Ko9y7YgQRN+mVoHgv9nTd+IjgLyiuNDuMFKCAUrKSBpTVyqfv8AEYoovGFuaCx1gCp6aT6MKmyzQ==", + "requires": { + "@babel/runtime": "^7.6.0", + "bluebird": "^3.5.5", + "gatsby-core-utils": "^1.0.8", + "gray-matter": "^4.0.2", + "hast-util-raw": "^4.0.0", + "hast-util-to-html": "^4.0.1", + "lodash": "^4.17.15", + "mdast-util-to-hast": "^3.0.4", + "mdast-util-to-string": "^1.0.6", + "mdast-util-toc": "^2.1.0", + "remark": "^10.0.1", + "remark-parse": "^6.0.3", + "remark-retext": "^3.1.3", + "remark-stringify": "^5.0.0", + "retext-english": "^3.0.3", + "sanitize-html": "^1.20.1", + "underscore.string": "^3.3.5", + "unified": "^6.2.0", + "unist-util-remove-position": "^1.1.3", + "unist-util-select": "^1.5.0", + "unist-util-visit": "^1.4.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", + "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "gatsby-core-utils": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-1.0.8.tgz", + "integrity": "sha512-080Jl8NamTbCGliKxXpMjEO1XUYU5FAow+VPR/j6hJk+Kl/gFmpE1mqa5QnHRGLZQhBP/h2T0mUwnSJn9m/Jsw==" + } + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==" + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=" + }, + "get-proxy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", + "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", + "requires": { + "npm-conf": "^1.1.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "get-urls": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-urls/-/get-urls-8.0.0.tgz", + "integrity": "sha512-9c6aVD6HqnpFjqWSoRzSGNo69hNnSa8EevNFVeIRSLYqYlIJNvtHgrqiQ1sUjHwbZPBY5gO1FMlVjmElfdneqw==", + "requires": { + "normalize-url": "^3.3.0", + "url-regex": "^4.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-up": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.1.tgz", + "integrity": "sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw==", + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^5.0.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "github-slugger": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.1.tgz", + "integrity": "sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==", + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=" + } + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=" + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "^1.3.4" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "google-fonts-plugin": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/google-fonts-plugin/-/google-fonts-plugin-2.0.2.tgz", + "integrity": "sha512-pWYFe6zoLA6uIUpSr/pkakf3DwA2fYgpStfe54AmkiKTHMCUILvtqihHaS2f4SqbTpdpEUYVTMMgvs2ur1ge8g==", + "requires": { + "axios": "^0.18.0", + "cssnano": "^4.0.5", + "mkdirp": "^0.5.1", + "neon-js": "^1.1.2", + "path": "^0.12.7" + }, + "dependencies": { + "axios": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", + "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "got": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/got/-/got-8.0.0.tgz", + "integrity": "sha512-lqVA9ORcSGfJPHfMXh1RW451aYMP1NyXivpGqGggnfDqNz3QVfMl7MkuEz+dr70gK2X8dhLiS5YzHhCV3/3yOQ==", + "requires": { + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.1.0", + "is-stream": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.2.0", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "graphql": { + "version": "14.4.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.4.2.tgz", + "integrity": "sha512-6uQadiRgnpnSS56hdZUSvFrVcQ6OF9y6wkxJfKquFtHlnl7+KSuWwSJsdwiK1vybm1HgcdbpGkCpvhvsVQ0UZQ==", + "requires": { + "iterall": "^1.2.2" + } + }, + "graphql-compose": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/graphql-compose/-/graphql-compose-6.3.5.tgz", + "integrity": "sha512-XUpp7JqbaQ+vK/Nw4Jw0CQKs3UU8YFz3wpbBz+6WvPhrMkexco0bIbK4iGW9okQT7+/toAphEdVO4HFqM7lk2w==", + "requires": { + "graphql-type-json": "^0.2.4", + "object-path": "^0.11.4" + } + }, + "graphql-config": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.2.1.tgz", + "integrity": "sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ==", + "requires": { + "graphql-import": "^0.7.1", + "graphql-request": "^1.5.0", + "js-yaml": "^3.10.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.4" + } + }, + "graphql-import": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz", + "integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==", + "requires": { + "lodash": "^4.17.4", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, + "graphql-playground-html": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.12.tgz", + "integrity": "sha512-yOYFwwSMBL0MwufeL8bkrNDgRE7eF/kTHiwrqn9FiR9KLcNIl1xw9l9a+6yIRZM56JReQOHpbQFXTZn1IuSKRg==" + }, + "graphql-playground-middleware-express": { + "version": "1.7.12", + "resolved": "https://registry.npmjs.org/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.7.12.tgz", + "integrity": "sha512-17szgonnVSxWVrgblLRHHLjWnMUONfkULIwSunaMvYx8k5oG3yL86cyGCbHuDFUFkyr2swLhdfYl4mDfDXuvOA==", + "requires": { + "graphql-playground-html": "1.6.12" + } + }, + "graphql-request": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz", + "integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==", + "requires": { + "cross-fetch": "2.2.2" + } + }, + "graphql-type-json": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.2.4.tgz", + "integrity": "sha512-/tq02ayMQjrG4oDFDRLLrPk0KvJXue0nVXoItBe7uAdbNXjQUu+HYCBdAmPLQoseVzUKKMzrhq2P/sfI76ON6w==" + }, + "gray-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.2.tgz", + "integrity": "sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw==", + "requires": { + "js-yaml": "^3.11.0", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + } + }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "requires": { + "duplexer": "^0.1.1" + } + }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hast-to-hyperscript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-5.0.0.tgz", + "integrity": "sha512-DLl3eYTz8uwwzEubDUdCChsR5t5b2ne+yvHrA2h58Suq/JnN3+Gsb9Tc4iZoCCsykmFUc6UUpwxTmQXs0akSeg==", + "requires": { + "comma-separated-tokens": "^1.0.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0", + "style-to-object": "^0.2.1", + "unist-util-is": "^2.0.0", + "web-namespaces": "^1.1.2" + } + }, + "hast-util-from-parse5": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-4.0.2.tgz", + "integrity": "sha512-I6dtjsGtDqz4fmGSiFClFyiXdKhj5bPceS6intta7k/VDuiKz9P61C6hO6WMiNNmEm1b/EtBH8f+juvz4o0uwQ==", + "requires": { + "ccount": "^1.0.3", + "hastscript": "^4.0.0", + "property-information": "^4.0.0", + "web-namespaces": "^1.1.2", + "xtend": "^4.0.1" + } + }, + "hast-util-is-element": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.3.tgz", + "integrity": "sha512-C62CVn7jbjp89yOhhy7vrkSaB7Vk906Gtcw/Ihd+Iufnq+2pwOZjdPmpzpKLWJXPJBMDX3wXg4FqmdOayPcewA==" + }, + "hast-util-parse-selector": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.2.tgz", + "integrity": "sha512-jIMtnzrLTjzqgVEQqPEmwEZV+ea4zHRFTP8Z2Utw0I5HuBOXHzUPPQWr6ouJdJqDKLbFU/OEiYwZ79LalZkmmw==" + }, + "hast-util-raw": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-4.0.0.tgz", + "integrity": "sha512-5xYHyEJMCf8lX/NT4iA5z6N43yoFsrJqXJ5GWwAbLn815URbIz+UNNFEgid33F9paZuDlqVKvB+K3Aqu5+DdSw==", + "requires": { + "hast-util-from-parse5": "^4.0.2", + "hast-util-to-parse5": "^4.0.1", + "html-void-elements": "^1.0.1", + "parse5": "^5.0.0", + "unist-util-position": "^3.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1", + "zwitch": "^1.0.0" + }, + "dependencies": { + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" + } + } + }, + "hast-util-to-html": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-4.0.1.tgz", + "integrity": "sha512-2emzwyf0xEsc4TBIPmDJmBttIw8R4SXAJiJZoiRR/s47ODYWgOqNoDbf2SJAbMbfNdFWMiCSOrI3OVnX6Qq2Mg==", + "requires": { + "ccount": "^1.0.0", + "comma-separated-tokens": "^1.0.1", + "hast-util-is-element": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "html-void-elements": "^1.0.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0", + "stringify-entities": "^1.0.1", + "unist-util-is": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "hast-util-to-parse5": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-4.0.1.tgz", + "integrity": "sha512-U/61W+fsNfBpCyJBB5Pt3l5ypIfgXqEyW9pyrtxF7XrqDJHzcFrYpnC94d0JDYjvobLpYCzcU9srhMRPEO1YXw==", + "requires": { + "hast-to-hyperscript": "^5.0.0", + "property-information": "^4.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.1", + "zwitch": "^1.0.0" + } + }, + "hast-util-whitespace": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.3.tgz", + "integrity": "sha512-AlkYiLTTwPOyxZ8axq2/bCwRUPjIPBfrHkXuCR92B38b3lSdU22R5F/Z4DL6a2kxWpekWq1w6Nj48tWat6GeRA==" + }, + "hastscript": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-4.1.0.tgz", + "integrity": "sha512-bOTn9hEfzewvHyXdbYGKqOr/LOz+2zYhKbC17U2YAjd16mnjqB1BQ0nooM/RdMy/htVyli0NAznXiBtwDi1cmQ==", + "requires": { + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.2.0", + "property-information": "^4.0.0", + "space-separated-tokens": "^1.0.0" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" + }, + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=" + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=" + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "html-void-elements": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.4.tgz", + "integrity": "sha512-yMk3naGPLrfvUV9TdDbuYXngh/TpHbA6TrOw3HL9kS8yhwx7i309BReNg7CbAJXGE+UMJ6je5OqJ7lC63o6YuQ==" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "http-parser-js": { + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "idb-keyval": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-3.2.0.tgz", + "integrity": "sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==" + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "imagemin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz", + "integrity": "sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A==", + "requires": { + "file-type": "^10.7.0", + "globby": "^8.0.1", + "make-dir": "^1.0.0", + "p-pipe": "^1.1.0", + "pify": "^4.0.1", + "replace-ext": "^1.0.0" + }, + "dependencies": { + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "imagemin-mozjpeg": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-8.0.0.tgz", + "integrity": "sha512-+EciPiIjCb8JWjQNr1q8sYWYf7GDCNDxPYnkD11TNIjjWNzaV+oTg4DpOPQjl5ZX/KRCPMEgS79zLYAQzLitIA==", + "requires": { + "execa": "^1.0.0", + "is-jpg": "^2.0.0", + "mozjpeg": "^6.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "imagemin-pngquant": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-6.0.1.tgz", + "integrity": "sha512-Stk+fZCLxZznV8MFNA/T3AY/VRKevsiP9uZOLV0RCXoi0vUUFriySYuz/83IGp9D254EW8miGyyQ69zKouFr7w==", + "requires": { + "execa": "^0.10.0", + "is-png": "^1.0.0", + "is-stream": "^1.1.0", + "pngquant-bin": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + } + } + }, + "imagemin-webp": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/imagemin-webp/-/imagemin-webp-5.1.0.tgz", + "integrity": "sha512-BsPTpobgbDPFBBsI3UflnU/cpIVa15qInEDBcYBw16qI/6XiB4vDF/dGp9l4aM3pfFDDYqR0mANMcKpBD7wbCw==", + "requires": { + "cwebp-bin": "^5.0.0", + "exec-buffer": "^3.0.0", + "is-cwebp-readable": "^2.0.1" + } + }, + "immutable": { + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", + "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks=" + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "ink": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-2.3.0.tgz", + "integrity": "sha512-931rgXHAS3hM++8ygWPOBeHOFwTzHh3pDAVZtiBVOUH6tVvJijym43ODUy22ySo2NwYUFeR/Zj3xuWzBEKMiHw==", + "optional": true, + "requires": { + "@types/react": "^16.8.6", + "arrify": "^1.0.1", + "auto-bind": "^2.0.0", + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "cli-truncate": "^1.1.0", + "is-ci": "^2.0.0", + "lodash.throttle": "^4.1.1", + "log-update": "^3.0.0", + "prop-types": "^15.6.2", + "react-reconciler": "^0.20.0", + "scheduler": "^0.13.2", + "signal-exit": "^3.0.2", + "slice-ansi": "^1.0.0", + "string-length": "^2.0.0", + "widest-line": "^2.0.0", + "wrap-ansi": "^5.0.0", + "yoga-layout-prebuilt": "^1.9.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "optional": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "optional": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "optional": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "optional": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "ink-spinner": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ink-spinner/-/ink-spinner-3.0.1.tgz", + "integrity": "sha512-AVR4Z/NXDQ7dT5ltWcCzFS9Dd4T8eaO//E2UO8VYNiJcZpPCSJ11o5A0UVPcMlZxGbGD6ikUFDR3ZgPUQk5haQ==", + "optional": true, + "requires": { + "cli-spinners": "^1.0.0", + "prop-types": "^15.5.10" + } + }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "inquirer": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz", + "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==", + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + }, + "dependencies": { + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-alphabetical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", + "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==" + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=" + }, + "is-alphanumerical": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz", + "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==", + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.0.0.tgz", + "integrity": "sha512-/93sDihsAD652hrMEbJGbMAVBf1qc96kyThHQ0CAOONHaE3aROLpTjDe4WQ5aoC5ITHFxEq1z8XqSU7km+8amw==", + "requires": { + "builtin-modules": "^3.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-cwebp-readable": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-cwebp-readable/-/is-cwebp-readable-2.0.1.tgz", + "integrity": "sha1-r7k7DAq9CiUQEBauM66ort+SbSY=", + "requires": { + "file-type": "^4.3.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=" + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-decimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", + "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-docker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", + "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=" + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz", + "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==" + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-invalid-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-0.1.0.tgz", + "integrity": "sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ=", + "requires": { + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "is-jpg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz", + "integrity": "sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=" + }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-png": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz", + "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-relative-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-relative-url/-/is-relative-url-2.0.0.tgz", + "integrity": "sha1-cpAtf+BLPUeS59sV+duEtyBMnO8=", + "requires": { + "is-absolute-url": "^2.0.0" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, + "is-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", + "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=" + }, + "is-ssh": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz", + "integrity": "sha512-0eRIASHZt1E68/ixClI8bp2YK2wmBPVWEismTs6M+M099jKgrzl/3E976zIbImSIob48N2/XGe9y7ZiYdImSlg==", + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-valid-path": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-valid-path/-/is-valid-path-0.1.1.tgz", + "integrity": "sha1-EQ+f90w39mPh7HkV60UfLbk6yd8=", + "requires": { + "is-invalid-path": "^0.1.0" + } + }, + "is-what": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.3.1.tgz", + "integrity": "sha512-seFn10yAXy+yJlTRO+8VfiafC+0QJanGLMPTBWLrJm/QPauuchy0UXh8B6H5o9VA8BAzk0iYievt6mNp6gfaqA==" + }, + "is-whitespace-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz", + "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-word-character": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz", + "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "requires": { + "punycode": "2.x.x" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "iterall": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", + "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" + }, + "jest-worker": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.2.0.tgz", + "integrity": "sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=", + "requires": { + "merge-stream": "^1.0.1" + } + }, + "jimp": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.6.4.tgz", + "integrity": "sha512-WQVMoNhkcq/fgthZOWeMdIguCVPg+t4PDFfSxvbNcrECwl8eq3/Ou2whcFWWjyW45m43yAJEY2UT7acDKl6uSQ==", + "requires": { + "@babel/polyfill": "^7.0.0", + "@jimp/custom": "^0.6.4", + "@jimp/plugins": "^0.6.4", + "@jimp/types": "^0.6.4", + "core-js": "^2.5.7" + } + }, + "joi": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz", + "integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==", + "requires": { + "hoek": "4.x.x", + "isemail": "3.x.x", + "topo": "2.x.x" + } + }, + "jpeg-js": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.6.tgz", + "integrity": "sha512-MUj2XlMB8kpe+8DJUGH/3UJm4XpI8XEgZQ+CiHDeyrGoKPdW/8FJv6ku+3UiYm5Fz3CWaL+iXmD8Q4Ap6aC1Jw==" + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "json-loader": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", + "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==" + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", + "requires": { + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" + } + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "requires": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-bmfont": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", + "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==", + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + } + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-fs-cache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz", + "integrity": "sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw==", + "requires": { + "find-cache-dir": "^0.1.1", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "requires": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "requires": { + "signal-exit": "^3.0.2" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, + "lodash.every": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", + "integrity": "sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.maxby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.maxby/-/lodash.maxby-4.6.0.tgz", + "integrity": "sha1-CCJABo88eiJ6oAqDgOTzjPB4bj0=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" + }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "optional": true + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + }, + "log-update": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.2.0.tgz", + "integrity": "sha512-KJ6zAPIHWo7Xg1jYror6IUDFJBq1bQ4Bi4wAEp2y/0ScjBBVi/g0thr0sUVhuvuXauWzczt7T2QHghPDNnKBuw==", + "optional": true, + "requires": { + "ansi-escapes": "^3.2.0", + "cli-cursor": "^2.1.0", + "wrap-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "optional": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "optional": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "optional": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "optional": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "logalot": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz", + "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=", + "requires": { + "figures": "^1.3.5", + "squeak": "^1.0.0" + }, + "dependencies": { + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + } + } + }, + "loglevel": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", + "integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==" + }, + "lokijs": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.7.tgz", + "integrity": "sha512-2SqUV6JH4f15Z5/7LVsyadSUwHhZppxhujgy/VhVqiRYMGt5oaocb7fV/3JGjHJ6rTuEIajnpTLGRz9cJW/c3g==" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "longest-streak": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz", + "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lpad-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz", + "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=", + "requires": { + "get-stdin": "^4.0.1", + "indent-string": "^2.1.0", + "longest": "^1.0.0", + "meow": "^3.3.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "ltcdr": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltcdr/-/ltcdr-2.2.1.tgz", + "integrity": "sha1-Wrh60dTB2rjowIu/A37gwZAih88=" + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz", + "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==" + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==" + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "md5-file": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-3.2.3.tgz", + "integrity": "sha512-3Tkp1piAHaworfcCgH0jKbTvj1jWWFgbvh2cXaNCgHwyTCBxxvD1Y04rmfpvdPm1P4oXMOpm6+2H7sr7v9v8Fw==", + "requires": { + "buffer-alloc": "^1.1.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdast-util-compact": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz", + "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==", + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "mdast-util-definitions": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.4.tgz", + "integrity": "sha512-HfUArPog1j4Z78Xlzy9Q4aHLnrF/7fb57cooTHypyGoe2XFNbcx/kWZDoOz+ra8CkUzvg3+VHV434yqEd1DRmA==", + "requires": { + "unist-util-visit": "^1.0.0" + } + }, + "mdast-util-to-hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.4.tgz", + "integrity": "sha512-/eIbly2YmyVgpJNo+bFLLMCI1XgolO/Ffowhf+pHDq3X4/V6FntC9sGQCDLM147eTS+uSXv5dRzJyFn+o0tazA==", + "requires": { + "collapse-white-space": "^1.0.0", + "detab": "^2.0.0", + "mdast-util-definitions": "^1.2.0", + "mdurl": "^1.0.1", + "trim": "0.0.1", + "trim-lines": "^1.0.0", + "unist-builder": "^1.0.1", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "mdast-util-to-nlcst": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-nlcst/-/mdast-util-to-nlcst-3.2.3.tgz", + "integrity": "sha512-hPIsgEg7zCvdU6/qvjcR6lCmJeRuIEpZGY5xBV+pqzuMOvQajyyF8b6f24f8k3Rw8u40GwkI3aAxUXr3bB2xag==", + "requires": { + "nlcst-to-string": "^2.0.0", + "repeat-string": "^1.5.2", + "unist-util-position": "^3.0.0", + "vfile-location": "^2.0.0" + } + }, + "mdast-util-to-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.6.tgz", + "integrity": "sha512-868pp48gUPmZIhfKrLbaDneuzGiw3OTDjHc5M1kAepR2CWBJ+HpEsm252K4aXdiP5coVZaJPOqGtVU6Po8xnXg==" + }, + "mdast-util-toc": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-2.1.0.tgz", + "integrity": "sha512-ove/QQWSrYOrf9G3xn2MTAjy7PKCtCmm261wpQwecoPAsUtkihkMVczxFqil7VihxgSz4ID9c8bBTsyXR30gQg==", + "requires": { + "github-slugger": "^1.1.1", + "mdast-util-to-string": "^1.0.2", + "unist-util-visit": "^1.1.0" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "meant": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.1.tgz", + "integrity": "sha512-UakVLFjKkbbUwNWJ2frVLnnAtbb7D7DsloxRd3s/gDpI8rdv8W5Hp3NaDb+POBI1fQdeussER6NB8vpcRURvlg==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "merge-anything": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.1.tgz", + "integrity": "sha512-dYOIAl9GFCJNctSIHWOj9OJtarCjsD16P8ObCl6oxrujAG+kOvlwJuOD9/O9iYZ9aTi1RGpGTG9q9etIvuUikQ==", + "requires": { + "is-what": "^3.3.1" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz", + "integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "mini-css-extract-plugin": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.4.5.tgz", + "integrity": "sha512-dqBanNfktnp2hwL2YguV9Jh91PFX7gu7nRLs4TGsbAfAG6WOtlynFRYzwDwmmeSb5uIwHo9nx1ta0f7vAZVp2w==", + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "mini-svg-data-uri": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.1.3.tgz", + "integrity": "sha512-EeKOmdzekjdPe53/GdxmUpNgDQFkNeSte6XkJmOBt4BfWL6FQ9G9RtLNh+JMjFS3LhdpSICMIkZdznjiecASHQ==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "minipass": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "requires": { + "minipass": "^2.2.1" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "mozjpeg": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-6.0.1.tgz", + "integrity": "sha512-9Z59pJMi8ni+IUvSH5xQwK5tNLw7p3dwDNCZ3o1xE+of3G5Hc/yOz6Ue/YuLiBXU3ZB5oaHPURyPdqfBX/QYJA==", + "requires": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.0", + "logalot": "^2.1.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "name-all-modules-plugin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/name-all-modules-plugin/-/name-all-modules-plugin-1.0.1.tgz", + "integrity": "sha1-Cr+2rYNXGLn7Te8GdOBmV6lUN1w=" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "napi-build-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", + "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "neon-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/neon-js/-/neon-js-1.1.2.tgz", + "integrity": "sha1-r4XY4ruAmc/H9v4laolqVGSwBiM=" + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "nlcst-to-string": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-2.0.3.tgz", + "integrity": "sha512-OY2QhGdf6jpYfHqS4vJwqF7aIBZkaMjMUkcHcskMPitvXLuYNGdQvgVWI/5yKwkmIdmhft3ounSJv+Re2yydng==" + }, + "node-abi": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", + "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", + "requires": { + "semver": "^5.4.1" + } + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-eta": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-eta/-/node-eta-0.9.0.tgz", + "integrity": "sha1-n7CwmbzSoCGUDmA8ZCVNwAPZp6g=" + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-forge": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "node-releases": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.27.tgz", + "integrity": "sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA==", + "requires": { + "semver": "^5.3.0" + } + }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + }, + "npm-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", + "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "null-loader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-0.1.1.tgz", + "integrity": "sha1-F76av80/8OFRL2/Er8sfUDk3j64=" + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-fit-images": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/object-fit-images/-/object-fit-images-3.2.4.tgz", + "integrity": "sha512-G+7LzpYfTfqUyrZlfrou/PLLLAPNC52FTy5y1CBywX+1/FkxIloOyQXBmZ3Zxa2AWO+lMF0JTuvqbr7G5e5CWg==" + }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "requires": { + "mimic-fn": "^2.1.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + } + } + }, + "opentracing": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.4.tgz", + "integrity": "sha512-nNnZDkUNExBwEpb7LZaeMeQgvrlO8l4bgY/LvGNZCR0xG/dGWqHqjKrAmR5GUoYo0FIz38kxasvA1aevxWs2CA==" + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimize-css-assets-webpack-plugin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", + "requires": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-filter-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", + "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", + "requires": { + "arch": "^2.1.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "p-cancelable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-event": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", + "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=", + "requires": { + "p-timeout": "^1.1.1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==" + }, + "p-map-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", + "integrity": "sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=", + "requires": { + "p-reduce": "^1.0.0" + } + }, + "p-pipe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", + "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=" + }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=" + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "requires": { + "retry": "^0.12.0" + } + }, + "p-timeout": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", + "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + } + } + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + } + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=" + }, + "parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=" + }, + "parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "requires": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "parse-english": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/parse-english/-/parse-english-4.1.2.tgz", + "integrity": "sha512-+PBf+1ifxqJlOpisODiKX4A8wBEgWm4goMvDB5O9zx/cQI58vzHTZeWFbAgCF9fUXRl8/YdINv1cfmfIRR1acg==", + "requires": { + "nlcst-to-string": "^2.0.0", + "parse-latin": "^4.0.0", + "unist-util-modify-children": "^1.0.0", + "unist-util-visit-children": "^1.0.0" + } + }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-headers": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz", + "integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==", + "requires": { + "for-each": "^0.3.3", + "string.prototype.trim": "^1.1.2" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-latin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-4.2.0.tgz", + "integrity": "sha512-b8PvsA1Ohh7hIQwDDy6kSjx3EbcuR3oKYm5lC1/l/zIB6mVVV5ESEoS1+Qr5+QgEGmp+aEZzc+D145FIPJUszw==", + "requires": { + "nlcst-to-string": "^2.0.0", + "unist-util-modify-children": "^1.0.0", + "unist-util-visit-children": "^1.0.0" + } + }, + "parse-numeric-range": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-0.0.2.tgz", + "integrity": "sha1-tPCdQTx6282Yf26SM8e0shDJOOQ=" + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + }, + "parse-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.1.tgz", + "integrity": "sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA==", + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "parse-url": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.1.tgz", + "integrity": "sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg==", + "requires": { + "is-ssh": "^1.3.0", + "normalize-url": "^3.3.0", + "parse-path": "^4.0.0", + "protocols": "^1.4.0" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "requires": { + "@types/node": "*" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + } + } + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" + }, + "physical-cpu-count": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", + "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=" + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==" + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", + "requires": { + "pngjs": "^3.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + } + } + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" + }, + "pngquant-bin": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-5.0.2.tgz", + "integrity": "sha512-OLdT+4JZx5BqE1CFJkrvomYV0aSsv6x2Bba+aWaVc0PMfWlE+ZByNKYAdKeIqsM4uvW1HOSEHnf8KcOnykPNxA==", + "requires": { + "bin-build": "^3.0.0", + "bin-wrapper": "^4.0.1", + "execa": "^0.10.0", + "logalot": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + } + } + }, + "pnp-webpack-plugin": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz", + "integrity": "sha512-jd9olUr9D7do+RN8Wspzhpxhgp1n6Vd0NtQ4SFkmIACZoEL1nkyAdW9Ygrinjec0vgDcWjscFQQ1gDW8rsfKTg==", + "requires": { + "ts-pnp": "^1.1.2" + } + }, + "portfinder": { + "version": "1.0.23", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.23.tgz", + "integrity": "sha512-B729mL/uLklxtxuiJKfQ84WPxNw5a7Yhx3geQZdcA4GjNjZSTSSMMWyoennMVnTWSmAR0lMdzWYN0JLnHrg1KQ==", + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "postcss": { + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz", + "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", + "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-flexbugs-fixes": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.3.1.tgz", + "integrity": "sha512-9y9kDDf2F9EjKX6x9ueNa5GARvsUbXw4ezH8vXItXHwKzljbu8awP7t5dCaabKYm18Vs1lo5bKQcnc0HkISt+w==", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-load-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + } + }, + "postcss-loader": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.6.tgz", + "integrity": "sha512-hgiWSc13xVQAq25cVw80CH0l49ZKlAnU1hKPOdRrNj89bokRr/bZF2nT+hebPPF9c9xs8c3gw3Fr2nxtmXYnNg==", + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^6.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^0.4.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + } + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==" + } + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz", + "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==" + }, + "potrace": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/potrace/-/potrace-2.1.2.tgz", + "integrity": "sha512-dNcUBapRgPkiv3j+70+rSlf0whtJJqEszC04g9a/Ll3p6kA7QVRV1Vsi3jg22voJr2jA9x9fjPbz5MdD+ngbUg==", + "requires": { + "jimp": "^0.6.4" + } + }, + "prebuild-install": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.0.tgz", + "integrity": "sha512-aaLVANlj4HgZweKttFNUVNRxDukytuIuxeK2boIMHjagNJCiVKWFsKF4tCE3ql3GbrD2tExPQ7/pwtEJcHNZeg==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "os-homedir": "^1.0.1", + "pump": "^2.0.1", + "rc": "^1.2.7", + "simple-get": "^2.7.0", + "tar-fs": "^1.13.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "simple-get": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", + "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + }, + "pretty-bytes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=" + }, + "pretty-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", + "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "requires": { + "renderkid": "^2.0.1", + "utila": "~0.4" + } + }, + "prismjs": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", + "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", + "requires": { + "clipboard": "^2.0.0" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "probe-image-size": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-4.1.1.tgz", + "integrity": "sha512-42LqKZqTLxH/UvAZ2/cKhAsR4G/Y6B7i7fI2qtQu9hRBK4YjS6gqO+QRtwTjvojUx4+/+JuOMzLoFyRecT9qRw==", + "requires": { + "any-promise": "^1.3.0", + "deepmerge": "^4.0.0", + "inherits": "^2.0.3", + "next-tick": "^1.0.0", + "request": "^2.83.0", + "stream-parser": "~0.3.1" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + }, + "prompts": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", + "integrity": "sha512-VObPvJiWPhpZI6C5m60XOzTfnYg/xc/an+r9VYymj9WJW3B/DIH+REzjpAACPf8brwPeP+7vz3bIim3S+AaMjw==", + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "property-information": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-4.2.0.tgz", + "integrity": "sha512-TlgDPagHh+eBKOnH2VYvk8qbwsCG/TAJdmTL7f1PROUcSO8qt/KSmShEQ/OKvock8X9tFjtqjCScyOkkkvIKVQ==", + "requires": { + "xtend": "^4.0.1" + } + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, + "protocols": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz", + "integrity": "sha512-Fx65lf9/YDn3hUX08XUc0J8rSux36rEsyiv21ZGUC1mOyeM3lTRpZLcrm8aAolzS4itwVfm7TAPyxC2E5zd6xg==" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", + "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==" + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + } + } + }, + "raw-loader": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", + "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "react": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", + "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dev-utils": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-4.2.3.tgz", + "integrity": "sha512-uvmkwl5uMexCmC0GUv1XGQP0YjfYePJufGg4YYiukhqk2vN1tQxwWJIBERqhOmSi80cppZg8mZnPP/kOMf1sUQ==", + "requires": { + "address": "1.0.3", + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "cross-spawn": "5.1.0", + "detect-port-alt": "1.1.3", + "escape-string-regexp": "1.0.5", + "filesize": "3.5.11", + "global-modules": "1.0.0", + "gzip-size": "3.0.0", + "inquirer": "3.3.0", + "is-root": "1.0.0", + "opn": "5.1.0", + "react-error-overlay": "^3.0.0", + "recursive-readdir": "2.2.1", + "shell-quote": "1.6.1", + "sockjs-client": "1.1.4", + "strip-ansi": "3.0.1", + "text-table": "0.2.0" + }, + "dependencies": { + "address": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/address/-/address-1.0.3.tgz", + "integrity": "sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==" + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "detect-port-alt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.3.tgz", + "integrity": "sha1-pNLwYddXoDTs83xRQmCph1DysTE=", + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", + "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "react-dom": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", + "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.15.0" + }, + "dependencies": { + "scheduler": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } + } + }, + "react-error-overlay": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-3.0.0.tgz", + "integrity": "sha512-XzgvowFrwDo6TWcpJ/WTiarb9UI6lhA4PMzS7n1joK3sHfBBBOQHUc0U4u57D6DWO9vHv6lVSWx2Q/Ymfyv4hw==" + }, + "react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" + }, + "react-helmet": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-5.2.1.tgz", + "integrity": "sha512-CnwD822LU8NDBnjCpZ4ySh8L6HYyngViTZLfBBb3NjtrpN8m49clH8hidHouq20I51Y6TpCTISCBbqiY5GamwA==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.5.4", + "react-fast-compare": "^2.0.2", + "react-side-effect": "^1.1.0" + } + }, + "react-hot-loader": { + "version": "4.12.11", + "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.12.11.tgz", + "integrity": "sha512-ySsg1hPwr/5dkZCJVp1nZRbwbpbEQ+3e2+bn/D681Wvr9+o+5bLKkTGq0TXskj8HgCS3ScysXddOng9Cg+JKzw==", + "requires": { + "fast-levenshtein": "^2.0.6", + "global": "^4.3.0", + "hoist-non-react-statics": "^3.3.0", + "loader-utils": "^1.1.0", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "shallowequal": "^1.1.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "react-is": { + "version": "16.8.3", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz", + "integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA==" + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-reconciler": { + "version": "0.20.4", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.20.4.tgz", + "integrity": "sha512-kxERc4H32zV2lXMg/iMiwQHOtyqf15qojvkcZ5Ja2CPkjVohHw9k70pdDBwrnQhLVetUJBSYyqU3yqrlVTOajA==", + "optional": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-side-effect": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.1.5.tgz", + "integrity": "sha512-Z2ZJE4p/jIfvUpiUMRydEVpQRf2f8GMHczT6qLcARmX7QRb28JDBTpnM2g/i5y/p7ZDEXYGHWg0RbhikE+hJRw==", + "requires": { + "exenv": "^1.2.1", + "shallowequal": "^1.0.1" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-chunk": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-3.2.0.tgz", + "integrity": "sha512-CEjy9LCzhmD7nUpJ1oVOE6s/hBkejlcJEgLQHVnQznOSilOPb+kpKktlLfFDK3/WP43+F80xkUTM2VOkYoSYvQ==", + "requires": { + "pify": "^4.0.1", + "with-open-file": "^0.1.6" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "rebass": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/rebass/-/rebass-4.0.5.tgz", + "integrity": "sha512-8MZngk/AmbC8u8pGmI1WelbsKYjmN9Z91C11G4ESB9QZnoppWsI+OAqio1/4/l6dxHmwZ/hR8Q4UApF+IVEprA==", + "requires": { + "reflexbox": "^4.0.5" + } + }, + "recursive-readdir": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.1.tgz", + "integrity": "sha1-kO8jHQd4xc4JPJpI105cVCLROpk=", + "requires": { + "minimatch": "3.0.3" + }, + "dependencies": { + "minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "redux": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", + "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, + "reflexbox": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/reflexbox/-/reflexbox-4.0.5.tgz", + "integrity": "sha512-SFWlrlKusgQVqjEimlLGNls3khjMlaTLrrF1H7YY7FfXv/mKK5mREDOW4l95D6Qa1kGoyM3hF+H5RLb3N6bCCA==", + "requires": { + "@emotion/core": "^10.0.0", + "@emotion/styled": "^10.0.0", + "@styled-system/css": "^5.0.0", + "@styled-system/should-forward-prop": "^5.0.0", + "react": "^16.8.6", + "styled-system": "^5.0.0" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-tree": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.11.tgz", + "integrity": "sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==" + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, + "regexpu-core": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz", + "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==" + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + } + } + }, + "relay-runtime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-2.0.0.tgz", + "integrity": "sha512-o/LPFHTI6+3FLJXM3Ec4N6hzkKYILVHYRJThNX0UQlMnqjTVPR6NO4qFE2QzzEiUS+lys+qfnvBzSmNbSh1zWQ==", + "requires": { + "@babel/runtime": "^7.0.0", + "fbjs": "^1.0.0" + } + }, + "remark": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", + "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "requires": { + "remark-parse": "^6.0.0", + "remark-stringify": "^6.0.0", + "unified": "^7.0.0" + }, + "dependencies": { + "remark-stringify": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", + "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "unified": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", + "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "requires": { + "@types/unist": "^2.0.0", + "@types/vfile": "^3.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^3.0.0", + "x-is-string": "^0.1.0" + } + } + } + }, + "remark-parse": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", + "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-retext": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/remark-retext/-/remark-retext-3.1.3.tgz", + "integrity": "sha512-UujXAm28u4lnUvtOZQFYfRIhxX+auKI9PuA2QpQVTT7gYk1OgX6o0OUrSo1KOa6GNrFX+OODOtS5PWIHPxM7qw==", + "requires": { + "mdast-util-to-nlcst": "^3.2.0" + } + }, + "remark-stringify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-5.0.0.tgz", + "integrity": "sha512-Ws5MdA69ftqQ/yhRF9XhVV29mhxbfGhbz0Rx5bQH+oJcNhhSM6nCu1EpLod+DjrFGrU0BMPs+czVmJZU7xiS7w==", + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", + "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "requires": { + "css-select": "^1.1.0", + "dom-converter": "^0.2", + "htmlparser2": "^3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "requires": { + "is-finite": "^1.0.0" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "retext-english": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/retext-english/-/retext-english-3.0.3.tgz", + "integrity": "sha512-qltUsSjHMvCvpAm90qRvzK1DEBOnhSK3tUQk5aHFCBtiMHccp6FhlCH0mQ9vFcBf5BsG7GEBdPysTlY3g9Lchg==", + "requires": { + "parse-english": "^4.0.0", + "unherit": "^1.0.4" + } + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=" + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "requires": { + "aproba": "^1.1.1" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "*" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sanitize-html": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.1.tgz", + "integrity": "sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA==", + "requires": { + "chalk": "^2.4.1", + "htmlparser2": "^3.10.0", + "lodash.clonedeep": "^4.5.0", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.mergewith": "^4.6.1", + "postcss": "^7.0.5", + "srcset": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "optional": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + }, + "scroll-behavior": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/scroll-behavior/-/scroll-behavior-0.9.10.tgz", + "integrity": "sha512-JVJQkBkqMLEM4ATtbHTKare97zhz/qlla9mNttFYY/bcpyOb4BuBGEQ/N9AQWXvshzf6zo9jP60TlphnJ4YPoQ==", + "requires": { + "dom-helpers": "^3.2.1", + "invariant": "^2.2.2" + } + }, + "section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "requires": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "seek-bzip": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", + "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", + "requires": { + "commander": "~2.8.1" + }, + "dependencies": { + "commander": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", + "requires": { + "graceful-readlink": ">= 1.0.0" + } + } + } + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" + }, + "selfsigned": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", + "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "requires": { + "node-forge": "0.7.5" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "^5.0.3" + } + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==" + }, + "semver-truncate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz", + "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=", + "requires": { + "semver": "^5.3.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serialize-javascript": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.8.0.tgz", + "integrity": "sha512-3tHgtF4OzDmeKYj6V9nSyceRS0UJ3C7VqyD2Yj28vC/z2j6jG5FmFGahOKMD9CrglxTm3tETr87jEypaYV8DUg==" + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-compare": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/shallow-compare/-/shallow-compare-1.2.2.tgz", + "integrity": "sha512-LUMFi+RppPlrHzbqmFnINTrazo0lPNwhcgzuAXVVcfy/mqPDrQmHAyz5bvV0gDAuRFrk804V0HpQ6u9sZ0tBeg==" + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "sharp": { + "version": "0.22.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.22.1.tgz", + "integrity": "sha512-lXzSk/FL5b/MpWrT1pQZneKe25stVjEbl6uhhJcTULm7PhmJgKKRbTDM/vtjyUuC/RLqL2PRyC4rpKwbv3soEw==", + "requires": { + "color": "^3.1.1", + "detect-libc": "^1.0.3", + "fs-copy-file-sync": "^1.1.1", + "nan": "^2.13.2", + "npmlog": "^4.1.2", + "prebuild-install": "^5.3.0", + "semver": "^6.0.0", + "simple-get": "^3.0.3", + "tar": "^4.4.8", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "sift": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-5.1.0.tgz", + "integrity": "sha1-G78t+w63HlbEzH+1Z/vRNRtlAV4=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "signedsource": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz", + "integrity": "sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.3.tgz", + "integrity": "sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==", + "requires": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, + "sisteransi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.3.tgz", + "integrity": "sha512-SbEG75TzH8G7eVXFSN5f9EExILKfly7SUvVY5DhhYLvfhKqhDFY0OzevWa/zwak0RLRfWS5AvfMWpd9gJvr5Yg==" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz", + "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.3.1", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.2.0", + "socket.io-parser": "~3.3.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "requires": { + "websocket-driver": ">=0.5.1" + } + } + } + }, + "sockjs-client": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", + "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", + "requires": { + "debug": "^2.6.6", + "eventsource": "0.1.6", + "faye-websocket": "~0.11.0", + "inherits": "^2.0.1", + "json3": "^3.3.2", + "url-parse": "^1.1.8" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "requires": { + "sort-keys": "^1.0.0" + }, + "dependencies": { + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "space-separated-tokens": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz", + "integrity": "sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==" + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "spdy": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "squeak": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz", + "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=", + "requires": { + "chalk": "^1.0.0", + "console-stream": "^0.1.1", + "lpad-align": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "srcset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", + "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", + "requires": { + "array-uniq": "^1.0.2", + "number-is-nan": "^1.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" + }, + "stackframe": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.4.tgz", + "integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==" + }, + "state-toggle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz", + "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-parser": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz", + "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=", + "requires": { + "debug": "2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "optional": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "optional": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "optional": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string-similarity": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", + "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", + "requires": { + "lodash.every": "^4.6.0", + "lodash.flattendeep": "^4.4.0", + "lodash.foreach": "^4.5.0", + "lodash.map": "^4.6.0", + "lodash.maxby": "^4.6.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trim": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz", + "integrity": "sha512-9EIjYD/WdlvLpn987+ctkLf0FfvBefOCuiEr2henD8X+7jfwPnyvTdmW8OJhj5p+M0/96mBdynLWkxUr+rHlpg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" + }, + "strip-comments": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-1.0.2.tgz", + "integrity": "sha512-kL97alc47hoyIQSV165tTt9rG5dn4w1dNnBhOQ3bOU1Nc1hel09jnXANaHJ7vzHLd4Ju8kseDGzlev96pghLFw==", + "requires": { + "babel-extract-comments": "^1.0.0", + "babel-plugin-transform-object-rest-spread": "^6.26.0" + } + }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "requires": { + "is-natural-number": "^4.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "style-loader": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.21.0.tgz", + "integrity": "sha512-T+UNsAcl3Yg+BsPKs1vd22Fr8sVT+CJMtzqc6LEw9bbJZb43lm9GoeIfUcDEefBSWC0BhYbcdupV1GtI4DGzxg==", + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5" + } + }, + "style-to-object": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", + "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, + "styled-components": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.0.tgz", + "integrity": "sha512-xQ6vTI/0zNjZ1BBDRxyjvBddrxhQ3DxjeCdaLM1lSn5FDnkTOQgRkmWvcUiTajqc5nJqKVl+7sUioMqktD0+Zw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "merge-anything": "^2.2.4", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + } + }, + "styled-system": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-system/-/styled-system-5.1.1.tgz", + "integrity": "sha512-jTFstSW5valWSkCsJhgh0fqUFLi1hL+S7Zj6Q6Dj1VTkR77l8B3/mgtSROjjiIwRG9SLW1BsJWjLn8mTNiwqgg==", + "requires": { + "@styled-system/background": "^5.1.1", + "@styled-system/border": "^5.1.1", + "@styled-system/color": "^5.1.1", + "@styled-system/core": "^5.1.1", + "@styled-system/flexbox": "^5.1.1", + "@styled-system/grid": "^5.1.1", + "@styled-system/layout": "^5.1.1", + "@styled-system/position": "^5.1.1", + "@styled-system/shadow": "^5.1.1", + "@styled-system/space": "^5.1.1", + "@styled-system/typography": "^5.1.1", + "@styled-system/variant": "^5.1.1", + "object-assign": "^4.1.1" + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "browserslist": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz", + "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==", + "requires": { + "caniuse-lite": "^1.0.30000984", + "electron-to-chromium": "^1.3.191", + "node-releases": "^1.1.25" + } + }, + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" + }, + "stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "svgo": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", + "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.33", + "csso": "^3.5.1", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + }, + "tar": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", + "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.5", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } + } + }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=" + }, + "tempfile": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz", + "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=", + "requires": { + "temp-dir": "^1.0.0", + "uuid": "^3.0.1" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "^0.7.0" + } + }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "requires": { + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "terser-webpack-plugin": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.4.tgz", + "integrity": "sha512-64IiILNQlACWZLzFlpzNaG0bpQ4ytaB7fwOsbpsdIV70AfLUmIGGeuKL0YV2WmtcrURjE2aOvHD4/lrFV3Rg+Q==", + "requires": { + "cacache": "^11.3.2", + "find-cache-dir": "^2.0.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "source-map": "^0.6.1", + "terser": "^3.17.0", + "webpack-sources": "^1.3.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timm": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz", + "integrity": "sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw==" + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" + }, + "tlds": { + "version": "1.203.1", + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.203.1.tgz", + "integrity": "sha512-7MUlYyGJ6rSitEZ3r1Q1QNV8uSIzapS8SmmhSusBuIc7uIxPPwsKllEP0GRp1NS6Ik6F+fRZvnjDWm3ecv2hDw==" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "topo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", + "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", + "requires": { + "hoek": "4.x.x" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + }, + "trim-lines": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.2.tgz", + "integrity": "sha512-3GOuyNeTqk3FAqc3jOJtw7FTjYl94XBR5aD9QnDbK/T4CA9sW/J0l9RoaRPE9wyPP7NF331qnHnvJFBJ+IDkmQ==" + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "trim-trailing-lines": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz", + "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==" + }, + "trough": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", + "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==" + }, + "true-case-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz", + "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q==" + }, + "ts-pnp": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.2.tgz", + "integrity": "sha512-f5Knjh7XCyRIzoC/z1Su1yLLRrPrFCgtUAh/9fCSP6NKbATwpOL1+idQVXQokK9GRFURn/jYPGPfegIctwunoA==" + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "type-of": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-of/-/type-of-2.0.1.tgz", + "integrity": "sha1-5yoXQYllaOn2KDeNgW1pEvfyOXI=" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ua-parser-js": { + "version": "0.7.20", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", + "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" + }, + "unbzip2-stream": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", + "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + }, + "dependencies": { + "buffer": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.0.tgz", + "integrity": "sha512-Xpgy0IwHK2N01ncykXTy6FpCWuM+CJSHoPVBLyNqyrWxsedpLvwsYUhf0ME3WRFNUhos0dMamz9cOS/xRDtU5g==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + }, + "underscore.string": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", + "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", + "requires": { + "sprintf-js": "^1.0.3", + "util-deprecate": "^1.0.2" + } + }, + "unherit": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", + "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", + "requires": { + "inherits": "^2.0.1", + "xtend": "^4.0.1" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + }, + "unified": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-string": "^0.1.0" + }, + "dependencies": { + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + } + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unist-builder": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.4.tgz", + "integrity": "sha512-v6xbUPP7ILrT15fHGrNyHc1Xda8H3xVhP7/HAIotHOhVPjH5dCXA097C3Rry1Q2O+HbOLCao4hfPB+EYEjHgVg==", + "requires": { + "object-assign": "^4.1.0" + } + }, + "unist-util-generated": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.4.tgz", + "integrity": "sha512-SA7Sys3h3X4AlVnxHdvN/qYdr4R38HzihoEVY2Q2BZu8NHWDnw5OGcC/tXWjQfd4iG+M6qRFNIRGqJmp2ez4Ww==" + }, + "unist-util-is": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", + "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" + }, + "unist-util-modify-children": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.4.tgz", + "integrity": "sha512-8iey9wkoB62C7Vi/8zcRUmi4b1f5AYKTwMkyEgLduo2D8+OY65RoSvbn6k9tVNri6qumXxAwXDVlXWQi0sENTw==", + "requires": { + "array-iterate": "^1.0.0" + } + }, + "unist-util-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.3.tgz", + "integrity": "sha512-28EpCBYFvnMeq9y/4w6pbnFmCUfzlsc41NJui5c51hOFjBA1fejcwc+5W4z2+0ECVbScG3dURS3JTVqwenzqZw==" + }, + "unist-util-remove-position": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz", + "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==", + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-select": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-1.5.0.tgz", + "integrity": "sha1-qTwr6MD2U4J4A7gTMa3sKqJM2TM=", + "requires": { + "css-selector-parser": "^1.1.0", + "debug": "^2.2.0", + "nth-check": "^1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-children": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.3.tgz", + "integrity": "sha512-/GQ8KNRrG+qD30H76FZNc6Ok+8XTu8lxJByN5LnQ4eQfqxda2gP0CPsCX63BRB26ZRMNf6i1c+jlvNlqysEoFg==" + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "requires": { + "unist-util-is": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "^2.0.0" + } + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "requires": { + "ci-info": "^1.5.0" + } + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-loader": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz", + "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", + "requires": { + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + }, + "url-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-4.1.1.tgz", + "integrity": "sha512-ViSDgDPNKkrQHI81GLCjdDN+Rsk3tAW/uLXlBOJxtcHzWZjta58Z0APXhfXzS89YszsheMnEvXeDXsWUB53wwA==", + "requires": { + "ip-regex": "^1.0.1", + "tlds": "^1.187.0" + }, + "dependencies": { + "ip-regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz", + "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=" + } + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "requires": { + "pako": "^1.0.5" + } + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "v8-compile-cache": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz", + "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==" + }, + "valid-url": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", + "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA=" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vendors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz", + "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", + "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "requires": { + "is-buffer": "^2.0.0", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "vfile-location": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz", + "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==" + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "web-namespaces": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.3.tgz", + "integrity": "sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA==" + }, + "webpack": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", + "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", + "requires": { + "@webassemblyjs/ast": "1.7.11", + "@webassemblyjs/helper-module-context": "1.7.11", + "@webassemblyjs/wasm-edit": "1.7.11", + "@webassemblyjs/wasm-parser": "1.7.11", + "acorn": "^5.6.2", + "acorn-dynamic-import": "^3.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", + "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.2", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + } + }, + "webpack-dev-server": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.0.tgz", + "integrity": "sha512-Hs8K9yI6pyMvGkaPTeTonhD6JXVsigXDApYk9JLW4M7viVBspQvb1WdAcWxqtmttxNW4zf2UFLsLNe0y87pIGQ==", + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.6", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "^0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.0", + "killable": "^1.0.1", + "loglevel": "^1.6.3", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.21", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.4", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.1", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.0", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "12.0.5" + }, + "dependencies": { + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + } + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "requires": { + "original": "^1.0.0" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-absolute-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.1.tgz", + "integrity": "sha512-c2QjUwuMxLsld90sj3xYzpFYWJtuxkIn1f5ua9RTEYJt/vV2IsM+Py00/6qjV7qExgifUvt7qfyBGBBKm+2iBg==" + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==" + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==" + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "sockjs-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-hot-middleware": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz", + "integrity": "sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA==", + "requires": { + "ansi-html": "0.0.7", + "html-entities": "^1.2.0", + "querystring": "^0.2.0", + "strip-ansi": "^3.0.0" + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz", + "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==", + "requires": { + "lodash": "^4.17.5" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "webpack-stats-plugin": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/webpack-stats-plugin/-/webpack-stats-plugin-0.1.5.tgz", + "integrity": "sha1-KeXxLr/VMVjTHWVqETrB97hhedk=" + }, + "websocket-driver": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "requires": { + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "requires": { + "string-width": "^2.1.1" + } + }, + "with-open-file": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/with-open-file/-/with-open-file-0.1.6.tgz", + "integrity": "sha512-SQS05JekbtwQSgCYlBsZn/+m2gpn4zWsqpCYIrCHva0+ojXcnmUEPsBN6Ipoz3vmY/81k5PvYEWSxER2g4BTqA==", + "requires": { + "p-finally": "^1.0.0", + "p-try": "^2.1.0", + "pify": "^4.0.1" + }, + "dependencies": { + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "workbox-background-sync": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-3.6.3.tgz", + "integrity": "sha512-ypLo0B6dces4gSpaslmDg5wuoUWrHHVJfFWwl1udvSylLdXvnrfhFfriCS42SNEe5lsZtcNZF27W/SMzBlva7Q==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-broadcast-cache-update": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.6.3.tgz", + "integrity": "sha512-pJl4lbClQcvp0SyTiEw0zLSsVYE1RDlCPtpKnpMjxFtu8lCFTAEuVyzxp9w7GF4/b3P4h5nyQ+q7V9mIR7YzGg==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-build": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-3.6.3.tgz", + "integrity": "sha512-w0clZ/pVjL8VXy6GfthefxpEXs0T8uiRuopZSFVQ8ovfbH6c6kUpEh6DcYwm/Y6dyWPiCucdyAZotgjz+nRz8g==", + "requires": { + "babel-runtime": "^6.26.0", + "common-tags": "^1.4.0", + "fs-extra": "^4.0.2", + "glob": "^7.1.2", + "joi": "^11.1.1", + "lodash.template": "^4.4.0", + "pretty-bytes": "^4.0.2", + "stringify-object": "^3.2.2", + "strip-comments": "^1.0.2", + "workbox-background-sync": "^3.6.3", + "workbox-broadcast-cache-update": "^3.6.3", + "workbox-cache-expiration": "^3.6.3", + "workbox-cacheable-response": "^3.6.3", + "workbox-core": "^3.6.3", + "workbox-google-analytics": "^3.6.3", + "workbox-navigation-preload": "^3.6.3", + "workbox-precaching": "^3.6.3", + "workbox-range-requests": "^3.6.3", + "workbox-routing": "^3.6.3", + "workbox-strategies": "^3.6.3", + "workbox-streams": "^3.6.3", + "workbox-sw": "^3.6.3" + }, + "dependencies": { + "fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, + "workbox-cache-expiration": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-cache-expiration/-/workbox-cache-expiration-3.6.3.tgz", + "integrity": "sha512-+ECNph/6doYx89oopO/UolYdDmQtGUgo8KCgluwBF/RieyA1ZOFKfrSiNjztxOrGJoyBB7raTIOlEEwZ1LaHoA==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-cacheable-response": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-3.6.3.tgz", + "integrity": "sha512-QpmbGA9SLcA7fklBLm06C4zFg577Dt8u3QgLM0eMnnbaVv3rhm4vbmDpBkyTqvgK/Ly8MBDQzlXDtUCswQwqqg==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-core": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-3.6.3.tgz", + "integrity": "sha512-cx9cx0nscPkIWs8Pt98HGrS9/aORuUcSkWjG25GqNWdvD/pSe7/5Oh3BKs0fC+rUshCiyLbxW54q0hA+GqZeSQ==" + }, + "workbox-google-analytics": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-3.6.3.tgz", + "integrity": "sha512-RQBUo/6SXtIaQTRFj4RQZ9e1gAl7D8oS5S+Hi173Kk70/BgJjzPwXpC5A249Jv5YfkCOLMQCeF9A27BiD0b0ig==", + "requires": { + "workbox-background-sync": "^3.6.3", + "workbox-core": "^3.6.3", + "workbox-routing": "^3.6.3", + "workbox-strategies": "^3.6.3" + } + }, + "workbox-navigation-preload": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-3.6.3.tgz", + "integrity": "sha512-dd26xTX16DUu0i+MhqZK/jQXgfIitu0yATM4jhRXEmpMqQ4MxEeNvl2CgjDMOHBnCVMax+CFZQWwxMx/X/PqCw==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-precaching": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-3.6.3.tgz", + "integrity": "sha512-aBqT66BuMFviPTW6IpccZZHzpA8xzvZU2OM1AdhmSlYDXOJyb1+Z6blVD7z2Q8VNtV1UVwQIdImIX+hH3C3PIw==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-range-requests": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-3.6.3.tgz", + "integrity": "sha512-R+yLWQy7D9aRF9yJ3QzwYnGFnGDhMUij4jVBUVtkl67oaVoP1ymZ81AfCmfZro2kpPRI+vmNMfxxW531cqdx8A==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-routing": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-3.6.3.tgz", + "integrity": "sha512-bX20i95OKXXQovXhFOViOK63HYmXvsIwZXKWbSpVeKToxMrp0G/6LZXnhg82ijj/S5yhKNRf9LeGDzaqxzAwMQ==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-strategies": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-3.6.3.tgz", + "integrity": "sha512-Pg5eulqeKet2y8j73Yw6xTgLdElktcWExGkzDVCGqfV9JCvnGuEpz5eVsCIK70+k4oJcBCin9qEg3g3CwEIH3g==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-streams": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-3.6.3.tgz", + "integrity": "sha512-rqDuS4duj+3aZUYI1LsrD2t9hHOjwPqnUIfrXSOxSVjVn83W2MisDF2Bj+dFUZv4GalL9xqErcFW++9gH+Z27w==", + "requires": { + "workbox-core": "^3.6.3" + } + }, + "workbox-sw": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-3.6.3.tgz", + "integrity": "sha512-IQOUi+RLhvYCiv80RP23KBW/NTtIvzvjex28B8NW1jOm+iV4VIu3VXKXTA6er5/wjjuhmtB28qEAUqADLAyOSg==" + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=" + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, + "xhr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", + "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", + "requires": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "requires": { + "min-document": "^2.19.0", + "process": "~0.5.1" + } + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" + } + } + }, + "xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=" + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" + }, + "xstate": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-4.6.7.tgz", + "integrity": "sha512-mqgtH6BXOgjOHVDxZPyW/h6QUC5kfEggh5IN8uOitjzrdCScE/a/cwcRvgcH8CGAXYReDNvasOKD0aFBWAZ1fg==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yaml-loader": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/yaml-loader/-/yaml-loader-0.5.0.tgz", + "integrity": "sha512-p9QIzcFSNm4mCw/m5NdyMfN4RE4aFZJWRRb01ERVNGCym8VNbKtw3OYZXnvUIkim6U/EjqE/2yIh9F/msShH9A==", + "requires": { + "js-yaml": "^3.5.2" + } + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "^4.1.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, + "yoga-layout-prebuilt": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.9.3.tgz", + "integrity": "sha512-9SNQpwuEh2NucU83i2KMZnONVudZ86YNcFk9tq74YaqrQfgJWO3yB9uzH1tAg8iqh5c9F5j0wuyJ2z72wcum2w==", + "optional": true + }, + "yurnalist": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/yurnalist/-/yurnalist-1.0.5.tgz", + "integrity": "sha512-EuLjqX3Q15iVM0UtZa5Ju536uRmklKd2kKhdE5D5fIh8RZmh+pJ8c6wj2oGo0TA+T/Ii2o79cIHCTMfciW8jlA==", + "requires": { + "babel-runtime": "^6.26.0", + "chalk": "^2.1.0", + "cli-table3": "^0.5.1", + "debug": "^4.1.0", + "deep-equal": "^1.0.1", + "detect-indent": "^5.0.0", + "inquirer": "^6.2.0", + "invariant": "^2.2.0", + "is-builtin-module": "^3.0.0", + "is-ci": "^2.0.0", + "leven": "^2.0.0", + "loud-rejection": "^1.2.0", + "node-emoji": "^1.6.1", + "object-path": "^0.11.2", + "read": "^1.0.7", + "rimraf": "^2.5.0", + "semver": "^5.1.0", + "strip-ansi": "^5.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "zwitch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.4.tgz", + "integrity": "sha512-YO803/X+13GNaZB7fVopjvHH0uWQKgJkgKnU1YCjxShjKGVuN9PPHHW8g+uFDpkHpSTNi3rCMKMewIcbC1BAYg==" + } + } +} diff --git a/deps/npm/docs/package.json b/deps/npm/docs/package.json new file mode 100644 index 00000000000000..cc009c53b8a3ee --- /dev/null +++ b/deps/npm/docs/package.json @@ -0,0 +1,45 @@ +{ + "name": "npm-cli-docs", + "description": "npm cli docs", + "version": "0.1.0", + "author": "Tanya Brassie ", + "license": "Artistic-2.0", + "repository": { + "type": "git", + "url": "https://github.com/npm/cli" + }, + "dependencies": { + "babel-plugin-styled-components": "^1.10.6", + "eslint": "^6.3.0", + "gatsby": "^2.13.73", + "gatsby-image": "^2.2.10", + "gatsby-plugin-catch-links": "^2.1.9", + "gatsby-plugin-ipfs": "^2.0.2", + "gatsby-plugin-manifest": "^2.2.6", + "gatsby-plugin-no-sourcemaps": "^2.1.1", + "gatsby-plugin-offline": "^2.2.7", + "gatsby-plugin-prefetch-google-fonts": "^1.4.3", + "gatsby-plugin-react-helmet": "^3.1.4", + "gatsby-plugin-root-import": "^2.0.5", + "gatsby-plugin-sharp": "^2.2.13", + "gatsby-plugin-styled-components": "^3.1.11", + "gatsby-remark-autolink-headers": "^2.1.10", + "gatsby-remark-prismjs": "^3.3.13", + "gatsby-source-filesystem": "^2.1.21", + "gatsby-transformer-remark": "^2.6.22", + "prismjs": "^1.17.1", + "prop-types": "^15.7.2", + "react": "^16.9.0", + "react-dom": "^16.9.0", + "react-helmet": "^5.2.1", + "rebass": "^4.0.5", + "styled-components": "^4.4.0" + }, + "scripts": { + "develop": "gatsby develop", + "start": "npm run develop", + "build": "gatsby build", + "build:static": "GATSBY_IS_STATIC=true gatsby build --prefix-paths", + "serve": "gatsby serve" + } +} diff --git a/deps/npm/docs/src/components/Accordion.js b/deps/npm/docs/src/components/Accordion.js new file mode 100644 index 00000000000000..e7086f4ec09aac --- /dev/null +++ b/deps/npm/docs/src/components/Accordion.js @@ -0,0 +1,57 @@ +import React from 'react' +import styled from 'styled-components' +import downCarrot from '../images/down-carrot.svg' +import upCarrot from '../images/up-carrot.svg' + +const SectionButton = styled.button` + outline: none; + background-color: transparent; + cursor: pointer; + color: red; + border: none; + font-size: 18px; + font-weight: bold; + padding: 5px 0; + transition: opacity .5s; + + &:after { + background: center / contain no-repeat url(${(props) => props.isOpen ? upCarrot : downCarrot}); + content: ''; + height: 11px; + width: 28px; + display: inline-block; + } + + &:hover { + opacity: .6; + } +` + +class Accordion extends React.Component { + constructor (props) { + super(props) + this.state = { + isOpen: true + } + this.onHide = this.onHide.bind(this) + } + + onHide () { + this.setState({isOpen: !this.state.isOpen}) + } + + render () { + return ( +
+ {this.props.section} + {this.state.isOpen && +
+ {this.props.children} +
+ } +
+ ) + } +} + +export default Accordion diff --git a/deps/npm/docs/src/components/Button.js b/deps/npm/docs/src/components/Button.js new file mode 100644 index 00000000000000..f8372ba7cd5126 --- /dev/null +++ b/deps/npm/docs/src/components/Button.js @@ -0,0 +1,22 @@ +import {Link} from 'gatsby' +import {colors} from '../theme' +import styled from 'styled-components' + +export const LinkButton = styled(Link)` + background-color: ${colors.red}; + color: ${colors.white}; + font-size: 20px; + border-radius: 1px; + padding: 20px; + box-shadow: 8px 8px 0 rgba(251,59,73,.2); + text-decoration: none; + text-align: center; + display: inline-block; + min-width: 180px; + font-weight: 700; + transition: opacity .5s; + + &:hover { + opacity: .8; + } +` diff --git a/deps/npm/docs/src/components/DocLinks.js b/deps/npm/docs/src/components/DocLinks.js new file mode 100644 index 00000000000000..f3f5ef6484e953 --- /dev/null +++ b/deps/npm/docs/src/components/DocLinks.js @@ -0,0 +1,72 @@ +import React from 'react' +import styled from 'styled-components' +import {StaticQuery, graphql} from 'gatsby' +import {Flex} from 'rebass' +import {SidebarLink} from './links' +import Accordion from './Accordion' + +const LinkDesc = styled.span` + font-size: 11px; + line-height: 1.5; + text-transform: lowercase; + display: block; + font-weight: 400; + color: ${(props) => props.theme.colors.darkGray}; +` + +const DocLinks = ({data}) => { + const linkInfo = data.allMarkdownRemark.nodes + const sections = ['cli-commands', 'configuring-npm', 'using-npm'] + let sortedData = {} + + sections.map((section) => ( + sortedData[section] = linkInfo.filter(function (item) { + return item.frontmatter.section === section + }) + )) + + return sections.map((section, index) => ( + + {sortedData[section].map((linkData, index) => { + const title = section === 'cli-commands' + ? linkData.frontmatter.title.replace(/(npm-)+([a-zA-Z\\.-]*)/, 'npm $2') + : linkData.frontmatter.title + + return ( + + + {title} + {linkData.frontmatter.description} + + + ) + }) + } + + )) +} + +export default props => ( + } + /> +) diff --git a/deps/npm/docs/src/components/FoundTypo.js b/deps/npm/docs/src/components/FoundTypo.js new file mode 100644 index 00000000000000..5aca0894934dc8 --- /dev/null +++ b/deps/npm/docs/src/components/FoundTypo.js @@ -0,0 +1,23 @@ +import React from 'react' +import styled from 'styled-components' + +const Container = styled.div` + margin: 80px 0; + border-top: 1px solid black; + padding: 20px 0; +` + +const FoundTypo = () => { + return ( + +

👀 Found a typo? Let us know!

+

The current stable version of npm is here. To upgrade, run: npm install npm@latest -g

+

+ To report bugs or submit feature requests for the docs, please post here. + Submit npm issues here. +

+
+ ) +} + +export default FoundTypo diff --git a/deps/npm/docs/src/components/MobileSidebar.js b/deps/npm/docs/src/components/MobileSidebar.js new file mode 100644 index 00000000000000..13835e6aa78a1a --- /dev/null +++ b/deps/npm/docs/src/components/MobileSidebar.js @@ -0,0 +1,33 @@ +import React from 'react' +import styled from 'styled-components' +import DocLinks from './DocLinks' +import {} from '../components/Sidebar' + +const MobileContainer = styled.div` + border-left: 1px solid #86838333; + border-bottom: 1px solid #86838333; + padding: 30px 30px 200px; + width: 340px; + display: block; + height: calc(100vh - 54px); + overflow: scroll; + position: fixed; + top: 54px; + right: 0px; + background-color: ${(props) => props.theme.colors.white}; + z-index: 100; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + display: none; + } +` + +const MobileSidebar = () => { + return ( + + + + ) +} + +export default MobileSidebar diff --git a/deps/npm/docs/src/components/Sidebar.js b/deps/npm/docs/src/components/Sidebar.js new file mode 100644 index 00000000000000..3141cb0fa0fa88 --- /dev/null +++ b/deps/npm/docs/src/components/Sidebar.js @@ -0,0 +1,30 @@ +import React from 'react' +import styled from 'styled-components' +import DocLinks from './DocLinks' + +const Container = styled.nav` + border-right: 1px solid #86838333; + padding: 30px; + height: 100vh; + display: none; + width: 380px; + position: sticky; + overflow: scroll; + padding-bottom: 200px; + top: 54px; + background-color: ${(props) => props.theme.colors.white}; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + display: block; + } +` + +const Sidebar = () => { + return ( + + + + ) +} + +export default Sidebar diff --git a/deps/npm/docs/src/components/home/DarkBlock.js b/deps/npm/docs/src/components/home/DarkBlock.js new file mode 100644 index 00000000000000..bba6a9fc51b3d8 --- /dev/null +++ b/deps/npm/docs/src/components/home/DarkBlock.js @@ -0,0 +1,40 @@ +import React from 'react' +import styled from 'styled-components' +import {Flex, Box} from 'rebass' +import {LinkButton} from '../Button' + +const Container = styled(Flex)` + background-color: ${(props) => props.theme.colors.purpleBlack}; + color: ${(props) => props.theme.colors.white}; +` + +const ContentWrapper = styled(Flex)` + max-width: 640px; + align-items: center; +` + +const Text = styled.p` + line-height: 1.5; + text-align: center; +` + +const aStyle = { + color: '#fb3b49', + textDecoration: 'none' +} + +const DarkBlock = () => { + return ( + + + +

The current stable version of npm is available on GitHub.

+

To upgrade, run: npm install npm@latest -g

+
+ read docs +
+
+ ) +} + +export default DarkBlock diff --git a/deps/npm/docs/src/components/home/FeatureCard.js b/deps/npm/docs/src/components/home/FeatureCard.js new file mode 100644 index 00000000000000..744a01bb7224ff --- /dev/null +++ b/deps/npm/docs/src/components/home/FeatureCard.js @@ -0,0 +1,39 @@ +import React from 'react' +import styled from 'styled-components' +import {Flex, Image, Text} from 'rebass' + +const Card = styled(Flex)` + background-color: #f2f2f2ab; + box-shadow: 5px 5px 1px 1px ${(props) => props.theme.colors.red}; + border-radius: 2px; +` + +const Desc = styled.p` + padding: 5px 0; + font-size: 16px; +` + +const Title = styled(Text)` + font-size: 24px; + font-weight: 500; + text-shadow: 1px 2px 2px #f061df6e; +` + +const Icon = styled(Image)` + width: 110px; + flex-shrink: 0; +` + +const FeatureCard = ({icon, text, title}) => { + return ( + + + + {title} + {text} + + + ) +} + +export default FeatureCard diff --git a/deps/npm/docs/src/components/home/Features.js b/deps/npm/docs/src/components/home/Features.js new file mode 100644 index 00000000000000..e544b4ac9de413 --- /dev/null +++ b/deps/npm/docs/src/components/home/Features.js @@ -0,0 +1,83 @@ +import React from 'react' +import styled from 'styled-components' +import FeatureCard from './FeatureCard' +import { FeatureLink } from '../links' +import { Flex } from 'rebass' +import rectangles from '../../images/background-rectangles.svg' +import terminalIcon from '../../images/terminal-icon.svg' +import networkIcon from '../../images/network-icon.svg' +import npmIcon from '../../images/npm-icon.png' +import managerIcon from '../../images/manager-icon.svg' + +const ContainerInner = styled(Flex)` + background: linear-gradient(84deg, #fb881799, #ff4b0199, #c1212799, #e02aff99); +` + +const Container = styled.div` + background: top / cover no-repeat url(${rectangles}); +` + +const ContentWrapper = styled(Flex)` + max-width: 640px; +` + +const featureTexts = { + textOne: 'Download, install, and configure.', + textTwo: 'All available npm commands.', + textThree: 'How npm things work.', + textFour: 'Publish your own public or private packages to the registry with a free or paid account on npmjs.com from npm, Inc.' +} + +const featureTitles = { + titleOne: 'Getting Started', + titleTwo: 'Command Reference', + titleThree: 'Using npm', + titleFour: 'Publishing' +} + +const aStyle = { + color: '#231f20', + textDecoration: 'none' +} +const productsLink = `https://www.npmjs.com/products` + +const Features = () => { + return ( + + + + + + + + + + + + + + + + + + + ) +} + +export default Features diff --git a/deps/npm/docs/src/components/home/Footer.js b/deps/npm/docs/src/components/home/Footer.js new file mode 100644 index 00000000000000..851b8dd5652a78 --- /dev/null +++ b/deps/npm/docs/src/components/home/Footer.js @@ -0,0 +1,29 @@ +import React from 'react' +import boxes from '../../images/background-boxes.svg' +import styled from 'styled-components' +import {Flex, Box} from 'rebass' + +const Container = styled(Flex)` + background: center / cover no-repeat url(${boxes}); + height: 380px; + background-color: ${(props) => props.theme.colors.offWhite}; + ` + +const ContentWrapper = styled(Box)` + align-content: center; + width: 100%; + text-align: center; + background-color: ${(props) => props.theme.colors.white}; +` + +const Footer = () => { + return ( + + + Footer Text 🤪 + + + ) +} + +export default Footer diff --git a/deps/npm/docs/src/components/home/Terminal.js b/deps/npm/docs/src/components/home/Terminal.js new file mode 100644 index 00000000000000..19d890cb980576 --- /dev/null +++ b/deps/npm/docs/src/components/home/Terminal.js @@ -0,0 +1,120 @@ +import React from 'react' +import styled, {keyframes} from 'styled-components' +import {Flex, Box, Button as RebassButton} from 'rebass' +import closeX from '../../images/x.svg' +import {LinkButton} from '../Button' +import bracket from '../../images/bracket.svg' + +const TerminalBody = styled(Flex)` + background-color: ${(props) => props.theme.colors.purpleBlack}; + border: 2px solid ${(props) => props.theme.colors.purpleBlack}; + color: ${(props) => props.theme.colors.white}; + flex-direction: column; + max-width: 620px; + width: 100%; + height: 100%; + box-shadow: 0px 0px 17px 1px #dc3bc180; + border-radius: 2px; + top: ${(props) => props.top}; + left: ${(props) => props.left}; + right: 0; + position: absolute; +` + +const Top = styled(Flex)` + background-color: ${(props) => props.theme.colors.white}; + height: 18px; +` + +const SiteName = styled(Flex)` + font-size: 45px; + font-family: 'Inconsolata', sans-serif; + font-weight: 700; + letter-spacing: 5px; + text-shadow: 3px 2px 4px #abf1e04d; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + font-size: 70px; + } +` + +const Bottom = styled(Flex)` + flex-direction: column; + padding: 30px; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + font-size: 70px; + padding: 30px 50px; + + } +` + +const blink = keyframes` + 0% { + opacity: 0; + } + 50% { + opacity 1; + } + 100% { + opacity: 0; + } +` + +const Cursor = styled.span` + color: ${(props) => props.theme.colors.red}; + text-shadow: none; + opacity: 1; + animation: ${blink}; + animation-duration: 3s; + animation-iteration-count: infinite; + animation-fill-mode: both; +` + +const Bracket = styled.span` + background: center / contain no-repeat url(${bracket}); + width: 25px; + margin-right: 5px; + margin-top: 10px; +` + +const Text = styled.span` + font-size: 15px; + font-weight: 400; + letter-spacing: 1px; + line-height: 1.4; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + font-size: 18px; + } +` + +const ModalButton = styled(RebassButton)` + cursor: pointer; + background: center no-repeat url(${closeX}); + width: 14px; + height: 14px; +` + +const Terminal = ({onClose, top, left}) => { + return ( + + + + + + npm cli _ + + The intelligent package manager for the Node Javascript Platform. Install stuff and get coding! + + + + read docs + + + + + ) +} + +export default Terminal diff --git a/deps/npm/docs/src/components/home/Windows.js b/deps/npm/docs/src/components/home/Windows.js new file mode 100644 index 00000000000000..fcdfd0eed029ac --- /dev/null +++ b/deps/npm/docs/src/components/home/Windows.js @@ -0,0 +1,73 @@ +import React from 'react' +import Terminal from './Terminal' +import styled from 'styled-components' + +const Container = styled.div` + position: relative; + height: 350px; + width: 80%; + margin: auto; + left: -4%; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + height: 400px; + } +` + +class Windows extends React.Component { + constructor (props) { + super(props) + this.state = { + showTopTerminal: true, + showMiddleTerminal: true, + showBottomTerminal: true, + counter: 0 + } + this.onHide = this.onHide.bind(this) + } + + onHide (terminal) { + this.setState({ [terminal]: false, counter: this.state.counter + 1 }, () => { + if (this.state.counter === 3) { + this.setState({ + showTopTerminal: true, + showMiddleTerminal: true, + showBottomTerminal: true, + counter: 0 + }) + } + }) + } + + render () { + return ( + + {this.state.showTopTerminal && + this.onHide('showTopTerminal')} + top={'0%'} + left={'0%'} + /> + } + + {this.state.showMiddleTerminal && + this.onHide('showMiddleTerminal')} + top={'8%'} + left={'5%'} + /> + } + + {this.state.showBottomTerminal && + this.onHide('showBottomTerminal')} + top={'16%'} + left={'10%'} + /> + } + + ) + } +} + +export default Windows diff --git a/deps/npm/docs/src/components/home/cubes.js b/deps/npm/docs/src/components/home/cubes.js new file mode 100644 index 00000000000000..65a2b8bd953f2b --- /dev/null +++ b/deps/npm/docs/src/components/home/cubes.js @@ -0,0 +1,101 @@ +import styled, {css, keyframes} from 'styled-components' +import purpleCube from '../../images/purple-cube.svg' +import orangeCube from '../../images/orange-cube.svg' +import redCube from '../../images/red-cube.svg' +import purpleGradientCube from '../../images/purple-gradient-cube.svg' +import pinkGradientCube from '../../images/pink-gradient-cube.svg' + +const commonCubeStyles = css` + background-position: center; + background-repeat: no-repeat; + position: absolute; +` + +const wiggle = keyframes` + 0% { + transform: rotate(0deg); + } + 33% { + transform: rotate(8deg); + } + 100% { + transform: rotate(0deg); + } +` + +export const CubeTopLeft = styled.div` + ${commonCubeStyles}; + background-image: url(${purpleCube}); + height: 35px; + width: 35px; + top: 10%; + left: 8%; + + animation-name: ${wiggle}; + animation-duration: 2.5s; + animation-delay: .5s; + animation-iteration-count: infinite; + animation-fill-mode: both; + animation-timing-function: ease-in-out; +` + +export const CubeMiddleLeft = styled.span` + ${commonCubeStyles}; + background-image: url(${orangeCube}); + height: 30px; + width: 30px; + top: 40%; + left: 17%; + + animation-name: ${wiggle}; + animation-duration: 2.5s; + animation-iteration-count: infinite; + animation-fill-mode: both; + animation-timing-function: ease-in-out; +` + +export const CubeBottomLeft = styled.span` + ${commonCubeStyles}; + background-image: url(${redCube}); + height: 45px; + width: 45px; + top: 78%; + left: 12%; + + animation-name: ${wiggle}; + animation-duration: 3s; + animation-iteration-count: infinite; + animation-fill-mode: both; + animation-timing-function: ease-in-out; +` + +export const CubeBottomRight = styled.span` + ${commonCubeStyles}; + background-image: url(${pinkGradientCube}); + height: 40px; + width: 40px; + top: 70%; + right: 12%; + + animation-name: ${wiggle}; + animation-duration: 2.5s; + animation-iteration-count: infinite; + animation-delay: .3s; + animation-fill-mode: both; + animation-timing-function: ease-in-out; +` + +export const CubeTopRight = styled.span` + ${commonCubeStyles}; + background-image: url(${purpleGradientCube}); + height: 40px; + width: 40px; + top: 14%; + right: 12%; + + animation-name: ${wiggle}; + animation-duration: 3s; + animation-iteration-count: infinite; + animation-fill-mode: backwards; + animation-timing-function: ease-in-out; +` diff --git a/deps/npm/docs/src/components/home/hero.js b/deps/npm/docs/src/components/home/hero.js new file mode 100644 index 00000000000000..eb690b290de824 --- /dev/null +++ b/deps/npm/docs/src/components/home/hero.js @@ -0,0 +1,25 @@ +import React from 'react' +import styled from 'styled-components' +import Windows from './Windows' +import {Flex} from 'rebass' +import {CubeTopLeft, CubeMiddleLeft, CubeBottomLeft, CubeTopRight, CubeBottomRight} from './cubes' + +const Container = styled(Flex)` + background-color: ${(props) => props.theme.colors.offWhite}; + position: relative; +` + +const Hero = () => { + return ( + + + + + + + + + ) +} + +export default Hero diff --git a/deps/npm/docs/src/components/layout.js b/deps/npm/docs/src/components/layout.js new file mode 100644 index 00000000000000..ebb2636bfcb17a --- /dev/null +++ b/deps/npm/docs/src/components/layout.js @@ -0,0 +1,24 @@ +import React from 'react' +import Navbar from './navbar' +import Sidebar from './Sidebar' +import {Flex, Box} from 'rebass' +import { theme } from 'src/theme' +import { ThemeProvider } from 'styled-components' + +const IS_STATIC = process.env.GATSBY_IS_STATIC + +const Layout = ({children, path}) => { + const showSidebar = IS_STATIC || path.match(/cli-commands|configuring-npm|using-npm/) + + return ( + + + + {showSidebar && } + {children} + + + ) +} + +export default Layout diff --git a/deps/npm/docs/src/components/links.js b/deps/npm/docs/src/components/links.js new file mode 100644 index 00000000000000..b0424c132cc0c4 --- /dev/null +++ b/deps/npm/docs/src/components/links.js @@ -0,0 +1,50 @@ +import {Link} from 'gatsby' +import styled, {css} from 'styled-components' + +const baseLinkStyles = css` + font-weight: 500; + text-decoration: none; + letter-spacing: .3px; + font-size: 14px; +` +const featureLinkStyles = css` + ${baseLinkStyles} + color: ${(props) => props.theme.colors.black}; + transition: opacity .5s + &:hover { + opacity: .9; + } +` + +const navLinkStyles = css` + ${baseLinkStyles}; + color: ${(props) => props.theme.colors.black}; + transition: opacity .5s; + margin: 0 10px; + + &:hover { + opacity: .5; + } +` +export const FeatureLink = styled(Link)` + ${featureLinkStyles} +` + +export const NavLink = styled(Link)` + ${navLinkStyles}; +` + +export const BasicNavLink = styled.a` + ${navLinkStyles}; +` + +export const SidebarLink = styled(Link)` + ${baseLinkStyles}; + color: ${(props) => props.theme.colors.red}; + padding: 10px; + transition: background-color .3s; + + &:hover { + background-color: ${(props) => props.theme.colors.lightPurple}; + } +` diff --git a/deps/npm/docs/src/components/navbar.js b/deps/npm/docs/src/components/navbar.js new file mode 100644 index 00000000000000..37356a6a47a054 --- /dev/null +++ b/deps/npm/docs/src/components/navbar.js @@ -0,0 +1,136 @@ +import React from 'react' +import styled from 'styled-components' +import {Flex, Image, Box} from 'rebass' +import cliLogo from '../images/cli-logo.svg' +import {Link} from 'gatsby' +import {NavLink, BasicNavLink} from './links' +import MobileSidebar from '../components/MobileSidebar' +import hamburger from '../images/hamburger.svg' +import hamburgerClose from '../images/hamburger-close.svg' + +const IS_STATIC = !!process.env.GATSBY_IS_STATIC + +const Container = styled(Flex)` + width: 100%; + border-bottom: 1px solid #86838333; + position: sticky; + top: 0; + background-color: ${(props) => props.theme.colors.white}; + z-index: 1; +` + +const Inner = styled(Flex)` + border-top: 3px solid; + border-image: linear-gradient(139deg, #fb8817, #ff4b01, #c12127, #e02aff) 3; + margin: auto; + height: 53px; + padding: 0 30px; + align-items: center; + width: 100%; +` + +const Logo = styled(Image)` + width: 120px; + padding: 0px 5px; + height: 18px; + vertical-align: middle; + display: inline-block; + transition: opacity .5s; + + &:hover { + opacity: .8; + } +` + +const Links = styled.ul` + display: none; + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + display: block; + margin-left: auto; + } +` + +const Heart = styled(Box)` + font-size: 15px; + display: inline-block; +` + +const Hamburger = styled.button` + border: none; + background: center no-repeat url(${(props) => props.isOpen ? hamburgerClose : hamburger}); + height: 30px; + width: 30px; + display: block; + margin-left: auto; + transition: opacity .5s; + cursor: pointer; + + &:hover { + opacity: .6; + } + + @media screen and (min-width: ${(props) => props.theme.breakpoints.TABLET}) { + display: none; + } +` + +class Navbar extends React.Component { + constructor (props) { + super(props) + this.state = { + value: null, + showMobileNav: false + } + this.enableBody = this.enableBody.bind(this) + this.toggleNav = this.toggleNav.bind(this) + } + + componentDidMount () { + window.addEventListener('resize', () => { + this.enableBody() + this.setState({showMobileNav: false}) + }) + } + + componentWillUnmount () { + this.enableBody() + } + + enableBody () { + window.document.getElementsByTagName('body')[0].classList.remove('disabled-body') + } + + toggleNav () { + this.setState({showMobileNav: !this.state.showMobileNav}) + window.document.getElementsByTagName('body')[0].classList.toggle('disabled-body') + } + + render () { + return ( + + + + + + + + + docs + + npmjs.org + + + + + {this.state.showMobileNav && } + + ) + } +} + +export default Navbar diff --git a/deps/npm/docs/src/components/scripts.js b/deps/npm/docs/src/components/scripts.js new file mode 100644 index 00000000000000..75126e11ffaf85 --- /dev/null +++ b/deps/npm/docs/src/components/scripts.js @@ -0,0 +1,27 @@ +import React from 'react' + +const IS_STATIC = process.env.GATSBY_IS_STATIC + +const Scripts = () => { + // Workaround: Make links work on the static html site + if (IS_STATIC) { + return ( + - - -
- -

npm

a JavaScript package manager

-

Build Status

-

SYNOPSIS

-

This is just enough info to get you up and running.

-

Much more info will be available via npm help once it's installed.

-

IMPORTANT

-

You need node v6 or higher to run this program.

-

To install an old and unsupported version of npm that works on node v5 -and prior, clone the git repo and dig through the old tags and branches.

-

npm is configured to use npm, Inc.'s public registry at -https://registry.npmjs.org by default. Use of the npm public registry -is subject to terms of use available at https://www.npmjs.com/policies/terms.

-

You can configure npm to use any compatible registry you -like, and even run your own registry. Check out the doc on -registries.

-

Super Easy Install

-

npm is bundled with node.

-

Windows Computers

-

Get the MSI. npm is in it.

-

Apple Macintosh Computers

-

Get the pkg. npm is in it.

-

Other Sorts of Unices

-

Run make install. npm will be installed with node.

-

If you want a more fancy pants install (a different version, customized -paths, etc.) then read on.

-

Fancy Install (Unix)

-

There's a pretty robust install script at -https://www.npmjs.com/install.sh. You can download that and run it.

-

Here's an example using curl:

-
curl -L https://www.npmjs.com/install.sh | sh
-

Slightly Fancier

-

You can set any npm configuration params with that script:

-
npm_config_prefix=/some/path sh install.sh
-

Or, you can run it in uber-debuggery mode:

-
npm_debug=1 sh install.sh
-

Even Fancier

-

Get the code with git. Use make to build the docs and do other stuff. -If you plan on hacking on npm, make link is your friend.

-

If you've got the npm source code, you can also semi-permanently set -arbitrary config keys using the ./configure --key=val ..., and then -run npm commands by doing node bin/npm-cli.js <command> <args>. (This is helpful -for testing, or running stuff without actually installing npm itself.)

-

Windows Install or Upgrade

-

Many improvements for Windows users have been made in npm 3 - you will have a better -experience if you run a recent version of npm. To upgrade, either use Microsoft's -upgrade tool, -download a new version of Node, -or follow the Windows upgrade instructions in the -Installing/upgrading npm post.

-

If that's not fancy enough for you, then you can fetch the code with -git, and mess with it directly.

-

Installing on Cygwin

-

No.

-

Uninstalling

-

So sad to see you go.

-
sudo npm uninstall npm -g
-

Or, if that fails,

-
sudo make uninstall
-

More Severe Uninstalling

-

Usually, the above instructions are sufficient. That will remove -npm, but leave behind anything you've installed.

-

If you would like to remove all the packages that you have installed, -then you can use the npm ls command to find them, and then npm rm to -remove them.

-

To remove cruft left behind by npm 0.x, you can use the included -clean-old.sh script file. You can run it conveniently like this:

-
npm explore npm -g -- sh scripts/clean-old.sh
-

npm uses two configuration files, one for per-user configs, and another -for global (every-user) configs. You can view them by doing:

-
npm config get userconfig   # defaults to ~/.npmrc
-npm config get globalconfig # defaults to /usr/local/etc/npmrc
-

Uninstalling npm does not remove configuration files by default. You -must remove them yourself manually if you want them gone. Note that -this means that future npm installs will not remember the settings that -you have chosen.

-

More Docs

-

Check out the docs.

-

You can use the npm help command to read any of them.

-

If you're a developer, and you want to use npm to publish your program, -you should read this.

-

BUGS

-

When you find issues, please report them:

- -

Be sure to include all of the output from the npm command that didn't work -as expected. The npm-debug.log file is also helpful to provide.

-

You can also find npm people in #npm on https://package.community/ or -on Twitter. Whoever responds will no -doubt tell you to put the output in a gist or email.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-access.html b/deps/npm/html/doc/cli/npm-access.html deleted file mode 100644 index 33411d29397238..00000000000000 --- a/deps/npm/html/doc/cli/npm-access.html +++ /dev/null @@ -1,97 +0,0 @@ - - - npm-access - - - - - - -
- -

npm-access

Set access level on published packages

-

SYNOPSIS

-
npm access public [<package>]
-npm access restricted [<package>]
-
-npm access grant <read-only|read-write> <scope:team> [<package>]
-npm access revoke <scope:team> [<package>]
-
-npm access 2fa-required [<package>]
-npm access 2fa-not-required [<package>]
-
-npm access ls-packages [<user>|<scope>|<scope:team>]
-npm access ls-collaborators [<package> [<user>]]
-npm access edit [<package>]

DESCRIPTION

-

Used to set access controls on private packages.

-

For all of the subcommands, npm access will perform actions on the packages -in the current working directory if no package name is passed to the -subcommand.

-
    -
  • public / restricted: -Set a package to be either publicly accessible or restricted.

    -
  • -
  • grant / revoke: -Add or remove the ability of users and teams to have read-only or read-write -access to a package.

    -
  • -
  • 2fa-required / 2fa-not-required: -Configure whether a package requires that anyone publishing it have two-factor -authentication enabled on their account.

    -
  • -
  • ls-packages: -Show all of the packages a user or a team is able to access, along with the -access level, except for read-only public packages (it won't print the whole -registry listing)

    -
  • -
  • ls-collaborators: -Show all of the access privileges for a package. Will only show permissions -for packages to which you have at least read access. If <user> is passed in, -the list is filtered only to teams that user happens to belong to.

    -
  • -
  • edit: -Set the access privileges for a package at once using $EDITOR.

    -
  • -
-

DETAILS

-

npm access always operates directly on the current registry, configurable -from the command line using --registry=<registry url>.

-

Unscoped packages are always public.

-

Scoped packages default to restricted, but you can either publish them as -public using npm publish --access=public, or set their access as public using -npm access public after the initial publish.

-

You must have privileges to set the access of a package:

-
    -
  • You are an owner of an unscoped or scoped package.
  • -
  • You are a member of the team that owns a scope.
  • -
  • You have been given read-write privileges for a package, either as a member -of a team or directly as an owner.
  • -
-

If you have two-factor authentication enabled then you'll have to pass in an -otp with --otp when making access changes.

-

If your account is not paid, then attempts to publish scoped packages will fail -with an HTTP 402 status code (logically enough), unless you use ---access=public.

-

Management of teams and team memberships is done with the npm team command.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-adduser.html b/deps/npm/html/doc/cli/npm-adduser.html deleted file mode 100644 index 2b29655abe1ab7..00000000000000 --- a/deps/npm/html/doc/cli/npm-adduser.html +++ /dev/null @@ -1,82 +0,0 @@ - - - npm-adduser - - - - - - -
- -

npm-adduser

Add a registry user account

-

SYNOPSIS

-
npm adduser [--registry=url] [--scope=@orgname] [--always-auth] [--auth-type=legacy]
-
-aliases: login, add-user

DESCRIPTION

-

Create or verify a user named <username> in the specified registry, and -save the credentials to the .npmrc file. If no registry is specified, -the default registry will be used (see npm-config(7)).

-

The username, password, and email are read in from prompts.

-

To reset your password, go to https://www.npmjs.com/forgot

-

To change your email address, go to https://www.npmjs.com/email-edit

-

You may use this command multiple times with the same user account to -authorize on a new machine. When authenticating on a new machine, -the username, password and email address must all match with -your existing record.

-

npm login is an alias to adduser and behaves exactly the same way.

-

CONFIGURATION

-

registry

-

Default: https://registry.npmjs.org/

-

The base URL of the npm package registry. If scope is also specified, -this registry will only be used for packages with that scope. scope defaults -to the scope of the project directory you're currently in, if any. See npm-scope(7).

-

scope

-

Default: none

-

If specified, the user and login credentials given will be associated -with the specified scope. See npm-scope(7). You can use both at the same time, -e.g.

-
npm adduser --registry=http://myregistry.example.com --scope=@myco

This will set a registry for the given scope and login or create a user for -that registry at the same time.

-

always-auth

-

Default: false

-

If specified, save configuration indicating that all requests to the given -registry should include authorization information. Useful for private -registries. Can be used with --registry and / or --scope, e.g.

-
npm adduser --registry=http://private-registry.example.com --always-auth

This will ensure that all requests to that registry (including for tarballs) -include an authorization header. This setting may be necessary for use with -private registries where metadata and package tarballs are stored on hosts with -different hostnames. See always-auth in npm-config(7) for more details on -always-auth. Registry-specific configuration of always-auth takes precedence -over any global configuration.

-

auth-type

-
    -
  • Default: 'legacy'
  • -
  • Type: 'legacy', 'sso', 'saml', 'oauth'
  • -
-

What authentication strategy to use with adduser/login. Some npm registries -(for example, npmE) might support alternative auth strategies besides classic -username/password entry in legacy npm.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-audit.html b/deps/npm/html/doc/cli/npm-audit.html deleted file mode 100644 index a7064a719653c5..00000000000000 --- a/deps/npm/html/doc/cli/npm-audit.html +++ /dev/null @@ -1,97 +0,0 @@ - - - npm-audit - - - - - - -
- -

npm-audit

Run a security audit

-

SYNOPSIS

-
npm audit [--json|--parseable|--audit-level=(low|moderate|high|critical)]
-npm audit fix [--force|--package-lock-only|--dry-run]
-
-common options: [--production] [--only=(dev|prod)]

EXAMPLES

-

Scan your project for vulnerabilities and automatically install any compatible -updates to vulnerable dependencies:

-
$ npm audit fix

Run audit fix without modifying node_modules, but still updating the -pkglock:

-
$ npm audit fix --package-lock-only

Skip updating devDependencies:

-
$ npm audit fix --only=prod

Have audit fix install semver-major updates to toplevel dependencies, not just -semver-compatible ones:

-
$ npm audit fix --force

Do a dry run to get an idea of what audit fix will do, and also output -install information in JSON format:

-
$ npm audit fix --dry-run --json

Scan your project for vulnerabilities and just show the details, without fixing -anything:

-
$ npm audit

Get the detailed audit report in JSON format:

-
$ npm audit --json

Get the detailed audit report in plain text result, separated by tab characters, allowing for -future reuse in scripting or command line post processing, like for example, selecting -some of the columns printed:

-
$ npm audit --parseable

To parse columns, you can use for example awk, and just print some of them:

-
$ npm audit --parseable | awk -F $'\t' '{print $1,$4}'

Fail an audit only if the results include a vulnerability with a level of moderate or higher:

-
$ npm audit --audit-level=moderate

DESCRIPTION

-

The audit command submits a description of the dependencies configured in -your project to your default registry and asks for a report of known -vulnerabilities. The report returned includes instructions on how to act on -this information. The command will exit with a 0 exit code if no -vulnerabilities were found.

-

You can also have npm automatically fix the vulnerabilities by running npm -audit fix. Note that some vulnerabilities cannot be fixed automatically and -will require manual intervention or review. Also note that since npm audit fix -runs a full-fledged npm install under the hood, all configs that apply to the -installer will also apply to npm install -- so things like npm audit fix ---package-lock-only will work as expected.

-

By default, the audit command will exit with a non-zero code if any vulnerability -is found. It may be useful in CI environments to include the --audit-level parameter -to specify the minimum vulnerability level that will cause the command to fail. This -option does not filter the report output, it simply changes the command's failure -threshold.

-

CONTENT SUBMITTED

-
    -
  • npm_version
  • -
  • node_version
  • -
  • platform
  • -
  • node_env
  • -
  • A scrubbed version of your package-lock.json or npm-shrinkwrap.json
  • -
-

SCRUBBING

-

In order to ensure that potentially sensitive information is not included in -the audit data bundle, some dependencies may have their names (and sometimes -versions) replaced with opaque non-reversible identifiers. It is done for -the following dependency types:

-
    -
  • Any module referencing a scope that is configured for a non-default -registry has its name scrubbed. (That is, a scope you did a npm login --scope=@ourscope for.)
  • -
  • All git dependencies have their names and specifiers scrubbed.
  • -
  • All remote tarball dependencies have their names and specifiers scrubbed.
  • -
  • All local directory and tarball dependencies have their names and specifiers scrubbed.
  • -
-

The non-reversible identifiers are a sha256 of a session-specific UUID and the -value being replaced, ensuring a consistent value within the payload that is -different between runs.

-

EXIT CODE

-

The npm audit command will exit with a 0 exit code if no vulnerabilities were found.

-

If vulnerabilities were found the exit code will depend on the audit-level -configuration setting.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-bin.html b/deps/npm/html/doc/cli/npm-bin.html deleted file mode 100644 index f0af59c8b4cf2b..00000000000000 --- a/deps/npm/html/doc/cli/npm-bin.html +++ /dev/null @@ -1,38 +0,0 @@ - - - npm-bin - - - - - - -
- -

npm-bin

Display npm bin folder

-

SYNOPSIS

-
npm bin [-g|--global]

DESCRIPTION

-

Print the folder where npm will install executables.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-bugs.html b/deps/npm/html/doc/cli/npm-bugs.html deleted file mode 100644 index 3988ff3c5bb007..00000000000000 --- a/deps/npm/html/doc/cli/npm-bugs.html +++ /dev/null @@ -1,58 +0,0 @@ - - - npm-bugs - - - - - - -
- -

npm-bugs

Bugs for a package in a web browser maybe

-

SYNOPSIS

-
npm bugs [<pkgname>]
-
-aliases: issues

DESCRIPTION

-

This command tries to guess at the likely location of a package's -bug tracker URL, and then tries to open it using the --browser -config param. If no package name is provided, it will search for -a package.json in the current folder and use the name property.

-

CONFIGURATION

-

browser

-
    -
  • Default: OS X: "open", Windows: "start", Others: "xdg-open"
  • -
  • Type: String
  • -
-

The browser that is called by the npm bugs command to open websites.

-

registry

- -

The base URL of the npm package registry.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-build.html b/deps/npm/html/doc/cli/npm-build.html deleted file mode 100644 index 7b86bb7f8ee4c6..00000000000000 --- a/deps/npm/html/doc/cli/npm-build.html +++ /dev/null @@ -1,42 +0,0 @@ - - - npm-build - - - - - - -
- -

npm-build

Build a package

-

SYNOPSIS

-
npm build [<package-folder>]
    -
  • <package-folder>: -A folder containing a package.json file in its root.
  • -
-

DESCRIPTION

-

This is the plumbing command called by npm link and npm install.

-

It should generally be called during installation, but if you need to run it -directly, run:

-
npm run-script build

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-bundle.html b/deps/npm/html/doc/cli/npm-bundle.html deleted file mode 100644 index 818e407bac7d4f..00000000000000 --- a/deps/npm/html/doc/cli/npm-bundle.html +++ /dev/null @@ -1,35 +0,0 @@ - - - npm-bundle - - - - - - -
- -

npm-bundle

REMOVED

-

DESCRIPTION

-

The npm bundle command has been removed in 1.0, for the simple reason -that it is no longer necessary, as the default behavior is now to -install packages into the local space.

-

Just use npm install now to do what npm bundle used to do.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-cache.html b/deps/npm/html/doc/cli/npm-cache.html deleted file mode 100644 index 132f9c3b1c4e5f..00000000000000 --- a/deps/npm/html/doc/cli/npm-cache.html +++ /dev/null @@ -1,92 +0,0 @@ - - - npm-cache - - - - - - -
- -

npm-cache

Manipulates packages cache

-

SYNOPSIS

-
npm cache add <tarball file>
-npm cache add <folder>
-npm cache add <tarball url>
-npm cache add <name>@<version>
-
-npm cache clean [<path>]
-aliases: npm cache clear, npm cache rm
-
-npm cache verify

DESCRIPTION

-

Used to add, list, or clean the npm cache folder.

-
    -
  • add: -Add the specified package to the local cache. This command is primarily -intended to be used internally by npm, but it can provide a way to -add data to the local installation cache explicitly.

    -
  • -
  • clean: -Delete all data out of the cache folder.

    -
  • -
  • verify: -Verify the contents of the cache folder, garbage collecting any unneeded data, -and verifying the integrity of the cache index and all cached data.

    -
  • -
-

DETAILS

-

npm stores cache data in an opaque directory within the configured cache, -named _cacache. This directory is a cacache-based content-addressable cache -that stores all http request data as well as other package-related data. This -directory is primarily accessed through pacote, the library responsible for -all package fetching as of npm@5.

-

All data that passes through the cache is fully verified for integrity on both -insertion and extraction. Cache corruption will either trigger an error, or -signal to pacote that the data must be refetched, which it will do -automatically. For this reason, it should never be necessary to clear the cache -for any reason other than reclaiming disk space, thus why clean now requires ---force to run.

-

There is currently no method exposed through npm to inspect or directly manage -the contents of this cache. In order to access it, cacache must be used -directly.

-

npm will not remove data by itself: the cache will grow as new packages are -installed.

-

A NOTE ABOUT THE CACHE'S DESIGN

-

The npm cache is strictly a cache: it should not be relied upon as a persistent -and reliable data store for package data. npm makes no guarantee that a -previously-cached piece of data will be available later, and will automatically -delete corrupted contents. The primary guarantee that the cache makes is that, -if it does return data, that data will be exactly the data that was inserted.

-

To run an offline verification of existing cache contents, use npm cache -verify.

-

CONFIGURATION

-

cache

-

Default: ~/.npm on Posix, or %AppData%/npm-cache on Windows.

-

The root cache folder.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-ci.html b/deps/npm/html/doc/cli/npm-ci.html deleted file mode 100644 index c308ab4fa0bd99..00000000000000 --- a/deps/npm/html/doc/cli/npm-ci.html +++ /dev/null @@ -1,61 +0,0 @@ - - - npm-ci - - - - - - -
- -

npm-ci

Install a project with a clean slate

-

SYNOPSIS

-
npm ci

EXAMPLE

-

Make sure you have a package-lock and an up-to-date install:

-
$ cd ./my/npm/project
-$ npm install
-added 154 packages in 10s
-$ ls | grep package-lock

Run npm ci in that project

-
$ npm ci
-added 154 packages in 5s

Configure Travis to build using npm ci instead of npm install:

-
# .travis.yml
-install:
-- npm ci
-# keep the npm cache around to speed up installs
-cache:
-  directories:
-  - "$HOME/.npm"

DESCRIPTION

-

This command is similar to npm-install(1), except it's meant to be used in -automated environments such as test platforms, continuous integration, and -deployment -- or any situation where you want to make sure you're doing a clean -install of your dependencies. It can be significantly faster than a regular npm -install by skipping certain user-oriented features. It is also more strict than -a regular install, which can help catch errors or inconsistencies caused by the -incrementally-installed local environments of most npm users.

-

In short, the main differences between using npm install and npm ci are:

-
    -
  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • -
  • If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
  • -
  • npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.
  • -
  • If a node_modules is already present, it will be automatically removed before npm ci begins its install.
  • -
  • It will never write to package.json or any of the package-locks: installs are essentially frozen.
  • -
-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-completion.html b/deps/npm/html/doc/cli/npm-completion.html deleted file mode 100644 index 48622a8953f9e9..00000000000000 --- a/deps/npm/html/doc/cli/npm-completion.html +++ /dev/null @@ -1,46 +0,0 @@ - - - npm-completion - - - - - - -
- -

npm-completion

Tab Completion for npm

-

SYNOPSIS

-
source <(npm completion)

DESCRIPTION

-

Enables tab-completion in all npm commands.

-

The synopsis above -loads the completions into your current shell. Adding it to -your ~/.bashrc or ~/.zshrc will make the completions available -everywhere:

-
npm completion >> ~/.bashrc
-npm completion >> ~/.zshrc

You may of course also pipe the output of npm completion to a file -such as /usr/local/etc/bash_completion.d/npm or -/etc/bash_completion.d/npm if you have a system that will read -that file for you.

-

When COMP_CWORD, COMP_LINE, and COMP_POINT are defined in the -environment, npm completion acts in "plumbing mode", and outputs -completions based on the arguments.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-config.html b/deps/npm/html/doc/cli/npm-config.html deleted file mode 100644 index ff165a76f85774..00000000000000 --- a/deps/npm/html/doc/cli/npm-config.html +++ /dev/null @@ -1,66 +0,0 @@ - - - npm-config - - - - - - -
- -

npm-config

Manage the npm configuration files

-

SYNOPSIS

-
npm config set <key> <value> [-g|--global]
-npm config get <key>
-npm config delete <key>
-npm config list [-l] [--json]
-npm config edit
-npm get <key>
-npm set <key> <value> [-g|--global]
-
-aliases: c

DESCRIPTION

-

npm gets its config settings from the command line, environment -variables, npmrc files, and in some cases, the package.json file.

-

See npmrc(5) for more information about the npmrc files.

-

See npm-config(7) for a more thorough discussion of the mechanisms -involved.

-

The npm config command can be used to update and edit the contents -of the user and global npmrc files.

-

Sub-commands

-

Config supports the following sub-commands:

-

set

-
npm config set key value

Sets the config key to the value.

-

If value is omitted, then it sets it to "true".

-

get

-
npm config get key

Echo the config value to stdout.

-

list

-
npm config list

Show all the config settings. Use -l to also show defaults. Use --json -to show the settings in json format.

-

delete

-
npm config delete key

Deletes the key from all configuration files.

-

edit

-
npm config edit

Opens the config file in an editor. Use the --global flag to edit the -global config.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-dedupe.html b/deps/npm/html/doc/cli/npm-dedupe.html deleted file mode 100644 index 63ace676816cc2..00000000000000 --- a/deps/npm/html/doc/cli/npm-dedupe.html +++ /dev/null @@ -1,62 +0,0 @@ - - - npm-dedupe - - - - - - -
- -

npm-dedupe

Reduce duplication

-

SYNOPSIS

-
npm dedupe
-npm ddp
-
-aliases: find-dupes, ddp

DESCRIPTION

-

Searches the local package tree and attempts to simplify the overall -structure by moving dependencies further up the tree, where they can -be more effectively shared by multiple dependent packages.

-

For example, consider this dependency graph:

-
a
-+-- b <-- depends on c@1.0.x
-|   `-- c@1.0.3
-`-- d <-- depends on c@~1.0.9
-    `-- c@1.0.10

In this case, npm-dedupe(1) will transform the tree to:

-
a
-+-- b
-+-- d
-`-- c@1.0.10

Because of the hierarchical nature of node's module lookup, b and d -will both get their dependency met by the single c package at the root -level of the tree.

-

The deduplication algorithm walks the tree, moving each dependency as far -up in the tree as possible, even if duplicates are not found. This will -result in both a flat and deduplicated tree.

-

If a suitable version exists at the target location in the tree -already, then it will be left untouched, but the other duplicates will -be deleted.

-

Arguments are ignored. Dedupe always acts on the entire tree.

-

Modules

-

Note that this operation transforms the dependency tree, but will never -result in new modules being installed.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-deprecate.html b/deps/npm/html/doc/cli/npm-deprecate.html deleted file mode 100644 index 06d0bc8f23c36e..00000000000000 --- a/deps/npm/html/doc/cli/npm-deprecate.html +++ /dev/null @@ -1,42 +0,0 @@ - - - npm-deprecate - - - - - - -
- -

npm-deprecate

Deprecate a version of a package

-

SYNOPSIS

-
npm deprecate <pkg>[@<version>] <message>

DESCRIPTION

-

This command will update the npm registry entry for a package, providing -a deprecation warning to all who attempt to install it.

-

It works on version ranges as well as specific -versions, so you can do something like this:

-
npm deprecate my-thing@"< 0.2.3" "critical bug fixed in v0.2.3"

Note that you must be the package owner to deprecate something. See the -owner and adduser help topics.

-

To un-deprecate a package, specify an empty string ("") for the message -argument. Note that you must use double quotes with no space between them to -format an empty string.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-dist-tag.html b/deps/npm/html/doc/cli/npm-dist-tag.html deleted file mode 100644 index 26bf3d484c4b02..00000000000000 --- a/deps/npm/html/doc/cli/npm-dist-tag.html +++ /dev/null @@ -1,90 +0,0 @@ - - - npm-dist-tag - - - - - - -
- -

npm-dist-tag

Modify package distribution tags

-

SYNOPSIS

-
npm dist-tag add <pkg>@<version> [<tag>]
-npm dist-tag rm <pkg> <tag>
-npm dist-tag ls [<pkg>]
-
-aliases: dist-tags

DESCRIPTION

-

Add, remove, and enumerate distribution tags on a package:

-
    -
  • add: -Tags the specified version of the package with the specified tag, or the ---tag config if not specified. If you have two-factor authentication on -auth-and-writes then you’ll need to include a one-time password on the -command line with --otp <one-time password>.

    -
  • -
  • rm: -Clear a tag that is no longer in use from the package.

    -
  • -
  • ls: -Show all of the dist-tags for a package, defaulting to the package in -the current prefix.

    -

    This is the default action if none is specified.

    -
  • -
-

A tag can be used when installing packages as a reference to a version instead -of using a specific version number:

-
npm install <name>@<tag>

When installing dependencies, a preferred tagged version may be specified:

-
npm install --tag <tag>

This also applies to npm dedupe.

-

Publishing a package sets the latest tag to the published version unless the ---tag option is used. For example, npm publish --tag=beta.

-

By default, npm install <pkg> (without any @<version> or @<tag> -specifier) installs the latest tag.

-

PURPOSE

-

Tags can be used to provide an alias instead of version numbers.

-

For example, a project might choose to have multiple streams of development -and use a different tag for each stream, -e.g., stable, beta, dev, canary.

-

By default, the latest tag is used by npm to identify the current version of -a package, and npm install <pkg> (without any @<version> or @<tag> -specifier) installs the latest tag. Typically, projects only use the latest -tag for stable release versions, and use other tags for unstable versions such -as prereleases.

-

The next tag is used by some projects to identify the upcoming version.

-

By default, other than latest, no tag has any special significance to npm -itself.

-

CAVEATS

-

This command used to be known as npm tag, which only created new tags, and so -had a different syntax.

-

Tags must share a namespace with version numbers, because they are specified in -the same slot: npm install <pkg>@<version> vs npm install <pkg>@<tag>.

-

Tags that can be interpreted as valid semver ranges will be rejected. For -example, v1.4 cannot be used as a tag, because it is interpreted by semver as ->=1.4.0 <1.5.0. See https://github.com/npm/npm/issues/6082.

-

The simplest way to avoid semver problems with tags is to use tags that do not -begin with a number or the letter v.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-docs.html b/deps/npm/html/doc/cli/npm-docs.html deleted file mode 100644 index 0d54bbd09cfc66..00000000000000 --- a/deps/npm/html/doc/cli/npm-docs.html +++ /dev/null @@ -1,59 +0,0 @@ - - - npm-docs - - - - - - -
- -

npm-docs

Docs for a package in a web browser maybe

-

SYNOPSIS

-
npm docs [<pkgname> [<pkgname> ...]]
-npm docs .
-npm home [<pkgname> [<pkgname> ...]]
-npm home .

DESCRIPTION

-

This command tries to guess at the likely location of a package's -documentation URL, and then tries to open it using the --browser -config param. You can pass multiple package names at once. If no -package name is provided, it will search for a package.json in -the current folder and use the name property.

-

CONFIGURATION

-

browser

-
    -
  • Default: OS X: "open", Windows: "start", Others: "xdg-open"
  • -
  • Type: String
  • -
-

The browser that is called by the npm docs command to open websites.

-

registry

- -

The base URL of the npm package registry.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-doctor.html b/deps/npm/html/doc/cli/npm-doctor.html deleted file mode 100644 index e4ac987571a047..00000000000000 --- a/deps/npm/html/doc/cli/npm-doctor.html +++ /dev/null @@ -1,105 +0,0 @@ - - - npm-doctor - - - - - - -
- -

npm-doctor

Check your environments

-

SYNOPSIS

-
npm doctor

DESCRIPTION

-

npm doctor runs a set of checks to ensure that your npm installation has -what it needs to manage your JavaScript packages. npm is mostly a standalone tool, but it does -have some basic requirements that must be met:

-
    -
  • Node.js and git must be executable by npm.
  • -
  • The primary npm registry, registry.npmjs.com, or another service that uses -the registry API, is available.
  • -
  • The directories that npm uses, node_modules (both locally and globally), -exist and can be written by the current user.
  • -
  • The npm cache exists, and the package tarballs within it aren't corrupt.
  • -
-

Without all of these working properly, npm may not work properly. Many issues -are often attributable to things that are outside npm's code base, so npm -doctor confirms that the npm installation is in a good state.

-

Also, in addition to this, there are also very many issue reports due to using -old versions of npm. Since npm is constantly improving, running npm@latest is -better than an old version.

-

npm doctor verifies the following items in your environment, and if there are -any recommended changes, it will display them.

-

npm ping

-

By default, npm installs from the primary npm registry, registry.npmjs.org. -npm doctor hits a special ping endpoint within the registry. This can also be -checked with npm ping. If this check fails, you may be using a proxy that -needs to be configured, or may need to talk to your IT staff to get access over -HTTPS to registry.npmjs.org.

-

This check is done against whichever registry you've configured (you can see -what that is by running npm config get registry), and if you're using a -private registry that doesn't support the /whoami endpoint supported by the -primary registry, this check may fail.

-

npm -v

-

While Node.js may come bundled with a particular version of npm, it's the -policy of the CLI team that we recommend all users run npm@latest if they -can. As the CLI is maintained by a small team of contributors, there are only -resources for a single line of development, so npm's own long-term support -releases typically only receive critical security and regression fixes. The -team believes that the latest tested version of npm is almost always likely to -be the most functional and defect-free version of npm.

-

node -v

-

For most users, in most circumstances, the best version of Node will be the -latest long-term support (LTS) release. Those of you who want access to new -ECMAscript features or bleeding-edge changes to Node's standard library may be -running a newer version, and some of you may be required to run an older -version of Node because of enterprise change control policies. That's OK! But -in general, the npm team recommends that most users run Node.js LTS.

-

npm config get registry

-

Some of you may be installing from private package registries for your project -or company. That's great! Others of you may be following tutorials or -StackOverflow questions in an effort to troubleshoot problems you may be -having. Sometimes, this may entail changing the registry you're pointing at. -This part of npm doctor just lets you, and maybe whoever's helping you with -support, know that you're not using the default registry.

-

which git

-

While it's documented in the README, it may not be obvious that npm needs Git -installed to do many of the things that it does. Also, in some cases -– especially on Windows – you may have Git set up in such a way that it's not -accessible via your PATH so that npm can find it. This check ensures that Git -is available.

-

Permissions checks

-
    -
  • Your cache must be readable and writable by the user running npm.
  • -
  • Global package binaries must be writable by the user running npm.
  • -
  • Your local node_modules path, if you're running npm doctor with a project -directory, must be readable and writable by the user running npm.
  • -
-

Validate the checksums of cached packages

-

When an npm package is published, the publishing process generates a checksum -that npm uses at install time to verify that the package didn't get corrupted -in transit. npm doctor uses these checksums to validate the package tarballs -in your local cache (you can see where that cache is located with npm config -get cache, and see what's in that cache with npm cache ls – probably more -than you were expecting!). In the event that there are corrupt packages in your -cache, you should probably run npm cache clean and reset the cache.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-edit.html b/deps/npm/html/doc/cli/npm-edit.html deleted file mode 100644 index 33a25fc4a36ac3..00000000000000 --- a/deps/npm/html/doc/cli/npm-edit.html +++ /dev/null @@ -1,54 +0,0 @@ - - - npm-edit - - - - - - -
- -

npm-edit

Edit an installed package

-

SYNOPSIS

-
npm edit <pkg>[/<subpkg>...]

DESCRIPTION

-

Selects a (sub)dependency in the current -working directory and opens the package folder in the default editor -(or whatever you've configured as the npm editor config -- see -npm-config(7).)

-

After it has been edited, the package is rebuilt so as to pick up any -changes in compiled packages.

-

For instance, you can do npm install connect to install connect -into your package, and then npm edit connect to make a few -changes to your locally installed copy.

-

CONFIGURATION

-

editor

-
    -
  • Default: EDITOR environment variable if set, or "vi" on Posix, -or "notepad" on Windows.
  • -
  • Type: path
  • -
-

The command to run for npm edit or npm config edit.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-explore.html b/deps/npm/html/doc/cli/npm-explore.html deleted file mode 100644 index 05fc585cc213b0..00000000000000 --- a/deps/npm/html/doc/cli/npm-explore.html +++ /dev/null @@ -1,51 +0,0 @@ - - - npm-explore - - - - - - -
- -

npm-explore

Browse an installed package

-

SYNOPSIS

-
npm explore <pkg> [ -- <command>]

DESCRIPTION

-

Spawn a subshell in the directory of the installed package specified.

-

If a command is specified, then it is run in the subshell, which then -immediately terminates.

-

This is particularly handy in the case of git submodules in the -node_modules folder:

-
npm explore some-dependency -- git pull origin master

Note that the package is not automatically rebuilt afterwards, so be -sure to use npm rebuild <pkg> if you make any changes.

-

CONFIGURATION

-

shell

-
    -
  • Default: SHELL environment variable, or "bash" on Posix, or "cmd" on -Windows
  • -
  • Type: path
  • -
-

The shell to run for the npm explore command.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-help-search.html b/deps/npm/html/doc/cli/npm-help-search.html deleted file mode 100644 index 9cc8f42db2b168..00000000000000 --- a/deps/npm/html/doc/cli/npm-help-search.html +++ /dev/null @@ -1,48 +0,0 @@ - - - npm-help-search - - - - - - -
- -

npm-help-search

Search npm help documentation

-

SYNOPSIS

-
npm help-search <text>

DESCRIPTION

-

This command will search the npm markdown documentation files for the -terms provided, and then list the results, sorted by relevance.

-

If only one result is found, then it will show that help topic.

-

If the argument to npm help is not a known help topic, then it will -call help-search. It is rarely if ever necessary to call this -command directly.

-

CONFIGURATION

-

long

-
    -
  • Type: Boolean
  • -
  • Default: false
  • -
-

If true, the "long" flag will cause help-search to output context around -where the terms were found in the documentation.

-

If false, then help-search will just list out the help topics found.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-help.html b/deps/npm/html/doc/cli/npm-help.html deleted file mode 100644 index c8788374f1d488..00000000000000 --- a/deps/npm/html/doc/cli/npm-help.html +++ /dev/null @@ -1,53 +0,0 @@ - - - npm-help - - - - - - -
- -

npm-help

Get help on npm

-

SYNOPSIS

-
npm help <term> [<terms..>]

DESCRIPTION

-

If supplied a topic, then show the appropriate documentation page.

-

If the topic does not exist, or if multiple terms are provided, then run -the help-search command to find a match. Note that, if help-search -finds a single subject, then it will run help on that topic, so unique -matches are equivalent to specifying a topic name.

-

CONFIGURATION

-

viewer

-
    -
  • Default: "man" on Posix, "browser" on Windows
  • -
  • Type: path
  • -
-

The program to use to view help content.

-

Set to "browser" to view html help content in the default web browser.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-hook.html b/deps/npm/html/doc/cli/npm-hook.html deleted file mode 100644 index a5b352c54eb156..00000000000000 --- a/deps/npm/html/doc/cli/npm-hook.html +++ /dev/null @@ -1,55 +0,0 @@ - - - npm-hook - - - - - - -
- -

npm-hook

Manage registry hooks

-

SYNOPSIS

-
npm hook ls [pkg]
-npm hook add <entity> <url> <secret>
-npm hook update <id> <url> [secret]
-npm hook rm <id>

EXAMPLE

-

Add a hook to watch a package for changes:

-
$ npm hook add lodash https://example.com/ my-shared-secret

Add a hook to watch packages belonging to the user substack:

-
$ npm hook add ~substack https://example.com/ my-shared-secret

Add a hook to watch packages in the scope @npm

-
$ npm hook add @npm https://example.com/ my-shared-secret

List all your active hooks:

-
$ npm hook ls

List your active hooks for the lodash package:

-
$ npm hook ls lodash

Update an existing hook's url:

-
$ npm hook update id-deadbeef https://my-new-website.here/

Remove a hook:

-
$ npm hook rm id-deadbeef

DESCRIPTION

-

Allows you to manage npm -hooks, -including adding, removing, listing, and updating.

-

Hooks allow you to configure URL endpoints that will be notified whenever a -change happens to any of the supported entity types. Three different types of -entities can be watched by hooks: packages, owners, and scopes.

-

To create a package hook, simply reference the package name.

-

To create an owner hook, prefix the owner name with ~ (as in, ~youruser).

-

To create a scope hook, prefix the scope name with @ (as in, @yourscope).

-

The hook id used by update and rm are the IDs listed in npm hook ls for -that particular hook.

-

The shared secret will be sent along to the URL endpoint so you can verify the -request came from your own configured hook.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-init.html b/deps/npm/html/doc/cli/npm-init.html deleted file mode 100644 index cac14079dc63ef..00000000000000 --- a/deps/npm/html/doc/cli/npm-init.html +++ /dev/null @@ -1,65 +0,0 @@ - - - npm-init - - - - - - -
- -

npm-init

create a package.json file

-

SYNOPSIS

-
npm init [--force|-f|--yes|-y|--scope]
-npm init <@scope> (same as `npx <@scope>/create`)
-npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)

EXAMPLES

-

Create a new React-based project using create-react-app:

-
$ npm init react-app ./my-react-app

Create a new esm-compatible package using create-esm:

-
$ mkdir my-esm-lib && cd my-esm-lib
-$ npm init esm --yes

Generate a plain old package.json using legacy init:

-
$ mkdir my-npm-pkg && cd my-npm-pkg
-$ git init
-$ npm init

Generate it without having it ask any questions:

-
$ npm init -y

DESCRIPTION

-

npm init <initializer> can be used to set up a new or existing npm package.

-

initializer in this case is an npm package named create-<initializer>, which -will be installed by npx(1), and then have its main bin -executed -- presumably creating or updating package.json and running any other -initialization-related operations.

-

The init command is transformed to a corresponding npx operation as follows:

-
    -
  • npm init foo -> npx create-foo
  • -
  • npm init @usr/foo -> npx @usr/create-foo
  • -
  • npm init @usr -> npx @usr/create
  • -
-

Any additional options will be passed directly to the command, so npm init foo ---hello will map to npx create-foo --hello.

-

If the initializer is omitted (by just calling npm init), init will fall back -to legacy init behavior. It will ask you a bunch of questions, and then write a -package.json for you. It will attempt to make reasonable guesses based on -existing fields, dependencies, and options selected. It is strictly additive, so -it will keep any fields and values that were already set. You can also use --y/--yes to skip the questionnaire altogether. If you pass --scope, it -will create a scoped package.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-install-ci-test.html b/deps/npm/html/doc/cli/npm-install-ci-test.html deleted file mode 100644 index 802112b8d7dc3f..00000000000000 --- a/deps/npm/html/doc/cli/npm-install-ci-test.html +++ /dev/null @@ -1,35 +0,0 @@ - - - npm-install-ci-test - - - - - - -
- -

npm install-ci-test

Install a project with a clean slate and run tests

-

SYNOPSIS

-
npm install-ci-test
-
-alias: npm cit

DESCRIPTION

-

This command runs an npm ci followed immediately by an npm test.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-install-test.html b/deps/npm/html/doc/cli/npm-install-test.html deleted file mode 100644 index be69c6106a5728..00000000000000 --- a/deps/npm/html/doc/cli/npm-install-test.html +++ /dev/null @@ -1,45 +0,0 @@ - - - npm-install-test - - - - - - -
- -

npm install-test

Install package(s) and run tests

-

SYNOPSIS

-
npm install-test (with no args, in package dir)
-npm install-test [<@scope>/]<name>
-npm install-test [<@scope>/]<name>@<tag>
-npm install-test [<@scope>/]<name>@<version>
-npm install-test [<@scope>/]<name>@<version range>
-npm install-test <tarball file>
-npm install-test <tarball url>
-npm install-test <folder>
-
-alias: npm it
-common options: [--save|--save-dev|--save-optional] [--save-exact] [--dry-run]

DESCRIPTION

-

This command runs an npm install followed immediately by an npm test. It -takes exactly the same arguments as npm install.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-install.html b/deps/npm/html/doc/cli/npm-install.html deleted file mode 100644 index 9e40f4c11dddb7..00000000000000 --- a/deps/npm/html/doc/cli/npm-install.html +++ /dev/null @@ -1,374 +0,0 @@ - - - npm-install - - - - - - -
- -

npm-install

Install a package

-

SYNOPSIS

-
npm install (with no args, in package dir)
-npm install [<@scope>/]<name>
-npm install [<@scope>/]<name>@<tag>
-npm install [<@scope>/]<name>@<version>
-npm install [<@scope>/]<name>@<version range>
-npm install <git-host>:<git-user>/<repo-name>
-npm install <git repo url>
-npm install <tarball file>
-npm install <tarball url>
-npm install <folder>
-
-aliases: npm i, npm add
-common options: [-P|--save-prod|-D|--save-dev|-O|--save-optional] [-E|--save-exact] [-B|--save-bundle] [--no-save] [--dry-run]

DESCRIPTION

-

This command installs a package, and any packages that it depends on. If the -package has a package-lock or shrinkwrap file, the installation of dependencies -will be driven by that, with an npm-shrinkwrap.json taking precedence if both -files exist. See package-lock.json(5) and npm-shrinkwrap(1).

-

A package is:

-
    -
  • a) a folder containing a program described by a package.json(5) file
  • -
  • b) a gzipped tarball containing (a)
  • -
  • c) a url that resolves to (b)
  • -
  • d) a <name>@<version> that is published on the registry (see npm-registry(7)) with (c)
  • -
  • e) a <name>@<tag> (see npm-dist-tag(1)) that points to (d)
  • -
  • f) a <name> that has a "latest" tag satisfying (e)
  • -
  • g) a <git remote url> that resolves to (a)
  • -
-

Even if you never publish your package, you can still get a lot of -benefits of using npm if you just want to write a node program (a), and -perhaps if you also want to be able to easily install it elsewhere -after packing it up into a tarball (b).

-
    -
  • npm install (in package directory, no arguments):

    -

    Install the dependencies in the local node_modules folder.

    -

    In global mode (ie, with -g or --global appended to the command), - it installs the current package context (ie, the current working - directory) as a global package.

    -

    By default, npm install will install all modules listed as dependencies - in package.json(5).

    -

    With the --production flag (or when the NODE_ENV environment variable - is set to production), npm will not install modules listed in - devDependencies.

    -
    -

    NOTE: The --production flag has no particular meaning when adding a - dependency to a project.

    -
    -
  • -
  • npm install <folder>:

    -

    Install the package in the directory as a symlink in the current project. - Its dependencies will be installed before it's linked. If <folder> sits - inside the root of your project, its dependencies may be hoisted to the - toplevel node_modules as they would for other types of dependencies.

    -
  • -
  • npm install <tarball file>:

    -

    Install a package that is sitting on the filesystem. Note: if you just want - to link a dev directory into your npm root, you can do this more easily by - using npm link.

    -

    Tarball requirements:

    -
      -
    • The filename must use .tar, .tar.gz, or .tgz as -the extension.

      -
    • -
    • The package contents should reside in a subfolder inside the tarball (usually it is called package/). npm strips one directory layer when installing the package (an equivalent of tar x --strip-components=1 is run).

      -
    • -
    • The package must contain a package.json file with name and version properties.

      -

      Example:

      -
      npm install ./package.tgz
    • -
    -
  • -
  • npm install <tarball url>:

    -

    Fetch the tarball url, and then install it. In order to distinguish between - this and other options, the argument must start with "http://" or "https://"

    -

    Example:

    -
        npm install https://github.com/indexzero/forever/tarball/v0.5.6
  • -
  • npm install [<@scope>/]<name>:

    -

    Do a <name>@<tag> install, where <tag> is the "tag" config. (See - npm-config(7). The config's default value is latest.)

    -

    In most cases, this will install the version of the modules tagged as - latest on the npm registry.

    -

    Example:

    -
        npm install sax

    npm install saves any specified packages into dependencies by default. - Additionally, you can control where and how they get saved with some - additional flags:

    -
      -
    • -P, --save-prod: Package will appear in your dependencies. This is the

      -
                     default unless `-D` or `-O` are present.
    • -
    • -D, --save-dev: Package will appear in your devDependencies.

      -
    • -
    • -O, --save-optional: Package will appear in your optionalDependencies.

      -
    • -
    • --no-save: Prevents saving to dependencies.

      -

      When using any of the above options to save dependencies to your -package.json, there are two additional, optional flags:

      -
    • -
    • -E, --save-exact: Saved dependencies will be configured with an -exact version rather than using npm's default semver range -operator.

      -
    • -
    • -B, --save-bundle: Saved dependencies will also be added to your bundleDependencies list.

      -

      Further, if you have an npm-shrinkwrap.json or package-lock.json then it -will be updated as well.

      -

      <scope> is optional. The package will be downloaded from the registry -associated with the specified scope. If no registry is associated with -the given scope the default registry is assumed. See npm-scope(7).

      -

      Note: if you do not include the @-symbol on your scope name, npm will -interpret this as a GitHub repository instead, see below. Scopes names -must also be followed by a slash.

      -

      Examples:

      -
      npm install sax
      -npm install githubname/reponame
      -npm install @myorg/privatepackage
      -npm install node-tap --save-dev
      -npm install dtrace-provider --save-optional
      -npm install readable-stream --save-exact
      -npm install ansi-regex --save-bundle
    • -
    -
  • -
-
**Note**: If there is a file or folder named `<name>` in the current
-working directory, then it will try to install that, and only try to
-fetch the package by name if it is not valid.
    -
  • npm install [<@scope>/]<name>@<tag>:

    -

    Install the version of the package that is referenced by the specified tag. - If the tag does not exist in the registry data for that package, then this - will fail.

    -

    Example:

    -
        npm install sax@latest
    -    npm install @myorg/mypackage@latest
  • -
  • npm install [<@scope>/]<name>@<version>:

    -

    Install the specified version of the package. This will fail if the - version has not been published to the registry.

    -

    Example:

    -
        npm install sax@0.1.1
    -    npm install @myorg/privatepackage@1.5.0
  • -
  • npm install [<@scope>/]<name>@<version range>:

    -

    Install a version of the package matching the specified version range. This - will follow the same rules for resolving dependencies described in package.json(5).

    -

    Note that most version ranges must be put in quotes so that your shell will - treat it as a single argument.

    -

    Example:

    -
        npm install sax@">=0.1.0 <0.2.0"
    -    npm install @myorg/privatepackage@">=0.1.0 <0.2.0"
  • -
  • npm install <git remote url>:

    -

    Installs the package from the hosted git provider, cloning it with git. - For a full git remote url, only that URL will be attempted.

    -
        <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

    <protocol> is one of git, git+ssh, git+http, git+https, or - git+file.

    -

    If #<commit-ish> is provided, it will be used to clone exactly that - commit. If the commit-ish has the format #semver:<semver>, <semver> can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither #<commit-ish> or #semver:<semver> is - specified, then the default branch of the repository is used.

    -

    If the repository makes use of submodules, those submodules will be cloned - as well.

    -

    If the package being installed contains a prepare script, its - dependencies and devDependencies will be installed, and the prepare - script will be run, before the package is packaged and installed.

    -

    The following git environment variables are recognized by npm and will be - added to the environment when running git:

    -
      -
    • GIT_ASKPASS

      -
    • -
    • GIT_EXEC_PATH

      -
    • -
    • GIT_PROXY_COMMAND

      -
    • -
    • GIT_SSH

      -
    • -
    • GIT_SSH_COMMAND

      -
    • -
    • GIT_SSL_CAINFO

      -
    • -
    • GIT_SSL_NO_VERIFY

      -

      See the git man page for details.

      -

      Examples:

      -
      npm install git+ssh://git@github.com:npm/cli.git#v1.0.27
      -npm install git+ssh://git@github.com:npm/cli#semver:^5.0
      -npm install git+https://isaacs@github.com/npm/cli.git
      -npm install git://github.com/npm/cli.git#v1.0.27
      -GIT_SSH_COMMAND='ssh -i ~/.ssh/custom_ident' npm install git+ssh://git@github.com:npm/cli.git
    • -
    -
  • -
  • npm install <githubname>/<githubrepo>[#<commit-ish>]:

    -
  • -
  • npm install github:<githubname>/<githubrepo>[#<commit-ish>]:

    -

    Install the package at https://github.com/githubname/githubrepo by - attempting to clone it using git.

    -

    If #<commit-ish> is provided, it will be used to clone exactly that - commit. If the commit-ish has the format #semver:<semver>, <semver> can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither #<commit-ish> or #semver:<semver> is - specified, then master is used.

    -

    As with regular git dependencies, dependencies and devDependencies will - be installed if the package has a prepare script, before the package is - done installing.

    -

    Examples:

    -
        npm install mygithubuser/myproject
    -    npm install github:mygithubuser/myproject
  • -
  • npm install gist:[<githubname>/]<gistID>[#<commit-ish>|#semver:<semver>]:

    -

    Install the package at https://gist.github.com/gistID by attempting to - clone it using git. The GitHub username associated with the gist is - optional and will not be saved in package.json.

    -

    As with regular git dependencies, dependencies and devDependencies will - be installed if the package has a prepare script, before the package is - done installing.

    -

    Example:

    -
        npm install gist:101a11beef
  • -
  • npm install bitbucket:<bitbucketname>/<bitbucketrepo>[#<commit-ish>]:

    -

    Install the package at https://bitbucket.org/bitbucketname/bitbucketrepo - by attempting to clone it using git.

    -

    If #<commit-ish> is provided, it will be used to clone exactly that - commit. If the commit-ish has the format #semver:<semver>, <semver> can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither #<commit-ish> or #semver:<semver> is - specified, then master is used.

    -

    As with regular git dependencies, dependencies and devDependencies will - be installed if the package has a prepare script, before the package is - done installing.

    -

    Example:

    -
        npm install bitbucket:mybitbucketuser/myproject
  • -
  • npm install gitlab:<gitlabname>/<gitlabrepo>[#<commit-ish>]:

    -

    Install the package at https://gitlab.com/gitlabname/gitlabrepo - by attempting to clone it using git.

    -

    If #<commit-ish> is provided, it will be used to clone exactly that - commit. If the commit-ish has the format #semver:<semver>, <semver> can - be any valid semver range or exact version, and npm will look for any tags - or refs matching that range in the remote repository, much as it would for a - registry dependency. If neither #<commit-ish> or #semver:<semver> is - specified, then master is used.

    -

    As with regular git dependencies, dependencies and devDependencies will - be installed if the package has a prepare script, before the package is - done installing.

    -

    Example:

    -
        npm install gitlab:mygitlabuser/myproject
    -    npm install gitlab:myusr/myproj#semver:^5.0
  • -
-

You may combine multiple arguments, and even multiple types of arguments. -For example:

-
npm install sax@">=0.1.0 <0.2.0" bench supervisor

The --tag argument will apply to all of the specified install targets. If a -tag with the given name exists, the tagged version is preferred over newer -versions.

-

The --dry-run argument will report in the usual way what the install would -have done without actually installing anything.

-

The --package-lock-only argument will only update the package-lock.json, -instead of checking node_modules and downloading dependencies.

-

The -f or --force argument will force npm to fetch remote resources even if a -local copy exists on disk.

-
npm install sax --force

The -g or --global argument will cause npm to install the package globally -rather than locally. See npm-folders(5).

-

The --global-style argument will cause npm to install the package into -your local node_modules folder with the same layout it uses with the -global node_modules folder. Only your direct dependencies will show in -node_modules and everything they depend on will be flattened in their -node_modules folders. This obviously will eliminate some deduping.

-

The --ignore-scripts argument will cause npm to not execute any -scripts defined in the package.json. See npm-scripts(7).

-

The --legacy-bundling argument will cause npm to install the package such -that versions of npm prior to 1.4, such as the one included with node 0.8, -can install the package. This eliminates all automatic deduping.

-

The --link argument will cause npm to link global installs into the -local space in some cases.

-

The --no-bin-links argument will prevent npm from creating symlinks for -any binaries the package might contain.

-

The --no-optional argument will prevent optional dependencies from -being installed.

-

The --no-shrinkwrap argument, which will ignore an available -package lock or shrinkwrap file and use the package.json instead.

-

The --no-package-lock argument will prevent npm from creating a -package-lock.json file. When running with package-lock's disabled npm -will not automatically prune your node modules when installing.

-

The --nodedir=/path/to/node/source argument will allow npm to find the -node source code so that npm can compile native modules.

-

The --only={prod[uction]|dev[elopment]} argument will cause either only -devDependencies or only non-devDependencies to be installed regardless of the NODE_ENV.

-

The --no-audit argument can be used to disable sending of audit reports to -the configured registries. See npm-audit(1) for details on what is sent.

-

See npm-config(7). Many of the configuration params have some -effect on installation, since that's most of what npm does.

-

ALGORITHM

-

To install a package, npm uses the following algorithm:

-
load the existing node_modules tree from disk
-clone the tree
-fetch the package.json and assorted metadata and add it to the clone
-walk the clone and add any missing dependencies
-  dependencies will be added as close to the top as is possible
-  without breaking any other modules
-compare the original tree with the cloned tree and make a list of
-actions to take to convert one to the other
-execute all of the actions, deepest first
-  kinds of actions are install, update, remove and move

For this package{dep} structure: A{B,C}, B{C}, C{D}, -this algorithm produces:

-
A
-+-- B
-+-- C
-+-- D

That is, the dependency from B to C is satisfied by the fact that A -already caused C to be installed at a higher level. D is still installed -at the top level because nothing conflicts with it.

-

For A{B,C}, B{C,D@1}, C{D@2}, this algorithm produces:

-
A
-+-- B
-+-- C
-   `-- D@2
-+-- D@1

Because B's D@1 will be installed in the top level, C now has to install D@2 -privately for itself. This algorithm is deterministic, but different trees may -be produced if two dependencies are requested for installation in a different -order.

-

See npm-folders(5) for a more detailed description of the specific -folder structures that npm creates.

-

Limitations of npm's Install Algorithm

-

npm will refuse to install any package with an identical name to the -current package. This can be overridden with the --force flag, but in -most cases can simply be addressed by changing the local package name.

-

There are some very rare and pathological edge-cases where a cycle can -cause npm to try to install a never-ending tree of packages. Here is -the simplest case:

-
A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ...

where A is some version of a package, and A' is a different version -of the same package. Because B depends on a different version of A -than the one that is already in the tree, it must install a separate -copy. The same is true of A', which must install B'. Because B' -depends on the original version of A, which has been overridden, the -cycle falls into infinite regress.

-

To avoid this situation, npm flat-out refuses to install any -name@version that is already present anywhere in the tree of package -folder ancestors. A more correct, but more complex, solution would be -to symlink the existing version into the new location. If this ever -affects a real use-case, it will be investigated.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-link.html b/deps/npm/html/doc/cli/npm-link.html deleted file mode 100644 index c2b7d651bd8fca..00000000000000 --- a/deps/npm/html/doc/cli/npm-link.html +++ /dev/null @@ -1,75 +0,0 @@ - - - npm-link - - - - - - -
- -

npm-link

Symlink a package folder

-

SYNOPSIS

-
npm link (in package dir)
-npm link [<@scope>/]<pkg>[@<version>]
-
-alias: npm ln

DESCRIPTION

-

Package linking is a two-step process.

-

First, npm link in a package folder will create a symlink in the global folder -{prefix}/lib/node_modules/<package> that links to the package where the npm -link command was executed. (see npm-config(7) for the value of prefix). It -will also link any bins in the package to {prefix}/bin/{name}.

-

Next, in some other location, npm link package-name will create a -symbolic link from globally-installed package-name to node_modules/ -of the current folder.

-

Note that package-name is taken from package.json, -not from directory name.

-

The package name can be optionally prefixed with a scope. See npm-scope(7). -The scope must be preceded by an @-symbol and followed by a slash.

-

When creating tarballs for npm publish, the linked packages are -"snapshotted" to their current state by resolving the symbolic links.

-

This is handy for installing your own stuff, so that you can work on it and -test it iteratively without having to continually rebuild.

-

For example:

-
cd ~/projects/node-redis    # go into the package directory
-npm link                    # creates global link
-cd ~/projects/node-bloggy   # go into some other package directory.
-npm link redis              # link-install the package

Now, any changes to ~/projects/node-redis will be reflected in -~/projects/node-bloggy/node_modules/node-redis/. Note that the link should -be to the package name, not the directory name for that package.

-

You may also shortcut the two steps in one. For example, to do the -above use-case in a shorter way:

-
cd ~/projects/node-bloggy  # go into the dir of your main project
-npm link ../node-redis     # link the dir of your dependency

The second line is the equivalent of doing:

-
(cd ../node-redis; npm link)
-npm link redis

That is, it first creates a global link, and then links the global -installation target into your project's node_modules folder.

-

Note that in this case, you are referring to the directory name, node-redis, -rather than the package name redis.

-

If your linked package is scoped (see npm-scope(7)) your link command must -include that scope, e.g.

-
npm link @myorg/privatepackage

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-logout.html b/deps/npm/html/doc/cli/npm-logout.html deleted file mode 100644 index 717d4da3cb4c93..00000000000000 --- a/deps/npm/html/doc/cli/npm-logout.html +++ /dev/null @@ -1,53 +0,0 @@ - - - npm-logout - - - - - - -
- -

npm-logout

Log out of the registry

-

SYNOPSIS

-
npm logout [--registry=<url>] [--scope=<@scope>]

DESCRIPTION

-

When logged into a registry that supports token-based authentication, tell the -server to end this token's session. This will invalidate the token everywhere -you're using it, not just for the current environment.

-

When logged into a legacy registry that uses username and password authentication, this will -clear the credentials in your user configuration. In this case, it will only affect -the current environment.

-

If --scope is provided, this will find the credentials for the registry -connected to that scope, if set.

-

CONFIGURATION

-

registry

-

Default: https://registry.npmjs.org/

-

The base URL of the npm package registry. If scope is also specified, -it takes precedence.

-

scope

-

Default: The scope of your current project, if any, otherwise none.

-

If specified, you will be logged out of the specified scope. See npm-scope(7).

-
npm logout --scope=@myco

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-ls.html b/deps/npm/html/doc/cli/npm-ls.html deleted file mode 100644 index f1e6a2088d8960..00000000000000 --- a/deps/npm/html/doc/cli/npm-ls.html +++ /dev/null @@ -1,112 +0,0 @@ - - - npm-ls - - - - - - -
- -

npm-ls

List installed packages

-

SYNOPSIS

-
npm ls [[<@scope>/]<pkg> ...]
-
-aliases: list, la, ll

DESCRIPTION

-

This command will print to stdout all the versions of packages that are -installed, as well as their dependencies, in a tree-structure.

-

Positional arguments are name@version-range identifiers, which will -limit the results to only the paths to the packages named. Note that -nested packages will also show the paths to the specified packages. -For example, running npm ls promzard in npm's source tree will show:

-
npm@6.12.1 /path/to/npm
-└─┬ init-package-json@0.0.4
-  └── promzard@0.1.5

It will print out extraneous, missing, and invalid packages.

-

If a project specifies git urls for dependencies these are shown -in parentheses after the name@version to make it easier for users to -recognize potential forks of a project.

-

The tree shown is the logical dependency tree, based on package -dependencies, not the physical layout of your node_modules folder.

-

When run as ll or la, it shows extended information by default.

-

CONFIGURATION

-

json

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show information in JSON format.

-

long

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show extended information.

-

parseable

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show parseable output instead of tree view.

-

global

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

List packages in the global install prefix instead of in the current -project.

-

depth

-
    -
  • Type: Int
  • -
-

Max display depth of the dependency tree.

-

prod / production

-
    -
  • Type: Boolean
  • -
  • Default: false
  • -
-

Display only the dependency tree for packages in dependencies.

-

dev / development

-
    -
  • Type: Boolean
  • -
  • Default: false
  • -
-

Display only the dependency tree for packages in devDependencies.

-

only

-
    -
  • Type: String
  • -
-

When "dev" or "development", is an alias to dev.

-

When "prod" or "production", is an alias to production.

- -
    -
  • Type: Boolean
  • -
  • Default: false
  • -
-

Display only dependencies which are linked

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-org.html b/deps/npm/html/doc/cli/npm-org.html deleted file mode 100644 index 6fff7d60f75420..00000000000000 --- a/deps/npm/html/doc/cli/npm-org.html +++ /dev/null @@ -1,43 +0,0 @@ - - - npm-org - - - - - - -
- -

npm-org

Manage orgs

-

SYNOPSIS

-
npm org set <orgname> <username> [developer | admin | owner]
-npm org rm <orgname> <username>
-npm org ls <orgname> [<username>]

EXAMPLE

-

Add a new developer to an org:

-
$ npm org set my-org @mx-smith

Add a new admin to an org (or change a developer to an admin):

-
$ npm org set my-org @mx-santos admin

Remove a user from an org:

-
$ npm org rm my-org mx-santos

List all users in an org:

-
$ npm org ls my-org

List all users in JSON format:

-
$ npm org ls my-org --json

See what role a user has in an org:

-
$ npm org ls my-org @mx-santos

DESCRIPTION

-

You can use the npm org commands to manage and view users of an organization. -It supports adding and removing users, changing their roles, listing them, and -finding specific ones and their roles.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-outdated.html b/deps/npm/html/doc/cli/npm-outdated.html deleted file mode 100644 index be64b518103bbb..00000000000000 --- a/deps/npm/html/doc/cli/npm-outdated.html +++ /dev/null @@ -1,120 +0,0 @@ - - - npm-outdated - - - - - - -
- -

npm-outdated

Check for outdated packages

-

SYNOPSIS

-
npm outdated [[<@scope>/]<pkg> ...]

DESCRIPTION

-

This command will check the registry to see if any (or, specific) installed -packages are currently outdated.

-

In the output:

-
    -
  • wanted is the maximum version of the package that satisfies the semver -range specified in package.json. If there's no available semver range (i.e. -you're running npm outdated --global, or the package isn't included in -package.json), then wanted shows the currently-installed version.
  • -
  • latest is the version of the package tagged as latest in the registry. -Running npm publish with no special configuration will publish the package -with a dist-tag of latest. This may or may not be the maximum version of -the package, or the most-recently published version of the package, depending -on how the package's developer manages the latest dist-tag(1).
  • -
  • location is where in the dependency tree the package is located. Note that -npm outdated defaults to a depth of 0, so unless you override that, you'll -always be seeing only top-level dependencies that are outdated.
  • -
  • package type (when using --long / -l) tells you whether this package is -a dependency or a devDependency. Packages not included in package.json -are always marked dependencies.
  • -
  • homepage (when using --long / -l) is the homepage value contained in the package's package.json
  • -
  • Red means there's a newer version matching your semver requirements, so you should update now.
  • -
  • Yellow indicates that there's a newer version above your semver requirements (usually new major, or new 0.x minor) so proceed with caution.
  • -
-

An example

-
$ npm outdated
-Package      Current   Wanted   Latest  Location
-glob          5.0.15   5.0.15    6.0.1  test-outdated-output
-nothingness    0.0.3      git      git  test-outdated-output
-npm            3.5.1    3.5.2    3.5.1  test-outdated-output
-local-dev      0.0.3   linked   linked  test-outdated-output
-once           1.3.2    1.3.3    1.3.3  test-outdated-output

With these dependencies:

-
{
-  "glob": "^5.0.15",
-  "nothingness": "github:othiym23/nothingness#master",
-  "npm": "^3.5.1",
-  "once": "^1.3.1"
-}
-

A few things to note:

-
    -
  • glob requires ^5, which prevents npm from installing glob@6, which is -outside the semver range.
  • -
  • Git dependencies will always be reinstalled, because of how they're specified. -The installed committish might satisfy the dependency specifier (if it's -something immutable, like a commit SHA), or it might not, so npm outdated and -npm update have to fetch Git repos to check. This is why currently doing a -reinstall of a Git dependency always forces a new clone and install.
  • -
  • npm@3.5.2 is marked as "wanted", but "latest" is npm@3.5.1 because npm -uses dist-tags to manage its latest and next release channels. npm update -will install the newest version, but npm install npm (with no semver range) -will install whatever's tagged as latest.
  • -
  • once is just plain out of date. Reinstalling node_modules from scratch or -running npm update will bring it up to spec.
  • -
-

CONFIGURATION

-

json

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show information in JSON format.

-

long

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show extended information.

-

parseable

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show parseable output instead of tree view.

-

global

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Check packages in the global install prefix instead of in the current -project.

-

depth

-
    -
  • Default: 0
  • -
  • Type: Int
  • -
-

Max depth for checking dependency tree.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-owner.html b/deps/npm/html/doc/cli/npm-owner.html deleted file mode 100644 index fd96ae327cfb2e..00000000000000 --- a/deps/npm/html/doc/cli/npm-owner.html +++ /dev/null @@ -1,57 +0,0 @@ - - - npm-owner - - - - - - -
- -

npm-owner

Manage package owners

-

SYNOPSIS

-
npm owner add <user> [<@scope>/]<pkg>
-npm owner rm <user> [<@scope>/]<pkg>
-npm owner ls [<@scope>/]<pkg>
-
-aliases: author

DESCRIPTION

-

Manage ownership of published packages.

-
    -
  • ls: -List all the users who have access to modify a package and push new versions. -Handy when you need to know who to bug for help.
  • -
  • add: -Add a new user as a maintainer of a package. This user is enabled to modify -metadata, publish new versions, and add other owners.
  • -
  • rm: -Remove a user from the package owner list. This immediately revokes their -privileges.
  • -
-

Note that there is only one level of access. Either you can modify a package, -or you can't. Future versions may contain more fine-grained access levels, but -that is not implemented at this time.

-

If you have two-factor authentication enabled with auth-and-writes then -you'll need to include an otp on the command line when changing ownership -with --otp.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-pack.html b/deps/npm/html/doc/cli/npm-pack.html deleted file mode 100644 index f2d8cd398d8dda..00000000000000 --- a/deps/npm/html/doc/cli/npm-pack.html +++ /dev/null @@ -1,46 +0,0 @@ - - - npm-pack - - - - - - -
- -

npm-pack

Create a tarball from a package

-

SYNOPSIS

-
npm pack [[<@scope>/]<pkg>...] [--dry-run]

DESCRIPTION

-

For anything that's installable (that is, a package folder, tarball, -tarball url, name@tag, name@version, name, or scoped name), this -command will fetch it to the cache, and then copy the tarball to the -current working directory as <name>-<version>.tgz, and then write -the filenames out to stdout.

-

If the same package is specified multiple times, then the file will be -overwritten the second time.

-

If no arguments are supplied, then npm packs the current package folder.

-

The --dry-run argument will do everything that pack usually does without -actually packing anything. Reports on what would have gone into the tarball.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-ping.html b/deps/npm/html/doc/cli/npm-ping.html deleted file mode 100644 index ffc7d03c148bbb..00000000000000 --- a/deps/npm/html/doc/cli/npm-ping.html +++ /dev/null @@ -1,37 +0,0 @@ - - - npm-ping - - - - - - -
- -

npm-ping

Ping npm registry

-

SYNOPSIS

-
npm ping [--registry <registry>]

DESCRIPTION

-

Ping the configured or given npm registry and verify authentication. -If it works it will output something like:

-
Ping success: {*Details about registry*}

otherwise you will get:

-
Ping error: {*Detail about error}

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-prefix.html b/deps/npm/html/doc/cli/npm-prefix.html deleted file mode 100644 index e3a0f338d19679..00000000000000 --- a/deps/npm/html/doc/cli/npm-prefix.html +++ /dev/null @@ -1,42 +0,0 @@ - - - npm-prefix - - - - - - -
- -

npm-prefix

Display prefix

-

SYNOPSIS

-
npm prefix [-g]

DESCRIPTION

-

Print the local prefix to standard out. This is the closest parent directory -to contain a package.json file or node_modules directory, unless -g is -also specified.

-

If -g is specified, this will be the value of the global prefix. See -npm-config(7) for more detail.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-profile.html b/deps/npm/html/doc/cli/npm-profile.html deleted file mode 100644 index b28bf5ecac2192..00000000000000 --- a/deps/npm/html/doc/cli/npm-profile.html +++ /dev/null @@ -1,91 +0,0 @@ - - - npm-profile - - - - - - -
- -

npm-profile

Change settings on your registry profile

-

SYNOPSIS

-
npm profile get [--json|--parseable] [<property>]
-npm profile set [--json|--parseable] <property> <value>
-npm profile set password
-npm profile enable-2fa [auth-and-writes|auth-only]
-npm profile disable-2fa

DESCRIPTION

-

Change your profile information on the registry. This not be available if -you're using a non-npmjs registry.

-
    -
  • npm profile get [<property>]: -Display all of the properties of your profile, or one or more specific -properties. It looks like:
  • -
-
+-----------------+---------------------------+
-| name            | example                   |
-+-----------------+---------------------------+
-| email           | me@example.com (verified) |
-+-----------------+---------------------------+
-| two factor auth | auth-and-writes           |
-+-----------------+---------------------------+
-| fullname        | Example User              |
-+-----------------+---------------------------+
-| homepage        |                           |
-+-----------------+---------------------------+
-| freenode        |                           |
-+-----------------+---------------------------+
-| twitter         |                           |
-+-----------------+---------------------------+
-| github          |                           |
-+-----------------+---------------------------+
-| created         | 2015-02-26T01:38:35.892Z  |
-+-----------------+---------------------------+
-| updated         | 2017-10-02T21:29:45.922Z  |
-+-----------------+---------------------------+
    -
  • npm profile set <property> <value>: -Set the value of a profile property. You can set the following properties this way: - email, fullname, homepage, freenode, twitter, github

    -
  • -
  • npm profile set password: -Change your password. This is interactive, you'll be prompted for your -current password and a new password. You'll also be prompted for an OTP -if you have two-factor authentication enabled.

    -
  • -
  • npm profile enable-2fa [auth-and-writes|auth-only]: -Enables two-factor authentication. Defaults to auth-and-writes mode. Modes are:

    -
      -
    • auth-only: Require an OTP when logging in or making changes to your -account's authentication. The OTP will be required on both the website -and the command line.
    • -
    • auth-and-writes: Requires an OTP at all the times auth-only does, and also requires one when -publishing a module, setting the latest dist-tag, or changing access -via npm access and npm owner.
    • -
    -
  • -
  • npm profile disable-2fa: -Disables two-factor authentication.

    -
  • -
-

DETAILS

-

All of the npm profile subcommands accept --json and --parseable and -will tailor their output based on those. Some of these commands may not be -available on non npmjs.com registries.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-prune.html b/deps/npm/html/doc/cli/npm-prune.html deleted file mode 100644 index 9b2822437f43b7..00000000000000 --- a/deps/npm/html/doc/cli/npm-prune.html +++ /dev/null @@ -1,51 +0,0 @@ - - - npm-prune - - - - - - -
- -

npm-prune

Remove extraneous packages

-

SYNOPSIS

-
npm prune [[<@scope>/]<pkg>...] [--production] [--dry-run] [--json]

DESCRIPTION

-

This command removes "extraneous" packages. If a package name is -provided, then only packages matching one of the supplied names are -removed.

-

Extraneous packages are packages that are not listed on the parent -package's dependencies list.

-

If the --production flag is specified or the NODE_ENV environment -variable is set to production, this command will remove the packages -specified in your devDependencies. Setting --no-production will -negate NODE_ENV being set to production.

-

If the --dry-run flag is used then no changes will actually be made.

-

If the --json flag is used then the changes npm prune made (or would -have made with --dry-run) are printed as a JSON object.

-

In normal operation with package-locks enabled, extraneous modules are -pruned automatically when modules are installed and you'll only need -this command with the --production flag.

-

If you've disabled package-locks then extraneous modules will not be removed -and it's up to you to run npm prune from time-to-time to remove them.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-publish.html b/deps/npm/html/doc/cli/npm-publish.html deleted file mode 100644 index 5a569d95eeaf0c..00000000000000 --- a/deps/npm/html/doc/cli/npm-publish.html +++ /dev/null @@ -1,91 +0,0 @@ - - - npm-publish - - - - - - -
- -

npm-publish

Publish a package

-

SYNOPSIS

-
npm publish [<tarball>|<folder>] [--tag <tag>] [--access <public|restricted>] [--otp otpcode] [--dry-run]
-
-Publishes '.' if no argument supplied
-Sets tag 'latest' if no --tag specified

DESCRIPTION

-

Publishes a package to the registry so that it can be installed by name. All -files in the package directory are included if no local .gitignore or -.npmignore file exists. If both files exist and a file is ignored by -.gitignore but not by .npmignore then it will be included. See -npm-developers(7) for full details on what's included in the published -package, as well as details on how the package is built.

-

By default npm will publish to the public registry. This can be overridden by -specifying a different default registry or using a npm-scope(7) in the name -(see package.json(5)).

-
    -
  • <folder>: -A folder containing a package.json file

    -
  • -
  • <tarball>: -A url or file path to a gzipped tar archive containing a single folder -with a package.json file inside.

    -
  • -
  • [--tag <tag>] -Registers the published package with the given tag, such that npm install -<name>@<tag> will install this version. By default, npm publish updates -and npm install installs the latest tag. See npm-dist-tag(1) for -details about tags.

    -
  • -
  • [--access <public|restricted>] -Tells the registry whether this package should be published as public or -restricted. Only applies to scoped packages, which default to restricted. -If you don't have a paid account, you must publish with --access public -to publish scoped packages.

    -
  • -
  • [--otp <otpcode>] -If you have two-factor authentication enabled in auth-and-writes mode -then you can provide a code from your authenticator with this. If you -don't include this and you're running from a TTY then you'll be prompted.

    -
  • -
  • [--dry-run] -As of npm@6, does everything publish would do except actually publishing -to the registry. Reports the details of what would have been published.

    -
  • -
-

Fails if the package name and version combination already exists in -the specified registry.

-

Once a package is published with a given name and version, that -specific name and version combination can never be used again, even if -it is removed with npm-unpublish(1).

-

As of npm@5, both a sha1sum and an integrity field with a sha512sum of the -tarball will be submitted to the registry during publication. Subsequent -installs will use the strongest supported algorithm to verify downloads.

-

Similar to --dry-run see npm-pack(1), which figures out the files to be -included and packs them into a tarball to be uploaded to the registry.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-rebuild.html b/deps/npm/html/doc/cli/npm-rebuild.html deleted file mode 100644 index 77e1e37e3bd195..00000000000000 --- a/deps/npm/html/doc/cli/npm-rebuild.html +++ /dev/null @@ -1,38 +0,0 @@ - - - npm-rebuild - - - - - - -
- -

npm-rebuild

Rebuild a package

-

SYNOPSIS

-
npm rebuild [[<@scope>/<name>]...]
-
-alias: npm rb

DESCRIPTION

-

This command runs the npm build command on the matched folders. This is useful -when you install a new version of node, and must recompile all your C++ addons with -the new binary.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-repo.html b/deps/npm/html/doc/cli/npm-repo.html deleted file mode 100644 index 1665e27197260f..00000000000000 --- a/deps/npm/html/doc/cli/npm-repo.html +++ /dev/null @@ -1,44 +0,0 @@ - - - npm-repo - - - - - - -
- -

npm-repo

Open package repository page in the browser

-

SYNOPSIS

-
npm repo [<pkg>]

DESCRIPTION

-

This command tries to guess at the likely location of a package's -repository URL, and then tries to open it using the --browser -config param. If no package name is provided, it will search for -a package.json in the current folder and use the name property.

-

CONFIGURATION

-

browser

-
    -
  • Default: OS X: "open", Windows: "start", Others: "xdg-open"
  • -
  • Type: String
  • -
-

The browser that is called by the npm repo command to open websites.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-restart.html b/deps/npm/html/doc/cli/npm-restart.html deleted file mode 100644 index e827f2064da9e4..00000000000000 --- a/deps/npm/html/doc/cli/npm-restart.html +++ /dev/null @@ -1,56 +0,0 @@ - - - npm-restart - - - - - - -
- -

npm-restart

Restart a package

-

SYNOPSIS

-
npm restart [-- <args>]

DESCRIPTION

-

This restarts a package.

-

This runs a package's "stop", "restart", and "start" scripts, and associated -pre- and post- scripts, in the order given below:

-
    -
  1. prerestart
  2. -
  3. prestop
  4. -
  5. stop
  6. -
  7. poststop
  8. -
  9. restart
  10. -
  11. prestart
  12. -
  13. start
  14. -
  15. poststart
  16. -
  17. postrestart
  18. -
-

NOTE

-

Note that the "restart" script is run in addition to the "stop" -and "start" scripts, not instead of them.

-

This is the behavior as of npm major version 2. A change in this -behavior will be accompanied by an increase in major version number

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-root.html b/deps/npm/html/doc/cli/npm-root.html deleted file mode 100644 index f029e96a5951a7..00000000000000 --- a/deps/npm/html/doc/cli/npm-root.html +++ /dev/null @@ -1,38 +0,0 @@ - - - npm-root - - - - - - -
- -

npm-root

Display npm root

-

SYNOPSIS

-
npm root [-g]

DESCRIPTION

-

Print the effective node_modules folder to standard out.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-run-script.html b/deps/npm/html/doc/cli/npm-run-script.html deleted file mode 100644 index 51d2be8fec8338..00000000000000 --- a/deps/npm/html/doc/cli/npm-run-script.html +++ /dev/null @@ -1,83 +0,0 @@ - - - npm-run-script - - - - - - -
- -

npm-run-script

Run arbitrary package scripts

-

SYNOPSIS

-
npm run-script <command> [--silent] [-- <args>...]
-
-alias: npm run

DESCRIPTION

-

This runs an arbitrary command from a package's "scripts" object. If no -"command" is provided, it will list the available scripts. run[-script] is -used by the test, start, restart, and stop commands, but can be called -directly, as well. When the scripts in the package are printed out, they're -separated into lifecycle (test, start, restart) and directly-run scripts.

-

As of npm@2.0.0, you can -use custom arguments when executing scripts. The special option -- is used by -getopt to delimit the end of the options. npm will pass -all the arguments after the -- directly to your script:

-
npm run test -- --grep="pattern"

The arguments will only be passed to the script specified after npm run -and not to any pre or post script.

-

The env script is a special built-in command that can be used to list -environment variables that will be available to the script at runtime. If an -"env" command is defined in your package, it will take precedence over the -built-in.

-

In addition to the shell's pre-existing PATH, npm run adds -node_modules/.bin to the PATH provided to scripts. Any binaries provided by -locally-installed dependencies can be used without the node_modules/.bin -prefix. For example, if there is a devDependency on tap in your package, -you should write:

-
"scripts": {"test": "tap test/\*.js"}

instead of

-
"scripts": {"test": "node_modules/.bin/tap test/\*.js"}  

to run your tests.

-

The actual shell your script is run within is platform dependent. By default, -on Unix-like systems it is the /bin/sh command, on Windows it is the cmd.exe. -The actual shell referred to by /bin/sh also depends on the system. -As of npm@5.1.0 you can -customize the shell with the script-shell configuration.

-

Scripts are run from the root of the module, regardless of what your current -working directory is when you call npm run. If you want your script to -use different behavior based on what subdirectory you're in, you can use the -INIT_CWD environment variable, which holds the full path you were in when -you ran npm run.

-

npm run sets the NODE environment variable to the node executable with -which npm is executed. Also, if the --scripts-prepend-node-path is passed, -the directory within which node resides is added to the -PATH. If --scripts-prepend-node-path=auto is passed (which has been the -default in npm v3), this is only performed when that node executable is -not found in the PATH.

-

If you try to run a script without having a node_modules directory and it fails, -you will be given a warning to run npm install, just in case you've forgotten.

-

You can use the --silent flag to prevent showing npm ERR! output on error.

-

You can use the --if-present flag to avoid exiting with a non-zero exit code -when the script is undefined. This lets you run potentially undefined scripts -without breaking the execution chain.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-search.html b/deps/npm/html/doc/cli/npm-search.html deleted file mode 100644 index 01d0686d39f5eb..00000000000000 --- a/deps/npm/html/doc/cli/npm-search.html +++ /dev/null @@ -1,112 +0,0 @@ - - - npm-search - - - - - - -
- -

npm-search

Search for packages

-

SYNOPSIS

-
npm search [-l|--long] [--json] [--parseable] [--no-description] [search terms ...]
-
-aliases: s, se, find

DESCRIPTION

-

Search the registry for packages matching the search terms. npm search -performs a linear, incremental, lexically-ordered search through package -metadata for all files in the registry. If color is enabled, it will further -highlight the matches in the results.

-

Additionally, using the --searchopts and --searchexclude options paired with -more search terms will respectively include and exclude further patterns. The -main difference between --searchopts and the standard search terms is that the -former does not highlight results in the output and can be used for more -fine-grained filtering. Additionally, both of these can be added to .npmrc for -default search filtering behavior.

-

Search also allows targeting of maintainers in search results, by prefixing -their npm username with =.

-

If a term starts with /, then it's interpreted as a regular expression and -supports standard JavaScript RegExp syntax. A trailing / will be ignored in -this case. (Note that many regular expression characters must be escaped or -quoted in most shells.)

-

A Note on caching

-

CONFIGURATION

-

description

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Used as --no-description, disables search matching in package descriptions and -suppresses display of that field in results.

-

json

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Output search results as a JSON array.

-

parseable

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Output search results as lines with tab-separated columns.

-

long

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Display full package descriptions and other long text across multiple -lines. When disabled (default) search results are truncated to fit -neatly on a single line. Modules with extremely long names will -fall on multiple lines.

-

searchopts

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

Space-separated options that are always passed to search.

-

searchexclude

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

Space-separated options that limit the results from search.

-

searchstaleness

-
    -
  • Default: 900 (15 minutes)
  • -
  • Type: Number
  • -
-

The age of the cache, in seconds, before another registry request is made.

-

registry

- -

Search the specified registry for modules. If you have configured npm to point -to a different default registry, such as your internal private module -repository, npm search will default to that registry when searching. Pass a -different registry url such as the default above in order to override this -setting.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-shrinkwrap.html b/deps/npm/html/doc/cli/npm-shrinkwrap.html deleted file mode 100644 index 9a077cf1860493..00000000000000 --- a/deps/npm/html/doc/cli/npm-shrinkwrap.html +++ /dev/null @@ -1,44 +0,0 @@ - - - npm-shrinkwrap - - - - - - -
- -

npm-shrinkwrap

Lock down dependency versions for publication

-

SYNOPSIS

-
npm shrinkwrap

DESCRIPTION

-

This command repurposes package-lock.json into a publishable -npm-shrinkwrap.json or simply creates a new one. The file created and updated -by this command will then take precedence over any other existing or future -package-lock.json files. For a detailed explanation of the design and purpose -of package locks in npm, see npm-package-locks(5).

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-star.html b/deps/npm/html/doc/cli/npm-star.html deleted file mode 100644 index a11093566a1ba5..00000000000000 --- a/deps/npm/html/doc/cli/npm-star.html +++ /dev/null @@ -1,39 +0,0 @@ - - - npm-star - - - - - - -
- -

npm-star

Mark your favorite packages

-

SYNOPSIS

-
npm star [<pkg>...]
-npm unstar [<pkg>...]

DESCRIPTION

-

"Starring" a package means that you have some interest in it. It's -a vaguely positive way to show that you care.

-

"Unstarring" is the same thing, but in reverse.

-

It's a boolean thing. Starring repeatedly has no additional effect.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-stars.html b/deps/npm/html/doc/cli/npm-stars.html deleted file mode 100644 index fdbb1a4af99edb..00000000000000 --- a/deps/npm/html/doc/cli/npm-stars.html +++ /dev/null @@ -1,39 +0,0 @@ - - - npm-stars - - - - - - -
- -

npm-stars

View packages marked as favorites

-

SYNOPSIS

-
npm stars [<user>]

DESCRIPTION

-

If you have starred a lot of neat things and want to find them again -quickly this command lets you do just that.

-

You may also want to see your friend's favorite packages, in this case -you will most certainly enjoy this command.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-start.html b/deps/npm/html/doc/cli/npm-start.html deleted file mode 100644 index 42be90129e9d40..00000000000000 --- a/deps/npm/html/doc/cli/npm-start.html +++ /dev/null @@ -1,42 +0,0 @@ - - - npm-start - - - - - - -
- -

npm-start

Start a package

-

SYNOPSIS

-
npm start [-- <args>]

DESCRIPTION

-

This runs an arbitrary command specified in the package's "start" property of -its "scripts" object. If no "start" property is specified on the -"scripts" object, it will run node server.js.

-

As of npm@2.0.0, you can -use custom arguments when executing scripts. Refer to npm-run-script(1) for -more details.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-stop.html b/deps/npm/html/doc/cli/npm-stop.html deleted file mode 100644 index f5802ed026c13b..00000000000000 --- a/deps/npm/html/doc/cli/npm-stop.html +++ /dev/null @@ -1,37 +0,0 @@ - - - npm-stop - - - - - - -
- -

npm-stop

Stop a package

-

SYNOPSIS

-
npm stop [-- <args>]

DESCRIPTION

-

This runs a package's "stop" script, if one was provided.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-team.html b/deps/npm/html/doc/cli/npm-team.html deleted file mode 100644 index 922707968e3f0b..00000000000000 --- a/deps/npm/html/doc/cli/npm-team.html +++ /dev/null @@ -1,73 +0,0 @@ - - - npm-team - - - - - - -
- -

npm-team

Manage organization teams and team memberships

-

SYNOPSIS

-
npm team create <scope:team>
-npm team destroy <scope:team>
-
-npm team add <scope:team> <user>
-npm team rm <scope:team> <user>
-
-npm team ls <scope>|<scope:team>
-
-npm team edit <scope:team>

DESCRIPTION

-

Used to manage teams in organizations, and change team memberships. Does not -handle permissions for packages.

-

Teams must always be fully qualified with the organization/scope they belong to -when operating on them, separated by a colon (:). That is, if you have a -developers team on a foo organization, you must always refer to that team as -foo:developers in these commands.

-
    -
  • create / destroy: -Create a new team, or destroy an existing one.

    -
  • -
  • add / rm: -Add a user to an existing team, or remove a user from a team they belong to.

    -
  • -
  • ls: -If performed on an organization name, will return a list of existing teams -under that organization. If performed on a team, it will instead return a list -of all users belonging to that particular team.

    -
  • -
  • edit: -Edit a current team.

    -
  • -
-

DETAILS

-

npm team always operates directly on the current registry, configurable from -the command line using --registry=<registry url>.

-

In order to create teams and manage team membership, you must be a team admin -under the given organization. Listing teams and team memberships may be done by -any member of the organizations.

-

Organization creation and management of team admins and organization members -is done through the website, not the npm CLI.

-

To use teams to manage permissions on packages belonging to your organization, -use the npm access command to grant or revoke the appropriate permissions.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-test.html b/deps/npm/html/doc/cli/npm-test.html deleted file mode 100644 index 35bcbf8ecc096c..00000000000000 --- a/deps/npm/html/doc/cli/npm-test.html +++ /dev/null @@ -1,39 +0,0 @@ - - - npm-test - - - - - - -
- -

npm-test

Test a package

-

SYNOPSIS

-
  npm test [-- <args>]
-
-  aliases: t, tst

DESCRIPTION

-

This runs a package's "test" script, if one was provided.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-token.html b/deps/npm/html/doc/cli/npm-token.html deleted file mode 100644 index 33c0dee0b628f0..00000000000000 --- a/deps/npm/html/doc/cli/npm-token.html +++ /dev/null @@ -1,84 +0,0 @@ - - - npm-token - - - - - - -
- -

npm-token

Manage your authentication tokens

-

SYNOPSIS

-
npm token list [--json|--parseable]
-npm token create [--read-only] [--cidr=1.1.1.1/24,2.2.2.2/16]
-npm token revoke <id|token>

DESCRIPTION

-

This lets you list, create and revoke authentication tokens.

-
    -
  • npm token list: -Shows a table of all active authentication tokens. You can request this as -JSON with --json or tab-separated values with --parseable. -```

    -
  • -
  • --------+---------+------------+----------+----------------+ -| id | token | created | read-only | CIDR whitelist |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| 7f3134 | 1fa9ba… | 2017-10-02 | yes | |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| c03241 | af7aef… | 2017-10-02 | no | 192.168.0.1/24 |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| e0cf92 | 3a436a… | 2017-10-02 | no | |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| 63eb9d | 74ef35… | 2017-09-28 | no | |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| 2daaa8 | cbad5f… | 2017-09-26 | no | |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| 68c2fe | 127e51… | 2017-09-23 | no | |

    -
  • -
  • --------+---------+------------+----------+----------------+ -| 6334e1 | 1dadd1… | 2017-09-23 | no | |

    -
  • -
  • --------+---------+------------+----------+----------------+

    -
  • -
  • npm token create [--read-only] [--cidr=<cidr-ranges>]: -Create a new authentication token. It can be --read-only or accept a list of -CIDR ranges to -limit use of this token to. This will prompt you for your password, and, if you have -two-factor authentication enabled, an otp.

    -
  • -
-
+----------------+--------------------------------------+
-| token          | a73c9572-f1b9-8983-983d-ba3ac3cc913d |
-+----------------+--------------------------------------+
-| cidr_whitelist |                                      |
-+----------------+--------------------------------------+
-| readonly       | false                                |
-+----------------+--------------------------------------+
-| created        | 2017-10-02T07:52:24.838Z             |
-+----------------+--------------------------------------+
    -
  • npm token revoke <token|id>: -This removes an authentication token, making it immediately unusable. This can accept -both complete tokens (as you get back from npm token create and will -find in your .npmrc) and ids as seen in the npm token list output. -This will NOT accept the truncated token found in npm token list output.
  • -
- -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-uninstall.html b/deps/npm/html/doc/cli/npm-uninstall.html deleted file mode 100644 index e403783daef612..00000000000000 --- a/deps/npm/html/doc/cli/npm-uninstall.html +++ /dev/null @@ -1,64 +0,0 @@ - - - npm-uninstall - - - - - - -
- -

npm-uninstall

Remove a package

-

SYNOPSIS

-
npm uninstall [<@scope>/]<pkg>[@<version>]... [-S|--save|-D|--save-dev|-O|--save-optional|--no-save]
-
-aliases: remove, rm, r, un, unlink

DESCRIPTION

-

This uninstalls a package, completely removing everything npm installed -on its behalf.

-

Example:

-
npm uninstall sax

In global mode (ie, with -g or --global appended to the command), -it uninstalls the current package context as a global package.

-

npm uninstall takes 3 exclusive, optional flags which save or update -the package version in your main package.json:

-
    -
  • -S, --save: Package will be removed from your dependencies.

    -
  • -
  • -D, --save-dev: Package will be removed from your devDependencies.

    -
  • -
  • -O, --save-optional: Package will be removed from your optionalDependencies.

    -
  • -
  • --no-save: Package will not be removed from your package.json file.

    -
  • -
-

Further, if you have an npm-shrinkwrap.json then it will be updated as -well.

-

Scope is optional and follows the usual rules for npm-scope(7).

-

Examples:

-
npm uninstall sax --save
-npm uninstall @myorg/privatepackage --save
-npm uninstall node-tap --save-dev
-npm uninstall dtrace-provider --save-optional
-npm uninstall lodash --no-save

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-unpublish.html b/deps/npm/html/doc/cli/npm-unpublish.html deleted file mode 100644 index 5dcb1cdd43f816..00000000000000 --- a/deps/npm/html/doc/cli/npm-unpublish.html +++ /dev/null @@ -1,56 +0,0 @@ - - - npm-unpublish - - - - - - -
- -

npm-unpublish

Remove a package from the registry

-

SYNOPSIS

-
npm unpublish [<@scope>/]<pkg>[@<version>]

WARNING

-

It is generally considered bad behavior to remove versions of a library -that others are depending on!

-

Consider using the deprecate command -instead, if your intent is to encourage users to upgrade.

-

There is plenty of room on the registry.

-

DESCRIPTION

-

This removes a package version from the registry, deleting its -entry and removing the tarball.

-

If no version is specified, or if all versions are removed then -the root package entry is removed from the registry entirely.

-

Even if a package version is unpublished, that specific name and -version combination can never be reused. In order to publish the -package again, a new version number must be used. Additionally, -new versions of packages with every version unpublished may not -be republished until 24 hours have passed.

-

With the default registry (registry.npmjs.org), unpublish is -only allowed with versions published in the last 72 hours. If you -are trying to unpublish a version published longer ago than that, -contact support@npmjs.com.

-

The scope is optional and follows the usual rules for npm-scope(7).

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-update.html b/deps/npm/html/doc/cli/npm-update.html deleted file mode 100644 index 3902de03fc43ad..00000000000000 --- a/deps/npm/html/doc/cli/npm-update.html +++ /dev/null @@ -1,104 +0,0 @@ - - - npm-update - - - - - - -
- -

npm-update

Update a package

-

SYNOPSIS

-
npm update [-g] [<pkg>...]
-
-aliases: up, upgrade

DESCRIPTION

-

This command will update all the packages listed to the latest version -(specified by the tag config), respecting semver.

-

It will also install missing packages. As with all commands that install -packages, the --dev flag will cause devDependencies to be processed -as well.

-

If the -g flag is specified, this command will update globally installed -packages.

-

If no package name is specified, all packages in the specified location (global -or local) will be updated.

-

As of npm@2.6.1, the npm update will only inspect top-level packages. -Prior versions of npm would also recursively inspect all dependencies. -To get the old behavior, use npm --depth 9999 update.

-

As of npm@5.0.0, the npm update will change package.json to save the -new version as the minimum required dependency. To get the old behavior, -use npm update --no-save.

-

EXAMPLES

-

IMPORTANT VERSION NOTE: these examples assume npm@2.6.1 or later. For -older versions of npm, you must specify --depth 0 to get the behavior -described below.

-

For the examples below, assume that the current package is app and it depends -on dependencies, dep1 (dep2, .. etc.). The published versions of dep1 are:

-
{
-  "dist-tags": { "latest": "1.2.2" },
-  "versions": [
-    "1.2.2",
-    "1.2.1",
-    "1.2.0",
-    "1.1.2",
-    "1.1.1",
-    "1.0.0",
-    "0.4.1",
-    "0.4.0",
-    "0.2.0"
-  ]
-}

Caret Dependencies

-

If app's package.json contains:

-
"dependencies": {
-  "dep1": "^1.1.1"
-}

Then npm update will install dep1@1.2.2, because 1.2.2 is latest and -1.2.2 satisfies ^1.1.1.

-

Tilde Dependencies

-

However, if app's package.json contains:

-
"dependencies": {
-  "dep1": "~1.1.1"
-}

In this case, running npm update will install dep1@1.1.2. Even though the latest -tag points to 1.2.2, this version does not satisfy ~1.1.1, which is equivalent -to >=1.1.1 <1.2.0. So the highest-sorting version that satisfies ~1.1.1 is used, -which is 1.1.2.

-

Caret Dependencies below 1.0.0

-

Suppose app has a caret dependency on a version below 1.0.0, for example:

-
"dependencies": {
-  "dep1": "^0.2.0"
-}

npm update will install dep1@0.2.0, because there are no other -versions which satisfy ^0.2.0.

-

If the dependence were on ^0.4.0:

-
"dependencies": {
-  "dep1": "^0.4.0"
-}

Then npm update will install dep1@0.4.1, because that is the highest-sorting -version that satisfies ^0.4.0 (>= 0.4.0 <0.5.0)

-

Updating Globally-Installed Packages

-

npm update -g will apply the update action to each globally installed -package that is outdated -- that is, has a version that is different from -latest.

-

NOTE: If a package has been upgraded to a version newer than latest, it will -be downgraded.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-version.html b/deps/npm/html/doc/cli/npm-version.html deleted file mode 100644 index 20fa06c4ce8443..00000000000000 --- a/deps/npm/html/doc/cli/npm-version.html +++ /dev/null @@ -1,120 +0,0 @@ - - - npm-version - - - - - - -
- -

npm-version

Bump a package version

-

SYNOPSIS

-
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
-
-'npm [-v | --version]' to print npm version
-'npm view <pkg> version' to view a package's published version
-'npm ls' to inspect current package/dependency versions

DESCRIPTION

-

Run this in a package directory to bump the version and write the new -data back to package.json, package-lock.json, and, if present, npm-shrinkwrap.json.

-

The newversion argument should be a valid semver string, a -valid second argument to semver.inc (one of patch, minor, major, -prepatch, preminor, premajor, prerelease), or from-git. In the second case, -the existing version will be incremented by 1 in the specified field. -from-git will try to read the latest git tag, and use that as the new npm version.

-

If run in a git repo, it will also create a version commit and tag. -This behavior is controlled by git-tag-version (see below), and can -be disabled on the command line by running npm --no-git-tag-version version. -It will fail if the working directory is not clean, unless the -f or ---force flag is set.

-

If supplied with -m or --message config option, npm will -use it as a commit message when creating a version commit. If the -message config contains %s then that will be replaced with the -resulting version number. For example:

-
npm version patch -m "Upgrade to %s for reasons"

If the sign-git-tag config is set, then the tag will be signed using -the -s flag to git. Note that you must have a default GPG key set up -in your git config for this to work properly. For example:

-
$ npm config set sign-git-tag true
-$ npm version patch
-
-You need a passphrase to unlock the secret key for
-user: "isaacs (http://blog.izs.me/) <i@izs.me>"
-2048-bit RSA key, ID 6C481CF6, created 2010-08-31
-
-Enter passphrase:

If preversion, version, or postversion are in the scripts property of -the package.json, they will be executed as part of running npm version.

-

The exact order of execution is as follows:

-
    -
  1. Check to make sure the git working directory is clean before we get started. -Your scripts may add files to the commit in future steps. -This step is skipped if the --force flag is set.
  2. -
  3. Run the preversion script. These scripts have access to the old version in package.json. -A typical use would be running your full test suite before deploying. -Any files you want added to the commit should be explicitly added using git add.
  4. -
  5. Bump version in package.json as requested (patch, minor, major, etc).
  6. -
  7. Run the version script. These scripts have access to the new version in package.json -(so they can incorporate it into file headers in generated files for example). -Again, scripts should explicitly add generated files to the commit using git add.
  8. -
  9. Commit and tag.
  10. -
  11. Run the postversion script. Use it to clean up the file system or automatically push -the commit and/or tag.
  12. -
-

Take the following example:

-
"scripts": {
-  "preversion": "npm test",
-  "version": "npm run build && git add -A dist",
-  "postversion": "git push && git push --tags && rm -rf build/temp"
-}

This runs all your tests, and proceeds only if they pass. Then runs your build script, and -adds everything in the dist directory to the commit. After the commit, it pushes the new commit -and tag up to the server, and deletes the build/temp directory.

-

CONFIGURATION

-

allow-same-version

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Prevents throwing an error when npm version is used to set the new version -to the same value as the current version.

-

git-tag-version

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Commit and tag the version change.

-

commit-hooks

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Run git commit hooks when committing the version change.

-

sign-git-tag

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Pass the -s flag to git to sign the tag.

-

Note that you must have a default GPG key set up in your git config for this to work properly.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-view.html b/deps/npm/html/doc/cli/npm-view.html deleted file mode 100644 index 814e813b98b7ce..00000000000000 --- a/deps/npm/html/doc/cli/npm-view.html +++ /dev/null @@ -1,79 +0,0 @@ - - - npm-view - - - - - - -
- -

npm-view

View registry info

-

SYNOPSIS

-
npm view [<@scope>/]<name>[@<version>] [<field>[.<subfield>]...]
-
-aliases: info, show, v

DESCRIPTION

-

This command shows data about a package and prints it to the stream -referenced by the outfd config, which defaults to stdout.

-

To show the package registry entry for the connect package, you can do -this:

-
npm view connect

The default version is "latest" if unspecified.

-

Field names can be specified after the package descriptor. -For example, to show the dependencies of the ronn package at version -0.3.5, you could do the following:

-
npm view ronn@0.3.5 dependencies

You can view child fields by separating them with a period. -To view the git repository URL for the latest version of npm, you could -do this:

-
npm view npm repository.url

This makes it easy to view information about a dependency with a bit of -shell scripting. For example, to view all the data about the version of -opts that ronn depends on, you can do this:

-
npm view opts@$(npm view ronn dependencies.opts)

For fields that are arrays, requesting a non-numeric field will return -all of the values from the objects in the list. For example, to get all -the contributor names for the "express" project, you can do this:

-
npm view express contributors.email

You may also use numeric indices in square braces to specifically select -an item in an array field. To just get the email address of the first -contributor in the list, you can do this:

-
npm view express contributors[0].email

Multiple fields may be specified, and will be printed one after another. -For example, to get all the contributor names and email addresses, you -can do this:

-
npm view express contributors.name contributors.email

"Person" fields are shown as a string if they would be shown as an -object. So, for example, this will show the list of npm contributors in -the shortened string format. (See package.json(5) for more on this.)

-
npm view npm contributors

If a version range is provided, then data will be printed for every -matching version of the package. This will show which version of jsdom -was required by each matching version of yui3:

-
npm view yui3@'>0.5.4' dependencies.jsdom

To show the connect package version history, you can do -this:

-
npm view connect versions

OUTPUT

-

If only a single string field for a single version is output, then it -will not be colorized or quoted, so as to enable piping the output to -another command. If the field is an object, it will be output as a JavaScript object literal.

-

If the --json flag is given, the outputted fields will be JSON.

-

If the version range matches multiple versions, than each printed value -will be prefixed with the version it applies to.

-

If multiple fields are requested, than each of them are prefixed with -the field name.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm-whoami.html b/deps/npm/html/doc/cli/npm-whoami.html deleted file mode 100644 index d986eeef56bddc..00000000000000 --- a/deps/npm/html/doc/cli/npm-whoami.html +++ /dev/null @@ -1,36 +0,0 @@ - - - npm-whoami - - - - - - -
- -

npm-whoami

Display npm username

-

SYNOPSIS

-
npm whoami [--registry <registry>]

DESCRIPTION

-

Print the username config to standard output.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/cli/npm.html b/deps/npm/html/doc/cli/npm.html deleted file mode 100644 index 74a27382b39b2b..00000000000000 --- a/deps/npm/html/doc/cli/npm.html +++ /dev/null @@ -1,158 +0,0 @@ - - - npm - - - - - - -
- -

npm

javascript package manager

-

SYNOPSIS

-
npm <command> [args]

VERSION

-

6.12.1

-

DESCRIPTION

-

npm is the package manager for the Node JavaScript platform. It puts -modules in place so that node can find them, and manages dependency -conflicts intelligently.

-

It is extremely configurable to support a wide variety of use cases. -Most commonly, it is used to publish, discover, install, and develop node -programs.

-

Run npm help to get a list of available commands.

-

IMPORTANT

-

npm is configured to use npm, Inc.'s public registry at -https://registry.npmjs.org by default. Use of the npm public registry is -subject to terms of use available at https://www.npmjs.com/policies/terms.

-

You can configure npm to use any compatible registry you like, and even run -your own registry. Use of someone else's registry may be governed by their -terms of use.

-

INTRODUCTION

-

You probably got npm because you want to install stuff.

-

Use npm install blerg to install the latest version of "blerg". Check out -npm-install(1) for more info. It can do a lot of stuff.

-

Use the npm search command to show everything that's available. -Use npm ls to show everything you've installed.

-

DEPENDENCIES

-

If a package references to another package with a git URL, npm depends -on a preinstalled git.

-

If one of the packages npm tries to install is a native node module and -requires compiling of C++ Code, npm will use -node-gyp for that task. -For a Unix system, node-gyp -needs Python, make and a buildchain like GCC. On Windows, -Python and Microsoft Visual Studio C++ are needed. Python 3 is -not supported by node-gyp. -For more information visit -the node-gyp repository and -the node-gyp Wiki.

-

DIRECTORIES

-

See npm-folders(5) to learn about where npm puts stuff.

-

In particular, npm has two modes of operation:

-
    -
  • global mode: -npm installs packages into the install prefix at -prefix/lib/node_modules and bins are installed in prefix/bin.
  • -
  • local mode: -npm installs packages into the current project directory, which -defaults to the current working directory. Packages are installed to -./node_modules, and bins are installed to ./node_modules/.bin.
  • -
-

Local mode is the default. Use -g or --global on any command to -operate in global mode instead.

-

DEVELOPER USAGE

-

If you're using npm to develop and publish your code, check out the -following help topics:

-
    -
  • json: -Make a package.json file. See package.json(5).
  • -
  • link: -For linking your current working code into Node's path, so that you -don't have to reinstall every time you make a change. Use -npm link to do this.
  • -
  • install: -It's a good idea to install things if you don't need the symbolic link. -Especially, installing other peoples code from the registry is done via -npm install
  • -
  • adduser: -Create an account or log in. Credentials are stored in the -user config file.
  • -
  • publish: -Use the npm publish command to upload your code to the registry.
  • -
-

CONFIGURATION

-

npm is extremely configurable. It reads its configuration options from -5 places.

-
    -
  • Command line switches: -Set a config with --key val. All keys take a value, even if they -are booleans (the config parser doesn't know what the options are at -the time of parsing). If no value is provided, then the option is set -to boolean true.
  • -
  • Environment Variables: -Set any config by prefixing the name in an environment variable with -npm_config_. For example, export npm_config_key=val.
  • -
  • User Configs: -The file at $HOME/.npmrc is an ini-formatted list of configs. If -present, it is parsed. If the userconfig option is set in the cli -or env, then that will be used instead.
  • -
  • Global Configs: -The file found at ../etc/npmrc (from the node executable, by default -this resolves to /usr/local/etc/npmrc) will be parsed if it is found. -If the globalconfig option is set in the cli, env, or user config, -then that file is parsed instead.
  • -
  • Defaults: -npm's default configuration options are defined in -lib/utils/config-defs.js. These must not be changed.
  • -
-

See npm-config(7) for much much more information.

-

CONTRIBUTIONS

-

Patches welcome!

-

If you would like to contribute, but don't know what to work on, read -the contributing guidelines and check the issues list.

- -

BUGS

-

When you find issues, please report them:

- -

Be sure to follow the template and bug reporting guidelines. You can also ask -for help in the support forum if you're -unsure if it's actually a bug or are having trouble coming up with a detailed -reproduction to report.

-

AUTHOR

-

Isaac Z. Schlueter :: -isaacs :: -@izs :: -i@izs.me

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npm-folders.html b/deps/npm/html/doc/files/npm-folders.html deleted file mode 100644 index e3ea5410587717..00000000000000 --- a/deps/npm/html/doc/files/npm-folders.html +++ /dev/null @@ -1,183 +0,0 @@ - - - npm-folders - - - - - - -
- -

npm-folders

Folder Structures Used by npm

-

DESCRIPTION

-

npm puts various things on your computer. That's its job.

-

This document will tell you what it puts where.

-

tl;dr

-
    -
  • Local install (default): puts stuff in ./node_modules of the current -package root.
  • -
  • Global install (with -g): puts stuff in /usr/local or wherever node -is installed.
  • -
  • Install it locally if you're going to require() it.
  • -
  • Install it globally if you're going to run it on the command line.
  • -
  • If you need both, then install it in both places, or use npm link.
  • -
-

prefix Configuration

-

The prefix config defaults to the location where node is installed. -On most systems, this is /usr/local. On Windows, it's %AppData%\npm. -On Unix systems, it's one level up, since node is typically installed at -{prefix}/bin/node rather than {prefix}/node.exe.

-

When the global flag is set, npm installs things into this prefix. -When it is not set, it uses the root of the current package, or the -current working directory if not in a package already.

-

Node Modules

-

Packages are dropped into the node_modules folder under the prefix. -When installing locally, this means that you can -require("packagename") to load its main module, or -require("packagename/lib/path/to/sub/module") to load other modules.

-

Global installs on Unix systems go to {prefix}/lib/node_modules. -Global installs on Windows go to {prefix}/node_modules (that is, no -lib folder.)

-

Scoped packages are installed the same way, except they are grouped together -in a sub-folder of the relevant node_modules folder with the name of that -scope prefix by the @ symbol, e.g. npm install @myorg/package would place -the package in {prefix}/node_modules/@myorg/package. See scope(7) for -more details.

-

If you wish to require() a package, then install it locally.

-

Executables

-

When in global mode, executables are linked into {prefix}/bin on Unix, -or directly into {prefix} on Windows.

-

When in local mode, executables are linked into -./node_modules/.bin so that they can be made available to scripts run -through npm. (For example, so that a test runner will be in the path -when you run npm test.)

-

Man Pages

-

When in global mode, man pages are linked into {prefix}/share/man.

-

When in local mode, man pages are not installed.

-

Man pages are not installed on Windows systems.

-

Cache

-

See npm-cache(1). Cache files are stored in ~/.npm on Posix, or -%AppData%/npm-cache on Windows.

-

This is controlled by the cache configuration param.

-

Temp Files

-

Temporary files are stored by default in the folder specified by the -tmp config, which defaults to the TMPDIR, TMP, or TEMP environment -variables, or /tmp on Unix and c:\windows\temp on Windows.

-

Temp files are given a unique folder under this root for each run of the -program, and are deleted upon successful exit.

-

More Information

-

When installing locally, npm first tries to find an appropriate -prefix folder. This is so that npm install foo@1.2.3 will install -to the sensible root of your package, even if you happen to have cded -into some other folder.

-

Starting at the $PWD, npm will walk up the folder tree checking for a -folder that contains either a package.json file, or a node_modules -folder. If such a thing is found, then that is treated as the effective -"current directory" for the purpose of running npm commands. (This -behavior is inspired by and similar to git's .git-folder seeking -logic when running git commands in a working dir.)

-

If no package root is found, then the current folder is used.

-

When you run npm install foo@1.2.3, then the package is loaded into -the cache, and then unpacked into ./node_modules/foo. Then, any of -foo's dependencies are similarly unpacked into -./node_modules/foo/node_modules/....

-

Any bin files are symlinked to ./node_modules/.bin/, so that they may -be found by npm scripts when necessary.

-

Global Installation

-

If the global configuration is set to true, then npm will -install packages "globally".

-

For global installation, packages are installed roughly the same way, -but using the folders described above.

-

Cycles, Conflicts, and Folder Parsimony

-

Cycles are handled using the property of node's module system that it -walks up the directories looking for node_modules folders. So, at every -stage, if a package is already installed in an ancestor node_modules -folder, then it is not installed at the current location.

-

Consider the case above, where foo -> bar -> baz. Imagine if, in -addition to that, baz depended on bar, so you'd have: -foo -> bar -> baz -> bar -> baz .... However, since the folder -structure is: foo/node_modules/bar/node_modules/baz, there's no need to -put another copy of bar into .../baz/node_modules, since when it calls -require("bar"), it will get the copy that is installed in -foo/node_modules/bar.

-

This shortcut is only used if the exact same -version would be installed in multiple nested node_modules folders. It -is still possible to have a/node_modules/b/node_modules/a if the two -"a" packages are different versions. However, without repeating the -exact same package multiple times, an infinite regress will always be -prevented.

-

Another optimization can be made by installing dependencies at the -highest level possible, below the localized "target" folder.

-

Example

-

Consider this dependency graph:

-
foo
-+-- blerg@1.2.5
-+-- bar@1.2.3
-|   +-- blerg@1.x (latest=1.3.7)
-|   +-- baz@2.x
-|   |   `-- quux@3.x
-|   |       `-- bar@1.2.3 (cycle)
-|   `-- asdf@*
-`-- baz@1.2.3
-    `-- quux@3.x
-        `-- bar

In this case, we might expect a folder structure like this:

-
foo
-+-- node_modules
-    +-- blerg (1.2.5) <---[A]
-    +-- bar (1.2.3) <---[B]
-    |   `-- node_modules
-    |       +-- baz (2.0.2) <---[C]
-    |       |   `-- node_modules
-    |       |       `-- quux (3.2.0)
-    |       `-- asdf (2.3.4)
-    `-- baz (1.2.3) <---[D]
-        `-- node_modules
-            `-- quux (3.2.0) <---[E]

Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are -installed in foo's node_modules folder.

-

Even though the latest copy of blerg is 1.3.7, foo has a specific -dependency on version 1.2.5. So, that gets installed at [A]. Since the -parent installation of blerg satisfies bar's dependency on blerg@1.x, -it does not install another copy under [B].

-

Bar [B] also has dependencies on baz and asdf, so those are installed in -bar's node_modules folder. Because it depends on baz@2.x, it cannot -re-use the baz@1.2.3 installed in the parent node_modules folder [D], -and must install its own copy [C].

-

Underneath bar, the baz -> quux -> bar dependency creates a cycle. -However, because bar is already in quux's ancestry [B], it does not -unpack another copy of bar into that folder.

-

Underneath foo -> baz [D], quux's [E] folder tree is empty, because its -dependency on bar is satisfied by the parent folder copy installed at [B].

-

For a graphical breakdown of what is installed where, use npm ls.

-

Publishing

-

Upon publishing, npm will look in the node_modules folder. If any of -the items there are not in the bundledDependencies array, then they will -not be included in the package tarball.

-

This allows a package maintainer to install all of their dependencies -(and dev dependencies) locally, but only re-publish those items that -cannot be found elsewhere. See package.json(5) for more information.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npm-global.html b/deps/npm/html/doc/files/npm-global.html deleted file mode 100644 index e3ea5410587717..00000000000000 --- a/deps/npm/html/doc/files/npm-global.html +++ /dev/null @@ -1,183 +0,0 @@ - - - npm-folders - - - - - - -
- -

npm-folders

Folder Structures Used by npm

-

DESCRIPTION

-

npm puts various things on your computer. That's its job.

-

This document will tell you what it puts where.

-

tl;dr

-
    -
  • Local install (default): puts stuff in ./node_modules of the current -package root.
  • -
  • Global install (with -g): puts stuff in /usr/local or wherever node -is installed.
  • -
  • Install it locally if you're going to require() it.
  • -
  • Install it globally if you're going to run it on the command line.
  • -
  • If you need both, then install it in both places, or use npm link.
  • -
-

prefix Configuration

-

The prefix config defaults to the location where node is installed. -On most systems, this is /usr/local. On Windows, it's %AppData%\npm. -On Unix systems, it's one level up, since node is typically installed at -{prefix}/bin/node rather than {prefix}/node.exe.

-

When the global flag is set, npm installs things into this prefix. -When it is not set, it uses the root of the current package, or the -current working directory if not in a package already.

-

Node Modules

-

Packages are dropped into the node_modules folder under the prefix. -When installing locally, this means that you can -require("packagename") to load its main module, or -require("packagename/lib/path/to/sub/module") to load other modules.

-

Global installs on Unix systems go to {prefix}/lib/node_modules. -Global installs on Windows go to {prefix}/node_modules (that is, no -lib folder.)

-

Scoped packages are installed the same way, except they are grouped together -in a sub-folder of the relevant node_modules folder with the name of that -scope prefix by the @ symbol, e.g. npm install @myorg/package would place -the package in {prefix}/node_modules/@myorg/package. See scope(7) for -more details.

-

If you wish to require() a package, then install it locally.

-

Executables

-

When in global mode, executables are linked into {prefix}/bin on Unix, -or directly into {prefix} on Windows.

-

When in local mode, executables are linked into -./node_modules/.bin so that they can be made available to scripts run -through npm. (For example, so that a test runner will be in the path -when you run npm test.)

-

Man Pages

-

When in global mode, man pages are linked into {prefix}/share/man.

-

When in local mode, man pages are not installed.

-

Man pages are not installed on Windows systems.

-

Cache

-

See npm-cache(1). Cache files are stored in ~/.npm on Posix, or -%AppData%/npm-cache on Windows.

-

This is controlled by the cache configuration param.

-

Temp Files

-

Temporary files are stored by default in the folder specified by the -tmp config, which defaults to the TMPDIR, TMP, or TEMP environment -variables, or /tmp on Unix and c:\windows\temp on Windows.

-

Temp files are given a unique folder under this root for each run of the -program, and are deleted upon successful exit.

-

More Information

-

When installing locally, npm first tries to find an appropriate -prefix folder. This is so that npm install foo@1.2.3 will install -to the sensible root of your package, even if you happen to have cded -into some other folder.

-

Starting at the $PWD, npm will walk up the folder tree checking for a -folder that contains either a package.json file, or a node_modules -folder. If such a thing is found, then that is treated as the effective -"current directory" for the purpose of running npm commands. (This -behavior is inspired by and similar to git's .git-folder seeking -logic when running git commands in a working dir.)

-

If no package root is found, then the current folder is used.

-

When you run npm install foo@1.2.3, then the package is loaded into -the cache, and then unpacked into ./node_modules/foo. Then, any of -foo's dependencies are similarly unpacked into -./node_modules/foo/node_modules/....

-

Any bin files are symlinked to ./node_modules/.bin/, so that they may -be found by npm scripts when necessary.

-

Global Installation

-

If the global configuration is set to true, then npm will -install packages "globally".

-

For global installation, packages are installed roughly the same way, -but using the folders described above.

-

Cycles, Conflicts, and Folder Parsimony

-

Cycles are handled using the property of node's module system that it -walks up the directories looking for node_modules folders. So, at every -stage, if a package is already installed in an ancestor node_modules -folder, then it is not installed at the current location.

-

Consider the case above, where foo -> bar -> baz. Imagine if, in -addition to that, baz depended on bar, so you'd have: -foo -> bar -> baz -> bar -> baz .... However, since the folder -structure is: foo/node_modules/bar/node_modules/baz, there's no need to -put another copy of bar into .../baz/node_modules, since when it calls -require("bar"), it will get the copy that is installed in -foo/node_modules/bar.

-

This shortcut is only used if the exact same -version would be installed in multiple nested node_modules folders. It -is still possible to have a/node_modules/b/node_modules/a if the two -"a" packages are different versions. However, without repeating the -exact same package multiple times, an infinite regress will always be -prevented.

-

Another optimization can be made by installing dependencies at the -highest level possible, below the localized "target" folder.

-

Example

-

Consider this dependency graph:

-
foo
-+-- blerg@1.2.5
-+-- bar@1.2.3
-|   +-- blerg@1.x (latest=1.3.7)
-|   +-- baz@2.x
-|   |   `-- quux@3.x
-|   |       `-- bar@1.2.3 (cycle)
-|   `-- asdf@*
-`-- baz@1.2.3
-    `-- quux@3.x
-        `-- bar

In this case, we might expect a folder structure like this:

-
foo
-+-- node_modules
-    +-- blerg (1.2.5) <---[A]
-    +-- bar (1.2.3) <---[B]
-    |   `-- node_modules
-    |       +-- baz (2.0.2) <---[C]
-    |       |   `-- node_modules
-    |       |       `-- quux (3.2.0)
-    |       `-- asdf (2.3.4)
-    `-- baz (1.2.3) <---[D]
-        `-- node_modules
-            `-- quux (3.2.0) <---[E]

Since foo depends directly on bar@1.2.3 and baz@1.2.3, those are -installed in foo's node_modules folder.

-

Even though the latest copy of blerg is 1.3.7, foo has a specific -dependency on version 1.2.5. So, that gets installed at [A]. Since the -parent installation of blerg satisfies bar's dependency on blerg@1.x, -it does not install another copy under [B].

-

Bar [B] also has dependencies on baz and asdf, so those are installed in -bar's node_modules folder. Because it depends on baz@2.x, it cannot -re-use the baz@1.2.3 installed in the parent node_modules folder [D], -and must install its own copy [C].

-

Underneath bar, the baz -> quux -> bar dependency creates a cycle. -However, because bar is already in quux's ancestry [B], it does not -unpack another copy of bar into that folder.

-

Underneath foo -> baz [D], quux's [E] folder tree is empty, because its -dependency on bar is satisfied by the parent folder copy installed at [B].

-

For a graphical breakdown of what is installed where, use npm ls.

-

Publishing

-

Upon publishing, npm will look in the node_modules folder. If any of -the items there are not in the bundledDependencies array, then they will -not be included in the package tarball.

-

This allows a package maintainer to install all of their dependencies -(and dev dependencies) locally, but only re-publish those items that -cannot be found elsewhere. See package.json(5) for more information.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npm-json.html b/deps/npm/html/doc/files/npm-json.html deleted file mode 100644 index be7a98ea58e76a..00000000000000 --- a/deps/npm/html/doc/files/npm-json.html +++ /dev/null @@ -1,585 +0,0 @@ - - - package.json - - - - - - -
- -

package.json

Specifics of npm's package.json handling

-

DESCRIPTION

-

This document is all you need to know about what's required in your package.json -file. It must be actual JSON, not just a JavaScript object literal.

-

A lot of the behavior described in this document is affected by the config -settings described in npm-config(7).

-

name

-

If you plan to publish your package, the most important things in your -package.json are the name and version fields as they will be required. The name -and version together form an identifier that is assumed to be completely unique. -Changes to the package should come along with changes to the version. If you don't -plan to publish your package, the name and version fields are optional.

-

The name is what your thing is called.

-

Some rules:

-
    -
  • The name must be less than or equal to 214 characters. This includes the scope for -scoped packages.
  • -
  • The name can't start with a dot or an underscore.
  • -
  • New packages must not have uppercase letters in the name.
  • -
  • The name ends up being part of a URL, an argument on the command line, and a -folder name. Therefore, the name can't contain any non-URL-safe characters.
  • -
-

Some tips:

-
    -
  • Don't use the same name as a core Node module.
  • -
  • Don't put "js" or "node" in the name. It's assumed that it's js, since you're -writing a package.json file, and you can specify the engine using the "engines" -field. (See below.)
  • -
  • The name will probably be passed as an argument to require(), so it should -be something short, but also reasonably descriptive.
  • -
  • You may want to check the npm registry to see if there's something by that name -already, before you get too attached to it. https://www.npmjs.com/
  • -
-

A name can be optionally prefixed by a scope, e.g. @myorg/mypackage. See -npm-scope(7) for more detail.

-

version

-

If you plan to publish your package, the most important things in your -package.json are the name and version fields as they will be required. The name -and version together form an identifier that is assumed to be completely unique. -Changes to the package should come along with changes to the version. If you don't -plan to publish your package, the name and version fields are optional.

-

Version must be parseable by -node-semver, which is bundled -with npm as a dependency. (npm install semver to use it yourself.)

-

More on version numbers and ranges at semver(7).

-

description

-

Put a description in it. It's a string. This helps people discover your -package, as it's listed in npm search.

-

keywords

-

Put keywords in it. It's an array of strings. This helps people -discover your package as it's listed in npm search.

-

homepage

-

The url to the project homepage.

-

Example:

-
"homepage": "https://github.com/owner/project#readme"

bugs

-

The url to your project's issue tracker and / or the email address to which -issues should be reported. These are helpful for people who encounter issues -with your package.

-

It should look like this:

-
{ "url" : "https://github.com/owner/project/issues"
-, "email" : "project@hostname.com"
-}

You can specify either one or both values. If you want to provide only a url, -you can specify the value for "bugs" as a simple string instead of an object.

-

If a url is provided, it will be used by the npm bugs command.

-

license

-

You should specify a license for your package so that people know how they are -permitted to use it, and any restrictions you're placing on it.

-

If you're using a common license such as BSD-2-Clause or MIT, add a -current SPDX license identifier for the license you're using, like this:

-
{ "license" : "BSD-3-Clause" }

You can check the full list of SPDX license IDs. -Ideally you should pick one that is -OSI approved.

-

If your package is licensed under multiple common licenses, use an SPDX license -expression syntax version 2.0 string, like this:

-
{ "license" : "(ISC OR GPL-3.0)" }

If you are using a license that hasn't been assigned an SPDX identifier, or if -you are using a custom license, use a string value like this one:

-
{ "license" : "SEE LICENSE IN <filename>" }

Then include a file named <filename> at the top level of the package.

-

Some old packages used license objects or a "licenses" property containing an -array of license objects:

-
// Not valid metadata
-{ "license" :
-  { "type" : "ISC"
-  , "url" : "https://opensource.org/licenses/ISC"
-  }
-}
-
-// Not valid metadata
-{ "licenses" :
-  [
-    { "type": "MIT"
-    , "url": "https://www.opensource.org/licenses/mit-license.php"
-    }
-  , { "type": "Apache-2.0"
-    , "url": "https://opensource.org/licenses/apache2.0.php"
-    }
-  ]
-}

Those styles are now deprecated. Instead, use SPDX expressions, like this:

-
{ "license": "ISC" }
-
-{ "license": "(MIT OR Apache-2.0)" }

Finally, if you do not wish to grant others the right to use a private or -unpublished package under any terms:

-
{ "license": "UNLICENSED" }

Consider also setting "private": true to prevent accidental publication.

-

people fields: author, contributors

-

The "author" is one person. "contributors" is an array of people. A "person" -is an object with a "name" field and optionally "url" and "email", like this:

-
{ "name" : "Barney Rubble"
-, "email" : "b@rubble.com"
-, "url" : "http://barnyrubble.tumblr.com/"
-}

Or you can shorten that all into a single string, and npm will parse it for you:

-
"Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"

Both email and url are optional either way.

-

npm also sets a top-level "maintainers" field with your npm user info.

-

files

-

The optional files field is an array of file patterns that describes -the entries to be included when your package is installed as a -dependency. File patterns follow a similar syntax to .gitignore, but -reversed: including a file, directory, or glob pattern (*, **/*, and such) -will make it so that file is included in the tarball when it's packed. Omitting -the field will make it default to ["*"], which means it will include all files.

-

Some special files and directories are also included or excluded regardless of -whether they exist in the files array (see below).

-

You can also provide a .npmignore file in the root of your package or -in subdirectories, which will keep files from being included. At the -root of your package it will not override the "files" field, but in -subdirectories it will. The .npmignore file works just like a -.gitignore. If there is a .gitignore file, and .npmignore is -missing, .gitignore's contents will be used instead.

-

Files included with the "package.json#files" field cannot be excluded -through .npmignore or .gitignore.

-

Certain files are always included, regardless of settings:

-
    -
  • package.json
  • -
  • README
  • -
  • CHANGES / CHANGELOG / HISTORY
  • -
  • LICENSE / LICENCE
  • -
  • NOTICE
  • -
  • The file in the "main" field
  • -
-

README, CHANGES, LICENSE & NOTICE can have any case and extension.

-

Conversely, some files are always ignored:

-
    -
  • .git
  • -
  • CVS
  • -
  • .svn
  • -
  • .hg
  • -
  • .lock-wscript
  • -
  • .wafpickle-N
  • -
  • .*.swp
  • -
  • .DS_Store
  • -
  • ._*
  • -
  • npm-debug.log
  • -
  • .npmrc
  • -
  • node_modules
  • -
  • config.gypi
  • -
  • *.orig
  • -
  • package-lock.json (use shrinkwrap instead)
  • -
-

main

-

The main field is a module ID that is the primary entry point to your program. -That is, if your package is named foo, and a user installs it, and then does -require("foo"), then your main module's exports object will be returned.

-

This should be a module ID relative to the root of your package folder.

-

For most modules, it makes the most sense to have a main script and often not -much else.

-

browser

-

If your module is meant to be used client-side the browser field should be -used instead of the main field. This is helpful to hint users that it might -rely on primitives that aren't available in Node.js modules. (e.g. window)

-

bin

-

A lot of packages have one or more executable files that they'd like to -install into the PATH. npm makes this pretty easy (in fact, it uses this -feature to install the "npm" executable.)

-

To use this, supply a bin field in your package.json which is a map of -command name to local file name. On install, npm will symlink that file into -prefix/bin for global installs, or ./node_modules/.bin/ for local -installs.

-

For example, myapp could have this:

-
{ "bin" : { "myapp" : "./cli.js" } }

So, when you install myapp, it'll create a symlink from the cli.js script to -/usr/local/bin/myapp.

-

If you have a single executable, and its name should be the name -of the package, then you can just supply it as a string. For example:

-
{ "name": "my-program"
-, "version": "1.2.5"
-, "bin": "./path/to/program" }

would be the same as this:

-
{ "name": "my-program"
-, "version": "1.2.5"
-, "bin" : { "my-program" : "./path/to/program" } }

Please make sure that your file(s) referenced in bin starts with -#!/usr/bin/env node, otherwise the scripts are started without the node -executable!

-

man

-

Specify either a single file or an array of filenames to put in place for the -man program to find.

-

If only a single file is provided, then it's installed such that it is the -result from man <pkgname>, regardless of its actual filename. For example:

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : "./man/doc.1"
-}

would link the ./man/doc.1 file in such that it is the target for man foo

-

If the filename doesn't start with the package name, then it's prefixed. -So, this:

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : [ "./man/foo.1", "./man/bar.1" ]
-}

will create files to do man foo and man foo-bar.

-

Man files must end with a number, and optionally a .gz suffix if they are -compressed. The number dictates which man section the file is installed into.

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : [ "./man/foo.1", "./man/foo.2" ]
-}

will create entries for man foo and man 2 foo

-

directories

-

The CommonJS Packages spec details a -few ways that you can indicate the structure of your package using a directories -object. If you look at npm's package.json, -you'll see that it has directories for doc, lib, and man.

-

In the future, this information may be used in other creative ways.

-

directories.lib

-

Tell people where the bulk of your library is. Nothing special is done -with the lib folder in any way, but it's useful meta info.

-

directories.bin

-

If you specify a bin directory in directories.bin, all the files in -that folder will be added.

-

Because of the way the bin directive works, specifying both a -bin path and setting directories.bin is an error. If you want to -specify individual files, use bin, and for all the files in an -existing bin directory, use directories.bin.

-

directories.man

-

A folder that is full of man pages. Sugar to generate a "man" array by -walking the folder.

-

directories.doc

-

Put markdown files in here. Eventually, these will be displayed nicely, -maybe, someday.

-

directories.example

-

Put example scripts in here. Someday, it might be exposed in some clever way.

-

directories.test

-

Put your tests in here. It is currently not exposed, but it might be in the -future.

-

repository

-

Specify the place where your code lives. This is helpful for people who -want to contribute. If the git repo is on GitHub, then the npm docs -command will be able to find you.

-

Do it like this:

-
"repository": {
-  "type" : "git",
-  "url" : "https://github.com/npm/cli.git"
-}
-
-"repository": {
-  "type" : "svn",
-  "url" : "https://v8.googlecode.com/svn/trunk/"
-}

The URL should be a publicly available (perhaps read-only) url that can be handed -directly to a VCS program without any modification. It should not be a url to an -html project page that you put in your browser. It's for computers.

-

For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same -shortcut syntax you use for npm install:

-
"repository": "npm/npm"
-
-"repository": "github:user/repo"
-
-"repository": "gist:11081aaa281"
-
-"repository": "bitbucket:user/repo"
-
-"repository": "gitlab:user/repo"

If the package.json for your package is not in the root directory (for example -if it is part of a monorepo), you can specify the directory in which it lives:

-
"repository": {
-  "type" : "git",
-  "url" : "https://github.com/facebook/react.git",
-  "directory": "packages/react-dom"
-}

scripts

-

The "scripts" property is a dictionary containing script commands that are run -at various times in the lifecycle of your package. The key is the lifecycle -event, and the value is the command to run at that point.

-

See npm-scripts(7) to find out more about writing package scripts.

-

config

-

A "config" object can be used to set configuration parameters used in package -scripts that persist across upgrades. For instance, if a package had the -following:

-
{ "name" : "foo"
-, "config" : { "port" : "8080" } }

and then had a "start" command that then referenced the -npm_package_config_port environment variable, then the user could -override that by doing npm config set foo:port 8001.

-

See npm-config(7) and npm-scripts(7) for more on package -configs.

-

dependencies

-

Dependencies are specified in a simple object that maps a package name to a -version range. The version range is a string which has one or more -space-separated descriptors. Dependencies can also be identified with a -tarball or git URL.

-

Please do not put test harnesses or transpilers in your -dependencies object. See devDependencies, below.

-

See semver(7) for more details about specifying version ranges.

-
    -
  • version Must match version exactly
  • -
  • >version Must be greater than version
  • -
  • >=version etc
  • -
  • <version
  • -
  • <=version
  • -
  • ~version "Approximately equivalent to version" See semver(7)
  • -
  • ^version "Compatible with version" See semver(7)
  • -
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • -
  • http://... See 'URLs as Dependencies' below
  • -
  • * Matches any version
  • -
  • "" (just an empty string) Same as *
  • -
  • version1 - version2 Same as >=version1 <=version2.
  • -
  • range1 || range2 Passes if either range1 or range2 are satisfied.
  • -
  • git... See 'Git URLs as Dependencies' below
  • -
  • user/repo See 'GitHub URLs' below
  • -
  • tag A specific version tagged and published as tag See npm-dist-tag(1)
  • -
  • path/path/path See Local Paths below
  • -
-

For example, these are all valid:

-
{ "dependencies" :
-  { "foo" : "1.0.0 - 2.9999.9999"
-  , "bar" : ">=1.0.2 <2.1.2"
-  , "baz" : ">1.0.2 <=2.3.4"
-  , "boo" : "2.0.1"
-  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
-  , "asd" : "http://asdf.com/asdf.tar.gz"
-  , "til" : "~1.2"
-  , "elf" : "~1.2.3"
-  , "two" : "2.x"
-  , "thr" : "3.3.x"
-  , "lat" : "latest"
-  , "dyl" : "file:../dyl"
-  }
-}

URLs as Dependencies

-

You may specify a tarball URL in place of a version range.

-

This tarball will be downloaded and installed locally to your package at -install time.

-

Git URLs as Dependencies

-

Git urls are of the form:

-
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

<protocol> is one of git, git+ssh, git+http, git+https, or -git+file.

-

If #<commit-ish> is provided, it will be used to clone exactly that -commit. If the commit-ish has the format #semver:<semver>, <semver> can -be any valid semver range or exact version, and npm will look for any tags -or refs matching that range in the remote repository, much as it would for a -registry dependency. If neither #<commit-ish> or #semver:<semver> is -specified, then master is used.

-

Examples:

-
git+ssh://git@github.com:npm/cli.git#v1.0.27
-git+ssh://git@github.com:npm/cli#semver:^5.0
-git+https://isaacs@github.com/npm/cli.git
-git://github.com/npm/cli.git#v1.0.27

GitHub URLs

-

As of version 1.1.65, you can refer to GitHub urls as just "foo": -"user/foo-project". Just as with git URLs, a commit-ish suffix can be -included. For example:

-
{
-  "name": "foo",
-  "version": "0.0.0",
-  "dependencies": {
-    "express": "expressjs/express",
-    "mocha": "mochajs/mocha#4727d357ea",
-    "module": "user/repo#feature\/branch"
-  }
-}

Local Paths

-

As of version 2.0.0 you can provide a path to a local directory that contains a -package. Local paths can be saved using npm install -S or -npm install --save, using any of these forms:

-
../foo/bar
-~/foo/bar
-./foo/bar
-/foo/bar

in which case they will be normalized to a relative path and added to your -package.json. For example:

-
{
-  "name": "baz",
-  "dependencies": {
-    "bar": "file:../foo/bar"
-  }
-}

This feature is helpful for local offline development and creating -tests that require npm installing where you don't want to hit an -external server, but should not be used when publishing packages -to the public registry.

-

devDependencies

-

If someone is planning on downloading and using your module in their -program, then they probably don't want or need to download and build -the external test or documentation framework that you use.

-

In this case, it's best to map these additional items in a devDependencies -object.

-

These things will be installed when doing npm link or npm install -from the root of a package, and can be managed like any other npm -configuration param. See npm-config(7) for more on the topic.

-

For build steps that are not platform-specific, such as compiling -CoffeeScript or other languages to JavaScript, use the prepare -script to do this, and make the required package a devDependency.

-

For example:

-
{ "name": "ethopia-waza",
-  "description": "a delightfully fruity coffee varietal",
-  "version": "1.2.3",
-  "devDependencies": {
-    "coffee-script": "~1.6.3"
-  },
-  "scripts": {
-    "prepare": "coffee -o lib/ -c src/waza.coffee"
-  },
-  "main": "lib/waza.js"
-}

The prepare script will be run before publishing, so that users -can consume the functionality without requiring them to compile it -themselves. In dev mode (ie, locally running npm install), it'll -run this script as well, so that you can test it easily.

-

peerDependencies

-

In some cases, you want to express the compatibility of your package with a -host tool or library, while not necessarily doing a require of this host. -This is usually referred to as a plugin. Notably, your module may be exposing -a specific interface, expected and specified by the host documentation.

-

For example:

-
{
-  "name": "tea-latte",
-  "version": "1.3.5",
-  "peerDependencies": {
-    "tea": "2.x"
-  }
-}

This ensures your package tea-latte can be installed along with the second -major version of the host package tea only. npm install tea-latte could -possibly yield the following dependency graph:

-
├── tea-latte@1.3.5
-└── tea@2.2.0

NOTE: npm versions 1 and 2 will automatically install peerDependencies if -they are not explicitly depended upon higher in the dependency tree. In the -next major version of npm (npm@3), this will no longer be the case. You will -receive a warning that the peerDependency is not installed instead. The -behavior in npms 1 & 2 was frequently confusing and could easily put you into -dependency hell, a situation that npm is designed to avoid as much as possible.

-

Trying to install another plugin with a conflicting requirement will cause an -error. For this reason, make sure your plugin requirement is as broad as -possible, and not to lock it down to specific patch versions.

-

Assuming the host complies with semver, only changes in -the host package's major version will break your plugin. Thus, if you've worked -with every 1.x version of the host package, use "^1.0" or "1.x" to express -this. If you depend on features introduced in 1.5.2, use ">= 1.5.2 < 2".

-

bundledDependencies

-

This defines an array of package names that will be bundled when publishing -the package.

-

In cases where you need to preserve npm packages locally or have them -available through a single file download, you can bundle the packages in a -tarball file by specifying the package names in the bundledDependencies -array and executing npm pack.

-

For example:

-

If we define a package.json like this:

-
{
-  "name": "awesome-web-framework",
-  "version": "1.0.0",
-  "bundledDependencies": [
-    "renderized", "super-streams"
-  ]
-}

we can obtain awesome-web-framework-1.0.0.tgz file by running npm pack. -This file contains the dependencies renderized and super-streams which -can be installed in a new project by executing npm install -awesome-web-framework-1.0.0.tgz. Note that the package names do not include -any versions, as that information is specified in dependencies.

-

If this is spelled "bundleDependencies", then that is also honored.

-

optionalDependencies

-

If a dependency can be used, but you would like npm to proceed if it cannot be -found or fails to install, then you may put it in the optionalDependencies -object. This is a map of package name to version or url, just like the -dependencies object. The difference is that build failures do not cause -installation to fail.

-

It is still your program's responsibility to handle the lack of the -dependency. For example, something like this:

-
try {
-  var foo = require('foo')
-  var fooVersion = require('foo/package.json').version
-} catch (er) {
-  foo = null
-}
-if ( notGoodFooVersion(fooVersion) ) {
-  foo = null
-}
-
-// .. then later in your program ..
-
-if (foo) {
-  foo.doFooThings()
-}

Entries in optionalDependencies will override entries of the same name in -dependencies, so it's usually best to only put in one place.

-

engines

-

You can specify the version of node that your stuff works on:

-
{ "engines" : { "node" : ">=0.10.3 <0.12" } }

And, like with dependencies, if you don't specify the version (or if you -specify "*" as the version), then any version of node will do.

-

If you specify an "engines" field, then npm will require that "node" be -somewhere on that list. If "engines" is omitted, then npm will just assume -that it works on node.

-

You can also use the "engines" field to specify which versions of npm -are capable of properly installing your program. For example:

-
{ "engines" : { "npm" : "~1.0.20" } }

Unless the user has set the engine-strict config flag, this -field is advisory only and will only produce warnings when your package is installed as a dependency.

-

engineStrict

-

This feature was removed in npm 3.0.0

-

Prior to npm 3.0.0, this feature was used to treat this package as if the -user had set engine-strict. It is no longer used.

-

os

-

You can specify which operating systems your -module will run on:

-
"os" : [ "darwin", "linux" ]

You can also blacklist instead of whitelist operating systems, -just prepend the blacklisted os with a '!':

-
"os" : [ "!win32" ]

The host operating system is determined by process.platform

-

It is allowed to both blacklist, and whitelist, although there isn't any -good reason to do this.

-

cpu

-

If your code only runs on certain cpu architectures, -you can specify which ones.

-
"cpu" : [ "x64", "ia32" ]

Like the os option, you can also blacklist architectures:

-
"cpu" : [ "!arm", "!mips" ]

The host architecture is determined by process.arch

-

preferGlobal

-

DEPRECATED

-

This option used to trigger an npm warning, but it will no longer warn. It is -purely there for informational purposes. It is now recommended that you install -any binaries as local devDependencies wherever possible.

-

private

-

If you set "private": true in your package.json, then npm will refuse -to publish it.

-

This is a way to prevent accidental publication of private repositories. If -you would like to ensure that a given package is only ever published to a -specific registry (for example, an internal registry), then use the -publishConfig dictionary described below to override the registry config -param at publish-time.

-

publishConfig

-

This is a set of config values that will be used at publish-time. It's -especially handy if you want to set the tag, registry or access, so that -you can ensure that a given package is not tagged with "latest", published -to the global public registry or that a scoped module is private by default.

-

Any config values can be overridden, but only "tag", "registry" and "access" -probably matter for the purposes of publishing.

-

See npm-config(7) to see the list of config options that can be -overridden.

-

DEFAULT VALUES

-

npm will default some values based on package contents.

-
    -
  • "scripts": {"start": "node server.js"}

    -

    If there is a server.js file in the root of your package, then npm -will default the start command to node server.js.

    -
  • -
  • "scripts":{"install": "node-gyp rebuild"}

    -

    If there is a binding.gyp file in the root of your package and you have not defined an install or preinstall script, npm will -default the install command to compile using node-gyp.

    -
  • -
  • "contributors": [...]

    -

    If there is an AUTHORS file in the root of your package, npm will -treat each line as a Name <email> (url) format, where email and url -are optional. Lines which start with a # or are blank, will be -ignored.

    -
  • -
-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npm-package-locks.html b/deps/npm/html/doc/files/npm-package-locks.html deleted file mode 100644 index 221c759b60dce4..00000000000000 --- a/deps/npm/html/doc/files/npm-package-locks.html +++ /dev/null @@ -1,157 +0,0 @@ - - - npm-package-locks - - - - - - -
- -

npm-package-locks

An explanation of npm lockfiles

-

DESCRIPTION

-

Conceptually, the "input" to npm-install(1) is a package.json(5), while its -"output" is a fully-formed node_modules tree: a representation of the -dependencies you declared. In an ideal world, npm would work like a pure -function: the same package.json should produce the exact same node_modules -tree, any time. In some cases, this is indeed true. But in many others, npm is -unable to do this. There are multiple reasons for this:

-
    -
  • different versions of npm (or other package managers) may have been used to install a package, each using slightly different installation algorithms.

    -
  • -
  • a new version of a direct semver-range package may have been published since the last time your packages were installed, and thus a newer version will be used.

    -
  • -
  • A dependency of one of your dependencies may have published a new version, which will update even if you used pinned dependency specifiers (1.2.3 instead of ^1.2.3)

    -
  • -
  • The registry you installed from is no longer available, or allows mutation of versions (unlike the primary npm registry), and a different version of a package exists under the same version number now.

    -
  • -
-

As an example, consider package A:

-
{
-  "name": "A",
-  "version": "0.1.0",
-  "dependencies": {
-    "B": "<0.1.0"
-  }
-}

package B:

-
{
-  "name": "B",
-  "version": "0.0.1",
-  "dependencies": {
-    "C": "<0.1.0"
-  }
-}

and package C:

-
{
-  "name": "C",
-  "version": "0.0.1"
-}

If these are the only versions of A, B, and C available in the -registry, then a normal npm install A will install:

-
A@0.1.0
-`-- B@0.0.1
-    `-- C@0.0.1

However, if B@0.0.2 is published, then a fresh npm install A will -install:

-
A@0.1.0
-`-- B@0.0.2
-    `-- C@0.0.1

assuming the new version did not modify B's dependencies. Of course, -the new version of B could include a new version of C and any number -of new dependencies. If such changes are undesirable, the author of A -could specify a dependency on B@0.0.1. However, if A's author and B's -author are not the same person, there's no way for A's author to say -that he or she does not want to pull in newly published versions of C -when B hasn't changed at all.

-

To prevent this potential issue, npm uses package-lock.json(5) or, if present, -npm-shrinkwrap.json(5). These files are called package locks, or lockfiles.

-

Whenever you run npm install, npm generates or updates your package lock, -which will look something like this:

-
{
-  "name": "A",
-  "version": "0.1.0",
-  ...metadata fields...
-  "dependencies": {
-    "B": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/B/-/B-0.0.1.tgz",
-      "integrity": "sha512-DeAdb33F+"
-      "dependencies": {
-        "C": {
-          "version": "git://github.com/org/C.git#5c380ae319fc4efe9e7f2d9c78b0faa588fd99b4"
-        }
-      }
-    }
-  }
-}

This file describes an exact, and more importantly reproducible -node_modules tree. Once it's present, any future installation will base its -work off this file, instead of recalculating dependency versions off -package.json(5).

-

The presence of a package lock changes the installation behavior such that:

-
    -
  1. The module tree described by the package lock is reproduced. This means -reproducing the structure described in the file, using the specific files -referenced in "resolved" if available, falling back to normal package resolution -using "version" if one isn't.

    -
  2. -
  3. The tree is walked and any missing dependencies are installed in the usual -fashion.

    -
  4. -
-

If preshrinkwrap, shrinkwrap or postshrinkwrap are in the scripts -property of the package.json, they will be executed in order. preshrinkwrap -and shrinkwrap are executed before the shrinkwrap, postshrinkwrap is -executed afterwards. These scripts run for both package-lock.json and -npm-shrinkwrap.json. For example to run some postprocessing on the generated -file:

-
"scripts": {
-  "postshrinkwrap": "json -I -e \"this.myMetadata = $MY_APP_METADATA\""
-}

Using locked packages

-

Using a locked package is no different than using any package without a package -lock: any commands that update node_modules and/or package.json's -dependencies will automatically sync the existing lockfile. This includes npm -install, npm rm, npm update, etc. To prevent this update from happening, -you can use the --no-save option to prevent saving altogether, or ---no-shrinkwrap to allow package.json to be updated while leaving -package-lock.json or npm-shrinkwrap.json intact.

-

It is highly recommended you commit the generated package lock to source -control: this will allow anyone else on your team, your deployments, your -CI/continuous integration, and anyone else who runs npm install in your -package source to get the exact same dependency tree that you were developing -on. Additionally, the diffs from these changes are human-readable and will -inform you of any changes npm has made to your node_modules, so you can notice -if any transitive dependencies were updated, hoisted, etc.

-

Resolving lockfile conflicts

-

Occasionally, two separate npm install will create package locks that cause -merge conflicts in source control systems. As of npm@5.7.0, these conflicts -can be resolved by manually fixing any package.json conflicts, and then -running npm install [--package-lock-only] again. npm will automatically -resolve any conflicts for you and write a merged package lock that includes all -the dependencies from both branches in a reasonable tree. If ---package-lock-only is provided, it will do this without also modifying your -local node_modules/.

-

To make this process seamless on git, consider installing -npm-merge-driver, which will teach git how -to do this itself without any user interaction. In short: $ npx -npm-merge-driver install -g will let you do this, and even works with -pre-npm@5.7.0 versions of npm 5, albeit a bit more noisily. Note that if -package.json itself conflicts, you will have to resolve that by hand and run -npm install manually, even with the merge driver.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npm-shrinkwrap.json.html b/deps/npm/html/doc/files/npm-shrinkwrap.json.html deleted file mode 100644 index 5a1f5a271e0b41..00000000000000 --- a/deps/npm/html/doc/files/npm-shrinkwrap.json.html +++ /dev/null @@ -1,45 +0,0 @@ - - - npm-shrinkwrap.json - - - - - - -
- -

npm-shrinkwrap.json

A publishable lockfile

-

DESCRIPTION

-

npm-shrinkwrap.json is a file created by npm-shrinkwrap(1). It is identical to -package-lock.json, with one major caveat: Unlike package-lock.json, -npm-shrinkwrap.json may be included when publishing a package.

-

The recommended use-case for npm-shrinkwrap.json is applications deployed -through the publishing process on the registry: for example, daemons and -command-line tools intended as global installs or devDependencies. It's -strongly discouraged for library authors to publish this file, since that would -prevent end users from having control over transitive dependency updates.

-

Additionally, if both package-lock.json and npm-shrinkwrap.json are present -in a package root, package-lock.json will be ignored in favor of this file.

-

For full details and description of the npm-shrinkwrap.json file format, refer -to the manual page for package-lock.json(5).

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/files/npmrc.html b/deps/npm/html/doc/files/npmrc.html deleted file mode 100644 index b428127f3ec57a..00000000000000 --- a/deps/npm/html/doc/files/npmrc.html +++ /dev/null @@ -1,86 +0,0 @@ - - - npmrc - - - - - - -
- -

npmrc

The npm config files

-

DESCRIPTION

-

npm gets its config settings from the command line, environment -variables, and npmrc files.

-

The npm config command can be used to update and edit the contents -of the user and global npmrc files.

-

For a list of available configuration options, see npm-config(7).

-

FILES

-

The four relevant files are:

-
    -
  • per-project config file (/path/to/my/project/.npmrc)
  • -
  • per-user config file (~/.npmrc)
  • -
  • global config file ($PREFIX/etc/npmrc)
  • -
  • npm builtin config file (/path/to/npm/npmrc)
  • -
-

All npm config files are an ini-formatted list of key = value -parameters. Environment variables can be replaced using -${VARIABLE_NAME}. For example:

-
prefix = ${HOME}/.npm-packages

Each of these files is loaded, and config options are resolved in -priority order. For example, a setting in the userconfig file would -override the setting in the globalconfig file.

-

Array values are specified by adding "[]" after the key name. For -example:

-
key[] = "first value"
-key[] = "second value"

Comments

-

Lines in .npmrc files are interpreted as comments when they begin with a ; or # character. .npmrc files are parsed by npm/ini, which specifies this comment syntax.

-

For example:

-
# last modified: 01 Jan 2016
-; Set a new registry for a scoped package
-@myscope:registry=https://mycustomregistry.example.org

Per-project config file

-

When working locally in a project, a .npmrc file in the root of the -project (ie, a sibling of node_modules and package.json) will set -config values specific to this project.

-

Note that this only applies to the root of the project that you're -running npm in. It has no effect when your module is published. For -example, you can't publish a module that forces itself to install -globally, or in a different location.

-

Additionally, this file is not read in global mode, such as when running -npm install -g.

-

Per-user config file

-

$HOME/.npmrc (or the userconfig param, if set in the environment -or on the command line)

-

Global config file

-

$PREFIX/etc/npmrc (or the globalconfig param, if set above): -This file is an ini-file formatted list of key = value parameters. -Environment variables can be replaced as above.

-

Built-in config file

-

path/to/npm/itself/npmrc

-

This is an unchangeable "builtin" configuration file that npm keeps -consistent across updates. Set fields in here using the ./configure -script that comes with npm. This is primarily for distribution -maintainers to override default configs in a standard and consistent -manner.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/files/package-lock.json.html b/deps/npm/html/doc/files/package-lock.json.html deleted file mode 100644 index 7756498b2c8506..00000000000000 --- a/deps/npm/html/doc/files/package-lock.json.html +++ /dev/null @@ -1,133 +0,0 @@ - - - package-lock.json - - - - - - -
- -

package-lock.json

A manifestation of the manifest

-

DESCRIPTION

-

package-lock.json is automatically generated for any operations where npm -modifies either the node_modules tree, or package.json. It describes the -exact tree that was generated, such that subsequent installs are able to -generate identical trees, regardless of intermediate dependency updates.

-

This file is intended to be committed into source repositories, and serves -various purposes:

-
    -
  • Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.

    -
  • -
  • Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.

    -
  • -
  • To facilitate greater visibility of tree changes through readable source control diffs.

    -
  • -
  • And optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.

    -
  • -
-

One key detail about package-lock.json is that it cannot be published, and it -will be ignored if found in any place other than the toplevel package. It shares -a format with npm-shrinkwrap.json(5), which is essentially the same file, but -allows publication. This is not recommended unless deploying a CLI tool or -otherwise using the publication process for producing production packages.

-

If both package-lock.json and npm-shrinkwrap.json are present in the root of -a package, package-lock.json will be completely ignored.

-

FILE FORMAT

-

name

-

The name of the package this is a package-lock for. This must match what's in -package.json.

-

version

-

The version of the package this is a package-lock for. This must match what's in -package.json.

-

lockfileVersion

-

An integer version, starting at 1 with the version number of this document -whose semantics were used when generating this package-lock.json.

-

packageIntegrity

-

This is a subresource -integrity value -created from the package.json. No preprocessing of the package.json should -be done. Subresource integrity strings can be produced by modules like -ssri.

- -

Indicates that the install was done with the environment variable -NODE_PRESERVE_SYMLINKS enabled. The installer should insist that the value of -this property match that environment variable.

-

dependencies

-

A mapping of package name to dependency object. Dependency objects have the -following properties:

-

version

-

This is a specifier that uniquely identifies this package and should be -usable in fetching a new copy of it.

-
    -
  • bundled dependencies: Regardless of source, this is a version number that is purely for informational purposes.
  • -
  • registry sources: This is a version number. (eg, 1.2.3)
  • -
  • git sources: This is a git specifier with resolved committish. (eg, git+https://example.com/foo/bar#115311855adb0789a0466714ed48a1499ffea97e)
  • -
  • http tarball sources: This is the URL of the tarball. (eg, https://example.com/example-1.3.0.tgz)
  • -
  • local tarball sources: This is the file URL of the tarball. (eg file:///opt/storage/example-1.3.0.tgz)
  • -
  • local link sources: This is the file URL of the link. (eg file:libs/our-module)
  • -
-

integrity

-

This is a Standard Subresource -Integrity for this -resource.

-
    -
  • For bundled dependencies this is not included, regardless of source.
  • -
  • For registry sources, this is the integrity that the registry provided, or if one wasn't provided the SHA1 in shasum.
  • -
  • For git sources this is the specific commit hash we cloned from.
  • -
  • For remote tarball sources this is an integrity based on a SHA512 of -the file.
  • -
  • For local tarball sources: This is an integrity field based on the SHA512 of the file.
  • -
-

resolved

-
    -
  • For bundled dependencies this is not included, regardless of source.
  • -
  • For registry sources this is path of the tarball relative to the registry -URL. If the tarball URL isn't on the same server as the registry URL then -this is a complete URL.
  • -
-

bundled

-

If true, this is the bundled dependency and will be installed by the parent -module. When installing, this module will be extracted from the parent -module during the extract phase, not installed as a separate dependency.

-

dev

-

If true then this dependency is either a development dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both a development dependency of the top level and a -transitive dependency of a non-development dependency of the top level.

-

optional

-

If true then this dependency is either an optional dependency ONLY of the -top level module or a transitive dependency of one. This is false for -dependencies that are both an optional dependency of the top level and a -transitive dependency of a non-optional dependency of the top level.

-

All optional dependencies should be included even if they're uninstallable -on the current platform.

-

requires

-

This is a mapping of module name to version. This is a list of everything -this module requires, regardless of where it will be installed. The version -should match via normal matching rules a dependency either in our -dependencies or in a level higher than us.

-

dependencies

-

The dependencies of this dependency, exactly as at the top level.

-

SEE ALSO

- - -
- - - - - - - - - - - diff --git a/deps/npm/html/doc/files/package.json.html b/deps/npm/html/doc/files/package.json.html deleted file mode 100644 index be7a98ea58e76a..00000000000000 --- a/deps/npm/html/doc/files/package.json.html +++ /dev/null @@ -1,585 +0,0 @@ - - - package.json - - - - - - -
- -

package.json

Specifics of npm's package.json handling

-

DESCRIPTION

-

This document is all you need to know about what's required in your package.json -file. It must be actual JSON, not just a JavaScript object literal.

-

A lot of the behavior described in this document is affected by the config -settings described in npm-config(7).

-

name

-

If you plan to publish your package, the most important things in your -package.json are the name and version fields as they will be required. The name -and version together form an identifier that is assumed to be completely unique. -Changes to the package should come along with changes to the version. If you don't -plan to publish your package, the name and version fields are optional.

-

The name is what your thing is called.

-

Some rules:

-
    -
  • The name must be less than or equal to 214 characters. This includes the scope for -scoped packages.
  • -
  • The name can't start with a dot or an underscore.
  • -
  • New packages must not have uppercase letters in the name.
  • -
  • The name ends up being part of a URL, an argument on the command line, and a -folder name. Therefore, the name can't contain any non-URL-safe characters.
  • -
-

Some tips:

-
    -
  • Don't use the same name as a core Node module.
  • -
  • Don't put "js" or "node" in the name. It's assumed that it's js, since you're -writing a package.json file, and you can specify the engine using the "engines" -field. (See below.)
  • -
  • The name will probably be passed as an argument to require(), so it should -be something short, but also reasonably descriptive.
  • -
  • You may want to check the npm registry to see if there's something by that name -already, before you get too attached to it. https://www.npmjs.com/
  • -
-

A name can be optionally prefixed by a scope, e.g. @myorg/mypackage. See -npm-scope(7) for more detail.

-

version

-

If you plan to publish your package, the most important things in your -package.json are the name and version fields as they will be required. The name -and version together form an identifier that is assumed to be completely unique. -Changes to the package should come along with changes to the version. If you don't -plan to publish your package, the name and version fields are optional.

-

Version must be parseable by -node-semver, which is bundled -with npm as a dependency. (npm install semver to use it yourself.)

-

More on version numbers and ranges at semver(7).

-

description

-

Put a description in it. It's a string. This helps people discover your -package, as it's listed in npm search.

-

keywords

-

Put keywords in it. It's an array of strings. This helps people -discover your package as it's listed in npm search.

-

homepage

-

The url to the project homepage.

-

Example:

-
"homepage": "https://github.com/owner/project#readme"

bugs

-

The url to your project's issue tracker and / or the email address to which -issues should be reported. These are helpful for people who encounter issues -with your package.

-

It should look like this:

-
{ "url" : "https://github.com/owner/project/issues"
-, "email" : "project@hostname.com"
-}

You can specify either one or both values. If you want to provide only a url, -you can specify the value for "bugs" as a simple string instead of an object.

-

If a url is provided, it will be used by the npm bugs command.

-

license

-

You should specify a license for your package so that people know how they are -permitted to use it, and any restrictions you're placing on it.

-

If you're using a common license such as BSD-2-Clause or MIT, add a -current SPDX license identifier for the license you're using, like this:

-
{ "license" : "BSD-3-Clause" }

You can check the full list of SPDX license IDs. -Ideally you should pick one that is -OSI approved.

-

If your package is licensed under multiple common licenses, use an SPDX license -expression syntax version 2.0 string, like this:

-
{ "license" : "(ISC OR GPL-3.0)" }

If you are using a license that hasn't been assigned an SPDX identifier, or if -you are using a custom license, use a string value like this one:

-
{ "license" : "SEE LICENSE IN <filename>" }

Then include a file named <filename> at the top level of the package.

-

Some old packages used license objects or a "licenses" property containing an -array of license objects:

-
// Not valid metadata
-{ "license" :
-  { "type" : "ISC"
-  , "url" : "https://opensource.org/licenses/ISC"
-  }
-}
-
-// Not valid metadata
-{ "licenses" :
-  [
-    { "type": "MIT"
-    , "url": "https://www.opensource.org/licenses/mit-license.php"
-    }
-  , { "type": "Apache-2.0"
-    , "url": "https://opensource.org/licenses/apache2.0.php"
-    }
-  ]
-}

Those styles are now deprecated. Instead, use SPDX expressions, like this:

-
{ "license": "ISC" }
-
-{ "license": "(MIT OR Apache-2.0)" }

Finally, if you do not wish to grant others the right to use a private or -unpublished package under any terms:

-
{ "license": "UNLICENSED" }

Consider also setting "private": true to prevent accidental publication.

-

people fields: author, contributors

-

The "author" is one person. "contributors" is an array of people. A "person" -is an object with a "name" field and optionally "url" and "email", like this:

-
{ "name" : "Barney Rubble"
-, "email" : "b@rubble.com"
-, "url" : "http://barnyrubble.tumblr.com/"
-}

Or you can shorten that all into a single string, and npm will parse it for you:

-
"Barney Rubble <b@rubble.com> (http://barnyrubble.tumblr.com/)"

Both email and url are optional either way.

-

npm also sets a top-level "maintainers" field with your npm user info.

-

files

-

The optional files field is an array of file patterns that describes -the entries to be included when your package is installed as a -dependency. File patterns follow a similar syntax to .gitignore, but -reversed: including a file, directory, or glob pattern (*, **/*, and such) -will make it so that file is included in the tarball when it's packed. Omitting -the field will make it default to ["*"], which means it will include all files.

-

Some special files and directories are also included or excluded regardless of -whether they exist in the files array (see below).

-

You can also provide a .npmignore file in the root of your package or -in subdirectories, which will keep files from being included. At the -root of your package it will not override the "files" field, but in -subdirectories it will. The .npmignore file works just like a -.gitignore. If there is a .gitignore file, and .npmignore is -missing, .gitignore's contents will be used instead.

-

Files included with the "package.json#files" field cannot be excluded -through .npmignore or .gitignore.

-

Certain files are always included, regardless of settings:

-
    -
  • package.json
  • -
  • README
  • -
  • CHANGES / CHANGELOG / HISTORY
  • -
  • LICENSE / LICENCE
  • -
  • NOTICE
  • -
  • The file in the "main" field
  • -
-

README, CHANGES, LICENSE & NOTICE can have any case and extension.

-

Conversely, some files are always ignored:

-
    -
  • .git
  • -
  • CVS
  • -
  • .svn
  • -
  • .hg
  • -
  • .lock-wscript
  • -
  • .wafpickle-N
  • -
  • .*.swp
  • -
  • .DS_Store
  • -
  • ._*
  • -
  • npm-debug.log
  • -
  • .npmrc
  • -
  • node_modules
  • -
  • config.gypi
  • -
  • *.orig
  • -
  • package-lock.json (use shrinkwrap instead)
  • -
-

main

-

The main field is a module ID that is the primary entry point to your program. -That is, if your package is named foo, and a user installs it, and then does -require("foo"), then your main module's exports object will be returned.

-

This should be a module ID relative to the root of your package folder.

-

For most modules, it makes the most sense to have a main script and often not -much else.

-

browser

-

If your module is meant to be used client-side the browser field should be -used instead of the main field. This is helpful to hint users that it might -rely on primitives that aren't available in Node.js modules. (e.g. window)

-

bin

-

A lot of packages have one or more executable files that they'd like to -install into the PATH. npm makes this pretty easy (in fact, it uses this -feature to install the "npm" executable.)

-

To use this, supply a bin field in your package.json which is a map of -command name to local file name. On install, npm will symlink that file into -prefix/bin for global installs, or ./node_modules/.bin/ for local -installs.

-

For example, myapp could have this:

-
{ "bin" : { "myapp" : "./cli.js" } }

So, when you install myapp, it'll create a symlink from the cli.js script to -/usr/local/bin/myapp.

-

If you have a single executable, and its name should be the name -of the package, then you can just supply it as a string. For example:

-
{ "name": "my-program"
-, "version": "1.2.5"
-, "bin": "./path/to/program" }

would be the same as this:

-
{ "name": "my-program"
-, "version": "1.2.5"
-, "bin" : { "my-program" : "./path/to/program" } }

Please make sure that your file(s) referenced in bin starts with -#!/usr/bin/env node, otherwise the scripts are started without the node -executable!

-

man

-

Specify either a single file or an array of filenames to put in place for the -man program to find.

-

If only a single file is provided, then it's installed such that it is the -result from man <pkgname>, regardless of its actual filename. For example:

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : "./man/doc.1"
-}

would link the ./man/doc.1 file in such that it is the target for man foo

-

If the filename doesn't start with the package name, then it's prefixed. -So, this:

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : [ "./man/foo.1", "./man/bar.1" ]
-}

will create files to do man foo and man foo-bar.

-

Man files must end with a number, and optionally a .gz suffix if they are -compressed. The number dictates which man section the file is installed into.

-
{ "name" : "foo"
-, "version" : "1.2.3"
-, "description" : "A packaged foo fooer for fooing foos"
-, "main" : "foo.js"
-, "man" : [ "./man/foo.1", "./man/foo.2" ]
-}

will create entries for man foo and man 2 foo

-

directories

-

The CommonJS Packages spec details a -few ways that you can indicate the structure of your package using a directories -object. If you look at npm's package.json, -you'll see that it has directories for doc, lib, and man.

-

In the future, this information may be used in other creative ways.

-

directories.lib

-

Tell people where the bulk of your library is. Nothing special is done -with the lib folder in any way, but it's useful meta info.

-

directories.bin

-

If you specify a bin directory in directories.bin, all the files in -that folder will be added.

-

Because of the way the bin directive works, specifying both a -bin path and setting directories.bin is an error. If you want to -specify individual files, use bin, and for all the files in an -existing bin directory, use directories.bin.

-

directories.man

-

A folder that is full of man pages. Sugar to generate a "man" array by -walking the folder.

-

directories.doc

-

Put markdown files in here. Eventually, these will be displayed nicely, -maybe, someday.

-

directories.example

-

Put example scripts in here. Someday, it might be exposed in some clever way.

-

directories.test

-

Put your tests in here. It is currently not exposed, but it might be in the -future.

-

repository

-

Specify the place where your code lives. This is helpful for people who -want to contribute. If the git repo is on GitHub, then the npm docs -command will be able to find you.

-

Do it like this:

-
"repository": {
-  "type" : "git",
-  "url" : "https://github.com/npm/cli.git"
-}
-
-"repository": {
-  "type" : "svn",
-  "url" : "https://v8.googlecode.com/svn/trunk/"
-}

The URL should be a publicly available (perhaps read-only) url that can be handed -directly to a VCS program without any modification. It should not be a url to an -html project page that you put in your browser. It's for computers.

-

For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same -shortcut syntax you use for npm install:

-
"repository": "npm/npm"
-
-"repository": "github:user/repo"
-
-"repository": "gist:11081aaa281"
-
-"repository": "bitbucket:user/repo"
-
-"repository": "gitlab:user/repo"

If the package.json for your package is not in the root directory (for example -if it is part of a monorepo), you can specify the directory in which it lives:

-
"repository": {
-  "type" : "git",
-  "url" : "https://github.com/facebook/react.git",
-  "directory": "packages/react-dom"
-}

scripts

-

The "scripts" property is a dictionary containing script commands that are run -at various times in the lifecycle of your package. The key is the lifecycle -event, and the value is the command to run at that point.

-

See npm-scripts(7) to find out more about writing package scripts.

-

config

-

A "config" object can be used to set configuration parameters used in package -scripts that persist across upgrades. For instance, if a package had the -following:

-
{ "name" : "foo"
-, "config" : { "port" : "8080" } }

and then had a "start" command that then referenced the -npm_package_config_port environment variable, then the user could -override that by doing npm config set foo:port 8001.

-

See npm-config(7) and npm-scripts(7) for more on package -configs.

-

dependencies

-

Dependencies are specified in a simple object that maps a package name to a -version range. The version range is a string which has one or more -space-separated descriptors. Dependencies can also be identified with a -tarball or git URL.

-

Please do not put test harnesses or transpilers in your -dependencies object. See devDependencies, below.

-

See semver(7) for more details about specifying version ranges.

-
    -
  • version Must match version exactly
  • -
  • >version Must be greater than version
  • -
  • >=version etc
  • -
  • <version
  • -
  • <=version
  • -
  • ~version "Approximately equivalent to version" See semver(7)
  • -
  • ^version "Compatible with version" See semver(7)
  • -
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • -
  • http://... See 'URLs as Dependencies' below
  • -
  • * Matches any version
  • -
  • "" (just an empty string) Same as *
  • -
  • version1 - version2 Same as >=version1 <=version2.
  • -
  • range1 || range2 Passes if either range1 or range2 are satisfied.
  • -
  • git... See 'Git URLs as Dependencies' below
  • -
  • user/repo See 'GitHub URLs' below
  • -
  • tag A specific version tagged and published as tag See npm-dist-tag(1)
  • -
  • path/path/path See Local Paths below
  • -
-

For example, these are all valid:

-
{ "dependencies" :
-  { "foo" : "1.0.0 - 2.9999.9999"
-  , "bar" : ">=1.0.2 <2.1.2"
-  , "baz" : ">1.0.2 <=2.3.4"
-  , "boo" : "2.0.1"
-  , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"
-  , "asd" : "http://asdf.com/asdf.tar.gz"
-  , "til" : "~1.2"
-  , "elf" : "~1.2.3"
-  , "two" : "2.x"
-  , "thr" : "3.3.x"
-  , "lat" : "latest"
-  , "dyl" : "file:../dyl"
-  }
-}

URLs as Dependencies

-

You may specify a tarball URL in place of a version range.

-

This tarball will be downloaded and installed locally to your package at -install time.

-

Git URLs as Dependencies

-

Git urls are of the form:

-
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

<protocol> is one of git, git+ssh, git+http, git+https, or -git+file.

-

If #<commit-ish> is provided, it will be used to clone exactly that -commit. If the commit-ish has the format #semver:<semver>, <semver> can -be any valid semver range or exact version, and npm will look for any tags -or refs matching that range in the remote repository, much as it would for a -registry dependency. If neither #<commit-ish> or #semver:<semver> is -specified, then master is used.

-

Examples:

-
git+ssh://git@github.com:npm/cli.git#v1.0.27
-git+ssh://git@github.com:npm/cli#semver:^5.0
-git+https://isaacs@github.com/npm/cli.git
-git://github.com/npm/cli.git#v1.0.27

GitHub URLs

-

As of version 1.1.65, you can refer to GitHub urls as just "foo": -"user/foo-project". Just as with git URLs, a commit-ish suffix can be -included. For example:

-
{
-  "name": "foo",
-  "version": "0.0.0",
-  "dependencies": {
-    "express": "expressjs/express",
-    "mocha": "mochajs/mocha#4727d357ea",
-    "module": "user/repo#feature\/branch"
-  }
-}

Local Paths

-

As of version 2.0.0 you can provide a path to a local directory that contains a -package. Local paths can be saved using npm install -S or -npm install --save, using any of these forms:

-
../foo/bar
-~/foo/bar
-./foo/bar
-/foo/bar

in which case they will be normalized to a relative path and added to your -package.json. For example:

-
{
-  "name": "baz",
-  "dependencies": {
-    "bar": "file:../foo/bar"
-  }
-}

This feature is helpful for local offline development and creating -tests that require npm installing where you don't want to hit an -external server, but should not be used when publishing packages -to the public registry.

-

devDependencies

-

If someone is planning on downloading and using your module in their -program, then they probably don't want or need to download and build -the external test or documentation framework that you use.

-

In this case, it's best to map these additional items in a devDependencies -object.

-

These things will be installed when doing npm link or npm install -from the root of a package, and can be managed like any other npm -configuration param. See npm-config(7) for more on the topic.

-

For build steps that are not platform-specific, such as compiling -CoffeeScript or other languages to JavaScript, use the prepare -script to do this, and make the required package a devDependency.

-

For example:

-
{ "name": "ethopia-waza",
-  "description": "a delightfully fruity coffee varietal",
-  "version": "1.2.3",
-  "devDependencies": {
-    "coffee-script": "~1.6.3"
-  },
-  "scripts": {
-    "prepare": "coffee -o lib/ -c src/waza.coffee"
-  },
-  "main": "lib/waza.js"
-}

The prepare script will be run before publishing, so that users -can consume the functionality without requiring them to compile it -themselves. In dev mode (ie, locally running npm install), it'll -run this script as well, so that you can test it easily.

-

peerDependencies

-

In some cases, you want to express the compatibility of your package with a -host tool or library, while not necessarily doing a require of this host. -This is usually referred to as a plugin. Notably, your module may be exposing -a specific interface, expected and specified by the host documentation.

-

For example:

-
{
-  "name": "tea-latte",
-  "version": "1.3.5",
-  "peerDependencies": {
-    "tea": "2.x"
-  }
-}

This ensures your package tea-latte can be installed along with the second -major version of the host package tea only. npm install tea-latte could -possibly yield the following dependency graph:

-
├── tea-latte@1.3.5
-└── tea@2.2.0

NOTE: npm versions 1 and 2 will automatically install peerDependencies if -they are not explicitly depended upon higher in the dependency tree. In the -next major version of npm (npm@3), this will no longer be the case. You will -receive a warning that the peerDependency is not installed instead. The -behavior in npms 1 & 2 was frequently confusing and could easily put you into -dependency hell, a situation that npm is designed to avoid as much as possible.

-

Trying to install another plugin with a conflicting requirement will cause an -error. For this reason, make sure your plugin requirement is as broad as -possible, and not to lock it down to specific patch versions.

-

Assuming the host complies with semver, only changes in -the host package's major version will break your plugin. Thus, if you've worked -with every 1.x version of the host package, use "^1.0" or "1.x" to express -this. If you depend on features introduced in 1.5.2, use ">= 1.5.2 < 2".

-

bundledDependencies

-

This defines an array of package names that will be bundled when publishing -the package.

-

In cases where you need to preserve npm packages locally or have them -available through a single file download, you can bundle the packages in a -tarball file by specifying the package names in the bundledDependencies -array and executing npm pack.

-

For example:

-

If we define a package.json like this:

-
{
-  "name": "awesome-web-framework",
-  "version": "1.0.0",
-  "bundledDependencies": [
-    "renderized", "super-streams"
-  ]
-}

we can obtain awesome-web-framework-1.0.0.tgz file by running npm pack. -This file contains the dependencies renderized and super-streams which -can be installed in a new project by executing npm install -awesome-web-framework-1.0.0.tgz. Note that the package names do not include -any versions, as that information is specified in dependencies.

-

If this is spelled "bundleDependencies", then that is also honored.

-

optionalDependencies

-

If a dependency can be used, but you would like npm to proceed if it cannot be -found or fails to install, then you may put it in the optionalDependencies -object. This is a map of package name to version or url, just like the -dependencies object. The difference is that build failures do not cause -installation to fail.

-

It is still your program's responsibility to handle the lack of the -dependency. For example, something like this:

-
try {
-  var foo = require('foo')
-  var fooVersion = require('foo/package.json').version
-} catch (er) {
-  foo = null
-}
-if ( notGoodFooVersion(fooVersion) ) {
-  foo = null
-}
-
-// .. then later in your program ..
-
-if (foo) {
-  foo.doFooThings()
-}

Entries in optionalDependencies will override entries of the same name in -dependencies, so it's usually best to only put in one place.

-

engines

-

You can specify the version of node that your stuff works on:

-
{ "engines" : { "node" : ">=0.10.3 <0.12" } }

And, like with dependencies, if you don't specify the version (or if you -specify "*" as the version), then any version of node will do.

-

If you specify an "engines" field, then npm will require that "node" be -somewhere on that list. If "engines" is omitted, then npm will just assume -that it works on node.

-

You can also use the "engines" field to specify which versions of npm -are capable of properly installing your program. For example:

-
{ "engines" : { "npm" : "~1.0.20" } }

Unless the user has set the engine-strict config flag, this -field is advisory only and will only produce warnings when your package is installed as a dependency.

-

engineStrict

-

This feature was removed in npm 3.0.0

-

Prior to npm 3.0.0, this feature was used to treat this package as if the -user had set engine-strict. It is no longer used.

-

os

-

You can specify which operating systems your -module will run on:

-
"os" : [ "darwin", "linux" ]

You can also blacklist instead of whitelist operating systems, -just prepend the blacklisted os with a '!':

-
"os" : [ "!win32" ]

The host operating system is determined by process.platform

-

It is allowed to both blacklist, and whitelist, although there isn't any -good reason to do this.

-

cpu

-

If your code only runs on certain cpu architectures, -you can specify which ones.

-
"cpu" : [ "x64", "ia32" ]

Like the os option, you can also blacklist architectures:

-
"cpu" : [ "!arm", "!mips" ]

The host architecture is determined by process.arch

-

preferGlobal

-

DEPRECATED

-

This option used to trigger an npm warning, but it will no longer warn. It is -purely there for informational purposes. It is now recommended that you install -any binaries as local devDependencies wherever possible.

-

private

-

If you set "private": true in your package.json, then npm will refuse -to publish it.

-

This is a way to prevent accidental publication of private repositories. If -you would like to ensure that a given package is only ever published to a -specific registry (for example, an internal registry), then use the -publishConfig dictionary described below to override the registry config -param at publish-time.

-

publishConfig

-

This is a set of config values that will be used at publish-time. It's -especially handy if you want to set the tag, registry or access, so that -you can ensure that a given package is not tagged with "latest", published -to the global public registry or that a scoped module is private by default.

-

Any config values can be overridden, but only "tag", "registry" and "access" -probably matter for the purposes of publishing.

-

See npm-config(7) to see the list of config options that can be -overridden.

-

DEFAULT VALUES

-

npm will default some values based on package contents.

-
    -
  • "scripts": {"start": "node server.js"}

    -

    If there is a server.js file in the root of your package, then npm -will default the start command to node server.js.

    -
  • -
  • "scripts":{"install": "node-gyp rebuild"}

    -

    If there is a binding.gyp file in the root of your package and you have not defined an install or preinstall script, npm will -default the install command to compile using node-gyp.

    -
  • -
  • "contributors": [...]

    -

    If there is an AUTHORS file in the root of your package, npm will -treat each line as a Name <email> (url) format, where email and url -are optional. Lines which start with a # or are blank, will be -ignored.

    -
  • -
-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/index.html b/deps/npm/html/doc/index.html deleted file mode 100644 index 39cc94c700cd85..00000000000000 --- a/deps/npm/html/doc/index.html +++ /dev/null @@ -1,186 +0,0 @@ - - - npm-index - - - - - - -
- -

npm-index

Index of all npm documentation

-

README

-

a JavaScript package manager

-

Command Line Documentation

-

Using npm on the command line

-

npm(1)

-

javascript package manager

-

npm-access(1)

-

Set access level on published packages

-

npm-adduser(1)

-

Add a registry user account

-

npm-audit(1)

-

Run a security audit

-

npm-bin(1)

-

Display npm bin folder

-

npm-bugs(1)

-

Bugs for a package in a web browser maybe

-

npm-build(1)

-

Build a package

-

npm-bundle(1)

-

REMOVED

-

npm-cache(1)

-

Manipulates packages cache

-

npm-ci(1)

-

Install a project with a clean slate

-

npm-completion(1)

-

Tab Completion for npm

-

npm-config(1)

-

Manage the npm configuration files

-

npm-dedupe(1)

-

Reduce duplication

-

npm-deprecate(1)

-

Deprecate a version of a package

-

npm-dist-tag(1)

-

Modify package distribution tags

-

npm-docs(1)

-

Docs for a package in a web browser maybe

-

npm-doctor(1)

-

Check your environments

-

npm-edit(1)

-

Edit an installed package

-

npm-explore(1)

-

Browse an installed package

-

npm-help-search(1)

-

Search npm help documentation

-

npm-help(1)

-

Get help on npm

-

npm-hook(1)

-

Manage registry hooks

-

npm-init(1)

-

create a package.json file

-

npm-install-ci-test(1)

-

Install a project with a clean slate and run tests

-

npm-install-test(1)

-

Install package(s) and run tests

-

npm-install(1)

-

Install a package

-

npm-link(1)

-

Symlink a package folder

-

npm-logout(1)

-

Log out of the registry

-

npm-ls(1)

-

List installed packages

-

npm-org(1)

-

Manage orgs

-

npm-outdated(1)

-

Check for outdated packages

-

npm-owner(1)

-

Manage package owners

-

npm-pack(1)

-

Create a tarball from a package

-

npm-ping(1)

-

Ping npm registry

-

npm-prefix(1)

-

Display prefix

-

npm-profile(1)

-

Change settings on your registry profile

-

npm-prune(1)

-

Remove extraneous packages

-

npm-publish(1)

-

Publish a package

-

npm-rebuild(1)

-

Rebuild a package

-

npm-repo(1)

-

Open package repository page in the browser

-

npm-restart(1)

-

Restart a package

-

npm-root(1)

-

Display npm root

-

npm-run-script(1)

-

Run arbitrary package scripts

-

npm-search(1)

-

Search for packages

-

npm-shrinkwrap(1)

-

Lock down dependency versions for publication

-

npm-star(1)

-

Mark your favorite packages

-

npm-stars(1)

-

View packages marked as favorites

-

npm-start(1)

-

Start a package

-

npm-stop(1)

-

Stop a package

-

npm-team(1)

-

Manage organization teams and team memberships

-

npm-test(1)

-

Test a package

-

npm-token(1)

-

Manage your authentication tokens

-

npm-uninstall(1)

-

Remove a package

-

npm-unpublish(1)

-

Remove a package from the registry

-

npm-update(1)

-

Update a package

-

npm-version(1)

-

Bump a package version

-

npm-view(1)

-

View registry info

-

npm-whoami(1)

-

Display npm username

-

API Documentation

-

Using npm in your Node programs

-

Files

-

File system structures npm uses

-

npm-folders(5)

-

Folder Structures Used by npm

-

npm-package-locks(5)

-

An explanation of npm lockfiles

-

npm-shrinkwrap.json(5)

-

A publishable lockfile

-

npmrc(5)

-

The npm config files

-

package-lock.json(5)

-

A manifestation of the manifest

-

package.json(5)

-

Specifics of npm's package.json handling

-

Misc

-

Various other bits and bobs

-

npm-coding-style(7)

-

npm's "funny" coding style

-

npm-config(7)

-

More than you probably want to know about npm configuration

-

npm-developers(7)

-

Developer Guide

-

npm-disputes(7)

-

Handling Module Name Disputes

-

npm-index(7)

-

Index of all npm documentation

-

npm-orgs(7)

-

Working with Teams & Orgs

-

npm-registry(7)

-

The JavaScript Package Registry

-

npm-scope(7)

-

Scoped packages

-

npm-scripts(7)

-

How npm handles the "scripts" field

-

removing-npm(7)

-

Cleaning the Slate

-

semver(7)

-

The semantic versioner for npm

- -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-coding-style.html b/deps/npm/html/doc/misc/npm-coding-style.html deleted file mode 100644 index c23d44552928f8..00000000000000 --- a/deps/npm/html/doc/misc/npm-coding-style.html +++ /dev/null @@ -1,149 +0,0 @@ - - - npm-coding-style - - - - - - -
- -

npm-coding-style

npm's "funny" coding style

-

DESCRIPTION

-

npm's coding style is a bit unconventional. It is not different for -difference's sake, but rather a carefully crafted style that is -designed to reduce visual clutter and make bugs more apparent.

-

If you want to contribute to npm (which is very encouraged), you should -make your code conform to npm's style.

-

Note: this concerns npm's code not the specific packages that you can download from the npm registry.

-

Line Length

-

Keep lines shorter than 80 characters. It's better for lines to be -too short than to be too long. Break up long lists, objects, and other -statements onto multiple lines.

-

Indentation

-

Two-spaces. Tabs are better, but they look like hell in web browsers -(and on GitHub), and node uses 2 spaces, so that's that.

-

Configure your editor appropriately.

-

Curly braces

-

Curly braces belong on the same line as the thing that necessitates them.

-

Bad:

-
function ()
-{

Good:

-
function () {

If a block needs to wrap to the next line, use a curly brace. Don't -use it if it doesn't.

-

Bad:

-
if (foo) { bar() }
-while (foo)
-  bar()

Good:

-
if (foo) bar()
-while (foo) {
-  bar()
-}

Semicolons

-

Don't use them except in four situations:

-
    -
  • for (;;) loops. They're actually required.
  • -
  • null loops like: while (something) ; (But you'd better have a good -reason for doing that.)
  • -
  • case 'foo': doSomething(); break
  • -
  • In front of a leading ( or [ at the start of the line. -This prevents the expression from being interpreted -as a function call or property access, respectively.
  • -
-

Some examples of good semicolon usage:

-
;(x || y).doSomething()
-;[a, b, c].forEach(doSomething)
-for (var i = 0; i < 10; i ++) {
-  switch (state) {
-    case 'begin': start(); continue
-    case 'end': finish(); break
-    default: throw new Error('unknown state')
-  }
-  end()
-}

Note that starting lines with - and + also should be prefixed -with a semicolon, but this is much less common.

-

Comma First

-

If there is a list of things separated by commas, and it wraps -across multiple lines, put the comma at the start of the next -line, directly below the token that starts the list. Put the -final token in the list on a line by itself. For example:

-
var magicWords = [ 'abracadabra'
-                 , 'gesundheit'
-                 , 'ventrilo'
-                 ]
-  , spells = { 'fireball' : function () { setOnFire() }
-             , 'water' : function () { putOut() }
-             }
-  , a = 1
-  , b = 'abc'
-  , etc
-  , somethingElse

Quotes

-

Use single quotes for strings except to avoid escaping.

-

Bad:

-
var notOk = "Just double quotes"

Good:

-
var ok = 'String contains "double" quotes'
-var alsoOk = "String contains 'single' quotes or apostrophe"

Whitespace

-

Put a single space in front of ( for anything other than a function call. -Also use a single space wherever it makes things more readable.

-

Don't leave trailing whitespace at the end of lines. Don't indent empty -lines. Don't use more spaces than are helpful.

-

Functions

-

Use named functions. They make stack traces a lot easier to read.

-

Callbacks, Sync/async Style

-

Use the asynchronous/non-blocking versions of things as much as possible. -It might make more sense for npm to use the synchronous fs APIs, but this -way, the fs and http and child process stuff all uses the same callback-passing -methodology.

-

The callback should always be the last argument in the list. Its first -argument is the Error or null.

-

Be very careful never to ever ever throw anything. It's worse than useless. -Just send the error message back as the first argument to the callback.

-

Errors

-

Always create a new Error object with your message. Don't just return a -string message to the callback. Stack traces are handy.

-

Logging

-

Logging is done using the npmlog -utility.

-

Please clean up logs when they are no longer helpful. In particular, -logging the same object over and over again is not helpful. Logs should -report what's happening so that it's easier to track down where a fault -occurs.

-

Use appropriate log levels. See npm-config(7) and search for -"loglevel".

-

Case, naming, etc.

-

Use lowerCamelCase for multiword identifiers when they refer to objects, -functions, methods, properties, or anything not specified in this section.

-

Use UpperCamelCase for class names (things that you'd pass to "new").

-

Use all-lower-hyphen-css-case for multiword filenames and config keys.

-

Use named functions. They make stack traces easier to follow.

-

Use CAPS_SNAKE_CASE for constants, things that should never change -and are rarely used.

-

Use a single uppercase letter for function names where the function -would normally be anonymous, but needs to call itself recursively. It -makes it clear that it's a "throwaway" function.

-

null, undefined, false, 0

-

Boolean variables and functions should always be either true or -false. Don't set it to 0 unless it's supposed to be a number.

-

When something is intentionally missing or removed, set it to null.

-

Don't set things to undefined. Reserve that value to mean "not yet -set to anything."

-

Boolean objects are forbidden.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-config.html b/deps/npm/html/doc/misc/npm-config.html deleted file mode 100644 index 1be6e95422587b..00000000000000 --- a/deps/npm/html/doc/misc/npm-config.html +++ /dev/null @@ -1,1088 +0,0 @@ - - - npm-config - - - - - - -
- -

npm-config

More than you probably want to know about npm configuration

-

DESCRIPTION

-

npm gets its configuration values from the following sources, sorted by priority:

-

Command Line Flags

-

Putting --foo bar on the command line sets the foo configuration -parameter to "bar". A -- argument tells the cli parser to stop -reading flags. Using --flag without specifying any value will set -the value to true.

-

Example: --flag1 --flag2 will set both configuration parameters -to true, while --flag1 --flag2 bar will set flag1 to true, -and flag2 to bar. Finally, --flag1 --flag2 -- bar will set -both configuration parameters to true, and the bar is taken -as a command argument.

-

Environment Variables

-

Any environment variables that start with npm_config_ will be -interpreted as a configuration parameter. For example, putting -npm_config_foo=bar in your environment will set the foo -configuration parameter to bar. Any environment configurations that -are not given a value will be given the value of true. Config -values are case-insensitive, so NPM_CONFIG_FOO=bar will work the -same. However, please note that inside npm-scripts -npm will set its own environment variables and Node will prefer -those lowercase versions over any uppercase ones that you might set. -For details see this issue.

-

Notice that you need to use underscores instead of dashes, so --allow-same-version -would become npm_config_allow_same_version=true.

-

npmrc Files

-

The four relevant files are:

-
    -
  • per-project configuration file (/path/to/my/project/.npmrc)
  • -
  • per-user configuration file (defaults to $HOME/.npmrc; configurable via CLI -option --userconfig or environment variable $NPM_CONFIG_USERCONFIG)
  • -
  • global configuration file (defaults to $PREFIX/etc/npmrc; configurable via -CLI option --globalconfig or environment variable $NPM_CONFIG_GLOBALCONFIG)
  • -
  • npm's built-in configuration file (/path/to/npm/npmrc)
  • -
-

See npmrc(5) for more details.

-

Default Configs

-

Run npm config ls -l to see a set of configuration parameters that are -internal to npm, and are defaults if nothing else is specified.

-

Shorthands and Other CLI Niceties

-

The following shorthands are parsed on the command-line:

-
    -
  • -v: --version
  • -
  • -h, -?, --help, -H: --usage
  • -
  • -s, --silent: --loglevel silent
  • -
  • -q, --quiet: --loglevel warn
  • -
  • -d: --loglevel info
  • -
  • -dd, --verbose: --loglevel verbose
  • -
  • -ddd: --loglevel silly
  • -
  • -g: --global
  • -
  • -C: --prefix
  • -
  • -l: --long
  • -
  • -m: --message
  • -
  • -p, --porcelain: --parseable
  • -
  • -reg: --registry
  • -
  • -f: --force
  • -
  • -desc: --description
  • -
  • -S: --save
  • -
  • -P: --save-prod
  • -
  • -D: --save-dev
  • -
  • -O: --save-optional
  • -
  • -B: --save-bundle
  • -
  • -E: --save-exact
  • -
  • -y: --yes
  • -
  • -n: --yes false
  • -
  • ll and la commands: ls --long
  • -
-

If the specified configuration param resolves unambiguously to a known -configuration parameter, then it is expanded to that configuration -parameter. For example:

-
npm ls --par
-# same as:
-npm ls --parseable

If multiple single-character shorthands are strung together, and the -resulting combination is unambiguously not some other configuration -param, then it is expanded to its various component pieces. For -example:

-
npm ls -gpld
-# same as:
-npm ls --global --parseable --long --loglevel info

Per-Package Config Settings

-

When running scripts (see npm-scripts(7)) the package.json "config" -keys are overwritten in the environment if there is a config param of -<name>[@<version>]:<key>. For example, if the package.json has -this:

-
{ "name" : "foo"
-, "config" : { "port" : "8080" }
-, "scripts" : { "start" : "node server.js" } }

and the server.js is this:

-
http.createServer(...).listen(process.env.npm_package_config_port)

then the user could change the behavior by doing:

-
npm config set foo:port 80

See package.json(5) for more information.

-

Config Settings

-

access

-
    -
  • Default: restricted
  • -
  • Type: Access
  • -
-

When publishing scoped packages, the access level defaults to restricted. If -you want your scoped package to be publicly viewable (and installable) set ---access=public. The only valid values for access are public and -restricted. Unscoped packages always have an access level of public.

-

allow-same-version

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Prevents throwing an error when npm version is used to set the new version -to the same value as the current version.

-

always-auth

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Force npm to always require authentication when accessing the registry, -even for GET requests.

-

also

-
    -
  • Default: null
  • -
  • Type: String
  • -
-

When "dev" or "development" and running local npm shrinkwrap, -npm outdated, or npm update, is an alias for --dev.

-

audit

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

When "true" submit audit reports alongside npm install runs to the default -registry and all registries configured for scopes. See the documentation -for npm-audit(1) for details on what is submitted.

-

audit-level

-
    -
  • Default: "low"
  • -
  • Type: 'low', 'moderate', 'high', 'critical'
  • -
-

The minimum level of vulnerability for npm audit to exit with -a non-zero exit code.

-

auth-type

-
    -
  • Default: 'legacy'
  • -
  • Type: 'legacy', 'sso', 'saml', 'oauth'
  • -
-

What authentication strategy to use with adduser/login.

-

before

-
    -
  • Alias: enjoy-by
  • -
  • Default: null
  • -
  • Type: Date
  • -
-

If passed to npm install, will rebuild the npm tree such that only versions -that were available on or before the --before time get installed. -If there's no versions available for the current set of direct dependencies, the -command will error.

-

If the requested version is a dist-tag and the given tag does not pass the ---before filter, the most recent version less than or equal to that tag will -be used. For example, foo@latest might install foo@1.2 even though latest -is 2.0.

- -
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Tells npm to create symlinks (or .cmd shims on Windows) for package -executables.

-

Set to false to have it not do this. This can be used to work around -the fact that some file systems don't support symlinks, even on -ostensibly Unix systems.

-

browser

-
    -
  • Default: OS X: "open", Windows: "start", Others: "xdg-open"
  • -
  • Type: String
  • -
-

The browser that is called by the npm docs command to open websites.

-

ca

-
    -
  • Default: The npm CA certificate
  • -
  • Type: String, Array or null
  • -
-

The Certificate Authority signing certificate that is trusted for SSL -connections to the registry. Values should be in PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with newlines -replaced by the string "\n". For example:

-
ca="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----"

Set to null to only allow "known" registrars, or to a specific CA cert -to trust only that specific signing authority.

-

Multiple CAs can be trusted by specifying an array of certificates:

-
ca[]="..."
-ca[]="..."

See also the strict-ssl config.

-

cafile

-
    -
  • Default: null
  • -
  • Type: path
  • -
-

A path to a file containing one or multiple Certificate Authority signing -certificates. Similar to the ca setting, but allows for multiple CA's, as -well as for the CA information to be stored in a file on disk.

-

cache

-
    -
  • Default: Windows: %AppData%\npm-cache, Posix: ~/.npm
  • -
  • Type: path
  • -
-

The location of npm's cache directory. See npm-cache(1)

-

cache-lock-stale

-
    -
  • Default: 60000 (1 minute)
  • -
  • Type: Number
  • -
-

The number of ms before cache folder lockfiles are considered stale.

-

cache-lock-retries

-
    -
  • Default: 10
  • -
  • Type: Number
  • -
-

Number of times to retry to acquire a lock on cache folder lockfiles.

-

cache-lock-wait

-
    -
  • Default: 10000 (10 seconds)
  • -
  • Type: Number
  • -
-

Number of ms to wait for cache lock files to expire.

-

cache-max

-
    -
  • Default: Infinity
  • -
  • Type: Number
  • -
-

DEPRECATED: This option has been deprecated in favor of --prefer-online.

-

--cache-max=0 is an alias for --prefer-online.

-

cache-min

-
    -
  • Default: 10
  • -
  • Type: Number
  • -
-

DEPRECATED: This option has been deprecated in favor of --prefer-offline.

-

--cache-min=9999 (or bigger) is an alias for --prefer-offline.

-

cert

-
    -
  • Default: null
  • -
  • Type: String
  • -
-

A client certificate to pass when accessing the registry. Values should be in -PEM format (Windows calls it "Base-64 encoded X.509 (.CER)") with newlines replaced by the string "\n". For example:

-
cert="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----"

It is not the path to a certificate file (and there is no "certfile" option).

-

cidr

-
    -
  • Default: null
  • -
  • Type: String, Array, null
  • -
-

This is a list of CIDR address to be used when configuring limited access tokens with the npm token create command.

-

color

-
    -
  • Default: true
  • -
  • Type: Boolean or "always"
  • -
-

If false, never shows colors. If "always" then always shows colors. -If true, then only prints color codes for tty file descriptors.

-

This option can also be changed using the environment: colors are -disabled when the environment variable NO_COLOR is set to any value.

-

depth

-
    -
  • Default: Infinity
  • -
  • Type: Number
  • -
-

The depth to go when recursing directories for npm ls, -npm cache ls, and npm outdated.

-

For npm outdated, a setting of Infinity will be treated as 0 -since that gives more useful information. To show the outdated status -of all packages and dependents, use a large integer value, -e.g., npm outdated --depth 9999

-

description

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Show the description in npm search

-

dev

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Install dev-dependencies along with packages.

-

dry-run

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Indicates that you don't want npm to make any changes and that it should -only report what it would have done. This can be passed into any of the -commands that modify your local installation, eg, install, update, -dedupe, uninstall. This is NOT currently honored by some network related -commands, eg dist-tags, owner, etc.

-

editor

-
    -
  • Default: EDITOR environment variable if set, or "vi" on Posix, -or "notepad" on Windows.
  • -
  • Type: path
  • -
-

The command to run for npm edit or npm config edit.

-

engine-strict

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If set to true, then npm will stubbornly refuse to install (or even -consider installing) any package that claims to not be compatible with -the current Node.js version.

-

force

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Makes various commands more forceful.

-
    -
  • lifecycle script failure does not block progress.
  • -
  • publishing clobbers previously published versions.
  • -
  • skips cache when requesting from the registry.
  • -
  • prevents checks against clobbering non-npm files.
  • -
-

format-package-lock

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Format package-lock.json or npm-shrinkwrap.json as a human readable file.

-

fetch-retries

-
    -
  • Default: 2
  • -
  • Type: Number
  • -
-

The "retries" config for the retry module to use when fetching -packages from the registry.

-

fetch-retry-factor

-
    -
  • Default: 10
  • -
  • Type: Number
  • -
-

The "factor" config for the retry module to use when fetching -packages.

-

fetch-retry-mintimeout

-
    -
  • Default: 10000 (10 seconds)
  • -
  • Type: Number
  • -
-

The "minTimeout" config for the retry module to use when fetching -packages.

-

fetch-retry-maxtimeout

-
    -
  • Default: 60000 (1 minute)
  • -
  • Type: Number
  • -
-

The "maxTimeout" config for the retry module to use when fetching -packages.

-

git

-
    -
  • Default: "git"
  • -
  • Type: String
  • -
-

The command to use for git commands. If git is installed on the -computer, but is not in the PATH, then set this to the full path to -the git binary.

-

git-tag-version

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Tag the commit when using the npm version command.

-

commit-hooks

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Run git commit hooks when using the npm version command.

-

global

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Operates in "global" mode, so that packages are installed into the -prefix folder instead of the current working directory. See -npm-folders(5) for more on the differences in behavior.

-
    -
  • packages are installed into the {prefix}/lib/node_modules folder, instead of the -current working directory.
  • -
  • bin files are linked to {prefix}/bin
  • -
  • man pages are linked to {prefix}/share/man
  • -
-

globalconfig

-
    -
  • Default: {prefix}/etc/npmrc
  • -
  • Type: path
  • -
-

The config file to read for global config options.

-

global-style

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Causes npm to install the package into your local node_modules folder with -the same layout it uses with the global node_modules folder. Only your -direct dependencies will show in node_modules and everything they depend -on will be flattened in their node_modules folders. This obviously will -eliminate some deduping. If used with legacy-bundling, legacy-bundling will be -preferred.

-

group

-
    -
  • Default: GID of the current process
  • -
  • Type: String or Number
  • -
-

The group to use when running package scripts in global mode as the root -user.

-

heading

-
    -
  • Default: "npm"
  • -
  • Type: String
  • -
-

The string that starts all the debugging log output.

-

https-proxy

-
    -
  • Default: null
  • -
  • Type: url
  • -
-

A proxy to use for outgoing https requests. If the HTTPS_PROXY or -https_proxy or HTTP_PROXY or http_proxy environment variables are set, -proxy settings will be honored by the underlying request library.

-

if-present

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, npm will not exit with an error code when run-script is invoked for -a script that isn't defined in the scripts section of package.json. This -option can be used when it's desirable to optionally run a script when it's -present and fail if the script fails. This is useful, for example, when running -scripts that may only apply for some builds in an otherwise generic CI setup.

-

ignore-prepublish

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, npm will not run prepublish scripts.

-

ignore-scripts

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, npm does not run scripts specified in package.json files.

-

init-module

-
    -
  • Default: ~/.npm-init.js
  • -
  • Type: path
  • -
-

A module that will be loaded by the npm init command. See the -documentation for the -init-package-json module -for more information, or npm-init(1).

-

init-author-name

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

The value npm init should use by default for the package author's name.

-

init-author-email

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

The value npm init should use by default for the package author's email.

-

init-author-url

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

The value npm init should use by default for the package author's homepage.

-

init-license

-
    -
  • Default: "ISC"
  • -
  • Type: String
  • -
-

The value npm init should use by default for the package license.

-

init-version

-
    -
  • Default: "1.0.0"
  • -
  • Type: semver
  • -
-

The value that npm init should use by default for the package -version number, if not already set in package.json.

-

json

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Whether or not to output JSON data, rather than the normal output.

-

This feature is currently experimental, and the output data structures for many -commands is either not implemented in JSON yet, or subject to change. Only the -output from npm ls --json and npm search --json are currently valid.

-

key

-
    -
  • Default: null
  • -
  • Type: String
  • -
-

A client key to pass when accessing the registry. Values should be in PEM -format with newlines replaced by the string "\n". For example:

-
key="-----BEGIN PRIVATE KEY-----\nXXXX\nXXXX\n-----END PRIVATE KEY-----"

It is not the path to a key file (and there is no "keyfile" option).

-

legacy-bundling

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Causes npm to install the package such that versions of npm prior to 1.4, -such as the one included with node 0.8, can install the package. This -eliminates all automatic deduping. If used with global-style this option -will be preferred.

- -
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, then local installs will link if there is a suitable globally -installed package.

-

Note that this means that local installs can cause things to be -installed into the global space at the same time. The link is only done -if one of the two conditions are met:

-
    -
  • The package is not already installed globally, or
  • -
  • the globally installed version is identical to the version that is -being installed locally.
  • -
-

local-address

-
    -
  • Default: undefined
  • -
  • Type: IP Address
  • -
-

The IP address of the local interface to use when making connections -to the npm registry. Must be IPv4 in versions of Node prior to 0.12.

-

loglevel

-
    -
  • Default: "notice"
  • -
  • Type: String
  • -
  • Values: "silent", "error", "warn", "notice", "http", "timing", "info", -"verbose", "silly"
  • -
-

What level of logs to report. On failure, all logs are written to -npm-debug.log in the current working directory.

-

Any logs of a higher level than the setting are shown. The default is "notice".

-

logstream

-
    -
  • Default: process.stderr
  • -
  • Type: Stream
  • -
-

This is the stream that is passed to the -npmlog module at run time.

-

It cannot be set from the command line, but if you are using npm -programmatically, you may wish to send logs to somewhere other than -stderr.

-

If the color config is set to true, then this stream will receive -colored output if it is a TTY.

-

logs-max

-
    -
  • Default: 10
  • -
  • Type: Number
  • -
-

The maximum number of log files to store.

-

long

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Show extended information in npm ls and npm search.

-

maxsockets

-
    -
  • Default: 50
  • -
  • Type: Number
  • -
-

The maximum number of connections to use per origin (protocol/host/port -combination). Passed to the http Agent used to make the request.

-

message

-
    -
  • Default: "%s"
  • -
  • Type: String
  • -
-

Commit message which is used by npm version when creating version commit.

-

Any "%s" in the message will be replaced with the version number.

-

metrics-registry

- -

The registry you want to send cli metrics to if send-metrics is true.

-

node-options

-
    -
  • Default: null
  • -
  • Type: String
  • -
-

Options to pass through to Node.js via the NODE_OPTIONS environment -variable. This does not impact how npm itself is executed but it does -impact how lifecycle scripts are called.

-

node-version

-
    -
  • Default: process.version
  • -
  • Type: semver or false
  • -
-

The node version to use when checking a package's engines map.

-

noproxy

-
    -
  • Default: null
  • -
  • Type: String or Array
  • -
-

A comma-separated string or an array of domain extensions that a proxy should not be used for.

-

offline

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Force offline mode: no network requests will be done during install. To allow -the CLI to fill in missing cache data, see --prefer-offline.

-

onload-script

-
    -
  • Default: false
  • -
  • Type: path
  • -
-

A node module to require() when npm loads. Useful for programmatic -usage.

-

only

-
    -
  • Default: null
  • -
  • Type: String
  • -
-

When "dev" or "development" and running local npm install without any -arguments, only devDependencies (and their dependencies) are installed.

-

When "dev" or "development" and running local npm ls, npm outdated, or -npm update, is an alias for --dev.

-

When "prod" or "production" and running local npm install without any -arguments, only non-devDependencies (and their dependencies) are -installed.

-

When "prod" or "production" and running local npm ls, npm outdated, or -npm update, is an alias for --production.

-

optional

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Attempt to install packages in the optionalDependencies object. Note -that if these packages fail to install, the overall installation -process is not aborted.

-

otp

-
    -
  • Default: null
  • -
  • Type: Number
  • -
-

This is a one-time password from a two-factor authenticator. It's needed -when publishing or changing package permissions with npm access.

-

package-lock

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

If set to false, then ignore package-lock.json files when installing. This -will also prevent writing package-lock.json if save is true.

-

When package package-locks are disabled, automatic pruning of extraneous -modules will also be disabled. To remove extraneous modules with -package-locks disabled use npm prune.

-

This option is an alias for --shrinkwrap.

-

package-lock-only

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If set to true, it will update only the package-lock.json, -instead of checking node_modules and downloading dependencies.

-

parseable

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Output parseable results from commands that write to -standard output. For npm search, this will be tab-separated table format.

-

prefer-offline

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, staleness checks for cached data will be bypassed, but missing data -will be requested from the server. To force full offline mode, use --offline.

-

This option is effectively equivalent to --cache-min=9999999.

-

prefer-online

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, staleness checks for cached data will be forced, making the CLI look -for updates immediately even for fresh package data.

-

prefix

- -

The location to install global items. If set on the command line, then -it forces non-global commands to run in the specified folder.

-

preid

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

The "prerelease identifier" to use as a prefix for the "prerelease" part of a -semver. Like the rc in 1.2.0-rc.8.

-

production

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Set to true to run in "production" mode.

-
    -
  1. devDependencies are not installed at the topmost level when running -local npm install without any arguments.
  2. -
  3. Set the NODE_ENV="production" for lifecycle scripts.
  4. -
-

progress

-
    -
  • Default: true, unless TRAVIS or CI env vars set.
  • -
  • Type: Boolean
  • -
-

When set to true, npm will display a progress bar during time intensive -operations, if process.stderr is a TTY.

-

Set to false to suppress the progress bar.

-

proxy

-
    -
  • Default: null
  • -
  • Type: url
  • -
-

A proxy to use for outgoing http requests. If the HTTP_PROXY or -http_proxy environment variables are set, proxy settings will be -honored by the underlying request library.

-

read-only

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

This is used to mark a token as unable to publish when configuring limited access tokens with the npm token create command.

-

rebuild-bundle

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Rebuild bundled dependencies after installation.

-

registry

- -

The base URL of the npm package registry.

-

rollback

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Remove failed installs.

-

save

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Save installed packages to a package.json file as dependencies.

-

When used with the npm rm command, it removes it from the dependencies -object.

-

Only works if there is already a package.json file present.

-

save-bundle

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If a package would be saved at install time by the use of --save, ---save-dev, or --save-optional, then also put it in the -bundleDependencies list.

-

When used with the npm rm command, it removes it from the -bundledDependencies list.

-

save-prod

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Makes sure that a package will be saved into dependencies specifically. This -is useful if a package already exists in devDependencies or -optionalDependencies, but you want to move it to be a production dep. This is -also the default behavior if --save is true, and neither --save-dev or ---save-optional are true.

-

save-dev

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Save installed packages to a package.json file as devDependencies.

-

When used with the npm rm command, it removes it from the -devDependencies object.

-

Only works if there is already a package.json file present.

-

save-exact

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Dependencies saved to package.json using --save, --save-dev or ---save-optional will be configured with an exact version rather than -using npm's default semver range operator.

-

save-optional

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Save installed packages to a package.json file as -optionalDependencies.

-

When used with the npm rm command, it removes it from the -devDependencies object.

-

Only works if there is already a package.json file present.

-

save-prefix

-
    -
  • Default: '^'
  • -
  • Type: String
  • -
-

Configure how versions of packages installed to a package.json file via ---save or --save-dev get prefixed.

-

For example if a package has version 1.2.3, by default its version is -set to ^1.2.3 which allows minor upgrades for that package, but after -npm config set save-prefix='~' it would be set to ~1.2.3 which only allows -patch upgrades.

-

scope

-
    -
  • Default: the scope of the current project, if any, or ""
  • -
  • Type: String
  • -
-

Associate an operation with a scope for a scoped registry. Useful when logging -in to a private registry for the first time: -npm login --scope=@organization --registry=registry.organization.com, which -will cause @organization to be mapped to the registry for future installation -of packages specified according to the pattern @organization/package.

-

script-shell

-
    -
  • Default: null
  • -
  • Type: path
  • -
-

The shell to use for scripts run with the npm run command.

-

scripts-prepend-node-path

-
    -
  • Default: "warn-only"
  • -
  • Type: Boolean, "auto" or "warn-only"
  • -
-

If set to true, add the directory in which the current node executable -resides to the PATH environment variable when running scripts, -even if that means that npm will invoke a different node executable than -the one which it is running.

-

If set to false, never modify PATH with that.

-

If set to "warn-only", never modify PATH but print a warning if npm thinks -that you may want to run it with true, e.g. because the node executable -in the PATH is not the one npm was invoked with.

-

If set to auto, only add that directory to the PATH environment variable -if the node executable with which npm was invoked and the one that is found -first on the PATH are different.

-

searchexclude

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

Space-separated options that limit the results from search.

-

searchopts

-
    -
  • Default: ""
  • -
  • Type: String
  • -
-

Space-separated options that are always passed to search.

-

searchlimit

-
    -
  • Default: 20
  • -
  • Type: Number
  • -
-

Number of items to limit search results to. Will not apply at all to legacy -searches.

-

searchstaleness

-
    -
  • Default: 900 (15 minutes)
  • -
  • Type: Number
  • -
-

The age of the cache, in seconds, before another registry request is made if -using legacy search endpoint.

-

send-metrics

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, success/failure metrics will be reported to the registry stored in -metrics-registry. These requests contain the number of successful and -failing runs of the npm CLI and the time period overwhich those counts were -gathered. No identifying information is included in these requests.

-

shell

-
    -
  • Default: SHELL environment variable, or "bash" on Posix, or "cmd" on -Windows
  • -
  • Type: path
  • -
-

The shell to run for the npm explore command.

-

shrinkwrap

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

If set to false, then ignore npm-shrinkwrap.json files when installing. This -will also prevent writing npm-shrinkwrap.json if save is true.

-

This option is an alias for --package-lock.

-

sign-git-commit

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If set to true, then the npm version command will commit the new package -version using -S to add a signature.

-

Note that git requires you to have set up GPG keys in your git configs -for this to work properly.

-

sign-git-tag

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If set to true, then the npm version command will tag the version -using -s to add a signature.

-

Note that git requires you to have set up GPG keys in your git configs -for this to work properly.

-

sso-poll-frequency

-
    -
  • Default: 500
  • -
  • Type: Number
  • -
-

When used with SSO-enabled auth-types, configures how regularly the registry -should be polled while the user is completing authentication.

-

sso-type

-
    -
  • Default: 'oauth'
  • -
  • Type: 'oauth', 'saml', or null
  • -
-

If --auth-type=sso, the type of SSO type to use.

-

strict-ssl

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Whether or not to do SSL key validation when making requests to the -registry via https.

-

See also the ca config.

-

tag

-
    -
  • Default: latest
  • -
  • Type: String
  • -
-

If you ask npm to install a package and don't tell it a specific version, then -it will install the specified tag.

-

Also the tag that is added to the package@version specified by the npm -tag command, if no explicit tag is given.

-

tag-version-prefix

-
    -
  • Default: "v"
  • -
  • Type: String
  • -
-

If set, alters the prefix used when tagging a new version when performing a -version increment using npm-version. To remove the prefix altogether, set it -to the empty string: "".

-

Because other tools may rely on the convention that npm version tags look like -v1.0.0, only use this property if it is absolutely necessary. In -particular, use care when overriding this setting for public packages.

-

timing

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

If true, writes an npm-debug log to _logs and timing information to -_timing.json, both in your cache. _timing.json is a newline delimited -list of JSON objects. You can quickly view it with this -json command line: -json -g < ~/.npm/_timing.json.

-

tmp

-
    -
  • Default: TMPDIR environment variable, or "/tmp"
  • -
  • Type: path
  • -
-

Where to store temporary files and folders. All temp files are deleted -on success, but left behind on failure for forensic purposes.

-

unicode

-
    -
  • Default: false on windows, true on mac/unix systems with a unicode locale
  • -
  • Type: Boolean
  • -
-

When set to true, npm uses unicode characters in the tree output. When -false, it uses ascii characters to draw trees.

-

unsafe-perm

-
    -
  • Default: false if running as root, true otherwise
  • -
  • Type: Boolean
  • -
-

Set to true to suppress the UID/GID switching when running package -scripts. If set explicitly to false, then installing as a non-root user -will fail.

-

update-notifier

-
    -
  • Default: true
  • -
  • Type: Boolean
  • -
-

Set to false to suppress the update notification when using an older -version of npm than the latest.

-

usage

-
    -
  • Default: false
  • -
  • Type: Boolean
  • -
-

Set to show short usage output (like the -H output) -instead of complete help when doing npm-help(1).

-

user

-
    -
  • Default: "nobody"
  • -
  • Type: String or Number
  • -
-

The UID to set to when running package scripts as root.

-

userconfig

-
    -
  • Default: ~/.npmrc
  • -
  • Type: path
  • -
-

The location of user-level configuration settings.

-

umask

-
    -
  • Default: 022
  • -
  • Type: Octal numeric string in range 0000..0777 (0..511)
  • -
-

The "umask" value to use when setting the file creation mode on files -and folders.

-

Folders and executables are given a mode which is 0777 masked against -this value. Other files are given a mode which is 0666 masked against -this value. Thus, the defaults are 0755 and 0644 respectively.

-

user-agent

-
    -
  • Default: node/{process.version} {process.platform} {process.arch}
  • -
  • Type: String
  • -
-

Sets a User-Agent to the request header

-

version

-
    -
  • Default: false
  • -
  • Type: boolean
  • -
-

If true, output the npm version and exit successfully.

-

Only relevant when specified explicitly on the command line.

-

versions

-
    -
  • Default: false
  • -
  • Type: boolean
  • -
-

If true, output the npm version as well as node's process.versions map, and -exit successfully.

-

Only relevant when specified explicitly on the command line.

-

viewer

-
    -
  • Default: "man" on Posix, "browser" on Windows
  • -
  • Type: path
  • -
-

The program to use to view help content.

-

Set to "browser" to view html help content in the default web browser.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-developers.html b/deps/npm/html/doc/misc/npm-developers.html deleted file mode 100644 index f03694b88c6467..00000000000000 --- a/deps/npm/html/doc/misc/npm-developers.html +++ /dev/null @@ -1,202 +0,0 @@ - - - npm-developers - - - - - - -
- -

npm-developers

Developer Guide

-

DESCRIPTION

-

So, you've decided to use npm to develop (and maybe publish/deploy) -your project.

-

Fantastic!

-

There are a few things that you need to do above the simple steps -that your users will do to install your program.

-

About These Documents

-

These are man pages. If you install npm, you should be able to -then do man npm-thing to get the documentation on a particular -topic, or npm help thing to see the same information.

-

What is a package

-

A package is:

-
    -
  • a) a folder containing a program described by a package.json file
  • -
  • b) a gzipped tarball containing (a)
  • -
  • c) a url that resolves to (b)
  • -
  • d) a <name>@<version> that is published on the registry with (c)
  • -
  • e) a <name>@<tag> that points to (d)
  • -
  • f) a <name> that has a "latest" tag satisfying (e)
  • -
  • g) a git url that, when cloned, results in (a).
  • -
-

Even if you never publish your package, you can still get a lot of -benefits of using npm if you just want to write a node program (a), and -perhaps if you also want to be able to easily install it elsewhere -after packing it up into a tarball (b).

-

Git urls can be of the form:

-
git://github.com/user/project.git#commit-ish
-git+ssh://user@hostname:project.git#commit-ish
-git+http://user@hostname/project/blah.git#commit-ish
-git+https://user@hostname/project/blah.git#commit-ish

The commit-ish can be any tag, sha, or branch which can be supplied as -an argument to git checkout. The default is master.

-

The package.json File

-

You need to have a package.json file in the root of your project to do -much of anything with npm. That is basically the whole interface.

-

See package.json(5) for details about what goes in that file. At the very -least, you need:

-
    -
  • name: -This should be a string that identifies your project. Please do not -use the name to specify that it runs on node, or is in JavaScript. -You can use the "engines" field to explicitly state the versions of -node (or whatever else) that your program requires, and it's pretty -well assumed that it's JavaScript.

    -

    It does not necessarily need to match your github repository name.

    -

    So, node-foo and bar-js are bad names. foo or bar are better.

    -
  • -
  • version: -A semver-compatible version.

    -
  • -
  • engines: -Specify the versions of node (or whatever else) that your program -runs on. The node API changes a lot, and there may be bugs or new -functionality that you depend on. Be explicit.

    -
  • -
  • author: -Take some credit.

    -
  • -
  • scripts: -If you have a special compilation or installation script, then you -should put it in the scripts object. You should definitely have at -least a basic smoke-test command as the "scripts.test" field. -See npm-scripts(7).

    -
  • -
  • main: -If you have a single module that serves as the entry point to your -program (like what the "foo" package gives you at require("foo")), -then you need to specify that in the "main" field.

    -
  • -
  • directories: -This is an object mapping names to folders. The best ones to include are -"lib" and "doc", but if you use "man" to specify a folder full of man pages, -they'll get installed just like these ones.

    -
  • -
-

You can use npm init in the root of your package in order to get you -started with a pretty basic package.json file. See npm-init(1) for -more info.

-

Keeping files out of your package

-

Use a .npmignore file to keep stuff out of your package. If there's -no .npmignore file, but there is a .gitignore file, then npm will -ignore the stuff matched by the .gitignore file. If you want to -include something that is excluded by your .gitignore file, you can -create an empty .npmignore file to override it. Like git, npm looks -for .npmignore and .gitignore files in all subdirectories of your -package, not only the root directory.

-

.npmignore files follow the same pattern rules -as .gitignore files:

-
    -
  • Blank lines or lines starting with # are ignored.
  • -
  • Standard glob patterns work.
  • -
  • You can end patterns with a forward slash / to specify a directory.
  • -
  • You can negate a pattern by starting it with an exclamation point !.
  • -
-

By default, the following paths and files are ignored, so there's no -need to add them to .npmignore explicitly:

-
    -
  • .*.swp
  • -
  • ._*
  • -
  • .DS_Store
  • -
  • .git
  • -
  • .hg
  • -
  • .npmrc
  • -
  • .lock-wscript
  • -
  • .svn
  • -
  • .wafpickle-*
  • -
  • config.gypi
  • -
  • CVS
  • -
  • npm-debug.log
  • -
-

Additionally, everything in node_modules is ignored, except for -bundled dependencies. npm automatically handles this for you, so don't -bother adding node_modules to .npmignore.

-

The following paths and files are never ignored, so adding them to -.npmignore is pointless:

-
    -
  • package.json
  • -
  • README (and its variants)
  • -
  • CHANGELOG (and its variants)
  • -
  • LICENSE / LICENCE
  • -
-

If, given the structure of your project, you find .npmignore to be a -maintenance headache, you might instead try populating the files -property of package.json, which is an array of file or directory names -that should be included in your package. Sometimes a whitelist is easier -to manage than a blacklist.

-

Testing whether your .npmignore or files config works

-

If you want to double check that your package will include only the files -you intend it to when published, you can run the npm pack command locally -which will generate a tarball in the working directory, the same way it -does for publishing.

- -

npm link is designed to install a development package and see the -changes in real time without having to keep re-installing it. (You do -need to either re-link or npm rebuild -g to update compiled packages, -of course.)

-

More info at npm-link(1).

-

Before Publishing: Make Sure Your Package Installs and Works

-

This is important.

-

If you can not install it locally, you'll have -problems trying to publish it. Or, worse yet, you'll be able to -publish it, but you'll be publishing a broken or pointless package. -So don't do that.

-

In the root of your package, do this:

-
npm install . -g

That'll show you that it's working. If you'd rather just create a symlink -package that points to your working directory, then do this:

-
npm link

Use npm ls -g to see if it's there.

-

To test a local install, go into some other folder, and then do:

-
cd ../some-other-folder
-npm install ../my-package

to install it locally into the node_modules folder in that other place.

-

Then go into the node-repl, and try using require("my-thing") to -bring in your module's main module.

-

Create a User Account

-

Create a user with the adduser command. It works like this:

-
npm adduser

and then follow the prompts.

-

This is documented better in npm-adduser(1).

-

Publish your package

-

This part's easy. In the root of your folder, do this:

-
npm publish

You can give publish a url to a tarball, or a filename of a tarball, -or a path to a folder.

-

Note that pretty much everything in that folder will be exposed -by default. So, if you have secret stuff in there, use a -.npmignore file to list out the globs to ignore, or publish -from a fresh checkout.

-

Brag about it

-

Send emails, write blogs, blab in IRC.

-

Tell the world how easy it is to install your program!

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-disputes.html b/deps/npm/html/doc/misc/npm-disputes.html deleted file mode 100644 index c8bbce384308ea..00000000000000 --- a/deps/npm/html/doc/misc/npm-disputes.html +++ /dev/null @@ -1,143 +0,0 @@ - - - npm-disputes - - - - - - -
- -

npm-disputes

Handling Module Name Disputes

-

This document describes the steps that you should take to resolve module name -disputes with other npm publishers. It also describes special steps you should -take about names you think infringe your trademarks.

-

This document is a clarification of the acceptable behavior outlined in the -npm Code of Conduct, and nothing in -this document should be interpreted to contradict any aspect of the npm Code of -Conduct.

-

TL;DR

-
    -
  1. Get the author email with npm owner ls <pkgname>
  2. -
  3. Email the author, CC support@npmjs.com
  4. -
  5. After a few weeks, if there's no resolution, we'll sort it out.
  6. -
-

Don't squat on package names. Publish code or move out of the way.

-

DESCRIPTION

-

There sometimes arise cases where a user publishes a module, and then later, -some other user wants to use that name. Here are some common ways that happens -(each of these is based on actual events.)

-
    -
  1. Alice writes a JavaScript module foo, which is not node-specific. Alice -doesn't use node at all. Yusuf wants to use foo in node, so he wraps it in -an npm module. Some time later, Alice starts using node, and wants to take -over management of her program.

    -
  2. -
  3. Yusuf writes an npm module foo, and publishes it. Perhaps much later, Alice -finds a bug in foo, and fixes it. She sends a pull request to Yusuf, but -Yusuf doesn't have the time to deal with it, because he has a new job and a -new baby and is focused on his new Erlang project, and kind of not involved -with node any more. Alice would like to publish a new foo, but can't, -because the name is taken.

    -
  4. -
  5. Yusuf writes a 10-line flow-control library, and calls it foo, and -publishes it to the npm registry. Being a simple little thing, it never -really has to be updated. Alice works for Foo Inc, the makers of the -critically acclaimed and widely-marketed foo JavaScript toolkit framework. -They publish it to npm as foojs, but people are routinely confused when -npm install foo is some different thing.

    -
  6. -
  7. Yusuf writes a parser for the widely-known foo file format, because he -needs it for work. Then, he gets a new job, and never updates the prototype. -Later on, Alice writes a much more complete foo parser, but can't publish, -because Yusuf's foo is in the way.

    -
  8. -
  9. npm owner ls foo. This will tell Alice the email address of the owner -(Yusuf).

    -
  10. -
  11. Alice emails Yusuf, explaining the situation as respectfully as possible, -and what she would like to do with the module name. She adds the npm support -staff support@npmjs.com to the CC list of the email. Mention in the email -that Yusuf can run npm owner add alice foo to add Alice as an owner of the -foo package.

    -
  12. -
  13. After a reasonable amount of time, if Yusuf has not responded, or if Yusuf -and Alice can't come to any sort of resolution, email support -support@npmjs.com and we'll sort it out. ("Reasonable" is usually at least -4 weeks.)

    -
  14. -
-

REASONING

-

In almost every case so far, the parties involved have been able to reach an -amicable resolution without any major intervention. Most people really do want -to be reasonable, and are probably not even aware that they're in your way.

-

Module ecosystems are most vibrant and powerful when they are as self-directed -as possible. If an admin one day deletes something you had worked on, then that -is going to make most people quite upset, regardless of the justification. When -humans solve their problems by talking to other humans with respect, everyone -has the chance to end up feeling good about the interaction.

-

EXCEPTIONS

-

Some things are not allowed, and will be removed without discussion if they are -brought to the attention of the npm registry admins, including but not limited -to:

-
    -
  1. Malware (that is, a package designed to exploit or harm the machine on which -it is installed).
  2. -
  3. Violations of copyright or licenses (for example, cloning an MIT-licensed -program, and then removing or changing the copyright and license statement).
  4. -
  5. Illegal content.
  6. -
  7. "Squatting" on a package name that you plan to use, but aren't actually -using. Sorry, I don't care how great the name is, or how perfect a fit it is -for the thing that someday might happen. If someone wants to use it today, -and you're just taking up space with an empty tarball, you're going to be -evicted.
  8. -
  9. Putting empty packages in the registry. Packages must have SOME -functionality. It can be silly, but it can't be nothing. (See also: -squatting.)
  10. -
  11. Doing weird things with the registry, like using it as your own personal -application database or otherwise putting non-packagey things into it.
  12. -
  13. Other things forbidden by the npm -Code of Conduct such as hateful -language, pornographic content, or harassment.
  14. -
-

If you see bad behavior like this, please report it to abuse@npmjs.com right -away. You are never expected to resolve abusive behavior on your own. We are -here to help.

-

TRADEMARKS

-

If you think another npm publisher is infringing your trademark, such as by -using a confusingly similar package name, email abuse@npmjs.com with a link to -the package or user account on https://www.npmjs.com/. -Attach a copy of your trademark registration certificate.

-

If we see that the package's publisher is intentionally misleading others by -misusing your registered mark without permission, we will transfer the package -name to you. Otherwise, we will contact the package publisher and ask them to -clear up any confusion with changes to their package's README file or -metadata.

-

CHANGES

-

This is a living document and may be updated from time to time. Please refer to -the git history for this document -to view the changes.

-

LICENSE

-

Copyright (C) npm, Inc., All rights reserved

-

This document may be reused under a Creative Commons Attribution-ShareAlike -License.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-index.html b/deps/npm/html/doc/misc/npm-index.html deleted file mode 100644 index ee9bf45888c5f2..00000000000000 --- a/deps/npm/html/doc/misc/npm-index.html +++ /dev/null @@ -1,186 +0,0 @@ - - - npm-index - - - - - - -
- -

npm-index

Index of all npm documentation

-

README

-

a JavaScript package manager

-

Command Line Documentation

-

Using npm on the command line

-

npm(1)

-

javascript package manager

-

npm-access(1)

-

Set access level on published packages

-

npm-adduser(1)

-

Add a registry user account

-

npm-audit(1)

-

Run a security audit

-

npm-bin(1)

-

Display npm bin folder

-

npm-bugs(1)

-

Bugs for a package in a web browser maybe

-

npm-build(1)

-

Build a package

-

npm-bundle(1)

-

REMOVED

-

npm-cache(1)

-

Manipulates packages cache

-

npm-ci(1)

-

Install a project with a clean slate

-

npm-completion(1)

-

Tab Completion for npm

-

npm-config(1)

-

Manage the npm configuration files

-

npm-dedupe(1)

-

Reduce duplication

-

npm-deprecate(1)

-

Deprecate a version of a package

-

npm-dist-tag(1)

-

Modify package distribution tags

-

npm-docs(1)

-

Docs for a package in a web browser maybe

-

npm-doctor(1)

-

Check your environments

-

npm-edit(1)

-

Edit an installed package

-

npm-explore(1)

-

Browse an installed package

-

npm-help-search(1)

-

Search npm help documentation

-

npm-help(1)

-

Get help on npm

-

npm-hook(1)

-

Manage registry hooks

-

npm-init(1)

-

create a package.json file

-

npm-install-ci-test(1)

-

Install a project with a clean slate and run tests

-

npm-install-test(1)

-

Install package(s) and run tests

-

npm-install(1)

-

Install a package

-

npm-link(1)

-

Symlink a package folder

-

npm-logout(1)

-

Log out of the registry

-

npm-ls(1)

-

List installed packages

-

npm-org(1)

-

Manage orgs

-

npm-outdated(1)

-

Check for outdated packages

-

npm-owner(1)

-

Manage package owners

-

npm-pack(1)

-

Create a tarball from a package

-

npm-ping(1)

-

Ping npm registry

-

npm-prefix(1)

-

Display prefix

-

npm-profile(1)

-

Change settings on your registry profile

-

npm-prune(1)

-

Remove extraneous packages

-

npm-publish(1)

-

Publish a package

-

npm-rebuild(1)

-

Rebuild a package

-

npm-repo(1)

-

Open package repository page in the browser

-

npm-restart(1)

-

Restart a package

-

npm-root(1)

-

Display npm root

-

npm-run-script(1)

-

Run arbitrary package scripts

-

npm-search(1)

-

Search for packages

-

npm-shrinkwrap(1)

-

Lock down dependency versions for publication

-

npm-star(1)

-

Mark your favorite packages

-

npm-stars(1)

-

View packages marked as favorites

-

npm-start(1)

-

Start a package

-

npm-stop(1)

-

Stop a package

-

npm-team(1)

-

Manage organization teams and team memberships

-

npm-test(1)

-

Test a package

-

npm-token(1)

-

Manage your authentication tokens

-

npm-uninstall(1)

-

Remove a package

-

npm-unpublish(1)

-

Remove a package from the registry

-

npm-update(1)

-

Update a package

-

npm-version(1)

-

Bump a package version

-

npm-view(1)

-

View registry info

-

npm-whoami(1)

-

Display npm username

-

API Documentation

-

Using npm in your Node programs

-

Files

-

File system structures npm uses

-

npm-folders(5)

-

Folder Structures Used by npm

-

npm-package-locks(5)

-

An explanation of npm lockfiles

-

npm-shrinkwrap.json(5)

-

A publishable lockfile

-

npmrc(5)

-

The npm config files

-

package-lock.json(5)

-

A manifestation of the manifest

-

package.json(5)

-

Specifics of npm's package.json handling

-

Misc

-

Various other bits and bobs

-

npm-coding-style(7)

-

npm's "funny" coding style

-

npm-config(7)

-

More than you probably want to know about npm configuration

-

npm-developers(7)

-

Developer Guide

-

npm-disputes(7)

-

Handling Module Name Disputes

-

npm-index(7)

-

Index of all npm documentation

-

npm-orgs(7)

-

Working with Teams & Orgs

-

npm-registry(7)

-

The JavaScript Package Registry

-

npm-scope(7)

-

Scoped packages

-

npm-scripts(7)

-

How npm handles the "scripts" field

-

removing-npm(7)

-

Cleaning the Slate

-

semver(7)

-

The semantic versioner for npm

- -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-orgs.html b/deps/npm/html/doc/misc/npm-orgs.html deleted file mode 100644 index 854df8e73c7365..00000000000000 --- a/deps/npm/html/doc/misc/npm-orgs.html +++ /dev/null @@ -1,81 +0,0 @@ - - - npm-orgs - - - - - - -
- -

npm-orgs

Working with Teams & Orgs

-

DESCRIPTION

-

There are three levels of org users:

-
    -
  1. Super admin, controls billing & adding people to the org.
  2. -
  3. Team admin, manages team membership & package access.
  4. -
  5. Developer, works on packages they are given access to.
  6. -
-

The super admin is the only person who can add users to the org because it impacts the monthly bill. The super admin will use the website to manage membership. Every org has a developers team that all users are automatically added to.

-

The team admin is the person who manages team creation, team membership, and package access for teams. The team admin grants package access to teams, not individuals.

-

The developer will be able to access packages based on the teams they are on. Access is either read-write or read-only.

-

There are two main commands:

-
    -
  1. npm team see npm-team(1) for more details
  2. -
  3. npm access see npm-access(1) for more details
  4. -
-

Team Admins create teams

-
    -
  • Check who you’ve added to your org:
  • -
-
npm team ls <org>:developers
    -
  • Each org is automatically given a developers team, so you can see the whole list of team members in your org. This team automatically gets read-write access to all packages, but you can change that with the access command.

    -
  • -
  • Create a new team:

    -
  • -
-
npm team create <org:team>
    -
  • Add members to that team:
  • -
-
npm team add <org:team> <user>

Publish a package and adjust package access

-
    -
  • In package directory, run
  • -
-
npm init --scope=<org>

to scope it for your org & publish as usual

-
    -
  • Grant access:
  • -
-
npm access grant <read-only|read-write> <org:team> [<package>]
    -
  • Revoke access:
  • -
-
npm access revoke <org:team> [<package>]

Monitor your package access

-
    -
  • See what org packages a team member can access:
  • -
-
npm access ls-packages <org> <user>
    -
  • See packages available to a specific team:
  • -
-
npm access ls-packages <org:team>
    -
  • Check which teams are collaborating on a package:
  • -
-
npm access ls-collaborators <pkg>

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-registry.html b/deps/npm/html/doc/misc/npm-registry.html deleted file mode 100644 index d0e5ab9ae1cc17..00000000000000 --- a/deps/npm/html/doc/misc/npm-registry.html +++ /dev/null @@ -1,100 +0,0 @@ - - - npm-registry - - - - - - -
- -

npm-registry

The JavaScript Package Registry

-

DESCRIPTION

-

To resolve packages by name and version, npm talks to a registry website -that implements the CommonJS Package Registry specification for reading -package info.

-

npm is configured to use npm, Inc.'s public registry at -https://registry.npmjs.org by default. Use of the npm public registry is -subject to terms of use available at https://www.npmjs.com/policies/terms.

-

You can configure npm to use any compatible registry you like, and even run -your own registry. Use of someone else's registry may be governed by their -terms of use.

-

npm's package registry implementation supports several -write APIs as well, to allow for publishing packages and managing user -account information.

-

The npm public registry is powered by a CouchDB database, -of which there is a public mirror at -https://skimdb.npmjs.com/registry. The code for the couchapp is -available at https://github.com/npm/npm-registry-couchapp.

-

The registry URL used is determined by the scope of the package (see -npm-scope(7)). If no scope is specified, the default registry is used, which is -supplied by the registry config parameter. See npm-config(1), -npmrc(5), and npm-config(7) for more on managing npm's configuration.

-

Does npm send any information about me back to the registry?

-

Yes.

-

When making requests of the registry npm adds two headers with information -about your environment:

-
    -
  • Npm-Scope – If your project is scoped, this header will contain its -scope. In the future npm hopes to build registry features that use this -information to allow you to customize your experience for your -organization.
  • -
  • Npm-In-CI – Set to "true" if npm believes this install is running in a -continuous integration environment, "false" otherwise. This is detected by -looking for the following environment variables: CI, TDDIUM, -JENKINS_URL, bamboo.buildKey. If you'd like to learn more you may find -the original PR -interesting. -This is used to gather better metrics on how npm is used by humans, versus -build farms.
  • -
-

The npm registry does not try to correlate the information in these headers -with any authenticated accounts that may be used in the same requests.

-

Can I run my own private registry?

-

Yes!

-

The easiest way is to replicate the couch database, and use the same (or -similar) design doc to implement the APIs.

-

If you set up continuous replication from the official CouchDB, and then -set your internal CouchDB as the registry config, then you'll be able -to read any published packages, in addition to your private ones, and by -default will only publish internally.

-

If you then want to publish a package for the whole world to see, you can -simply override the --registry option for that publish command.

-

I don't want my package published in the official registry. It's private.

-

Set "private": true in your package.json to prevent it from being -published at all, or -"publishConfig":{"registry":"http://my-internal-registry.local"} -to force it to be published only to your internal registry.

-

See package.json(5) for more info on what goes in the package.json file.

-

Will you replicate from my registry into the public one?

-

No. If you want things to be public, then publish them into the public -registry using npm. What little security there is would be for nought -otherwise.

-

Do I have to use couchdb to build a registry that npm can talk to?

-

No, but it's way easier. Basically, yes, you do, or you have to -effectively implement the entire CouchDB API anyway.

-

Is there a website or something to see package docs and such?

-

Yes, head over to https://www.npmjs.com/

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-scope.html b/deps/npm/html/doc/misc/npm-scope.html deleted file mode 100644 index 3566a27ea9f1f0..00000000000000 --- a/deps/npm/html/doc/misc/npm-scope.html +++ /dev/null @@ -1,97 +0,0 @@ - - - npm-scope - - - - - - -
- -

npm-scope

Scoped packages

-

DESCRIPTION

-

All npm packages have a name. Some package names also have a scope. A scope -follows the usual rules for package names (URL-safe characters, no leading dots -or underscores). When used in package names, scopes are preceded by an @ symbol -and followed by a slash, e.g.

-
@somescope/somepackagename

Scopes are a way of grouping related packages together, and also affect a few -things about the way npm treats the package.

-

Each npm user/organization has their own scope, and only you can add packages -in your scope. This means you don't have to worry about someone taking your -package name ahead of you. Thus it is also a good way to signal official packages -for organizations.

-

Scoped packages can be published and installed as of npm@2 and are supported -by the primary npm registry. Unscoped packages can depend on scoped packages and -vice versa. The npm client is backwards-compatible with unscoped registries, -so it can be used to work with scoped and unscoped registries at the same time.

-

Installing scoped packages

-

Scoped packages are installed to a sub-folder of the regular installation -folder, e.g. if your other packages are installed in node_modules/packagename, -scoped modules will be installed in node_modules/@myorg/packagename. The scope -folder (@myorg) is simply the name of the scope preceded by an @ symbol, and can -contain any number of scoped packages.

-

A scoped package is installed by referencing it by name, preceded by an -@ symbol, in npm install:

-
npm install @myorg/mypackage

Or in package.json:

-
"dependencies": {
-  "@myorg/mypackage": "^1.3.0"
-}

Note that if the @ symbol is omitted, in either case, npm will instead attempt to -install from GitHub; see npm-install(1).

-

Requiring scoped packages

-

Because scoped packages are installed into a scope folder, you have to -include the name of the scope when requiring them in your code, e.g.

-
require('@myorg/mypackage')

There is nothing special about the way Node treats scope folders. This -simply requires the mypackage module in the folder named @myorg.

-

Publishing scoped packages

-

Scoped packages can be published from the CLI as of npm@2 and can be -published to any registry that supports them, including the primary npm -registry.

-

(As of 2015-04-19, and with npm 2.0 or better, the primary npm registry -does support scoped packages.)

-

If you wish, you may associate a scope with a registry; see below.

-

Publishing public scoped packages to the primary npm registry

-

To publish a public scoped package, you must specify --access public with -the initial publication. This will publish the package and set access -to public as if you had run npm access public after publishing.

-

Publishing private scoped packages to the npm registry

-

To publish a private scoped package to the npm registry, you must have -an npm Private Modules -account.

-

You can then publish the module with npm publish or npm publish ---access restricted, and it will be present in the npm registry, with -restricted access. You can then change the access permissions, if -desired, with npm access or on the npmjs.com website.

-

Associating a scope with a registry

-

Scopes can be associated with a separate registry. This allows you to -seamlessly use a mix of packages from the primary npm registry and one or more -private registries, such as npm Enterprise.

-

You can associate a scope with a registry at login, e.g.

-
npm login --registry=http://reg.example.com --scope=@myco

Scopes have a many-to-one relationship with registries: one registry can -host multiple scopes, but a scope only ever points to one registry.

-

You can also associate a scope with a registry using npm config:

-
npm config set @myco:registry http://reg.example.com

Once a scope is associated with a registry, any npm install for a package -with that scope will request packages from that registry instead. Any -npm publish for a package name that contains the scope will be published to -that registry instead.

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/npm-scripts.html b/deps/npm/html/doc/misc/npm-scripts.html deleted file mode 100644 index 3cee61320bbaa0..00000000000000 --- a/deps/npm/html/doc/misc/npm-scripts.html +++ /dev/null @@ -1,238 +0,0 @@ - - - npm-scripts - - - - - - -
- -

npm-scripts

How npm handles the "scripts" field

-

DESCRIPTION

-

npm supports the "scripts" property of the package.json file, for the -following scripts:

-
    -
  • prepublish: -Run BEFORE the package is packed and published, as well as on local npm -install without any arguments. (See below)
  • -
  • prepare: -Run both BEFORE the package is packed and published, on local npm -install without any arguments, and when installing git dependencies (See -below). This is run AFTER prepublish, but BEFORE prepublishOnly.
  • -
  • prepublishOnly: -Run BEFORE the package is prepared and packed, ONLY on npm publish. (See -below.)
  • -
  • prepack: -run BEFORE a tarball is packed (on npm pack, npm publish, and when -installing git dependencies)
  • -
  • postpack: -Run AFTER the tarball has been generated and moved to its final destination.
  • -
  • publish, postpublish: -Run AFTER the package is published.
  • -
  • preinstall: -Run BEFORE the package is installed
  • -
  • install, postinstall: -Run AFTER the package is installed.
  • -
  • preuninstall, uninstall: -Run BEFORE the package is uninstalled.
  • -
  • postuninstall: -Run AFTER the package is uninstalled.
  • -
  • preversion: -Run BEFORE bumping the package version.
  • -
  • version: -Run AFTER bumping the package version, but BEFORE commit.
  • -
  • postversion: -Run AFTER bumping the package version, and AFTER commit.
  • -
  • pretest, test, posttest: -Run by the npm test command.
  • -
  • prestop, stop, poststop: -Run by the npm stop command.
  • -
  • prestart, start, poststart: -Run by the npm start command.
  • -
  • prerestart, restart, postrestart: -Run by the npm restart command. Note: npm restart will run the -stop and start scripts if no restart script is provided.
  • -
  • preshrinkwrap, shrinkwrap, postshrinkwrap: -Run by the npm shrinkwrap command.
  • -
-

Additionally, arbitrary scripts can be executed by running npm -run-script <stage>. Pre and post commands with matching -names will be run for those as well (e.g. premyscript, myscript, -postmyscript). Scripts from dependencies can be run with -npm explore <pkg> -- npm run <stage>.

-

PREPUBLISH AND PREPARE

-

DEPRECATION NOTE

-

Since npm@1.1.71, the npm CLI has run the prepublish script for both npm -publish and npm install, because it's a convenient way to prepare a package -for use (some common use cases are described in the section below). It has -also turned out to be, in practice, very -confusing. As of npm@4.0.0, a new -event has been introduced, prepare, that preserves this existing behavior. A -new event, prepublishOnly has been added as a transitional strategy to -allow users to avoid the confusing behavior of existing npm versions and only -run on npm publish (for instance, running the tests one last time to ensure -they're in good shape).

-

See https://github.com/npm/npm/issues/10074 for a much lengthier -justification, with further reading, for this change.

-

USE CASES

-

If you need to perform operations on your package before it is used, in a way -that is not dependent on the operating system or architecture of the -target system, use a prepublish script. This includes -tasks such as:

-
    -
  • Compiling CoffeeScript source code into JavaScript.
  • -
  • Creating minified versions of JavaScript source code.
  • -
  • Fetching remote resources that your package will use.
  • -
-

The advantage of doing these things at prepublish time is that they can be done once, in a -single place, thus reducing complexity and variability. -Additionally, this means that:

-
    -
  • You can depend on coffee-script as a devDependency, and thus -your users don't need to have it installed.
  • -
  • You don't need to include minifiers in your package, reducing -the size for your users.
  • -
  • You don't need to rely on your users having curl or wget or -other system tools on the target machines.
  • -
-

DEFAULT VALUES

-

npm will default some script values based on package contents.

-
    -
  • "start": "node server.js":

    -

    If there is a server.js file in the root of your package, then npm -will default the start command to node server.js.

    -
  • -
  • "install": "node-gyp rebuild":

    -

    If there is a binding.gyp file in the root of your package and you -haven't defined your own install or preinstall scripts, npm will -default the install command to compile using node-gyp.

    -
  • -
-

USER

-

If npm was invoked with root privileges, then it will change the uid -to the user account or uid specified by the user config, which -defaults to nobody. Set the unsafe-perm flag to run scripts with -root privileges.

-

ENVIRONMENT

-

Package scripts run in an environment where many pieces of information -are made available regarding the setup of npm and the current state of -the process.

-

path

-

If you depend on modules that define executable scripts, like test -suites, then those executables will be added to the PATH for -executing the scripts. So, if your package.json has this:

-
{ "name" : "foo"
-, "dependencies" : { "bar" : "0.1.x" }
-, "scripts": { "start" : "bar ./test" } }

then you could run npm start to execute the bar script, which is -exported into the node_modules/.bin directory on npm install.

-

package.json vars

-

The package.json fields are tacked onto the npm_package_ prefix. So, -for instance, if you had {"name":"foo", "version":"1.2.5"} in your -package.json file, then your package scripts would have the -npm_package_name environment variable set to "foo", and the -npm_package_version set to "1.2.5". You can access these variables -in your code with process.env.npm_package_name and -process.env.npm_package_version, and so on for other fields.

-

configuration

-

Configuration parameters are put in the environment with the -npm_config_ prefix. For instance, you can view the effective root -config by checking the npm_config_root environment variable.

-

Special: package.json "config" object

-

The package.json "config" keys are overwritten in the environment if -there is a config param of <name>[@<version>]:<key>. For example, -if the package.json has this:

-
{ "name" : "foo"
-, "config" : { "port" : "8080" }
-, "scripts" : { "start" : "node server.js" } }

and the server.js is this:

-
http.createServer(...).listen(process.env.npm_package_config_port)

then the user could change the behavior by doing:

-
npm config set foo:port 80

current lifecycle event

-

Lastly, the npm_lifecycle_event environment variable is set to -whichever stage of the cycle is being executed. So, you could have a -single script used for different parts of the process which switches -based on what's currently happening.

-

Objects are flattened following this format, so if you had -{"scripts":{"install":"foo.js"}} in your package.json, then you'd -see this in the script:

-
process.env.npm_package_scripts_install === "foo.js"

EXAMPLES

-

For example, if your package.json contains this:

-
{ "scripts" :
-  { "install" : "scripts/install.js"
-  , "postinstall" : "scripts/install.js"
-  , "uninstall" : "scripts/uninstall.js"
-  }
-}

then scripts/install.js will be called for the install -and post-install stages of the lifecycle, and scripts/uninstall.js -will be called when the package is uninstalled. Since -scripts/install.js is running for two different phases, it would -be wise in this case to look at the npm_lifecycle_event environment -variable.

-

If you want to run a make command, you can do so. This works just -fine:

-
{ "scripts" :
-  { "preinstall" : "./configure"
-  , "install" : "make && make install"
-  , "test" : "make test"
-  }
-}

EXITING

-

Scripts are run by passing the line as a script argument to sh.

-

If the script exits with a code other than 0, then this will abort the -process.

-

Note that these script files don't have to be nodejs or even -javascript programs. They just have to be some kind of executable -file.

-

HOOK SCRIPTS

-

If you want to run a specific script at a specific lifecycle event for -ALL packages, then you can use a hook script.

-

Place an executable file at node_modules/.hooks/{eventname}, and -it'll get run for all packages when they are going through that point -in the package lifecycle for any packages installed in that root.

-

Hook scripts are run exactly the same way as package.json scripts. -That is, they are in a separate child process, with the env described -above.

-

BEST PRACTICES

-
    -
  • Don't exit with a non-zero error code unless you really mean it. -Except for uninstall scripts, this will cause the npm action to -fail, and potentially be rolled back. If the failure is minor or -only will prevent some optional features, then it's better to just -print a warning and exit successfully.
  • -
  • Try not to use scripts to do what npm can do for you. Read through -package.json(5) to see all the things that you can specify and enable -by simply describing your package appropriately. In general, this -will lead to a more robust and consistent state.
  • -
  • Inspect the env to determine where to put things. For instance, if -the npm_config_binroot environment variable is set to /home/user/bin, then -don't try to install executables into /usr/local/bin. The user -probably set it up that way for a reason.
  • -
  • Don't prefix your script commands with "sudo". If root permissions -are required for some reason, then it'll fail with that error, and -the user will sudo the npm command in question.
  • -
  • Don't use install. Use a .gyp file for compilation, and prepublish -for anything else. You should almost never have to explicitly set a -preinstall or install script. If you are doing this, please consider if -there is another option. The only valid use of install or preinstall -scripts is for compilation which must be done on the target architecture.
  • -
-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/removing-npm.html b/deps/npm/html/doc/misc/removing-npm.html deleted file mode 100644 index b5fcfbc7dcf024..00000000000000 --- a/deps/npm/html/doc/misc/removing-npm.html +++ /dev/null @@ -1,56 +0,0 @@ - - - removing-npm - - - - - - -
- -

npm-removal

Cleaning the Slate

-

SYNOPSIS

-

So sad to see you go.

-
sudo npm uninstall npm -g

Or, if that fails, get the npm source code, and do:

-
sudo make uninstall

More Severe Uninstalling

-

Usually, the above instructions are sufficient. That will remove -npm, but leave behind anything you've installed.

-

If that doesn't work, or if you require more drastic measures, -continue reading.

-

Note that this is only necessary for globally-installed packages. Local -installs are completely contained within a project's node_modules -folder. Delete that folder, and everything is gone (unless a package's -install script is particularly ill-behaved).

-

This assumes that you installed node and npm in the default place. If -you configured node with a different --prefix, or installed npm with a -different prefix setting, then adjust the paths accordingly, replacing -/usr/local with your install prefix.

-

To remove everything npm-related manually:

-
rm -rf /usr/local/{lib/node{,/.npm,_modules},bin,share/man}/npm*

If you installed things with npm, then your best bet is to uninstall -them with npm first, and then install them again once you have a -proper install. This can help find any symlinks that are lying -around:

-
ls -laF /usr/local/{lib/node{,/.npm},bin,share/man} | grep npm

Prior to version 0.3, npm used shim files for executables and node -modules. To track those down, you can do the following:

-
find /usr/local/{lib/node,bin} -exec grep -l npm \{\} \; ;

(This is also in the README file.)

-

SEE ALSO

- - -
- - - - - - - - - - - - diff --git a/deps/npm/html/doc/misc/semver.html b/deps/npm/html/doc/misc/semver.html deleted file mode 100644 index b419e9bf6953bc..00000000000000 --- a/deps/npm/html/doc/misc/semver.html +++ /dev/null @@ -1,377 +0,0 @@ - - - semver - - - - - - -
- -

semver

The semantic versioner for npm

-

Install

-
npm install --save semver
-

Usage

-

As a node module:

-
const semver = require('semver')
-
-semver.valid('1.2.3') // '1.2.3'
-semver.valid('a.b.c') // null
-semver.clean('  =v1.2.3   ') // '1.2.3'
-semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
-semver.gt('1.2.3', '9.8.7') // false
-semver.lt('1.2.3', '9.8.7') // true
-semver.minVersion('>=1.0.0') // '1.0.0'
-semver.valid(semver.coerce('v2')) // '2.0.0'
-semver.valid(semver.coerce('42.6.7.9.3-alpha')) // '42.6.7'
-

As a command-line utility:

-
$ semver -h
-
-A JavaScript implementation of the https://semver.org/ specification
-Copyright Isaac Z. Schlueter
-
-Usage: semver [options] <version> [<version> [...]]
-Prints valid versions sorted by SemVer precedence
-
-Options:
--r --range <range>
-        Print versions that match the specified range.
-
--i --increment [<level>]
-        Increment a version by the specified level.  Level can
-        be one of: major, minor, patch, premajor, preminor,
-        prepatch, or prerelease.  Default level is 'patch'.
-        Only one version may be specified.
-
---preid <identifier>
-        Identifier to be used to prefix premajor, preminor,
-        prepatch or prerelease version increments.
-
--l --loose
-        Interpret versions and ranges loosely
-
--p --include-prerelease
-        Always include prerelease versions in range matching
-
--c --coerce
-        Coerce a string into SemVer if possible
-        (does not imply --loose)
-
-Program exits successfully if any valid version satisfies
-all supplied ranges, and prints all satisfying versions.
-
-If no satisfying versions are found, then exits failure.
-
-Versions are printed in ascending order, so supplying
-multiple versions to the utility will just sort them.

Versions

-

A "version" is described by the v2.0.0 specification found at -https://semver.org/.

-

A leading "=" or "v" character is stripped off and ignored.

-

Ranges

-

A version range is a set of comparators which specify versions -that satisfy the range.

-

A comparator is composed of an operator and a version. The set -of primitive operators is:

-
    -
  • < Less than
  • -
  • <= Less than or equal to
  • -
  • > Greater than
  • -
  • >= Greater than or equal to
  • -
  • = Equal. If no operator is specified, then equality is assumed, -so this operator is optional, but MAY be included.
  • -
-

For example, the comparator >=1.2.7 would match the versions -1.2.7, 1.2.8, 2.5.3, and 1.3.9, but not the versions 1.2.6 -or 1.1.0.

-

Comparators can be joined by whitespace to form a comparator set, -which is satisfied by the intersection of all of the comparators -it includes.

-

A range is composed of one or more comparator sets, joined by ||. A -version matches a range if and only if every comparator in at least -one of the ||-separated comparator sets is satisfied by the version.

-

For example, the range >=1.2.7 <1.3.0 would match the versions -1.2.7, 1.2.8, and 1.2.99, but not the versions 1.2.6, 1.3.0, -or 1.1.0.

-

The range 1.2.7 || >=1.2.9 <2.0.0 would match the versions 1.2.7, -1.2.9, and 1.4.6, but not the versions 1.2.8 or 2.0.0.

-

Prerelease Tags

-

If a version has a prerelease tag (for example, 1.2.3-alpha.3) then -it will only be allowed to satisfy comparator sets if at least one -comparator with the same [major, minor, patch] tuple also has a -prerelease tag.

-

For example, the range >1.2.3-alpha.3 would be allowed to match the -version 1.2.3-alpha.7, but it would not be satisfied by -3.4.5-alpha.9, even though 3.4.5-alpha.9 is technically "greater -than" 1.2.3-alpha.3 according to the SemVer sort rules. The version -range only accepts prerelease tags on the 1.2.3 version. The -version 3.4.5 would satisfy the range, because it does not have a -prerelease flag, and 3.4.5 is greater than 1.2.3-alpha.7.

-

The purpose for this behavior is twofold. First, prerelease versions -frequently are updated very quickly, and contain many breaking changes -that are (by the author's design) not yet fit for public consumption. -Therefore, by default, they are excluded from range matching -semantics.

-

Second, a user who has opted into using a prerelease version has -clearly indicated the intent to use that specific set of -alpha/beta/rc versions. By including a prerelease tag in the range, -the user is indicating that they are aware of the risk. However, it -is still not appropriate to assume that they have opted into taking a -similar risk on the next set of prerelease versions.

-

Note that this behavior can be suppressed (treating all prerelease -versions as if they were normal versions, for the purpose of range -matching) by setting the includePrerelease flag on the options -object to any -functions that do -range matching.

-

Prerelease Identifiers

-

The method .inc takes an additional identifier string argument that -will append the value of the string as a prerelease identifier:

-
semver.inc('1.2.3', 'prerelease', 'beta')
-// '1.2.4-beta.0'
-

command-line example:

-
$ semver 1.2.3 -i prerelease --preid beta
-1.2.4-beta.0
-

Which then can be used to increment further:

-
$ semver 1.2.4-beta.0 -i prerelease
-1.2.4-beta.1
-

Advanced Range Syntax

-

Advanced range syntax desugars to primitive comparators in -deterministic ways.

-

Advanced ranges may be combined in the same way as primitive -comparators using white space or ||.

-

Hyphen Ranges X.Y.Z - A.B.C

-

Specifies an inclusive set.

-
    -
  • 1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4
  • -
-

If a partial version is provided as the first version in the inclusive -range, then the missing pieces are replaced with zeroes.

-
    -
  • 1.2 - 2.3.4 := >=1.2.0 <=2.3.4
  • -
-

If a partial version is provided as the second version in the -inclusive range, then all versions that start with the supplied parts -of the tuple are accepted, but nothing that would be greater than the -provided tuple parts.

-
    -
  • 1.2.3 - 2.3 := >=1.2.3 <2.4.0
  • -
  • 1.2.3 - 2 := >=1.2.3 <3.0.0
  • -
-

X-Ranges 1.2.x 1.X 1.2.* *

-

Any of X, x, or * may be used to "stand in" for one of the -numeric values in the [major, minor, patch] tuple.

-
    -
  • * := >=0.0.0 (Any version satisfies)
  • -
  • 1.x := >=1.0.0 <2.0.0 (Matching major version)
  • -
  • 1.2.x := >=1.2.0 <1.3.0 (Matching major and minor versions)
  • -
-

A partial version range is treated as an X-Range, so the special -character is in fact optional.

-
    -
  • "" (empty string) := * := >=0.0.0
  • -
  • 1 := 1.x.x := >=1.0.0 <2.0.0
  • -
  • 1.2 := 1.2.x := >=1.2.0 <1.3.0
  • -
-

Tilde Ranges ~1.2.3 ~1.2 ~1

-

Allows patch-level changes if a minor version is specified on the -comparator. Allows minor-level changes if not.

-
    -
  • ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
  • -
  • ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
  • -
  • ~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
  • -
  • ~0.2.3 := >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
  • -
  • ~0.2 := >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
  • -
  • ~0 := >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
  • -
  • ~1.2.3-beta.2 := >=1.2.3-beta.2 <1.3.0 Note that prereleases in -the 1.2.3 version will be allowed, if they are greater than or -equal to beta.2. So, 1.2.3-beta.4 would be allowed, but -1.2.4-beta.2 would not, because it is a prerelease of a -different [major, minor, patch] tuple.
  • -
-

Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4

-

Allows changes that do not modify the left-most non-zero digit in the -[major, minor, patch] tuple. In other words, this allows patch and -minor updates for versions 1.0.0 and above, patch updates for -versions 0.X >=0.1.0, and no updates for versions 0.0.X.

-

Many authors treat a 0.x version as if the x were the major -"breaking-change" indicator.

-

Caret ranges are ideal when an author may make breaking changes -between 0.2.4 and 0.3.0 releases, which is a common practice. -However, it presumes that there will not be breaking changes between -0.2.4 and 0.2.5. It allows for changes that are presumed to be -additive (but non-breaking), according to commonly observed practices.

-
    -
  • ^1.2.3 := >=1.2.3 <2.0.0
  • -
  • ^0.2.3 := >=0.2.3 <0.3.0
  • -
  • ^0.0.3 := >=0.0.3 <0.0.4
  • -
  • ^1.2.3-beta.2 := >=1.2.3-beta.2 <2.0.0 Note that prereleases in -the 1.2.3 version will be allowed, if they are greater than or -equal to beta.2. So, 1.2.3-beta.4 would be allowed, but -1.2.4-beta.2 would not, because it is a prerelease of a -different [major, minor, patch] tuple.
  • -
  • ^0.0.3-beta := >=0.0.3-beta <0.0.4 Note that prereleases in the -0.0.3 version only will be allowed, if they are greater than or -equal to beta. So, 0.0.3-pr.2 would be allowed.
  • -
-

When parsing caret ranges, a missing patch value desugars to the -number 0, but will allow flexibility within that value, even if the -major and minor versions are both 0.

-
    -
  • ^1.2.x := >=1.2.0 <2.0.0
  • -
  • ^0.0.x := >=0.0.0 <0.1.0
  • -
  • ^0.0 := >=0.0.0 <0.1.0
  • -
-

A missing minor and patch values will desugar to zero, but also -allow flexibility within those values, even if the major version is -zero.

-
    -
  • ^1.x := >=1.0.0 <2.0.0
  • -
  • ^0.x := >=0.0.0 <1.0.0
  • -
-

Range Grammar

-

Putting all this together, here is a Backus-Naur grammar for ranges, -for the benefit of parser authors:

-
range-set  ::= range ( logical-or range ) *
-logical-or ::= ( ' ' ) * '||' ( ' ' ) *
-range      ::= hyphen | simple ( ' ' simple ) * | ''
-hyphen     ::= partial ' - ' partial
-simple     ::= primitive | partial | tilde | caret
-primitive  ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
-partial    ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
-xr         ::= 'x' | 'X' | '*' | nr
-nr         ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
-tilde      ::= '~' partial
-caret      ::= '^' partial
-qualifier  ::= ( '-' pre )? ( '+' build )?
-pre        ::= parts
-build      ::= parts
-parts      ::= part ( '.' part ) *
-part       ::= nr | [-0-9A-Za-z]+
-

Functions

-

All methods and classes take a final options object argument. All -options in this object are false by default. The options supported -are:

-
    -
  • loose Be more forgiving about not-quite-valid semver strings. -(Any resulting output will always be 100% strict compliant, of -course.) For backwards compatibility reasons, if the options -argument is a boolean value instead of an object, it is interpreted -to be the loose param.
  • -
  • includePrerelease Set to suppress the default -behavior of -excluding prerelease tagged versions from ranges unless they are -explicitly opted into.
  • -
-

Strict-mode Comparators and Ranges will be strict about the SemVer -strings that they parse.

-
    -
  • valid(v): Return the parsed version, or null if it's not valid.
  • -
  • inc(v, release): Return the version incremented by the release -type (major, premajor, minor, preminor, patch, -prepatch, or prerelease), or null if it's not valid
      -
    • premajor in one call will bump the version up to the next major -version and down to a prerelease of that major version. -preminor, and prepatch work the same way.
    • -
    • If called from a non-prerelease version, the prerelease will work the -same as prepatch. It increments the patch version, then makes a -prerelease. If the input version is already a prerelease it simply -increments it.
    • -
    -
  • -
  • prerelease(v): Returns an array of prerelease components, or null -if none exist. Example: prerelease('1.2.3-alpha.1') -> ['alpha', 1]
  • -
  • major(v): Return the major version number.
  • -
  • minor(v): Return the minor version number.
  • -
  • patch(v): Return the patch version number.
  • -
  • intersects(r1, r2, loose): Return true if the two supplied ranges -or comparators intersect.
  • -
  • parse(v): Attempt to parse a string as a semantic version, returning either -a SemVer object or null.
  • -
-

Comparison

-
    -
  • gt(v1, v2): v1 > v2
  • -
  • gte(v1, v2): v1 >= v2
  • -
  • lt(v1, v2): v1 < v2
  • -
  • lte(v1, v2): v1 <= v2
  • -
  • eq(v1, v2): v1 == v2 This is true if they're logically equivalent, -even if they're not the exact same string. You already know how to -compare strings.
  • -
  • neq(v1, v2): v1 != v2 The opposite of eq.
  • -
  • cmp(v1, comparator, v2): Pass in a comparison string, and it'll call -the corresponding function above. "===" and "!==" do simple -string comparison, but are included for completeness. Throws if an -invalid comparison string is provided.
  • -
  • compare(v1, v2): Return 0 if v1 == v2, or 1 if v1 is greater, or -1 if -v2 is greater. Sorts in ascending order if passed to Array.sort().
  • -
  • rcompare(v1, v2): The reverse of compare. Sorts an array of versions -in descending order when passed to Array.sort().
  • -
  • diff(v1, v2): Returns difference between two versions by the release type -(major, premajor, minor, preminor, patch, prepatch, or prerelease), -or null if the versions are the same.
  • -
-

Comparators

-
    -
  • intersects(comparator): Return true if the comparators intersect
  • -
-

Ranges

-
    -
  • validRange(range): Return the valid range or null if it's not valid
  • -
  • satisfies(version, range): Return true if the version satisfies the -range.
  • -
  • maxSatisfying(versions, range): Return the highest version in the list -that satisfies the range, or null if none of them do.
  • -
  • minSatisfying(versions, range): Return the lowest version in the list -that satisfies the range, or null if none of them do.
  • -
  • minVersion(range): Return the lowest version that can possibly match -the given range.
  • -
  • gtr(version, range): Return true if version is greater than all the -versions possible in the range.
  • -
  • ltr(version, range): Return true if version is less than all the -versions possible in the range.
  • -
  • outside(version, range, hilo): Return true if the version is outside -the bounds of the range in either the high or low direction. The -hilo argument must be either the string '>' or '<'. (This is -the function called by gtr and ltr.)
  • -
  • intersects(range): Return true if any of the ranges comparators intersect
  • -
-

Note that, since ranges may be non-contiguous, a version might not be -greater than a range, less than a range, or satisfy a range! For -example, the range 1.2 <1.2.9 || >2.0.0 would have a hole from 1.2.9 -until 2.0.0, so the version 1.2.10 would not be greater than the -range (because 2.0.1 satisfies, which is higher), nor less than the -range (since 1.2.8 satisfies, which is lower), and it also does not -satisfy the range.

-

If you want to know if a version satisfies or does not satisfy a -range, use the satisfies(version, range) function.

-

Coercion

-
    -
  • coerce(version): Coerces a string to semver if possible
  • -
-

This aims to provide a very forgiving translation of a non-semver string to -semver. It looks for the first digit in a string, and consumes all -remaining characters which satisfy at least a partial semver (e.g., 1, -1.2, 1.2.3) up to the max permitted length (256 characters). Longer -versions are simply truncated (4.6.3.9.2-alpha2 becomes 4.6.3). All -surrounding text is simply ignored (v3.4 replaces v3.3.1 becomes -3.4.0). Only text which lacks digits will fail coercion (version one -is not valid). The maximum length for any semver component considered for -coercion is 16 characters; longer components will be ignored -(10000000000000000.4.7.4 becomes 4.7.4). The maximum value for any -semver component is Number.MAX_SAFE_INTEGER || (2**53 - 1); higher value -components are invalid (9999999999999999.4.7.4 is likely invalid).

- -
- - - - - - - - - - - - diff --git a/deps/npm/html/docfoot.html b/deps/npm/html/docfoot.html deleted file mode 100644 index 11a67943b9b200..00000000000000 --- a/deps/npm/html/docfoot.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/deps/npm/html/dochead.html b/deps/npm/html/dochead.html deleted file mode 100644 index 26602b2b8af684..00000000000000 --- a/deps/npm/html/dochead.html +++ /dev/null @@ -1,11 +0,0 @@ - - - @NAME@ - - - - - - -
- diff --git a/deps/npm/html/favicon.ico b/deps/npm/html/favicon.ico deleted file mode 100644 index 9e0d4eef78c9c0..00000000000000 Binary files a/deps/npm/html/favicon.ico and /dev/null differ diff --git a/deps/npm/html/index.html b/deps/npm/html/index.html deleted file mode 100644 index 32dd01a34f8ee7..00000000000000 --- a/deps/npm/html/index.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - npm - JavaScript Package Manager - -

npm

- -

npm is a package manager for node. You can use it to install - and publish your node programs. It manages dependencies and does other cool stuff.

- -

Easy Zero Line Install

- -

Install Node.js
-(npm comes with it.)

- -

Because a one-line install is one too many.

- -

Fancy Install

- -
    -
  1. Get the code. -
  2. Do what the README - says to do. -
- -

There's a pretty thorough install script at -https://npmjs.org/install.sh

- -

For maximum security, make sure to thoroughly inspect every -program that you run on your computer!

- -

Other Cool Stuff

- - - - - diff --git a/deps/npm/html/static/style.css b/deps/npm/html/static/style.css deleted file mode 100644 index 7a7f6ea5df871f..00000000000000 --- a/deps/npm/html/static/style.css +++ /dev/null @@ -1,336 +0,0 @@ -/* reset */ -* { - margin:0; - padding:0; - border:none; - font-family:inherit; - font-size:inherit; - font-weight:inherit; -} -:target::before { - content:" >>> "; - position:absolute; - display:block; - opacity:0.5; - color:#f00; - margin:0 0 0 -2em; -} -abbr, acronym { - border-bottom:1px dotted #aaa; -} -kbd, code, pre { - font-family:monospace; - margin:0; - font-size:18px; - line-height:24px; - background:#eee; - outline:1px solid #ccc; -} -kbd code, kbd pre, kbd kbd, -pre code, pre pre, pre kbd, -code code, code pre, code kbd { outline: none } -.dollar::before { - content:"$ "; - display:inline; -} -p, ul, ol, dl, pre { - margin:30px 0; - line-height:30px; -} -hr { - margin:30px auto 29px; - width:66%; - height:1px; - background:#aaa; -} -pre { - display:block; -} -dd :first-child { - margin-top:0; -} - -body { - quotes:"“" "”" "‘" "’"; - width:666px; - margin:30px auto 120px; - font-family:Times New Roman, serif; - font-size:20px; - background:#fff; - line-height:30px; - color:#111; -} - -blockquote { - position:relative; - font-size:16px; - line-height:30px; - font-weight:bold; - width:85%; - margin:0 auto; -} -blockquote::before { - font-size:90px; - display:block; - position:absolute; - top:20px; - right:100%; - content:"“"; - padding-right:10px; - color:#ccc; -} -.source cite::before { - content:"— "; -} -.source { - padding-left:20%; - margin-top:30px; -} -.source cite span { - font-style:normal; -} -blockquote p { - margin-bottom:0; -} -.quote blockquote { - font-weight:normal; -} - -h1, h2, h3, h4, h5, h6, dt, #header { - font-family:serif; - font-size:20px; - font-weight:bold; -} -h2 { - background:#eee; -} -h1, h2 { - line-height:40px; -} - -i, em, cite { - font-style:italic; -} -b, strong { - font-weight:bold; -} -i, em, cite, b, strong, small { - line-height:28px; -} -small, .small, .small *, aside { - font-style:italic; - color:#669; - font-size:18px; -} -small a, .small a { - text-decoration:underline; -} -del { - text-decoration:line-through; -} -ins { - text-decoration:underline; -} -.alignright { display:block; float:right; margin-left:1em; } -.alignleft { display:block; float:left; margin-right:1em; } - -q:before, q q q:before, q q q q q:before, q q q q q q q:before { content:"“"; } -q q:before, q q q q:before, q q q q q q:before, q q q q q q q q:before { content:"‘"; } -q:after, q q q:after, q q q q q:after, q q q q q q q:after { content:"”"; } -q q:after, q q q q:after, q q q q q q:after, q q q q q q q q:after { content:"’"; } - -a { color:#00f; text-decoration:none; } -a:visited { color:#636; } -a:hover, a:active { color:#c00!important; text-decoration:underline; } - -h1 { - font-weight:bold; - background:#fff; -} -h1 a, h1 a:visited { - font-family:monospace; - font-size:60px; - color:#c00; - display:block; -} -h1 a:focus, h1 a:hover, h1 a:active { - color:#f00!important; - text-decoration:none; -} - -.navigation { - display:table; - width:100%; - margin:0 0 30px 0; - position:relative; -} -#nav-above { - margin-bottom:0; -} -.navigation .nav-previous { - display:table-cell; - text-align:left; - width:50%; -} -/* hang the » and « off into the margins */ -.navigation .nav-previous a:before, .navigation .nav-next a:after { - content: "«"; - display:block; - height:30px; - margin-bottom:-30px; - text-decoration:none; - margin-left:-15px; -} -.navigation .nav-next a:after { - content: "»"; - text-align:right; - margin-left:0; - margin-top:-30px; - margin-right:-15px; -} - - -.navigation .nav-next { - display:table-cell; - text-align:right; - width:50%; -} -.navigation a { - display:block; - width:100%; - height:100%; -} - -input, button, textarea { - border:0; - line-height:30px; -} -textarea { - height:300px; -} -input { - height:30px; - line-height:30px; -} -input.submit, input#submit, input.button, button, input[type=submit] { - cursor:hand; cursor:pointer; - outline:1px solid #ccc; -} - -#wrapper { - margin-bottom:90px; - position:relative; - z-index:1; - *zoom:1; - background:#fff; -} -#wrapper:after { - display:block; - content:"."; - visibility:hidden; - width:0; - height:0; - clear:both; -} - -.sidebar .xoxo > li { - float:left; - width:50%; -} -.sidebar li { - list-style:none; -} -.sidebar #elsewhere { - margin-left:-10%; - margin-right:-10%; -} -.sidebar #rss-links, .sidebar #twitter-feeds { - float:right; - clear:right; - width:20%; -} -.sidebar #comment { - clear:both; - float:none; - width:100%; -} -.sidebar #search { - clear:both; - float:none; - width:100%; -} -.sidebar #search h2 { - margin-left:40%; -} -.sidebar #search #s { - width:90%; - float:left; -} -.sidebar #search #searchsubmit { - width:10%; - float:right; -} -.sidebar * { - font-size:15px; - line-height:30px; -} - -#footer, #footer * { - text-align:center; - font-size:16px; - color:#ccc; - font-style:italic; - word-spacing:1em; - margin-top:0; -} - -#toc { - position:absolute; - top:0; - right:0; - padding:40px 0 40px 20px; - margin:0; - width:200px; - opacity:0.2; - z-index:-1; -} -#toc:hover { - opacity:1; - background:#fff; - z-index:999; -} -#toc ul { - padding:0; - margin:0; -} -#toc, #toc li { - list-style-type:none; - font-size:15px; - line-height:15px; -} -#toc li { - padding:0 0 0 10px; -} -#toc li a { - position:relative; - display:block; -} - -table#npmlogo { - line-height:10px; - width:180px; - margin:0 auto; -} - -@media print { - a[href] { - color:inherit; - } - a[href]:after { - white-space:nowrap; - content:" " attr(href); - } - a[href^=\#], .navigation { - display:none; - } -} diff --git a/deps/npm/html/static/toc.js b/deps/npm/html/static/toc.js deleted file mode 100644 index 7551e47efdf48e..00000000000000 --- a/deps/npm/html/static/toc.js +++ /dev/null @@ -1,29 +0,0 @@ -;(function () { - var wrapper = document.getElementById('wrapper') - var els = Array.prototype.slice.call(wrapper.getElementsByTagName('*'), 0) - .filter(function (el) { - return el.parentNode === wrapper && - el.tagName.match(/H[1-6]/) && - el.id - }) - var l = 2 - var toc = document.createElement('ul') - toc.innerHTML = els.map(function (el) { - var i = el.tagName.charAt(1) - var out = '' - while (i > l) { - out += '
    ' - l++ - } - while (i < l) { - out += '
' - l-- - } - out += '
  • ' + - (el.innerText || el.text || el.innerHTML) + - '' - return out - }).join('\n') - toc.id = 'toc' - document.body.appendChild(toc) -})() diff --git a/deps/npm/lib/config/cmd-list.js b/deps/npm/lib/config/cmd-list.js index fa4390fcdcba77..d9d0d85b7d520f 100644 --- a/deps/npm/lib/config/cmd-list.js +++ b/deps/npm/lib/config/cmd-list.js @@ -91,6 +91,7 @@ var cmdList = [ 'token', 'profile', 'audit', + 'fund', 'org', 'help', diff --git a/deps/npm/lib/config/defaults.js b/deps/npm/lib/config/defaults.js index 57d373df1e10c3..e07da3aaf97f4b 100644 --- a/deps/npm/lib/config/defaults.js +++ b/deps/npm/lib/config/defaults.js @@ -143,6 +143,8 @@ Object.defineProperty(exports, 'defaults', {get: function () { force: false, 'format-package-lock': true, + fund: true, + 'fetch-retries': 2, 'fetch-retry-factor': 10, 'fetch-retry-mintimeout': 10000, @@ -284,6 +286,7 @@ exports.types = { editor: String, 'engine-strict': Boolean, force: Boolean, + fund: Boolean, 'format-package-lock': Boolean, 'fetch-retries': Number, 'fetch-retry-factor': Number, diff --git a/deps/npm/lib/fund.js b/deps/npm/lib/fund.js new file mode 100644 index 00000000000000..4981e461596c07 --- /dev/null +++ b/deps/npm/lib/fund.js @@ -0,0 +1,202 @@ +'use strict' + +const path = require('path') + +const archy = require('archy') +const figgyPudding = require('figgy-pudding') +const readPackageTree = require('read-package-tree') + +const npm = require('./npm.js') +const npmConfig = require('./config/figgy-config.js') +const fetchPackageMetadata = require('./fetch-package-metadata.js') +const computeMetadata = require('./install/deps.js').computeMetadata +const readShrinkwrap = require('./install/read-shrinkwrap.js') +const mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js') +const output = require('./utils/output.js') +const openUrl = require('./utils/open-url.js') +const { getFundingInfo, validFundingUrl } = require('./utils/funding.js') + +const FundConfig = figgyPudding({ + browser: {}, // used by ./utils/open-url + global: {}, + json: {}, + unicode: {} +}) + +module.exports = fundCmd + +const usage = require('./utils/usage') +fundCmd.usage = usage( + 'fund', + 'npm fund [--json]', + 'npm fund [--browser] [[<@scope>/]' +) + +fundCmd.completion = function (opts, cb) { + const argv = opts.conf.argv.remain + switch (argv[2]) { + case 'fund': + return cb(null, []) + default: + return cb(new Error(argv[2] + ' not recognized')) + } +} + +function printJSON (fundingInfo) { + return JSON.stringify(fundingInfo, null, 2) +} + +// the human-printable version does some special things that turned out to +// be very verbose but hopefully not hard to follow: we stack up items +// that have a shared url/type and make sure they're printed at the highest +// level possible, in that process they also carry their dependencies along +// with them, moving those up in the visual tree +function printHuman (fundingInfo, opts) { + // mapping logic that keeps track of seen items in order to be able + // to push all other items from the same type/url in the same place + const seen = new Map() + + function seenKey ({ type, url } = {}) { + return url ? String(type) + String(url) : null + } + + function setStackedItem (funding, result) { + const key = seenKey(funding) + if (key && !seen.has(key)) seen.set(key, result) + } + + function retrieveStackedItem (funding) { + const key = seenKey(funding) + if (key && seen.has(key)) return seen.get(key) + } + + // --- + + const getFundingItems = (fundingItems) => + Object.keys(fundingItems || {}).map((fundingItemName) => { + // first-level loop, prepare the pretty-printed formatted data + const fundingItem = fundingItems[fundingItemName] + const { version, funding } = fundingItem + const { type, url } = funding || {} + + const printableVersion = version ? `@${version}` : '' + const printableType = type && { label: `type: ${funding.type}` } + const printableUrl = url && { label: `url: ${funding.url}` } + const result = { + fundingItem, + label: fundingItemName + printableVersion, + nodes: [] + } + + if (printableType) { + result.nodes.push(printableType) + } + + if (printableUrl) { + result.nodes.push(printableUrl) + } + + setStackedItem(funding, result) + + return result + }).reduce((res, result) => { + // recurse and exclude nodes that are going to be stacked together + const { fundingItem } = result + const { dependencies, funding } = fundingItem + const items = getFundingItems(dependencies) + const stackedResult = retrieveStackedItem(funding) + items.forEach(i => result.nodes.push(i)) + + if (stackedResult && stackedResult !== result) { + stackedResult.label += `, ${result.label}` + items.forEach(i => stackedResult.nodes.push(i)) + return res + } + + res.push(result) + + return res + }, []) + + const [ result ] = getFundingItems({ + [fundingInfo.name]: { + dependencies: fundingInfo.dependencies, + funding: fundingInfo.funding, + version: fundingInfo.version + } + }) + + return archy(result, '', { unicode: opts.unicode }) +} + +function openFundingUrl (packageName, cb) { + function getUrlAndOpen (packageMetadata) { + const { funding } = packageMetadata + const { type, url } = funding || {} + const noFundingError = + new Error(`No funding method available for: ${packageName}`) + noFundingError.code = 'ENOFUND' + const typePrefix = type ? `${type} funding` : 'Funding' + const msg = `${typePrefix} available at the following URL` + + if (validFundingUrl(funding)) { + openUrl(url, msg, cb) + } else { + throw noFundingError + } + } + + fetchPackageMetadata( + packageName, + '.', + { fullMetadata: true }, + function (err, packageMetadata) { + if (err) return cb(err) + getUrlAndOpen(packageMetadata) + } + ) +} + +function fundCmd (args, cb) { + const opts = FundConfig(npmConfig()) + const dir = path.resolve(npm.dir, '..') + const packageName = args[0] + + if (opts.global) { + const err = new Error('`npm fund` does not support globals') + err.code = 'EFUNDGLOBAL' + throw err + } + + if (packageName) { + openFundingUrl(packageName, cb) + return + } + + readPackageTree(dir, function (err, tree) { + if (err) { + process.exitCode = 1 + return cb(err) + } + + readShrinkwrap.andInflate(tree, function () { + const fundingInfo = getFundingInfo( + mutateIntoLogicalTree.asReadInstalled( + computeMetadata(tree) + ) + ) + + const print = opts.json + ? printJSON + : printHuman + + output( + print( + fundingInfo, + opts + ) + ) + cb(err, tree) + }) + }) +} diff --git a/deps/npm/lib/help.js b/deps/npm/lib/help.js index 3f70f2dc1f84c7..61f1f3f94cc66c 100644 --- a/deps/npm/lib/help.js +++ b/deps/npm/lib/help.js @@ -63,7 +63,7 @@ function help (args, cb) { // legacy if (section === 'global') section = 'folders' - else if (section === 'json') section = 'package.json' + else if (section.match(/.*json/)) section = section.replace('.json', '-json') // find either /section.n or /npm-section.n // The glob is used in the glob. The regexp is used much @@ -140,24 +140,21 @@ function viewMan (man, cb) { function htmlMan (man) { var sect = +man.match(/([0-9]+)$/)[1] - var f = path.basename(man).replace(/([0-9]+)$/, 'html') + var f = path.basename(man).replace(/[.]([0-9]+)$/, '') switch (sect) { case 1: - sect = 'cli' - break - case 3: - sect = 'api' + sect = 'cli-commands' break case 5: - sect = 'files' + sect = 'configuring-npm' break case 7: - sect = 'misc' + sect = 'using-npm' break default: throw new Error('invalid man section: ' + sect) } - return path.resolve(__dirname, '..', 'html', 'doc', sect, f) + return path.resolve(__dirname, '..', 'docs', 'public', sect, f, 'index.html') } function npmUsage (valid, cb) { diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 8cc6d16bdd1698..378ada7b05c061 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -26,6 +26,7 @@ install.usage = usage( '\nnpm install [<@scope>/]@' + '\nnpm install [<@scope>/]@' + '\nnpm install [<@scope>/]@' + + '\nnpm install @npm:' + '\nnpm install ' + '\nnpm install ' + '\nnpm install ' + @@ -138,6 +139,10 @@ var validateArgs = require('./install/validate-args.js') var saveRequested = require('./install/save.js').saveRequested var saveShrinkwrap = require('./install/save.js').saveShrinkwrap var audit = require('./install/audit.js') +var { + getPrintFundingReport, + getPrintFundingReportJSON +} = require('./install/fund.js') var getSaveType = require('./install/save.js').getSaveType var doSerialActions = require('./install/actions.js').doSerial var doReverseSerialActions = require('./install/actions.js').doReverseSerial @@ -240,6 +245,7 @@ function Installer (where, dryrun, args, opts) { this.saveOnlyLock = opts.saveOnlyLock this.global = opts.global != null ? opts.global : this.where === path.resolve(npm.globalDir, '..') this.audit = npm.config.get('audit') && !this.global + this.fund = npm.config.get('fund') && !this.global this.started = Date.now() } Installer.prototype = {} @@ -872,7 +878,6 @@ Installer.prototype.printInstalledForHuman = function (diffs, auditResult) { report += ' in ' + ((Date.now() - this.started) / 1000) + 's' output(report) - return auditResult && audit.printInstallReport(auditResult) function packages (num) { return num + ' package' + (num > 1 ? 's' : '') @@ -894,9 +899,27 @@ Installer.prototype.printInstalledForHuman = function (diffs, auditResult) { if (argument.url) returned += ' (' + argument.email + ')' return returned } + + const { fund, idealTree } = this + const printFundingReport = getPrintFundingReport({ + fund, + idealTree + }) + if (printFundingReport.length) { + output(printFundingReport) + } + + if (auditResult) { + return audit.printInstallReport(auditResult) + } } Installer.prototype.printInstalledForJSON = function (diffs, auditResult) { + const { fund, idealTree } = this + const printFundingReport = getPrintFundingReportJSON({ + fund, + idealTree + }) var result = { added: [], removed: [], @@ -905,6 +928,7 @@ Installer.prototype.printInstalledForJSON = function (diffs, auditResult) { failed: [], warnings: [], audit: auditResult, + funding: printFundingReport, elapsed: Date.now() - this.started } var self = this diff --git a/deps/npm/lib/install/fund.js b/deps/npm/lib/install/fund.js new file mode 100644 index 00000000000000..809c05b33878b2 --- /dev/null +++ b/deps/npm/lib/install/fund.js @@ -0,0 +1,48 @@ +'use strict' + +const { EOL } = require('os') + +const computeMetadata = require('./deps.js').computeMetadata +const mutateIntoLogicalTree = require('./mutate-into-logical-tree.js') +var { getFundingInfo } = require('../utils/funding.js') + +exports.getPrintFundingReport = getPrintFundingReport +exports.getPrintFundingReportJSON = getPrintFundingReportJSON + +function getFundingResult ({ fund, idealTree }) { + if (fund) { + const fundingInfoTree = + mutateIntoLogicalTree.asReadInstalled( + computeMetadata(idealTree) + ) + const fundResult = getFundingInfo(fundingInfoTree, { countOnly: true }) + return fundResult + } else { + return {} + } +} + +function getPrintFundingReport ({ fund, idealTree }, opts) { + const fundResult = getFundingResult({ fund, idealTree }) + const { length } = fundResult || {} + const { json } = opts || {} + + function padding (msg) { + return json ? '' : (EOL + msg) + } + + function packageQuantity (amount) { + return `package${amount > 1 ? 's are' : ' is'}` + } + + if (!length) return '' + + return padding('') + length + ' ' + + packageQuantity(length) + + ' looking for funding' + + padding(' run `npm fund` for details\n') +} + +function getPrintFundingReportJSON ({ fund, idealTree }) { + return getPrintFundingReport({ fund, idealTree }, { json: true }) +} diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js index e06ee5eb30e209..3e8d3e4f1f3edb 100644 --- a/deps/npm/lib/unbuild.js +++ b/deps/npm/lib/unbuild.js @@ -78,8 +78,11 @@ function rmBins (pkg, folder, parent, top, cb) { const binRoot = top ? npm.bin : path.resolve(parent, '.bin') asyncMap(Object.keys(pkg.bin), function (b, cb) { if (process.platform === 'win32') { - chain([ [gentlyRm, path.resolve(binRoot, b) + '.cmd', true, folder], - [gentlyRm, path.resolve(binRoot, b), true, folder] ], cb) + chain([ + [gentlyRm, path.resolve(binRoot, b) + '.ps1', true, folder], + [gentlyRm, path.resolve(binRoot, b) + '.cmd', true, folder], + [gentlyRm, path.resolve(binRoot, b), true, folder] + ], cb) } else { gentlyRm(path.resolve(binRoot, b), true, folder, cb) } diff --git a/deps/npm/lib/utils/funding.js b/deps/npm/lib/utils/funding.js new file mode 100644 index 00000000000000..dce40147642c5f --- /dev/null +++ b/deps/npm/lib/utils/funding.js @@ -0,0 +1,151 @@ +'use strict' + +const URL = require('url').URL + +exports.getFundingInfo = getFundingInfo +exports.validFundingUrl = validFundingUrl + +// Is the value of a `funding` property of a `package.json` +// a valid type+url for `npm fund` to display? +function validFundingUrl (funding) { + if (!funding) return false + + try { + var parsed = new URL(funding.url || funding) + } catch (error) { + return false + } + + if ( + parsed.protocol !== 'https:' && + parsed.protocol !== 'http:' + ) return false + + return Boolean(parsed.host) +} + +function getFundingInfo (idealTree, opts) { + let length = 0 + const seen = new Set() + const { countOnly } = opts || {} + const empty = () => Object.create(null) + const _trailingDependencies = Symbol('trailingDependencies') + + function tracked (name, version) { + const key = String(name) + String(version) + if (seen.has(key)) { + return true + } + seen.add(key) + } + + function retrieveDependencies (dependencies) { + const trailing = dependencies[_trailingDependencies] + + if (trailing) { + return Object.assign( + empty(), + dependencies, + trailing + ) + } + + return dependencies + } + + function hasDependencies (dependencies) { + return dependencies && ( + Object.keys(dependencies).length || + dependencies[_trailingDependencies] + ) + } + + function retrieveFunding (funding) { + return typeof funding === 'string' + ? { + url: funding + } + : funding + } + + function getFundingDependencies (tree) { + const deps = tree && tree.dependencies + if (!deps) return empty() + + // broken into two steps to make sure items appearance + // within top levels takes precedence over nested ones + return (Object.keys(deps)).map((key) => { + const dep = deps[key] + const { name, funding, version } = dep + + const fundingItem = {} + + // avoids duplicated items within the funding tree + if (tracked(name, version)) return empty() + + if (version) { + fundingItem.version = version + } + + if (funding && validFundingUrl(funding)) { + fundingItem.funding = retrieveFunding(funding) + length++ + } + + return { + dep, + fundingItem + } + }).reduce((res, { dep, fundingItem }, i) => { + if (!fundingItem) return res + + // recurse + const dependencies = dep.dependencies && + Object.keys(dep.dependencies).length > 0 && + getFundingDependencies(dep) + + // if we're only counting items there's no need + // to add all the data to the resulting object + if (countOnly) return null + + if (hasDependencies(dependencies)) { + fundingItem.dependencies = retrieveDependencies(dependencies) + } + + if (fundingItem.funding) { + res[dep.name] = fundingItem + } else if (fundingItem.dependencies) { + res[_trailingDependencies] = + Object.assign( + empty(), + res[_trailingDependencies], + fundingItem.dependencies + ) + } + + return res + }, empty()) + } + + const idealTreeDependencies = getFundingDependencies(idealTree) + const result = { + length + } + + if (!countOnly) { + result.name = idealTree.name || idealTree.path + + if (idealTree && idealTree.version) { + result.version = idealTree.version + } + + if (idealTree && idealTree.funding) { + result.funding = retrieveFunding(idealTree.funding) + } + + result.dependencies = + retrieveDependencies(idealTreeDependencies) + } + + return result +} diff --git a/deps/npm/lib/utils/open-url.js b/deps/npm/lib/utils/open-url.js index 7a48d2e868959b..e1ed2b3fab76d5 100644 --- a/deps/npm/lib/utils/open-url.js +++ b/deps/npm/lib/utils/open-url.js @@ -5,9 +5,28 @@ const opener = require('opener') // attempt to open URL in web-browser, print address otherwise: module.exports = function open (url, errMsg, cb, browser = npm.config.get('browser')) { - opener(url, { command: npm.config.get('browser') }, (er) => { + function printAlternateMsg () { + const json = npm.config.get('json') + const alternateMsg = json + ? JSON.stringify({ + title: errMsg, + url + }, null, 2) + : `${errMsg}:\n\n${url}` + + output(alternateMsg) + } + + const skipBrowser = process.argv.indexOf('--no-browser') > -1 + + if (skipBrowser) { + printAlternateMsg() + return cb() + } + + opener(url, { command: browser }, (er) => { if (er && er.code === 'ENOENT') { - output(`${errMsg}:\n\n${url}`) + printAlternateMsg() return cb() } else { return cb(er) diff --git a/deps/npm/lib/utils/unsupported.js b/deps/npm/lib/utils/unsupported.js index aaae8c44266534..71a304030e2424 100644 --- a/deps/npm/lib/utils/unsupported.js +++ b/deps/npm/lib/utils/unsupported.js @@ -9,7 +9,7 @@ var supportedNode = [ {ver: '12', min: '12.0.0'}, {ver: '13', min: '13.0.0'} ] -var knownBroken = '<6.0.0' +var knownBroken = '<6.2.0 || 9.0 - 9.2' var checkVersion = exports.checkVersion = function (version) { var versionNoPrerelease = version.replace(/-.*$/, '') diff --git a/deps/npm/man/man1/npm-README.1 b/deps/npm/man/man1/npm-README.1 index 1a344948609691..c2535cc28a1a51 100644 --- a/deps/npm/man/man1/npm-README.1 +++ b/deps/npm/man/man1/npm-README.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "October 2019" "" "" +.TH "NPM" "1" "November 2019" "" "" .SH "NAME" \fBnpm\fR \- a JavaScript package manager .P @@ -165,11 +165,8 @@ doubt tell you to put the output in a gist or email\. .SH SEE ALSO .RS 0 .IP \(bu 2 -npm help npm +npm(1) .IP \(bu 2 -npm help help -.IP \(bu 2 -npm help 7 index +npm\-help(1) .RE - diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index 16dcab951913e7..ac6274bacdb066 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -1,7 +1,7 @@ -.TH "NPM\-ACCESS" "1" "October 2019" "" "" +.TH "NPM\-ACCESS" "1" "November 2019" "" "" .SH "NAME" \fBnpm-access\fR \- Set access level on published packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -19,7 +19,7 @@ npm access ls\-collaborators [ []] npm access edit [] .fi .RE -.SH DESCRIPTION +.SS Description .P Used to set access controls on private packages\. .P @@ -53,7 +53,7 @@ edit: Set the access privileges for a package at once using \fB$EDITOR\fP\|\. .RE -.SH DETAILS +.SS Details .P \fBnpm access\fP always operates directly on the current registry, configurable from the command line using \fB\-\-registry=\fP\|\. @@ -84,7 +84,7 @@ with an HTTP 402 status code (logically enough), unless you use \fB\-\-access=public\fP\|\. .P Management of teams and team memberships is done with the \fBnpm team\fP command\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 \fBlibnpmaccess\fP \fIhttps://npm\.im/libnpmaccess\fR @@ -93,9 +93,8 @@ npm help team .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 config +npm help config .IP \(bu 2 -npm help 7 registry +npm help registry .RE - diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index 5ea0f27ee44900..89cda8029790e5 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,7 +1,7 @@ -.TH "NPM\-ADDUSER" "1" "October 2019" "" "" +.TH "NPM\-ADDUSER" "1" "November 2019" "" "" .SH "NAME" \fBnpm-adduser\fR \- Add a registry user account -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,11 +10,11 @@ npm adduser [\-\-registry=url] [\-\-scope=@orgname] [\-\-always\-auth] [\-\-auth aliases: login, add\-user .fi .RE -.SH DESCRIPTION +.SS Description .P Create or verify a user named \fB\fP in the specified registry, and save the credentials to the \fB\|\.npmrc\fP file\. If no registry is specified, -the default registry will be used (see npm help 7 \fBnpm\-config\fP)\. +the default registry will be used (see npm help \fBconfig\fP)\. .P The username, password, and email are read in from prompts\. .P @@ -28,25 +28,25 @@ the username, password and email address must all match with your existing record\. .P \fBnpm login\fP is an alias to \fBadduser\fP and behaves exactly the same way\. -.SH CONFIGURATION +.SS Configuration .SS registry .P Default: https://registry\.npmjs\.org/ .P The base URL of the npm package registry\. If \fBscope\fP is also specified, this registry will only be used for packages with that scope\. \fBscope\fP defaults -to the scope of the project directory you're currently in, if any\. See npm help 7 \fBnpm\-scope\fP\|\. +to the scope of the project directory you're currently in, if any\. See npm help \fBscope\fP\|\. .SS scope .P Default: none .P If specified, the user and login credentials given will be associated -with the specified scope\. See npm help 7 \fBnpm\-scope\fP\|\. You can use both at the same time, +with the specified scope\. See npm help \fBscope\fP\|\. You can use both at the same time, e\.g\. .P .RS 2 .nf -npm adduser \-\-registry=http://myregistry\.example\.com \-\-scope=@myco + npm adduser \-\-registry=http://myregistry\.example\.com \-\-scope=@myco .fi .RE .P @@ -62,16 +62,14 @@ registries\. Can be used with \fB\-\-registry\fP and / or \fB\-\-scope\fP, e\.g\ .P .RS 2 .nf -npm adduser \-\-registry=http://private\-registry\.example\.com \-\-always\-auth + npm adduser \-\-registry=http://private\-registry\.example\.com \-\-always\-auth .fi .RE .P This will ensure that all requests to that registry (including for tarballs) include an authorization header\. This setting may be necessary for use with private registries where metadata and package tarballs are stored on hosts with -different hostnames\. See \fBalways\-auth\fP in npm help 7 \fBnpm\-config\fP for more details on -always\-auth\. Registry\-specific configuration of \fBalways\-auth\fP takes precedence -over any global configuration\. +different hostnames\. See \fBalways\-auth\fP in npm help \fBconfig\fP for more details on always\-auth\. Registry\-specific configuration of \fBalways\-auth\fP takes precedence over any global configuration\. .SS auth\-type .RS 0 .IP \(bu 2 @@ -84,20 +82,17 @@ Type: \fB\|'legacy'\fP, \fB\|'sso'\fP, \fB\|'saml'\fP, \fB\|'oauth'\fP What authentication strategy to use with \fBadduser\fP/\fBlogin\fP\|\. Some npm registries (for example, npmE) might support alternative auth strategies besides classic username/password entry in legacy npm\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help owner .IP \(bu 2 npm help whoami .RE - diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1 index 4f5d8a69806190..50e61c60d1748e 100644 --- a/deps/npm/man/man1/npm-audit.1 +++ b/deps/npm/man/man1/npm-audit.1 @@ -1,7 +1,7 @@ -.TH "NPM\-AUDIT" "1" "October 2019" "" "" +.TH "NPM\-AUDIT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-audit\fR \- Run a security audit -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,7 +11,7 @@ npm audit fix [\-\-force|\-\-package\-lock\-only|\-\-dry\-run] common options: [\-\-production] [\-\-only=(dev|prod)] .fi .RE -.SH EXAMPLES +.SS Examples .P Scan your project for vulnerabilities and automatically install any compatible updates to vulnerable dependencies: @@ -99,7 +99,7 @@ Fail an audit only if the results include a vulnerability with a level of modera $ npm audit \-\-audit\-level=moderate .fi .RE -.SH DESCRIPTION +.SS Description .P The audit command submits a description of the dependencies configured in your project to your default registry and asks for a report of known @@ -119,7 +119,7 @@ is found\. It may be useful in CI environments to include the \fB\-\-audit\-leve to specify the minimum vulnerability level that will cause the command to fail\. This option does not filter the report output, it simply changes the command's failure threshold\. -.SH CONTENT SUBMITTED +.SS Content Submitted .RS 0 .IP \(bu 2 npm_version @@ -133,7 +133,7 @@ node_env A scrubbed version of your package\-lock\.json or npm\-shrinkwrap\.json .RE -.SS SCRUBBING +.SS Scrubbing .P In order to ensure that potentially sensitive information is not included in the audit data bundle, some dependencies may have their names (and sometimes @@ -155,19 +155,19 @@ All local directory and tarball dependencies have their names and specifiers scr The non\-reversible identifiers are a sha256 of a session\-specific UUID and the value being replaced, ensuring a consistent value within the payload that is different between runs\. -.SH EXIT CODE +.SS Exit Code .P The \fBnpm audit\fP command will exit with a 0 exit code if no vulnerabilities were found\. .P If vulnerabilities were found the exit code will depend on the \fBaudit\-level\fP configuration setting\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install .IP \(bu 2 -npm help 5 package\-locks +npm help package\-locks .IP \(bu 2 -npm help 7 config +npm help config .RE diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1 index 3ffed54b371207..8a925ee708ee5d 100644 --- a/deps/npm/man/man1/npm-bin.1 +++ b/deps/npm/man/man1/npm-bin.1 @@ -1,30 +1,27 @@ -.TH "NPM\-BIN" "1" "October 2019" "" "" +.TH "NPM\-BIN" "1" "November 2019" "" "" .SH "NAME" \fBnpm-bin\fR \- Display npm bin folder -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm bin [\-g|\-\-global] .fi .RE -.SH DESCRIPTION +.SS Description .P Print the folder where npm will install executables\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help prefix .IP \(bu 2 npm help root .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index ad72639c7f7986..953d83bc78ac68 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,7 +1,7 @@ -.TH "NPM\-BUGS" "1" "October 2019" "" "" +.TH "NPM\-BUGS" "1" "November 2019" "" "" .SH "NAME" \fBnpm-bugs\fR \- Bugs for a package in a web browser maybe -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,13 +10,13 @@ npm bugs [] aliases: issues .fi .RE -.SH DESCRIPTION +.SS Description .P This command tries to guess at the likely location of a package's bug tracker URL, and then tries to open it using the \fB\-\-browser\fP config param\. If no package name is provided, it will search for a \fBpackage\.json\fP in the current folder and use the \fBname\fP property\. -.SH CONFIGURATION +.SS Configuration .SS browser .RS 0 .IP \(bu 2 @@ -37,7 +37,7 @@ Type: url .RE .P The base URL of the npm package registry\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help docs @@ -46,15 +46,12 @@ npm help view .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config +npm help npmrc .IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 5 package\.json +npm help package\.json .RE - diff --git a/deps/npm/man/man1/npm-build.1 b/deps/npm/man/man1/npm-build.1 index 7f0cd77aaa4c14..7ea03625729cd2 100644 --- a/deps/npm/man/man1/npm-build.1 +++ b/deps/npm/man/man1/npm-build.1 @@ -1,7 +1,7 @@ -.TH "NPM\-BUILD" "1" "October 2019" "" "" +.TH "NPM\-BUILD" "1" "November 2019" "" "" .SH "NAME" \fBnpm-build\fR \- Build a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -14,7 +14,7 @@ npm build [] A folder containing a \fBpackage\.json\fP file in its root\. .RE -.SH DESCRIPTION +.SS Description .P This is the plumbing command called by \fBnpm link\fP and \fBnpm install\fP\|\. .P @@ -23,19 +23,18 @@ directly, run: .P .RS 2 .nf -npm run\-script build + npm run\-script build .fi .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install .IP \(bu 2 npm help link .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .RE - diff --git a/deps/npm/man/man1/npm-bundle.1 b/deps/npm/man/man1/npm-bundle.1 index c1044226e60832..8c911b2d570f3e 100644 --- a/deps/npm/man/man1/npm-bundle.1 +++ b/deps/npm/man/man1/npm-bundle.1 @@ -1,17 +1,16 @@ -.TH "NPM\-BUNDLE" "1" "October 2019" "" "" +.TH "NPM\-BUNDLE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-bundle\fR \- REMOVED -.SH DESCRIPTION +.SS Description .P The \fBnpm bundle\fP command has been removed in 1\.0, for the simple reason that it is no longer necessary, as the default behavior is now to install packages into the local space\. .P Just use \fBnpm install\fP now to do what \fBnpm bundle\fP used to do\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install .RE - diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index 3e5f7ad2e97175..5740233250a513 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,7 +1,7 @@ -.TH "NPM\-CACHE" "1" "October 2019" "" "" +.TH "NPM\-CACHE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-cache\fR \- Manipulates packages cache -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -16,7 +16,7 @@ aliases: npm cache clear, npm cache rm npm cache verify .fi .RE -.SH DESCRIPTION +.SS Description .P Used to add, list, or clean the npm cache folder\. .RS 0 @@ -34,7 +34,7 @@ Verify the contents of the cache folder, garbage collecting any unneeded data, and verifying the integrity of the cache index and all cached data\. .RE -.SH DETAILS +.SS Details .P npm stores cache data in an opaque directory within the configured \fBcache\fP, named \fB_cacache\fP\|\. This directory is a \fBcacache\fP\-based content\-addressable cache @@ -55,7 +55,7 @@ directly\. .P npm will not remove data by itself: the cache will grow as new packages are installed\. -.SH A NOTE ABOUT THE CACHE'S DESIGN +.SS A note about the cache's design .P The npm cache is strictly a cache: it should not be relied upon as a persistent and reliable data store for package data\. npm makes no guarantee that a @@ -65,22 +65,20 @@ if it does return data, that data will be exactly the data that was inserted\. .P To run an offline verification of existing cache contents, use \fBnpm cache verify\fP\|\. -.SH CONFIGURATION +.SS Configuration .SS cache .P Default: \fB~/\.npm\fP on Posix, or \fB%AppData%/npm\-cache\fP on Windows\. .P The root cache folder\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help install .IP \(bu 2 @@ -93,4 +91,3 @@ https://npm\.im/cacache https://npm\.im/pacote .RE - diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1 index b0bf8dbeed3319..adad70234939f4 100644 --- a/deps/npm/man/man1/npm-ci.1 +++ b/deps/npm/man/man1/npm-ci.1 @@ -1,14 +1,14 @@ -.TH "NPM\-CI" "1" "October 2019" "" "" +.TH "NPM\-CI" "1" "November 2019" "" "" .SH "NAME" \fBnpm-ci\fR \- Install a project with a clean slate -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm ci .fi .RE -.SH EXAMPLE +.SS Example .P Make sure you have a package\-lock and an up\-to\-date install: .P @@ -43,9 +43,9 @@ cache: \- "$HOME/\.npm" .fi .RE -.SH DESCRIPTION +.SS Description .P -This command is similar to npm help \fBnpm\-install\fP, except it's meant to be used in +This command is similar to npm help \fBinstall\fP, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment \-\- or any situation where you want to make sure you're doing a clean install of your dependencies\. It can be significantly faster than a regular npm @@ -67,11 +67,11 @@ If a \fBnode_modules\fP is already present, it will be automatically removed bef It will never write to \fBpackage\.json\fP or any of the package\-locks: installs are essentially frozen\. .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install .IP \(bu 2 -npm help 5 package\-locks +npm help package\-locks .RE diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index e864a09741e53f..ce6654a0c93a63 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,14 +1,14 @@ -.TH "NPM\-COMPLETION" "1" "October 2019" "" "" +.TH "NPM\-COMPLETION" "1" "November 2019" "" "" .SH "NAME" \fBnpm-completion\fR \- Tab Completion for npm -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf source <(npm completion) .fi .RE -.SH DESCRIPTION +.SS Description .P Enables tab\-completion in all npm commands\. .P @@ -25,19 +25,18 @@ npm completion >> ~/\.zshrc .RE .P You may of course also pipe the output of \fBnpm completion\fP to a file -such as \fB/usr/local/etc/bash_completion\.d/npm\fP or -\fB/etc/bash_completion\.d/npm\fP if you have a system that will read +such as \fB/usr/local/etc/bash_completion\.d/npm\fP or +\fB/etc/bash_completion\.d/npm\fP if you have a system that will read that file for you\. .P When \fBCOMP_CWORD\fP, \fBCOMP_LINE\fP, and \fBCOMP_POINT\fP are defined in the environment, \fBnpm completion\fP acts in "plumbing mode", and outputs completions based on the arguments\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 developers +npm help developers .IP \(bu 2 npm help npm .RE - diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index 4c6b59a163d577..423f7f258b67d0 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,7 +1,7 @@ -.TH "NPM\-CONFIG" "1" "October 2019" "" "" +.TH "NPM\-CONFIG" "1" "November 2019" "" "" .SH "NAME" \fBnpm-config\fR \- Manage the npm configuration files -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -16,19 +16,19 @@ npm set [\-g|\-\-global] aliases: c .fi .RE -.SH DESCRIPTION +.SS Description .P npm gets its config settings from the command line, environment variables, \fBnpmrc\fP files, and in some cases, the \fBpackage\.json\fP file\. .P -See npm help 5 npmrc for more information about the npmrc files\. +See npm help npmrc for more information about the npmrc files\. .P -See npm help 7 \fBnpm\-config\fP for a more thorough discussion of the mechanisms +See npm help config for a more thorough discussion of the mechanisms involved\. .P The \fBnpm config\fP command can be used to update and edit the contents of the user and global npmrc files\. -.SH Sub\-commands +.SS Sub\-commands .P Config supports the following sub\-commands: .SS set @@ -80,18 +80,17 @@ npm config edit .P Opens the config file in an editor\. Use the \fB\-\-global\fP flag to edit the global config\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 -npm help 7 config +npm help config .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help npm .RE - diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index 6104c08692ffd7..f4b0e6fd56c281 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,7 +1,7 @@ -.TH "NPM\-DEDUPE" "1" "October 2019" "" "" +.TH "NPM\-DEDUPE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-dedupe\fR \- Reduce duplication -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,7 +11,7 @@ npm ddp aliases: find\-dupes, ddp .fi .RE -.SH DESCRIPTION +.SS Description .P Searches the local package tree and attempts to simplify the overall structure by moving dependencies further up the tree, where they can @@ -29,7 +29,7 @@ a .fi .RE .P -In this case, npm help \fBnpm\-dedupe\fP will transform the tree to: +In this case, \fBnpm dedupe\fP will transform the tree to: .P .RS 2 .nf @@ -58,7 +58,7 @@ Modules .P Note that this operation transforms the dependency tree, but will never result in new modules being installed\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help ls @@ -68,4 +68,3 @@ npm help update npm help install .RE - diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index 9fd7e1582ca78c..cfbe9dcf2be5f6 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,19 +1,19 @@ -.TH "NPM\-DEPRECATE" "1" "October 2019" "" "" +.TH "NPM\-DEPRECATE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-deprecate\fR \- Deprecate a version of a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm deprecate [@] .fi .RE -.SH DESCRIPTION +.SS Description .P This command will update the npm registry entry for a package, providing a deprecation warning to all who attempt to install it\. .P -It works on version ranges \fIhttps://semver\.npmjs\.com/\fR as well as specific +It works on version ranges \fIhttps://semver\.npmjs\.com/\fR as well as specific versions, so you can do something like this: .P .RS 2 @@ -25,15 +25,14 @@ npm deprecate my\-thing@"< 0\.2\.3" "critical bug fixed in v0\.2\.3" Note that you must be the package owner to deprecate something\. See the \fBowner\fP and \fBadduser\fP help topics\. .P -To un\-deprecate a package, specify an empty string (\fB""\fP) for the \fBmessage\fP -argument\. Note that you must use double quotes with no space between them to +To un\-deprecate a package, specify an empty string (\fB""\fP) for the \fBmessage\fP +argument\. Note that you must use double quotes with no space between them to format an empty string\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 registry +npm help registry .RE - diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index 9880de7cdea042..211c02dbac9a24 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -1,7 +1,7 @@ -.TH "NPM\-DIST\-TAG" "1" "October 2019" "" "" +.TH "NPM\-DIST\-TAG" "1" "November 2019" "" "" .SH "NAME" \fBnpm-dist-tag\fR \- Modify package distribution tags -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -12,7 +12,7 @@ npm dist\-tag ls [] aliases: dist\-tags .fi .RE -.SH DESCRIPTION +.SS Description .P Add, remove, and enumerate distribution tags on a package: .RS 0 @@ -28,8 +28,7 @@ Clear a tag that is no longer in use from the package\. .IP \(bu 2 ls: Show all of the dist\-tags for a package, defaulting to the package in -the current prefix\. -This is the default action if none is specified\. +the current prefix\. This is the default action if none is specified\. .RE .P @@ -57,7 +56,7 @@ Publishing a package sets the \fBlatest\fP tag to the published version unless t .P By default, \fBnpm install \fP (without any \fB@\fP or \fB@\fP specifier) installs the \fBlatest\fP tag\. -.SH PURPOSE +.SS Purpose .P Tags can be used to provide an alias instead of version numbers\. .P @@ -75,7 +74,7 @@ The \fBnext\fP tag is used by some projects to identify the upcoming version\. .P By default, other than \fBlatest\fP, no tag has any special significance to npm itself\. -.SH CAVEATS +.SS Caveats .P This command used to be known as \fBnpm tag\fP, which only created new tags, and so had a different syntax\. @@ -89,7 +88,7 @@ example, \fBv1\.4\fP cannot be used as a tag, because it is interpreted by semve .P The simplest way to avoid semver problems with tags is to use tags that do not begin with a number or the letter \fBv\fP\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help publish @@ -98,13 +97,10 @@ npm help install .IP \(bu 2 npm help dedupe .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index 49ab61870bebf6..7adbedd9a0f019 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,7 +1,7 @@ -.TH "NPM\-DOCS" "1" "October 2019" "" "" +.TH "NPM\-DOCS" "1" "November 2019" "" "" .SH "NAME" \fBnpm-docs\fR \- Docs for a package in a web browser maybe -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,14 +11,14 @@ npm home [ [ \.\.\.]] npm home \. .fi .RE -.SH DESCRIPTION +.SS Description .P This command tries to guess at the likely location of a package's documentation URL, and then tries to open it using the \fB\-\-browser\fP config param\. You can pass multiple package names at once\. If no package name is provided, it will search for a \fBpackage\.json\fP in the current folder and use the \fBname\fP property\. -.SH CONFIGURATION +.SS Configuration .SS browser .RS 0 .IP \(bu 2 @@ -39,22 +39,19 @@ Type: url .RE .P The base URL of the npm package registry\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help view .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config +npm help npmrc .IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 5 package\.json +npm help package\.json .RE - diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 45a569b192690d..52ccfb0c4cb52c 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -1,14 +1,14 @@ -.TH "NPM\-DOCTOR" "1" "October 2019" "" "" +.TH "NPM\-DOCTOR" "1" "November 2019" "" "" .SH "NAME" \fBnpm-doctor\fR \- Check your environments -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm doctor .fi .RE -.SH DESCRIPTION +.SS Description .P \fBnpm doctor\fP runs a set of checks to ensure that your npm installation has what it needs to manage your JavaScript packages\. npm is mostly a standalone tool, but it does @@ -101,7 +101,7 @@ in your local cache (you can see where that cache is located with \fBnpm config get cache\fP, and see what's in that cache with \fBnpm cache ls\fP – probably more than you were expecting!)\. In the event that there are corrupt packages in your cache, you should probably run \fBnpm cache clean\fP and reset the cache\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help bugs diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index 01cf30c809f3ba..36abc611f88c6a 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,19 +1,19 @@ -.TH "NPM\-EDIT" "1" "October 2019" "" "" +.TH "NPM\-EDIT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-edit\fR \- Edit an installed package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm edit [/\.\.\.] .fi .RE -.SH DESCRIPTION +.SS Description .P Selects a (sub)dependency in the current working directory and opens the package folder in the default editor (or whatever you've configured as the npm \fBeditor\fP config \-\- see -npm help 7 \fBnpm\-config\fP\|\.) +\fBnpm\-config\fP \fInpm\-config)\.\fR .P After it has been edited, the package is rebuilt so as to pick up any changes in compiled packages\. @@ -21,7 +21,7 @@ changes in compiled packages\. For instance, you can do \fBnpm install connect\fP to install connect into your package, and then \fBnpm edit connect\fP to make a few changes to your locally installed copy\. -.SH CONFIGURATION +.SS Configuration .SS editor .RS 0 .IP \(bu 2 @@ -33,10 +33,10 @@ Type: path .RE .P The command to run for \fBnpm edit\fP or \fBnpm config edit\fP\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help explore .IP \(bu 2 @@ -44,9 +44,6 @@ npm help install .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index fed639636e9078..5b27fcf9b76bef 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,14 +1,14 @@ -.TH "NPM\-EXPLORE" "1" "October 2019" "" "" +.TH "NPM\-EXPLORE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-explore\fR \- Browse an installed package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm explore [ \-\- ] .fi .RE -.SH DESCRIPTION +.SS Description .P Spawn a subshell in the directory of the installed package specified\. .P @@ -26,7 +26,7 @@ npm explore some\-dependency \-\- git pull origin master .P Note that the package is \fInot\fR automatically rebuilt afterwards, so be sure to use \fBnpm rebuild \fP if you make any changes\. -.SH CONFIGURATION +.SS Configuration .SS shell .RS 0 .IP \(bu 2 @@ -38,10 +38,10 @@ Type: path .RE .P The shell to run for the \fBnpm explore\fP command\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help edit .IP \(bu 2 @@ -52,4 +52,3 @@ npm help build npm help install .RE - diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1 new file mode 100644 index 00000000000000..83280693f2794b --- /dev/null +++ b/deps/npm/man/man1/npm-fund.1 @@ -0,0 +1,66 @@ +.TH "NPM\-FUND" "1" "November 2019" "" "" +.SH "NAME" +\fBnpm-fund\fR \- Retrieve funding information +.SS Synopsis +.P +.RS 2 +.nf + npm fund [] +.fi +.RE +.SS Description +.P +This command retrieves information on how to fund the dependencies of +a given project\. If no package name is provided, it will list all +dependencies that are looking for funding in a tree\-structure in which +are listed the type of funding and the url to visit\. If a package name +is provided then it tries to open its funding url using the \fB\-\-browser\fP +config param\. +.P +The list will avoid duplicated entries and will stack all packages +that share the same type/url as a single entry\. Given this nature the +list is not going to have the same shape of the output from \fBnpm ls\fP\|\. +.SS Configuration +.SS browser +.RS 0 +.IP \(bu 2 +Default: OS X: \fB"open"\fP, Windows: \fB"start"\fP, Others: \fB"xdg\-open"\fP +.IP \(bu 2 +Type: String + +.RE +.P +The browser that is called by the \fBnpm fund\fP command to open websites\. +.SS json +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Show information in JSON format\. +.SS unicode +.RS 0 +.IP \(bu 2 +Type: Boolean +.IP \(bu 2 +Default: true + +.RE +.P +Whether to represent the tree structure using unicode characters\. +Set it to \fBfalse\fP in order to use all\-ansi output\. +.SH See Also +.RS 0 +.IP \(bu 2 +npm help docs +.IP \(bu 2 +npm help config +.IP \(bu 2 +npm help install +.IP \(bu 2 +npm help ls + +.RE diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index 2bbfc4505136ea..01400fe1528523 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,14 +1,14 @@ -.TH "NPM\-HELP\-SEARCH" "1" "October 2019" "" "" +.TH "NPM\-HELP\-SEARCH" "1" "November 2019" "" "" .SH "NAME" \fBnpm-help-search\fR \- Search npm help documentation -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm help\-search .fi .RE -.SH DESCRIPTION +.SS Description .P This command will search the npm markdown documentation files for the terms provided, and then list the results, sorted by relevance\. @@ -18,7 +18,7 @@ If only one result is found, then it will show that help topic\. If the argument to \fBnpm help\fP is not a known help topic, then it will call \fBhelp\-search\fP\|\. It is rarely if ever necessary to call this command directly\. -.SH CONFIGURATION +.SS Configuration .SS long .RS 0 .IP \(bu 2 @@ -32,7 +32,7 @@ If true, the "long" flag will cause help\-search to output context around where the terms were found in the documentation\. .P If false, then help\-search will just list out the help topics found\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help npm @@ -40,4 +40,3 @@ npm help npm npm help help .RE - diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index c492a9c578bc6b..f5331a6ac72e83 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,14 +1,14 @@ -.TH "NPM\-HELP" "1" "October 2019" "" "" +.TH "NPM\-HELP" "1" "November 2019" "" "" .SH "NAME" \fBnpm-help\fR \- Get help on npm -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm help [] .fi .RE -.SH DESCRIPTION +.SS Description .P If supplied a topic, then show the appropriate documentation page\. .P @@ -16,7 +16,7 @@ If the topic does not exist, or if multiple terms are provided, then run the \fBhelp\-search\fP command to find a match\. Note that, if \fBhelp\-search\fP finds a single subject, then it will run \fBhelp\fP on that topic, so unique matches are equivalent to specifying a topic name\. -.SH CONFIGURATION +.SS Configuration .SS viewer .RS 0 .IP \(bu 2 @@ -29,26 +29,19 @@ Type: path The program to use to view help content\. .P Set to \fB"browser"\fP to view html help content in the default web browser\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help npm .IP \(bu 2 -README -.IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help help\-search -.IP \(bu 2 -npm help 7 index .RE - diff --git a/deps/npm/man/man1/npm-hook.1 b/deps/npm/man/man1/npm-hook.1 index a58d0f32644cfb..521f44f01ad2a8 100644 --- a/deps/npm/man/man1/npm-hook.1 +++ b/deps/npm/man/man1/npm-hook.1 @@ -1,7 +1,7 @@ -.TH "NPM\-HOOK" "1" "October 2019" "" "" +.TH "NPM\-HOOK" "1" "November 2019" "" "" .SH "NAME" \fBnpm-hook\fR \- Manage registry hooks -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,7 +11,7 @@ npm hook update [secret] npm hook rm .fi .RE -.SH EXAMPLE +.SS Example .P Add a hook to watch a package for changes: .P @@ -68,10 +68,9 @@ Remove a hook: $ npm hook rm id\-deadbeef .fi .RE -.SH DESCRIPTION +.SS Description .P -Allows you to manage npm -hooks \fIhttps://blog\.npmjs\.org/post/145260155635/introducing\-hooks\-get\-notifications\-of\-npm\fR, +Allows you to manage npm hooks \fIhttps://blog\.npmjs\.org/post/145260155635/introducing\-hooks\-get\-notifications\-of\-npm\fR, including adding, removing, listing, and updating\. .P Hooks allow you to configure URL endpoints that will be notified whenever a @@ -89,7 +88,7 @@ that particular hook\. .P The shared secret will be sent along to the URL endpoint so you can verify the request came from your own configured hook\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 "Introducing Hooks" blog post \fIhttps://blog\.npmjs\.org/post/145260155635/introducing\-hooks\-get\-notifications\-of\-npm\fR diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index 60dfe546683da4..d0bf42286e182e 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,7 +1,7 @@ -.TH "NPM\-INIT" "1" "October 2019" "" "" +.TH "NPM\-INIT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-init\fR \- create a package\.json file -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm init <@scope> (same as `npx <@scope>/create`) npm init [<@scope>/] (same as `npx [<@scope>/]create\-`) .fi .RE -.SH EXAMPLES +.SS Examples .P Create a new React\-based project using \fBcreate\-react\-app\fP \fIhttps://npm\.im/create\-react\-app\fR: .P @@ -46,12 +46,12 @@ Generate it without having it ask any questions: $ npm init \-y .fi .RE -.SH DESCRIPTION +.SS Description .P \fBnpm init \fP can be used to set up a new or existing npm package\. .P \fBinitializer\fP in this case is an npm package named \fBcreate\-\fP, which -will be installed by npm help \fBnpx\fP \fIhttps://npm\.im/npx\fR, and then have its main bin +will be installed by \fBnpx\fP \fIhttps://npm\.im/npx\fR, and then have its main bin executed \-\- presumably creating or updating \fBpackage\.json\fP and running any other initialization\-related operations\. .P @@ -76,16 +76,15 @@ existing fields, dependencies, and options selected\. It is strictly additive, s it will keep any fields and values that were already set\. You can also use \fB\-y\fP/\fB\-\-yes\fP to skip the questionnaire altogether\. If you pass \fB\-\-scope\fP, it will create a scoped package\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 https://github\.com/isaacs/init\-package\-json .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help version .IP \(bu 2 -npm help 7 scope +npm help scope .RE - diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1 index 8c1c780d49525f..8ac6535034ea1c 100644 --- a/deps/npm/man/man1/npm-install-ci-test.1 +++ b/deps/npm/man/man1/npm-install-ci-test.1 @@ -1,7 +1,7 @@ -.TH "NPM" "" "October 2019" "" "" +.TH "NPM" "" "November 2019" "" "" .SH "NAME" \fBnpm\fR -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,10 +10,10 @@ npm install\-ci\-test alias: npm cit .fi .RE -.SH DESCRIPTION +.SS Description .P This command runs an \fBnpm ci\fP followed immediately by an \fBnpm test\fP\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help ci diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index 6bf6aa325a98c1..470d20f3574047 100644 --- a/deps/npm/man/man1/npm-install-test.1 +++ b/deps/npm/man/man1/npm-install-test.1 @@ -1,7 +1,7 @@ -.TH "NPM" "" "October 2019" "" "" +.TH "NPM" "" "November 2019" "" "" .SH "NAME" \fBnpm\fR -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -18,11 +18,11 @@ alias: npm it common options: [\-\-save|\-\-save\-dev|\-\-save\-optional] [\-\-save\-exact] [\-\-dry\-run] .fi .RE -.SH DESCRIPTION +.SS Description .P This command runs an \fBnpm install\fP followed immediately by an \fBnpm test\fP\|\. It takes exactly the same arguments as \fBnpm install\fP\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install @@ -30,4 +30,3 @@ npm help install npm help test .RE - diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index 41d26b62176d43..c3ab9dc7740435 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,7 +1,7 @@ -.TH "NPM\-INSTALL" "1" "October 2019" "" "" +.TH "NPM\-INSTALL" "1" "November 2019" "" "" .SH "NAME" \fBnpm-install\fR \- Install a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,6 +10,7 @@ npm install [<@scope>/] npm install [<@scope>/]@ npm install [<@scope>/]@ npm install [<@scope>/]@ +npm install @npm: npm install :/ npm install npm install @@ -20,25 +21,25 @@ aliases: npm i, npm add common options: [\-P|\-\-save\-prod|\-D|\-\-save\-dev|\-O|\-\-save\-optional] [\-E|\-\-save\-exact] [\-B|\-\-save\-bundle] [\-\-no\-save] [\-\-dry\-run] .fi .RE -.SH DESCRIPTION +.SS Description .P This command installs a package, and any packages that it depends on\. If the package has a package\-lock or shrinkwrap file, the installation of dependencies will be driven by that, with an \fBnpm\-shrinkwrap\.json\fP taking precedence if both -files exist\. See npm help 5 package\-lock\.json and npm help shrinkwrap\. +files exist\. See npm help package\-lock\.json and npm help \fBshrinkwrap\fP\|\. .P A \fBpackage\fP is: .RS 0 .IP \(bu 2 -a) a folder containing a program described by a npm help 5 \fBpackage\.json\fP file +a) a folder containing a program described by a npm help \fBpackage\.json\fP file .IP \(bu 2 b) a gzipped tarball containing (a) .IP \(bu 2 c) a url that resolves to (b) .IP \(bu 2 -d) a \fB@\fP that is published on the registry (see npm help 7 \fBnpm\-registry\fP) with (c) +d) a \fB@\fP that is published on the registry (see npm help \fBregistry\fP) with (c) .IP \(bu 2 -e) a \fB@\fP (see npm help \fBnpm\-dist\-tag\fP) that points to (d) +e) a \fB@\fP (see npm help \fBdist\-tag\fP) that points to (d) .IP \(bu 2 f) a \fB\fP that has a "latest" tag satisfying (e) .IP \(bu 2 @@ -58,10 +59,12 @@ after packing it up into a tarball (b)\. it installs the current package context (ie, the current working directory) as a global package\. By default, \fBnpm install\fP will install all modules listed as dependencies - in npm help 5 \fBpackage\.json\fP\|\. + in npm help \fBpackage\.json\fP\|\. With the \fB\-\-production\fP flag (or when the \fBNODE_ENV\fP environment variable is set to \fBproduction\fP), npm will not install modules listed in - \fBdevDependencies\fP\|\. + \fBdevDependencies\fP\|\. To install all modules listed in both \fBdependencies\fP + and \fBdevDependencies\fP when \fBNODE_ENV\fP environment variable is set to \fBproduction\fP, + you can use \fB\-\-production=false\fP\|\. .QP NOTE: The \fB\-\-production\fP flag has no particular meaning when adding a dependency to a project\. @@ -110,7 +113,7 @@ npm install \./package\.tgz .IP \(bu 2 \fBnpm install [<@scope>/]\fP: Do a \fB@\fP install, where \fB\fP is the "tag" config\. (See - npm help 7 \fBnpm\-config\fP\|\. The config's default value is \fBlatest\fP\|\.) + npm help \fBconfig\fP\|\. The config's default value is \fBlatest\fP\|\.) In most cases, this will install the version of the modules tagged as \fBlatest\fP on the npm registry\. Example: @@ -120,44 +123,66 @@ npm install \./package\.tgz npm install sax .fi .RE - \fBnpm install\fP saves any specified packages into \fBdependencies\fP by default\. - Additionally, you can control where and how they get saved with some - additional flags: -.RS .IP \(bu 2 -\fB\-P, \-\-save\-prod\fP: Package will appear in your \fBdependencies\fP\|\. This is the +\fBnpm install @npm:\fP: + Install a package under a custom alias\. Allows multiple versions of + a same\-name package side\-by\-side, more convenient import names for + packages with otherwise long ones and using git forks replacements + or forked npm packages as replacements\. Aliasing works only on your + project and does not rename packages in transitive dependencies\. + Aliases should follow the naming conventions stated in + \fBvalidate\-npm\-package\-name\fP \fIhttps://www\.npmjs\.com/package/validate\-npm\-package\-name#naming\-rules\fR\|\. + Examples: .P .RS 2 .nf - default unless `\-D` or `\-O` are present\. + npm install my\-react@npm:react + npm install jquery2@npm:jquery@2 + npm install jquery3@npm:jquery@3 + npm install npa@npm:npm\-package\-arg .fi .RE -.IP \(bu 2 -\fB\-D, \-\-save\-dev\fP: Package will appear in your \fBdevDependencies\fP\|\. -.IP \(bu 2 -\fB\-O, \-\-save\-optional\fP: Package will appear in your \fBoptionalDependencies\fP\|\. -.IP \(bu 2 -\fB\-\-no\-save\fP: Prevents saving to \fBdependencies\fP\|\. + +.RE +.P +.RS 2 +.nf +`npm install` saves any specified packages into `dependencies` by default\. +Additionally, you can control where and how they get saved with some +additional flags: + +* `\-P, \-\-save\-prod`: Package will appear in your `dependencies`\. This is the + default unless `\-D` or `\-O` are present\. + +* `\-D, \-\-save\-dev`: Package will appear in your `devDependencies`\. + +* `\-O, \-\-save\-optional`: Package will appear in your `optionalDependencies`\. + +* `\-\-no\-save`: Prevents saving to `dependencies`\. + When using any of the above options to save dependencies to your package\.json, there are two additional, optional flags: -.IP \(bu 2 -\fB\-E, \-\-save\-exact\fP: Saved dependencies will be configured with an -exact version rather than using npm's default semver range -operator\. -.IP \(bu 2 -\fB\-B, \-\-save\-bundle\fP: Saved dependencies will also be added to your \fBbundleDependencies\fP list\. -Further, if you have an \fBnpm\-shrinkwrap\.json\fP or \fBpackage\-lock\.json\fP then it + +* `\-E, \-\-save\-exact`: Saved dependencies will be configured with an + exact version rather than using npm's default semver range + operator\. + +* `\-B, \-\-save\-bundle`: Saved dependencies will also be added to your `bundleDependencies` list\. + +Further, if you have an `npm\-shrinkwrap\.json` or `package\-lock\.json` then it will be updated as well\. -\fB\fP is optional\. The package will be downloaded from the registry + +`` is optional\. The package will be downloaded from the registry associated with the specified scope\. If no registry is associated with -the given scope the default registry is assumed\. See npm help 7 \fBnpm\-scope\fP\|\. +the given scope the default registry is assumed\. See npm help `scope`\. + Note: if you do not include the @\-symbol on your scope name, npm will interpret this as a GitHub repository instead, see below\. Scopes names must also be followed by a slash\. + Examples: -.P -.RS 2 -.nf + +```bash npm install sax npm install githubname/reponame npm install @myorg/privatepackage @@ -165,15 +190,8 @@ npm install node\-tap \-\-save\-dev npm install dtrace\-provider \-\-save\-optional npm install readable\-stream \-\-save\-exact npm install ansi\-regex \-\-save\-bundle -.fi -.RE +``` -.RE - -.RE -.P -.RS 2 -.nf **Note**: If there is a file or folder named `` in the current working directory, then it will try to install that, and only try to fetch the package by name if it is not valid\. @@ -189,8 +207,8 @@ fetch the package by name if it is not valid\. .P .RS 2 .nf - npm install sax@latest - npm install @myorg/mypackage@latest + npm install sax@latest + npm install @myorg/mypackage@latest .fi .RE .IP \(bu 2 @@ -201,22 +219,22 @@ fetch the package by name if it is not valid\. .P .RS 2 .nf - npm install sax@0\.1\.1 - npm install @myorg/privatepackage@1\.5\.0 + npm install sax@0\.1\.1 + npm install @myorg/privatepackage@1\.5\.0 .fi .RE .IP \(bu 2 \fBnpm install [<@scope>/]@\fP: Install a version of the package matching the specified version range\. This - will follow the same rules for resolving dependencies described in npm help 5 \fBpackage\.json\fP\|\. + will follow the same rules for resolving dependencies described in npm help \fBpackage\.json\fP\|\. Note that most version ranges must be put in quotes so that your shell will treat it as a single argument\. Example: .P .RS 2 .nf - npm install sax@">=0\.1\.0 <0\.2\.0" - npm install @myorg/privatepackage@">=0\.1\.0 <0\.2\.0" + npm install sax@">=0\.1\.0 <0\.2\.0" + npm install @myorg/privatepackage@">=0\.1\.0 <0\.2\.0" .fi .RE .IP \(bu 2 @@ -292,8 +310,8 @@ GIT_SSH_COMMAND='ssh \-i ~/\.ssh/custom_ident' npm install git+ssh://git@github\ .P .RS 2 .nf - npm install mygithubuser/myproject - npm install github:mygithubuser/myproject + npm install mygithubuser/myproject + npm install github:mygithubuser/myproject .fi .RE .IP \(bu 2 @@ -308,7 +326,7 @@ GIT_SSH_COMMAND='ssh \-i ~/\.ssh/custom_ident' npm install git+ssh://git@github\ .P .RS 2 .nf - npm install gist:101a11beef + npm install gist:101a11beef .fi .RE .IP \(bu 2 @@ -328,7 +346,7 @@ GIT_SSH_COMMAND='ssh \-i ~/\.ssh/custom_ident' npm install git+ssh://git@github\ .P .RS 2 .nf - npm install bitbucket:mybitbucketuser/myproject + npm install bitbucket:mybitbucketuser/myproject .fi .RE .IP \(bu 2 @@ -348,8 +366,8 @@ GIT_SSH_COMMAND='ssh \-i ~/\.ssh/custom_ident' npm install git+ssh://git@github\ .P .RS 2 .nf - npm install gitlab:mygitlabuser/myproject - npm install gitlab:myusr/myproj#semver:^5\.0 + npm install gitlab:mygitlabuser/myproject + npm install gitlab:myusr/myproj#semver:^5\.0 .fi .RE @@ -383,8 +401,12 @@ npm install sax \-\-force .fi .RE .P +The \fB\-\-no\-fund\fP argument will hide the message displayed at the end of each +install that acknowledges the number of dependencies looking for funding\. +See \fBnpm\-fund(1)\fP +.P The \fB\-g\fP or \fB\-\-global\fP argument will cause npm to install the package globally -rather than locally\. See npm help 5 \fBnpm\-folders\fP\|\. +rather than locally\. See npm help folders\. .P The \fB\-\-global\-style\fP argument will cause npm to install the package into your local \fBnode_modules\fP folder with the same layout it uses with the @@ -393,7 +415,7 @@ global \fBnode_modules\fP folder\. Only your direct dependencies will show in \fBnode_modules\fP folders\. This obviously will eliminate some deduping\. .P The \fB\-\-ignore\-scripts\fP argument will cause npm to not execute any -scripts defined in the package\.json\. See npm help 7 \fBnpm\-scripts\fP\|\. +scripts defined in the package\.json\. See npm help \fBscripts\fP\|\. .P The \fB\-\-legacy\-bundling\fP argument will cause npm to install the package such that versions of npm prior to 1\.4, such as the one included with node 0\.8, @@ -422,11 +444,11 @@ The \fB\-\-only={prod[uction]|dev[elopment]}\fP argument will cause either only \fBdevDependencies\fP or only non\-\fBdevDependencies\fP to be installed regardless of the \fBNODE_ENV\fP\|\. .P The \fB\-\-no\-audit\fP argument can be used to disable sending of audit reports to -the configured registries\. See npm help \fBnpm\-audit\fP for details on what is sent\. +the configured registries\. See \fBnpm\-audit\fP \fInpm\-audit\fR for details on what is sent\. .P -See npm help 7 \fBnpm\-config\fP\|\. Many of the configuration params have some +See npm help \fBconfig\fP\|\. Many of the configuration params have some effect on installation, since that's most of what npm does\. -.SH ALGORITHM +.SS Algorithm .P To install a package, npm uses the following algorithm: .P @@ -478,8 +500,7 @@ privately for itself\. This algorithm is deterministic, but different trees may be produced if two dependencies are requested for installation in a different order\. .P -See npm help 5 folders for a more detailed description of the specific -folder structures that npm creates\. +See npm help folders for a more detailed description of the specific folder structures that npm creates\. .SS Limitations of npm's Install Algorithm .P npm will refuse to install any package with an identical name to the @@ -508,30 +529,30 @@ To avoid this situation, npm flat\-out refuses to install any folder ancestors\. A more correct, but more complex, solution would be to symlink the existing version into the new location\. If this ever affects a real use\-case, it will be investigated\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help update .IP \(bu 2 npm help audit .IP \(bu 2 +npm help fund +.IP \(bu 2 npm help link .IP \(bu 2 npm help rebuild .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help build .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config +npm help npmrc .IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help dist\-tag .IP \(bu 2 @@ -539,7 +560,6 @@ npm help uninstall .IP \(bu 2 npm help shrinkwrap .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .RE - diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index 1d0d230914c2a3..3485c817455caf 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,7 +1,7 @@ -.TH "NPM\-LINK" "1" "October 2019" "" "" +.TH "NPM\-LINK" "1" "November 2019" "" "" .SH "NAME" \fBnpm-link\fR \- Symlink a package folder -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,13 +11,13 @@ npm link [<@scope>/][@] alias: npm ln .fi .RE -.SH DESCRIPTION +.SS Description .P Package linking is a two\-step process\. .P First, \fBnpm link\fP in a package folder will create a symlink in the global folder \fB{prefix}/lib/node_modules/\fP that links to the package where the \fBnpm -link\fP command was executed\. (see npm help 7 \fBnpm\-config\fP for the value of \fBprefix\fP)\. It +link\fP command was executed\. (see \fBnpm\-config\fP \fInpm\-config\fR for the value of \fBprefix\fP)\. It will also link any bins in the package to \fB{prefix}/bin/{name}\fP\|\. .P Next, in some other location, \fBnpm link package\-name\fP will create a @@ -27,7 +27,7 @@ of the current folder\. Note that \fBpackage\-name\fP is taken from \fBpackage\.json\fP, not from directory name\. .P -The package name can be optionally prefixed with a scope\. See npm help 7 \fBnpm\-scope\fP\|\. +The package name can be optionally prefixed with a scope\. See npm help \fBscope\fP\|\. The scope must be preceded by an @\-symbol and followed by a slash\. .P When creating tarballs for \fBnpm publish\fP, the linked packages are @@ -40,10 +40,10 @@ For example: .P .RS 2 .nf -cd ~/projects/node\-redis # go into the package directory -npm link # creates global link -cd ~/projects/node\-bloggy # go into some other package directory\. -npm link redis # link\-install the package + cd ~/projects/node\-redis # go into the package directory + npm link # creates global link + cd ~/projects/node\-bloggy # go into some other package directory\. + npm link redis # link\-install the package .fi .RE .P @@ -76,30 +76,26 @@ installation target into your project's \fBnode_modules\fP folder\. Note that in this case, you are referring to the directory name, \fBnode\-redis\fP, rather than the package name \fBredis\fP\|\. .P -If your linked package is scoped (see npm help 7 \fBnpm\-scope\fP) your link command must -include that scope, e\.g\. +If your linked package is scoped (see npm help \fBscope\fP) your link command must include that scope, e\.g\. .P .RS 2 .nf npm link @myorg/privatepackage .fi .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 developers +npm help developers .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help install +npm help npm\- nstall .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index 5de250d38d6aaa..997668379c100a 100644 --- a/deps/npm/man/man1/npm-logout.1 +++ b/deps/npm/man/man1/npm-logout.1 @@ -1,14 +1,14 @@ -.TH "NPM\-LOGOUT" "1" "October 2019" "" "" +.TH "NPM\-LOGOUT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-logout\fR \- Log out of the registry -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm logout [\-\-registry=] [\-\-scope=<@scope>] .fi .RE -.SH DESCRIPTION +.SS Description .P When logged into a registry that supports token\-based authentication, tell the server to end this token's session\. This will invalidate the token everywhere @@ -20,7 +20,7 @@ the current environment\. .P If \fB\-\-scope\fP is provided, this will find the credentials for the registry connected to that scope, if set\. -.SH CONFIGURATION +.SS Configuration .SS registry .P Default: https://registry\.npmjs\.org/ @@ -31,27 +31,22 @@ it takes precedence\. .P Default: The scope of your current project, if any, otherwise none\. .P -If specified, you will be logged out of the specified scope\. See npm help 7 \fBnpm\-scope\fP\|\. +If specified, you will be logged out of the specified scope\. See npm help \fBscope\fP\|\. .P .RS 2 .nf npm logout \-\-scope=@myco .fi .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help adduser .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 npm help whoami .RE - diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 9baeecc886dc4e..c6d035446ff2cc 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,7 +1,7 @@ -.TH "NPM\-LS" "1" "October 2019" "" "" +.TH "NPM\-LS" "1" "November 2019" "" "" .SH "NAME" \fBnpm-ls\fR \- List installed packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm ls [[<@scope>/] \.\.\.] aliases: list, la, ll .fi .RE -.SH DESCRIPTION +.SS Description .P This command will print to stdout all the versions of packages that are installed, as well as their dependencies, in a tree\-structure\. @@ -22,9 +22,9 @@ For example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf -npm@6.12.1 /path/to/npm -└─┬ init\-package\-json@0\.0\.4 - └── promzard@0\.1\.5 + npm@6\.13\.1 /path/to/npm + └─┬ init\-package\-json@0\.0\.4 + └── promzard@0\.1\.5 .fi .RE .P @@ -38,7 +38,7 @@ The tree shown is the logical dependency tree, based on package dependencies, not the physical layout of your node_modules folder\. .P When run as \fBll\fP or \fBla\fP, it shows extended information by default\. -.SH CONFIGURATION +.SS Configuration .SS json .RS 0 .IP \(bu 2 @@ -128,16 +128,25 @@ Default: false .RE .P Display only dependencies which are linked -.SH SEE ALSO +.SS unicode .RS 0 .IP \(bu 2 -npm help config +Type: Boolean .IP \(bu 2 -npm help 7 config +Default: true + +.RE +.P +Whether to represent the tree structure using unicode characters\. +Set it to false in order to use all\-ansi output\. +.SS See Also +.RS 0 +.IP \(bu 2 +npm help config .IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help install .IP \(bu 2 @@ -150,4 +159,3 @@ npm help outdated npm help update .RE - diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1 index 2dc41214e3f8c8..d3e7cb74f5bc30 100644 --- a/deps/npm/man/man1/npm-org.1 +++ b/deps/npm/man/man1/npm-org.1 @@ -1,7 +1,7 @@ -.TH "NPM\-ORG" "1" "October 2019" "" "" +.TH "NPM\-ORG" "1" "November 2019" "" "" .SH "NAME" \fBnpm-org\fR \- Manage orgs -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm org rm npm org ls [] .fi .RE -.SH EXAMPLE +.SS Example .P Add a new developer to an org: .P @@ -59,12 +59,12 @@ See what role a user has in an org: $ npm org ls my\-org @mx\-santos .fi .RE -.SH DESCRIPTION +.SS Description .P You can use the \fBnpm org\fP commands to manage and view users of an organization\. It supports adding and removing users, changing their roles, listing them, and finding specific ones and their roles\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 Documentation on npm Orgs \fIhttps://docs\.npmjs\.com/orgs/\fR diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index 7154ae46a7c1c0..681b457d8d611c 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,14 +1,14 @@ -.TH "NPM\-OUTDATED" "1" "October 2019" "" "" +.TH "NPM\-OUTDATED" "1" "November 2019" "" "" .SH "NAME" \fBnpm-outdated\fR \- Check for outdated packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm outdated [[<@scope>/] \.\.\.] .fi .RE -.SH DESCRIPTION +.SS Description .P This command will check the registry to see if any (or, specific) installed packages are currently outdated\. @@ -25,7 +25,7 @@ you're running \fBnpm outdated \-\-global\fP, or the package isn't included in Running \fBnpm publish\fP with no special configuration will publish the package with a dist\-tag of \fBlatest\fP\|\. This may or may not be the maximum version of the package, or the most\-recently published version of the package, depending -on how the package's developer manages the latest npm help dist\-tag\. +on how the package's developer manages the latest dist\-tag \fInpm\-dist\-tag\fR\|\. .IP \(bu 2 \fBlocation\fP is where in the dependency tree the package is located\. Note that \fBnpm outdated\fP defaults to a depth of 0, so unless you override that, you'll @@ -90,7 +90,7 @@ will install whatever's tagged as \fBlatest\fP\|\. running \fBnpm update\fP will bring it up to spec\. .RE -.SH CONFIGURATION +.SS Configuration .SS json .RS 0 .IP \(bu 2 @@ -142,16 +142,15 @@ Type: Int .RE .P Max depth for checking dependency tree\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help update .IP \(bu 2 npm help dist\-tag .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 -npm help 5 folders +npm help folders .RE - diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index 38b602d1d7bd3a..343fcc3ea3f67e 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,7 +1,7 @@ -.TH "NPM\-OWNER" "1" "October 2019" "" "" +.TH "NPM\-OWNER" "1" "November 2019" "" "" .SH "NAME" \fBnpm-owner\fR \- Manage package owners -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -12,7 +12,7 @@ npm owner ls [<@scope>/] aliases: author .fi .RE -.SH DESCRIPTION +.SS Description .P Manage ownership of published packages\. .RS 0 @@ -38,16 +38,15 @@ that is not implemented at this time\. If you have two\-factor authentication enabled with \fBauth\-and\-writes\fP then you'll need to include an otp on the command line when changing ownership with \fB\-\-otp\fP\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help adduser .IP \(bu 2 -npm help 7 disputes +npm help disputes .RE - diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index fb7a8ce3b9f0ab..9b8feaaa67f864 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,14 +1,14 @@ -.TH "NPM\-PACK" "1" "October 2019" "" "" +.TH "NPM\-PACK" "1" "November 2019" "" "" .SH "NAME" \fBnpm-pack\fR \- Create a tarball from a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm pack [[<@scope>/]\.\.\.] [\-\-dry\-run] .fi .RE -.SH DESCRIPTION +.SS Description .P For anything that's installable (that is, a package folder, tarball, tarball url, name@tag, name@version, name, or scoped name), this @@ -23,7 +23,7 @@ If no arguments are supplied, then npm packs the current package folder\. .P The \fB\-\-dry\-run\fP argument will do everything that pack usually does without actually packing anything\. Reports on what would have gone into the tarball\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help cache @@ -32,9 +32,6 @@ npm help publish .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1 index ac58e1f104d12d..dda31466bffe25 100644 --- a/deps/npm/man/man1/npm-ping.1 +++ b/deps/npm/man/man1/npm-ping.1 @@ -1,14 +1,14 @@ -.TH "NPM\-PING" "1" "October 2019" "" "" +.TH "NPM\-PING" "1" "November 2019" "" "" .SH "NAME" \fBnpm-ping\fR \- Ping npm registry -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm ping [\-\-registry ] .fi .RE -.SH DESCRIPTION +.SS Description .P Ping the configured or given npm registry and verify authentication\. If it works it will output something like: @@ -26,14 +26,11 @@ otherwise you will get: Ping error: {*Detail about error} .fi .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index d1f0bef9686b41..04d7c00ecfd983 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,35 +1,32 @@ -.TH "NPM\-PREFIX" "1" "October 2019" "" "" +.TH "NPM\-PREFIX" "1" "November 2019" "" "" .SH "NAME" \fBnpm-prefix\fR \- Display prefix -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm prefix [\-g] .fi .RE -.SH DESCRIPTION +.SS Description .P Print the local prefix to standard out\. This is the closest parent directory to contain a \fBpackage\.json\fP file or \fBnode_modules\fP directory, unless \fB\-g\fP is also specified\. .P If \fB\-g\fP is specified, this will be the value of the global prefix\. See -npm help 7 \fBnpm\-config\fP for more detail\. -.SH SEE ALSO +npm help \fBconfig\fP for more detail\. +.SS See Also .RS 0 .IP \(bu 2 npm help root .IP \(bu 2 npm help bin .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1 index 7976f48c49cdd3..d05b776e85e23b 100644 --- a/deps/npm/man/man1/npm-profile.1 +++ b/deps/npm/man/man1/npm-profile.1 @@ -1,54 +1,6 @@ -.TH "NPM\-PROFILE" "1" "October 2019" "" "" -.SH "NAME" -\fBnpm-profile\fR \- Change settings on your registry profile -.SH SYNOPSIS .P -.RS 2 -.nf -npm profile get [\-\-json|\-\-parseable] [] -npm profile set [\-\-json|\-\-parseable] -npm profile set password -npm profile enable\-2fa [auth\-and\-writes|auth\-only] -npm profile disable\-2fa -.fi -.RE -.SH DESCRIPTION -.P -Change your profile information on the registry\. This not be available if -you're using a non\-npmjs registry\. -.RS 0 -.IP \(bu 2 -\fBnpm profile get []\fP: -Display all of the properties of your profile, or one or more specific -properties\. It looks like: - -.RE -.P -.RS 2 -.nf -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| name | example | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| email | me@example\.com (verified) | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| two factor auth | auth\-and\-writes | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| fullname | Example User | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| homepage | | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| freenode | | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| twitter | | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| github | | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| created | 2015\-02\-26T01:38:35\.892Z | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| updated | 2017\-10\-02T21:29:45\.922Z | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.fi -.RE ++ +``` .RS 0 .IP \(bu 2 \fBnpm profile set \fP: @@ -78,14 +30,14 @@ via \fBnpm access\fP and \fBnpm owner\fP\|\. Disables two\-factor authentication\. .RE -.SH DETAILS +.SS Details .P All of the \fBnpm profile\fP subcommands accept \fB\-\-json\fP and \fB\-\-parseable\fP and will tailor their output based on those\. Some of these commands may not be available on non npmjs\.com registries\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 config +npm help config .RE diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index e34e5d13dee56f..58ccd7b3852cdc 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,14 +1,14 @@ -.TH "NPM\-PRUNE" "1" "October 2019" "" "" +.TH "NPM\-PRUNE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-prune\fR \- Remove extraneous packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm prune [[<@scope>/]\.\.\.] [\-\-production] [\-\-dry\-run] [\-\-json] .fi .RE -.SH DESCRIPTION +.SS Description .P This command removes "extraneous" packages\. If a package name is provided, then only packages matching one of the supplied names are @@ -33,14 +33,13 @@ this command with the \fB\-\-production\fP flag\. .P If you've disabled package\-locks then extraneous modules will not be removed and it's up to you to run \fBnpm prune\fP from time\-to\-time to remove them\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help uninstall .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help ls .RE - diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index a5bd2f901afa7c..45de41045e180f 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,7 +1,7 @@ -.TH "NPM\-PUBLISH" "1" "October 2019" "" "" +.TH "NPM\-PUBLISH" "1" "November 2019" "" "" .SH "NAME" \fBnpm-publish\fR \- Publish a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -11,18 +11,16 @@ Publishes '\.' if no argument supplied Sets tag 'latest' if no \-\-tag specified .fi .RE -.SH DESCRIPTION +.SS Description .P Publishes a package to the registry so that it can be installed by name\. All files in the package directory are included if no local \fB\|\.gitignore\fP or \fB\|\.npmignore\fP file exists\. If both files exist and a file is ignored by \fB\|\.gitignore\fP but not by \fB\|\.npmignore\fP then it will be included\. See -npm help 7 \fBnpm\-developers\fP for full details on what's included in the published -package, as well as details on how the package is built\. +npm help \fBdevelopers\fP for full details on what's included in the published package, as well as details on how the package is built\. .P By default npm will publish to the public registry\. This can be overridden by -specifying a different default registry or using a npm help 7 \fBnpm\-scope\fP in the name -(see npm help 5 \fBpackage\.json\fP)\. +specifying a different default registry or using a npm help \fBscope\fP in the name (see npm help \fBpackage\.json\fP)\. .RS 0 .IP \(bu 2 \fB\fP: @@ -35,7 +33,7 @@ with a package\.json file inside\. \fB[\-\-tag ]\fP Registers the published package with the given tag, such that \fBnpm install @\fP will install this version\. By default, \fBnpm publish\fP updates -and \fBnpm install\fP installs the \fBlatest\fP tag\. See npm help \fBnpm\-dist\-tag\fP for +and \fBnpm install\fP installs the \fBlatest\fP tag\. See \fBnpm\-dist\-tag\fP \fInpm\-dist\-tag\fR for details about tags\. .IP \(bu 2 \fB[\-\-access ]\fP @@ -60,20 +58,20 @@ the specified registry\. .P Once a package is published with a given name and version, that specific name and version combination can never be used again, even if -it is removed with npm help unpublish\. +it is removed with npm help \fBunpublish\fP\|\. .P As of \fBnpm@5\fP, both a sha1sum and an integrity field with a sha512sum of the tarball will be submitted to the registry during publication\. Subsequent installs will use the strongest supported algorithm to verify downloads\. .P -Similar to \fB\-\-dry\-run\fP see npm help \fBnpm\-pack\fP, which figures out the files to be +Similar to \fB\-\-dry\-run\fP see npm help \fBpack\fP, which figures out the files to be included and packs them into a tarball to be uploaded to the registry\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 -npm help 7 scope +npm help scope .IP \(bu 2 npm help adduser .IP \(bu 2 @@ -88,4 +86,3 @@ npm help pack npm help profile .RE - diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index 2524e48ff757da..49674eca385994 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,7 +1,7 @@ -.TH "NPM\-REBUILD" "1" "October 2019" "" "" +.TH "NPM\-REBUILD" "1" "November 2019" "" "" .SH "NAME" \fBnpm-rebuild\fR \- Rebuild a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,12 +10,10 @@ npm rebuild [[<@scope>/]\.\.\.] alias: npm rb .fi .RE -.SH DESCRIPTION +.SS Description .P -This command runs the \fBnpm build\fP command on the matched folders\. This is useful -when you install a new version of node, and must recompile all your C++ addons with -the new binary\. -.SH SEE ALSO +This command runs the \fBnpm build\fP command on the matched folders\. This is useful when you install a new version of node, and must recompile all your C++ addons with the new binary\. +.SS See Also .RS 0 .IP \(bu 2 npm help build @@ -23,4 +21,3 @@ npm help build npm help install .RE - diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index fe525f52db666f..597292b8d43e6e 100644 --- a/deps/npm/man/man1/npm-repo.1 +++ b/deps/npm/man/man1/npm-repo.1 @@ -1,20 +1,20 @@ -.TH "NPM\-REPO" "1" "October 2019" "" "" +.TH "NPM\-REPO" "1" "November 2019" "" "" .SH "NAME" \fBnpm-repo\fR \- Open package repository page in the browser -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm repo [] .fi .RE -.SH DESCRIPTION +.SS Description .P This command tries to guess at the likely location of a package's repository URL, and then tries to open it using the \fB\-\-browser\fP config param\. If no package name is provided, it will search for a \fBpackage\.json\fP in the current folder and use the \fBname\fP property\. -.SH CONFIGURATION +.SS Configuration .SS browser .RS 0 .IP \(bu 2 @@ -25,7 +25,7 @@ Type: String .RE .P The browser that is called by the \fBnpm repo\fP command to open websites\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help docs @@ -33,4 +33,3 @@ npm help docs npm help config .RE - diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index de134d05379606..9d566ef0c26ffe 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,14 +1,14 @@ -.TH "NPM\-RESTART" "1" "October 2019" "" "" +.TH "NPM\-RESTART" "1" "November 2019" "" "" .SH "NAME" \fBnpm-restart\fR \- Restart a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm restart [\-\- ] .fi .RE -.SH DESCRIPTION +.SS Description .P This restarts a package\. .P @@ -35,19 +35,19 @@ poststart postrestart .RE -.SH NOTE +.SS Note .P Note that the "restart" script is run \fBin addition to\fR the "stop" and "start" scripts, not instead of them\. .P This is the behavior as of \fBnpm\fP major version 2\. A change in this behavior will be accompanied by an increase in major version number -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help test .IP \(bu 2 @@ -55,7 +55,6 @@ npm help start .IP \(bu 2 npm help stop .IP \(bu 2 -npm apihelp restart +npm help restart .RE - diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 665c8d4d31ed99..f86181ef7c5635 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,30 +1,27 @@ -.TH "NPM\-ROOT" "1" "October 2019" "" "" +.TH "NPM\-ROOT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-root\fR \- Display npm root -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm root [\-g] .fi .RE -.SH DESCRIPTION +.SS Description .P Print the effective \fBnode_modules\fP folder to standard out\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help prefix .IP \(bu 2 npm help bin .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1 index 18eb5fcc2130c3..22c9f95306a9a9 100644 --- a/deps/npm/man/man1/npm-run-script.1 +++ b/deps/npm/man/man1/npm-run-script.1 @@ -1,7 +1,7 @@ -.TH "NPM\-RUN\-SCRIPT" "1" "October 2019" "" "" +.TH "NPM\-RUN\-SCRIPT" "1" "November 2019" "" "" .SH "NAME" \fBnpm-run-script\fR \- Run arbitrary package scripts -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm run\-script [\-\-silent] [\-\- \.\.\.] alias: npm run .fi .RE -.SH DESCRIPTION +.SS Description .P This runs an arbitrary command from a package's \fB"scripts"\fP object\. If no \fB"command"\fP is provided, it will list the available scripts\. \fBrun[\-script]\fP is @@ -86,10 +86,10 @@ You can use the \fB\-\-silent\fP flag to prevent showing \fBnpm ERR!\fP output o You can use the \fB\-\-if\-present\fP flag to avoid exiting with a non\-zero exit code when the script is undefined\. This lets you run potentially undefined scripts without breaking the execution chain\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help test .IP \(bu 2 @@ -99,7 +99,6 @@ npm help restart .IP \(bu 2 npm help stop .IP \(bu 2 -npm help 7 config +npm help config .RE - diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index a05e15d08e804d..b792f39e813ff1 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,7 +1,7 @@ -.TH "NPM\-SEARCH" "1" "October 2019" "" "" +.TH "NPM\-SEARCH" "1" "November 2019" "" "" .SH "NAME" \fBnpm-search\fR \- Search for packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm search [\-l|\-\-long] [\-\-json] [\-\-parseable] [\-\-no\-description] [sear aliases: s, se, find .fi .RE -.SH DESCRIPTION +.SS Description .P Search the registry for packages matching the search terms\. \fBnpm search\fP performs a linear, incremental, lexically\-ordered search through package @@ -32,7 +32,7 @@ supports standard JavaScript RegExp syntax\. A trailing \fB/\fP will be ignored this case\. (Note that many regular expression characters must be escaped or quoted in most shells\.) .SS A Note on caching -.SH CONFIGURATION +.SS Configuration .SS description .RS 0 .IP \(bu 2 @@ -121,18 +121,15 @@ to a different default registry, such as your internal private module repository, \fBnpm search\fP will default to that registry when searching\. Pass a different registry url such as the default above in order to override this setting\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help view .RE - diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index cdeea0c0dc972f..33286dc895f391 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,38 +1,37 @@ -.TH "NPM\-SHRINKWRAP" "1" "October 2019" "" "" +.TH "NPM\-SHRINKWRAP" "1" "November 2019" "" "" .SH "NAME" \fBnpm-shrinkwrap\fR \- Lock down dependency versions for publication -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm shrinkwrap .fi .RE -.SH DESCRIPTION +.SS Description .P This command repurposes \fBpackage\-lock\.json\fP into a publishable \fBnpm\-shrinkwrap\.json\fP or simply creates a new one\. The file created and updated by this command will then take precedence over any other existing or future \fBpackage\-lock\.json\fP files\. For a detailed explanation of the design and purpose -of package locks in npm, see npm help 5 package\-locks\. -.SH SEE ALSO +of package locks in npm, see npm help package\-locks\. +.SS See Also .RS 0 .IP \(bu 2 npm help install .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 -npm help 5 package\.json +npm help package\.js .IP \(bu 2 -npm help 5 package\-locks +npm help package\-locks .IP \(bu 2 -npm help 5 package\-lock\.json +npm help package\-lock\.json .IP \(bu 2 -npm help 5 shrinkwrap\.json +npm help shrinkwrap\.json .IP \(bu 2 npm help ls .RE - diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index 04b338f36c7923..4ad11a7efbcdf0 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,7 +1,7 @@ -.TH "NPM\-STAR" "1" "October 2019" "" "" +.TH "NPM\-STAR" "1" "November 2019" "" "" .SH "NAME" \fBnpm-star\fR \- Mark your favorite packages -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -9,7 +9,7 @@ npm star [\.\.\.] npm unstar [\.\.\.] .fi .RE -.SH DESCRIPTION +.SS Description .P "Starring" a package means that you have some interest in it\. It's a vaguely positive way to show that you care\. @@ -17,7 +17,7 @@ a vaguely positive way to show that you care\. "Unstarring" is the same thing, but in reverse\. .P It's a boolean thing\. Starring repeatedly has no additional effect\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help view @@ -27,4 +27,3 @@ npm help whoami npm help adduser .RE - diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index 0ea4b584c1be93..2c7b6f243098a2 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,21 +1,21 @@ -.TH "NPM\-STARS" "1" "October 2019" "" "" +.TH "NPM\-STARS" "1" "November 2019" "" "" .SH "NAME" \fBnpm-stars\fR \- View packages marked as favorites -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm stars [] .fi .RE -.SH DESCRIPTION +.SS Description .P If you have starred a lot of neat things and want to find them again quickly this command lets you do just that\. .P You may also want to see your friend's favorite packages, in this case you will most certainly enjoy this command\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help star @@ -27,4 +27,3 @@ npm help whoami npm help adduser .RE - diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index da7ea063207981..e83e6800f7d01a 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,28 +1,27 @@ -.TH "NPM\-START" "1" "October 2019" "" "" +.TH "NPM\-START" "1" "November 2019" "" "" .SH "NAME" \fBnpm-start\fR \- Start a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm start [\-\- ] .fi .RE -.SH DESCRIPTION +.SS Description .P This runs an arbitrary command specified in the package's \fB"start"\fP property of its \fB"scripts"\fP object\. If no \fB"start"\fP property is specified on the \fB"scripts"\fP object, it will run \fBnode server\.js\fP\|\. .P As of \fBnpm@2\.0\.0\fP \fIhttps://blog\.npmjs\.org/post/98131109725/npm\-2\-0\-0\fR, you can -use custom arguments when executing scripts\. Refer to npm help run\-script for -more details\. -.SH SEE ALSO +use custom arguments when executing scripts\. Refer to npm help \fBrun\-script\fP for more details\. +.SS See Also .RS 0 .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help test .IP \(bu 2 @@ -31,4 +30,3 @@ npm help restart npm help stop .RE - diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index e435b56f8947cb..d3b612b08adffb 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,22 +1,22 @@ -.TH "NPM\-STOP" "1" "October 2019" "" "" +.TH "NPM\-STOP" "1" "November 2019" "" "" .SH "NAME" \fBnpm-stop\fR \- Stop a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm stop [\-\- ] .fi .RE -.SH DESCRIPTION +.SS Description .P This runs a package's "stop" script, if one was provided\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help test .IP \(bu 2 @@ -25,4 +25,3 @@ npm help start npm help restart .RE - diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1 index d4c2bf18e35fb6..ca7f0beb1fafb2 100644 --- a/deps/npm/man/man1/npm-team.1 +++ b/deps/npm/man/man1/npm-team.1 @@ -1,7 +1,7 @@ -.TH "NPM\-TEAM" "1" "October 2019" "" "" +.TH "NPM\-TEAM" "1" "November 2019" "" "" .SH "NAME" \fBnpm-team\fR \- Manage organization teams and team memberships -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -16,19 +16,17 @@ npm team ls | npm team edit .fi .RE -.SH DESCRIPTION +.SS Description .P Used to manage teams in organizations, and change team memberships\. Does not handle permissions for packages\. .P Teams must always be fully qualified with the organization/scope they belong to -when operating on them, separated by a colon (\fB:\fP)\. That is, if you have a -\fBdevelopers\fP team on a \fBfoo\fP organization, you must always refer to that team as -\fBfoo:developers\fP in these commands\. +when operating on them, separated by a colon (\fB:\fP)\. That is, if you have a \fBwombats\fP team in a \fBwisdom\fP organization, you must always refer to that team as \fBwisdom:wombats\fP in these commands\. .RS 0 .IP \(bu 2 create / destroy: -Create a new team, or destroy an existing one\. +Create a new team, or destroy an existing one\. Note: You cannot remove the \fBdevelopers\fP team, learn more\. .IP \(bu 2 add / rm: Add a user to an existing team, or remove a user from a team they belong to\. @@ -42,7 +40,7 @@ edit: Edit a current team\. .RE -.SH DETAILS +.SS Details .P \fBnpm team\fP always operates directly on the current registry, configurable from the command line using \fB\-\-registry=\fP\|\. @@ -56,12 +54,11 @@ is done through the website, not the npm CLI\. .P To use teams to manage permissions on packages belonging to your organization, use the \fBnpm access\fP command to grant or revoke the appropriate permissions\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help access .IP \(bu 2 -npm help 7 registry +npm help registry .RE - diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index b98fa1502a9fc5..bd18fedb505bfd 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,24 +1,24 @@ -.TH "NPM\-TEST" "1" "October 2019" "" "" +.TH "NPM\-TEST" "1" "November 2019" "" "" .SH "NAME" \fBnpm-test\fR \- Test a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf - npm test [\-\- ] +npm test [\-\- ] - aliases: t, tst +aliases: t, tst .fi .RE -.SH DESCRIPTION +.SS Description .P This runs a package's "test" script, if one was provided\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help start .IP \(bu 2 @@ -27,4 +27,3 @@ npm help restart npm help stop .RE - diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1 index f71a5c03ba03eb..04a0f5f82f2c6c 100644 --- a/deps/npm/man/man1/npm-token.1 +++ b/deps/npm/man/man1/npm-token.1 @@ -1,84 +1,12 @@ -.TH "NPM\-TOKEN" "1" "October 2019" "" "" -.SH "NAME" -\fBnpm-token\fR \- Manage your authentication tokens -.SH SYNOPSIS .P -.RS 2 -.nf -npm token list [\-\-json|\-\-parseable] -npm token create [\-\-read\-only] [\-\-cidr=1\.1\.1\.1/24,2\.2\.2\.2/16] -npm token revoke -.fi -.RE -.SH DESCRIPTION -.P -This lets you list, create and revoke authentication tokens\. -.RS 0 -.IP \(bu 2 -\fBnpm token list\fP: -Shows a table of all active authentication tokens\. You can request this as -JSON with \fB\-\-json\fP or tab\-separated values with \fB\-\-parseable\fP\|\. ++ ``` -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| id | token | created | read\-only | CIDR whitelist | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| 7f3134 | 1fa9ba… | 2017\-10\-02 | yes | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| c03241 | af7aef… | 2017\-10\-02 | no | 192\.168\.0\.1/24 | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| e0cf92 | 3a436a… | 2017\-10\-02 | no | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| 63eb9d | 74ef35… | 2017\-09\-28 | no | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| 2daaa8 | cbad5f… | 2017\-09\-26 | no | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| 68c2fe | 127e51… | 2017\-09\-23 | no | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| 6334e1 | 1dadd1… | 2017\-09\-23 | no | | -.IP \(bu 2 -\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.P -.RS 2 -.nf - -.fi -.RE -.IP \(bu 2 -\fBnpm token create [\-\-read\-only] [\-\-cidr=]\fP: -Create a new authentication token\. It can be \fB\-\-read\-only\fP or accept a list of -CIDR \fIhttps://en\.wikipedia\.org/wiki/Classless_Inter\-Domain_Routing\fR ranges to -limit use of this token to\. This will prompt you for your password, and, if you have -two\-factor authentication enabled, an otp\. - -.RE -.P -.RS 2 -.nf -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| token | a73c9572\-f1b9\-8983\-983d\-ba3ac3cc913d | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| cidr_whitelist | | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| readonly | false | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -| created | 2017\-10\-02T07:52:24\.838Z | -+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+ -.fi -.RE .RS 0 .IP \(bu 2 \fBnpm token revoke \fP: This removes an authentication token, making it immediately unusable\. This can accept both complete tokens (as you get back from \fBnpm token create\fP and will -find in your \fB\|\.npmrc\fP) and ids as seen in the \fBnpm token list\fP output\. +find in your \fB\|\.npmrc\fP) and ids as seen in the \fBnpm token list\fP output\. This will NOT accept the truncated token found in \fBnpm token list\fP output\. .RE diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index f1be6e3cf9f310..35523df7a17d5f 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,7 +1,7 @@ -.TH "NPM\-UNINSTALL" "1" "October 2019" "" "" +.TH "NPM\-UNINSTALL" "1" "November 2019" "" "" .SH "NAME" \fBnpm-uninstall\fR \- Remove a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm uninstall [<@scope>/][@]\.\.\. [\-S|\-\-save|\-D|\-\-save\-dev aliases: remove, rm, r, un, unlink .fi .RE -.SH DESCRIPTION +.SS Description .P This uninstalls a package, completely removing everything npm installed on its behalf\. @@ -43,7 +43,7 @@ the package version in your main package\.json: Further, if you have an \fBnpm\-shrinkwrap\.json\fP then it will be updated as well\. .P -Scope is optional and follows the usual rules for npm help 7 \fBnpm\-scope\fP\|\. +Scope is optional and follows the usual rules for npm help \fBscope\fP\|\. .P Examples: .P @@ -56,20 +56,17 @@ npm uninstall dtrace\-provider \-\-save\-optional npm uninstall lodash \-\-no\-save .fi .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help prune .IP \(bu 2 npm help install .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index 620f02c88570a9..f0ce9fa92db2ca 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,14 +1,14 @@ -.TH "NPM\-UNPUBLISH" "1" "October 2019" "" "" +.TH "NPM\-UNPUBLISH" "1" "November 2019" "" "" .SH "NAME" \fBnpm-unpublish\fR \- Remove a package from the registry -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm unpublish [<@scope>/][@] .fi .RE -.SH WARNING +.SS Warning .P \fBIt is generally considered bad behavior to remove versions of a library that others are depending on!\fR @@ -17,7 +17,7 @@ Consider using the \fBdeprecate\fP command instead, if your intent is to encourage users to upgrade\. .P There is plenty of room on the registry\. -.SH DESCRIPTION +.SS Description .P This removes a package version from the registry, deleting its entry and removing the tarball\. @@ -36,19 +36,18 @@ only allowed with versions published in the last 72 hours\. If you are trying to unpublish a version published longer ago than that, contact support@npmjs\.com\|\. .P -The scope is optional and follows the usual rules for npm help 7 \fBnpm\-scope\fP\|\. -.SH SEE ALSO +The scope is optional and follows the usual rules for npm help \fBscope\fP\|\. +.SS See Also .RS 0 .IP \(bu 2 npm help deprecate .IP \(bu 2 npm help publish .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help adduser .IP \(bu 2 npm help owner .RE - diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index 0bc252aff045d5..2ebe4a29456c04 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,7 +1,7 @@ -.TH "NPM\-UPDATE" "1" "October 2019" "" "" +.TH "NPM\-UPDATE" "1" "November 2019" "" "" .SH "NAME" \fBnpm-update\fR \- Update a package -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm update [\-g] [\.\.\.] aliases: up, upgrade .fi .RE -.SH DESCRIPTION +.SS Description .P This command will update all the packages listed to the latest version (specified by the \fBtag\fP config), respecting semver\. @@ -29,10 +29,10 @@ As of \fBnpm@2\.6\.1\fP, the \fBnpm update\fP will only inspect top\-level packa Prior versions of \fBnpm\fP would also recursively inspect all dependencies\. To get the old behavior, use \fBnpm \-\-depth 9999 update\fP\|\. .P -As of \fBnpm@5\.0\.0\fP, the \fBnpm update\fP will change \fBpackage\.json\fP to save the -new version as the minimum required dependency\. To get the old behavior, +As of \fBnpm@5\.0\.0\fP, the \fBnpm update\fP will change \fBpackage\.json\fP to save the +new version as the minimum required dependency\. To get the old behavior, use \fBnpm update \-\-no\-save\fP\|\. -.SH EXAMPLES +.SS Example .P IMPORTANT VERSION NOTE: these examples assume \fBnpm@2\.6\.1\fP or later\. For older versions of \fBnpm\fP, you must specify \fB\-\-depth 0\fP to get the behavior @@ -124,7 +124,7 @@ package that is \fBoutdated\fP \-\- that is, has a version that is different fro .P NOTE: If a package has been upgraded to a version newer than \fBlatest\fP, it will be \fIdowngraded\fR\|\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help install @@ -133,11 +133,10 @@ npm help outdated .IP \(bu 2 npm help shrinkwrap .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help ls .RE - diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 3be068b7731090..df14c7f67e88fa 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,7 +1,7 @@ -.TH "NPM\-VERSION" "1" "October 2019" "" "" +.TH "NPM\-VERSION" "1" "November 2019" "" "" .SH "NAME" \fBnpm-version\fR \- Bump a package version -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -12,7 +12,7 @@ npm version [ | major | minor | patch | premajor | preminor | prepat \|'npm ls' to inspect current package/dependency versions .fi .RE -.SH DESCRIPTION +.SS Description .P Run this in a package directory to bump the version and write the new data back to \fBpackage\.json\fP, \fBpackage\-lock\.json\fP, and, if present, \fBnpm\-shrinkwrap\.json\fP\|\. @@ -88,18 +88,18 @@ Take the following example: .P .RS 2 .nf -"scripts": { - "preversion": "npm test", - "version": "npm run build && git add \-A dist", - "postversion": "git push && git push \-\-tags && rm \-rf build/temp" -} + "scripts": { + "preversion": "npm test", + "version": "npm run build && git add \-A dist", + "postversion": "git push && git push \-\-tags && rm \-rf build/temp" + } .fi .RE .P This runs all your tests, and proceeds only if they pass\. Then runs your \fBbuild\fP script, and adds everything in the \fBdist\fP directory to the commit\. After the commit, it pushes the new commit and tag up to the server, and deletes the \fBbuild/temp\fP directory\. -.SH CONFIGURATION +.SS Configuration .SS allow\-same\-version .RS 0 .IP \(bu 2 @@ -109,7 +109,7 @@ Type: Boolean .RE .P -Prevents throwing an error when \fBnpm version\fP is used to set the new version +Prevents throwing an error when \fBnpm version\fP is used to set the new version to the same value as the current version\. .SS git\-tag\-version .RS 0 @@ -143,20 +143,19 @@ Type: Boolean Pass the \fB\-s\fP flag to git to sign the tag\. .P Note that you must have a default GPG key set up in your git config for this to work properly\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help init .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help 7 semver +npm help semver .IP \(bu 2 -npm help 7 config +npm help config .RE - diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index b4dacc8d9ba4ca..72d41b9cf18d0d 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,7 +1,7 @@ -.TH "NPM\-VIEW" "1" "October 2019" "" "" +.TH "NPM\-VIEW" "1" "November 2019" "" "" .SH "NAME" \fBnpm-view\fR \- View registry info -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf @@ -10,7 +10,7 @@ npm view [<@scope>/][@] [[\.]\.\.\.] aliases: info, show, v .fi .RE -.SH DESCRIPTION +.SS Description .P This command shows data about a package and prints it to the stream referenced by the \fBoutfd\fP config, which defaults to stdout\. @@ -88,7 +88,7 @@ npm view express contributors\.name contributors\.email .P "Person" fields are shown as a string if they would be shown as an object\. So, for example, this will show the list of npm contributors in -the shortened string format\. (See npm help 5 \fBpackage\.json\fP for more on this\.) +the shortened string format\. (See npm help \fBpackage\.json\fP for more on this\.) .P .RS 2 .nf @@ -114,7 +114,7 @@ this: npm view connect versions .fi .RE -.SH OUTPUT +.SS Output .P If only a single string field for a single version is output, then it will not be colorized or quoted, so as to enable piping the output to @@ -127,20 +127,17 @@ will be prefixed with the version it applies to\. .P If multiple fields are requested, than each of them are prefixed with the field name\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help search .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help docs .RE - diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index d6811a0e8fbf2a..40c627e8c44f11 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,26 +1,23 @@ -.TH "NPM\-WHOAMI" "1" "October 2019" "" "" +.TH "NPM\-WHOAMI" "1" "November 2019" "" "" .SH "NAME" \fBnpm-whoami\fR \- Display npm username -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm whoami [\-\-registry ] .fi .RE -.SH DESCRIPTION +.SS Description .P Print the \fBusername\fP config to standard output\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 npm help adduser .RE - diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 8d198b4a2d1256..6ef81e031837b0 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,17 +1,17 @@ -.TH "NPM" "1" "October 2019" "" "" +.TH "NPM" "1" "November 2019" "" "" .SH "NAME" \fBnpm\fR \- javascript package manager -.SH SYNOPSIS +.SS Synopsis .P .RS 2 .nf npm [args] .fi .RE -.SH VERSION +.SS Version .P -6.12.1 -.SH DESCRIPTION +6\.13\.1 +.SS Description .P npm is the package manager for the Node JavaScript platform\. It puts modules in place so that node can find them, and manages dependency @@ -22,7 +22,7 @@ Most commonly, it is used to publish, discover, install, and develop node programs\. .P Run \fBnpm help\fP to get a list of available commands\. -.SH IMPORTANT +.SS Important .P npm is configured to use npm, Inc\.'s public registry at https://registry\.npmjs\.org by default\. Use of the npm public registry is @@ -31,16 +31,16 @@ subject to terms of use available at https://www\.npmjs\.com/policies/terms\. You can configure npm to use any compatible registry you like, and even run your own registry\. Use of someone else's registry may be governed by their terms of use\. -.SH INTRODUCTION +.SS Introduction .P You probably got npm because you want to install stuff\. .P Use \fBnpm install blerg\fP to install the latest version of "blerg"\. Check out -npm help \fBnpm\-install\fP for more info\. It can do a lot of stuff\. +npm help \fBinstall\fP for more info\. It can do a lot of stuff\. .P Use the \fBnpm search\fP command to show everything that's available\. Use \fBnpm ls\fP to show everything you've installed\. -.SH DEPENDENCIES +.SS Dependencies .P If a package references to another package with a git URL, npm depends on a preinstalled git\. @@ -55,9 +55,9 @@ not supported by node\-gyp \fIhttps://github\.com/TooTallNate/node\-gyp\fR\|\. For more information visit the node\-gyp repository \fIhttps://github\.com/TooTallNate/node\-gyp\fR and the node\-gyp Wiki \fIhttps://github\.com/TooTallNate/node\-gyp/wiki\fR\|\. -.SH DIRECTORIES +.SS Directories .P -See npm help 5 \fBnpm\-folders\fP to learn about where npm puts stuff\. +See npm help \fBfolders\fP to learn about where npm puts stuff\. .P In particular, npm has two modes of operation: .RS 0 @@ -75,14 +75,14 @@ defaults to the current working directory\. Packages are installed to .P Local mode is the default\. Use \fB\-g\fP or \fB\-\-global\fP on any command to operate in global mode instead\. -.SH DEVELOPER USAGE +.SS Developer Usage .P If you're using npm to develop and publish your code, check out the following help topics: .RS 0 .IP \(bu 2 json: -Make a package\.json file\. See npm help 5 \fBpackage\.json\fP\|\. +Make a package\.json file\. See npm help \fBpackage\.json\fP\|\. .IP \(bu 2 link: For linking your current working code into Node's path, so that you @@ -102,7 +102,7 @@ publish: Use the \fBnpm publish\fP command to upload your code to the registry\. .RE -.SH CONFIGURATION +.SS Configuration .P npm is extremely configurable\. It reads its configuration options from 5 places\. @@ -135,8 +135,8 @@ lib/utils/config\-defs\.js\. These must not be changed\. .RE .P -See npm help 7 \fBnpm\-config\fP for much much more information\. -.SH CONTRIBUTIONS +See npm help \fBconfig\fP for much much more information\. +.SS Contributions .P Patches welcome! .P @@ -146,12 +146,10 @@ the contributing guidelines and check the issues list\. .IP \(bu 2 CONTRIBUTING\.md \fIhttps://github\.com/npm/cli/blob/latest/CONTRIBUTING\.md\fR .IP \(bu 2 -Bug tracker \fIhttps://npm\.community/c/bugs\fR -.IP \(bu 2 -Support tracker \fIhttps://npm\.community/c/support\fR +Bug tracker \fIhttps://github\.com/npm/cli/issues\fR .RE -.SH BUGS +.SS Bugs .P When you find issues, please report them: .RS 0 @@ -165,30 +163,23 @@ Be sure to follow the template and bug reporting guidelines\. You can also ask for help in the support forum \fIhttps://npm\.community/c/support\fR if you're unsure if it's actually a bug or are having trouble coming up with a detailed reproduction to report\. -.SH AUTHOR +.SS Author .P Isaac Z\. Schlueter \fIhttp://blog\.izs\.me/\fR :: isaacs \fIhttps://github\.com/isaacs/\fR :: @izs \fIhttps://twitter\.com/izs\fR :: i@izs\.me -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help help .IP \(bu 2 -README -.IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help install .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 7 index +npm help npmrc .RE - diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1 index d00c489c39b213..cd44dda044ad62 100644 --- a/deps/npm/man/man1/npx.1 +++ b/deps/npm/man/man1/npx.1 @@ -172,3 +172,4 @@ This work is released by its authors into the public domain under CC0\-1\.0\. Se \fBnpm\-config(7)\fP .RE + diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5 new file mode 100644 index 00000000000000..a6d802775989a0 --- /dev/null +++ b/deps/npm/man/man5/folders.5 @@ -0,0 +1,54 @@ +.P +[E] +``` +.P +Since foo depends directly on \fBbar@1\.2\.3\fP and \fBbaz@1\.2\.3\fP, those are +installed in foo's \fBnode_modules\fP folder\. +.P +Even though the latest copy of blerg is 1\.3\.7, foo has a specific +dependency on version 1\.2\.5\. So, that gets installed at [A]\. Since the +parent installation of blerg satisfies bar's dependency on \fBblerg@1\.x\fP, +it does not install another copy under [B]\. +.P +Bar [B] also has dependencies on baz and asdf, so those are installed in +bar's \fBnode_modules\fP folder\. Because it depends on \fBbaz@2\.x\fP, it cannot +re\-use the \fBbaz@1\.2\.3\fP installed in the parent \fBnode_modules\fP folder [D], +and must install its own copy [C]\. +.P +Underneath bar, the \fBbaz \-> quux \-> bar\fP dependency creates a cycle\. +However, because bar is already in quux's ancestry [B], it does not +unpack another copy of bar into that folder\. +.P +Underneath \fBfoo \-> baz\fP [D], quux's [E] folder tree is empty, because its +dependency on bar is satisfied by the parent folder copy installed at [B]\. +.P +For a graphical breakdown of what is installed where, use \fBnpm ls\fP\|\. +.SS Publishing +.P +Upon publishing, npm will look in the \fBnode_modules\fP folder\. If any of +the items there are not in the \fBbundledDependencies\fP array, then they will +not be included in the package tarball\. +.P +This allows a package maintainer to install all of their dependencies +(and dev dependencies) locally, but only re\-publish those items that +cannot be found elsewhere\. See npm help \fBpackage\.json\fP for more information\. +.SS See also +.RS 0 +.IP \(bu 2 +npm help package\.json +.IP \(bu 2 +npm help install +.IP \(bu 2 +npm help pack +.IP \(bu 2 +npm help cache +.IP \(bu 2 +npm help config +.IP \(bu 2 +npm help npmrc +.IP \(bu 2 +npm help config +.IP \(bu 2 +npm help publish + +.RE diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5 new file mode 100644 index 00000000000000..d14b649fe75e72 --- /dev/null +++ b/deps/npm/man/man5/install.5 @@ -0,0 +1,73 @@ +.TH "INSTALL" "5" "November 2019" "" "" +.SH "NAME" +\fBinstall\fR \- Download and Install npm +.SS Description +.P +To publish and install packages to and from the public npm registry, you must install Node\.js and the npm command line interface using either a Node version manager or a Node installer\. \fBWe strongly recommend using a Node version manager to install Node\.js and npm\.\fR We do not recommend using a Node installer, since the Node installation process installs npm in a directory with local permissions and can cause permissions errors when you run npm packages globally\. +.SS Overview +.RS 0 +.IP \(bu 2 +Checking your version of npm and Node\.js \fI#checking\-your\-version\-of\-npm\-and\-node\-js\fR +.IP \(bu 2 +Using a Node version manager to install Node\.js and npm \fI#using\-a\-node\-version\-manager\-to\-install\-node\-js\-and\-npm\fR +.IP \(bu 2 +Using a Node installer to install Node\.js and npm \fI#using\-a\-node\-installer\-to\-install\-node\-js\-and\-npm\fR + +.RE +.SS Checking your version of npm and Node\.js +.P +To see if you already have Node\.js and npm installed and check the installed version, run the following commands: +.P +.RS 2 +.nf +node \-v +npm \-v +.fi +.RE +.SS Using a Node version manager to install Node\.js and npm +.P +Node version managers allow you to install and switch between multiple versions of Node\.js and npm on your system so you can test your applications on multiple versions of npm to ensure they work for users on different versions\. +.SS OSX or Linux Node version managers +.RS 0 +.IP \(bu 2 +nvm \fIhttps://github\.com/creationix/nvm\fR +.IP \(bu 2 +n \fIhttps://github\.com/tj/n\fR + +.RE +.SS Windows Node version managers +.RS 0 +.IP \(bu 2 +nodist \fIhttps://github\.com/marcelklehr/nodist\fR +.IP \(bu 2 +nvm\-windows \fIhttps://github\.com/coreybutler/nvm\-windows\fR + +.RE +.SS Using a Node installer to install Node\.js and npm +.P +If you are unable to use a Node version manager, you can use a Node installer to install both Node\.js and npm on your system\. +.RS 0 +.IP \(bu 2 +Node\.js installer \fIhttps://nodejs\.org/en/download/\fR +.IP \(bu 2 +NodeSource installer \fIhttps://github\.com/nodesource/distributions\fR\|\. If you use Linux, we recommend that you use a NodeSource installer\. + +.RE +.SS OS X or Windows Node installers +.P +If you're using OS X or Windows, use one of the installers from the Node\.js download page \fIhttps://nodejs\.org/en/download/\fR\|\. Be sure to install the version labeled \fBLTS\fR\|\. Other versions have not yet been tested with npm\. +.SS Linux or other operating systems Node installers +.P +If you're using Linux or another operating system, use one of the following installers: +.RS 0 +.IP \(bu 2 +NodeSource installer \fIhttps://github\.com/nodesource/distributions\fR (recommended) +.IP \(bu 2 +One of the installers on the Node\.js download page \fIhttps://nodejs\.org/en/download/\fR + +.RE +.P +Or see this page \fIhttps://nodejs\.org/en/download/package\-manager/\fR to install npm for Linux in the way many Linux developers prefer\. +.SS Less\-common operating systems +.P +For more information on installing Node\.js on a variety of operating systems, see this page \fIhttps://nodejs\.org/en/download/package\-manager/\fR\|\. diff --git a/deps/npm/man/man5/npm-folders.5 b/deps/npm/man/man5/npm-folders.5 deleted file mode 100644 index 2da094fcc68544..00000000000000 --- a/deps/npm/man/man5/npm-folders.5 +++ /dev/null @@ -1,226 +0,0 @@ -.TH "NPM\-FOLDERS" "5" "October 2019" "" "" -.SH "NAME" -\fBnpm-folders\fR \- Folder Structures Used by npm -.SH DESCRIPTION -.P -npm puts various things on your computer\. That's its job\. -.P -This document will tell you what it puts where\. -.SS tl;dr -.RS 0 -.IP \(bu 2 -Local install (default): puts stuff in \fB\|\./node_modules\fP of the current -package root\. -.IP \(bu 2 -Global install (with \fB\-g\fP): puts stuff in /usr/local or wherever node -is installed\. -.IP \(bu 2 -Install it \fBlocally\fR if you're going to \fBrequire()\fP it\. -.IP \(bu 2 -Install it \fBglobally\fR if you're going to run it on the command line\. -.IP \(bu 2 -If you need both, then install it in both places, or use \fBnpm link\fP\|\. - -.RE -.SS prefix Configuration -.P -The \fBprefix\fP config defaults to the location where node is installed\. -On most systems, this is \fB/usr/local\fP\|\. On Windows, it's \fB%AppData%\\npm\fP\|\. -On Unix systems, it's one level up, since node is typically installed at -\fB{prefix}/bin/node\fP rather than \fB{prefix}/node\.exe\fP\|\. -.P -When the \fBglobal\fP flag is set, npm installs things into this prefix\. -When it is not set, it uses the root of the current package, or the -current working directory if not in a package already\. -.SS Node Modules -.P -Packages are dropped into the \fBnode_modules\fP folder under the \fBprefix\fP\|\. -When installing locally, this means that you can -\fBrequire("packagename")\fP to load its main module, or -\fBrequire("packagename/lib/path/to/sub/module")\fP to load other modules\. -.P -Global installs on Unix systems go to \fB{prefix}/lib/node_modules\fP\|\. -Global installs on Windows go to \fB{prefix}/node_modules\fP (that is, no -\fBlib\fP folder\.) -.P -Scoped packages are installed the same way, except they are grouped together -in a sub\-folder of the relevant \fBnode_modules\fP folder with the name of that -scope prefix by the @ symbol, e\.g\. \fBnpm install @myorg/package\fP would place -the package in \fB{prefix}/node_modules/@myorg/package\fP\|\. See npm help 7 \fBscope\fP for -more details\. -.P -If you wish to \fBrequire()\fP a package, then install it locally\. -.SS Executables -.P -When in global mode, executables are linked into \fB{prefix}/bin\fP on Unix, -or directly into \fB{prefix}\fP on Windows\. -.P -When in local mode, executables are linked into -\fB\|\./node_modules/\.bin\fP so that they can be made available to scripts run -through npm\. (For example, so that a test runner will be in the path -when you run \fBnpm test\fP\|\.) -.SS Man Pages -.P -When in global mode, man pages are linked into \fB{prefix}/share/man\fP\|\. -.P -When in local mode, man pages are not installed\. -.P -Man pages are not installed on Windows systems\. -.SS Cache -.P -See npm help \fBnpm\-cache\fP\|\. Cache files are stored in \fB~/\.npm\fP on Posix, or -\fB%AppData%/npm\-cache\fP on Windows\. -.P -This is controlled by the \fBcache\fP configuration param\. -.SS Temp Files -.P -Temporary files are stored by default in the folder specified by the -\fBtmp\fP config, which defaults to the TMPDIR, TMP, or TEMP environment -variables, or \fB/tmp\fP on Unix and \fBc:\\windows\\temp\fP on Windows\. -.P -Temp files are given a unique folder under this root for each run of the -program, and are deleted upon successful exit\. -.SH More Information -.P -When installing locally, npm first tries to find an appropriate -\fBprefix\fP folder\. This is so that \fBnpm install foo@1\.2\.3\fP will install -to the sensible root of your package, even if you happen to have \fBcd\fPed -into some other folder\. -.P -Starting at the $PWD, npm will walk up the folder tree checking for a -folder that contains either a \fBpackage\.json\fP file, or a \fBnode_modules\fP -folder\. If such a thing is found, then that is treated as the effective -"current directory" for the purpose of running npm commands\. (This -behavior is inspired by and similar to git's \.git\-folder seeking -logic when running git commands in a working dir\.) -.P -If no package root is found, then the current folder is used\. -.P -When you run \fBnpm install foo@1\.2\.3\fP, then the package is loaded into -the cache, and then unpacked into \fB\|\./node_modules/foo\fP\|\. Then, any of -foo's dependencies are similarly unpacked into -\fB\|\./node_modules/foo/node_modules/\.\.\.\fP\|\. -.P -Any bin files are symlinked to \fB\|\./node_modules/\.bin/\fP, so that they may -be found by npm scripts when necessary\. -.SS Global Installation -.P -If the \fBglobal\fP configuration is set to true, then npm will -install packages "globally"\. -.P -For global installation, packages are installed roughly the same way, -but using the folders described above\. -.SS Cycles, Conflicts, and Folder Parsimony -.P -Cycles are handled using the property of node's module system that it -walks up the directories looking for \fBnode_modules\fP folders\. So, at every -stage, if a package is already installed in an ancestor \fBnode_modules\fP -folder, then it is not installed at the current location\. -.P -Consider the case above, where \fBfoo \-> bar \-> baz\fP\|\. Imagine if, in -addition to that, baz depended on bar, so you'd have: -\fBfoo \-> bar \-> baz \-> bar \-> baz \.\.\.\fP\|\. However, since the folder -structure is: \fBfoo/node_modules/bar/node_modules/baz\fP, there's no need to -put another copy of bar into \fB\|\.\.\./baz/node_modules\fP, since when it calls -require("bar"), it will get the copy that is installed in -\fBfoo/node_modules/bar\fP\|\. -.P -This shortcut is only used if the exact same -version would be installed in multiple nested \fBnode_modules\fP folders\. It -is still possible to have \fBa/node_modules/b/node_modules/a\fP if the two -"a" packages are different versions\. However, without repeating the -exact same package multiple times, an infinite regress will always be -prevented\. -.P -Another optimization can be made by installing dependencies at the -highest level possible, below the localized "target" folder\. -.SS Example -.P -Consider this dependency graph: -.P -.RS 2 -.nf -foo -+\-\- blerg@1\.2\.5 -+\-\- bar@1\.2\.3 -| +\-\- blerg@1\.x (latest=1\.3\.7) -| +\-\- baz@2\.x -| | `\-\- quux@3\.x -| | `\-\- bar@1\.2\.3 (cycle) -| `\-\- asdf@* -`\-\- baz@1\.2\.3 - `\-\- quux@3\.x - `\-\- bar -.fi -.RE -.P -In this case, we might expect a folder structure like this: -.P -.RS 2 -.nf -foo -+\-\- node_modules - +\-\- blerg (1\.2\.5) <\-\-\-[A] - +\-\- bar (1\.2\.3) <\-\-\-[B] - | `\-\- node_modules - | +\-\- baz (2\.0\.2) <\-\-\-[C] - | | `\-\- node_modules - | | `\-\- quux (3\.2\.0) - | `\-\- asdf (2\.3\.4) - `\-\- baz (1\.2\.3) <\-\-\-[D] - `\-\- node_modules - `\-\- quux (3\.2\.0) <\-\-\-[E] -.fi -.RE -.P -Since foo depends directly on \fBbar@1\.2\.3\fP and \fBbaz@1\.2\.3\fP, those are -installed in foo's \fBnode_modules\fP folder\. -.P -Even though the latest copy of blerg is 1\.3\.7, foo has a specific -dependency on version 1\.2\.5\. So, that gets installed at [A]\. Since the -parent installation of blerg satisfies bar's dependency on \fBblerg@1\.x\fP, -it does not install another copy under [B]\. -.P -Bar [B] also has dependencies on baz and asdf, so those are installed in -bar's \fBnode_modules\fP folder\. Because it depends on \fBbaz@2\.x\fP, it cannot -re\-use the \fBbaz@1\.2\.3\fP installed in the parent \fBnode_modules\fP folder [D], -and must install its own copy [C]\. -.P -Underneath bar, the \fBbaz \-> quux \-> bar\fP dependency creates a cycle\. -However, because bar is already in quux's ancestry [B], it does not -unpack another copy of bar into that folder\. -.P -Underneath \fBfoo \-> baz\fP [D], quux's [E] folder tree is empty, because its -dependency on bar is satisfied by the parent folder copy installed at [B]\. -.P -For a graphical breakdown of what is installed where, use \fBnpm ls\fP\|\. -.SS Publishing -.P -Upon publishing, npm will look in the \fBnode_modules\fP folder\. If any of -the items there are not in the \fBbundledDependencies\fP array, then they will -not be included in the package tarball\. -.P -This allows a package maintainer to install all of their dependencies -(and dev dependencies) locally, but only re\-publish those items that -cannot be found elsewhere\. See npm help 5 \fBpackage\.json\fP for more information\. -.SH SEE ALSO -.RS 0 -.IP \(bu 2 -npm help 5 package\.json -.IP \(bu 2 -npm help install -.IP \(bu 2 -npm help pack -.IP \(bu 2 -npm help cache -.IP \(bu 2 -npm help config -.IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help publish - -.RE - diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 deleted file mode 100644 index 2da094fcc68544..00000000000000 --- a/deps/npm/man/man5/npm-global.5 +++ /dev/null @@ -1,226 +0,0 @@ -.TH "NPM\-FOLDERS" "5" "October 2019" "" "" -.SH "NAME" -\fBnpm-folders\fR \- Folder Structures Used by npm -.SH DESCRIPTION -.P -npm puts various things on your computer\. That's its job\. -.P -This document will tell you what it puts where\. -.SS tl;dr -.RS 0 -.IP \(bu 2 -Local install (default): puts stuff in \fB\|\./node_modules\fP of the current -package root\. -.IP \(bu 2 -Global install (with \fB\-g\fP): puts stuff in /usr/local or wherever node -is installed\. -.IP \(bu 2 -Install it \fBlocally\fR if you're going to \fBrequire()\fP it\. -.IP \(bu 2 -Install it \fBglobally\fR if you're going to run it on the command line\. -.IP \(bu 2 -If you need both, then install it in both places, or use \fBnpm link\fP\|\. - -.RE -.SS prefix Configuration -.P -The \fBprefix\fP config defaults to the location where node is installed\. -On most systems, this is \fB/usr/local\fP\|\. On Windows, it's \fB%AppData%\\npm\fP\|\. -On Unix systems, it's one level up, since node is typically installed at -\fB{prefix}/bin/node\fP rather than \fB{prefix}/node\.exe\fP\|\. -.P -When the \fBglobal\fP flag is set, npm installs things into this prefix\. -When it is not set, it uses the root of the current package, or the -current working directory if not in a package already\. -.SS Node Modules -.P -Packages are dropped into the \fBnode_modules\fP folder under the \fBprefix\fP\|\. -When installing locally, this means that you can -\fBrequire("packagename")\fP to load its main module, or -\fBrequire("packagename/lib/path/to/sub/module")\fP to load other modules\. -.P -Global installs on Unix systems go to \fB{prefix}/lib/node_modules\fP\|\. -Global installs on Windows go to \fB{prefix}/node_modules\fP (that is, no -\fBlib\fP folder\.) -.P -Scoped packages are installed the same way, except they are grouped together -in a sub\-folder of the relevant \fBnode_modules\fP folder with the name of that -scope prefix by the @ symbol, e\.g\. \fBnpm install @myorg/package\fP would place -the package in \fB{prefix}/node_modules/@myorg/package\fP\|\. See npm help 7 \fBscope\fP for -more details\. -.P -If you wish to \fBrequire()\fP a package, then install it locally\. -.SS Executables -.P -When in global mode, executables are linked into \fB{prefix}/bin\fP on Unix, -or directly into \fB{prefix}\fP on Windows\. -.P -When in local mode, executables are linked into -\fB\|\./node_modules/\.bin\fP so that they can be made available to scripts run -through npm\. (For example, so that a test runner will be in the path -when you run \fBnpm test\fP\|\.) -.SS Man Pages -.P -When in global mode, man pages are linked into \fB{prefix}/share/man\fP\|\. -.P -When in local mode, man pages are not installed\. -.P -Man pages are not installed on Windows systems\. -.SS Cache -.P -See npm help \fBnpm\-cache\fP\|\. Cache files are stored in \fB~/\.npm\fP on Posix, or -\fB%AppData%/npm\-cache\fP on Windows\. -.P -This is controlled by the \fBcache\fP configuration param\. -.SS Temp Files -.P -Temporary files are stored by default in the folder specified by the -\fBtmp\fP config, which defaults to the TMPDIR, TMP, or TEMP environment -variables, or \fB/tmp\fP on Unix and \fBc:\\windows\\temp\fP on Windows\. -.P -Temp files are given a unique folder under this root for each run of the -program, and are deleted upon successful exit\. -.SH More Information -.P -When installing locally, npm first tries to find an appropriate -\fBprefix\fP folder\. This is so that \fBnpm install foo@1\.2\.3\fP will install -to the sensible root of your package, even if you happen to have \fBcd\fPed -into some other folder\. -.P -Starting at the $PWD, npm will walk up the folder tree checking for a -folder that contains either a \fBpackage\.json\fP file, or a \fBnode_modules\fP -folder\. If such a thing is found, then that is treated as the effective -"current directory" for the purpose of running npm commands\. (This -behavior is inspired by and similar to git's \.git\-folder seeking -logic when running git commands in a working dir\.) -.P -If no package root is found, then the current folder is used\. -.P -When you run \fBnpm install foo@1\.2\.3\fP, then the package is loaded into -the cache, and then unpacked into \fB\|\./node_modules/foo\fP\|\. Then, any of -foo's dependencies are similarly unpacked into -\fB\|\./node_modules/foo/node_modules/\.\.\.\fP\|\. -.P -Any bin files are symlinked to \fB\|\./node_modules/\.bin/\fP, so that they may -be found by npm scripts when necessary\. -.SS Global Installation -.P -If the \fBglobal\fP configuration is set to true, then npm will -install packages "globally"\. -.P -For global installation, packages are installed roughly the same way, -but using the folders described above\. -.SS Cycles, Conflicts, and Folder Parsimony -.P -Cycles are handled using the property of node's module system that it -walks up the directories looking for \fBnode_modules\fP folders\. So, at every -stage, if a package is already installed in an ancestor \fBnode_modules\fP -folder, then it is not installed at the current location\. -.P -Consider the case above, where \fBfoo \-> bar \-> baz\fP\|\. Imagine if, in -addition to that, baz depended on bar, so you'd have: -\fBfoo \-> bar \-> baz \-> bar \-> baz \.\.\.\fP\|\. However, since the folder -structure is: \fBfoo/node_modules/bar/node_modules/baz\fP, there's no need to -put another copy of bar into \fB\|\.\.\./baz/node_modules\fP, since when it calls -require("bar"), it will get the copy that is installed in -\fBfoo/node_modules/bar\fP\|\. -.P -This shortcut is only used if the exact same -version would be installed in multiple nested \fBnode_modules\fP folders\. It -is still possible to have \fBa/node_modules/b/node_modules/a\fP if the two -"a" packages are different versions\. However, without repeating the -exact same package multiple times, an infinite regress will always be -prevented\. -.P -Another optimization can be made by installing dependencies at the -highest level possible, below the localized "target" folder\. -.SS Example -.P -Consider this dependency graph: -.P -.RS 2 -.nf -foo -+\-\- blerg@1\.2\.5 -+\-\- bar@1\.2\.3 -| +\-\- blerg@1\.x (latest=1\.3\.7) -| +\-\- baz@2\.x -| | `\-\- quux@3\.x -| | `\-\- bar@1\.2\.3 (cycle) -| `\-\- asdf@* -`\-\- baz@1\.2\.3 - `\-\- quux@3\.x - `\-\- bar -.fi -.RE -.P -In this case, we might expect a folder structure like this: -.P -.RS 2 -.nf -foo -+\-\- node_modules - +\-\- blerg (1\.2\.5) <\-\-\-[A] - +\-\- bar (1\.2\.3) <\-\-\-[B] - | `\-\- node_modules - | +\-\- baz (2\.0\.2) <\-\-\-[C] - | | `\-\- node_modules - | | `\-\- quux (3\.2\.0) - | `\-\- asdf (2\.3\.4) - `\-\- baz (1\.2\.3) <\-\-\-[D] - `\-\- node_modules - `\-\- quux (3\.2\.0) <\-\-\-[E] -.fi -.RE -.P -Since foo depends directly on \fBbar@1\.2\.3\fP and \fBbaz@1\.2\.3\fP, those are -installed in foo's \fBnode_modules\fP folder\. -.P -Even though the latest copy of blerg is 1\.3\.7, foo has a specific -dependency on version 1\.2\.5\. So, that gets installed at [A]\. Since the -parent installation of blerg satisfies bar's dependency on \fBblerg@1\.x\fP, -it does not install another copy under [B]\. -.P -Bar [B] also has dependencies on baz and asdf, so those are installed in -bar's \fBnode_modules\fP folder\. Because it depends on \fBbaz@2\.x\fP, it cannot -re\-use the \fBbaz@1\.2\.3\fP installed in the parent \fBnode_modules\fP folder [D], -and must install its own copy [C]\. -.P -Underneath bar, the \fBbaz \-> quux \-> bar\fP dependency creates a cycle\. -However, because bar is already in quux's ancestry [B], it does not -unpack another copy of bar into that folder\. -.P -Underneath \fBfoo \-> baz\fP [D], quux's [E] folder tree is empty, because its -dependency on bar is satisfied by the parent folder copy installed at [B]\. -.P -For a graphical breakdown of what is installed where, use \fBnpm ls\fP\|\. -.SS Publishing -.P -Upon publishing, npm will look in the \fBnode_modules\fP folder\. If any of -the items there are not in the \fBbundledDependencies\fP array, then they will -not be included in the package tarball\. -.P -This allows a package maintainer to install all of their dependencies -(and dev dependencies) locally, but only re\-publish those items that -cannot be found elsewhere\. See npm help 5 \fBpackage\.json\fP for more information\. -.SH SEE ALSO -.RS 0 -.IP \(bu 2 -npm help 5 package\.json -.IP \(bu 2 -npm help install -.IP \(bu 2 -npm help pack -.IP \(bu 2 -npm help cache -.IP \(bu 2 -npm help config -.IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help publish - -.RE - diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index b995ecbd4ec3a4..d11cb449c019ef 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,7 +1,7 @@ -.TH "NPMRC" "5" "October 2019" "" "" +.TH "NPMRC" "5" "November 2019" "" "" .SH "NAME" \fBnpmrc\fR \- The npm config files -.SH DESCRIPTION +.SS Description .P npm gets its config settings from the command line, environment variables, and \fBnpmrc\fP files\. @@ -9,8 +9,8 @@ variables, and \fBnpmrc\fP files\. The \fBnpm config\fP command can be used to update and edit the contents of the user and global npmrc files\. .P -For a list of available configuration options, see npm help 7 config\. -.SH FILES +For a list of available configuration options, see npm help config\. +.SS Files .P The four relevant files are: .RS 0 @@ -92,18 +92,17 @@ consistent across updates\. Set fields in here using the \fB\|\./configure\fP script that comes with npm\. This is primarily for distribution maintainers to override default configs in a standard and consistent manner\. -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 -npm help 5 folders +npm help folders .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config +npm help config .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help npm .RE - diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/package-json.5 similarity index 93% rename from deps/npm/man/man5/npm-json.5 rename to deps/npm/man/man5/package-json.5 index 0f454b94776f57..01350c641035e1 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/package-json.5 @@ -1,14 +1,14 @@ -.TH "PACKAGE\.JSON" "5" "October 2019" "" "" +.TH "PACKAGE\.JSON" "5" "November 2019" "" "" .SH "NAME" \fBpackage.json\fR \- Specifics of npm's package\.json handling -.SH DESCRIPTION +.SS Description .P This document is all you need to know about what's required in your package\.json file\. It must be actual JSON, not just a JavaScript object literal\. .P A lot of the behavior described in this document is affected by the config -settings described in npm help 7 \fBnpm\-config\fP\|\. -.SH name +settings described in npm help \fBconfig\fP\|\. +.SS name .P If you plan to publish your package, the \fImost\fR important things in your package\.json are the name and version fields as they will be required\. The name @@ -24,7 +24,7 @@ Some rules: The name must be less than or equal to 214 characters\. This includes the scope for scoped packages\. .IP \(bu 2 -The name can't start with a dot or an underscore\. +The names of scoped packages can begin with a dot or an underscore\. This is not permitted without a scope\. .IP \(bu 2 New packages must not have uppercase letters in the name\. .IP \(bu 2 @@ -51,8 +51,8 @@ already, before you get too attached to it\. https://www\.npmjs\.com/ .RE .P A name can be optionally prefixed by a scope, e\.g\. \fB@myorg/mypackage\fP\|\. See -npm help 7 \fBnpm\-scope\fP for more detail\. -.SH version +npm help \fBscope\fP for more detail\. +.SS version .P If you plan to publish your package, the \fImost\fR important things in your package\.json are the name and version fields as they will be required\. The name @@ -64,16 +64,16 @@ Version must be parseable by node\-semver \fIhttps://github\.com/isaacs/node\-semver\fR, which is bundled with npm as a dependency\. (\fBnpm install semver\fP to use it yourself\.) .P -More on version numbers and ranges at npm help 7 semver\. -.SH description +More on version numbers and ranges at npm help semver\. +.SS description .P Put a description in it\. It's a string\. This helps people discover your package, as it's listed in \fBnpm search\fP\|\. -.SH keywords +.SS keywords .P Put keywords in it\. It's an array of strings\. This helps people discover your package as it's listed in \fBnpm search\fP\|\. -.SH homepage +.SS homepage .P The url to the project homepage\. .P @@ -84,7 +84,7 @@ Example: "homepage": "https://github\.com/owner/project#readme" .fi .RE -.SH bugs +.SS bugs .P The url to your project's issue tracker and / or the email address to which issues should be reported\. These are helpful for people who encounter issues @@ -104,7 +104,7 @@ You can specify either one or both values\. If you want to provide only a url, you can specify the value for "bugs" as a simple string instead of an object\. .P If a url is provided, it will be used by the \fBnpm bugs\fP command\. -.SH license +.SS license .P You should specify a license for your package so that people know how they are permitted to use it, and any restrictions you're placing on it\. @@ -188,7 +188,7 @@ unpublished package under any terms: .RE .P Consider also setting \fB"private": true\fP to prevent accidental publication\. -.SH people fields: author, contributors +.SS people fields: author, contributors .P The "author" is one person\. "contributors" is an array of people\. A "person" is an object with a "name" field and optionally "url" and "email", like this: @@ -213,7 +213,30 @@ Or you can shorten that all into a single string, and npm will parse it for you: Both email and url are optional either way\. .P npm also sets a top\-level "maintainers" field with your npm user info\. -.SH files +.SS funding +.P +You can specify an object containing an URL that provides up\-to\-date +information about ways to help fund development of your package: +.P +.RS 2 +.nf +"funding": { + "type" : "individual", + "url" : "http://example\.com/donate" +} + +"funding": { + "type" : "patreon", + "url" : "https://www\.patreon\.com/my\-account" +} +.fi +.RE +.P +Users can use the \fBnpm fund\fP subcommand to list the \fBfunding\fP URLs of all +dependencies of their project, direct and indirect\. A shortcut to visit each +funding url is also available when providing the project name such as: +\fBnpm fund \fP\|\. +.SS files .P The optional \fBfiles\fP field is an array of file patterns that describes the entries to be included when your package is installed as a @@ -288,7 +311,7 @@ Conversely, some files are always ignored: \fBpackage\-lock\.json\fP (use shrinkwrap instead) .RE -.SH main +.SS main .P The main field is a module ID that is the primary entry point to your program\. That is, if your package is named \fBfoo\fP, and a user installs it, and then does @@ -298,12 +321,12 @@ This should be a module ID relative to the root of your package folder\. .P For most modules, it makes the most sense to have a main script and often not much else\. -.SH browser +.SS browser .P If your module is meant to be used client\-side the browser field should be used instead of the main field\. This is helpful to hint users that it might rely on primitives that aren't available in Node\.js modules\. (e\.g\. \fBwindow\fP) -.SH bin +.SS bin .P A lot of packages have one or more executable files that they'd like to install into the PATH\. npm makes this pretty easy (in fact, it uses this @@ -349,7 +372,7 @@ would be the same as this: Please make sure that your file(s) referenced in \fBbin\fP starts with \fB#!/usr/bin/env node\fP, otherwise the scripts are started without the node executable! -.SH man +.SS man .P Specify either a single file or an array of filenames to put in place for the \fBman\fP program to find\. @@ -401,7 +424,7 @@ compressed\. The number dictates which man section the file is installed into\. .RE .P will create entries for \fBman foo\fP and \fBman 2 foo\fP -.SH directories +.SS directories .P The CommonJS Packages \fIhttp://wiki\.commonjs\.org/wiki/Packages/1\.0\fR spec details a few ways that you can indicate the structure of your package using a \fBdirectories\fP @@ -437,7 +460,7 @@ Put example scripts in here\. Someday, it might be exposed in some clever way\. .P Put your tests in here\. It is currently not exposed, but it might be in the future\. -.SH repository +.SS repository .P Specify the place where your code lives\. This is helpful for people who want to contribute\. If the git repo is on GitHub, then the \fBnpm docs\fP @@ -492,14 +515,14 @@ if it is part of a monorepo), you can specify the directory in which it lives: } .fi .RE -.SH scripts +.SS scripts .P The "scripts" property is a dictionary containing script commands that are run at various times in the lifecycle of your package\. The key is the lifecycle event, and the value is the command to run at that point\. .P -See npm help 7 \fBnpm\-scripts\fP to find out more about writing package scripts\. -.SH config +See npm help \fBscripts\fP to find out more about writing package scripts\. +.SS config .P A "config" object can be used to set configuration parameters used in package scripts that persist across upgrades\. For instance, if a package had the @@ -516,9 +539,9 @@ and then had a "start" command that then referenced the \fBnpm_package_config_port\fP environment variable, then the user could override that by doing \fBnpm config set foo:port 8001\fP\|\. .P -See npm help 7 \fBnpm\-config\fP and npm help 7 \fBnpm\-scripts\fP for more on package +See npm help \fBconfig\fP and npm help \fBscripts\fP for more on package configs\. -.SH dependencies +.SS dependencies .P Dependencies are specified in a simple object that maps a package name to a version range\. The version range is a string which has one or more @@ -528,7 +551,7 @@ tarball or git URL\. \fBPlease do not put test harnesses or transpilers in your \fBdependencies\fP object\.\fR See \fBdevDependencies\fP, below\. .P -See npm help 7 semver for more details about specifying version ranges\. +See npm help semver for more details about specifying version ranges\. .RS 0 .IP \(bu 2 \fBversion\fP Must match \fBversion\fP exactly @@ -541,9 +564,9 @@ See npm help 7 semver for more details about specifying version ranges\. .IP \(bu 2 \fB<=version\fP .IP \(bu 2 -\fB~version\fP "Approximately equivalent to version" See npm help 7 semver +\fB~version\fP "Approximately equivalent to version" See npm help semver .IP \(bu 2 -\fB^version\fP "Compatible with version" See npm help 7 semver +\fB^version\fP "Compatible with version" See npm help semver .IP \(bu 2 \fB1\.2\.x\fP 1\.2\.0, 1\.2\.1, etc\., but not 1\.3\.0 .IP \(bu 2 @@ -561,7 +584,7 @@ See npm help 7 semver for more details about specifying version ranges\. .IP \(bu 2 \fBuser/repo\fP See 'GitHub URLs' below .IP \(bu 2 -\fBtag\fP A specific version tagged and published as \fBtag\fP See npm help \fBnpm\-dist\-tag\fP +\fBtag\fP A specific version tagged and published as \fBtag\fP See npm help \fBdist\-tag\fP .IP \(bu 2 \fBpath/path/path\fP See Local Paths \fI#local\-paths\fR below @@ -676,7 +699,7 @@ This feature is helpful for local offline development and creating tests that require npm installing where you don't want to hit an external server, but should not be used when publishing packages to the public registry\. -.SH devDependencies +.SS devDependencies .P If someone is planning on downloading and using your module in their program, then they probably don't want or need to download and build @@ -687,7 +710,7 @@ object\. .P These things will be installed when doing \fBnpm link\fP or \fBnpm install\fP from the root of a package, and can be managed like any other npm -configuration param\. See npm help 7 \fBnpm\-config\fP for more on the topic\. +configuration param\. See npm help \fBconfig\fP for more on the topic\. .P For build steps that are not platform\-specific, such as compiling CoffeeScript or other languages to JavaScript, use the \fBprepare\fP @@ -715,7 +738,7 @@ The \fBprepare\fP script will be run before publishing, so that users can consume the functionality without requiring them to compile it themselves\. In dev mode (ie, locally running \fBnpm install\fP), it'll run this script as well, so that you can test it easily\. -.SH peerDependencies +.SS peerDependencies .P In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a \fBrequire\fP of this host\. @@ -762,7 +785,7 @@ Assuming the host complies with semver \fIhttps://semver\.org/\fR, only changes the host package's major version will break your plugin\. Thus, if you've worked with every 1\.x version of the host package, use \fB"^1\.0"\fP or \fB"1\.x"\fP to express this\. If you depend on features introduced in 1\.5\.2, use \fB">= 1\.5\.2 < 2"\fP\|\. -.SH bundledDependencies +.SS bundledDependencies .P This defines an array of package names that will be bundled when publishing the package\. @@ -795,7 +818,7 @@ awesome\-web\-framework\-1\.0\.0\.tgz\fP\|\. Note that the package names do not any versions, as that information is specified in \fBdependencies\fP\|\. .P If this is spelled \fB"bundleDependencies"\fP, then that is also honored\. -.SH optionalDependencies +.SS optionalDependencies .P If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the \fBoptionalDependencies\fP @@ -828,7 +851,7 @@ if (foo) { .P Entries in \fBoptionalDependencies\fP will override entries of the same name in \fBdependencies\fP, so it's usually best to only put in one place\. -.SH engines +.SS engines .P You can specify the version of node that your stuff works on: .P @@ -856,13 +879,13 @@ are capable of properly installing your program\. For example: .P Unless the user has set the \fBengine\-strict\fP config flag, this field is advisory only and will only produce warnings when your package is installed as a dependency\. -.SH engineStrict +.SS engineStrict .P \fBThis feature was removed in npm 3\.0\.0\fR .P Prior to npm 3\.0\.0, this feature was used to treat this package as if the user had set \fBengine\-strict\fP\|\. It is no longer used\. -.SH os +.SS os .P You can specify which operating systems your module will run on: @@ -886,7 +909,7 @@ The host operating system is determined by \fBprocess\.platform\fP .P It is allowed to both blacklist, and whitelist, although there isn't any good reason to do this\. -.SH cpu +.SS cpu .P If your code only runs on certain cpu architectures, you can specify which ones\. @@ -906,14 +929,14 @@ Like the \fBos\fP option, you can also blacklist architectures: .RE .P The host architecture is determined by \fBprocess\.arch\fP -.SH preferGlobal +.SS preferGlobal .P \fBDEPRECATED\fR .P This option used to trigger an npm warning, but it will no longer warn\. It is purely there for informational purposes\. It is now recommended that you install any binaries as local devDependencies wherever possible\. -.SH private +.SS private .P If you set \fB"private": true\fP in your package\.json, then npm will refuse to publish it\. @@ -923,7 +946,7 @@ you would like to ensure that a given package is only ever published to a specific registry (for example, an internal registry), then use the \fBpublishConfig\fP dictionary described below to override the \fBregistry\fP config param at publish\-time\. -.SH publishConfig +.SS publishConfig .P This is a set of config values that will be used at publish\-time\. It's especially handy if you want to set the tag, registry or access, so that @@ -933,9 +956,9 @@ to the global public registry or that a scoped module is private by default\. Any config values can be overridden, but only "tag", "registry" and "access" probably matter for the purposes of publishing\. .P -See npm help 7 \fBnpm\-config\fP to see the list of config options that can be +See npm help \fBconfig\fP to see the list of config options that can be overridden\. -.SH DEFAULT VALUES +.SS DEFAULT VALUES .P npm will default some values based on package contents\. .RS 0 @@ -955,10 +978,10 @@ are optional\. Lines which start with a \fB#\fP or are blank, will be ignored\. .RE -.SH SEE ALSO +.SS SEE ALSO .RS 0 .IP \(bu 2 -npm help 7 semver +npm help semver .IP \(bu 2 npm help init .IP \(bu 2 @@ -966,8 +989,6 @@ npm help version .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config -.IP \(bu 2 npm help help .IP \(bu 2 npm help install @@ -977,4 +998,3 @@ npm help publish npm help uninstall .RE - diff --git a/deps/npm/man/man5/package-lock.json.5 b/deps/npm/man/man5/package-lock-json.5 similarity index 95% rename from deps/npm/man/man5/package-lock.json.5 rename to deps/npm/man/man5/package-lock-json.5 index d46f66576c3616..36dbbc402341d5 100644 --- a/deps/npm/man/man5/package-lock.json.5 +++ b/deps/npm/man/man5/package-lock-json.5 @@ -1,7 +1,7 @@ -.TH "PACKAGE\-LOCK\.JSON" "5" "October 2019" "" "" +.TH "PACKAGE\-LOCK\.JSON" "5" "November 2019" "" "" .SH "NAME" \fBpackage-lock.json\fR \- A manifestation of the manifest -.SH DESCRIPTION +.SS Description .P \fBpackage\-lock\.json\fP is automatically generated for any operations where npm modifies either the \fBnode_modules\fP tree, or \fBpackage\.json\fP\|\. It describes the @@ -24,13 +24,13 @@ And optimize the installation process by allowing npm to skip repeated metadata .P One key detail about \fBpackage\-lock\.json\fP is that it cannot be published, and it will be ignored if found in any place other than the toplevel package\. It shares -a format with npm help 5 shrinkwrap\.json, which is essentially the same file, but +a format with npm help npm\-shrinkwrap\.json, which is essentially the same file, but allows publication\. This is not recommended unless deploying a CLI tool or otherwise using the publication process for producing production packages\. .P If both \fBpackage\-lock\.json\fP and \fBnpm\-shrinkwrap\.json\fP are present in the root of a package, \fBpackage\-lock\.json\fP will be completely ignored\. -.SH FILE FORMAT +.SS File Format .SS name .P The name of the package this is a package\-lock for\. This must match what's in @@ -136,16 +136,16 @@ should match via normal matching rules a dependency either in our .SS dependencies .P The dependencies of this dependency, exactly as at the top level\. -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 npm help shrinkwrap .IP \(bu 2 -npm help 5 shrinkwrap\.json +npm help shrinkwrap\.json .IP \(bu 2 -npm help 5 package\-locks +npm help package\-locks .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help install diff --git a/deps/npm/man/man5/npm-package-locks.5 b/deps/npm/man/man5/package-locks.5 similarity index 91% rename from deps/npm/man/man5/npm-package-locks.5 rename to deps/npm/man/man5/package-locks.5 index 5540b67ca31b32..ea2e51fc69714c 100644 --- a/deps/npm/man/man5/npm-package-locks.5 +++ b/deps/npm/man/man5/package-locks.5 @@ -1,9 +1,9 @@ -.TH "NPM\-PACKAGE\-LOCKS" "5" "October 2019" "" "" +.TH "PACKAGE\-LOCKS" "5" "November 2019" "" "" .SH "NAME" -\fBnpm-package-locks\fR \- An explanation of npm lockfiles -.SH DESCRIPTION +\fBpackage-locks\fR \- An explanation of npm lockfiles +.SS Description .P -Conceptually, the "input" to npm help install is a npm help 5 package\.json, while its +Conceptually, the "input" to npm help \fBinstall\fP is a npm help package\.json, while its "output" is a fully\-formed \fBnode_modules\fP tree: a representation of the dependencies you declared\. In an ideal world, npm would work like a pure function: the same \fBpackage\.json\fP should produce the exact same \fBnode_modules\fP @@ -90,8 +90,7 @@ author are not the same person, there's no way for A's author to say that he or she does not want to pull in newly published versions of C when B hasn't changed at all\. .P -To prevent this potential issue, npm uses npm help 5 package\-lock\.json or, if present, -npm help 5 shrinkwrap\.json\. These files are called package locks, or lockfiles\. +To prevent this potential issue, npm uses npm help package\-lock\.json or, if present, npm help npm\-shrinkwrap\.json\. These files are called package locks, or lockfiles\. .P Whenever you run \fBnpm install\fP, npm generates or updates your package lock, which will look something like this: @@ -121,7 +120,7 @@ which will look something like this: This file describes an \fIexact\fR, and more importantly \fIreproducible\fR \fBnode_modules\fP tree\. Once it's present, any future installation will base its work off this file, instead of recalculating dependency versions off -npm help 5 package\.json\. +npm help package\.json\. .P The presence of a package lock changes the installation behavior such that: .RS 0 @@ -145,9 +144,9 @@ file: .P .RS 2 .nf -"scripts": { - "postshrinkwrap": "json \-I \-e \\"this\.myMetadata = $MY_APP_METADATA\\"" -} + "scripts": { + "postshrinkwrap": "json \-I \-e \\"this\.myMetadata = $MY_APP_METADATA\\"" + } .fi .RE .SS Using locked packages @@ -185,16 +184,16 @@ npm\-merge\-driver install \-g\fP will let you do this, and even works with pre\-\fBnpm@5\.7\.0\fP versions of npm 5, albeit a bit more noisily\. Note that if \fBpackage\.json\fP itself conflicts, you will have to resolve that by hand and run \fBnpm install\fP manually, even with the merge driver\. -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 https://medium\.com/@sdboyer/so\-you\-want\-to\-write\-a\-package\-manager\-4ae9c17d9527 .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help 5 package\-lock\.json +npm help package\-lock\.json .IP \(bu 2 -npm help 5 shrinkwrap\.json +npm help shrinkwrap\.json .IP \(bu 2 npm help shrinkwrap diff --git a/deps/npm/man/man5/package.json.5 b/deps/npm/man/man5/package.json.5 deleted file mode 100644 index 0f454b94776f57..00000000000000 --- a/deps/npm/man/man5/package.json.5 +++ /dev/null @@ -1,980 +0,0 @@ -.TH "PACKAGE\.JSON" "5" "October 2019" "" "" -.SH "NAME" -\fBpackage.json\fR \- Specifics of npm's package\.json handling -.SH DESCRIPTION -.P -This document is all you need to know about what's required in your package\.json -file\. It must be actual JSON, not just a JavaScript object literal\. -.P -A lot of the behavior described in this document is affected by the config -settings described in npm help 7 \fBnpm\-config\fP\|\. -.SH name -.P -If you plan to publish your package, the \fImost\fR important things in your -package\.json are the name and version fields as they will be required\. The name -and version together form an identifier that is assumed to be completely unique\. -Changes to the package should come along with changes to the version\. If you don't -plan to publish your package, the name and version fields are optional\. -.P -The name is what your thing is called\. -.P -Some rules: -.RS 0 -.IP \(bu 2 -The name must be less than or equal to 214 characters\. This includes the scope for -scoped packages\. -.IP \(bu 2 -The name can't start with a dot or an underscore\. -.IP \(bu 2 -New packages must not have uppercase letters in the name\. -.IP \(bu 2 -The name ends up being part of a URL, an argument on the command line, and a -folder name\. Therefore, the name can't contain any non\-URL\-safe characters\. - -.RE -.P -Some tips: -.RS 0 -.IP \(bu 2 -Don't use the same name as a core Node module\. -.IP \(bu 2 -Don't put "js" or "node" in the name\. It's assumed that it's js, since you're -writing a package\.json file, and you can specify the engine using the "engines" -field\. (See below\.) -.IP \(bu 2 -The name will probably be passed as an argument to require(), so it should -be something short, but also reasonably descriptive\. -.IP \(bu 2 -You may want to check the npm registry to see if there's something by that name -already, before you get too attached to it\. https://www\.npmjs\.com/ - -.RE -.P -A name can be optionally prefixed by a scope, e\.g\. \fB@myorg/mypackage\fP\|\. See -npm help 7 \fBnpm\-scope\fP for more detail\. -.SH version -.P -If you plan to publish your package, the \fImost\fR important things in your -package\.json are the name and version fields as they will be required\. The name -and version together form an identifier that is assumed to be completely unique\. -Changes to the package should come along with changes to the version\. If you don't -plan to publish your package, the name and version fields are optional\. -.P -Version must be parseable by -node\-semver \fIhttps://github\.com/isaacs/node\-semver\fR, which is bundled -with npm as a dependency\. (\fBnpm install semver\fP to use it yourself\.) -.P -More on version numbers and ranges at npm help 7 semver\. -.SH description -.P -Put a description in it\. It's a string\. This helps people discover your -package, as it's listed in \fBnpm search\fP\|\. -.SH keywords -.P -Put keywords in it\. It's an array of strings\. This helps people -discover your package as it's listed in \fBnpm search\fP\|\. -.SH homepage -.P -The url to the project homepage\. -.P -Example: -.P -.RS 2 -.nf -"homepage": "https://github\.com/owner/project#readme" -.fi -.RE -.SH bugs -.P -The url to your project's issue tracker and / or the email address to which -issues should be reported\. These are helpful for people who encounter issues -with your package\. -.P -It should look like this: -.P -.RS 2 -.nf -{ "url" : "https://github\.com/owner/project/issues" -, "email" : "project@hostname\.com" -} -.fi -.RE -.P -You can specify either one or both values\. If you want to provide only a url, -you can specify the value for "bugs" as a simple string instead of an object\. -.P -If a url is provided, it will be used by the \fBnpm bugs\fP command\. -.SH license -.P -You should specify a license for your package so that people know how they are -permitted to use it, and any restrictions you're placing on it\. -.P -If you're using a common license such as BSD\-2\-Clause or MIT, add a -current SPDX license identifier for the license you're using, like this: -.P -.RS 2 -.nf -{ "license" : "BSD\-3\-Clause" } -.fi -.RE -.P -You can check the full list of SPDX license IDs \fIhttps://spdx\.org/licenses/\fR\|\. -Ideally you should pick one that is -OSI \fIhttps://opensource\.org/licenses/alphabetical\fR approved\. -.P -If your package is licensed under multiple common licenses, use an SPDX license -expression syntax version 2\.0 string \fIhttps://www\.npmjs\.com/package/spdx\fR, like this: -.P -.RS 2 -.nf -{ "license" : "(ISC OR GPL\-3\.0)" } -.fi -.RE -.P -If you are using a license that hasn't been assigned an SPDX identifier, or if -you are using a custom license, use a string value like this one: -.P -.RS 2 -.nf -{ "license" : "SEE LICENSE IN " } -.fi -.RE -.P -Then include a file named \fB\fP at the top level of the package\. -.P -Some old packages used license objects or a "licenses" property containing an -array of license objects: -.P -.RS 2 -.nf -// Not valid metadata -{ "license" : - { "type" : "ISC" - , "url" : "https://opensource\.org/licenses/ISC" - } -} - -// Not valid metadata -{ "licenses" : - [ - { "type": "MIT" - , "url": "https://www\.opensource\.org/licenses/mit\-license\.php" - } - , { "type": "Apache\-2\.0" - , "url": "https://opensource\.org/licenses/apache2\.0\.php" - } - ] -} -.fi -.RE -.P -Those styles are now deprecated\. Instead, use SPDX expressions, like this: -.P -.RS 2 -.nf -{ "license": "ISC" } - -{ "license": "(MIT OR Apache\-2\.0)" } -.fi -.RE -.P -Finally, if you do not wish to grant others the right to use a private or -unpublished package under any terms: -.P -.RS 2 -.nf -{ "license": "UNLICENSED" } -.fi -.RE -.P -Consider also setting \fB"private": true\fP to prevent accidental publication\. -.SH people fields: author, contributors -.P -The "author" is one person\. "contributors" is an array of people\. A "person" -is an object with a "name" field and optionally "url" and "email", like this: -.P -.RS 2 -.nf -{ "name" : "Barney Rubble" -, "email" : "b@rubble\.com" -, "url" : "http://barnyrubble\.tumblr\.com/" -} -.fi -.RE -.P -Or you can shorten that all into a single string, and npm will parse it for you: -.P -.RS 2 -.nf -"Barney Rubble (http://barnyrubble\.tumblr\.com/)" -.fi -.RE -.P -Both email and url are optional either way\. -.P -npm also sets a top\-level "maintainers" field with your npm user info\. -.SH files -.P -The optional \fBfiles\fP field is an array of file patterns that describes -the entries to be included when your package is installed as a -dependency\. File patterns follow a similar syntax to \fB\|\.gitignore\fP, but -reversed: including a file, directory, or glob pattern (\fB*\fP, \fB**/*\fP, and such) -will make it so that file is included in the tarball when it's packed\. Omitting -the field will make it default to \fB["*"]\fP, which means it will include all files\. -.P -Some special files and directories are also included or excluded regardless of -whether they exist in the \fBfiles\fP array (see below)\. -.P -You can also provide a \fB\|\.npmignore\fP file in the root of your package or -in subdirectories, which will keep files from being included\. At the -root of your package it will not override the "files" field, but in -subdirectories it will\. The \fB\|\.npmignore\fP file works just like a -\fB\|\.gitignore\fP\|\. If there is a \fB\|\.gitignore\fP file, and \fB\|\.npmignore\fP is -missing, \fB\|\.gitignore\fP\|'s contents will be used instead\. -.P -Files included with the "package\.json#files" field \fIcannot\fR be excluded -through \fB\|\.npmignore\fP or \fB\|\.gitignore\fP\|\. -.P -Certain files are always included, regardless of settings: -.RS 0 -.IP \(bu 2 -\fBpackage\.json\fP -.IP \(bu 2 -\fBREADME\fP -.IP \(bu 2 -\fBCHANGES\fP / \fBCHANGELOG\fP / \fBHISTORY\fP -.IP \(bu 2 -\fBLICENSE\fP / \fBLICENCE\fP -.IP \(bu 2 -\fBNOTICE\fP -.IP \(bu 2 -The file in the "main" field - -.RE -.P -\fBREADME\fP, \fBCHANGES\fP, \fBLICENSE\fP & \fBNOTICE\fP can have any case and extension\. -.P -Conversely, some files are always ignored: -.RS 0 -.IP \(bu 2 -\fB\|\.git\fP -.IP \(bu 2 -\fBCVS\fP -.IP \(bu 2 -\fB\|\.svn\fP -.IP \(bu 2 -\fB\|\.hg\fP -.IP \(bu 2 -\fB\|\.lock\-wscript\fP -.IP \(bu 2 -\fB\|\.wafpickle\-N\fP -.IP \(bu 2 -\fB\|\.*\.swp\fP -.IP \(bu 2 -\fB\|\.DS_Store\fP -.IP \(bu 2 -\fB\|\._*\fP -.IP \(bu 2 -\fBnpm\-debug\.log\fP -.IP \(bu 2 -\fB\|\.npmrc\fP -.IP \(bu 2 -\fBnode_modules\fP -.IP \(bu 2 -\fBconfig\.gypi\fP -.IP \(bu 2 -\fB*\.orig\fP -.IP \(bu 2 -\fBpackage\-lock\.json\fP (use shrinkwrap instead) - -.RE -.SH main -.P -The main field is a module ID that is the primary entry point to your program\. -That is, if your package is named \fBfoo\fP, and a user installs it, and then does -\fBrequire("foo")\fP, then your main module's exports object will be returned\. -.P -This should be a module ID relative to the root of your package folder\. -.P -For most modules, it makes the most sense to have a main script and often not -much else\. -.SH browser -.P -If your module is meant to be used client\-side the browser field should be -used instead of the main field\. This is helpful to hint users that it might -rely on primitives that aren't available in Node\.js modules\. (e\.g\. \fBwindow\fP) -.SH bin -.P -A lot of packages have one or more executable files that they'd like to -install into the PATH\. npm makes this pretty easy (in fact, it uses this -feature to install the "npm" executable\.) -.P -To use this, supply a \fBbin\fP field in your package\.json which is a map of -command name to local file name\. On install, npm will symlink that file into -\fBprefix/bin\fP for global installs, or \fB\|\./node_modules/\.bin/\fP for local -installs\. -.P -For example, myapp could have this: -.P -.RS 2 -.nf -{ "bin" : { "myapp" : "\./cli\.js" } } -.fi -.RE -.P -So, when you install myapp, it'll create a symlink from the \fBcli\.js\fP script to -\fB/usr/local/bin/myapp\fP\|\. -.P -If you have a single executable, and its name should be the name -of the package, then you can just supply it as a string\. For example: -.P -.RS 2 -.nf -{ "name": "my\-program" -, "version": "1\.2\.5" -, "bin": "\./path/to/program" } -.fi -.RE -.P -would be the same as this: -.P -.RS 2 -.nf -{ "name": "my\-program" -, "version": "1\.2\.5" -, "bin" : { "my\-program" : "\./path/to/program" } } -.fi -.RE -.P -Please make sure that your file(s) referenced in \fBbin\fP starts with -\fB#!/usr/bin/env node\fP, otherwise the scripts are started without the node -executable! -.SH man -.P -Specify either a single file or an array of filenames to put in place for the -\fBman\fP program to find\. -.P -If only a single file is provided, then it's installed such that it is the -result from \fBman \fP, regardless of its actual filename\. For example: -.P -.RS 2 -.nf -{ "name" : "foo" -, "version" : "1\.2\.3" -, "description" : "A packaged foo fooer for fooing foos" -, "main" : "foo\.js" -, "man" : "\./man/doc\.1" -} -.fi -.RE -.P -would link the \fB\|\./man/doc\.1\fP file in such that it is the target for \fBman foo\fP -.P -If the filename doesn't start with the package name, then it's prefixed\. -So, this: -.P -.RS 2 -.nf -{ "name" : "foo" -, "version" : "1\.2\.3" -, "description" : "A packaged foo fooer for fooing foos" -, "main" : "foo\.js" -, "man" : [ "\./man/foo\.1", "\./man/bar\.1" ] -} -.fi -.RE -.P -will create files to do \fBman foo\fP and \fBman foo\-bar\fP\|\. -.P -Man files must end with a number, and optionally a \fB\|\.gz\fP suffix if they are -compressed\. The number dictates which man section the file is installed into\. -.P -.RS 2 -.nf -{ "name" : "foo" -, "version" : "1\.2\.3" -, "description" : "A packaged foo fooer for fooing foos" -, "main" : "foo\.js" -, "man" : [ "\./man/foo\.1", "\./man/foo\.2" ] -} -.fi -.RE -.P -will create entries for \fBman foo\fP and \fBman 2 foo\fP -.SH directories -.P -The CommonJS Packages \fIhttp://wiki\.commonjs\.org/wiki/Packages/1\.0\fR spec details a -few ways that you can indicate the structure of your package using a \fBdirectories\fP -object\. If you look at npm's package\.json \fIhttps://registry\.npmjs\.org/npm/latest\fR, -you'll see that it has directories for doc, lib, and man\. -.P -In the future, this information may be used in other creative ways\. -.SS directories\.lib -.P -Tell people where the bulk of your library is\. Nothing special is done -with the lib folder in any way, but it's useful meta info\. -.SS directories\.bin -.P -If you specify a \fBbin\fP directory in \fBdirectories\.bin\fP, all the files in -that folder will be added\. -.P -Because of the way the \fBbin\fP directive works, specifying both a -\fBbin\fP path and setting \fBdirectories\.bin\fP is an error\. If you want to -specify individual files, use \fBbin\fP, and for all the files in an -existing \fBbin\fP directory, use \fBdirectories\.bin\fP\|\. -.SS directories\.man -.P -A folder that is full of man pages\. Sugar to generate a "man" array by -walking the folder\. -.SS directories\.doc -.P -Put markdown files in here\. Eventually, these will be displayed nicely, -maybe, someday\. -.SS directories\.example -.P -Put example scripts in here\. Someday, it might be exposed in some clever way\. -.SS directories\.test -.P -Put your tests in here\. It is currently not exposed, but it might be in the -future\. -.SH repository -.P -Specify the place where your code lives\. This is helpful for people who -want to contribute\. If the git repo is on GitHub, then the \fBnpm docs\fP -command will be able to find you\. -.P -Do it like this: -.P -.RS 2 -.nf -"repository": { - "type" : "git", - "url" : "https://github\.com/npm/cli\.git" -} - -"repository": { - "type" : "svn", - "url" : "https://v8\.googlecode\.com/svn/trunk/" -} -.fi -.RE -.P -The URL should be a publicly available (perhaps read\-only) url that can be handed -directly to a VCS program without any modification\. It should not be a url to an -html project page that you put in your browser\. It's for computers\. -.P -For GitHub, GitHub gist, Bitbucket, or GitLab repositories you can use the same -shortcut syntax you use for \fBnpm install\fP: -.P -.RS 2 -.nf -"repository": "npm/npm" - -"repository": "github:user/repo" - -"repository": "gist:11081aaa281" - -"repository": "bitbucket:user/repo" - -"repository": "gitlab:user/repo" -.fi -.RE -.P -If the \fBpackage\.json\fP for your package is not in the root directory (for example -if it is part of a monorepo), you can specify the directory in which it lives: -.P -.RS 2 -.nf -"repository": { - "type" : "git", - "url" : "https://github\.com/facebook/react\.git", - "directory": "packages/react\-dom" -} -.fi -.RE -.SH scripts -.P -The "scripts" property is a dictionary containing script commands that are run -at various times in the lifecycle of your package\. The key is the lifecycle -event, and the value is the command to run at that point\. -.P -See npm help 7 \fBnpm\-scripts\fP to find out more about writing package scripts\. -.SH config -.P -A "config" object can be used to set configuration parameters used in package -scripts that persist across upgrades\. For instance, if a package had the -following: -.P -.RS 2 -.nf -{ "name" : "foo" -, "config" : { "port" : "8080" } } -.fi -.RE -.P -and then had a "start" command that then referenced the -\fBnpm_package_config_port\fP environment variable, then the user could -override that by doing \fBnpm config set foo:port 8001\fP\|\. -.P -See npm help 7 \fBnpm\-config\fP and npm help 7 \fBnpm\-scripts\fP for more on package -configs\. -.SH dependencies -.P -Dependencies are specified in a simple object that maps a package name to a -version range\. The version range is a string which has one or more -space\-separated descriptors\. Dependencies can also be identified with a -tarball or git URL\. -.P -\fBPlease do not put test harnesses or transpilers in your -\fBdependencies\fP object\.\fR See \fBdevDependencies\fP, below\. -.P -See npm help 7 semver for more details about specifying version ranges\. -.RS 0 -.IP \(bu 2 -\fBversion\fP Must match \fBversion\fP exactly -.IP \(bu 2 -\fB>version\fP Must be greater than \fBversion\fP -.IP \(bu 2 -\fB>=version\fP etc -.IP \(bu 2 -\fB=version1 <=version2\fP\|\. -.IP \(bu 2 -\fBrange1 || range2\fP Passes if either range1 or range2 are satisfied\. -.IP \(bu 2 -\fBgit\.\.\.\fP See 'Git URLs as Dependencies' below -.IP \(bu 2 -\fBuser/repo\fP See 'GitHub URLs' below -.IP \(bu 2 -\fBtag\fP A specific version tagged and published as \fBtag\fP See npm help \fBnpm\-dist\-tag\fP -.IP \(bu 2 -\fBpath/path/path\fP See Local Paths \fI#local\-paths\fR below - -.RE -.P -For example, these are all valid: -.P -.RS 2 -.nf -{ "dependencies" : - { "foo" : "1\.0\.0 \- 2\.9999\.9999" - , "bar" : ">=1\.0\.2 <2\.1\.2" - , "baz" : ">1\.0\.2 <=2\.3\.4" - , "boo" : "2\.0\.1" - , "qux" : "<1\.0\.0 || >=2\.3\.1 <2\.4\.5 || >=2\.5\.2 <3\.0\.0" - , "asd" : "http://asdf\.com/asdf\.tar\.gz" - , "til" : "~1\.2" - , "elf" : "~1\.2\.3" - , "two" : "2\.x" - , "thr" : "3\.3\.x" - , "lat" : "latest" - , "dyl" : "file:\.\./dyl" - } -} -.fi -.RE -.SS URLs as Dependencies -.P -You may specify a tarball URL in place of a version range\. -.P -This tarball will be downloaded and installed locally to your package at -install time\. -.SS Git URLs as Dependencies -.P -Git urls are of the form: -.P -.RS 2 -.nf -://[[:]@][:][:][/][# | #semver:] -.fi -.RE -.P -\fB\fP is one of \fBgit\fP, \fBgit+ssh\fP, \fBgit+http\fP, \fBgit+https\fP, or -\fBgit+file\fP\|\. -.P -If \fB#\fP is provided, it will be used to clone exactly that -commit\. If the commit\-ish has the format \fB#semver:\fP, \fB\fP can -be any valid semver range or exact version, and npm will look for any tags -or refs matching that range in the remote repository, much as it would for a -registry dependency\. If neither \fB#\fP or \fB#semver:\fP is -specified, then \fBmaster\fP is used\. -.P -Examples: -.P -.RS 2 -.nf -git+ssh://git@github\.com:npm/cli\.git#v1\.0\.27 -git+ssh://git@github\.com:npm/cli#semver:^5\.0 -git+https://isaacs@github\.com/npm/cli\.git -git://github\.com/npm/cli\.git#v1\.0\.27 -.fi -.RE -.SS GitHub URLs -.P -As of version 1\.1\.65, you can refer to GitHub urls as just "foo": -"user/foo\-project"\. Just as with git URLs, a \fBcommit\-ish\fP suffix can be -included\. For example: -.P -.RS 2 -.nf -{ - "name": "foo", - "version": "0\.0\.0", - "dependencies": { - "express": "expressjs/express", - "mocha": "mochajs/mocha#4727d357ea", - "module": "user/repo#feature\\/branch" - } -} -.fi -.RE -.SS Local Paths -.P -As of version 2\.0\.0 you can provide a path to a local directory that contains a -package\. Local paths can be saved using \fBnpm install \-S\fP or -\fBnpm install \-\-save\fP, using any of these forms: -.P -.RS 2 -.nf -\|\.\./foo/bar -~/foo/bar -\|\./foo/bar -/foo/bar -.fi -.RE -.P -in which case they will be normalized to a relative path and added to your -\fBpackage\.json\fP\|\. For example: -.P -.RS 2 -.nf -{ - "name": "baz", - "dependencies": { - "bar": "file:\.\./foo/bar" - } -} -.fi -.RE -.P -This feature is helpful for local offline development and creating -tests that require npm installing where you don't want to hit an -external server, but should not be used when publishing packages -to the public registry\. -.SH devDependencies -.P -If someone is planning on downloading and using your module in their -program, then they probably don't want or need to download and build -the external test or documentation framework that you use\. -.P -In this case, it's best to map these additional items in a \fBdevDependencies\fP -object\. -.P -These things will be installed when doing \fBnpm link\fP or \fBnpm install\fP -from the root of a package, and can be managed like any other npm -configuration param\. See npm help 7 \fBnpm\-config\fP for more on the topic\. -.P -For build steps that are not platform\-specific, such as compiling -CoffeeScript or other languages to JavaScript, use the \fBprepare\fP -script to do this, and make the required package a devDependency\. -.P -For example: -.P -.RS 2 -.nf -{ "name": "ethopia\-waza", - "description": "a delightfully fruity coffee varietal", - "version": "1\.2\.3", - "devDependencies": { - "coffee\-script": "~1\.6\.3" - }, - "scripts": { - "prepare": "coffee \-o lib/ \-c src/waza\.coffee" - }, - "main": "lib/waza\.js" -} -.fi -.RE -.P -The \fBprepare\fP script will be run before publishing, so that users -can consume the functionality without requiring them to compile it -themselves\. In dev mode (ie, locally running \fBnpm install\fP), it'll -run this script as well, so that you can test it easily\. -.SH peerDependencies -.P -In some cases, you want to express the compatibility of your package with a -host tool or library, while not necessarily doing a \fBrequire\fP of this host\. -This is usually referred to as a \fIplugin\fR\|\. Notably, your module may be exposing -a specific interface, expected and specified by the host documentation\. -.P -For example: -.P -.RS 2 -.nf -{ - "name": "tea\-latte", - "version": "1\.3\.5", - "peerDependencies": { - "tea": "2\.x" - } -} -.fi -.RE -.P -This ensures your package \fBtea\-latte\fP can be installed \fIalong\fR with the second -major version of the host package \fBtea\fP only\. \fBnpm install tea\-latte\fP could -possibly yield the following dependency graph: -.P -.RS 2 -.nf -├── tea\-latte@1\.3\.5 -└── tea@2\.2\.0 -.fi -.RE -.P -\fBNOTE: npm versions 1 and 2 will automatically install \fBpeerDependencies\fP if -they are not explicitly depended upon higher in the dependency tree\. In the -next major version of npm (npm@3), this will no longer be the case\. You will -receive a warning that the peerDependency is not installed instead\.\fR The -behavior in npms 1 & 2 was frequently confusing and could easily put you into -dependency hell, a situation that npm is designed to avoid as much as possible\. -.P -Trying to install another plugin with a conflicting requirement will cause an -error\. For this reason, make sure your plugin requirement is as broad as -possible, and not to lock it down to specific patch versions\. -.P -Assuming the host complies with semver \fIhttps://semver\.org/\fR, only changes in -the host package's major version will break your plugin\. Thus, if you've worked -with every 1\.x version of the host package, use \fB"^1\.0"\fP or \fB"1\.x"\fP to express -this\. If you depend on features introduced in 1\.5\.2, use \fB">= 1\.5\.2 < 2"\fP\|\. -.SH bundledDependencies -.P -This defines an array of package names that will be bundled when publishing -the package\. -.P -In cases where you need to preserve npm packages locally or have them -available through a single file download, you can bundle the packages in a -tarball file by specifying the package names in the \fBbundledDependencies\fP -array and executing \fBnpm pack\fP\|\. -.P -For example: -.P -If we define a package\.json like this: -.P -.RS 2 -.nf -{ - "name": "awesome\-web\-framework", - "version": "1\.0\.0", - "bundledDependencies": [ - "renderized", "super\-streams" - ] -} -.fi -.RE -.P -we can obtain \fBawesome\-web\-framework\-1\.0\.0\.tgz\fP file by running \fBnpm pack\fP\|\. -This file contains the dependencies \fBrenderized\fP and \fBsuper\-streams\fP which -can be installed in a new project by executing \fBnpm install -awesome\-web\-framework\-1\.0\.0\.tgz\fP\|\. Note that the package names do not include -any versions, as that information is specified in \fBdependencies\fP\|\. -.P -If this is spelled \fB"bundleDependencies"\fP, then that is also honored\. -.SH optionalDependencies -.P -If a dependency can be used, but you would like npm to proceed if it cannot be -found or fails to install, then you may put it in the \fBoptionalDependencies\fP -object\. This is a map of package name to version or url, just like the -\fBdependencies\fP object\. The difference is that build failures do not cause -installation to fail\. -.P -It is still your program's responsibility to handle the lack of the -dependency\. For example, something like this: -.P -.RS 2 -.nf -try { - var foo = require('foo') - var fooVersion = require('foo/package\.json')\.version -} catch (er) { - foo = null -} -if ( notGoodFooVersion(fooVersion) ) { - foo = null -} - -// \.\. then later in your program \.\. - -if (foo) { - foo\.doFooThings() -} -.fi -.RE -.P -Entries in \fBoptionalDependencies\fP will override entries of the same name in -\fBdependencies\fP, so it's usually best to only put in one place\. -.SH engines -.P -You can specify the version of node that your stuff works on: -.P -.RS 2 -.nf -{ "engines" : { "node" : ">=0\.10\.3 <0\.12" } } -.fi -.RE -.P -And, like with dependencies, if you don't specify the version (or if you -specify "*" as the version), then any version of node will do\. -.P -If you specify an "engines" field, then npm will require that "node" be -somewhere on that list\. If "engines" is omitted, then npm will just assume -that it works on node\. -.P -You can also use the "engines" field to specify which versions of npm -are capable of properly installing your program\. For example: -.P -.RS 2 -.nf -{ "engines" : { "npm" : "~1\.0\.20" } } -.fi -.RE -.P -Unless the user has set the \fBengine\-strict\fP config flag, this -field is advisory only and will only produce warnings when your package is installed as a dependency\. -.SH engineStrict -.P -\fBThis feature was removed in npm 3\.0\.0\fR -.P -Prior to npm 3\.0\.0, this feature was used to treat this package as if the -user had set \fBengine\-strict\fP\|\. It is no longer used\. -.SH os -.P -You can specify which operating systems your -module will run on: -.P -.RS 2 -.nf -"os" : [ "darwin", "linux" ] -.fi -.RE -.P -You can also blacklist instead of whitelist operating systems, -just prepend the blacklisted os with a '!': -.P -.RS 2 -.nf -"os" : [ "!win32" ] -.fi -.RE -.P -The host operating system is determined by \fBprocess\.platform\fP -.P -It is allowed to both blacklist, and whitelist, although there isn't any -good reason to do this\. -.SH cpu -.P -If your code only runs on certain cpu architectures, -you can specify which ones\. -.P -.RS 2 -.nf -"cpu" : [ "x64", "ia32" ] -.fi -.RE -.P -Like the \fBos\fP option, you can also blacklist architectures: -.P -.RS 2 -.nf -"cpu" : [ "!arm", "!mips" ] -.fi -.RE -.P -The host architecture is determined by \fBprocess\.arch\fP -.SH preferGlobal -.P -\fBDEPRECATED\fR -.P -This option used to trigger an npm warning, but it will no longer warn\. It is -purely there for informational purposes\. It is now recommended that you install -any binaries as local devDependencies wherever possible\. -.SH private -.P -If you set \fB"private": true\fP in your package\.json, then npm will refuse -to publish it\. -.P -This is a way to prevent accidental publication of private repositories\. If -you would like to ensure that a given package is only ever published to a -specific registry (for example, an internal registry), then use the -\fBpublishConfig\fP dictionary described below to override the \fBregistry\fP config -param at publish\-time\. -.SH publishConfig -.P -This is a set of config values that will be used at publish\-time\. It's -especially handy if you want to set the tag, registry or access, so that -you can ensure that a given package is not tagged with "latest", published -to the global public registry or that a scoped module is private by default\. -.P -Any config values can be overridden, but only "tag", "registry" and "access" -probably matter for the purposes of publishing\. -.P -See npm help 7 \fBnpm\-config\fP to see the list of config options that can be -overridden\. -.SH DEFAULT VALUES -.P -npm will default some values based on package contents\. -.RS 0 -.IP \(bu 2 -\fB"scripts": {"start": "node server\.js"}\fP -If there is a \fBserver\.js\fP file in the root of your package, then npm -will default the \fBstart\fP command to \fBnode server\.js\fP\|\. -.IP \(bu 2 -\fB"scripts":{"install": "node\-gyp rebuild"}\fP -If there is a \fBbinding\.gyp\fP file in the root of your package and you have not defined an \fBinstall\fP or \fBpreinstall\fP script, npm will -default the \fBinstall\fP command to compile using node\-gyp\. -.IP \(bu 2 -\fB"contributors": [\.\.\.]\fP -If there is an \fBAUTHORS\fP file in the root of your package, npm will -treat each line as a \fBName (url)\fP format, where email and url -are optional\. Lines which start with a \fB#\fP or are blank, will be -ignored\. - -.RE -.SH SEE ALSO -.RS 0 -.IP \(bu 2 -npm help 7 semver -.IP \(bu 2 -npm help init -.IP \(bu 2 -npm help version -.IP \(bu 2 -npm help config -.IP \(bu 2 -npm help 7 config -.IP \(bu 2 -npm help help -.IP \(bu 2 -npm help install -.IP \(bu 2 -npm help publish -.IP \(bu 2 -npm help uninstall - -.RE - diff --git a/deps/npm/man/man5/npm-shrinkwrap.json.5 b/deps/npm/man/man5/shrinkwrap-json.5 similarity index 77% rename from deps/npm/man/man5/npm-shrinkwrap.json.5 rename to deps/npm/man/man5/shrinkwrap-json.5 index 5f8c7434bccbfe..5c1e05f8b7816d 100644 --- a/deps/npm/man/man5/npm-shrinkwrap.json.5 +++ b/deps/npm/man/man5/shrinkwrap-json.5 @@ -1,9 +1,9 @@ -.TH "NPM\-SHRINKWRAP\.JSON" "5" "October 2019" "" "" +.TH "NPM\-SHRINKWRAP\.JSON" "5" "November 2019" "" "" .SH "NAME" \fBnpm-shrinkwrap.json\fR \- A publishable lockfile -.SH DESCRIPTION +.SS Description .P -\fBnpm\-shrinkwrap\.json\fP is a file created by npm help shrinkwrap\. It is identical to +\fBnpm\-shrinkwrap\.json\fP is a file created by npm help \fBshrinkwrap\fP\|\. It is identical to \fBpackage\-lock\.json\fP, with one major caveat: Unlike \fBpackage\-lock\.json\fP, \fBnpm\-shrinkwrap\.json\fP may be included when publishing a package\. .P @@ -17,15 +17,15 @@ Additionally, if both \fBpackage\-lock\.json\fP and \fBnpm\-shrinkwrap\.json\fP in a package root, \fBpackage\-lock\.json\fP will be ignored in favor of this file\. .P For full details and description of the \fBnpm\-shrinkwrap\.json\fP file format, refer -to the manual page for npm help 5 package\-lock\.json\. -.SH SEE ALSO +to the manual page for npm help package\-lock\.json\. +.SS See also .RS 0 .IP \(bu 2 npm help shrinkwrap .IP \(bu 2 -npm help 5 package\-lock\.json +npm help package\-lock\.json .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 npm help install diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7 new file mode 100644 index 00000000000000..617b5354c1db25 --- /dev/null +++ b/deps/npm/man/man7/config.7 @@ -0,0 +1,892 @@ +.P +" +``` +.P +It is \fInot\fR the path to a key file (and there is no "keyfile" option)\. +.SS legacy\-bundling +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Causes npm to install the package such that versions of npm prior to 1\.4, +such as the one included with node 0\.8, can install the package\. This +eliminates all automatic deduping\. If used with \fBglobal\-style\fP this option +will be preferred\. +.SS link +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If true, then local installs will link if there is a suitable globally +installed package\. +.P +Note that this means that local installs can cause things to be +installed into the global space at the same time\. The link is only done +if one of the two conditions are met: +.RS 0 +.IP \(bu 2 +The package is not already installed globally, or +.IP \(bu 2 +the globally installed version is identical to the version that is +being installed locally\. + +.RE +.SS local\-address +.RS 0 +.IP \(bu 2 +Default: undefined +.IP \(bu 2 +Type: IP Address + +.RE +.P +The IP address of the local interface to use when making connections +to the npm registry\. Must be IPv4 in versions of Node prior to 0\.12\. +.SS loglevel +.RS 0 +.IP \(bu 2 +Default: "notice" +.IP \(bu 2 +Type: String +.IP \(bu 2 +Values: "silent", "error", "warn", "notice", "http", "timing", "info", +"verbose", "silly" + +.RE +.P +What level of logs to report\. On failure, \fIall\fR logs are written to +\fBnpm\-debug\.log\fP in the current working directory\. +.P +Any logs of a higher level than the setting are shown\. The default is "notice"\. +.SS logstream +.RS 0 +.IP \(bu 2 +Default: process\.stderr +.IP \(bu 2 +Type: Stream + +.RE +.P +This is the stream that is passed to the +npmlog \fIhttps://github\.com/npm/npmlog\fR module at run time\. +.P +It cannot be set from the command line, but if you are using npm +programmatically, you may wish to send logs to somewhere other than +stderr\. +.P +If the \fBcolor\fP config is set to true, then this stream will receive +colored output if it is a TTY\. +.SS logs\-max +.RS 0 +.IP \(bu 2 +Default: 10 +.IP \(bu 2 +Type: Number + +.RE +.P +The maximum number of log files to store\. +.SS long +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Show extended information in \fBnpm ls\fP and \fBnpm search\fP\|\. +.SS maxsockets +.RS 0 +.IP \(bu 2 +Default: 50 +.IP \(bu 2 +Type: Number + +.RE +.P +The maximum number of connections to use per origin (protocol/host/port +combination)\. Passed to the \fBhttp\fP \fBAgent\fP used to make the request\. +.SS message +.RS 0 +.IP \(bu 2 +Default: "%s" +.IP \(bu 2 +Type: String + +.RE +.P +Commit message which is used by \fBnpm version\fP when creating version commit\. +.P +Any "%s" in the message will be replaced with the version number\. +.SS metrics\-registry +.RS 0 +.IP \(bu 2 +Default: The value of \fBregistry\fP (which defaults to "https://registry\.npmjs\.org/") +.IP \(bu 2 +Type: String + +.RE +.P +The registry you want to send cli metrics to if \fBsend\-metrics\fP is true\. +.SS node\-options +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: String + +.RE +.P +Options to pass through to Node\.js via the \fBNODE_OPTIONS\fP environment +variable\. This does not impact how npm itself is executed but it does +impact how lifecycle scripts are called\. +.SS node\-version +.RS 0 +.IP \(bu 2 +Default: process\.version +.IP \(bu 2 +Type: semver or false + +.RE +.P +The node version to use when checking a package's \fBengines\fP map\. +.SS noproxy +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: String or Array + +.RE +.P +A comma\-separated string or an array of domain extensions that a proxy should not be used for\. +.SS offline +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Force offline mode: no network requests will be done during install\. To allow +the CLI to fill in missing cache data, see \fB\-\-prefer\-offline\fP\|\. +.SS onload\-script +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: path + +.RE +.P +A node module to \fBrequire()\fP when npm loads\. Useful for programmatic +usage\. +.SS only +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: String + +.RE +.P +When "dev" or "development" and running local \fBnpm install\fP without any +arguments, only devDependencies (and their dependencies) are installed\. +.P +When "dev" or "development" and running local \fBnpm ls\fP, \fBnpm outdated\fP, or +\fBnpm update\fP, is an alias for \fB\-\-dev\fP\|\. +.P +When "prod" or "production" and running local \fBnpm install\fP without any +arguments, only non\-devDependencies (and their dependencies) are +installed\. +.P +When "prod" or "production" and running local \fBnpm ls\fP, \fBnpm outdated\fP, or +\fBnpm update\fP, is an alias for \fB\-\-production\fP\|\. +.SS optional +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Attempt to install packages in the \fBoptionalDependencies\fP object\. Note +that if these packages fail to install, the overall installation +process is not aborted\. +.SS otp +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: Number + +.RE +.P +This is a one\-time password from a two\-factor authenticator\. It's needed +when publishing or changing package permissions with \fBnpm access\fP\|\. +.SS package\-lock +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +If set to false, then ignore \fBpackage\-lock\.json\fP files when installing\. This +will also prevent \fIwriting\fR \fBpackage\-lock\.json\fP if \fBsave\fP is true\. +.P +When package package\-locks are disabled, automatic pruning of extraneous +modules will also be disabled\. To remove extraneous modules with +package\-locks disabled use \fBnpm prune\fP\|\. +.P +This option is an alias for \fB\-\-shrinkwrap\fP\|\. +.SS package\-lock\-only +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If set to true, it will update only the \fBpackage\-lock\.json\fP, +instead of checking \fBnode_modules\fP and downloading dependencies\. +.SS parseable +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Output parseable results from commands that write to +standard output\. For \fBnpm search\fP, this will be tab\-separated table format\. +.SS prefer\-offline +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If true, staleness checks for cached data will be bypassed, but missing data +will be requested from the server\. To force full offline mode, use \fB\-\-offline\fP\|\. +.P +This option is effectively equivalent to \fB\-\-cache\-min=9999999\fP\|\. +.SS prefer\-online +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If true, staleness checks for cached data will be forced, making the CLI look +for updates immediately even for fresh package data\. +.SS prefix +.RS 0 +.IP \(bu 2 +Default: see npm help folders +.IP \(bu 2 +Type: path + +.RE +.P +The location to install global items\. If set on the command line, then +it forces non\-global commands to run in the specified folder\. +.SS preid +.RS 0 +.IP \(bu 2 +Default: "" +.IP \(bu 2 +Type: String + +.RE +.P +The "prerelease identifier" to use as a prefix for the "prerelease" part of a +semver\. Like the \fBrc\fP in \fB1\.2\.0\-rc\.8\fP\|\. +.SS production +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Set to true to run in "production" mode\. +.RS 0 +.IP 1. 3 +devDependencies are not installed at the topmost level when running +local \fBnpm install\fP without any arguments\. +.IP 2. 3 +Set the NODE_ENV="production" for lifecycle scripts\. + +.RE +.SS progress +.RS 0 +.IP \(bu 2 +Default: true, unless TRAVIS or CI env vars set\. +.IP \(bu 2 +Type: Boolean + +.RE +.P +When set to \fBtrue\fP, npm will display a progress bar during time intensive +operations, if \fBprocess\.stderr\fP is a TTY\. +.P +Set to \fBfalse\fP to suppress the progress bar\. +.SS proxy +.RS 0 +.IP \(bu 2 +Default: null +.IP \(bu 2 +Type: url + +.RE +.P +A proxy to use for outgoing http requests\. If the \fBHTTP_PROXY\fP or +\fBhttp_proxy\fP environment variables are set, proxy settings will be +honored by the underlying \fBrequest\fP library\. +.SS read\-only +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +This is used to mark a token as unable to publish when configuring limited access tokens with the \fBnpm token create\fP command\. +.SS rebuild\-bundle +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Rebuild bundled dependencies after installation\. +.SS registry +.RS 0 +.IP \(bu 2 +Default: https://registry\.npmjs\.org/ +.IP \(bu 2 +Type: url + +.RE +.P +The base URL of the npm package registry\. +.SS rollback +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Remove failed installs\. +.SS save +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Save installed packages to a package\.json file as dependencies\. +.P +When used with the \fBnpm rm\fP command, it removes it from the \fBdependencies\fP +object\. +.P +Only works if there is already a package\.json file present\. +.SS save\-bundle +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If a package would be saved at install time by the use of \fB\-\-save\fP, +\fB\-\-save\-dev\fP, or \fB\-\-save\-optional\fP, then also put it in the +\fBbundleDependencies\fP list\. +.P +When used with the \fBnpm rm\fP command, it removes it from the +bundledDependencies list\. +.SS save\-prod +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Makes sure that a package will be saved into \fBdependencies\fP specifically\. This +is useful if a package already exists in \fBdevDependencies\fP or +\fBoptionalDependencies\fP, but you want to move it to be a production dep\. This is +also the default behavior if \fB\-\-save\fP is true, and neither \fB\-\-save\-dev\fP or +\fB\-\-save\-optional\fP are true\. +.SS save\-dev +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Save installed packages to a package\.json file as \fBdevDependencies\fP\|\. +.P +When used with the \fBnpm rm\fP command, it removes it from the +\fBdevDependencies\fP object\. +.P +Only works if there is already a package\.json file present\. +.SS save\-exact +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Dependencies saved to package\.json using \fB\-\-save\fP, \fB\-\-save\-dev\fP or +\fB\-\-save\-optional\fP will be configured with an exact version rather than +using npm's default semver range operator\. +.SS save\-optional +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Save installed packages to a package\.json file as +optionalDependencies\. +.P +When used with the \fBnpm rm\fP command, it removes it from the +\fBdevDependencies\fP object\. +.P +Only works if there is already a package\.json file present\. +.SS save\-prefix +.RS 0 +.IP \(bu 2 +Default: '^' +.IP \(bu 2 +Type: String + +.RE +.P +Configure how versions of packages installed to a package\.json file via +\fB\-\-save\fP or \fB\-\-save\-dev\fP get prefixed\. +.P +For example if a package has version \fB1\.2\.3\fP, by default its version is +set to \fB^1\.2\.3\fP which allows minor upgrades for that package, but after +\fBnpm config set save\-prefix='~'\fP it would be set to \fB~1\.2\.3\fP which only allows +patch upgrades\. +.SS scope +.RS 0 +.IP \(bu 2 +Default: the scope of the current project, if any, or "" +.IP \(bu 2 +Type: String + +.RE +.P +Associate an operation with a scope for a scoped registry\. Useful when logging +in to a private registry for the first time: +\fBnpm login \-\-scope=@organization \-\-registry=registry\.organization\.com\fP, which +will cause \fB@organization\fP to be mapped to the registry for future installation +of packages specified according to the pattern \fB@organization/package\fP\|\. +.SS script\-shell +.RS 0 +.IP \(bu 2 +Default: \fBnull\fP +.IP \(bu 2 +Type: path + +.RE +.P +The shell to use for scripts run with the \fBnpm run\fP command\. +.SS scripts\-prepend\-node\-path +.RS 0 +.IP \(bu 2 +Default: "warn\-only" +.IP \(bu 2 +Type: Boolean, \fB"auto"\fP or \fB"warn\-only"\fP + +.RE +.P +If set to \fBtrue\fP, add the directory in which the current \fBnode\fP executable +resides to the \fBPATH\fP environment variable when running scripts, +even if that means that \fBnpm\fP will invoke a different \fBnode\fP executable than +the one which it is running\. +.P +If set to \fBfalse\fP, never modify \fBPATH\fP with that\. +.P +If set to \fB"warn\-only"\fP, never modify \fBPATH\fP but print a warning if \fBnpm\fP thinks +that you may want to run it with \fBtrue\fP, e\.g\. because the \fBnode\fP executable +in the \fBPATH\fP is not the one \fBnpm\fP was invoked with\. +.P +If set to \fBauto\fP, only add that directory to the \fBPATH\fP environment variable +if the \fBnode\fP executable with which \fBnpm\fP was invoked and the one that is found +first on the \fBPATH\fP are different\. +.SS searchexclude +.RS 0 +.IP \(bu 2 +Default: "" +.IP \(bu 2 +Type: String + +.RE +.P +Space\-separated options that limit the results from search\. +.SS searchopts +.RS 0 +.IP \(bu 2 +Default: "" +.IP \(bu 2 +Type: String + +.RE +.P +Space\-separated options that are always passed to search\. +.SS searchlimit +.RS 0 +.IP \(bu 2 +Default: 20 +.IP \(bu 2 +Type: Number + +.RE +.P +Number of items to limit search results to\. Will not apply at all to legacy +searches\. +.SS searchstaleness +.RS 0 +.IP \(bu 2 +Default: 900 (15 minutes) +.IP \(bu 2 +Type: Number + +.RE +.P +The age of the cache, in seconds, before another registry request is made if +using legacy search endpoint\. +.SS send\-metrics +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If true, success/failure metrics will be reported to the registry stored in +\fBmetrics\-registry\fP\|\. These requests contain the number of successful and +failing runs of the npm CLI and the time period overwhich those counts were +gathered\. No identifying information is included in these requests\. +.SS shell +.RS 0 +.IP \(bu 2 +Default: SHELL environment variable, or "bash" on Posix, or "cmd" on +Windows +.IP \(bu 2 +Type: path + +.RE +.P +The shell to run for the \fBnpm explore\fP command\. +.SS shrinkwrap +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +If set to false, then ignore \fBnpm\-shrinkwrap\.json\fP files when installing\. This +will also prevent \fIwriting\fR \fBnpm\-shrinkwrap\.json\fP if \fBsave\fP is true\. +.P +This option is an alias for \fB\-\-package\-lock\fP\|\. +.SS sign\-git\-commit +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If set to true, then the \fBnpm version\fP command will commit the new package +version using \fB\-S\fP to add a signature\. +.P +Note that git requires you to have set up GPG keys in your git configs +for this to work properly\. +.SS sign\-git\-tag +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +If set to true, then the \fBnpm version\fP command will tag the version +using \fB\-s\fP to add a signature\. +.P +Note that git requires you to have set up GPG keys in your git configs +for this to work properly\. +.SS sso\-poll\-frequency +.RS 0 +.IP \(bu 2 +Default: 500 +.IP \(bu 2 +Type: Number + +.RE +.P +When used with SSO\-enabled \fBauth\-type\fPs, configures how regularly the registry +should be polled while the user is completing authentication\. +.SS sso\-type +.RS 0 +.IP \(bu 2 +Default: 'oauth' +.IP \(bu 2 +Type: 'oauth', 'saml', or null + +.RE +.P +If \fB\-\-auth\-type=sso\fP, the type of SSO type to use\. +.SS strict\-ssl +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Whether or not to do SSL key validation when making requests to the +registry via https\. +.P +See also the \fBca\fP config\. +.SS tag +.RS 0 +.IP \(bu 2 +Default: latest +.IP \(bu 2 +Type: String + +.RE +.P +If you ask npm to install a package and don't tell it a specific version, then +it will install the specified tag\. +.P +Also the tag that is added to the package@version specified by the \fBnpm +tag\fP command, if no explicit tag is given\. +.SS tag\-version\-prefix +.RS 0 +.IP \(bu 2 +Default: \fB"v"\fP +.IP \(bu 2 +Type: String + +.RE +.P +If set, alters the prefix used when tagging a new version when performing a +version increment using \fBnpm\-version\fP\|\. To remove the prefix altogether, set it +to the empty string: \fB""\fP\|\. +.P +Because other tools may rely on the convention that npm version tags look like +\fBv1\.0\.0\fP, \fIonly use this property if it is absolutely necessary\fR\|\. In +particular, use care when overriding this setting for public packages\. +.SS timing +.RS 0 +.IP \(bu 2 +Default: \fBfalse\fP +.IP \(bu 2 +Type: Boolean + +.RE +.P +If true, writes an \fBnpm\-debug\fP log to \fB_logs\fP and timing information to +\fB_timing\.json\fP, both in your cache\. \fB_timing\.json\fP is a newline delimited +list of JSON objects\. You can quickly view it with this +json \fIhttps://www\.npmjs\.com/package/json\fR command line: +\fBjson \-g < ~/\.npm/_timing\.json\fP\|\. +.SS tmp +.RS 0 +.IP \(bu 2 +Default: TMPDIR environment variable, or "/tmp" +.IP \(bu 2 +Type: path + +.RE +.P +Where to store temporary files and folders\. All temp files are deleted +on success, but left behind on failure for forensic purposes\. +.SS unicode +.RS 0 +.IP \(bu 2 +Default: false on windows, true on mac/unix systems with a unicode locale +.IP \(bu 2 +Type: Boolean + +.RE +.P +When set to true, npm uses unicode characters in the tree output\. When +false, it uses ascii characters to draw trees\. +.SS unsafe\-perm +.RS 0 +.IP \(bu 2 +Default: false if running as root, true otherwise +.IP \(bu 2 +Type: Boolean + +.RE +.P +Set to true to suppress the UID/GID switching when running package +scripts\. If set explicitly to false, then installing as a non\-root user +will fail\. +.SS update\-notifier +.RS 0 +.IP \(bu 2 +Default: true +.IP \(bu 2 +Type: Boolean + +.RE +.P +Set to false to suppress the update notification when using an older +version of npm than the latest\. +.SS usage +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: Boolean + +.RE +.P +Set to show short usage output (like the \-H output) +instead of complete help when doing npm help \fBhelp\fP\|\. +.SS user +.RS 0 +.IP \(bu 2 +Default: "nobody" +.IP \(bu 2 +Type: String or Number + +.RE +.P +The UID to set to when running package scripts as root\. +.SS userconfig +.RS 0 +.IP \(bu 2 +Default: ~/\.npmrc +.IP \(bu 2 +Type: path + +.RE +.P +The location of user\-level configuration settings\. +.SS umask +.RS 0 +.IP \(bu 2 +Default: 022 +.IP \(bu 2 +Type: Octal numeric string in range 0000\.\.0777 (0\.\.511) + +.RE +.P +The "umask" value to use when setting the file creation mode on files +and folders\. +.P +Folders and executables are given a mode which is \fB0777\fP masked against +this value\. Other files are given a mode which is \fB0666\fP masked against +this value\. Thus, the defaults are \fB0755\fP and \fB0644\fP respectively\. +.SS user\-agent +.RS 0 +.IP \(bu 2 +Default: node/{process\.version} {process\.platform} {process\.arch} +.IP \(bu 2 +Type: String + +.RE +.P +Sets a User\-Agent to the request header +.SS version +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: boolean + +.RE +.P +If true, output the npm version and exit successfully\. +.P +Only relevant when specified explicitly on the command line\. +.SS versions +.RS 0 +.IP \(bu 2 +Default: false +.IP \(bu 2 +Type: boolean + +.RE +.P +If true, output the npm version as well as node's \fBprocess\.versions\fP map, and +exit successfully\. +.P +Only relevant when specified explicitly on the command line\. +.SS viewer +.RS 0 +.IP \(bu 2 +Default: "man" on Posix, "browser" on Windows +.IP \(bu 2 +Type: path + +.RE +.P +The program to use to view help content\. +.P +Set to \fB"browser"\fP to view html help content in the default web browser\. +.SS See also +.RS 0 +.IP \(bu 2 +npm help config +.IP \(bu 2 +npm help npmrc +.IP \(bu 2 +npm help scripts +.IP \(bu 2 +npm help folders +.IP \(bu 2 +npm help npm + +.RE diff --git a/deps/npm/man/man7/npm-developers.7 b/deps/npm/man/man7/developers.7 similarity index 92% rename from deps/npm/man/man7/npm-developers.7 rename to deps/npm/man/man7/developers.7 index 85920ef53d6a17..2f24215d26b19f 100644 --- a/deps/npm/man/man7/npm-developers.7 +++ b/deps/npm/man/man7/developers.7 @@ -1,7 +1,7 @@ -.TH "NPM\-DEVELOPERS" "7" "October 2019" "" "" +.TH "DEVELOPERS" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-developers\fR \- Developer Guide -.SH DESCRIPTION +\fBdevelopers\fR \- Developer Guide +.SS Description .P So, you've decided to use npm to develop (and maybe publish/deploy) your project\. @@ -10,12 +10,12 @@ Fantastic! .P There are a few things that you need to do above the simple steps that your users will do to install your program\. -.SH About These Documents +.SS About These Documents .P These are man pages\. If you install npm, you should be able to then do \fBman npm\-thing\fP to get the documentation on a particular topic, or \fBnpm help thing\fP to see the same information\. -.SH What is a \fBpackage\fP +.SS What is a package .P A package is: .RS 0 @@ -54,12 +54,12 @@ git+https://user@hostname/project/blah\.git#commit\-ish .P The \fBcommit\-ish\fP can be any tag, sha, or branch which can be supplied as an argument to \fBgit checkout\fP\|\. The default is \fBmaster\fP\|\. -.SH The package\.json File +.SS The package\.json File .P You need to have a \fBpackage\.json\fP file in the root of your project to do much of anything with npm\. That is basically the whole interface\. .P -See npm help 5 \fBpackage\.json\fP for details about what goes in that file\. At the very +See npm help \fBpackage\.json\fP for details about what goes in that file\. At the very least, you need: .RS 0 .IP \(bu 2 @@ -87,7 +87,7 @@ scripts: If you have a special compilation or installation script, then you should put it in the \fBscripts\fP object\. You should definitely have at least a basic smoke\-test command as the "scripts\.test" field\. -See npm help 7 scripts\. +See npm help scripts\. .IP \(bu 2 main: If you have a single module that serves as the entry point to your @@ -102,9 +102,9 @@ they'll get installed just like these ones\. .RE .P You can use \fBnpm init\fP in the root of your package in order to get you -started with a pretty basic package\.json file\. See npm help \fBnpm\-init\fP for +started with a pretty basic package\.json file\. See npm help \fBinit\fP for more info\. -.SH Keeping files \fIout\fR of your package +.SS Keeping files \fIout\fR of your package .P Use a \fB\|\.npmignore\fP file to keep stuff out of your package\. If there's no \fB\|\.npmignore\fP file, but there \fIis\fR a \fB\|\.gitignore\fP file, then npm will @@ -187,15 +187,15 @@ If you want to double check that your package will include only the files you intend it to when published, you can run the \fBnpm pack\fP command locally which will generate a tarball in the working directory, the same way it does for publishing\. -.SH Link Packages +.SS Link Packages .P \fBnpm link\fP is designed to install a development package and see the changes in real time without having to keep re\-installing it\. (You do need to either re\-link or \fBnpm rebuild \-g\fP to update compiled packages, of course\.) .P -More info at npm help \fBnpm\-link\fP\|\. -.SH Before Publishing: Make Sure Your Package Installs and Works +More info at npm help \fBlink\fP\|\. +.SS Before Publishing: Make Sure Your Package Installs and Works .P \fBThis is important\.\fR .P @@ -236,7 +236,7 @@ to install it locally into the node_modules folder in that other place\. .P Then go into the node\-repl, and try using require("my\-thing") to bring in your module's main module\. -.SH Create a User Account +.SS Create a User Account .P Create a user with the adduser command\. It works like this: .P @@ -249,7 +249,7 @@ npm adduser and then follow the prompts\. .P This is documented better in npm help adduser\. -.SH Publish your package +.SS Publish your package .P This part's easy\. In the root of your folder, do this: .P @@ -266,27 +266,26 @@ Note that pretty much \fBeverything in that folder will be exposed\fR by default\. So, if you have secret stuff in there, use a \fB\|\.npmignore\fP file to list out the globs to ignore, or publish from a fresh checkout\. -.SH Brag about it +.SS Brag about it .P Send emails, write blogs, blab in IRC\. .P Tell the world how easy it is to install your program! -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 npm help npm .IP \(bu 2 npm help init .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help 7 scripts +npm help scripts .IP \(bu 2 npm help publish .IP \(bu 2 npm help adduser .IP \(bu 2 -npm help 7 registry +npm help registry .RE - diff --git a/deps/npm/man/man7/npm-disputes.7 b/deps/npm/man/man7/disputes.7 similarity index 96% rename from deps/npm/man/man7/npm-disputes.7 rename to deps/npm/man/man7/disputes.7 index e0629d635636bc..c815d206351fbd 100644 --- a/deps/npm/man/man7/npm-disputes.7 +++ b/deps/npm/man/man7/disputes.7 @@ -1,6 +1,6 @@ -.TH "NPM\-DISPUTES" "7" "October 2019" "" "" +.TH "DISPUTES" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-disputes\fR \- Handling Module Name Disputes +\fBdisputes\fR \- Handling Module Name Disputes .P This document describes the steps that you should take to resolve module name disputes with other npm publishers\. It also describes special steps you should @@ -10,7 +10,7 @@ This document is a clarification of the acceptable behavior outlined in the npm Code of Conduct \fIhttps://www\.npmjs\.com/policies/conduct\fR, and nothing in this document should be interpreted to contradict any aspect of the npm Code of Conduct\. -.SH TL;DR +.SS TL;DR .RS 0 .IP 1. 3 Get the author email with \fBnpm owner ls \fP @@ -22,7 +22,7 @@ After a few weeks, if there's no resolution, we'll sort it out\. .RE .P Don't squat on package names\. Publish code or move out of the way\. -.SH DESCRIPTION +.SS Description .P There sometimes arise cases where a user publishes a module, and then later, some other user wants to use that name\. Here are some common ways that happens @@ -68,7 +68,7 @@ support@npmjs\.com and we'll sort it out\. ("Reasonable" is usually at least 4 weeks\.) .RE -.SH REASONING +.SS Reasoning .P In almost every case so far, the parties involved have been able to reach an amicable resolution without any major intervention\. Most people really do want @@ -79,7 +79,7 @@ as possible\. If an admin one day deletes something you had worked on, then that is going to make most people quite upset, regardless of the justification\. When humans solve their problems by talking to other humans with respect, everyone has the chance to end up feeling good about the interaction\. -.SH EXCEPTIONS +.SS Exceptions .P Some things are not allowed, and will be removed without discussion if they are brought to the attention of the npm registry admins, including but not limited @@ -116,7 +116,7 @@ language, pornographic content, or harassment\. If you see bad behavior like this, please report it to abuse@npmjs\.com right away\. \fBYou are never expected to resolve abusive behavior on your own\. We are here to help\.\fR -.SH TRADEMARKS +.SS Trademarkss .P If you think another npm publisher is infringing your trademark, such as by using a confusingly similar package name, email abuse@npmjs\.com with a link to @@ -128,23 +128,22 @@ misusing your registered mark without permission, we will transfer the package name to you\. Otherwise, we will contact the package publisher and ask them to clear up any confusion with changes to their package's \fBREADME\fP file or metadata\. -.SH CHANGES +.SS Changes .P This is a living document and may be updated from time to time\. Please refer to the git history for this document \fIhttps://github\.com/npm/cli/commits/latest/doc/misc/npm\-disputes\.md\fR to view the changes\. -.SH LICENSE +.SS License .P Copyright (C) npm, Inc\., All rights reserved .P This document may be reused under a Creative Commons Attribution\-ShareAlike License\. -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 -npm help 7 registry +npm help registry .IP \(bu 2 npm help owner .RE - diff --git a/deps/npm/man/man7/npm-coding-style.7 b/deps/npm/man/man7/npm-coding-style.7 deleted file mode 100644 index 6f7a47bfd5ef55..00000000000000 --- a/deps/npm/man/man7/npm-coding-style.7 +++ /dev/null @@ -1,222 +0,0 @@ -.TH "NPM\-CODING\-STYLE" "7" "October 2019" "" "" -.SH "NAME" -\fBnpm-coding-style\fR \- npm's "funny" coding style -.SH DESCRIPTION -.P -npm's coding style is a bit unconventional\. It is not different for -difference's sake, but rather a carefully crafted style that is -designed to reduce visual clutter and make bugs more apparent\. -.P -If you want to contribute to npm (which is very encouraged), you should -make your code conform to npm's style\. -.P -Note: this concerns npm's code not the specific packages that you can download from the npm registry\. -.SH Line Length -.P -Keep lines shorter than 80 characters\. It's better for lines to be -too short than to be too long\. Break up long lists, objects, and other -statements onto multiple lines\. -.SH Indentation -.P -Two\-spaces\. Tabs are better, but they look like hell in web browsers -(and on GitHub), and node uses 2 spaces, so that's that\. -.P -Configure your editor appropriately\. -.SH Curly braces -.P -Curly braces belong on the same line as the thing that necessitates them\. -.P -Bad: -.P -.RS 2 -.nf -function () -{ -.fi -.RE -.P -Good: -.P -.RS 2 -.nf -function () { -.fi -.RE -.P -If a block needs to wrap to the next line, use a curly brace\. Don't -use it if it doesn't\. -.P -Bad: -.P -.RS 2 -.nf -if (foo) { bar() } -while (foo) - bar() -.fi -.RE -.P -Good: -.P -.RS 2 -.nf -if (foo) bar() -while (foo) { - bar() -} -.fi -.RE -.SH Semicolons -.P -Don't use them except in four situations: -.RS 0 -.IP \(bu 2 -\fBfor (;;)\fP loops\. They're actually required\. -.IP \(bu 2 -null loops like: \fBwhile (something) ;\fP (But you'd better have a good -reason for doing that\.) -.IP \(bu 2 -\fBcase 'foo': doSomething(); break\fP -.IP \(bu 2 -In front of a leading \fB(\fP or \fB[\fP at the start of the line\. -This prevents the expression from being interpreted -as a function call or property access, respectively\. - -.RE -.P -Some examples of good semicolon usage: -.P -.RS 2 -.nf -;(x || y)\.doSomething() -;[a, b, c]\.forEach(doSomething) -for (var i = 0; i < 10; i ++) { - switch (state) { - case 'begin': start(); continue - case 'end': finish(); break - default: throw new Error('unknown state') - } - end() -} -.fi -.RE -.P -Note that starting lines with \fB\-\fP and \fB+\fP also should be prefixed -with a semicolon, but this is much less common\. -.SH Comma First -.P -If there is a list of things separated by commas, and it wraps -across multiple lines, put the comma at the start of the next -line, directly below the token that starts the list\. Put the -final token in the list on a line by itself\. For example: -.P -.RS 2 -.nf -var magicWords = [ 'abracadabra' - , 'gesundheit' - , 'ventrilo' - ] - , spells = { 'fireball' : function () { setOnFire() } - , 'water' : function () { putOut() } - } - , a = 1 - , b = 'abc' - , etc - , somethingElse -.fi -.RE -.SH Quotes -.P -Use single quotes for strings except to avoid escaping\. -.P -Bad: -.P -.RS 2 -.nf -var notOk = "Just double quotes" -.fi -.RE -.P -Good: -.P -.RS 2 -.nf -var ok = 'String contains "double" quotes' -var alsoOk = "String contains 'single' quotes or apostrophe" -.fi -.RE -.SH Whitespace -.P -Put a single space in front of \fB(\fP for anything other than a function call\. -Also use a single space wherever it makes things more readable\. -.P -Don't leave trailing whitespace at the end of lines\. Don't indent empty -lines\. Don't use more spaces than are helpful\. -.SH Functions -.P -Use named functions\. They make stack traces a lot easier to read\. -.SH Callbacks, Sync/async Style -.P -Use the asynchronous/non\-blocking versions of things as much as possible\. -It might make more sense for npm to use the synchronous fs APIs, but this -way, the fs and http and child process stuff all uses the same callback\-passing -methodology\. -.P -The callback should always be the last argument in the list\. Its first -argument is the Error or null\. -.P -Be very careful never to ever ever throw anything\. It's worse than useless\. -Just send the error message back as the first argument to the callback\. -.SH Errors -.P -Always create a new Error object with your message\. Don't just return a -string message to the callback\. Stack traces are handy\. -.SH Logging -.P -Logging is done using the npmlog \fIhttps://github\.com/npm/npmlog\fR -utility\. -.P -Please clean up logs when they are no longer helpful\. In particular, -logging the same object over and over again is not helpful\. Logs should -report what's happening so that it's easier to track down where a fault -occurs\. -.P -Use appropriate log levels\. See npm help 7 \fBnpm\-config\fP and search for -"loglevel"\. -.SH Case, naming, etc\. -.P -Use \fBlowerCamelCase\fP for multiword identifiers when they refer to objects, -functions, methods, properties, or anything not specified in this section\. -.P -Use \fBUpperCamelCase\fP for class names (things that you'd pass to "new")\. -.P -Use \fBall\-lower\-hyphen\-css\-case\fP for multiword filenames and config keys\. -.P -Use named functions\. They make stack traces easier to follow\. -.P -Use \fBCAPS_SNAKE_CASE\fP for constants, things that should never change -and are rarely used\. -.P -Use a single uppercase letter for function names where the function -would normally be anonymous, but needs to call itself recursively\. It -makes it clear that it's a "throwaway" function\. -.SH null, undefined, false, 0 -.P -Boolean variables and functions should always be either \fBtrue\fP or -\fBfalse\fP\|\. Don't set it to 0 unless it's supposed to be a number\. -.P -When something is intentionally missing or removed, set it to \fBnull\fP\|\. -.P -Don't set things to \fBundefined\fP\|\. Reserve that value to mean "not yet -set to anything\." -.P -Boolean objects are forbidden\. -.SH SEE ALSO -.RS 0 -.IP \(bu 2 -npm help 7 developers -.IP \(bu 2 -npm help npm - -.RE - diff --git a/deps/npm/man/man7/npm-config.7 b/deps/npm/man/man7/npm-config.7 deleted file mode 100644 index 4a3513dcc855c8..00000000000000 --- a/deps/npm/man/man7/npm-config.7 +++ /dev/null @@ -1,1721 +0,0 @@ -.TH "NPM\-CONFIG" "7" "October 2019" "" "" -.SH "NAME" -\fBnpm-config\fR \- More than you probably want to know about npm configuration -.SH DESCRIPTION -.P -npm gets its configuration values from the following sources, sorted by priority: -.SS Command Line Flags -.P -Putting \fB\-\-foo bar\fP on the command line sets the \fBfoo\fP configuration -parameter to \fB"bar"\fP\|\. A \fB\-\-\fP argument tells the cli parser to stop -reading flags\. Using \fB\-\-flag\fP without specifying any value will set -the value to \fBtrue\fP\|\. -.P -Example: \fB\-\-flag1 \-\-flag2\fP will set both configuration parameters -to \fBtrue\fP, while \fB\-\-flag1 \-\-flag2 bar\fP will set \fBflag1\fP to \fBtrue\fP, -and \fBflag2\fP to \fBbar\fP\|\. Finally, \fB\-\-flag1 \-\-flag2 \-\- bar\fP will set -both configuration parameters to \fBtrue\fP, and the \fBbar\fP is taken -as a command argument\. -.SS Environment Variables -.P -Any environment variables that start with \fBnpm_config_\fP will be -interpreted as a configuration parameter\. For example, putting -\fBnpm_config_foo=bar\fP in your environment will set the \fBfoo\fP -configuration parameter to \fBbar\fP\|\. Any environment configurations that -are not given a value will be given the value of \fBtrue\fP\|\. Config -values are case\-insensitive, so \fBNPM_CONFIG_FOO=bar\fP will work the -same\. However, please note that inside npm\-scripts \fI/misc/scripts\fR -npm will set its own environment variables and Node will prefer -those lowercase versions over any uppercase ones that you might set\. -For details see this issue \fIhttps://github\.com/npm/npm/issues/14528\fR\|\. -.P -Notice that you need to use underscores instead of dashes, so \fB\-\-allow\-same\-version\fP -would become \fBnpm_config_allow_same_version=true\fP\|\. -.SS npmrc Files -.P -The four relevant files are: -.RS 0 -.IP \(bu 2 -per\-project configuration file (\fB/path/to/my/project/\.npmrc\fP) -.IP \(bu 2 -per\-user configuration file (defaults to \fB$HOME/\.npmrc\fP; configurable via CLI -option \fB\-\-userconfig\fP or environment variable \fB$NPM_CONFIG_USERCONFIG\fP) -.IP \(bu 2 -global configuration file (defaults to \fB$PREFIX/etc/npmrc\fP; configurable via -CLI option \fB\-\-globalconfig\fP or environment variable \fB$NPM_CONFIG_GLOBALCONFIG\fP) -.IP \(bu 2 -npm's built\-in configuration file (\fB/path/to/npm/npmrc\fP) - -.RE -.P -See npm help 5 npmrc for more details\. -.SS Default Configs -.P -Run \fBnpm config ls \-l\fP to see a set of configuration parameters that are -internal to npm, and are defaults if nothing else is specified\. -.SH Shorthands and Other CLI Niceties -.P -The following shorthands are parsed on the command\-line: -.RS 0 -.IP \(bu 2 -\fB\-v\fP: \fB\-\-version\fP -.IP \(bu 2 -\fB\-h\fP, \fB\-?\fP, \fB\-\-help\fP, \fB\-H\fP: \fB\-\-usage\fP -.IP \(bu 2 -\fB\-s\fP, \fB\-\-silent\fP: \fB\-\-loglevel silent\fP -.IP \(bu 2 -\fB\-q\fP, \fB\-\-quiet\fP: \fB\-\-loglevel warn\fP -.IP \(bu 2 -\fB\-d\fP: \fB\-\-loglevel info\fP -.IP \(bu 2 -\fB\-dd\fP, \fB\-\-verbose\fP: \fB\-\-loglevel verbose\fP -.IP \(bu 2 -\fB\-ddd\fP: \fB\-\-loglevel silly\fP -.IP \(bu 2 -\fB\-g\fP: \fB\-\-global\fP -.IP \(bu 2 -\fB\-C\fP: \fB\-\-prefix\fP -.IP \(bu 2 -\fB\-l\fP: \fB\-\-long\fP -.IP \(bu 2 -\fB\-m\fP: \fB\-\-message\fP -.IP \(bu 2 -\fB\-p\fP, \fB\-\-porcelain\fP: \fB\-\-parseable\fP -.IP \(bu 2 -\fB\-reg\fP: \fB\-\-registry\fP -.IP \(bu 2 -\fB\-f\fP: \fB\-\-force\fP -.IP \(bu 2 -\fB\-desc\fP: \fB\-\-description\fP -.IP \(bu 2 -\fB\-S\fP: \fB\-\-save\fP -.IP \(bu 2 -\fB\-P\fP: \fB\-\-save\-prod\fP -.IP \(bu 2 -\fB\-D\fP: \fB\-\-save\-dev\fP -.IP \(bu 2 -\fB\-O\fP: \fB\-\-save\-optional\fP -.IP \(bu 2 -\fB\-B\fP: \fB\-\-save\-bundle\fP -.IP \(bu 2 -\fB\-E\fP: \fB\-\-save\-exact\fP -.IP \(bu 2 -\fB\-y\fP: \fB\-\-yes\fP -.IP \(bu 2 -\fB\-n\fP: \fB\-\-yes false\fP -.IP \(bu 2 -\fBll\fP and \fBla\fP commands: \fBls \-\-long\fP - -.RE -.P -If the specified configuration param resolves unambiguously to a known -configuration parameter, then it is expanded to that configuration -parameter\. For example: -.P -.RS 2 -.nf -npm ls \-\-par -# same as: -npm ls \-\-parseable -.fi -.RE -.P -If multiple single\-character shorthands are strung together, and the -resulting combination is unambiguously not some other configuration -param, then it is expanded to its various component pieces\. For -example: -.P -.RS 2 -.nf -npm ls \-gpld -# same as: -npm ls \-\-global \-\-parseable \-\-long \-\-loglevel info -.fi -.RE -.SH Per\-Package Config Settings -.P -When running scripts (see npm help 7 \fBnpm\-scripts\fP) the package\.json "config" -keys are overwritten in the environment if there is a config param of -\fB[@]:\fP\|\. For example, if the package\.json has -this: -.P -.RS 2 -.nf -{ "name" : "foo" -, "config" : { "port" : "8080" } -, "scripts" : { "start" : "node server\.js" } } -.fi -.RE -.P -and the server\.js is this: -.P -.RS 2 -.nf -http\.createServer(\.\.\.)\.listen(process\.env\.npm_package_config_port) -.fi -.RE -.P -then the user could change the behavior by doing: -.P -.RS 2 -.nf -npm config set foo:port 80 -.fi -.RE -.P -See npm help 5 package\.json for more information\. -.SH Config Settings -.SS access -.RS 0 -.IP \(bu 2 -Default: \fBrestricted\fP -.IP \(bu 2 -Type: Access - -.RE -.P -When publishing scoped packages, the access level defaults to \fBrestricted\fP\|\. If -you want your scoped package to be publicly viewable (and installable) set -\fB\-\-access=public\fP\|\. The only valid values for \fBaccess\fP are \fBpublic\fP and -\fBrestricted\fP\|\. Unscoped packages \fIalways\fR have an access level of \fBpublic\fP\|\. -.SS allow\-same\-version -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Prevents throwing an error when \fBnpm version\fP is used to set the new version -to the same value as the current version\. -.SS always\-auth -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Force npm to always require authentication when accessing the registry, -even for \fBGET\fP requests\. -.SS also -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: String - -.RE -.P -When "dev" or "development" and running local \fBnpm shrinkwrap\fP, -\fBnpm outdated\fP, or \fBnpm update\fP, is an alias for \fB\-\-dev\fP\|\. -.SS audit -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -When "true" submit audit reports alongside \fBnpm install\fP runs to the default -registry and all registries configured for scopes\. See the documentation -for npm help audit for details on what is submitted\. -.SS audit\-level -.RS 0 -.IP \(bu 2 -Default: \fB"low"\fP -.IP \(bu 2 -Type: \fB\|'low'\fP, \fB\|'moderate'\fP, \fB\|'high'\fP, \fB\|'critical'\fP - -.RE -.P -The minimum level of vulnerability for \fBnpm audit\fP to exit with -a non\-zero exit code\. -.SS auth\-type -.RS 0 -.IP \(bu 2 -Default: \fB\|'legacy'\fP -.IP \(bu 2 -Type: \fB\|'legacy'\fP, \fB\|'sso'\fP, \fB\|'saml'\fP, \fB\|'oauth'\fP - -.RE -.P -What authentication strategy to use with \fBadduser\fP/\fBlogin\fP\|\. -.SS before -.RS 0 -.IP \(bu 2 -Alias: enjoy\-by -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: Date - -.RE -.P -If passed to \fBnpm install\fP, will rebuild the npm tree such that only versions -that were available \fBon or before\fR the \fB\-\-before\fP time get installed\. -If there's no versions available for the current set of direct dependencies, the -command will error\. -.P -If the requested version is a \fBdist\-tag\fP and the given tag does not pass the -\fB\-\-before\fP filter, the most recent version less than or equal to that tag will -be used\. For example, \fBfoo@latest\fP might install \fBfoo@1\.2\fP even though \fBlatest\fP -is \fB2\.0\fP\|\. -.SS bin\-links -.RS 0 -.IP \(bu 2 -Default: \fBtrue\fP -.IP \(bu 2 -Type: Boolean - -.RE -.P -Tells npm to create symlinks (or \fB\|\.cmd\fP shims on Windows) for package -executables\. -.P -Set to false to have it not do this\. This can be used to work around -the fact that some file systems don't support symlinks, even on -ostensibly Unix systems\. -.SS browser -.RS 0 -.IP \(bu 2 -Default: OS X: \fB"open"\fP, Windows: \fB"start"\fP, Others: \fB"xdg\-open"\fP -.IP \(bu 2 -Type: String - -.RE -.P -The browser that is called by the \fBnpm docs\fP command to open websites\. -.SS ca -.RS 0 -.IP \(bu 2 -Default: The npm CA certificate -.IP \(bu 2 -Type: String, Array or null - -.RE -.P -The Certificate Authority signing certificate that is trusted for SSL -connections to the registry\. Values should be in PEM format (Windows calls it "Base\-64 encoded X\.509 (\.CER)") with newlines -replaced by the string "\\n"\. For example: -.P -.RS 2 -.nf -ca="\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-\\nXXXX\\nXXXX\\n\-\-\-\-\-END CERTIFICATE\-\-\-\-\-" -.fi -.RE -.P -Set to \fBnull\fP to only allow "known" registrars, or to a specific CA cert -to trust only that specific signing authority\. -.P -Multiple CAs can be trusted by specifying an array of certificates: -.P -.RS 2 -.nf -ca[]="\.\.\." -ca[]="\.\.\." -.fi -.RE -.P -See also the \fBstrict\-ssl\fP config\. -.SS cafile -.RS 0 -.IP \(bu 2 -Default: \fBnull\fP -.IP \(bu 2 -Type: path - -.RE -.P -A path to a file containing one or multiple Certificate Authority signing -certificates\. Similar to the \fBca\fP setting, but allows for multiple CA's, as -well as for the CA information to be stored in a file on disk\. -.SS cache -.RS 0 -.IP \(bu 2 -Default: Windows: \fB%AppData%\\npm\-cache\fP, Posix: \fB~/\.npm\fP -.IP \(bu 2 -Type: path - -.RE -.P -The location of npm's cache directory\. See npm help \fBnpm\-cache\fP -.SS cache\-lock\-stale -.RS 0 -.IP \(bu 2 -Default: 60000 (1 minute) -.IP \(bu 2 -Type: Number - -.RE -.P -The number of ms before cache folder lockfiles are considered stale\. -.SS cache\-lock\-retries -.RS 0 -.IP \(bu 2 -Default: 10 -.IP \(bu 2 -Type: Number - -.RE -.P -Number of times to retry to acquire a lock on cache folder lockfiles\. -.SS cache\-lock\-wait -.RS 0 -.IP \(bu 2 -Default: 10000 (10 seconds) -.IP \(bu 2 -Type: Number - -.RE -.P -Number of ms to wait for cache lock files to expire\. -.SS cache\-max -.RS 0 -.IP \(bu 2 -Default: Infinity -.IP \(bu 2 -Type: Number - -.RE -.P -\fBDEPRECATED\fR: This option has been deprecated in favor of \fB\-\-prefer\-online\fP\|\. -.P -\fB\-\-cache\-max=0\fP is an alias for \fB\-\-prefer\-online\fP\|\. -.SS cache\-min -.RS 0 -.IP \(bu 2 -Default: 10 -.IP \(bu 2 -Type: Number - -.RE -.P -\fBDEPRECATED\fR: This option has been deprecated in favor of \fB\-\-prefer\-offline\fP\|\. -.P -\fB\-\-cache\-min=9999 (or bigger)\fP is an alias for \fB\-\-prefer\-offline\fP\|\. -.SS cert -.RS 0 -.IP \(bu 2 -Default: \fBnull\fP -.IP \(bu 2 -Type: String - -.RE -.P -A client certificate to pass when accessing the registry\. Values should be in -PEM format (Windows calls it "Base\-64 encoded X\.509 (\.CER)") with newlines replaced by the string "\\n"\. For example: -.P -.RS 2 -.nf -cert="\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-\\nXXXX\\nXXXX\\n\-\-\-\-\-END CERTIFICATE\-\-\-\-\-" -.fi -.RE -.P -It is \fInot\fR the path to a certificate file (and there is no "certfile" option)\. -.SS cidr -.RS 0 -.IP \(bu 2 -Default: \fBnull\fP -.IP \(bu 2 -Type: String, Array, null - -.RE -.P -This is a list of CIDR address to be used when configuring limited access tokens with the \fBnpm token create\fP command\. -.SS color -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean or \fB"always"\fP - -.RE -.P -If false, never shows colors\. If \fB"always"\fP then always shows colors\. -If true, then only prints color codes for tty file descriptors\. -.P -This option can also be changed using the environment: colors are -disabled when the environment variable \fBNO_COLOR\fP is set to any value\. -.SS depth -.RS 0 -.IP \(bu 2 -Default: Infinity -.IP \(bu 2 -Type: Number - -.RE -.P -The depth to go when recursing directories for \fBnpm ls\fP, -\fBnpm cache ls\fP, and \fBnpm outdated\fP\|\. -.P -For \fBnpm outdated\fP, a setting of \fBInfinity\fP will be treated as \fB0\fP -since that gives more useful information\. To show the outdated status -of all packages and dependents, use a large integer value, -e\.g\., \fBnpm outdated \-\-depth 9999\fP -.SS description -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Show the description in \fBnpm search\fP -.SS dev -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Install \fBdev\-dependencies\fP along with packages\. -.SS dry\-run -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Indicates that you don't want npm to make any changes and that it should -only report what it would have done\. This can be passed into any of the -commands that modify your local installation, eg, \fBinstall\fP, \fBupdate\fP, -\fBdedupe\fP, \fBuninstall\fP\|\. This is NOT currently honored by some network related -commands, eg \fBdist\-tags\fP, \fBowner\fP, etc\. -.SS editor -.RS 0 -.IP \(bu 2 -Default: \fBEDITOR\fP environment variable if set, or \fB"vi"\fP on Posix, -or \fB"notepad"\fP on Windows\. -.IP \(bu 2 -Type: path - -.RE -.P -The command to run for \fBnpm edit\fP or \fBnpm config edit\fP\|\. -.SS engine\-strict -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to true, then npm will stubbornly refuse to install (or even -consider installing) any package that claims to not be compatible with -the current Node\.js version\. -.SS force -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Makes various commands more forceful\. -.RS 0 -.IP \(bu 2 -lifecycle script failure does not block progress\. -.IP \(bu 2 -publishing clobbers previously published versions\. -.IP \(bu 2 -skips cache when requesting from the registry\. -.IP \(bu 2 -prevents checks against clobbering non\-npm files\. - -.RE -.SS format\-package\-lock -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Format \fBpackage\-lock\.json\fP or \fBnpm\-shrinkwrap\.json\fP as a human readable file\. -.SS fetch\-retries -.RS 0 -.IP \(bu 2 -Default: 2 -.IP \(bu 2 -Type: Number - -.RE -.P -The "retries" config for the \fBretry\fP module to use when fetching -packages from the registry\. -.SS fetch\-retry\-factor -.RS 0 -.IP \(bu 2 -Default: 10 -.IP \(bu 2 -Type: Number - -.RE -.P -The "factor" config for the \fBretry\fP module to use when fetching -packages\. -.SS fetch\-retry\-mintimeout -.RS 0 -.IP \(bu 2 -Default: 10000 (10 seconds) -.IP \(bu 2 -Type: Number - -.RE -.P -The "minTimeout" config for the \fBretry\fP module to use when fetching -packages\. -.SS fetch\-retry\-maxtimeout -.RS 0 -.IP \(bu 2 -Default: 60000 (1 minute) -.IP \(bu 2 -Type: Number - -.RE -.P -The "maxTimeout" config for the \fBretry\fP module to use when fetching -packages\. -.SS git -.RS 0 -.IP \(bu 2 -Default: \fB"git"\fP -.IP \(bu 2 -Type: String - -.RE -.P -The command to use for git commands\. If git is installed on the -computer, but is not in the \fBPATH\fP, then set this to the full path to -the git binary\. -.SS git\-tag\-version -.RS 0 -.IP \(bu 2 -Default: \fBtrue\fP -.IP \(bu 2 -Type: Boolean - -.RE -.P -Tag the commit when using the \fBnpm version\fP command\. -.SS commit\-hooks -.RS 0 -.IP \(bu 2 -Default: \fBtrue\fP -.IP \(bu 2 -Type: Boolean - -.RE -.P -Run git commit hooks when using the \fBnpm version\fP command\. -.SS global -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Operates in "global" mode, so that packages are installed into the -\fBprefix\fP folder instead of the current working directory\. See -npm help 5 \fBnpm\-folders\fP for more on the differences in behavior\. -.RS 0 -.IP \(bu 2 -packages are installed into the \fB{prefix}/lib/node_modules\fP folder, instead of the -current working directory\. -.IP \(bu 2 -bin files are linked to \fB{prefix}/bin\fP -.IP \(bu 2 -man pages are linked to \fB{prefix}/share/man\fP - -.RE -.SS globalconfig -.RS 0 -.IP \(bu 2 -Default: {prefix}/etc/npmrc -.IP \(bu 2 -Type: path - -.RE -.P -The config file to read for global config options\. -.SS global\-style -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Causes npm to install the package into your local \fBnode_modules\fP folder with -the same layout it uses with the global \fBnode_modules\fP folder\. Only your -direct dependencies will show in \fBnode_modules\fP and everything they depend -on will be flattened in their \fBnode_modules\fP folders\. This obviously will -eliminate some deduping\. If used with \fBlegacy\-bundling\fP, \fBlegacy\-bundling\fP will be -preferred\. -.SS group -.RS 0 -.IP \(bu 2 -Default: GID of the current process -.IP \(bu 2 -Type: String or Number - -.RE -.P -The group to use when running package scripts in global mode as the root -user\. -.SS heading -.RS 0 -.IP \(bu 2 -Default: \fB"npm"\fP -.IP \(bu 2 -Type: String - -.RE -.P -The string that starts all the debugging log output\. -.SS https\-proxy -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: url - -.RE -.P -A proxy to use for outgoing https requests\. If the \fBHTTPS_PROXY\fP or -\fBhttps_proxy\fP or \fBHTTP_PROXY\fP or \fBhttp_proxy\fP environment variables are set, -proxy settings will be honored by the underlying \fBrequest\fP library\. -.SS if\-present -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, npm will not exit with an error code when \fBrun\-script\fP is invoked for -a script that isn't defined in the \fBscripts\fP section of \fBpackage\.json\fP\|\. This -option can be used when it's desirable to optionally run a script when it's -present and fail if the script fails\. This is useful, for example, when running -scripts that may only apply for some builds in an otherwise generic CI setup\. -.SS ignore\-prepublish -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, npm will not run \fBprepublish\fP scripts\. -.SS ignore\-scripts -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, npm does not run scripts specified in package\.json files\. -.SS init\-module -.RS 0 -.IP \(bu 2 -Default: ~/\.npm\-init\.js -.IP \(bu 2 -Type: path - -.RE -.P -A module that will be loaded by the \fBnpm init\fP command\. See the -documentation for the -init\-package\-json \fIhttps://github\.com/isaacs/init\-package\-json\fR module -for more information, or npm help init\. -.SS init\-author\-name -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -The value \fBnpm init\fP should use by default for the package author's name\. -.SS init\-author\-email -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -The value \fBnpm init\fP should use by default for the package author's email\. -.SS init\-author\-url -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -The value \fBnpm init\fP should use by default for the package author's homepage\. -.SS init\-license -.RS 0 -.IP \(bu 2 -Default: "ISC" -.IP \(bu 2 -Type: String - -.RE -.P -The value \fBnpm init\fP should use by default for the package license\. -.SS init\-version -.RS 0 -.IP \(bu 2 -Default: "1\.0\.0" -.IP \(bu 2 -Type: semver - -.RE -.P -The value that \fBnpm init\fP should use by default for the package -version number, if not already set in package\.json\. -.SS json -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Whether or not to output JSON data, rather than the normal output\. -.P -This feature is currently experimental, and the output data structures for many -commands is either not implemented in JSON yet, or subject to change\. Only the -output from \fBnpm ls \-\-json\fP and \fBnpm search \-\-json\fP are currently valid\. -.SS key -.RS 0 -.IP \(bu 2 -Default: \fBnull\fP -.IP \(bu 2 -Type: String - -.RE -.P -A client key to pass when accessing the registry\. Values should be in PEM -format with newlines replaced by the string "\\n"\. For example: -.P -.RS 2 -.nf -key="\-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\-\\nXXXX\\nXXXX\\n\-\-\-\-\-END PRIVATE KEY\-\-\-\-\-" -.fi -.RE -.P -It is \fInot\fR the path to a key file (and there is no "keyfile" option)\. -.SS legacy\-bundling -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Causes npm to install the package such that versions of npm prior to 1\.4, -such as the one included with node 0\.8, can install the package\. This -eliminates all automatic deduping\. If used with \fBglobal\-style\fP this option -will be preferred\. -.SS link -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, then local installs will link if there is a suitable globally -installed package\. -.P -Note that this means that local installs can cause things to be -installed into the global space at the same time\. The link is only done -if one of the two conditions are met: -.RS 0 -.IP \(bu 2 -The package is not already installed globally, or -.IP \(bu 2 -the globally installed version is identical to the version that is -being installed locally\. - -.RE -.SS local\-address -.RS 0 -.IP \(bu 2 -Default: undefined -.IP \(bu 2 -Type: IP Address - -.RE -.P -The IP address of the local interface to use when making connections -to the npm registry\. Must be IPv4 in versions of Node prior to 0\.12\. -.SS loglevel -.RS 0 -.IP \(bu 2 -Default: "notice" -.IP \(bu 2 -Type: String -.IP \(bu 2 -Values: "silent", "error", "warn", "notice", "http", "timing", "info", -"verbose", "silly" - -.RE -.P -What level of logs to report\. On failure, \fIall\fR logs are written to -\fBnpm\-debug\.log\fP in the current working directory\. -.P -Any logs of a higher level than the setting are shown\. The default is "notice"\. -.SS logstream -.RS 0 -.IP \(bu 2 -Default: process\.stderr -.IP \(bu 2 -Type: Stream - -.RE -.P -This is the stream that is passed to the -npmlog \fIhttps://github\.com/npm/npmlog\fR module at run time\. -.P -It cannot be set from the command line, but if you are using npm -programmatically, you may wish to send logs to somewhere other than -stderr\. -.P -If the \fBcolor\fP config is set to true, then this stream will receive -colored output if it is a TTY\. -.SS logs\-max -.RS 0 -.IP \(bu 2 -Default: 10 -.IP \(bu 2 -Type: Number - -.RE -.P -The maximum number of log files to store\. -.SS long -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Show extended information in \fBnpm ls\fP and \fBnpm search\fP\|\. -.SS maxsockets -.RS 0 -.IP \(bu 2 -Default: 50 -.IP \(bu 2 -Type: Number - -.RE -.P -The maximum number of connections to use per origin (protocol/host/port -combination)\. Passed to the \fBhttp\fP \fBAgent\fP used to make the request\. -.SS message -.RS 0 -.IP \(bu 2 -Default: "%s" -.IP \(bu 2 -Type: String - -.RE -.P -Commit message which is used by \fBnpm version\fP when creating version commit\. -.P -Any "%s" in the message will be replaced with the version number\. -.SS metrics\-registry -.RS 0 -.IP \(bu 2 -Default: The value of \fBregistry\fP (which defaults to "https://registry\.npmjs\.org/") -.IP \(bu 2 -Type: String - -.RE -.P -The registry you want to send cli metrics to if \fBsend\-metrics\fP is true\. -.SS node\-options -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: String - -.RE -.P -Options to pass through to Node\.js via the \fBNODE_OPTIONS\fP environment -variable\. This does not impact how npm itself is executed but it does -impact how lifecycle scripts are called\. -.SS node\-version -.RS 0 -.IP \(bu 2 -Default: process\.version -.IP \(bu 2 -Type: semver or false - -.RE -.P -The node version to use when checking a package's \fBengines\fP map\. -.SS noproxy -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: String or Array - -.RE -.P -A comma\-separated string or an array of domain extensions that a proxy should not be used for\. -.SS offline -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Force offline mode: no network requests will be done during install\. To allow -the CLI to fill in missing cache data, see \fB\-\-prefer\-offline\fP\|\. -.SS onload\-script -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: path - -.RE -.P -A node module to \fBrequire()\fP when npm loads\. Useful for programmatic -usage\. -.SS only -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: String - -.RE -.P -When "dev" or "development" and running local \fBnpm install\fP without any -arguments, only devDependencies (and their dependencies) are installed\. -.P -When "dev" or "development" and running local \fBnpm ls\fP, \fBnpm outdated\fP, or -\fBnpm update\fP, is an alias for \fB\-\-dev\fP\|\. -.P -When "prod" or "production" and running local \fBnpm install\fP without any -arguments, only non\-devDependencies (and their dependencies) are -installed\. -.P -When "prod" or "production" and running local \fBnpm ls\fP, \fBnpm outdated\fP, or -\fBnpm update\fP, is an alias for \fB\-\-production\fP\|\. -.SS optional -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Attempt to install packages in the \fBoptionalDependencies\fP object\. Note -that if these packages fail to install, the overall installation -process is not aborted\. -.SS otp -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: Number - -.RE -.P -This is a one\-time password from a two\-factor authenticator\. It's needed -when publishing or changing package permissions with \fBnpm access\fP\|\. -.SS package\-lock -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to false, then ignore \fBpackage\-lock\.json\fP files when installing\. This -will also prevent \fIwriting\fR \fBpackage\-lock\.json\fP if \fBsave\fP is true\. -.P -When package package\-locks are disabled, automatic pruning of extraneous -modules will also be disabled\. To remove extraneous modules with -package\-locks disabled use \fBnpm prune\fP\|\. -.P -This option is an alias for \fB\-\-shrinkwrap\fP\|\. -.SS package\-lock\-only -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to true, it will update only the \fBpackage\-lock\.json\fP, -instead of checking \fBnode_modules\fP and downloading dependencies\. -.SS parseable -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Output parseable results from commands that write to -standard output\. For \fBnpm search\fP, this will be tab\-separated table format\. -.SS prefer\-offline -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, staleness checks for cached data will be bypassed, but missing data -will be requested from the server\. To force full offline mode, use \fB\-\-offline\fP\|\. -.P -This option is effectively equivalent to \fB\-\-cache\-min=9999999\fP\|\. -.SS prefer\-online -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, staleness checks for cached data will be forced, making the CLI look -for updates immediately even for fresh package data\. -.SS prefix -.RS 0 -.IP \(bu 2 -Default: see npm help 5 folders -.IP \(bu 2 -Type: path - -.RE -.P -The location to install global items\. If set on the command line, then -it forces non\-global commands to run in the specified folder\. -.SS preid -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -The "prerelease identifier" to use as a prefix for the "prerelease" part of a -semver\. Like the \fBrc\fP in \fB1\.2\.0\-rc\.8\fP\|\. -.SS production -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Set to true to run in "production" mode\. -.RS 0 -.IP 1. 3 -devDependencies are not installed at the topmost level when running -local \fBnpm install\fP without any arguments\. -.IP 2. 3 -Set the NODE_ENV="production" for lifecycle scripts\. - -.RE -.SS progress -.RS 0 -.IP \(bu 2 -Default: true, unless TRAVIS or CI env vars set\. -.IP \(bu 2 -Type: Boolean - -.RE -.P -When set to \fBtrue\fP, npm will display a progress bar during time intensive -operations, if \fBprocess\.stderr\fP is a TTY\. -.P -Set to \fBfalse\fP to suppress the progress bar\. -.SS proxy -.RS 0 -.IP \(bu 2 -Default: null -.IP \(bu 2 -Type: url - -.RE -.P -A proxy to use for outgoing http requests\. If the \fBHTTP_PROXY\fP or -\fBhttp_proxy\fP environment variables are set, proxy settings will be -honored by the underlying \fBrequest\fP library\. -.SS read\-only -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -This is used to mark a token as unable to publish when configuring limited access tokens with the \fBnpm token create\fP command\. -.SS rebuild\-bundle -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Rebuild bundled dependencies after installation\. -.SS registry -.RS 0 -.IP \(bu 2 -Default: https://registry\.npmjs\.org/ -.IP \(bu 2 -Type: url - -.RE -.P -The base URL of the npm package registry\. -.SS rollback -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Remove failed installs\. -.SS save -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Save installed packages to a package\.json file as dependencies\. -.P -When used with the \fBnpm rm\fP command, it removes it from the \fBdependencies\fP -object\. -.P -Only works if there is already a package\.json file present\. -.SS save\-bundle -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If a package would be saved at install time by the use of \fB\-\-save\fP, -\fB\-\-save\-dev\fP, or \fB\-\-save\-optional\fP, then also put it in the -\fBbundleDependencies\fP list\. -.P -When used with the \fBnpm rm\fP command, it removes it from the -bundledDependencies list\. -.SS save\-prod -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Makes sure that a package will be saved into \fBdependencies\fP specifically\. This -is useful if a package already exists in \fBdevDependencies\fP or -\fBoptionalDependencies\fP, but you want to move it to be a production dep\. This is -also the default behavior if \fB\-\-save\fP is true, and neither \fB\-\-save\-dev\fP or -\fB\-\-save\-optional\fP are true\. -.SS save\-dev -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Save installed packages to a package\.json file as \fBdevDependencies\fP\|\. -.P -When used with the \fBnpm rm\fP command, it removes it from the -\fBdevDependencies\fP object\. -.P -Only works if there is already a package\.json file present\. -.SS save\-exact -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Dependencies saved to package\.json using \fB\-\-save\fP, \fB\-\-save\-dev\fP or -\fB\-\-save\-optional\fP will be configured with an exact version rather than -using npm's default semver range operator\. -.SS save\-optional -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Save installed packages to a package\.json file as -optionalDependencies\. -.P -When used with the \fBnpm rm\fP command, it removes it from the -\fBdevDependencies\fP object\. -.P -Only works if there is already a package\.json file present\. -.SS save\-prefix -.RS 0 -.IP \(bu 2 -Default: '^' -.IP \(bu 2 -Type: String - -.RE -.P -Configure how versions of packages installed to a package\.json file via -\fB\-\-save\fP or \fB\-\-save\-dev\fP get prefixed\. -.P -For example if a package has version \fB1\.2\.3\fP, by default its version is -set to \fB^1\.2\.3\fP which allows minor upgrades for that package, but after -\fBnpm config set save\-prefix='~'\fP it would be set to \fB~1\.2\.3\fP which only allows -patch upgrades\. -.SS scope -.RS 0 -.IP \(bu 2 -Default: the scope of the current project, if any, or "" -.IP \(bu 2 -Type: String - -.RE -.P -Associate an operation with a scope for a scoped registry\. Useful when logging -in to a private registry for the first time: -\fBnpm login \-\-scope=@organization \-\-registry=registry\.organization\.com\fP, which -will cause \fB@organization\fP to be mapped to the registry for future installation -of packages specified according to the pattern \fB@organization/package\fP\|\. -.SS script\-shell -.RS 0 -.IP \(bu 2 -Default: \fBnull\fP -.IP \(bu 2 -Type: path - -.RE -.P -The shell to use for scripts run with the \fBnpm run\fP command\. -.SS scripts\-prepend\-node\-path -.RS 0 -.IP \(bu 2 -Default: "warn\-only" -.IP \(bu 2 -Type: Boolean, \fB"auto"\fP or \fB"warn\-only"\fP - -.RE -.P -If set to \fBtrue\fP, add the directory in which the current \fBnode\fP executable -resides to the \fBPATH\fP environment variable when running scripts, -even if that means that \fBnpm\fP will invoke a different \fBnode\fP executable than -the one which it is running\. -.P -If set to \fBfalse\fP, never modify \fBPATH\fP with that\. -.P -If set to \fB"warn\-only"\fP, never modify \fBPATH\fP but print a warning if \fBnpm\fP thinks -that you may want to run it with \fBtrue\fP, e\.g\. because the \fBnode\fP executable -in the \fBPATH\fP is not the one \fBnpm\fP was invoked with\. -.P -If set to \fBauto\fP, only add that directory to the \fBPATH\fP environment variable -if the \fBnode\fP executable with which \fBnpm\fP was invoked and the one that is found -first on the \fBPATH\fP are different\. -.SS searchexclude -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -Space\-separated options that limit the results from search\. -.SS searchopts -.RS 0 -.IP \(bu 2 -Default: "" -.IP \(bu 2 -Type: String - -.RE -.P -Space\-separated options that are always passed to search\. -.SS searchlimit -.RS 0 -.IP \(bu 2 -Default: 20 -.IP \(bu 2 -Type: Number - -.RE -.P -Number of items to limit search results to\. Will not apply at all to legacy -searches\. -.SS searchstaleness -.RS 0 -.IP \(bu 2 -Default: 900 (15 minutes) -.IP \(bu 2 -Type: Number - -.RE -.P -The age of the cache, in seconds, before another registry request is made if -using legacy search endpoint\. -.SS send\-metrics -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, success/failure metrics will be reported to the registry stored in -\fBmetrics\-registry\fP\|\. These requests contain the number of successful and -failing runs of the npm CLI and the time period overwhich those counts were -gathered\. No identifying information is included in these requests\. -.SS shell -.RS 0 -.IP \(bu 2 -Default: SHELL environment variable, or "bash" on Posix, or "cmd" on -Windows -.IP \(bu 2 -Type: path - -.RE -.P -The shell to run for the \fBnpm explore\fP command\. -.SS shrinkwrap -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to false, then ignore \fBnpm\-shrinkwrap\.json\fP files when installing\. This -will also prevent \fIwriting\fR \fBnpm\-shrinkwrap\.json\fP if \fBsave\fP is true\. -.P -This option is an alias for \fB\-\-package\-lock\fP\|\. -.SS sign\-git\-commit -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to true, then the \fBnpm version\fP command will commit the new package -version using \fB\-S\fP to add a signature\. -.P -Note that git requires you to have set up GPG keys in your git configs -for this to work properly\. -.SS sign\-git\-tag -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -If set to true, then the \fBnpm version\fP command will tag the version -using \fB\-s\fP to add a signature\. -.P -Note that git requires you to have set up GPG keys in your git configs -for this to work properly\. -.SS sso\-poll\-frequency -.RS 0 -.IP \(bu 2 -Default: 500 -.IP \(bu 2 -Type: Number - -.RE -.P -When used with SSO\-enabled \fBauth\-type\fPs, configures how regularly the registry -should be polled while the user is completing authentication\. -.SS sso\-type -.RS 0 -.IP \(bu 2 -Default: 'oauth' -.IP \(bu 2 -Type: 'oauth', 'saml', or null - -.RE -.P -If \fB\-\-auth\-type=sso\fP, the type of SSO type to use\. -.SS strict\-ssl -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Whether or not to do SSL key validation when making requests to the -registry via https\. -.P -See also the \fBca\fP config\. -.SS tag -.RS 0 -.IP \(bu 2 -Default: latest -.IP \(bu 2 -Type: String - -.RE -.P -If you ask npm to install a package and don't tell it a specific version, then -it will install the specified tag\. -.P -Also the tag that is added to the package@version specified by the \fBnpm -tag\fP command, if no explicit tag is given\. -.SS tag\-version\-prefix -.RS 0 -.IP \(bu 2 -Default: \fB"v"\fP -.IP \(bu 2 -Type: String - -.RE -.P -If set, alters the prefix used when tagging a new version when performing a -version increment using \fBnpm\-version\fP\|\. To remove the prefix altogether, set it -to the empty string: \fB""\fP\|\. -.P -Because other tools may rely on the convention that npm version tags look like -\fBv1\.0\.0\fP, \fIonly use this property if it is absolutely necessary\fR\|\. In -particular, use care when overriding this setting for public packages\. -.SS timing -.RS 0 -.IP \(bu 2 -Default: \fBfalse\fP -.IP \(bu 2 -Type: Boolean - -.RE -.P -If true, writes an \fBnpm\-debug\fP log to \fB_logs\fP and timing information to -\fB_timing\.json\fP, both in your cache\. \fB_timing\.json\fP is a newline delimited -list of JSON objects\. You can quickly view it with this -json \fIhttps://www\.npmjs\.com/package/json\fR command line: -\fBjson \-g < ~/\.npm/_timing\.json\fP\|\. -.SS tmp -.RS 0 -.IP \(bu 2 -Default: TMPDIR environment variable, or "/tmp" -.IP \(bu 2 -Type: path - -.RE -.P -Where to store temporary files and folders\. All temp files are deleted -on success, but left behind on failure for forensic purposes\. -.SS unicode -.RS 0 -.IP \(bu 2 -Default: false on windows, true on mac/unix systems with a unicode locale -.IP \(bu 2 -Type: Boolean - -.RE -.P -When set to true, npm uses unicode characters in the tree output\. When -false, it uses ascii characters to draw trees\. -.SS unsafe\-perm -.RS 0 -.IP \(bu 2 -Default: false if running as root, true otherwise -.IP \(bu 2 -Type: Boolean - -.RE -.P -Set to true to suppress the UID/GID switching when running package -scripts\. If set explicitly to false, then installing as a non\-root user -will fail\. -.SS update\-notifier -.RS 0 -.IP \(bu 2 -Default: true -.IP \(bu 2 -Type: Boolean - -.RE -.P -Set to false to suppress the update notification when using an older -version of npm than the latest\. -.SS usage -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: Boolean - -.RE -.P -Set to show short usage output (like the \-H output) -instead of complete help when doing npm help \fBnpm\-help\fP\|\. -.SS user -.RS 0 -.IP \(bu 2 -Default: "nobody" -.IP \(bu 2 -Type: String or Number - -.RE -.P -The UID to set to when running package scripts as root\. -.SS userconfig -.RS 0 -.IP \(bu 2 -Default: ~/\.npmrc -.IP \(bu 2 -Type: path - -.RE -.P -The location of user\-level configuration settings\. -.SS umask -.RS 0 -.IP \(bu 2 -Default: 022 -.IP \(bu 2 -Type: Octal numeric string in range 0000\.\.0777 (0\.\.511) - -.RE -.P -The "umask" value to use when setting the file creation mode on files -and folders\. -.P -Folders and executables are given a mode which is \fB0777\fP masked against -this value\. Other files are given a mode which is \fB0666\fP masked against -this value\. Thus, the defaults are \fB0755\fP and \fB0644\fP respectively\. -.SS user\-agent -.RS 0 -.IP \(bu 2 -Default: node/{process\.version} {process\.platform} {process\.arch} -.IP \(bu 2 -Type: String - -.RE -.P -Sets a User\-Agent to the request header -.SS version -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: boolean - -.RE -.P -If true, output the npm version and exit successfully\. -.P -Only relevant when specified explicitly on the command line\. -.SS versions -.RS 0 -.IP \(bu 2 -Default: false -.IP \(bu 2 -Type: boolean - -.RE -.P -If true, output the npm version as well as node's \fBprocess\.versions\fP map, and -exit successfully\. -.P -Only relevant when specified explicitly on the command line\. -.SS viewer -.RS 0 -.IP \(bu 2 -Default: "man" on Posix, "browser" on Windows -.IP \(bu 2 -Type: path - -.RE -.P -The program to use to view help content\. -.P -Set to \fB"browser"\fP to view html help content in the default web browser\. -.SH SEE ALSO -.RS 0 -.IP \(bu 2 -npm help config -.IP \(bu 2 -npm help 5 npmrc -.IP \(bu 2 -npm help 7 scripts -.IP \(bu 2 -npm help 5 folders -.IP \(bu 2 -npm help npm - -.RE - diff --git a/deps/npm/man/man7/npm-index.7 b/deps/npm/man/man7/npm-index.7 deleted file mode 100644 index 0506601dadef70..00000000000000 --- a/deps/npm/man/man7/npm-index.7 +++ /dev/null @@ -1,244 +0,0 @@ -.TH "NPM\-INDEX" "7" "October 2019" "" "" -.SH "NAME" -\fBnpm-index\fR \- Index of all npm documentation -.SS npm help README -.P -a JavaScript package manager -.SH Command Line Documentation -.P -Using npm on the command line -.SS npm help npm -.P -javascript package manager -.SS npm help access -.P -Set access level on published packages -.SS npm help adduser -.P -Add a registry user account -.SS npm help audit -.P -Run a security audit -.SS npm help bin -.P -Display npm bin folder -.SS npm help bugs -.P -Bugs for a package in a web browser maybe -.SS npm help build -.P -Build a package -.SS npm help bundle -.P -REMOVED -.SS npm help cache -.P -Manipulates packages cache -.SS npm help ci -.P -Install a project with a clean slate -.SS npm help completion -.P -Tab Completion for npm -.SS npm help config -.P -Manage the npm configuration files -.SS npm help dedupe -.P -Reduce duplication -.SS npm help deprecate -.P -Deprecate a version of a package -.SS npm help dist\-tag -.P -Modify package distribution tags -.SS npm help docs -.P -Docs for a package in a web browser maybe -.SS npm help doctor -.P -Check your environments -.SS npm help edit -.P -Edit an installed package -.SS npm help explore -.P -Browse an installed package -.SS npm help help\-search -.P -Search npm help documentation -.SS npm help help -.P -Get help on npm -.SS npm help hook -.P -Manage registry hooks -.SS npm help init -.P -create a package\.json file -.SS npm help install\-ci\-test -.P -Install a project with a clean slate and run tests -.SS npm help install\-test -.P -Install package(s) and run tests -.SS npm help install -.P -Install a package -.SS npm help link -.P -Symlink a package folder -.SS npm help logout -.P -Log out of the registry -.SS npm help ls -.P -List installed packages -.SS npm help org -.P -Manage orgs -.SS npm help outdated -.P -Check for outdated packages -.SS npm help owner -.P -Manage package owners -.SS npm help pack -.P -Create a tarball from a package -.SS npm help ping -.P -Ping npm registry -.SS npm help prefix -.P -Display prefix -.SS npm help profile -.P -Change settings on your registry profile -.SS npm help prune -.P -Remove extraneous packages -.SS npm help publish -.P -Publish a package -.SS npm help rebuild -.P -Rebuild a package -.SS npm help repo -.P -Open package repository page in the browser -.SS npm help restart -.P -Restart a package -.SS npm help root -.P -Display npm root -.SS npm help run\-script -.P -Run arbitrary package scripts -.SS npm help search -.P -Search for packages -.SS npm help shrinkwrap -.P -Lock down dependency versions for publication -.SS npm help star -.P -Mark your favorite packages -.SS npm help stars -.P -View packages marked as favorites -.SS npm help start -.P -Start a package -.SS npm help stop -.P -Stop a package -.SS npm help team -.P -Manage organization teams and team memberships -.SS npm help test -.P -Test a package -.SS npm help token -.P -Manage your authentication tokens -.SS npm help uninstall -.P -Remove a package -.SS npm help unpublish -.P -Remove a package from the registry -.SS npm help update -.P -Update a package -.SS npm help version -.P -Bump a package version -.SS npm help view -.P -View registry info -.SS npm help whoami -.P -Display npm username -.SH API Documentation -.P -Using npm in your Node programs -.SH Files -.P -File system structures npm uses -.SS npm help 5 folders -.P -Folder Structures Used by npm -.SS npm help 5 package\-locks -.P -An explanation of npm lockfiles -.SS npm help 5 shrinkwrap\.json -.P -A publishable lockfile -.SS npm help 5 npmrc -.P -The npm config files -.SS npm help 5 package\-lock\.json -.P -A manifestation of the manifest -.SS npm help 5 package\.json -.P -Specifics of npm's package\.json handling -.SH Misc -.P -Various other bits and bobs -.SS npm help 7 coding\-style -.P -npm's "funny" coding style -.SS npm help 7 config -.P -More than you probably want to know about npm configuration -.SS npm help 7 developers -.P -Developer Guide -.SS npm help 7 disputes -.P -Handling Module Name Disputes -.SS npm help 7 index -.P -Index of all npm documentation -.SS npm help 7 orgs -.P -Working with Teams & Orgs -.SS npm help 7 registry -.P -The JavaScript Package Registry -.SS npm help 7 scope -.P -Scoped packages -.SS npm help 7 scripts -.P -How npm handles the "scripts" field -.SS npm help 7 removing\-npm -.P -Cleaning the Slate -.SS npm help 7 semver -.P -The semantic versioner for npm - diff --git a/deps/npm/man/man7/npm-orgs.7 b/deps/npm/man/man7/orgs.7 similarity index 90% rename from deps/npm/man/man7/npm-orgs.7 rename to deps/npm/man/man7/orgs.7 index 041dd985ba0a33..2c52a2db466960 100644 --- a/deps/npm/man/man7/npm-orgs.7 +++ b/deps/npm/man/man7/orgs.7 @@ -1,7 +1,7 @@ -.TH "NPM\-ORGS" "7" "October 2019" "" "" +.TH "ORGS" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-orgs\fR \- Working with Teams & Orgs -.SH DESCRIPTION +\fBorgs\fR \- Working with Teams & Orgs +.SS Description .P There are three levels of org users: .RS 0 @@ -28,7 +28,7 @@ There are two main commands: \fBnpm access\fP see npm help access for more details .RE -.SH Team Admins create teams +.SS Team Admins create teams .RS 0 .IP \(bu 2 Check who you’ve added to your org: @@ -64,7 +64,7 @@ Add members to that team: npm team add .fi .RE -.SH Publish a package and adjust package access +.SS Publish a package and adjust package access .RS 0 .IP \(bu 2 In package directory, run @@ -100,7 +100,7 @@ Revoke access: npm access revoke [] .fi .RE -.SH Monitor your package access +.SS Monitor your package access .RS 0 .IP \(bu 2 See what org packages a team member can access: @@ -134,14 +134,13 @@ Check which teams are collaborating on a package: npm access ls\-collaborators .fi .RE -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 npm help team .IP \(bu 2 npm help access .IP \(bu 2 -npm help 7 scope +npm help scope .RE - diff --git a/deps/npm/man/man7/npm-registry.7 b/deps/npm/man/man7/registry.7 similarity index 79% rename from deps/npm/man/man7/npm-registry.7 rename to deps/npm/man/man7/registry.7 index 77e249b6c34341..bbb5e802bfb826 100644 --- a/deps/npm/man/man7/npm-registry.7 +++ b/deps/npm/man/man7/registry.7 @@ -1,7 +1,7 @@ -.TH "NPM\-REGISTRY" "7" "October 2019" "" "" +.TH "REGISTRY" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-registry\fR \- The JavaScript Package Registry -.SH DESCRIPTION +\fBregistry\fR \- The JavaScript Package Registry +.SS Description .P To resolve packages by name and version, npm talks to a registry website that implements the CommonJS Package Registry specification for reading @@ -25,10 +25,10 @@ https://skimdb\.npmjs\.com/registry\|\. The code for the couchapp is available at https://github\.com/npm/npm\-registry\-couchapp\|\. .P The registry URL used is determined by the scope of the package (see -npm help 7 \fBnpm\-scope\fP)\. If no scope is specified, the default registry is used, which is -supplied by the \fBregistry\fP config parameter\. See npm help \fBnpm\-config\fP, -npm help 5 \fBnpmrc\fP, and npm help 7 \fBnpm\-config\fP for more on managing npm's configuration\. -.SH Does npm send any information about me back to the registry? +npm help \fBscope\fP\|\. If no scope is specified, the default registry is used, which is +supplied by the \fBregistry\fP config parameter\. See npm help \fBconfig\fP, +npm help \fBnpmrc\fP, and npm help \fBconfig\fP for more on managing npm's configuration\. +.SS Does npm send any information about me back to the registry? .P Yes\. .P @@ -54,7 +54,7 @@ build farms\. .P The npm registry does not try to correlate the information in these headers with any authenticated accounts that may be used in the same requests\. -.SH Can I run my own private registry? +.SS Can I run my own private registry? .P Yes! .P @@ -68,38 +68,37 @@ default will only publish internally\. .P If you then want to publish a package for the whole world to see, you can simply override the \fB\-\-registry\fP option for that \fBpublish\fP command\. -.SH I don't want my package published in the official registry\. It's private\. +.SS I don't want my package published in the official registry\. It's private\. .P Set \fB"private": true\fP in your package\.json to prevent it from being published at all, or \fB"publishConfig":{"registry":"http://my\-internal\-registry\.local"}\fP to force it to be published only to your internal registry\. .P -See npm help 5 \fBpackage\.json\fP for more info on what goes in the package\.json file\. -.SH Will you replicate from my registry into the public one? +See npm help \fBpackage\.json\fP for more info on what goes in the package\.json file\. +.SS Will you replicate from my registry into the public one? .P No\. If you want things to be public, then publish them into the public registry using npm\. What little security there is would be for nought otherwise\. -.SH Do I have to use couchdb to build a registry that npm can talk to? +.SS Do I have to use couchdb to build a registry that npm can talk to? .P No, but it's way easier\. Basically, yes, you do, or you have to effectively implement the entire CouchDB API anyway\. -.SH Is there a website or something to see package docs and such? +.SS Is there a website or something to see package docs and such? .P Yes, head over to https://www\.npmjs\.com/ -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 npm help config .IP \(bu 2 -npm help 7 config +npm help config .IP \(bu 2 -npm help 5 npmrc +npm help npmrc .IP \(bu 2 -npm help 7 developers +npm help developers .IP \(bu 2 -npm help 7 disputes +npm help disputes .RE - diff --git a/deps/npm/man/man7/removing-npm.7 b/deps/npm/man/man7/removal.7 similarity index 87% rename from deps/npm/man/man7/removing-npm.7 rename to deps/npm/man/man7/removal.7 index 2f034bd48b0aa2..a4df8b446127b2 100644 --- a/deps/npm/man/man7/removing-npm.7 +++ b/deps/npm/man/man7/removal.7 @@ -1,7 +1,7 @@ -.TH "NPM\-REMOVAL" "1" "October 2019" "" "" +.TH "REMOVAL" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-removal\fR \- Cleaning the Slate -.SH SYNOPSIS +\fBremoval\fR \- Cleaning the Slate +.SS Synopsis .P So sad to see you go\. .P @@ -18,7 +18,7 @@ Or, if that fails, get the npm source code, and do: sudo make uninstall .fi .RE -.SH More Severe Uninstalling +.SS More Severe Uninstalling .P Usually, the above instructions are sufficient\. That will remove npm, but leave behind anything you've installed\. @@ -28,7 +28,7 @@ continue reading\. .P Note that this is only necessary for globally\-installed packages\. Local installs are completely contained within a project's \fBnode_modules\fP -folder\. Delete that folder, and everything is gone (unless a package's +folder\. Delete that folder, and everything is gone less a package's install script is particularly ill\-behaved)\. .P This assumes that you installed node and npm in the default place\. If @@ -65,14 +65,11 @@ find /usr/local/{lib/node,bin} \-exec grep \-l npm \\{\\} \\; ; .RE .P (This is also in the README file\.) -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 -README -.IP \(bu 2 npm help uninstall .IP \(bu 2 npm help prune .RE - diff --git a/deps/npm/man/man7/npm-scope.7 b/deps/npm/man/man7/scope.7 similarity index 93% rename from deps/npm/man/man7/npm-scope.7 rename to deps/npm/man/man7/scope.7 index 491b08fd5798fe..ffe5570ae87b33 100644 --- a/deps/npm/man/man7/npm-scope.7 +++ b/deps/npm/man/man7/scope.7 @@ -1,7 +1,7 @@ -.TH "NPM\-SCOPE" "7" "October 2019" "" "" +.TH "SCOPE" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-scope\fR \- Scoped packages -.SH DESCRIPTION +\fBscope\fR \- Scoped packages +.SS Description .P All npm packages have a name\. Some package names also have a scope\. A scope follows the usual rules for package names (URL\-safe characters, no leading dots @@ -26,7 +26,7 @@ Scoped packages can be published and installed as of \fBnpm@2\fP and are support by the primary npm registry\. Unscoped packages can depend on scoped packages and vice versa\. The npm client is backwards\-compatible with unscoped registries, so it can be used to work with scoped and unscoped registries at the same time\. -.SH Installing scoped packages +.SS Installing scoped packages .P Scoped packages are installed to a sub\-folder of the regular installation folder, e\.g\. if your other packages are installed in \fBnode_modules/packagename\fP, @@ -54,8 +54,8 @@ Or in \fBpackage\.json\fP: .RE .P Note that if the \fB@\fP symbol is omitted, in either case, npm will instead attempt to -install from GitHub; see npm help \fBnpm\-install\fP\|\. -.SH Requiring scoped packages +install from GitHub; see npm help \fBinstall\fP\|\. +.SS Requiring scoped packages .P Because scoped packages are installed into a scope folder, you have to include the name of the scope when requiring them in your code, e\.g\. @@ -68,7 +68,7 @@ require('@myorg/mypackage') .P There is nothing special about the way Node treats scope folders\. This simply requires the \fBmypackage\fP module in the folder named \fB@myorg\fP\|\. -.SH Publishing scoped packages +.SS Publishing scoped packages .P Scoped packages can be published from the CLI as of \fBnpm@2\fP and can be published to any registry that supports them, including the primary npm @@ -93,7 +93,7 @@ You can then publish the module with \fBnpm publish\fP or \fBnpm publish \-\-access restricted\fP, and it will be present in the npm registry, with restricted access\. You can then change the access permissions, if desired, with \fBnpm access\fP or on the npmjs\.com website\. -.SH Associating a scope with a registry +.SS Associating a scope with a registry .P Scopes can be associated with a separate registry\. This allows you to seamlessly use a mix of packages from the primary npm registry and one or more @@ -122,7 +122,7 @@ Once a scope is associated with a registry, any \fBnpm install\fP for a package with that scope will request packages from that registry instead\. Any \fBnpm publish\fP for a package name that contains the scope will be published to that registry instead\. -.SH SEE ALSO +.SS See also .RS 0 .IP \(bu 2 npm help install @@ -131,7 +131,6 @@ npm help publish .IP \(bu 2 npm help access .IP \(bu 2 -npm help 7 registry +npm help registry .RE - diff --git a/deps/npm/man/man7/npm-scripts.7 b/deps/npm/man/man7/scripts.7 similarity index 88% rename from deps/npm/man/man7/npm-scripts.7 rename to deps/npm/man/man7/scripts.7 index 3d744ce065d091..7517c5997585fd 100644 --- a/deps/npm/man/man7/npm-scripts.7 +++ b/deps/npm/man/man7/scripts.7 @@ -1,70 +1,70 @@ -.TH "NPM\-SCRIPTS" "7" "October 2019" "" "" +.TH "SCRIPTS" "7" "November 2019" "" "" .SH "NAME" -\fBnpm-scripts\fR \- How npm handles the "scripts" field -.SH DESCRIPTION +\fBscripts\fR \- How npm handles the "scripts" field +.SS Description .P npm supports the "scripts" property of the package\.json file, for the following scripts: .RS 0 .IP \(bu 2 -prepublish: +\fBprepublish\fR (\fIas of npm@5, \fBprepublish\fP is deprecated\. Use \fBprepare\fP for build steps and \fBprepublishOnly\fP for upload\-only\.\fR): Run BEFORE the package is packed and published, as well as on local \fBnpm install\fP without any arguments\. (See below) .IP \(bu 2 -prepare: +\fBprepare\fR: Run both BEFORE the package is packed and published, on local \fBnpm install\fP without any arguments, and when installing git dependencies (See below)\. This is run AFTER \fBprepublish\fP, but BEFORE \fBprepublishOnly\fP\|\. .IP \(bu 2 -prepublishOnly: +\fBprepublishOnly\fR: Run BEFORE the package is prepared and packed, ONLY on \fBnpm publish\fP\|\. (See below\.) .IP \(bu 2 -prepack: +\fBprepack\fR: run BEFORE a tarball is packed (on \fBnpm pack\fP, \fBnpm publish\fP, and when installing git dependencies) .IP \(bu 2 -postpack: +\fBpostpack\fR: Run AFTER the tarball has been generated and moved to its final destination\. .IP \(bu 2 -publish, postpublish: +\fBpublish\fR, \fBpostpublish\fR: Run AFTER the package is published\. .IP \(bu 2 -preinstall: +\fBpreinstall\fR: Run BEFORE the package is installed .IP \(bu 2 -install, postinstall: +\fBinstall\fR, \fBpostinstall\fR: Run AFTER the package is installed\. .IP \(bu 2 -preuninstall, uninstall: +\fBpreuninstall\fR, \fBuninstall\fR: Run BEFORE the package is uninstalled\. .IP \(bu 2 -postuninstall: +\fBpostuninstall\fR: Run AFTER the package is uninstalled\. .IP \(bu 2 -preversion: +\fBpreversion\fR: Run BEFORE bumping the package version\. .IP \(bu 2 -version: +\fBversion\fR: Run AFTER bumping the package version, but BEFORE commit\. .IP \(bu 2 -postversion: +\fBpostversion\fR: Run AFTER bumping the package version, and AFTER commit\. .IP \(bu 2 -pretest, test, posttest: +\fBpretest\fR, \fBtest\fR, \fBposttest\fR: Run by the \fBnpm test\fP command\. .IP \(bu 2 -prestop, stop, poststop: +\fBprestop\fR, \fBstop\fR, \fBpoststop\fR: Run by the \fBnpm stop\fP command\. .IP \(bu 2 -prestart, start, poststart: +\fBprestart\fR, \fBstart\fR, \fBpoststart\fR: Run by the \fBnpm start\fP command\. .IP \(bu 2 -prerestart, restart, postrestart: +\fBprerestart\fR, \fBrestart\fR, \fBpostrestart\fR: Run by the \fBnpm restart\fP command\. Note: \fBnpm restart\fP will run the stop and start scripts if no \fBrestart\fP script is provided\. .IP \(bu 2 -preshrinkwrap, shrinkwrap, postshrinkwrap: +\fBpreshrinkwrap\fR, \fBshrinkwrap\fR, \fBpostshrinkwrap\fR: Run by the \fBnpm shrinkwrap\fP command\. .RE @@ -72,10 +72,10 @@ Run by the \fBnpm shrinkwrap\fP command\. Additionally, arbitrary scripts can be executed by running \fBnpm run\-script \fP\|\. \fIPre\fR and \fIpost\fR commands with matching names will be run for those as well (e\.g\. \fBpremyscript\fP, \fBmyscript\fP, -\fBpostmyscript\fP)\. Scripts from dependencies can be run with +\fBpostmyscript\fP)\. Scripts from dependencies can be run with \fBnpm explore \-\- npm run \fP\|\. -.SH PREPUBLISH AND PREPARE -.SS DEPRECATION NOTE +.SS Prepublish and Prepare +.SS Deprecation Note .P Since \fBnpm@1\.1\.71\fP, the npm CLI has run the \fBprepublish\fP script for both \fBnpm publish\fP and \fBnpm install\fP, because it's a convenient way to prepare a package @@ -90,7 +90,7 @@ they're in good shape)\. .P See https://github\.com/npm/npm/issues/10074 for a much lengthier justification, with further reading, for this change\. -.SS USE CASES +.SS Use Cases .P If you need to perform operations on your package before it is used, in a way that is not dependent on the operating system or architecture of the @@ -121,7 +121,7 @@ You don't need to rely on your users having \fBcurl\fP or \fBwget\fP or other system tools on the target machines\. .RE -.SH DEFAULT VALUES +.SS Default Values .P npm will default some script values based on package contents\. .RS 0 @@ -136,13 +136,13 @@ haven't defined your own \fBinstall\fP or \fBpreinstall\fP scripts, npm will default the \fBinstall\fP command to compile using node\-gyp\. .RE -.SH USER +.SS User .P If npm was invoked with root privileges, then it will change the uid to the user account or uid specified by the \fBuser\fP config, which defaults to \fBnobody\fP\|\. Set the \fBunsafe\-perm\fP flag to run scripts with root privileges\. -.SH ENVIRONMENT +.SS Environment .P Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of @@ -169,8 +169,8 @@ The package\.json fields are tacked onto the \fBnpm_package_\fP prefix\. So, for instance, if you had \fB{"name":"foo", "version":"1\.2\.5"}\fP in your package\.json file, then your package scripts would have the \fBnpm_package_name\fP environment variable set to "foo", and the -\fBnpm_package_version\fP set to "1\.2\.5"\. You can access these variables -in your code with \fBprocess\.env\.npm_package_name\fP and +\fBnpm_package_version\fP set to "1\.2\.5"\. You can access these variables +in your code with \fBprocess\.env\.npm_package_name\fP and \fBprocess\.env\.npm_package_version\fP, and so on for other fields\. .SS configuration .P @@ -203,7 +203,7 @@ then the user could change the behavior by doing: .P .RS 2 .nf -npm config set foo:port 80 + npm config set foo:port 80 .fi .RE .SS current lifecycle event @@ -222,7 +222,7 @@ see this in the script: process\.env\.npm_package_scripts_install === "foo\.js" .fi .RE -.SH EXAMPLES +.SS Examples .P For example, if your package\.json contains this: .P @@ -257,7 +257,7 @@ fine: } .fi .RE -.SH EXITING +.SS Exiting .P Scripts are run by passing the line as a script argument to \fBsh\fP\|\. .P @@ -267,7 +267,7 @@ process\. Note that these script files don't have to be nodejs or even javascript programs\. They just have to be some kind of executable file\. -.SH HOOK SCRIPTS +.SS Hook Scripts .P If you want to run a specific script at a specific lifecycle event for ALL packages, then you can use a hook script\. @@ -279,7 +279,7 @@ in the package lifecycle for any packages installed in that root\. Hook scripts are run exactly the same way as package\.json scripts\. That is, they are in a separate child process, with the env described above\. -.SH BEST PRACTICES +.SS Best Practices .RS 0 .IP \(bu 2 Don't exit with a non\-zero error code unless you \fIreally\fR mean it\. @@ -289,7 +289,7 @@ only will prevent some optional features, then it's better to just print a warning and exit successfully\. .IP \(bu 2 Try not to use scripts to do what npm can do for you\. Read through -npm help 5 \fBpackage\.json\fP to see all the things that you can specify and enable +npm help \fBpackage\.json\fP to see all the things that you can specify and enable by simply describing your package appropriately\. In general, this will lead to a more robust and consistent state\. .IP \(bu 2 @@ -309,16 +309,15 @@ there is another option\. The only valid use of \fBinstall\fP or \fBpreinstall\f scripts is for compilation which must be done on the target architecture\. .RE -.SH SEE ALSO +.SS See Also .RS 0 .IP \(bu 2 npm help run\-script .IP \(bu 2 -npm help 5 package\.json +npm help package\.json .IP \(bu 2 -npm help 7 developers +npm help developers .IP \(bu 2 npm help install .RE - diff --git a/deps/npm/man/man7/semver.7 b/deps/npm/man/man7/semver.7 index fceb494fcea32b..b65c475f6eb67e 100644 --- a/deps/npm/man/man7/semver.7 +++ b/deps/npm/man/man7/semver.7 @@ -1,4 +1,4 @@ -.TH "SEMVER" "7" "October 2019" "" "" +.TH "SEMVER" "7" "November 2019" "" "" .SH "NAME" \fBsemver\fR \- The semantic versioner for npm .SH Install @@ -508,4 +508,3 @@ coercion is 16 characters; longer components will be ignored (\fB10000000000000000\.4\.7\.4\fP becomes \fB4\.7\.4\fP)\. The maximum value for any semver component is \fBNumber\.MAX_SAFE_INTEGER || (2**53 \- 1)\fP; higher value components are invalid (\fB9999999999999999\.4\.7\.4\fP is likely invalid)\. - diff --git a/deps/npm/node_modules/JSONStream/.travis.yml b/deps/npm/node_modules/JSONStream/.travis.yml index 2f60c363d24cf4..5f30bb5bd1aad4 100644 --- a/deps/npm/node_modules/JSONStream/.travis.yml +++ b/deps/npm/node_modules/JSONStream/.travis.yml @@ -4,3 +4,5 @@ node_js: - 5 - 6 sudo: false + + diff --git a/deps/npm/node_modules/JSONStream/LICENSE.MIT b/deps/npm/node_modules/JSONStream/LICENSE.MIT index 49e7da41fec2be..6eafbd734a6e06 100644 --- a/deps/npm/node_modules/JSONStream/LICENSE.MIT +++ b/deps/npm/node_modules/JSONStream/LICENSE.MIT @@ -2,23 +2,23 @@ The MIT License Copyright (c) 2011 Dominic Tarr -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/JSONStream/bin.js b/deps/npm/node_modules/JSONStream/bin.js index 32209630f2f026..af2b6ac6c6e1aa 100755 --- a/deps/npm/node_modules/JSONStream/bin.js +++ b/deps/npm/node_modules/JSONStream/bin.js @@ -8,3 +8,5 @@ if(!module.parent && process.title !== 'browser') { .pipe(JSONStream.stringify('[', ',\n', ']\n', 2)) .pipe(process.stdout) } + + diff --git a/deps/npm/node_modules/JSONStream/examples/all_docs.js b/deps/npm/node_modules/JSONStream/examples/all_docs.js index f20781e18c9dbf..fa87fe52da53dc 100644 --- a/deps/npm/node_modules/JSONStream/examples/all_docs.js +++ b/deps/npm/node_modules/JSONStream/examples/all_docs.js @@ -6,7 +6,7 @@ var parser = JSONStream.parse(['rows', true]) //emit parts that match this path , req = request({url: 'http://isaacs.couchone.com/registry/_all_docs'}) , logger = es.mapSync(function (data) { //create a stream that logs to stderr, console.error(data) - return data + return data }) req.pipe(parser) diff --git a/deps/npm/node_modules/JSONStream/index.js b/deps/npm/node_modules/JSONStream/index.js index 8c587af769a2d7..f4ed901f965603 100755 --- a/deps/npm/node_modules/JSONStream/index.js +++ b/deps/npm/node_modules/JSONStream/index.js @@ -244,3 +244,4 @@ exports.stringifyObject = function (op, sep, cl, indent) { return stream } + diff --git a/deps/npm/node_modules/JSONStream/readme.markdown b/deps/npm/node_modules/JSONStream/readme.markdown index 7e94ddd7f4c029..422c3df2cc616a 100644 --- a/deps/npm/node_modules/JSONStream/readme.markdown +++ b/deps/npm/node_modules/JSONStream/readme.markdown @@ -118,9 +118,9 @@ stream.on('data', function(data) { ### recursive patterns (..) -`JSONStream.parse('docs..value')` +`JSONStream.parse('docs..value')` (or `JSONStream.parse(['docs', {recurse: true}, 'value'])` using an array) -will emit every `value` object that is a child, grand-child, etc. of the +will emit every `value` object that is a child, grand-child, etc. of the `docs` object. In this example, it will match exactly 5 times at various depth levels, emitting 0, 1, 2, 3 and 4 as results. @@ -204,3 +204,4 @@ https://github.com/Floby/node-json-streams ## license Dual-licensed under the MIT License or the Apache License, version 2.0 + diff --git a/deps/npm/node_modules/JSONStream/test/bool.js b/deps/npm/node_modules/JSONStream/test/bool.js index 9b87b1730f107d..6c386d609f07f5 100644 --- a/deps/npm/node_modules/JSONStream/test/bool.js +++ b/deps/npm/node_modules/JSONStream/test/bool.js @@ -13,7 +13,7 @@ var fs = require ('fs') lies: true, nothing: [null], // stuff: [Math.random(),Math.random(),Math.random()] - } + } : ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]] ) } @@ -25,7 +25,7 @@ var expected = [] , called = 0 , count = 10 , ended = false - + while (count --) expected.push(randomObj()) @@ -34,7 +34,7 @@ while (count --) stringify, JSONStream.parse([true]), es.writeArray(function (err, lines) { - + it(lines).has(expected) console.error('PASSED') }) diff --git a/deps/npm/node_modules/JSONStream/test/doubledot1.js b/deps/npm/node_modules/JSONStream/test/doubledot1.js index ceaa3edb33162b..78149b93f6e7c3 100644 --- a/deps/npm/node_modules/JSONStream/test/doubledot1.js +++ b/deps/npm/node_modules/JSONStream/test/doubledot1.js @@ -11,7 +11,7 @@ var expected = JSON.parse(fs.readFileSync(file)) , parsed = [] fs.createReadStream(file).pipe(parser) - + parser.on('data', function (data) { called ++ parsed.push(data) diff --git a/deps/npm/node_modules/JSONStream/test/doubledot2.js b/deps/npm/node_modules/JSONStream/test/doubledot2.js index 980024153c697a..b0bc5b16704a7b 100644 --- a/deps/npm/node_modules/JSONStream/test/doubledot2.js +++ b/deps/npm/node_modules/JSONStream/test/doubledot2.js @@ -11,7 +11,7 @@ , parsed = [] fs.createReadStream(file).pipe(parser) - + parser.on('data', function (data) { called ++ parsed.push(data) diff --git a/deps/npm/node_modules/JSONStream/test/fn.js b/deps/npm/node_modules/JSONStream/test/fn.js index 01e61e88fa6b61..4acc672627fd16 100644 --- a/deps/npm/node_modules/JSONStream/test/fn.js +++ b/deps/npm/node_modules/JSONStream/test/fn.js @@ -17,7 +17,7 @@ var expected = JSON.parse(fs.readFileSync(file)) , parsed = [] fs.createReadStream(file).pipe(parser) - + parser.on('data', function (data) { called ++ it.has({ diff --git a/deps/npm/node_modules/JSONStream/test/gen.js b/deps/npm/node_modules/JSONStream/test/gen.js index 75e87d56e45a49..c233722ac31a20 100644 --- a/deps/npm/node_modules/JSONStream/test/gen.js +++ b/deps/npm/node_modules/JSONStream/test/gen.js @@ -111,7 +111,7 @@ var tape = require('tape') items++ if(Math.random() < 0.01) console.log(items, '...') }); - + parser.on('end', function () { t.equal(items, size) }); @@ -126,10 +126,10 @@ var tape = require('tape') console.log(stat) if(err) generateTestData(testJSONStreamParse_causesOutOfMem); - else + else testJSONStreamParse_causesOutOfMem() }) }) - + // } diff --git a/deps/npm/node_modules/JSONStream/test/keys.js b/deps/npm/node_modules/JSONStream/test/keys.js index 86b65b257b9572..747723d11e2cc3 100644 --- a/deps/npm/node_modules/JSONStream/test/keys.js +++ b/deps/npm/node_modules/JSONStream/test/keys.js @@ -41,7 +41,7 @@ test('keys via array', function(t) { test('path via array', function(t) { var stream = JSONStream.parse(['obj',{emitPath: true}]); - + var paths = []; var values = []; stream.on('data', function(data) { diff --git a/deps/npm/node_modules/JSONStream/test/map.js b/deps/npm/node_modules/JSONStream/test/map.js index 6c05fc68406c4b..29b9d896913570 100644 --- a/deps/npm/node_modules/JSONStream/test/map.js +++ b/deps/npm/node_modules/JSONStream/test/map.js @@ -37,3 +37,4 @@ test('filter function', function (t) { stream.end() }) + diff --git a/deps/npm/node_modules/JSONStream/test/null.js b/deps/npm/node_modules/JSONStream/test/null.js index 25628ee585568c..95dd60c0af04dc 100644 --- a/deps/npm/node_modules/JSONStream/test/null.js +++ b/deps/npm/node_modules/JSONStream/test/null.js @@ -14,7 +14,7 @@ var test = require('tape') test ('null properties', function (t) { var actual = [] - var stream = + var stream = JSONStream.parse('*.optional') .on('data', function (v) { actual.push(v) }) diff --git a/deps/npm/node_modules/JSONStream/test/parsejson.js b/deps/npm/node_modules/JSONStream/test/parsejson.js index df4fbbe73a40d6..e70dabc1846240 100644 --- a/deps/npm/node_modules/JSONStream/test/parsejson.js +++ b/deps/npm/node_modules/JSONStream/test/parsejson.js @@ -7,7 +7,7 @@ var r = Math.random() , Parser = require('jsonparse') , p = new Parser() - , assert = require('assert') + , assert = require('assert') , times = 20 , bufferFrom = Buffer.from && Buffer.from !== Uint8Array.from , str diff --git a/deps/npm/node_modules/JSONStream/test/stringify.js b/deps/npm/node_modules/JSONStream/test/stringify.js index 20b996957524b9..b6de85ed253f22 100644 --- a/deps/npm/node_modules/JSONStream/test/stringify.js +++ b/deps/npm/node_modules/JSONStream/test/stringify.js @@ -13,7 +13,7 @@ var fs = require ('fs') lies: true, nothing: [null], stuff: [Math.random(),Math.random(),Math.random()] - } + } : ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]] ) } @@ -25,7 +25,7 @@ var expected = [] , called = 0 , count = 10 , ended = false - + while (count --) expected.push(randomObj()) @@ -34,7 +34,7 @@ while (count --) stringify, //JSONStream.parse([/./]), es.writeArray(function (err, lines) { - + it(JSON.parse(lines.join(''))).deepEqual(expected) console.error('PASSED') }) diff --git a/deps/npm/node_modules/JSONStream/test/stringify_object.js b/deps/npm/node_modules/JSONStream/test/stringify_object.js index 73a2b8350d83cf..9490115a0db996 100644 --- a/deps/npm/node_modules/JSONStream/test/stringify_object.js +++ b/deps/npm/node_modules/JSONStream/test/stringify_object.js @@ -16,7 +16,7 @@ var fs = require ('fs') lies: true, nothing: [null], stuff: [Math.random(),Math.random(),Math.random()] - } + } : ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]] ) } @@ -24,7 +24,7 @@ var fs = require ('fs') for (var ix = 0; ix < pending; ix++) (function (count) { var expected = {} , stringify = JSONStream.stringifyObject() - + es.connect( stringify, es.writeArray(function (err, lines) { diff --git a/deps/npm/node_modules/JSONStream/test/test.js b/deps/npm/node_modules/JSONStream/test/test.js index adc3d7569590ec..8ea7c2e1f13895 100644 --- a/deps/npm/node_modules/JSONStream/test/test.js +++ b/deps/npm/node_modules/JSONStream/test/test.js @@ -13,7 +13,7 @@ var expected = JSON.parse(fs.readFileSync(file)) , parsed = [] fs.createReadStream(file).pipe(parser) - + parser.on('data', function (data) { called ++ it.has({ diff --git a/deps/npm/node_modules/JSONStream/test/test2.js b/deps/npm/node_modules/JSONStream/test/test2.js index a77ca3910a9cfe..d09df7be4d3ee0 100644 --- a/deps/npm/node_modules/JSONStream/test/test2.js +++ b/deps/npm/node_modules/JSONStream/test/test2.js @@ -13,7 +13,7 @@ var expected = JSON.parse(fs.readFileSync(file)) , parsed = [] fs.createReadStream(file).pipe(parser) - + parser.on('data', function (data) { called ++ it(data).deepEqual(expected) diff --git a/deps/npm/node_modules/JSONStream/test/two-ways.js b/deps/npm/node_modules/JSONStream/test/two-ways.js index a74dfba36e86f7..8f3b89c8bfe6ec 100644 --- a/deps/npm/node_modules/JSONStream/test/two-ways.js +++ b/deps/npm/node_modules/JSONStream/test/two-ways.js @@ -13,7 +13,7 @@ var fs = require ('fs') lies: true, nothing: [null], // stuff: [Math.random(),Math.random(),Math.random()] - } + } : ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]] ) } @@ -25,7 +25,7 @@ var expected = [] , called = 0 , count = 10 , ended = false - + while (count --) expected.push(randomObj()) @@ -34,7 +34,7 @@ while (count --) stringify, JSONStream.parse([/./]), es.writeArray(function (err, lines) { - + it(lines).has(expected) console.error('PASSED') }) diff --git a/deps/npm/node_modules/agentkeepalive/History.md b/deps/npm/node_modules/agentkeepalive/History.md index 70771ca235f36f..d5d14d8b4cb683 100644 --- a/deps/npm/node_modules/agentkeepalive/History.md +++ b/deps/npm/node_modules/agentkeepalive/History.md @@ -143,22 +143,22 @@ * update _http_agent, only support 0.11+, only support node 0.11.0+ -0.2.2 / 2013-11-19 +0.2.2 / 2013-11-19 ================== * support node 0.8 and node 0.10 -0.2.1 / 2013-11-08 +0.2.1 / 2013-11-08 ================== * fix socket does not timeout bug, it will hang on life, must use 0.2.x on node 0.11 -0.2.0 / 2013-11-06 +0.2.0 / 2013-11-06 ================== * use keepalive agent on node 0.11+ impl -0.1.5 / 2013-06-24 +0.1.5 / 2013-06-24 ================== * support coveralls diff --git a/deps/npm/node_modules/ajv/LICENSE b/deps/npm/node_modules/ajv/LICENSE index 09f090263b226a..810539685b8aec 100644 --- a/deps/npm/node_modules/ajv/LICENSE +++ b/deps/npm/node_modules/ajv/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/ajv/README.md b/deps/npm/node_modules/ajv/README.md index 63a265f04d9e84..387c81d8ca6750 100644 --- a/deps/npm/node_modules/ajv/README.md +++ b/deps/npm/node_modules/ajv/README.md @@ -937,7 +937,7 @@ This allows you to do nice things like the following. ```javascript var validate = new Ajv().addSchema(schema).addFormat(name, regex).getSchema(uri); -``` +``` ##### .addMetaSchema(Array<Object>|Object schema [, String key]) -> Ajv diff --git a/deps/npm/node_modules/ajv/dist/ajv.bundle.js b/deps/npm/node_modules/ajv/dist/ajv.bundle.js index 25843d30c8535d..01d56327e693b3 100644 --- a/deps/npm/node_modules/ajv/dist/ajv.bundle.js +++ b/deps/npm/node_modules/ajv/dist/ajv.bundle.js @@ -4777,7 +4777,7 @@ module.exports={ "$data": { "type": "string", "anyOf": [ - { "format": "relative-json-pointer" }, + { "format": "relative-json-pointer" }, { "format": "json-pointer" } ] } diff --git a/deps/npm/node_modules/ajv/lib/ajv.d.ts b/deps/npm/node_modules/ajv/lib/ajv.d.ts index 9d0cb3cf317d94..b815fda5a0ebf0 100644 --- a/deps/npm/node_modules/ajv/lib/ajv.d.ts +++ b/deps/npm/node_modules/ajv/lib/ajv.d.ts @@ -1,4 +1,4 @@ -declare var ajv: { +declare var ajv: { (options?: ajv.Options): ajv.Ajv; new (options?: ajv.Options): ajv.Ajv; ValidationError: ValidationError; diff --git a/deps/npm/node_modules/ajv/lib/dot/dependencies.jst b/deps/npm/node_modules/ajv/lib/dot/dependencies.jst index 1e8c18ce967abe..c41f334224ee84 100644 --- a/deps/npm/node_modules/ajv/lib/dot/dependencies.jst +++ b/deps/npm/node_modules/ajv/lib/dot/dependencies.jst @@ -59,7 +59,7 @@ var missing{{=$lvl}}; {{=$nextValid}} = true; if ({{# def.propertyInData }}) { - {{ + {{ $it.schema = $sch; $it.schemaPath = $schemaPath + it.util.getProperty($property); $it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($property); @@ -72,7 +72,7 @@ var missing{{=$lvl}}; {{?}} {{ } }} -{{? $breakOnError }} +{{? $breakOnError }} {{= $closingBraces }} if ({{=$errs}} == errors) { {{?}} diff --git a/deps/npm/node_modules/ajv/lib/dot/items.jst b/deps/npm/node_modules/ajv/lib/dot/items.jst index fe1be473d46d80..8c0f5acb5dfdf2 100644 --- a/deps/npm/node_modules/ajv/lib/dot/items.jst +++ b/deps/npm/node_modules/ajv/lib/dot/items.jst @@ -38,7 +38,7 @@ var {{=$valid}}; {{=$valid}} = {{=$data}}.length <= {{= $schema.length }}; {{ var $currErrSchemaPath = $errSchemaPath; - $errSchemaPath = it.errSchemaPath + '/additionalItems'; + $errSchemaPath = it.errSchemaPath + '/additionalItems'; }} {{# def.checkError:'additionalItems' }} {{ $errSchemaPath = $currErrSchemaPath; }} diff --git a/deps/npm/node_modules/ajv/lib/refs/$data.json b/deps/npm/node_modules/ajv/lib/refs/$data.json index 9ab8f41c2f1b3a..4a2edec5567612 100644 --- a/deps/npm/node_modules/ajv/lib/refs/$data.json +++ b/deps/npm/node_modules/ajv/lib/refs/$data.json @@ -8,7 +8,7 @@ "$data": { "type": "string", "anyOf": [ - { "format": "relative-json-pointer" }, + { "format": "relative-json-pointer" }, { "format": "json-pointer" } ] } diff --git a/deps/npm/node_modules/ajv/lib/refs/json-schema-v5.json b/deps/npm/node_modules/ajv/lib/refs/json-schema-v5.json index 21aee97ed2c14f..cc679a459d462f 100644 --- a/deps/npm/node_modules/ajv/lib/refs/json-schema-v5.json +++ b/deps/npm/node_modules/ajv/lib/refs/json-schema-v5.json @@ -31,7 +31,7 @@ "$data": { "type": "string", "anyOf": [ - { "format": "relative-json-pointer" }, + { "format": "relative-json-pointer" }, { "format": "json-pointer" } ] } diff --git a/deps/npm/node_modules/are-we-there-yet/README.md b/deps/npm/node_modules/are-we-there-yet/README.md index a927eae6be3d02..7e2b42d866bd54 100644 --- a/deps/npm/node_modules/are-we-there-yet/README.md +++ b/deps/npm/node_modules/are-we-there-yet/README.md @@ -25,7 +25,7 @@ single.completeWork(20) console.log(top.completed()) // 0.2 fs.stat("file", function(er, stat) { - if (er) throw er + if (er) throw er var stream = top.newStream("file", stat.size) console.log(top.completed()) // now 0.1 as single is 50% of the job and is 20% complete // and 50% * 20% == 10% diff --git a/deps/npm/node_modules/are-we-there-yet/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/are-we-there-yet/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/are-we-there-yet/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/are-we-there-yet/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/are-we-there-yet/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/are-we-there-yet/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/are-we-there-yet/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/are-we-there-yet/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/asap/CHANGES.md b/deps/npm/node_modules/asap/CHANGES.md index ad50f0d8f1dff2..f105b91956d156 100644 --- a/deps/npm/node_modules/asap/CHANGES.md +++ b/deps/npm/node_modules/asap/CHANGES.md @@ -67,3 +67,4 @@ Integration][]. ![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) [Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md + diff --git a/deps/npm/node_modules/asap/LICENSE.md b/deps/npm/node_modules/asap/LICENSE.md index 0d82d695f7a242..ba18c61390db9a 100644 --- a/deps/npm/node_modules/asap/LICENSE.md +++ b/deps/npm/node_modules/asap/LICENSE.md @@ -18,3 +18,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/asap/README.md b/deps/npm/node_modules/asap/README.md index d60a08a044d9c2..452fd8c2037099 100644 --- a/deps/npm/node_modules/asap/README.md +++ b/deps/npm/node_modules/asap/README.md @@ -234,3 +234,4 @@ browser-only implementation. Copyright 2009-2014 by Contributors MIT License (enclosed) + diff --git a/deps/npm/node_modules/asap/asap.js b/deps/npm/node_modules/asap/asap.js index 3a27c8cee7a597..f04fcd58fc0b22 100644 --- a/deps/npm/node_modules/asap/asap.js +++ b/deps/npm/node_modules/asap/asap.js @@ -62,3 +62,4 @@ RawTask.prototype.call = function () { freeTasks.push(this); } }; + diff --git a/deps/npm/node_modules/asynckit/stream.js b/deps/npm/node_modules/asynckit/stream.js index 7b77116ebab733..d43465f903ed63 100644 --- a/deps/npm/node_modules/asynckit/stream.js +++ b/deps/npm/node_modules/asynckit/stream.js @@ -11,7 +11,7 @@ module.exports = { parallel : ReadableParallel, serial : ReadableSerial, - serialOrdered : ReadableSerialOrdered, + serialOrdered : ReadableSerialOrdered, }; inherits(ReadableAsyncKit, Readable); diff --git a/deps/npm/node_modules/aws-sign2/index.js b/deps/npm/node_modules/aws-sign2/index.js index 5efa65523dc3ed..fb35f6db01f6f6 100644 --- a/deps/npm/node_modules/aws-sign2/index.js +++ b/deps/npm/node_modules/aws-sign2/index.js @@ -27,7 +27,7 @@ var crypto = require('crypto') * Valid keys. */ -var keys = +var keys = [ 'acl' , 'location' , 'logging' @@ -66,7 +66,7 @@ module.exports.authorization = authorization * @param {Object} options * @return {String} * @api private - */ + */ function hmacSha1 (options) { return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64') @@ -75,8 +75,8 @@ function hmacSha1 (options) { module.exports.hmacSha1 = hmacSha1 /** - * Create a base64 sha1 HMAC for `options`. - * + * Create a base64 sha1 HMAC for `options`. + * * @param {Object} options * @return {String} * @api private @@ -89,10 +89,10 @@ function sign (options) { module.exports.sign = sign /** - * Create a base64 sha1 HMAC for `options`. + * Create a base64 sha1 HMAC for `options`. * * Specifically to be used with S3 presigned URLs - * + * * @param {Object} options * @return {String} * @api private @@ -108,7 +108,7 @@ module.exports.signQuery= signQuery * Return a string for sign() with the given `options`. * * Spec: - * + * * \n * \n * \n @@ -124,7 +124,7 @@ module.exports.signQuery= signQuery function stringToSign (options) { var headers = options.amazonHeaders || '' if (headers) headers += '\n' - var r = + var r = [ options.verb , options.md5 , options.contentType @@ -140,7 +140,7 @@ module.exports.stringToSign = stringToSign * for S3 presigned URLs * * Spec: - * + * * \n * * diff --git a/deps/npm/node_modules/aws4/README.md b/deps/npm/node_modules/aws4/README.md index cb1b1bf1ef5cd2..6b002d02f752a6 100644 --- a/deps/npm/node_modules/aws4/README.md +++ b/deps/npm/node_modules/aws4/README.md @@ -520,3 +520,4 @@ committed and subsequently extracted this code. Also thanks to the [official node.js AWS SDK](https://github.com/aws/aws-sdk-js) for giving me a start on implementing the v4 signature. + diff --git a/deps/npm/node_modules/bluebird/README.md b/deps/npm/node_modules/bluebird/README.md index 7800eb6f9114f0..0eb5b74aa14a8e 100644 --- a/deps/npm/node_modules/bluebird/README.md +++ b/deps/npm/node_modules/bluebird/README.md @@ -17,7 +17,7 @@ See the [**bluebird website**](http://bluebirdjs.com/docs/getting-started.html) For bluebird 2.x documentation and files, see the [2.x tree](https://github.com/petkaantonov/bluebird/tree/2.x). -### Note +### Note Promises in Node.js 10 are significantly faster than before. Bluebird still includes a lot of features like cancellation, iteration methods and warnings that native promises don't. If you are using Bluebird for performance rather than for those - please consider giving native promises a shot and running the benchmarks yourself. @@ -29,7 +29,7 @@ The [github issue tracker](https://github.com/petkaantonov/bluebird/issues) is * ## Thanks -Thanks to BrowserStack for providing us with a free account which lets us support old browsers like IE8. +Thanks to BrowserStack for providing us with a free account which lets us support old browsers like IE8. # License @@ -54,3 +54,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/bluebird/js/browser/bluebird.core.js b/deps/npm/node_modules/bluebird/js/browser/bluebird.core.js index 0121a4bea78e10..bae7583d6fe07a 100644 --- a/deps/npm/node_modules/bluebird/js/browser/bluebird.core.js +++ b/deps/npm/node_modules/bluebird/js/browser/bluebird.core.js @@ -1,18 +1,18 @@ /* @preserve * The MIT License (MIT) - * + * * Copyright (c) 2013-2018 Petka Antonov - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,7 +20,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * + * */ /** * bluebird build version 3.5.5 @@ -2885,28 +2885,28 @@ _dereq_("./join")( Promise, PromiseArray, tryConvertToPromise, INTERNAL, async, getDomain); Promise.Promise = Promise; Promise.version = "3.5.5"; - - util.toFastProperties(Promise); - util.toFastProperties(Promise.prototype); - function fillTypes(value) { - var p = new Promise(INTERNAL); - p._fulfillmentHandler0 = value; - p._rejectionHandler0 = value; - p._promise0 = value; - p._receiver0 = value; - } - // Complete slack tracking, opt out of field-type tracking and - // stabilize map - fillTypes({a: 1}); - fillTypes({b: 2}); - fillTypes({c: 3}); - fillTypes(1); - fillTypes(function(){}); - fillTypes(undefined); - fillTypes(false); - fillTypes(new Promise(INTERNAL)); - debug.setBounds(Async.firstLineError, util.lastLineError); - return Promise; + + util.toFastProperties(Promise); + util.toFastProperties(Promise.prototype); + function fillTypes(value) { + var p = new Promise(INTERNAL); + p._fulfillmentHandler0 = value; + p._rejectionHandler0 = value; + p._promise0 = value; + p._receiver0 = value; + } + // Complete slack tracking, opt out of field-type tracking and + // stabilize map + fillTypes({a: 1}); + fillTypes({b: 2}); + fillTypes({c: 3}); + fillTypes(1); + fillTypes(function(){}); + fillTypes(undefined); + fillTypes(false); + fillTypes(new Promise(INTERNAL)); + debug.setBounds(Async.firstLineError, util.lastLineError); + return Promise; }; @@ -3807,7 +3807,7 @@ var ret = { }; ret.isRecentNode = ret.isNode && (function() { var version; - if (process.versions && process.versions.node) { + if (process.versions && process.versions.node) { version = process.versions.node.split(".").map(Number); } else if (process.version) { version = process.version.split(".").map(Number); diff --git a/deps/npm/node_modules/bluebird/js/browser/bluebird.core.min.js b/deps/npm/node_modules/bluebird/js/browser/bluebird.core.min.js index 5092a51e54338c..7091d9fac0ad23 100644 --- a/deps/npm/node_modules/bluebird/js/browser/bluebird.core.min.js +++ b/deps/npm/node_modules/bluebird/js/browser/bluebird.core.min.js @@ -1,18 +1,18 @@ /* @preserve * The MIT License (MIT) - * + * * Copyright (c) 2013-2018 Petka Antonov - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,7 +20,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * + * */ /** * bluebird build version 3.5.5 diff --git a/deps/npm/node_modules/bluebird/js/browser/bluebird.js b/deps/npm/node_modules/bluebird/js/browser/bluebird.js index 89273d90f29994..35d0912b0b4ebc 100644 --- a/deps/npm/node_modules/bluebird/js/browser/bluebird.js +++ b/deps/npm/node_modules/bluebird/js/browser/bluebird.js @@ -1,18 +1,18 @@ /* @preserve * The MIT License (MIT) - * + * * Copyright (c) 2013-2018 Petka Antonov - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,7 +20,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * + * */ /** * bluebird build version 3.5.5 @@ -3548,28 +3548,28 @@ _dereq_('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, _dereq_('./any.js')(Promise); _dereq_('./each.js')(Promise, INTERNAL); _dereq_('./filter.js')(Promise, INTERNAL); - - util.toFastProperties(Promise); - util.toFastProperties(Promise.prototype); - function fillTypes(value) { - var p = new Promise(INTERNAL); - p._fulfillmentHandler0 = value; - p._rejectionHandler0 = value; - p._promise0 = value; - p._receiver0 = value; - } - // Complete slack tracking, opt out of field-type tracking and - // stabilize map - fillTypes({a: 1}); - fillTypes({b: 2}); - fillTypes({c: 3}); - fillTypes(1); - fillTypes(function(){}); - fillTypes(undefined); - fillTypes(false); - fillTypes(new Promise(INTERNAL)); - debug.setBounds(Async.firstLineError, util.lastLineError); - return Promise; + + util.toFastProperties(Promise); + util.toFastProperties(Promise.prototype); + function fillTypes(value) { + var p = new Promise(INTERNAL); + p._fulfillmentHandler0 = value; + p._rejectionHandler0 = value; + p._promise0 = value; + p._receiver0 = value; + } + // Complete slack tracking, opt out of field-type tracking and + // stabilize map + fillTypes({a: 1}); + fillTypes({b: 2}); + fillTypes({c: 3}); + fillTypes(1); + fillTypes(function(){}); + fillTypes(undefined); + fillTypes(false); + fillTypes(new Promise(INTERNAL)); + debug.setBounds(Async.firstLineError, util.lastLineError); + return Promise; }; @@ -4357,8 +4357,8 @@ function ReductionPromiseArray(promises, fn, initialValue, _each) { util.inherits(ReductionPromiseArray, PromiseArray); ReductionPromiseArray.prototype._gotAccum = function(accum) { - if (this._eachValues !== undefined && - this._eachValues !== null && + if (this._eachValues !== undefined && + this._eachValues !== null && accum !== INTERNAL) { this._eachValues.push(accum); } @@ -5649,7 +5649,7 @@ var ret = { }; ret.isRecentNode = ret.isNode && (function() { var version; - if (process.versions && process.versions.node) { + if (process.versions && process.versions.node) { version = process.versions.node.split(".").map(Number); } else if (process.version) { version = process.version.split(".").map(Number); diff --git a/deps/npm/node_modules/bluebird/js/browser/bluebird.min.js b/deps/npm/node_modules/bluebird/js/browser/bluebird.min.js index 9bbd1726baa27b..ef4fb4ae88e461 100644 --- a/deps/npm/node_modules/bluebird/js/browser/bluebird.min.js +++ b/deps/npm/node_modules/bluebird/js/browser/bluebird.min.js @@ -1,18 +1,18 @@ /* @preserve * The MIT License (MIT) - * + * * Copyright (c) 2013-2018 Petka Antonov - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,7 +20,7 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. - * + * */ /** * bluebird build version 3.5.5 diff --git a/deps/npm/node_modules/bluebird/js/release/each.js b/deps/npm/node_modules/bluebird/js/release/each.js index e34b6b9c16fdb7..e4f3d05ba3477b 100644 --- a/deps/npm/node_modules/bluebird/js/release/each.js +++ b/deps/npm/node_modules/bluebird/js/release/each.js @@ -27,3 +27,4 @@ Promise.each = function (promises, fn) { Promise.mapSeries = PromiseMapSeries; }; + diff --git a/deps/npm/node_modules/bluebird/js/release/promise.js b/deps/npm/node_modules/bluebird/js/release/promise.js index 98061406b0f8b9..d80b44da438138 100644 --- a/deps/npm/node_modules/bluebird/js/release/promise.js +++ b/deps/npm/node_modules/bluebird/js/release/promise.js @@ -763,27 +763,27 @@ require('./using.js')(Promise, apiRejection, tryConvertToPromise, createContext, require('./any.js')(Promise); require('./each.js')(Promise, INTERNAL); require('./filter.js')(Promise, INTERNAL); - - util.toFastProperties(Promise); - util.toFastProperties(Promise.prototype); - function fillTypes(value) { - var p = new Promise(INTERNAL); - p._fulfillmentHandler0 = value; - p._rejectionHandler0 = value; - p._promise0 = value; - p._receiver0 = value; - } - // Complete slack tracking, opt out of field-type tracking and - // stabilize map - fillTypes({a: 1}); - fillTypes({b: 2}); - fillTypes({c: 3}); - fillTypes(1); - fillTypes(function(){}); - fillTypes(undefined); - fillTypes(false); - fillTypes(new Promise(INTERNAL)); - debug.setBounds(Async.firstLineError, util.lastLineError); - return Promise; + + util.toFastProperties(Promise); + util.toFastProperties(Promise.prototype); + function fillTypes(value) { + var p = new Promise(INTERNAL); + p._fulfillmentHandler0 = value; + p._rejectionHandler0 = value; + p._promise0 = value; + p._receiver0 = value; + } + // Complete slack tracking, opt out of field-type tracking and + // stabilize map + fillTypes({a: 1}); + fillTypes({b: 2}); + fillTypes({c: 3}); + fillTypes(1); + fillTypes(function(){}); + fillTypes(undefined); + fillTypes(false); + fillTypes(new Promise(INTERNAL)); + debug.setBounds(Async.firstLineError, util.lastLineError); + return Promise; }; diff --git a/deps/npm/node_modules/bluebird/js/release/promisify.js b/deps/npm/node_modules/bluebird/js/release/promisify.js index f7d14275b07c16..aa98e5bde1ca97 100644 --- a/deps/npm/node_modules/bluebird/js/release/promisify.js +++ b/deps/npm/node_modules/bluebird/js/release/promisify.js @@ -311,3 +311,4 @@ Promise.promisifyAll = function (target, options) { return promisifyAll(target, suffix, filter, promisifier, multiArgs); }; }; + diff --git a/deps/npm/node_modules/bluebird/js/release/reduce.js b/deps/npm/node_modules/bluebird/js/release/reduce.js index e8b7843e558da9..26e2b1a9706184 100644 --- a/deps/npm/node_modules/bluebird/js/release/reduce.js +++ b/deps/npm/node_modules/bluebird/js/release/reduce.js @@ -32,8 +32,8 @@ function ReductionPromiseArray(promises, fn, initialValue, _each) { util.inherits(ReductionPromiseArray, PromiseArray); ReductionPromiseArray.prototype._gotAccum = function(accum) { - if (this._eachValues !== undefined && - this._eachValues !== null && + if (this._eachValues !== undefined && + this._eachValues !== null && accum !== INTERNAL) { this._eachValues.push(accum); } diff --git a/deps/npm/node_modules/bluebird/js/release/util.js b/deps/npm/node_modules/bluebird/js/release/util.js index 7ea96834fe8417..74a24fa6c393d9 100644 --- a/deps/npm/node_modules/bluebird/js/release/util.js +++ b/deps/npm/node_modules/bluebird/js/release/util.js @@ -375,7 +375,7 @@ var ret = { }; ret.isRecentNode = ret.isNode && (function() { var version; - if (process.versions && process.versions.node) { + if (process.versions && process.versions.node) { version = process.versions.node.split(".").map(Number); } else if (process.version) { version = process.version.split(".").map(Number); diff --git a/deps/npm/node_modules/brace-expansion/README.md b/deps/npm/node_modules/brace-expansion/README.md index bbfd3fcb88c8e4..6b4e0e16409152 100644 --- a/deps/npm/node_modules/brace-expansion/README.md +++ b/deps/npm/node_modules/brace-expansion/README.md @@ -1,6 +1,6 @@ # brace-expansion -[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), +[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), as known from sh/bash, in JavaScript. [![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion) diff --git a/deps/npm/node_modules/brace-expansion/index.js b/deps/npm/node_modules/brace-expansion/index.js index 2b6f4f85c951fc..0478be81eabc2b 100644 --- a/deps/npm/node_modules/brace-expansion/index.js +++ b/deps/npm/node_modules/brace-expansion/index.js @@ -198,3 +198,4 @@ function expand(str, isTop) { return expansions; } + diff --git a/deps/npm/node_modules/builtins/History.md b/deps/npm/node_modules/builtins/History.md index e9837a5068ae0e..0eb45c420775eb 100644 --- a/deps/npm/node_modules/builtins/History.md +++ b/deps/npm/node_modules/builtins/History.md @@ -1,10 +1,10 @@ -0.0.7 / 2014-09-01 +0.0.7 / 2014-09-01 ================== * update .repository -0.0.6 / 2014-09-01 +0.0.6 / 2014-09-01 ================== * add travis @@ -22,17 +22,17 @@ * add timers -0.0.3 / 2014-02-22 +0.0.3 / 2014-02-22 ================== * add buffer -0.0.2 / 2014-02-11 +0.0.2 / 2014-02-11 ================== * add assert -0.0.1 / 2014-02-11 +0.0.1 / 2014-02-11 ================== * add main diff --git a/deps/npm/node_modules/byline/README.md b/deps/npm/node_modules/byline/README.md index f5a06440955588..2de1a849e6626a 100644 --- a/deps/npm/node_modules/byline/README.md +++ b/deps/npm/node_modules/byline/README.md @@ -42,11 +42,11 @@ stream.on('data', function(line) { ``` # Standard API - + You just need to add one line to wrap your readable `Stream` with a `LineStream`. ```javascript -var fs = require('fs'), +var fs = require('fs'), byline = require('byline'); var stream = fs.createReadStream('sample.txt'); @@ -74,7 +74,7 @@ stream: var stream = fs.createReadStream('sample.txt'); stream = byline.createStream(stream); stream.pipe(fs.createWriteStream('nolines.txt')); - + var input = fs.createReadStream('LICENSE'); var lineStream = byline.createStream(); input.pipe(lineStream); @@ -84,7 +84,7 @@ lineStream.pipe(output); ``` # Streams2 API - + Node v0.10 added a new streams2 API. This allows the stream to be used in non-flowing mode and is preferred over the legacy pause() and resume() methods. diff --git a/deps/npm/node_modules/byline/lib/byline.js b/deps/npm/node_modules/byline/lib/byline.js index 7612632048fb78..21843cb2aa5635 100644 --- a/deps/npm/node_modules/byline/lib/byline.js +++ b/deps/npm/node_modules/byline/lib/byline.js @@ -6,10 +6,10 @@ // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -87,7 +87,7 @@ util.inherits(LineStream, stream.Transform); LineStream.prototype._transform = function(chunk, encoding, done) { // decode binary chunks as UTF-8 encoding = encoding || 'utf8'; - + if (Buffer.isBuffer(chunk)) { if (encoding == 'buffer') { chunk = chunk.toString(); // utf8 @@ -98,15 +98,15 @@ LineStream.prototype._transform = function(chunk, encoding, done) { } } this._chunkEncoding = encoding; - + // see: http://www.unicode.org/reports/tr18/#Line_Boundaries var lines = chunk.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); - + // don't split CRLF which spans chunks if (this._lastChunkEndedWithCR && chunk[0] == '\n') { lines.shift(); } - + if (this._lineBuffer.length > 0) { this._lineBuffer[this._lineBuffer.length - 1] += lines[0]; lines.shift(); diff --git a/deps/npm/node_modules/byte-size/README.md b/deps/npm/node_modules/byte-size/README.md index 4d383ad76b6a5a..9a36daaf52f481 100644 --- a/deps/npm/node_modules/byte-size/README.md +++ b/deps/npm/node_modules/byte-size/README.md @@ -54,14 +54,14 @@ Value | IEC (octet) 1024^7 | Zio zebioctet 1024^8 | Yio yobioctet -**Example** +**Example** ```js const byteSize = require('byte-size') ``` ### byteSize(bytes, [options]) ⇒ Object ⏏ -**Kind**: Exported function +**Kind**: Exported function | Param | Type | Default | Description | | --- | --- | --- | --- | @@ -70,7 +70,7 @@ const byteSize = require('byte-size') | [options.precision] | number | 1 | number of decimal places. | | [options.units] | string | "metric" | select `'metric'`, `'iec'`, `'metric_octet'` or `'iec_octet'` units. | -**Example** +**Example** ```js > const byteSize = require('byte-size') diff --git a/deps/npm/node_modules/call-limit/README.md b/deps/npm/node_modules/call-limit/README.md index 5b5c7264e46f23..62086b68496f30 100644 --- a/deps/npm/node_modules/call-limit/README.md +++ b/deps/npm/node_modules/call-limit/README.md @@ -27,7 +27,7 @@ const limit = require('call-limit') ### limit(func, maxRunning) → limitedFunc -The returned function will execute up to maxRunning calls of `func` at once. +The returned function will execute up to maxRunning calls of `func` at once. Beyond that they get queued and called when the previous call completes. `func` must accept a callback as the final argument and must call it when diff --git a/deps/npm/node_modules/capture-stack-trace/readme.md b/deps/npm/node_modules/capture-stack-trace/readme.md index 061c463c4293aa..a944ab961b588f 100644 --- a/deps/npm/node_modules/capture-stack-trace/readme.md +++ b/deps/npm/node_modules/capture-stack-trace/readme.md @@ -26,7 +26,7 @@ captureStackTrace({}); #### error -*Required* +*Required* Type: `Object` Target Object, that will recieve stack property. diff --git a/deps/npm/node_modules/cli-table3/README.md b/deps/npm/node_modules/cli-table3/README.md index 22e4a75e9c3aa1..693b5448217289 100644 --- a/deps/npm/node_modules/cli-table3/README.md +++ b/deps/npm/node_modules/cli-table3/README.md @@ -1,4 +1,4 @@ -cli-table3 +cli-table3 =============================================================================== [![npm version](https://img.shields.io/npm/v/cli-table3.svg)](https://www.npmjs.com/package/cli-table3) diff --git a/deps/npm/node_modules/cmd-shim/lib/to-batch-syntax.js b/deps/npm/node_modules/cmd-shim/lib/to-batch-syntax.js index 59d242c071efe9..734be551d25686 100644 --- a/deps/npm/node_modules/cmd-shim/lib/to-batch-syntax.js +++ b/deps/npm/node_modules/cmd-shim/lib/to-batch-syntax.js @@ -47,3 +47,5 @@ function replaceDollarWithPercentPair(value) { result += value.substr(startIndex) return result } + + diff --git a/deps/npm/node_modules/color-convert/LICENSE b/deps/npm/node_modules/color-convert/LICENSE index 0e2e4909183090..5b4c386f9269b3 100644 --- a/deps/npm/node_modules/color-convert/LICENSE +++ b/deps/npm/node_modules/color-convert/LICENSE @@ -18,3 +18,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/color-convert/route.js b/deps/npm/node_modules/color-convert/route.js index c573930d5b31e2..0a1fdea689e2a7 100644 --- a/deps/npm/node_modules/color-convert/route.js +++ b/deps/npm/node_modules/color-convert/route.js @@ -94,3 +94,4 @@ module.exports = function (fromModel) { return conversion; }; + diff --git a/deps/npm/node_modules/colors/README.md b/deps/npm/node_modules/colors/README.md index c0550bdd522ec4..4bebb6c92b0734 100644 --- a/deps/npm/node_modules/colors/README.md +++ b/deps/npm/node_modules/colors/README.md @@ -90,7 +90,7 @@ console.log(colors.trap('Run the trap')); // Drops the bass ``` -I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. +I prefer the first way. Some people seem to be afraid of extending `String.prototype` and prefer the second way. If you are writing good code you will never have an issue with the first approach. If you really don't want to touch `String.prototype`, the second usage will not touch `String` native object. diff --git a/deps/npm/node_modules/colors/examples/safe-string.js b/deps/npm/node_modules/colors/examples/safe-string.js index bd22f2ff4ffc3b..98994873520ff5 100644 --- a/deps/npm/node_modules/colors/examples/safe-string.js +++ b/deps/npm/node_modules/colors/examples/safe-string.js @@ -73,3 +73,5 @@ console.log(colors.warn('this is a warning')); console.log(colors.input('this is an input')); // console.log(colors.zalgo("Don't summon him")) + + diff --git a/deps/npm/node_modules/colors/lib/custom/zalgo.js b/deps/npm/node_modules/colors/lib/custom/zalgo.js index 01bdd2b802f626..0ef2b011956358 100644 --- a/deps/npm/node_modules/colors/lib/custom/zalgo.js +++ b/deps/npm/node_modules/colors/lib/custom/zalgo.js @@ -107,3 +107,4 @@ module['exports'] = function zalgo(text, options) { // don't summon him return heComes(text, options); }; + diff --git a/deps/npm/node_modules/colors/lib/maps/rainbow.js b/deps/npm/node_modules/colors/lib/maps/rainbow.js index 874508da8ed17e..2b00ac0ac998e6 100644 --- a/deps/npm/node_modules/colors/lib/maps/rainbow.js +++ b/deps/npm/node_modules/colors/lib/maps/rainbow.js @@ -9,3 +9,4 @@ module['exports'] = function(colors) { } }; }; + diff --git a/deps/npm/node_modules/concat-stream/LICENSE b/deps/npm/node_modules/concat-stream/LICENSE index 1e836b4760025f..99c130e1de3427 100644 --- a/deps/npm/node_modules/concat-stream/LICENSE +++ b/deps/npm/node_modules/concat-stream/LICENSE @@ -2,23 +2,23 @@ The MIT License Copyright (c) 2013 Max Ogden -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/deps/npm/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/concat-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/concat-stream/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/concat-stream/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/concat-stream/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/concat-stream/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/concat-stream/readme.md b/deps/npm/node_modules/concat-stream/readme.md index d442f840cb42f6..7aa19c4fb104c3 100644 --- a/deps/npm/node_modules/concat-stream/readme.md +++ b/deps/npm/node_modules/concat-stream/readme.md @@ -77,7 +77,7 @@ var concat = require('concat-stream') Return a `writable` stream that will fire `cb(data)` with all of the data that was written to the stream. Data can be written to `writable` as strings, -Buffers, arrays of byte integers, and Uint8Arrays. +Buffers, arrays of byte integers, and Uint8Arrays. By default `concat-stream` will give you back the same data type as the type of the first buffer written to the stream. Use `opts.encoding` to set what format `data` should be returned as, e.g. if you if you don't want to rely on the built-in type checking or for some other reason. diff --git a/deps/npm/node_modules/config-chain/readme.markdown b/deps/npm/node_modules/config-chain/readme.markdown index 12dfbca3340e62..47f894c79884fc 100644 --- a/deps/npm/node_modules/config-chain/readme.markdown +++ b/deps/npm/node_modules/config-chain/readme.markdown @@ -14,7 +14,7 @@ but as [npm](https://github.com/npmjs/npm) depends on this, it cannot be changed ## Install -```sh +```sh yarn add config-chain # npm users diff --git a/deps/npm/node_modules/console-control-strings/README.md b/deps/npm/node_modules/console-control-strings/README.md index 59cbd5639de446..f58cc8d8925060 100644 --- a/deps/npm/node_modules/console-control-strings/README.md +++ b/deps/npm/node_modules/console-control-strings/README.md @@ -63,7 +63,7 @@ Returns the escape sequence to erase to the end of the current line. ### var code = consoleControl.goto(_x_, _y_) -Returns the escape sequence to move the cursor to the designated position. +Returns the escape sequence to move the cursor to the designated position. Note that the origin is _1, 1_ not _0, 0_. ### var code = consoleControl.gotoSOL() @@ -142,3 +142,4 @@ will have its own distinct escape sequence. Each attribute can be one of: * **bgBrightMagenta** * **bgBrightCyan** * **bgBrightWhite** + diff --git a/deps/npm/node_modules/copy-concurrently/LICENSE b/deps/npm/node_modules/copy-concurrently/LICENSE index e0040f6659d374..83e7c4c62903d7 100644 --- a/deps/npm/node_modules/copy-concurrently/LICENSE +++ b/deps/npm/node_modules/copy-concurrently/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/copy-concurrently/README.md b/deps/npm/node_modules/copy-concurrently/README.md index e27b016d72dc11..3f6f97426a8a4b 100644 --- a/deps/npm/node_modules/copy-concurrently/README.md +++ b/deps/npm/node_modules/copy-concurrently/README.md @@ -19,7 +19,7 @@ are unavailable then junctions will be used. ### copy(from, to, [options]) → Promise -Recursively copies `from` to `to` and resolves its promise when finished. +Recursively copies `from` to `to` and resolves its promise when finished. If `to` already exists then the promise will be rejected with an `EEXIST` error. diff --git a/deps/npm/node_modules/copy-concurrently/node_modules/aproba/LICENSE b/deps/npm/node_modules/copy-concurrently/node_modules/aproba/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/copy-concurrently/node_modules/aproba/LICENSE +++ b/deps/npm/node_modules/copy-concurrently/node_modules/aproba/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/copy-concurrently/node_modules/aproba/README.md b/deps/npm/node_modules/copy-concurrently/node_modules/aproba/README.md index e94799201ce046..0bfc594c56a372 100644 --- a/deps/npm/node_modules/copy-concurrently/node_modules/aproba/README.md +++ b/deps/npm/node_modules/copy-concurrently/node_modules/aproba/README.md @@ -84,10 +84,11 @@ I wanted a very simple argument validator. It needed to do two things: 2. Not encourage an infinite bikeshed of DSLs This is why types are specified by a single character and there's no such -thing as an optional argument. +thing as an optional argument. This is not intended to validate user data. This is specifically about asserting the interface of your functions. If you need greater validation, I encourage you to write them by hand or look elsewhere. + diff --git a/deps/npm/node_modules/create-error-class/readme.md b/deps/npm/node_modules/create-error-class/readme.md index 1076de88ebc371..d993cea37a495f 100644 --- a/deps/npm/node_modules/create-error-class/readme.md +++ b/deps/npm/node_modules/create-error-class/readme.md @@ -31,7 +31,7 @@ Return constructor of Errors with `className`. #### className -*Required* +*Required* Type: `string` Class name of Error Object. Should contain characters from `[0-9a-zA-Z_$]` range. diff --git a/deps/npm/node_modules/dashdash/LICENSE.txt b/deps/npm/node_modules/dashdash/LICENSE.txt index b09f304539a854..54706c66e88e0e 100644 --- a/deps/npm/node_modules/dashdash/LICENSE.txt +++ b/deps/npm/node_modules/dashdash/LICENSE.txt @@ -21,3 +21,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/debug/CHANGELOG.md b/deps/npm/node_modules/debug/CHANGELOG.md index 609591bbbf4ca7..820d21e3322b9d 100644 --- a/deps/npm/node_modules/debug/CHANGELOG.md +++ b/deps/npm/node_modules/debug/CHANGELOG.md @@ -51,7 +51,7 @@ 2.6.5 / 2017-04-27 ================== - + * Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek) * Misc: clean up browser reference checks (#447, @thebigredgeek) * Misc: add npm-debug.log to .gitignore (@thebigredgeek) diff --git a/deps/npm/node_modules/debug/LICENSE b/deps/npm/node_modules/debug/LICENSE index 54a5d93f4d70b1..658c933d28255e 100644 --- a/deps/npm/node_modules/debug/LICENSE +++ b/deps/npm/node_modules/debug/LICENSE @@ -2,17 +2,18 @@ Copyright (c) 2014 TJ Holowaychuk -Permission is hereby granted, free of charge, to any person obtaining a copy of this software -and associated documentation files (the 'Software'), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +Permission is hereby granted, free of charge, to any person obtaining a copy of this software +and associated documentation files (the 'Software'), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/defaults/test.js b/deps/npm/node_modules/defaults/test.js index eab79ff71f1498..60e0ffba8b4aab 100644 --- a/deps/npm/node_modules/defaults/test.js +++ b/deps/npm/node_modules/defaults/test.js @@ -31,3 +31,4 @@ test("ensure defaults clone nested objects", function(t) { t.ok(result.b !== d.b, 'objects should be clones'); t.end(); }); + diff --git a/deps/npm/node_modules/define-properties/.editorconfig b/deps/npm/node_modules/define-properties/.editorconfig index 572e9793f03233..eaa214161f5cdb 100644 --- a/deps/npm/node_modules/define-properties/.editorconfig +++ b/deps/npm/node_modules/define-properties/.editorconfig @@ -10,3 +10,4 @@ spaces_around_operators = true; trim_trailing_whitespace = true; spaces_in_brackets = false; end_of_line = lf; + diff --git a/deps/npm/node_modules/define-properties/.jscs.json b/deps/npm/node_modules/define-properties/.jscs.json index 30d54076557d92..6f2d7f9ff9b1f1 100644 --- a/deps/npm/node_modules/define-properties/.jscs.json +++ b/deps/npm/node_modules/define-properties/.jscs.json @@ -172,3 +172,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/define-properties/README.md b/deps/npm/node_modules/define-properties/README.md index 9b60c5f5b7efc8..33b6111f161852 100644 --- a/deps/npm/node_modules/define-properties/README.md +++ b/deps/npm/node_modules/define-properties/README.md @@ -83,3 +83,4 @@ Simply clone the repo, `npm install`, and run `npm test` [license-url]: LICENSE [downloads-image]: http://img.shields.io/npm/dm/define-properties.svg [downloads-url]: http://npm-stat.com/charts.html?package=define-properties + diff --git a/deps/npm/node_modules/delayed-stream/Makefile b/deps/npm/node_modules/delayed-stream/Makefile index 2d7580746d0b84..b4ff85a33b6eb4 100644 --- a/deps/npm/node_modules/delayed-stream/Makefile +++ b/deps/npm/node_modules/delayed-stream/Makefile @@ -4,3 +4,4 @@ test: @./test/run.js .PHONY: test + diff --git a/deps/npm/node_modules/dotenv/CHANGELOG.md b/deps/npm/node_modules/dotenv/CHANGELOG.md index 1cfa04fa4ffdf4..e604a4749305d8 100644 --- a/deps/npm/node_modules/dotenv/CHANGELOG.md +++ b/deps/npm/node_modules/dotenv/CHANGELOG.md @@ -12,7 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Documentation on trim behavior of values - Documentation on how to use with `import` -### Changed +### Changed - *Breaking*: default `path` is now `path.resolve(process.cwd(), '.env')` - *Breaking*: does not write over keys already in `process.env` if the key has a falsy value diff --git a/deps/npm/node_modules/dotenv/README.md b/deps/npm/node_modules/dotenv/README.md index 4665fd39623118..f8df11026cdd57 100644 --- a/deps/npm/node_modules/dotenv/README.md +++ b/deps/npm/node_modules/dotenv/README.md @@ -67,7 +67,7 @@ _Alias: `load`_ `config` will read your .env file, parse the contents, assign it to [`process.env`](https://nodejs.org/docs/latest/api/process.html#process_process_env), -and return an Object with a `parsed` key containing the loaded content or an `error` key if it failed. +and return an Object with a `parsed` key containing the loaded content or an `error` key if it failed. ```js const result = dotenv.config() diff --git a/deps/npm/node_modules/duplexer3/LICENSE.md b/deps/npm/node_modules/duplexer3/LICENSE.md index 75a50f3014e28e..547189a6a369fc 100644 --- a/deps/npm/node_modules/duplexer3/LICENSE.md +++ b/deps/npm/node_modules/duplexer3/LICENSE.md @@ -2,18 +2,18 @@ Copyright (c) 2013, Deoxxa Development ====================================== All rights reserved. -------------------- - + Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. + notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. + documentation and/or other materials provided with the distribution. 3. Neither the name of Deoxxa Development nor the names of its contributors may be used to endorse or promote products derived from this software - without specific prior written permission. - + without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY DEOXXA DEVELOPMENT ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE diff --git a/deps/npm/node_modules/duplexify/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/duplexify/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/duplexify/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/duplexify/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/duplexify/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/duplexify/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/duplexify/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/duplexify/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/ecc-jsbn/index.js b/deps/npm/node_modules/ecc-jsbn/index.js index 2c2a55aef5d7a6..fb19a1d6fcbcaf 100755 --- a/deps/npm/node_modules/ecc-jsbn/index.js +++ b/deps/npm/node_modules/ecc-jsbn/index.js @@ -26,11 +26,11 @@ exports.ECKey = function(curve, key, isPublic) // var y = key.slice(bytes+1); // this.P = new ECPointFp(curve, // curve.fromBigInteger(new BigInteger(x.toString("hex"), 16)), -// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); +// curve.fromBigInteger(new BigInteger(y.toString("hex"), 16))); this.P = curve.decodePointHex(key.toString("hex")); }else{ if(key.length != bytes) return false; - priv = new BigInteger(key.toString("hex"), 16); + priv = new BigInteger(key.toString("hex"), 16); } }else{ var n1 = n.subtract(BigInteger.ONE); @@ -52,6 +52,7 @@ exports.ECKey = function(curve, key, isPublic) if(!key || !key.P) return false; var S = key.P.multiply(priv); return Buffer.from(unstupid(S.getX().toBigInteger().toString(16),bytes*2),"hex"); - } + } } } + diff --git a/deps/npm/node_modules/ecc-jsbn/lib/LICENSE-jsbn b/deps/npm/node_modules/ecc-jsbn/lib/LICENSE-jsbn index c769b38beabae1..24502a9cf74836 100755 --- a/deps/npm/node_modules/ecc-jsbn/lib/LICENSE-jsbn +++ b/deps/npm/node_modules/ecc-jsbn/lib/LICENSE-jsbn @@ -18,9 +18,9 @@ This software is covered under the following copyright: * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER diff --git a/deps/npm/node_modules/ecc-jsbn/lib/ec.js b/deps/npm/node_modules/ecc-jsbn/lib/ec.js index 38dc523caaf279..3852671eca2204 100755 --- a/deps/npm/node_modules/ecc-jsbn/lib/ec.js +++ b/deps/npm/node_modules/ecc-jsbn/lib/ec.js @@ -434,7 +434,7 @@ ECFieldElementFp.prototype.modReduce = function(x) { u = u.multiply(this.getR()); } - x = u.add(v); + x = u.add(v); } while (x.compareTo(q) >= 0) { @@ -454,8 +454,8 @@ ECFieldElementFp.prototype.sqrt = function() // p mod 4 == 3 if (this.q.testBit(1)) { - var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); - return z.square().equals(this) ? z : null; + var z = new ECFieldElementFp(this.q,this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE),this.q)); + return z.square().equals(this) ? z : null; } // p mod 4 == 1 diff --git a/deps/npm/node_modules/err-code/README.md b/deps/npm/node_modules/err-code/README.md index 19a390df08c2d9..e0234e90a3f816 100644 --- a/deps/npm/node_modules/err-code/README.md +++ b/deps/npm/node_modules/err-code/README.md @@ -17,7 +17,7 @@ Create new error instances with a code and additional properties. ## Installation -`$ npm install err-code` - `NPM` +`$ npm install err-code` - `NPM` `$ bower install err-code` - `bower` The browser file is named index.umd.js which supports CommonJS, AMD and globals (errCode). diff --git a/deps/npm/node_modules/es-abstract/.editorconfig b/deps/npm/node_modules/es-abstract/.editorconfig index 572e9793f03233..eaa214161f5cdb 100644 --- a/deps/npm/node_modules/es-abstract/.editorconfig +++ b/deps/npm/node_modules/es-abstract/.editorconfig @@ -10,3 +10,4 @@ spaces_around_operators = true; trim_trailing_whitespace = true; spaces_in_brackets = false; end_of_line = lf; + diff --git a/deps/npm/node_modules/es-abstract/.jscs.json b/deps/npm/node_modules/es-abstract/.jscs.json index a6ed539a81db81..857f88f1d5f8e1 100644 --- a/deps/npm/node_modules/es-abstract/.jscs.json +++ b/deps/npm/node_modules/es-abstract/.jscs.json @@ -171,3 +171,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/es-to-primitive/.jscs.json b/deps/npm/node_modules/es-to-primitive/.jscs.json index 32edc7054c7282..8666c750db96c5 100644 --- a/deps/npm/node_modules/es-to-primitive/.jscs.json +++ b/deps/npm/node_modules/es-to-primitive/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/es-to-primitive/LICENSE b/deps/npm/node_modules/es-to-primitive/LICENSE index fcf5754efe64ab..b43df444e51828 100644 --- a/deps/npm/node_modules/es-to-primitive/LICENSE +++ b/deps/npm/node_modules/es-to-primitive/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/es6-promise/README.md b/deps/npm/node_modules/es6-promise/README.md index 5bc88d3a648de9..951db75fa5c147 100644 --- a/deps/npm/node_modules/es6-promise/README.md +++ b/deps/npm/node_modules/es6-promise/README.md @@ -11,18 +11,18 @@ For API details and how to use promises, see the - + - + ``` diff --git a/deps/npm/node_modules/es6-promise/dist/es6-promise.auto.js b/deps/npm/node_modules/es6-promise/dist/es6-promise.auto.js index 1c46f949055494..7ad1de569011e0 100644 --- a/deps/npm/node_modules/es6-promise/dist/es6-promise.auto.js +++ b/deps/npm/node_modules/es6-promise/dist/es6-promise.auto.js @@ -1059,9 +1059,9 @@ var Promise$2 = function () { /** `finally` will be invoked regardless of the promise's fate just as native try/catch/finally behaves - + Synchronous example: - + ```js findAuthor() { if (Math.random() > 0.5) { @@ -1069,7 +1069,7 @@ var Promise$2 = function () { } return new Author(); } - + try { return findAuthor(); // succeed or fail } catch(error) { @@ -1079,9 +1079,9 @@ var Promise$2 = function () { // doesn't affect the return value } ``` - + Asynchronous example: - + ```js findAuthor().catch(function(reason){ return findOtherAuther(); @@ -1089,7 +1089,7 @@ var Promise$2 = function () { // author was either found, or not }); ``` - + @method finally @param {Function} callback @return {Promise} diff --git a/deps/npm/node_modules/es6-promise/dist/es6-promise.js b/deps/npm/node_modules/es6-promise/dist/es6-promise.js index 780e6a112a8cfa..72fa0da4d3ed7b 100644 --- a/deps/npm/node_modules/es6-promise/dist/es6-promise.js +++ b/deps/npm/node_modules/es6-promise/dist/es6-promise.js @@ -1059,9 +1059,9 @@ var Promise$1 = function () { /** `finally` will be invoked regardless of the promise's fate just as native try/catch/finally behaves - + Synchronous example: - + ```js findAuthor() { if (Math.random() > 0.5) { @@ -1069,7 +1069,7 @@ var Promise$1 = function () { } return new Author(); } - + try { return findAuthor(); // succeed or fail } catch(error) { @@ -1079,9 +1079,9 @@ var Promise$1 = function () { // doesn't affect the return value } ``` - + Asynchronous example: - + ```js findAuthor().catch(function(reason){ return findOtherAuther(); @@ -1089,7 +1089,7 @@ var Promise$1 = function () { // author was either found, or not }); ``` - + @method finally @param {Function} callback @return {Promise} diff --git a/deps/npm/node_modules/es6-promise/lib/es6-promise/promise.js b/deps/npm/node_modules/es6-promise/lib/es6-promise/promise.js index 2722511b05ce6b..ae1703638d710d 100644 --- a/deps/npm/node_modules/es6-promise/lib/es6-promise/promise.js +++ b/deps/npm/node_modules/es6-promise/lib/es6-promise/promise.js @@ -428,3 +428,4 @@ Promise.reject = Reject; Promise._setScheduler = setScheduler; Promise._setAsap = setAsap; Promise._asap = asap; + diff --git a/deps/npm/node_modules/extend/.jscs.json b/deps/npm/node_modules/extend/.jscs.json index 0b03e0564b61ba..3cce01d7832943 100644 --- a/deps/npm/node_modules/extend/.jscs.json +++ b/deps/npm/node_modules/extend/.jscs.json @@ -172,3 +172,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/extend/CHANGELOG.md b/deps/npm/node_modules/extend/CHANGELOG.md index 120f8f4322b14c..2cf7de6fb3ae5d 100644 --- a/deps/npm/node_modules/extend/CHANGELOG.md +++ b/deps/npm/node_modules/extend/CHANGELOG.md @@ -80,3 +80,4 @@ 1.0.0 / 2012-04-08 ================== * Initial commit + diff --git a/deps/npm/node_modules/extend/LICENSE b/deps/npm/node_modules/extend/LICENSE index 92d41503d32ec1..e16d6a56ca64e2 100644 --- a/deps/npm/node_modules/extend/LICENSE +++ b/deps/npm/node_modules/extend/LICENSE @@ -20,3 +20,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/extend/README.md b/deps/npm/node_modules/extend/README.md index 947dda6aeb9640..5b8249aa95e5d3 100644 --- a/deps/npm/node_modules/extend/README.md +++ b/deps/npm/node_modules/extend/README.md @@ -78,3 +78,4 @@ Ported to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jon [deps-url]: https://david-dm.org/justmoon/node-extend [dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg [dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies + diff --git a/deps/npm/node_modules/extend/component.json b/deps/npm/node_modules/extend/component.json index 0f76b59305b7bc..1500a2f3718182 100644 --- a/deps/npm/node_modules/extend/component.json +++ b/deps/npm/node_modules/extend/component.json @@ -29,3 +29,4 @@ "jscs": "~1.6.2" } } + diff --git a/deps/npm/node_modules/extsprintf/jsl.node.conf b/deps/npm/node_modules/extsprintf/jsl.node.conf index eabe9650f5e489..03f787ffbdee4e 100644 --- a/deps/npm/node_modules/extsprintf/jsl.node.conf +++ b/deps/npm/node_modules/extsprintf/jsl.node.conf @@ -1,5 +1,5 @@ # -# Configuration File for JavaScript Lint +# Configuration File for JavaScript Lint # # This configuration file can be used to lint a collection of scripts, or to enable # or disable warnings for scripts that are linted via the command line. @@ -134,3 +134,4 @@ # To add a set of files, use "+process FileName", "+process Folder\Path\*.js", # or "+process Folder\Path\*.htm". # + diff --git a/deps/npm/node_modules/find-npm-prefix/README.md b/deps/npm/node_modules/find-npm-prefix/README.md index 77bf4b724275a8..26d3337065df8f 100644 --- a/deps/npm/node_modules/find-npm-prefix/README.md +++ b/deps/npm/node_modules/find-npm-prefix/README.md @@ -15,7 +15,7 @@ findPrefix(process.cwd).then(prefix => { ## findPrefix(dir) → Promise(prefix) This computes the npm prefix, that is, the directory that npm adds and -removes modules from for a given path. +removes modules from for a given path. It takes a directory as an argument and returns a promise of the associated prefix directory. diff --git a/deps/npm/node_modules/flush-write-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/flush-write-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/flush-write-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/flush-write-stream/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/flush-write-stream/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/flush-write-stream/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/flush-write-stream/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/flush-write-stream/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/forever-agent/index.js b/deps/npm/node_modules/forever-agent/index.js index d7276fd97391c6..416c7abd709233 100644 --- a/deps/npm/node_modules/forever-agent/index.js +++ b/deps/npm/node_modules/forever-agent/index.js @@ -6,8 +6,8 @@ var util = require('util') , net = require('net') , tls = require('tls') , AgentSSL = require('https').Agent - -function getConnectionName(host, port) { + +function getConnectionName(host, port) { var name = '' if (typeof host === 'string') { name = host + ':' + port @@ -16,7 +16,7 @@ function getConnectionName(host, port) { name = host.host + ':' + host.port + ':' + (host.localAddress ? (host.localAddress + ':') : ':') } return name -} +} function ForeverAgent(options) { var self = this @@ -34,7 +34,7 @@ function ForeverAgent(options) { } else if (self.sockets[name].length < self.minSockets) { if (!self.freeSockets[name]) self.freeSockets[name] = [] self.freeSockets[name].push(socket) - + // if an error happens while we don't use the socket anyway, meh, throw the socket away var onIdleError = function() { socket.destroy() @@ -60,7 +60,7 @@ ForeverAgent.prototype.createConnection = net.createConnection ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest ForeverAgent.prototype.addRequest = function(req, host, port) { var name = getConnectionName(host, port) - + if (typeof host !== 'string') { var options = host port = options.port @@ -89,7 +89,7 @@ ForeverAgent.prototype.removeSocket = function(s, name, host, port) { delete this.sockets[name] delete this.requests[name] } - + if (this.freeSockets[name]) { var index = this.freeSockets[name].indexOf(s) if (index !== -1) { diff --git a/deps/npm/node_modules/from2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/from2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/from2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/from2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/from2/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/from2/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/from2/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/from2/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/from2/test.js b/deps/npm/node_modules/from2/test.js index 150429b0f7df16..b11bd6cd86be26 100644 --- a/deps/npm/node_modules/from2/test.js +++ b/deps/npm/node_modules/from2/test.js @@ -97,7 +97,7 @@ test('arrays can emit errors', function (t) { t.deepEqual(['a', 'b'], output) t.equal('ooops', e.message) t.end() - }) + }) stream.on('end', function () { t.fail('the stream should have errored') }) @@ -119,3 +119,5 @@ test('obj arrays can emit errors', function (t) { t.fail('the stream should have errored') }) }) + + diff --git a/deps/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/function-bind/.jscs.json b/deps/npm/node_modules/function-bind/.jscs.json index 773f4ced19400f..8c4479480be70d 100644 --- a/deps/npm/node_modules/function-bind/.jscs.json +++ b/deps/npm/node_modules/function-bind/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/function-bind/LICENSE b/deps/npm/node_modules/function-bind/LICENSE index 5b1b5dc3683d91..62d6d237ff179b 100644 --- a/deps/npm/node_modules/function-bind/LICENSE +++ b/deps/npm/node_modules/function-bind/LICENSE @@ -17,3 +17,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/gauge/node_modules/aproba/LICENSE b/deps/npm/node_modules/gauge/node_modules/aproba/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/gauge/node_modules/aproba/LICENSE +++ b/deps/npm/node_modules/gauge/node_modules/aproba/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/gauge/node_modules/aproba/README.md b/deps/npm/node_modules/gauge/node_modules/aproba/README.md index e94799201ce046..0bfc594c56a372 100644 --- a/deps/npm/node_modules/gauge/node_modules/aproba/README.md +++ b/deps/npm/node_modules/gauge/node_modules/aproba/README.md @@ -84,10 +84,11 @@ I wanted a very simple argument validator. It needed to do two things: 2. Not encourage an infinite bikeshed of DSLs This is why types are specified by a single character and there's no such -thing as an optional argument. +thing as an optional argument. This is not intended to validate user data. This is specifically about asserting the interface of your functions. If you need greater validation, I encourage you to write them by hand or look elsewhere. + diff --git a/deps/npm/node_modules/gauge/template-item.js b/deps/npm/node_modules/gauge/template-item.js index 4f02fefaa23eca..e46f447c941d38 100644 --- a/deps/npm/node_modules/gauge/template-item.js +++ b/deps/npm/node_modules/gauge/template-item.js @@ -70,3 +70,4 @@ TemplateItem.prototype.getMinLength = function () { if (this.minLength == null) return null return this.minLength + this.padLeft + this.padRight } + diff --git a/deps/npm/node_modules/gauge/theme-set.js b/deps/npm/node_modules/gauge/theme-set.js index c022d61cf13cb0..68971d5d231b07 100644 --- a/deps/npm/node_modules/gauge/theme-set.js +++ b/deps/npm/node_modules/gauge/theme-set.js @@ -112,3 +112,4 @@ ThemeSetProto.newThemeSet = function () { defaults: JSON.parse(JSON.stringify(this.defaults || {})) }) } + diff --git a/deps/npm/node_modules/genfun/LICENSE b/deps/npm/node_modules/genfun/LICENSE index 1e0a1d6f8df2f3..ab41caa64b86cf 100644 --- a/deps/npm/node_modules/genfun/LICENSE +++ b/deps/npm/node_modules/genfun/LICENSE @@ -18,3 +18,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/gentle-fs/node_modules/aproba/LICENSE b/deps/npm/node_modules/gentle-fs/node_modules/aproba/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/gentle-fs/node_modules/aproba/LICENSE +++ b/deps/npm/node_modules/gentle-fs/node_modules/aproba/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/gentle-fs/node_modules/aproba/README.md b/deps/npm/node_modules/gentle-fs/node_modules/aproba/README.md index e94799201ce046..0bfc594c56a372 100644 --- a/deps/npm/node_modules/gentle-fs/node_modules/aproba/README.md +++ b/deps/npm/node_modules/gentle-fs/node_modules/aproba/README.md @@ -84,10 +84,11 @@ I wanted a very simple argument validator. It needed to do two things: 2. Not encourage an infinite bikeshed of DSLs This is why types are specified by a single character and there's no such -thing as an optional argument. +thing as an optional argument. This is not intended to validate user data. This is specifically about asserting the interface of your functions. If you need greater validation, I encourage you to write them by hand or look elsewhere. + diff --git a/deps/npm/node_modules/has-symbols/test/index.js b/deps/npm/node_modules/has-symbols/test/index.js index 352129ca356c8c..fc32aff94cbb2d 100644 --- a/deps/npm/node_modules/has-symbols/test/index.js +++ b/deps/npm/node_modules/has-symbols/test/index.js @@ -5,7 +5,7 @@ var hasSymbols = require('../'); var runSymbolTests = require('./tests'); test('interface', function (t) { - t.equal(typeof hasSymbols, 'function', 'is a function'); + t.equal(typeof hasSymbols, 'function', 'is a function'); t.equal(typeof hasSymbols(), 'boolean', 'returns a boolean'); t.end(); }); diff --git a/deps/npm/node_modules/http-signature/CHANGES.md b/deps/npm/node_modules/http-signature/CHANGES.md index 3e4b13881e0de4..6f69444ba6a0f6 100644 --- a/deps/npm/node_modules/http-signature/CHANGES.md +++ b/deps/npm/node_modules/http-signature/CHANGES.md @@ -27,7 +27,7 @@ - First semver release. - #36: Ensure verifySignature does not leak useful timing information -- #42: Bring the library up to the latest version of the spec (including the +- #42: Bring the library up to the latest version of the spec (including the request-target changes) - Support for ECDSA keys and signatures. - Now uses `sshpk` for key parsing, validation and conversion. diff --git a/deps/npm/node_modules/https-proxy-agent/.editorconfig b/deps/npm/node_modules/https-proxy-agent/.editorconfig new file mode 100644 index 00000000000000..12b4b9a3b9bffe --- /dev/null +++ b/deps/npm/node_modules/https-proxy-agent/.editorconfig @@ -0,0 +1,37 @@ +root = true + +[*] +indent_style = tab +indent_size = 4 +tab_width = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.json,*.json.example,*.gyp,*.yml,*.yaml,*.workflow}] +indent_style = space +indent_size = 2 + +[{*.py,*.asm}] +indent_style = space + +[*.py] +indent_size = 4 + +[*.asm] +indent_size = 8 + +[*.md] +trim_trailing_whitespace = false + +# Ideal settings - some plugins might support these. +[*.js] +quote_type = single + +[{*.c,*.cc,*.h,*.hh,*.cpp,*.hpp,*.m,*.mm,*.mpp,*.js,*.java,*.go,*.rs,*.php,*.ng,*.jsx,*.ts,*.d,*.cs,*.swift}] +curly_bracket_next_line = false +spaces_around_operators = true +spaces_around_brackets = outside +# close enough to 1TB +indent_brace_style = K&R diff --git a/deps/npm/node_modules/https-proxy-agent/.eslintrc.js b/deps/npm/node_modules/https-proxy-agent/.eslintrc.js new file mode 100644 index 00000000000000..62743f2c4d1879 --- /dev/null +++ b/deps/npm/node_modules/https-proxy-agent/.eslintrc.js @@ -0,0 +1,86 @@ +module.exports = { + 'extends': [ + 'airbnb', + 'prettier' + ], + 'parser': '@typescript-eslint/parser', + 'parserOptions': { + 'ecmaVersion': 2018, + 'sourceType': 'module', + 'modules': true + }, + 'plugins': [ + '@typescript-eslint' + ], + 'settings': { + 'import/resolver': { + 'typescript': { + } + } + }, + 'rules': { + 'quotes': [ + 2, + 'single', + { + 'allowTemplateLiterals': true + } + ], + 'class-methods-use-this': 0, + 'consistent-return': 0, + 'func-names': 0, + 'global-require': 0, + 'guard-for-in': 0, + 'import/no-duplicates': 0, + 'import/no-dynamic-require': 0, + 'import/no-extraneous-dependencies': 0, + 'import/prefer-default-export': 0, + 'lines-between-class-members': 0, + 'no-await-in-loop': 0, + 'no-bitwise': 0, + 'no-console': 0, + 'no-continue': 0, + 'no-control-regex': 0, + 'no-empty': 0, + 'no-loop-func': 0, + 'no-nested-ternary': 0, + 'no-param-reassign': 0, + 'no-plusplus': 0, + 'no-restricted-globals': 0, + 'no-restricted-syntax': 0, + 'no-shadow': 0, + 'no-underscore-dangle': 0, + 'no-use-before-define': 0, + 'prefer-const': 0, + 'prefer-destructuring': 0, + 'camelcase': 0, + 'no-unused-vars': 0, // in favor of '@typescript-eslint/no-unused-vars' + // 'indent': 0 // in favor of '@typescript-eslint/indent' + '@typescript-eslint/no-unused-vars': 'warn', + // '@typescript-eslint/indent': ['error', 2] // this might conflict with a lot ongoing changes + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/adjacent-overload-signatures': 'error', + '@typescript-eslint/class-name-casing': 'error', + '@typescript-eslint/interface-name-prefix': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-parameter-properties': 'error', + '@typescript-eslint/no-triple-slash-reference': 'error', + '@typescript-eslint/prefer-namespace-keyword': 'error', + '@typescript-eslint/type-annotation-spacing': 'error', + // '@typescript-eslint/array-type': 'error', + // '@typescript-eslint/ban-types': 'error', + // '@typescript-eslint/explicit-function-return-type': 'warn', + // '@typescript-eslint/explicit-member-accessibility': 'error', + // '@typescript-eslint/member-delimiter-style': 'error', + // '@typescript-eslint/no-angle-bracket-type-assertion': 'error', + // '@typescript-eslint/no-explicit-any': 'warn', + // '@typescript-eslint/no-object-literal-type-assertion': 'error', + // '@typescript-eslint/no-use-before-define': 'error', + // '@typescript-eslint/no-var-requires': 'error', + // '@typescript-eslint/prefer-interface': 'error' + } +} diff --git a/deps/npm/node_modules/https-proxy-agent/README.md b/deps/npm/node_modules/https-proxy-agent/README.md index 5e0419cf9ced0f..20fda1e24cf65b 100644 --- a/deps/npm/node_modules/https-proxy-agent/README.md +++ b/deps/npm/node_modules/https-proxy-agent/README.md @@ -103,7 +103,7 @@ The `options` argument may either be a string URI of the proxy server to use, or * `host` - String - Proxy host to connect to (may use `hostname` as well). Required. * `port` - Number - Proxy port to connect to. Required. - * `secureProxy` - Boolean - If `true`, then use TLS to connect to the proxy. Defaults to `false`. + * `protocol` - String - If `https:`, then use TLS to connect to the proxy. * `headers` - Object - Additional HTTP headers to be sent on the HTTP CONNECT method. * Any other options given are passed to the `net.connect()`/`tls.connect()` functions. diff --git a/deps/npm/node_modules/https-proxy-agent/index.d.ts b/deps/npm/node_modules/https-proxy-agent/index.d.ts index 00989abadebdeb..cec35d85e0f614 100644 --- a/deps/npm/node_modules/https-proxy-agent/index.d.ts +++ b/deps/npm/node_modules/https-proxy-agent/index.d.ts @@ -1,22 +1,22 @@ declare module 'https-proxy-agent' { - import * as https from 'https' + import * as https from 'https'; - namespace HttpsProxyAgent { - interface HttpsProxyAgentOptions { - host: string - port: number - secureProxy?: boolean - headers?: { - [key: string]: string - } - [key: string]: any - } - } + namespace HttpsProxyAgent { + interface HttpsProxyAgentOptions { + host: string; + port: number | string; + secureProxy?: boolean; + headers?: { + [key: string]: string; + }; + [key: string]: any; + } + } - // HttpsProxyAgent doesnt *actually* extend https.Agent, but for my purposes I want it to pretend that it does - class HttpsProxyAgent extends https.Agent { - constructor(opts: HttpsProxyAgent.HttpsProxyAgentOptions | string) - } + // HttpsProxyAgent doesnt *actually* extend https.Agent, but for my purposes I want it to pretend that it does + class HttpsProxyAgent extends https.Agent { + constructor(opts: HttpsProxyAgent.HttpsProxyAgentOptions | string); + } - export = HttpsProxyAgent + export = HttpsProxyAgent; } diff --git a/deps/npm/node_modules/https-proxy-agent/index.js b/deps/npm/node_modules/https-proxy-agent/index.js index 0a2fdabe8dcfab..817a0a9232060c 100644 --- a/deps/npm/node_modules/https-proxy-agent/index.js +++ b/deps/npm/node_modules/https-proxy-agent/index.js @@ -5,6 +5,7 @@ var net = require('net'); var tls = require('tls'); var url = require('url'); +var assert = require('assert'); var Agent = require('agent-base'); var inherits = require('util').inherits; var debug = require('debug')('https-proxy-agent'); @@ -23,40 +24,42 @@ module.exports = HttpsProxyAgent; */ function HttpsProxyAgent(opts) { - if (!(this instanceof HttpsProxyAgent)) return new HttpsProxyAgent(opts); - if ('string' == typeof opts) opts = url.parse(opts); - if (!opts) - throw new Error( - 'an HTTP(S) proxy server `host` and `port` must be specified!' - ); - debug('creating new HttpsProxyAgent instance: %o', opts); - Agent.call(this, opts); - - var proxy = Object.assign({}, opts); - - // if `true`, then connect to the proxy server over TLS. defaults to `false`. - this.secureProxy = proxy.protocol ? /^https:?$/i.test(proxy.protocol) : false; - - // prefer `hostname` over `host`, and set the `port` if needed - proxy.host = proxy.hostname || proxy.host; - proxy.port = +proxy.port || (this.secureProxy ? 443 : 80); - - // ALPN is supported by Node.js >= v5. - // attempt to negotiate http/1.1 for proxy servers that support http/2 - if (this.secureProxy && !('ALPNProtocols' in proxy)) { - proxy.ALPNProtocols = ['http 1.1'] - } - - if (proxy.host && proxy.path) { - // if both a `host` and `path` are specified then it's most likely the - // result of a `url.parse()` call... we need to remove the `path` portion so - // that `net.connect()` doesn't attempt to open that as a unix socket file. - delete proxy.path; - delete proxy.pathname; - } - - this.proxy = proxy; - this.defaultPort = 443; + if (!(this instanceof HttpsProxyAgent)) return new HttpsProxyAgent(opts); + if ('string' == typeof opts) opts = url.parse(opts); + if (!opts) + throw new Error( + 'an HTTP(S) proxy server `host` and `port` must be specified!' + ); + debug('creating new HttpsProxyAgent instance: %o', opts); + Agent.call(this, opts); + + var proxy = Object.assign({}, opts); + + // if `true`, then connect to the proxy server over TLS. defaults to `false`. + this.secureProxy = proxy.protocol + ? /^https:?$/i.test(proxy.protocol) + : false; + + // prefer `hostname` over `host`, and set the `port` if needed + proxy.host = proxy.hostname || proxy.host; + proxy.port = +proxy.port || (this.secureProxy ? 443 : 80); + + // ALPN is supported by Node.js >= v5. + // attempt to negotiate http/1.1 for proxy servers that support http/2 + if (this.secureProxy && !('ALPNProtocols' in proxy)) { + proxy.ALPNProtocols = ['http 1.1']; + } + + if (proxy.host && proxy.path) { + // if both a `host` and `path` are specified then it's most likely the + // result of a `url.parse()` call... we need to remove the `path` portion so + // that `net.connect()` doesn't attempt to open that as a unix socket file. + delete proxy.path; + delete proxy.pathname; + } + + this.proxy = proxy; + this.defaultPort = 443; } inherits(HttpsProxyAgent, Agent); @@ -67,163 +70,172 @@ inherits(HttpsProxyAgent, Agent); */ HttpsProxyAgent.prototype.callback = function connect(req, opts, fn) { - var proxy = this.proxy; - - // create a socket connection to the proxy server - var socket; - if (this.secureProxy) { - socket = tls.connect(proxy); - } else { - socket = net.connect(proxy); - } - - // we need to buffer any HTTP traffic that happens with the proxy before we get - // the CONNECT response, so that if the response is anything other than an "200" - // response code, then we can re-play the "data" events on the socket once the - // HTTP parser is hooked up... - var buffers = []; - var buffersLength = 0; - - function read() { - var b = socket.read(); - if (b) ondata(b); - else socket.once('readable', read); - } - - function cleanup() { - socket.removeListener('data', ondata); - socket.removeListener('end', onend); - socket.removeListener('error', onerror); - socket.removeListener('close', onclose); - socket.removeListener('readable', read); - } - - function onclose(err) { - debug('onclose had error %o', err); - } - - function onend() { - debug('onend'); - } - - function onerror(err) { - cleanup(); - fn(err); - } - - function ondata(b) { - buffers.push(b); - buffersLength += b.length; - var buffered = Buffer.concat(buffers, buffersLength); - var str = buffered.toString('ascii'); - - if (!~str.indexOf('\r\n\r\n')) { - // keep buffering - debug('have not received end of HTTP headers yet...'); - if (socket.read) { - read(); - } else { - socket.once('data', ondata); - } - return; - } - - var firstLine = str.substring(0, str.indexOf('\r\n')); - var statusCode = +firstLine.split(' ')[1]; - debug('got proxy server response: %o', firstLine); - - if (200 == statusCode) { - // 200 Connected status code! - var sock = socket; - - // nullify the buffered data since we won't be needing it - buffers = buffered = null; - - if (opts.secureEndpoint) { - // since the proxy is connecting to an SSL server, we have - // to upgrade this socket connection to an SSL connection - debug( - 'upgrading proxy-connected socket to TLS connection: %o', - opts.host - ); - opts.socket = socket; - opts.servername = opts.servername || opts.host; - opts.host = null; - opts.hostname = null; - opts.port = null; - sock = tls.connect(opts); - } - - cleanup(); - fn(null, sock); - } else { - // some other status code that's not 200... need to re-play the HTTP header - // "data" events onto the socket once the HTTP machinery is attached so that - // the user can parse and handle the error status code - cleanup(); - - // save a reference to the concat'd Buffer for the `onsocket` callback - buffers = buffered; - - // need to wait for the "socket" event to re-play the "data" events - req.once('socket', onsocket); - fn(null, socket); - } - } - - function onsocket(socket) { - // replay the "buffers" Buffer onto the `socket`, since at this point - // the HTTP module machinery has been hooked up for the user - if ('function' == typeof socket.ondata) { - // node <= v0.11.3, the `ondata` function is set on the socket - socket.ondata(buffers, 0, buffers.length); - } else if (socket.listeners('data').length > 0) { - // node > v0.11.3, the "data" event is listened for directly - socket.emit('data', buffers); - } else { - // never? - throw new Error('should not happen...'); - } - - // nullify the cached Buffer instance - buffers = null; - } - - socket.on('error', onerror); - socket.on('close', onclose); - socket.on('end', onend); - - if (socket.read) { - read(); - } else { - socket.once('data', ondata); - } - - var hostname = opts.host + ':' + opts.port; - var msg = 'CONNECT ' + hostname + ' HTTP/1.1\r\n'; - - var headers = Object.assign({}, proxy.headers); - if (proxy.auth) { - headers['Proxy-Authorization'] = - 'Basic ' + Buffer.from(proxy.auth).toString('base64'); - } - - // the Host header should only include the port - // number when it is a non-standard port - var host = opts.host; - if (!isDefaultPort(opts.port, opts.secureEndpoint)) { - host += ':' + opts.port; - } - headers['Host'] = host; - - headers['Connection'] = 'close'; - Object.keys(headers).forEach(function(name) { - msg += name + ': ' + headers[name] + '\r\n'; - }); - - socket.write(msg + '\r\n'); + var proxy = this.proxy; + + // create a socket connection to the proxy server + var socket; + if (this.secureProxy) { + socket = tls.connect(proxy); + } else { + socket = net.connect(proxy); + } + + // we need to buffer any HTTP traffic that happens with the proxy before we get + // the CONNECT response, so that if the response is anything other than an "200" + // response code, then we can re-play the "data" events on the socket once the + // HTTP parser is hooked up... + var buffers = []; + var buffersLength = 0; + + function read() { + var b = socket.read(); + if (b) ondata(b); + else socket.once('readable', read); + } + + function cleanup() { + socket.removeListener('end', onend); + socket.removeListener('error', onerror); + socket.removeListener('close', onclose); + socket.removeListener('readable', read); + } + + function onclose(err) { + debug('onclose had error %o', err); + } + + function onend() { + debug('onend'); + } + + function onerror(err) { + cleanup(); + fn(err); + } + + function ondata(b) { + buffers.push(b); + buffersLength += b.length; + var buffered = Buffer.concat(buffers, buffersLength); + var str = buffered.toString('ascii'); + + if (!~str.indexOf('\r\n\r\n')) { + // keep buffering + debug('have not received end of HTTP headers yet...'); + read(); + return; + } + + var firstLine = str.substring(0, str.indexOf('\r\n')); + var statusCode = +firstLine.split(' ')[1]; + debug('got proxy server response: %o', firstLine); + + if (200 == statusCode) { + // 200 Connected status code! + var sock = socket; + + // nullify the buffered data since we won't be needing it + buffers = buffered = null; + + if (opts.secureEndpoint) { + // since the proxy is connecting to an SSL server, we have + // to upgrade this socket connection to an SSL connection + debug( + 'upgrading proxy-connected socket to TLS connection: %o', + opts.host + ); + opts.socket = socket; + opts.servername = opts.servername || opts.host; + opts.host = null; + opts.hostname = null; + opts.port = null; + sock = tls.connect(opts); + } + + cleanup(); + req.once('socket', resume); + fn(null, sock); + } else { + // some other status code that's not 200... need to re-play the HTTP header + // "data" events onto the socket once the HTTP machinery is attached so + // that the node core `http` can parse and handle the error status code + cleanup(); + + // the original socket is closed, and a new closed socket is + // returned instead, so that the proxy doesn't get the HTTP request + // written to it (which may contain `Authorization` headers or other + // sensitive data). + // + // See: https://hackerone.com/reports/541502 + socket.destroy(); + socket = new net.Socket(); + socket.readable = true; + + + // save a reference to the concat'd Buffer for the `onsocket` callback + buffers = buffered; + + // need to wait for the "socket" event to re-play the "data" events + req.once('socket', onsocket); + + fn(null, socket); + } + } + + function onsocket(socket) { + debug('replaying proxy buffer for failed request'); + assert(socket.listenerCount('data') > 0); + + // replay the "buffers" Buffer onto the `socket`, since at this point + // the HTTP module machinery has been hooked up for the user + socket.push(buffers); + + // nullify the cached Buffer instance + buffers = null; + } + + socket.on('error', onerror); + socket.on('close', onclose); + socket.on('end', onend); + + read(); + + var hostname = opts.host + ':' + opts.port; + var msg = 'CONNECT ' + hostname + ' HTTP/1.1\r\n'; + + var headers = Object.assign({}, proxy.headers); + if (proxy.auth) { + headers['Proxy-Authorization'] = + 'Basic ' + Buffer.from(proxy.auth).toString('base64'); + } + + // the Host header should only include the port + // number when it is a non-standard port + var host = opts.host; + if (!isDefaultPort(opts.port, opts.secureEndpoint)) { + host += ':' + opts.port; + } + headers['Host'] = host; + + headers['Connection'] = 'close'; + Object.keys(headers).forEach(function(name) { + msg += name + ': ' + headers[name] + '\r\n'; + }); + + socket.write(msg + '\r\n'); }; +/** + * Resumes a socket. + * + * @param {(net.Socket|tls.Socket)} socket The socket to resume + * @api public + */ + +function resume(socket) { + socket.resume(); +} + function isDefaultPort(port, secure) { - return Boolean((!secure && port === 80) || (secure && port === 443)); + return Boolean((!secure && port === 80) || (secure && port === 443)); } diff --git a/deps/npm/node_modules/https-proxy-agent/package.json b/deps/npm/node_modules/https-proxy-agent/package.json index 1f2885918136a9..274df864b2161f 100644 --- a/deps/npm/node_modules/https-proxy-agent/package.json +++ b/deps/npm/node_modules/https-proxy-agent/package.json @@ -1,27 +1,27 @@ { - "_from": "https-proxy-agent@^2.2.1", - "_id": "https-proxy-agent@2.2.2", + "_from": "https-proxy-agent@^2.2.3", + "_id": "https-proxy-agent@2.2.4", "_inBundle": false, - "_integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "_integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "_location": "/https-proxy-agent", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "https-proxy-agent@^2.2.1", + "raw": "https-proxy-agent@^2.2.3", "name": "https-proxy-agent", "escapedName": "https-proxy-agent", - "rawSpec": "^2.2.1", + "rawSpec": "^2.2.3", "saveSpec": null, - "fetchSpec": "^2.2.1" + "fetchSpec": "^2.2.3" }, "_requiredBy": [ "/make-fetch-happen" ], - "_resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "_shasum": "271ea8e90f836ac9f119daccd39c19ff7dfb0793", - "_spec": "https-proxy-agent@^2.2.1", - "_where": "/Users/isaacs/dev/npm/cli/node_modules/make-fetch-happen", + "_resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "_shasum": "4ee7a737abd92678a293d9b34a1af4d0d08c787b", + "_spec": "https-proxy-agent@^2.2.3", + "_where": "/Users/claudiahdz/npm/cli/node_modules/make-fetch-happen", "author": { "name": "Nathan Rajlich", "email": "nathan@tootallnate.net", @@ -38,8 +38,8 @@ "deprecated": false, "description": "An HTTP(s) proxy `http.Agent` implementation for HTTPS", "devDependencies": { - "mocha": "^3.4.2", - "proxy": "^0.2.4" + "mocha": "^6.2.0", + "proxy": "1" }, "engines": { "node": ">= 4.5.0" @@ -62,5 +62,5 @@ "test": "mocha --reporter spec" }, "types": "./index.d.ts", - "version": "2.2.2" + "version": "2.2.4" } diff --git a/deps/npm/node_modules/iconv-lite/.travis.yml b/deps/npm/node_modules/iconv-lite/.travis.yml index 636d8d9123ad83..3eab7fdb3fcc6c 100644 --- a/deps/npm/node_modules/iconv-lite/.travis.yml +++ b/deps/npm/node_modules/iconv-lite/.travis.yml @@ -20,3 +20,4 @@ packages: - gcc-4.8 - g++-4.8 + diff --git a/deps/npm/node_modules/iconv-lite/Changelog.md b/deps/npm/node_modules/iconv-lite/Changelog.md index 6425e27c388b19..e31cd0c24e1f9c 100644 --- a/deps/npm/node_modules/iconv-lite/Changelog.md +++ b/deps/npm/node_modules/iconv-lite/Changelog.md @@ -90,7 +90,7 @@ # 0.4.9 / 2015-05-24 - * Streamlined BOM handling: strip BOM by default, add BOM when encoding if + * Streamlined BOM handling: strip BOM by default, add BOM when encoding if addBOM: true. Added docs to Readme. * UTF16 now uses UTF16-LE by default. * Fixed minor issue with big5 encoding. @@ -101,7 +101,7 @@ # 0.4.8 / 2015-04-14 - + * added alias UNICODE-1-1-UTF-7 for UTF-7 encoding (#94) @@ -109,12 +109,12 @@ * stop official support of Node.js v0.8. Should still work, but no guarantees. reason: Packages needed for testing are hard to get on Travis CI. - * work in environment where Object.prototype is monkey patched with enumerable + * work in environment where Object.prototype is monkey patched with enumerable props (#89). # 0.4.6 / 2015-01-12 - + * fix rare aliases of single-byte encodings (thanks @mscdex) * double the timeout for dbcs tests to make them less flaky on travis @@ -154,3 +154,5 @@ * browserify compatibility added * (optional) extend core primitive encodings to make usage even simpler * moved from vows to mocha as the testing framework + + diff --git a/deps/npm/node_modules/iconv-lite/LICENSE b/deps/npm/node_modules/iconv-lite/LICENSE index e3c1f8d36c4a2f..d518d8376af9fa 100644 --- a/deps/npm/node_modules/iconv-lite/LICENSE +++ b/deps/npm/node_modules/iconv-lite/LICENSE @@ -18,3 +18,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/iconv-lite/README.md b/deps/npm/node_modules/iconv-lite/README.md index 1d61f9e84d13ec..c981c3708582a5 100644 --- a/deps/npm/node_modules/iconv-lite/README.md +++ b/deps/npm/node_modules/iconv-lite/README.md @@ -1,7 +1,7 @@ ## Pure JS character encoding conversion [![Build Status](https://travis-ci.org/ashtuchkin/iconv-lite.svg?branch=master)](https://travis-ci.org/ashtuchkin/iconv-lite) * Doesn't need native code compilation. Works on Windows and in sandboxed environments like [Cloud9](http://c9.io). - * Used in popular projects like [Express.js (body_parser)](https://github.com/expressjs/body-parser), + * Used in popular projects like [Express.js (body_parser)](https://github.com/expressjs/body-parser), [Grunt](http://gruntjs.com/), [Nodemailer](http://www.nodemailer.com/), [Yeoman](http://yeoman.io/) and others. * Faster than [node-iconv](https://github.com/bnoordhuis/node-iconv) (see below for performance comparison). * Intuitive encode/decode API @@ -83,7 +83,7 @@ fs.createReadStream("file.txt", "shift_jis"); // External modules are also supported (if they use Node primitives, which they probably do). request = require('request'); request({ - url: "http://github.com/", + url: "http://github.com/", encoding: "cp932" }); @@ -95,8 +95,8 @@ iconv.undoExtendNodeEncodings(); * All node.js native encodings: utf8, ucs2 / utf16-le, ascii, binary, base64, hex. * Additional unicode encodings: utf16, utf16-be, utf-7, utf-7-imap. - * All widespread singlebyte encodings: Windows 125x family, ISO-8859 family, - IBM/DOS codepages, Macintosh family, KOI8 family, all others supported by iconv library. + * All widespread singlebyte encodings: Windows 125x family, ISO-8859 family, + IBM/DOS codepages, Macintosh family, KOI8 family, all others supported by iconv library. Aliases like 'latin1', 'us-ascii' also supported. * All widespread multibyte encodings: CP932, CP936, CP949, CP950, GB2312, GBK, GB18030, Big5, Shift_JIS, EUC-JP. @@ -109,7 +109,7 @@ Multibyte encodings are generated from [Unicode.org mappings](http://www.unicode ## Encoding/decoding speed -Comparison with node-iconv module (1000x256kb, on MacBook Pro, Core i5/2.6 GHz, Node v0.12.0). +Comparison with node-iconv module (1000x256kb, on MacBook Pro, Core i5/2.6 GHz, Node v0.12.0). Note: your results may vary, so please always check on your hardware. operation iconv@2.1.4 iconv-lite@0.4.7 @@ -129,15 +129,15 @@ Note: your results may vary, so please always check on your hardware. This library supports UTF-16LE, UTF-16BE and UTF-16 encodings. First two are straightforward, but UTF-16 is trying to be smart about endianness in the following ways: - * Decoding: uses BOM and 'spaces heuristic' to determine input endianness. Default is UTF-16LE, but can be + * Decoding: uses BOM and 'spaces heuristic' to determine input endianness. Default is UTF-16LE, but can be overridden with `defaultEncoding: 'utf-16be'` option. Strips BOM unless `stripBOM: false`. * Encoding: uses UTF-16LE and writes BOM by default. Use `addBOM: false` to override. ## Other notes -When decoding, be sure to supply a Buffer to decode() method, otherwise [bad things usually happen](https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding). -Untranslatable characters are set to � or ?. No transliteration is currently supported. -Node versions 0.10.31 and 0.11.13 are buggy, don't use them (see #65, #77). +When decoding, be sure to supply a Buffer to decode() method, otherwise [bad things usually happen](https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding). +Untranslatable characters are set to � or ?. No transliteration is currently supported. +Node versions 0.10.31 and 0.11.13 are buggy, don't use them (see #65, #77). ## Testing @@ -146,7 +146,7 @@ $ git clone git@github.com:ashtuchkin/iconv-lite.git $ cd iconv-lite $ npm install $ npm test - + $ # To view performance: $ node test/performance.js diff --git a/deps/npm/node_modules/iconv-lite/encodings/dbcs-codec.js b/deps/npm/node_modules/iconv-lite/encodings/dbcs-codec.js index 7a8559824e75d3..1fe3e160112aa9 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/dbcs-codec.js +++ b/deps/npm/node_modules/iconv-lite/encodings/dbcs-codec.js @@ -42,7 +42,7 @@ function DBCSCodec(codecOptions, iconv) { this.decodeTables = []; this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. - // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. + // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. this.decodeTableSeq = []; // Actual mapping tables consist of chunks. Use them to fill up decode tables. @@ -51,7 +51,7 @@ function DBCSCodec(codecOptions, iconv) { this.defaultCharUnicode = iconv.defaultCharUnicode; - + // Encode tables: Unicode -> DBCS. // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. @@ -60,7 +60,7 @@ function DBCSCodec(codecOptions, iconv) { // == UNASSIGNED -> no conversion found. Output a default char. // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. this.encodeTable = []; - + // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key // means end of sequence (needed when one sequence is a strict subsequence of another). @@ -78,7 +78,7 @@ function DBCSCodec(codecOptions, iconv) { for (var j = val.from; j <= val.to; j++) skipEncodeChars[j] = true; } - + // Use decode trie to recursively fill out encode tables. this._fillEncodeTable(0, 0, skipEncodeChars); @@ -115,7 +115,7 @@ function DBCSCodec(codecOptions, iconv) { thirdByteNode[i] = NODE_START - fourthByteNodeIdx; for (var i = 0x30; i <= 0x39; i++) fourthByteNode[i] = GB18030_CODE - } + } } DBCSCodec.prototype.encoder = DBCSEncoder; @@ -180,7 +180,7 @@ DBCSCodec.prototype._addDecodeChunk = function(chunk) { else writeTable[curAddr++] = code; // Basic char } - } + } else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. var charCode = writeTable[curAddr - 1] + 1; for (var l = 0; l < part; l++) @@ -211,7 +211,7 @@ DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { } DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { - + // Get the root of character tree according to first character of the sequence. var uCode = seq[0]; var bucket = this._getEncodeBucket(uCode); @@ -272,7 +272,7 @@ function DBCSEncoder(options, codec) { // Encoder state this.leadSurrogate = -1; this.seqObj = undefined; - + // Static data this.encodeTable = codec.encodeTable; this.encodeTableSeq = codec.encodeTableSeq; @@ -294,7 +294,7 @@ DBCSEncoder.prototype.write = function(str) { } else { var uCode = nextChar; - nextChar = -1; + nextChar = -1; } // 1. Handle surrogates. @@ -316,7 +316,7 @@ DBCSEncoder.prototype.write = function(str) { // Incomplete surrogate pair - only trail surrogate found. uCode = UNASSIGNED; } - + } } else if (leadSurrogate !== -1) { @@ -357,7 +357,7 @@ DBCSEncoder.prototype.write = function(str) { var subtable = this.encodeTable[uCode >> 8]; if (subtable !== undefined) dbcsCode = subtable[uCode & 0xFF]; - + if (dbcsCode <= SEQ_START) { // Sequence start seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; continue; @@ -380,7 +380,7 @@ DBCSEncoder.prototype.write = function(str) { // 3. Write dbcsCode character. if (dbcsCode === UNASSIGNED) dbcsCode = this.defaultCharSingleByte; - + if (dbcsCode < 0x100) { newBuf[j++] = dbcsCode; } @@ -427,7 +427,7 @@ DBCSEncoder.prototype.end = function() { newBuf[j++] = this.defaultCharSingleByte; this.leadSurrogate = -1; } - + return newBuf.slice(0, j); } @@ -451,21 +451,21 @@ function DBCSDecoder(options, codec) { DBCSDecoder.prototype.write = function(buf) { var newBuf = Buffer.alloc(buf.length*2), - nodeIdx = this.nodeIdx, + nodeIdx = this.nodeIdx, prevBuf = this.prevBuf, prevBufOffset = this.prevBuf.length, seqStart = -this.prevBuf.length, // idx of the start of current parsed sequence. uCode; if (prevBufOffset > 0) // Make prev buf overlap a little to make it easier to slice later. prevBuf = Buffer.concat([prevBuf, buf.slice(0, 10)]); - + for (var i = 0, j = 0; i < buf.length; i++) { var curByte = (i >= 0) ? buf[i] : prevBuf[i + prevBufOffset]; // Lookup in current trie node. var uCode = this.decodeTables[nodeIdx][curByte]; - if (uCode >= 0) { + if (uCode >= 0) { // Normal character, just use it. } else if (uCode === UNASSIGNED) { // Unknown char. @@ -497,7 +497,7 @@ DBCSDecoder.prototype.write = function(buf) { throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); // Write the character to buffer, handling higher planes using surrogate pair. - if (uCode > 0xFFFF) { + if (uCode > 0xFFFF) { uCode -= 0x10000; var uCodeLead = 0xD800 + Math.floor(uCode / 0x400); newBuf[j++] = uCodeLead & 0xFF; @@ -552,3 +552,4 @@ function findIdx(table, val) { } return l; } + diff --git a/deps/npm/node_modules/iconv-lite/encodings/dbcs-data.js b/deps/npm/node_modules/iconv-lite/encodings/dbcs-data.js index 53cb75bd1b1fea..4b61914341f916 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/dbcs-data.js +++ b/deps/npm/node_modules/iconv-lite/encodings/dbcs-data.js @@ -5,11 +5,11 @@ // require()-s are direct to support Browserify. module.exports = { - + // == Japanese/ShiftJIS ==================================================== // All japanese encodings are based on JIS X set of standards: // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. - // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. + // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. // Has several variations in 1978, 1983, 1990 and 1997. // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. @@ -27,7 +27,7 @@ module.exports = { // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. // Used as-is in ISO2022 family. - // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, + // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, // 0201-1976 Roman, 0208-1978, 0208-1983. // * ISO2022-JP-1: Adds esc seq for 0212-1990. // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. @@ -139,7 +139,7 @@ module.exports = { // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ // * Big5-2003 (Taiwan standard) almost superset of cp950. // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. - // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. + // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. // Plus, it has 4 combining sequences. // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 @@ -150,7 +150,7 @@ module.exports = { // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt - // + // // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. diff --git a/deps/npm/node_modules/iconv-lite/encodings/index.js b/deps/npm/node_modules/iconv-lite/encodings/index.js index 55144bd2278704..e30400317c18fb 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/index.js +++ b/deps/npm/node_modules/iconv-lite/encodings/index.js @@ -13,7 +13,7 @@ var modules = [ require("./dbcs-data"), ]; -// Put all encoding/alias/codec definitions to single object and export it. +// Put all encoding/alias/codec definitions to single object and export it. for (var i = 0; i < modules.length; i++) { var module = modules[i]; for (var enc in module) diff --git a/deps/npm/node_modules/iconv-lite/encodings/internal.js b/deps/npm/node_modules/iconv-lite/encodings/internal.js index fc23066bc91145..05ce38b276eee2 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/internal.js +++ b/deps/npm/node_modules/iconv-lite/encodings/internal.js @@ -136,7 +136,7 @@ function InternalDecoderCesu8(options, codec) { } InternalDecoderCesu8.prototype.write = function(buf) { - var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, + var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, res = ''; for (var i = 0; i < buf.length; i++) { var curByte = buf[i]; diff --git a/deps/npm/node_modules/iconv-lite/encodings/sbcs-codec.js b/deps/npm/node_modules/iconv-lite/encodings/sbcs-codec.js index 798497d2d5ca72..f2258237ba2724 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/sbcs-codec.js +++ b/deps/npm/node_modules/iconv-lite/encodings/sbcs-codec.js @@ -2,17 +2,17 @@ var Buffer = require("safer-buffer").Buffer; // Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that -// correspond to encoded bytes (if 128 - then lower half is ASCII). +// correspond to encoded bytes (if 128 - then lower half is ASCII). exports._sbcs = SBCSCodec; function SBCSCodec(codecOptions, iconv) { if (!codecOptions) throw new Error("SBCS codec is called without the data.") - + // Prepare char buffer for decoding. if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); - + if (codecOptions.chars.length === 128) { var asciiString = ""; for (var i = 0; i < 128; i++) @@ -21,7 +21,7 @@ function SBCSCodec(codecOptions, iconv) { } this.decodeBuf = new Buffer.from(codecOptions.chars, 'ucs2'); - + // Encoding buffer. var encodeBuf = new Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); @@ -43,7 +43,7 @@ SBCSEncoder.prototype.write = function(str) { var buf = Buffer.alloc(str.length); for (var i = 0; i < str.length; i++) buf[i] = this.encodeBuf[str.charCodeAt(i)]; - + return buf; } diff --git a/deps/npm/node_modules/iconv-lite/encodings/sbcs-data.js b/deps/npm/node_modules/iconv-lite/encodings/sbcs-data.js index 1009ad9901d75b..2d6f846ad4600a 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/sbcs-data.js +++ b/deps/npm/node_modules/iconv-lite/encodings/sbcs-data.js @@ -166,3 +166,4 @@ module.exports = { "mac": "macintosh", "csmacintosh": "macintosh", }; + diff --git a/deps/npm/node_modules/iconv-lite/encodings/utf16.js b/deps/npm/node_modules/iconv-lite/encodings/utf16.js index 0b183cf9e713a7..54765aeee2f11e 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/utf16.js +++ b/deps/npm/node_modules/iconv-lite/encodings/utf16.js @@ -115,7 +115,7 @@ Utf16Decoder.prototype.write = function(buf) { // Codec is not chosen yet. Accumulate initial bytes. this.initialBytes.push(buf); this.initialBytesLen += buf.length; - + if (this.initialBytesLen < 16) // We need more bytes to use space heuristic (see below) return ''; @@ -173,3 +173,5 @@ function detectEncoding(buf, defaultEncoding) { return enc; } + + diff --git a/deps/npm/node_modules/iconv-lite/encodings/utf7.js b/deps/npm/node_modules/iconv-lite/encodings/utf7.js index 3f776a87fa93d5..b7631c23a801b0 100644 --- a/deps/npm/node_modules/iconv-lite/encodings/utf7.js +++ b/deps/npm/node_modules/iconv-lite/encodings/utf7.js @@ -27,8 +27,8 @@ Utf7Encoder.prototype.write = function(str) { // Naive implementation. // Non-direct chars are encoded as "+-"; single "+" char is encoded as "+-". return Buffer.from(str.replace(nonDirectChars, function(chunk) { - return "+" + (chunk === '+' ? '' : - this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) + return "+" + (chunk === '+' ? '' : + this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) + "-"; }.bind(this))); } @@ -50,7 +50,7 @@ var base64Chars = []; for (var i = 0; i < 256; i++) base64Chars[i] = base64Regex.test(String.fromCharCode(i)); -var plusChar = '+'.charCodeAt(0), +var plusChar = '+'.charCodeAt(0), minusChar = '-'.charCodeAt(0), andChar = '&'.charCodeAt(0); @@ -286,3 +286,5 @@ Utf7IMAPDecoder.prototype.end = function() { this.base64Accum = ''; return res; } + + diff --git a/deps/npm/node_modules/iconv-lite/lib/bom-handling.js b/deps/npm/node_modules/iconv-lite/lib/bom-handling.js index b2b1e426d6cdd7..1050872385c7f9 100644 --- a/deps/npm/node_modules/iconv-lite/lib/bom-handling.js +++ b/deps/npm/node_modules/iconv-lite/lib/bom-handling.js @@ -49,3 +49,4 @@ StripBOMWrapper.prototype.write = function(buf) { StripBOMWrapper.prototype.end = function() { return this.decoder.end(); } + diff --git a/deps/npm/node_modules/iconv-lite/lib/extend-node.js b/deps/npm/node_modules/iconv-lite/lib/extend-node.js index 3f422f761d2c87..87f5394a4b3966 100644 --- a/deps/npm/node_modules/iconv-lite/lib/extend-node.js +++ b/deps/npm/node_modules/iconv-lite/lib/extend-node.js @@ -23,7 +23,7 @@ module.exports = function (iconv) { } var nodeNativeEncodings = { - 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, + 'hex': true, 'utf8': true, 'utf-8': true, 'ascii': true, 'binary': true, 'base64': true, 'ucs2': true, 'ucs-2': true, 'utf16le': true, 'utf-16le': true, }; diff --git a/deps/npm/node_modules/iconv-lite/lib/index.js b/deps/npm/node_modules/iconv-lite/lib/index.js index 270c1d86b04c07..5391919ca2c631 100644 --- a/deps/npm/node_modules/iconv-lite/lib/index.js +++ b/deps/npm/node_modules/iconv-lite/lib/index.js @@ -23,7 +23,7 @@ iconv.encode = function encode(str, encoding, options) { var res = encoder.write(str); var trail = encoder.end(); - + return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; } @@ -63,7 +63,7 @@ iconv._codecDataCache = {}; iconv.getCodec = function getCodec(encoding) { if (!iconv.encodings) iconv.encodings = require("../encodings"); // Lazy load all encoding definitions. - + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. var enc = iconv._canonicalizeEncoding(encoding); @@ -87,7 +87,7 @@ iconv.getCodec = function getCodec(encoding) { if (!codecOptions.encodingName) codecOptions.encodingName = enc; - + enc = codecDef.type; break; diff --git a/deps/npm/node_modules/iconv-lite/lib/streams.js b/deps/npm/node_modules/iconv-lite/lib/streams.js index bb4dbdaf4aafa8..4409552958edca 100644 --- a/deps/npm/node_modules/iconv-lite/lib/streams.js +++ b/deps/npm/node_modules/iconv-lite/lib/streams.js @@ -6,7 +6,7 @@ var Buffer = require("buffer").Buffer, // == Exports ================================================================== module.exports = function(iconv) { - + // Additional Public API. iconv.encodeStream = function encodeStream(encoding, options) { return new IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); @@ -101,7 +101,7 @@ IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { IconvLiteDecoderStream.prototype._flush = function(done) { try { var res = this.conv.end(); - if (res && res.length) this.push(res, this.encoding); + if (res && res.length) this.push(res, this.encoding); done(); } catch (e) { @@ -118,3 +118,4 @@ IconvLiteDecoderStream.prototype.collect = function(cb) { }); return this; } + diff --git a/deps/npm/node_modules/ip/README.md b/deps/npm/node_modules/ip/README.md index 9035fd71b139e3..22e5819ffaf946 100644 --- a/deps/npm/node_modules/ip/README.md +++ b/deps/npm/node_modules/ip/README.md @@ -1,5 +1,5 @@ -# IP -[![](https://badge.fury.io/js/ip.svg)](https://www.npmjs.com/package/ip) +# IP +[![](https://badge.fury.io/js/ip.svg)](https://www.npmjs.com/package/ip) IP address utilities for node.js @@ -15,7 +15,7 @@ npm install ip ```shell git clone https://github.com/indutny/node-ip.git ``` - + ## Usage Get your ip address, compare ip addresses, validate ip addresses, etc. diff --git a/deps/npm/node_modules/is-callable/.jscs.json b/deps/npm/node_modules/is-callable/.jscs.json index 759bd65c52915d..b4d9b8b40aebf6 100644 --- a/deps/npm/node_modules/is-callable/.jscs.json +++ b/deps/npm/node_modules/is-callable/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/is-callable/LICENSE b/deps/npm/node_modules/is-callable/LICENSE index fcf5754efe64ab..b43df444e51828 100644 --- a/deps/npm/node_modules/is-callable/LICENSE +++ b/deps/npm/node_modules/is-callable/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/is-date-object/.jscs.json b/deps/npm/node_modules/is-date-object/.jscs.json index 9f49765bf6aeff..040bb6806a566c 100644 --- a/deps/npm/node_modules/is-date-object/.jscs.json +++ b/deps/npm/node_modules/is-date-object/.jscs.json @@ -119,3 +119,4 @@ "validateOrderInObjectKeys": "asc-insensitive" } + diff --git a/deps/npm/node_modules/is-date-object/LICENSE b/deps/npm/node_modules/is-date-object/LICENSE index fcf5754efe64ab..b43df444e51828 100644 --- a/deps/npm/node_modules/is-date-object/LICENSE +++ b/deps/npm/node_modules/is-date-object/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/is-regex/.jscs.json b/deps/npm/node_modules/is-regex/.jscs.json index 7296cbab09bdf5..3d099c4b1192c4 100644 --- a/deps/npm/node_modules/is-regex/.jscs.json +++ b/deps/npm/node_modules/is-regex/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/is-regex/README.md b/deps/npm/node_modules/is-regex/README.md index dab42912bbdfb7..05baa0ebca339b 100644 --- a/deps/npm/node_modules/is-regex/README.md +++ b/deps/npm/node_modules/is-regex/README.md @@ -51,3 +51,4 @@ Simply clone the repo, `npm install`, and run `npm test` [license-url]: LICENSE [downloads-image]: http://img.shields.io/npm/dm/is-regex.svg [downloads-url]: http://npm-stat.com/charts.html?package=is-regex + diff --git a/deps/npm/node_modules/is-symbol/.editorconfig b/deps/npm/node_modules/is-symbol/.editorconfig index 572e9793f03233..eaa214161f5cdb 100644 --- a/deps/npm/node_modules/is-symbol/.editorconfig +++ b/deps/npm/node_modules/is-symbol/.editorconfig @@ -10,3 +10,4 @@ spaces_around_operators = true; trim_trailing_whitespace = true; spaces_in_brackets = false; end_of_line = lf; + diff --git a/deps/npm/node_modules/is-symbol/.jscs.json b/deps/npm/node_modules/is-symbol/.jscs.json index 759bd65c52915d..b4d9b8b40aebf6 100644 --- a/deps/npm/node_modules/is-symbol/.jscs.json +++ b/deps/npm/node_modules/is-symbol/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/is-symbol/LICENSE b/deps/npm/node_modules/is-symbol/LICENSE index fcf5754efe64ab..b43df444e51828 100644 --- a/deps/npm/node_modules/is-symbol/LICENSE +++ b/deps/npm/node_modules/is-symbol/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/is-symbol/test/index.js b/deps/npm/node_modules/is-symbol/test/index.js index 46dfa439d9bfe8..e01f035c8ca3ab 100644 --- a/deps/npm/node_modules/is-symbol/test/index.js +++ b/deps/npm/node_modules/is-symbol/test/index.js @@ -89,3 +89,4 @@ test('Symbol support', { skip: !hasSymbols }, function (t) { t.end(); }); + diff --git a/deps/npm/node_modules/isarray/Makefile b/deps/npm/node_modules/isarray/Makefile index 0ecc29c402c243..787d56e1e982e4 100644 --- a/deps/npm/node_modules/isarray/Makefile +++ b/deps/npm/node_modules/isarray/Makefile @@ -3,3 +3,4 @@ test: @node_modules/.bin/tape test.js .PHONY: test + diff --git a/deps/npm/node_modules/isarray/test.js b/deps/npm/node_modules/isarray/test.js index f7f7bcd19fec56..e0c3444d85d5c7 100644 --- a/deps/npm/node_modules/isarray/test.js +++ b/deps/npm/node_modules/isarray/test.js @@ -17,3 +17,4 @@ test('is array', function(t){ t.end(); }); + diff --git a/deps/npm/node_modules/isstream/test.js b/deps/npm/node_modules/isstream/test.js index 881e70b3098ff7..8c950c55e6375f 100644 --- a/deps/npm/node_modules/isstream/test.js +++ b/deps/npm/node_modules/isstream/test.js @@ -163,3 +163,6 @@ testDuplex(true, 'ReadableStream11.PassThrough', new (ReadableStream11.PassThrou }) }) + + + diff --git a/deps/npm/node_modules/jsbn/LICENSE b/deps/npm/node_modules/jsbn/LICENSE index 7ccbf5073c8650..2a6457e9ef1e09 100644 --- a/deps/npm/node_modules/jsbn/LICENSE +++ b/deps/npm/node_modules/jsbn/LICENSE @@ -18,9 +18,9 @@ This software is covered under the following copyright: * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER diff --git a/deps/npm/node_modules/jsbn/README.md b/deps/npm/node_modules/jsbn/README.md index 9686611db7f379..7aac67f53ff0ef 100644 --- a/deps/npm/node_modules/jsbn/README.md +++ b/deps/npm/node_modules/jsbn/README.md @@ -7,7 +7,7 @@ I felt compelled to put this on github and publish to npm. I haven't tested ever ## usage var BigInteger = require('jsbn'); - + var a = new BigInteger('91823918239182398123'); alert(a.bitLength()); // 67 @@ -171,3 +171,5 @@ returns new BI of absolute value ### bi.isProbablePrime + + diff --git a/deps/npm/node_modules/jsbn/example.html b/deps/npm/node_modules/jsbn/example.html index ea180b8cc4268f..7c26a5665c1b1a 100644 --- a/deps/npm/node_modules/jsbn/example.html +++ b/deps/npm/node_modules/jsbn/example.html @@ -5,8 +5,8 @@ - - + + \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/README.md b/deps/npm/node_modules/json-schema/README.md index 78b81d39683251..4de0124476e98c 100644 --- a/deps/npm/node_modules/json-schema/README.md +++ b/deps/npm/node_modules/json-schema/README.md @@ -1,5 +1,5 @@ JSON Schema is a repository for the JSON Schema specification, reference schemas and a CommonJS implementation of JSON Schema (not the only JavaScript implementation of JSON Schema, JSV is another excellent JavaScript validator). -Code is licensed under the AFL or BSD license as part of the Persevere +Code is licensed under the AFL or BSD license as part of the Persevere project which is administered under the Dojo foundation, and all contributions require a Dojo CLA. \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-00/hyper-schema b/deps/npm/node_modules/json-schema/draft-00/hyper-schema index 36a85ccd244926..de80b918b671c7 100644 --- a/deps/npm/node_modules/json-schema/draft-00/hyper-schema +++ b/deps/npm/node_modules/json-schema/draft-00/hyper-schema @@ -8,61 +8,61 @@ "items" : {"$ref" : "http://json-schema.org/draft-00/links#"}, "optional" : true }, - + "fragmentResolution" : { "type" : "string", "optional" : true, "default" : "dot-delimited" }, - + "root" : { "type" : "boolean", "optional" : true, "default" : false }, - + "readonly" : { "type" : "boolean", "optional" : true, "default" : false }, - + "pathStart" : { "type" : "string", "optional" : true, "format" : "uri" }, - + "mediaType" : { "type" : "string", "optional" : true, "format" : "media-type" }, - + "alternate" : { "type" : "array", "items" : {"$ref" : "#"}, "optional" : true } }, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "dot-delimited", "extends" : {"$ref" : "http://json-schema.org/draft-00/schema#"} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-00/json-ref b/deps/npm/node_modules/json-schema/draft-00/json-ref index 5d1f76b6a694a4..3a872a71c973dc 100644 --- a/deps/npm/node_modules/json-schema/draft-00/json-ref +++ b/deps/npm/node_modules/json-schema/draft-00/json-ref @@ -1,26 +1,26 @@ { "$schema" : "http://json-schema.org/draft-00/hyper-schema#", "id" : "http://json-schema.org/draft-00/json-ref#", - + "items" : {"$ref" : "#"}, "additionalProperties" : {"$ref" : "#"}, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "dot-delimited" } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-00/links b/deps/npm/node_modules/json-schema/draft-00/links index cbef326dd3de5b..8a5e7807250cf9 100644 --- a/deps/npm/node_modules/json-schema/draft-00/links +++ b/deps/npm/node_modules/json-schema/draft-00/links @@ -2,28 +2,28 @@ "$schema" : "http://json-schema.org/draft-00/hyper-schema#", "id" : "http://json-schema.org/draft-00/links#", "type" : "object", - + "properties" : { "href" : { "type" : "string" }, - + "rel" : { "type" : "string" }, - + "method" : { "type" : "string", "default" : "GET", "optional" : true }, - + "enctype" : { "type" : "string", "requires" : "method", "optional" : true }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "http://json-schema.org/draft-00/hyper-schema#"}, diff --git a/deps/npm/node_modules/json-schema/draft-00/schema b/deps/npm/node_modules/json-schema/draft-00/schema index d452b023ee484a..9aa2fbc57a4054 100644 --- a/deps/npm/node_modules/json-schema/draft-00/schema +++ b/deps/npm/node_modules/json-schema/draft-00/schema @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-00/hyper-schema#", "id" : "http://json-schema.org/draft-00/schema#", "type" : "object", - + "properties" : { "type" : { "type" : ["string", "array"], @@ -12,136 +12,136 @@ "optional" : true, "default" : "any" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "items" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "optional" : { "type" : "boolean", "optional" : true, "default" : false }, - + "additionalProperties" : { "type" : [{"$ref" : "#"}, "boolean"], "optional" : true, "default" : {} }, - + "requires" : { "type" : ["string", {"$ref" : "#"}], "optional" : true }, - + "minimum" : { "type" : "number", "optional" : true }, - + "maximum" : { "type" : "number", "optional" : true }, - + "minimumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "minimum", "default" : true }, - + "maximumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "maximum", "default" : true }, - + "minItems" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxItems" : { "type" : "integer", "optional" : true, "minimum" : 0 }, - + "pattern" : { "type" : "string", "optional" : true, "format" : "regex" }, - + "minLength" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxLength" : { "type" : "integer", "optional" : true }, - + "enum" : { "type" : "array", "optional" : true, "minItems" : 1 }, - + "title" : { "type" : "string", "optional" : true }, - + "description" : { "type" : "string", "optional" : true }, - + "format" : { "type" : "string", "optional" : true }, - + "contentEncoding" : { "type" : "string", "optional" : true }, - + "default" : { "type" : "any", "optional" : true }, - + "maxDecimal" : { "type" : "integer", "optional" : true, "minimum" : 0 }, - + "disallow" : { "type" : ["string", "array"], "items" : {"type" : "string"}, "optional" : true }, - + "extends" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, @@ -149,7 +149,7 @@ "default" : {} } }, - + "optional" : true, "default" : {} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-01/hyper-schema b/deps/npm/node_modules/json-schema/draft-01/hyper-schema index b0fb5e157ef9bd..3f6c6cc2c012df 100644 --- a/deps/npm/node_modules/json-schema/draft-01/hyper-schema +++ b/deps/npm/node_modules/json-schema/draft-01/hyper-schema @@ -8,61 +8,61 @@ "items" : {"$ref" : "http://json-schema.org/draft-01/links#"}, "optional" : true }, - + "fragmentResolution" : { "type" : "string", "optional" : true, "default" : "dot-delimited" }, - + "root" : { "type" : "boolean", "optional" : true, "default" : false }, - + "readonly" : { "type" : "boolean", "optional" : true, "default" : false }, - + "pathStart" : { "type" : "string", "optional" : true, "format" : "uri" }, - + "mediaType" : { "type" : "string", "optional" : true, "format" : "media-type" }, - + "alternate" : { "type" : "array", "items" : {"$ref" : "#"}, "optional" : true } }, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "dot-delimited", "extends" : {"$ref" : "http://json-schema.org/draft-01/schema#"} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-01/json-ref b/deps/npm/node_modules/json-schema/draft-01/json-ref index cbac1ba2e53286..4d26174ef17ad9 100644 --- a/deps/npm/node_modules/json-schema/draft-01/json-ref +++ b/deps/npm/node_modules/json-schema/draft-01/json-ref @@ -1,26 +1,26 @@ { "$schema" : "http://json-schema.org/draft-01/hyper-schema#", "id" : "http://json-schema.org/draft-01/json-ref#", - + "items" : {"$ref" : "#"}, "additionalProperties" : {"$ref" : "#"}, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "dot-delimited" } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-01/links b/deps/npm/node_modules/json-schema/draft-01/links index ebc7b7b58b1326..52430a5d94ac75 100644 --- a/deps/npm/node_modules/json-schema/draft-01/links +++ b/deps/npm/node_modules/json-schema/draft-01/links @@ -2,28 +2,28 @@ "$schema" : "http://json-schema.org/draft-01/hyper-schema#", "id" : "http://json-schema.org/draft-01/links#", "type" : "object", - + "properties" : { "href" : { "type" : "string" }, - + "rel" : { "type" : "string" }, - + "method" : { "type" : "string", "default" : "GET", "optional" : true }, - + "enctype" : { "type" : "string", "requires" : "method", "optional" : true }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "http://json-schema.org/draft-01/hyper-schema#"}, diff --git a/deps/npm/node_modules/json-schema/draft-01/schema b/deps/npm/node_modules/json-schema/draft-01/schema index a0f3801f840cca..7a208e680e631b 100644 --- a/deps/npm/node_modules/json-schema/draft-01/schema +++ b/deps/npm/node_modules/json-schema/draft-01/schema @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-01/hyper-schema#", "id" : "http://json-schema.org/draft-01/schema#", "type" : "object", - + "properties" : { "type" : { "type" : ["string", "array"], @@ -12,136 +12,136 @@ "optional" : true, "default" : "any" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "items" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "optional" : { "type" : "boolean", "optional" : true, "default" : false }, - + "additionalProperties" : { "type" : [{"$ref" : "#"}, "boolean"], "optional" : true, "default" : {} }, - + "requires" : { "type" : ["string", {"$ref" : "#"}], "optional" : true }, - + "minimum" : { "type" : "number", "optional" : true }, - + "maximum" : { "type" : "number", "optional" : true }, - + "minimumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "minimum", "default" : true }, - + "maximumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "maximum", "default" : true }, - + "minItems" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxItems" : { "type" : "integer", "optional" : true, "minimum" : 0 }, - + "pattern" : { "type" : "string", "optional" : true, "format" : "regex" }, - + "minLength" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxLength" : { "type" : "integer", "optional" : true }, - + "enum" : { "type" : "array", "optional" : true, "minItems" : 1 }, - + "title" : { "type" : "string", "optional" : true }, - + "description" : { "type" : "string", "optional" : true }, - + "format" : { "type" : "string", "optional" : true }, - + "contentEncoding" : { "type" : "string", "optional" : true }, - + "default" : { "type" : "any", "optional" : true }, - + "maxDecimal" : { "type" : "integer", "optional" : true, "minimum" : 0 }, - + "disallow" : { "type" : ["string", "array"], "items" : {"type" : "string"}, "optional" : true }, - + "extends" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, @@ -149,7 +149,7 @@ "default" : {} } }, - + "optional" : true, "default" : {} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-02/hyper-schema b/deps/npm/node_modules/json-schema/draft-02/hyper-schema index 0771e2b31e8eef..4ec1b7569137c3 100644 --- a/deps/npm/node_modules/json-schema/draft-02/hyper-schema +++ b/deps/npm/node_modules/json-schema/draft-02/hyper-schema @@ -8,61 +8,61 @@ "items" : {"$ref" : "http://json-schema.org/draft-02/links#"}, "optional" : true }, - + "fragmentResolution" : { "type" : "string", "optional" : true, "default" : "slash-delimited" }, - + "root" : { "type" : "boolean", "optional" : true, "default" : false }, - + "readonly" : { "type" : "boolean", "optional" : true, "default" : false }, - + "pathStart" : { "type" : "string", "optional" : true, "format" : "uri" }, - + "mediaType" : { "type" : "string", "optional" : true, "format" : "media-type" }, - + "alternate" : { "type" : "array", "items" : {"$ref" : "#"}, "optional" : true } }, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "slash-delimited", "extends" : {"$ref" : "http://json-schema.org/draft-02/schema#"} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-02/json-ref b/deps/npm/node_modules/json-schema/draft-02/json-ref index 1a6c56d04b665a..6526c394556665 100644 --- a/deps/npm/node_modules/json-schema/draft-02/json-ref +++ b/deps/npm/node_modules/json-schema/draft-02/json-ref @@ -1,26 +1,26 @@ { "$schema" : "http://json-schema.org/draft-02/hyper-schema#", "id" : "http://json-schema.org/draft-02/json-ref#", - + "items" : {"$ref" : "#"}, "additionalProperties" : {"$ref" : "#"}, - + "links" : [ { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" }, - + { "href" : "{id}", "rel" : "self" } ], - + "fragmentResolution" : "dot-delimited" } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-02/links b/deps/npm/node_modules/json-schema/draft-02/links index dacc53a1a4adb6..1b176178a2c333 100644 --- a/deps/npm/node_modules/json-schema/draft-02/links +++ b/deps/npm/node_modules/json-schema/draft-02/links @@ -2,30 +2,30 @@ "$schema" : "http://json-schema.org/draft-02/hyper-schema#", "id" : "http://json-schema.org/draft-02/links#", "type" : "object", - + "properties" : { "href" : { "type" : "string" }, - + "rel" : { "type" : "string" }, - + "targetSchema" : {"$ref" : "http://json-schema.org/draft-02/hyper-schema#"}, - + "method" : { "type" : "string", "default" : "GET", "optional" : true }, - + "enctype" : { "type" : "string", "requires" : "method", "optional" : true }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "http://json-schema.org/draft-02/hyper-schema#"}, diff --git a/deps/npm/node_modules/json-schema/draft-02/schema b/deps/npm/node_modules/json-schema/draft-02/schema index a4998abea2065e..61b8de15483962 100644 --- a/deps/npm/node_modules/json-schema/draft-02/schema +++ b/deps/npm/node_modules/json-schema/draft-02/schema @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-02/hyper-schema#", "id" : "http://json-schema.org/draft-02/schema#", "type" : "object", - + "properties" : { "type" : { "type" : ["string", "array"], @@ -13,131 +13,131 @@ "uniqueItems" : true, "default" : "any" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "items" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "optional" : true, "default" : {} }, - + "optional" : { "type" : "boolean", "optional" : true, "default" : false }, - + "additionalProperties" : { "type" : [{"$ref" : "#"}, "boolean"], "optional" : true, "default" : {} }, - + "requires" : { "type" : ["string", {"$ref" : "#"}], "optional" : true }, - + "minimum" : { "type" : "number", "optional" : true }, - + "maximum" : { "type" : "number", "optional" : true }, - + "minimumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "minimum", "default" : true }, - + "maximumCanEqual" : { "type" : "boolean", "optional" : true, "requires" : "maximum", "default" : true }, - + "minItems" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxItems" : { "type" : "integer", "optional" : true, "minimum" : 0 }, - + "uniqueItems" : { "type" : "boolean", "optional" : true, "default" : false }, - + "pattern" : { "type" : "string", "optional" : true, "format" : "regex" }, - + "minLength" : { "type" : "integer", "optional" : true, "minimum" : 0, "default" : 0 }, - + "maxLength" : { "type" : "integer", "optional" : true }, - + "enum" : { "type" : "array", "optional" : true, "minItems" : 1, "uniqueItems" : true }, - + "title" : { "type" : "string", "optional" : true }, - + "description" : { "type" : "string", "optional" : true }, - + "format" : { "type" : "string", "optional" : true }, - + "contentEncoding" : { "type" : "string", "optional" : true }, - + "default" : { "type" : "any", "optional" : true }, - + "divisibleBy" : { "type" : "number", "minimum" : 0, @@ -145,14 +145,14 @@ "optional" : true, "default" : 1 }, - + "disallow" : { "type" : ["string", "array"], "items" : {"type" : "string"}, "optional" : true, "uniqueItems" : true }, - + "extends" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, @@ -160,7 +160,7 @@ "default" : {} } }, - + "optional" : true, "default" : {} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-03/examples/calendar b/deps/npm/node_modules/json-schema/draft-03/examples/calendar index d8fb5335f081b4..463cfb314b6431 100644 --- a/deps/npm/node_modules/json-schema/draft-03/examples/calendar +++ b/deps/npm/node_modules/json-schema/draft-03/examples/calendar @@ -12,12 +12,12 @@ "type":"string", "required":true }, - "location" : { - "type" : "string" + "location" : { + "type" : "string" }, "url" : { - "type" : "string", - "format" : "url" + "type" : "string", + "format" : "url" }, "dtend" : { "format" : "date-time", @@ -47,3 +47,7 @@ "geo" : { "$ref" : "http://json-schema.org/draft-03/geo" } } } + + + + diff --git a/deps/npm/node_modules/json-schema/draft-03/examples/interfaces b/deps/npm/node_modules/json-schema/draft-03/examples/interfaces index 84ebf83a993f6d..288a19856b7263 100644 --- a/deps/npm/node_modules/json-schema/draft-03/examples/interfaces +++ b/deps/npm/node_modules/json-schema/draft-03/examples/interfaces @@ -6,18 +6,18 @@ "type":"object", "description":"This defines the set of methods available to the class instances", "additionalProperties":{ - "type":"object", - "description":"The definition of the method", - "properties":{ - "parameters":{ - "type":"array", - "description":"The set of parameters that should be passed to the method when it is called", - "items":{"$ref":"#"}, - "required": true - }, - "returns":{"$ref":"#"} - } + "type":"object", + "description":"The definition of the method", + "properties":{ + "parameters":{ + "type":"array", + "description":"The set of parameters that should be passed to the method when it is called", + "items":{"$ref":"#"}, + "required": true + }, + "returns":{"$ref":"#"} + } } - } + } } } diff --git a/deps/npm/node_modules/json-schema/draft-03/json-ref b/deps/npm/node_modules/json-schema/draft-03/json-ref index 388476323a08ab..7e491a8e882347 100644 --- a/deps/npm/node_modules/json-schema/draft-03/json-ref +++ b/deps/npm/node_modules/json-schema/draft-03/json-ref @@ -1,26 +1,26 @@ { "$schema" : "http://json-schema.org/draft-03/hyper-schema#", "id" : "http://json-schema.org/draft-03/json-ref#", - + "additionalItems" : {"$ref" : "#"}, "additionalProperties" : {"$ref" : "#"}, - + "links" : [ { "href" : "{id}", "rel" : "self" }, - + { "href" : "{$ref}", "rel" : "full" }, - + { "href" : "{$schema}", "rel" : "describedby" } ], - + "fragmentResolution" : "dot-delimited" } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-03/links b/deps/npm/node_modules/json-schema/draft-03/links index 3dbcdba73cc4e8..6b0a85a6295b25 100644 --- a/deps/npm/node_modules/json-schema/draft-03/links +++ b/deps/npm/node_modules/json-schema/draft-03/links @@ -2,31 +2,31 @@ "$schema" : "http://json-schema.org/draft-03/hyper-schema#", "id" : "http://json-schema.org/draft-03/links#", "type" : "object", - + "properties" : { "href" : { "type" : "string", "required" : true, "format" : "link-description-object-template" }, - + "rel" : { "type" : "string", "required" : true }, - + "targetSchema" : {"$ref" : "http://json-schema.org/draft-03/hyper-schema#"}, - + "method" : { "type" : "string", "default" : "GET" }, - + "enctype" : { "type" : "string", "requires" : "method" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "http://json-schema.org/draft-03/hyper-schema#"} diff --git a/deps/npm/node_modules/json-schema/draft-03/schema b/deps/npm/node_modules/json-schema/draft-03/schema index 361456d8a7e89e..55ae47d808c0ab 100644 --- a/deps/npm/node_modules/json-schema/draft-03/schema +++ b/deps/npm/node_modules/json-schema/draft-03/schema @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-03/schema#", "id" : "http://json-schema.org/draft-03/schema#", "type" : "object", - + "properties" : { "type" : { "type" : ["string", "array"], @@ -12,40 +12,40 @@ "uniqueItems" : true, "default" : "any" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "default" : {} }, - + "patternProperties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "default" : {} }, - + "additionalProperties" : { "type" : [{"$ref" : "#"}, "boolean"], "default" : {} }, - + "items" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "default" : {} }, - + "additionalItems" : { "type" : [{"$ref" : "#"}, "boolean"], "default" : {} }, - + "required" : { "type" : "boolean", "default" : false }, - + "dependencies" : { "type" : "object", "additionalProperties" : { @@ -56,85 +56,85 @@ }, "default" : {} }, - + "minimum" : { "type" : "number" }, - + "maximum" : { "type" : "number" }, - + "exclusiveMinimum" : { "type" : "boolean", "default" : false }, - + "exclusiveMaximum" : { "type" : "boolean", "default" : false }, - + "minItems" : { "type" : "integer", "minimum" : 0, "default" : 0 }, - + "maxItems" : { "type" : "integer", "minimum" : 0 }, - + "uniqueItems" : { "type" : "boolean", "default" : false }, - + "pattern" : { "type" : "string", "format" : "regex" }, - + "minLength" : { "type" : "integer", "minimum" : 0, "default" : 0 }, - + "maxLength" : { "type" : "integer" }, - + "enum" : { "type" : "array", "minItems" : 1, "uniqueItems" : true }, - + "default" : { "type" : "any" }, - + "title" : { "type" : "string" }, - + "description" : { "type" : "string" }, - + "format" : { "type" : "string" }, - + "divisibleBy" : { "type" : "number", "minimum" : 0, "exclusiveMinimum" : true, "default" : 1 }, - + "disallow" : { "type" : ["string", "array"], "items" : { @@ -142,33 +142,33 @@ }, "uniqueItems" : true }, - + "extends" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "default" : {} }, - + "id" : { "type" : "string", "format" : "uri" }, - + "$ref" : { "type" : "string", "format" : "uri" }, - + "$schema" : { "type" : "string", "format" : "uri" } }, - + "dependencies" : { "exclusiveMinimum" : "minimum", "exclusiveMaximum" : "maximum" }, - + "default" : {} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-04/links b/deps/npm/node_modules/json-schema/draft-04/links index 7cf7c92c20965c..de272cc4513d0a 100644 --- a/deps/npm/node_modules/json-schema/draft-04/links +++ b/deps/npm/node_modules/json-schema/draft-04/links @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-04/hyper-schema#", "id" : "http://json-schema.org/draft-04/links#", "type" : "object", - + "properties" : { "rel" : { "type" : "string" @@ -15,26 +15,26 @@ "template" : { "type" : "string" }, - + "targetSchema" : {"$ref" : "http://json-schema.org/draft-04/hyper-schema#"}, - + "method" : { "type" : "string", "default" : "GET" }, - + "enctype" : { "type" : "string" }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "http://json-schema.org/draft-04/hyper-schema#"} } }, - + "required" : ["rel", "href"], - + "dependencies" : { "enctype" : "method" } diff --git a/deps/npm/node_modules/json-schema/draft-04/schema b/deps/npm/node_modules/json-schema/draft-04/schema index e9c90699fda128..598951e57d2eb7 100644 --- a/deps/npm/node_modules/json-schema/draft-04/schema +++ b/deps/npm/node_modules/json-schema/draft-04/schema @@ -2,7 +2,7 @@ "$schema" : "http://json-schema.org/draft-04/schema#", "id" : "http://json-schema.org/draft-04/schema#", "type" : "object", - + "properties" : { "type" : { "type" : [ @@ -10,19 +10,19 @@ "id" : "#simple-type", "type" : "string", "enum" : ["object", "array", "string", "number", "boolean", "null", "any"] - }, + }, "array" ], "items" : { "type" : [ - {"$ref" : "#simple-type"}, + {"$ref" : "#simple-type"}, {"$ref" : "#"} ] }, "uniqueItems" : true, "default" : "any" }, - + "disallow" : { "type" : ["string", "array"], "items" : { @@ -30,7 +30,7 @@ }, "uniqueItems" : true }, - + "extends" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, @@ -42,108 +42,108 @@ "minItems" : 1, "uniqueItems" : true }, - + "minimum" : { "type" : "number" }, - + "maximum" : { "type" : "number" }, - + "exclusiveMinimum" : { "type" : "boolean", "default" : false }, - + "exclusiveMaximum" : { "type" : "boolean", "default" : false }, - + "divisibleBy" : { "type" : "number", "minimum" : 0, "exclusiveMinimum" : true, "default" : 1 }, - + "minLength" : { "type" : "integer", "minimum" : 0, "default" : 0 }, - + "maxLength" : { "type" : "integer" }, - + "pattern" : { "type" : "string" }, - + "items" : { "type" : [{"$ref" : "#"}, "array"], "items" : {"$ref" : "#"}, "default" : {} }, - + "additionalItems" : { "type" : [{"$ref" : "#"}, "boolean"], "default" : {} }, - + "minItems" : { "type" : "integer", "minimum" : 0, "default" : 0 }, - + "maxItems" : { "type" : "integer", "minimum" : 0 }, - + "uniqueItems" : { "type" : "boolean", "default" : false }, - + "properties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "default" : {} }, - + "patternProperties" : { "type" : "object", "additionalProperties" : {"$ref" : "#"}, "default" : {} }, - + "additionalProperties" : { "type" : [{"$ref" : "#"}, "boolean"], "default" : {} }, - + "minProperties" : { "type" : "integer", "minimum" : 0, "default" : 0 }, - + "maxProperties" : { "type" : "integer", "minimum" : 0 }, - + "required" : { "type" : "array", "items" : { "type" : "string" } }, - + "dependencies" : { "type" : "object", "additionalProperties" : { @@ -154,36 +154,36 @@ }, "default" : {} }, - + "id" : { "type" : "string" }, - + "$ref" : { "type" : "string" }, - + "$schema" : { "type" : "string" }, - + "title" : { "type" : "string" }, - + "description" : { "type" : "string" }, - + "default" : { "type" : "any" } }, - + "dependencies" : { "exclusiveMinimum" : "minimum", "exclusiveMaximum" : "maximum" }, - + "default" : {} } \ No newline at end of file diff --git a/deps/npm/node_modules/json-schema/draft-zyp-json-schema-03.xml b/deps/npm/node_modules/json-schema/draft-zyp-json-schema-03.xml index 1cf715910b5a83..c28f40dcd6ee44 100644 --- a/deps/npm/node_modules/json-schema/draft-zyp-json-schema-03.xml +++ b/deps/npm/node_modules/json-schema/draft-zyp-json-schema-03.xml @@ -24,7 +24,7 @@ A JSON Media Type for Describing the Structure and Meaning of JSON Documents - + SitePen (USA)
    @@ -37,7 +37,7 @@ kris@sitepen.com
    - +
    @@ -48,7 +48,7 @@ gary.court@gmail.com
    - + Internet Engineering Task Force JSON @@ -58,59 +58,59 @@ Notation Hyper Schema Hypermedia - + - JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", - a JSON based format for defining - the structure of JSON data. JSON Schema provides a contract for what JSON - data is required for a given application and how to interact with it. JSON - Schema is intended to define validation, documentation, hyperlink - navigation, and interaction control of JSON data. + JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", + a JSON based format for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data.
    - +
    - JSON (JavaScript Object Notation) Schema is a JSON media type for defining - the structure of JSON data. JSON Schema provides a contract for what JSON - data is required for a given application and how to interact with it. JSON - Schema is intended to define validation, documentation, hyperlink - navigation, and interaction control of JSON data. + JSON (JavaScript Object Notation) Schema is a JSON media type for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data.
    - +
    - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
    - + - +
    - JSON Schema defines the media type "application/schema+json" for + JSON Schema defines the media type "application/schema+json" for describing the structure of other - JSON documents. JSON Schema is JSON-based and includes facilities + JSON documents. JSON Schema is JSON-based and includes facilities for describing the structure of JSON documents in terms of allowable values, descriptions, and interpreting relations with other resources. - JSON Schema format is organized into several separate definitions. The first - definition is the core schema specification. This definition is primary + JSON Schema format is organized into several separate definitions. The first + definition is the core schema specification. This definition is primary concerned with describing a JSON structure and specifying valid elements in the structure. The second definition is the Hyper Schema specification which is intended define elements in a structure that can be interpreted as hyperlinks. - Hyper Schema builds on JSON Schema to describe the hyperlink structure of + Hyper Schema builds on JSON Schema to describe the hyperlink structure of other JSON documents and elements of interaction. This allows user agents to be able to successfully navigate JSON documents based on their schemas. @@ -118,12 +118,12 @@ Cumulatively JSON Schema acts as a meta-document that can be used to define the required type and constraints on property values, as well as define the meaning of the property values for the purpose of describing a resource and determining hyperlinks - within the representation. + within the representation.
    An example JSON Schema that describes products might look like: - - This schema defines the properties of the instance JSON documents, + This schema defines the properties of the instance JSON documents, the required properties (id, name, and price), as well as an optional property (tags). This also defines the link relations of the instance JSON documents.
    - +
    - For this specification, schema will be used to denote a JSON Schema - definition, and an instance refers to a JSON value that the schema + For this specification, schema will be used to denote a JSON Schema + definition, and an instance refers to a JSON value that the schema will be describing and validating.
    - +
    The JSON Schema media type does not attempt to dictate the structure of JSON @@ -194,7 +194,7 @@ This specification is protocol agnostic. The underlying protocol (such as HTTP) should sufficiently define the semantics of the client-server interface, the retrieval of resource - representations linked to by JSON representations, and modification of + representations linked to by JSON representations, and modification of those resources. The goal of this format is to sufficiently describe JSON structures such that one can utilize existing information available in existing JSON @@ -203,7 +203,7 @@
    - +
    JSON Schema instances are correlated to their schema by the "describedby" @@ -217,22 +217,22 @@ representation and messages may retain the self-descriptive characteristic, avoiding the need for out-of-band information about instance data. Two approaches are recommended for declaring the - relation to the schema that describes the meaning of a JSON instance's (or collection + relation to the schema that describes the meaning of a JSON instance's (or collection of instances) structure. A MIME type parameter named "profile" or a relation of "describedby" (which could be defined by a Link header) may be used: - +
    -
    - + or if the content is being transferred by a protocol (such as HTTP) that provides headers, a Link header can be used: - +
    ; rel="describedby" ]]>
    - - Instances MAY specify multiple schemas, to indicate all the schemas that - are applicable to the data, and the data SHOULD be valid by all the schemas. - The instance data MAY have multiple schemas - that it is defined by (the instance data SHOULD be valid for those schemas). - Or if the document is a collection of instances, the collection MAY contain - instances from different schemas. When collections contain heterogeneous - instances, the "pathStart" attribute MAY be specified in the - schema to disambiguate which schema should be applied for each item in the + + Instances MAY specify multiple schemas, to indicate all the schemas that + are applicable to the data, and the data SHOULD be valid by all the schemas. + The instance data MAY have multiple schemas + that it is defined by (the instance data SHOULD be valid for those schemas). + Or if the document is a collection of instances, the collection MAY contain + instances from different schemas. When collections contain heterogeneous + instances, the "pathStart" attribute MAY be specified in the + schema to disambiguate which schema should be applied for each item in the collection. However, ultimately, the mechanism for referencing a schema is up to the media type of the instance documents (if they choose to specify that schemas can be referenced).
    - +
    - JSON Schemas can themselves be described using JSON Schemas. + JSON Schemas can themselves be described using JSON Schemas. A self-describing JSON Schema for the core JSON Schema can - be found at http://json-schema.org/schema for the latest version or - http://json-schema.org/draft-03/schema for the draft-03 version. The hyper schema - self-description can be found at http://json-schema.org/hyper-schema + be found at http://json-schema.org/schema for the latest version or + http://json-schema.org/draft-03/schema for the draft-03 version. The hyper schema + self-description can be found at http://json-schema.org/hyper-schema or http://json-schema.org/draft-03/hyper-schema. All schemas used within a protocol with media type definitions SHOULD include a MIME parameter that refers to the self-descriptive hyper schema or another schema that extends this hyper schema: - +
    - @@ -277,15 +277,15 @@ Content-Type: application/json;
    - +
    - A JSON Schema is a JSON Object that defines various attributes + A JSON Schema is a JSON Object that defines various attributes (including usage and valid values) of a JSON value. JSON Schema has recursive capabilities; there are a number of elements in the structure that allow for nested JSON Schemas. - +
    An example JSON Schema definition could look like: @@ -307,15 +307,15 @@ Content-Type: application/json; ]]>
    - + A JSON Schema object may have any of the following properties, called schema attributes (all attributes are optional): - +
    - This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. + This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. This attribute can take one of two forms: @@ -332,19 +332,19 @@ Content-Type: application/json; Value MUST be null. Note this is mainly for purpose of being able use union types to define nullability. If this type is not included in a union, null values are not allowed (the primitives listed above do not allow nulls on their own). Value MAY be of any type including null. - - If the property is not defined or is not in this list, then any type of value is acceptable. - Other type values MAY be used for custom purposes, but minimal validators of the specification + + If the property is not defined or is not in this list, then any type of value is acceptable. + Other type values MAY be used for custom purposes, but minimal validators of the specification implementation can allow any instance value on unknown type values. - + An array of two or more simple type definitions. Each item in the array MUST be a simple type definition or a schema. - The instance value is valid if it is of the same type as one of the simple type definitions, or valid by one of the schemas, in the array. + The instance value is valid if it is of the same type as one of the simple type definitions, or valid by one of the schemas, in the array. - +
    For example, a schema that defines if an instance can be a string or a number would be: @@ -355,38 +355,38 @@ Content-Type: application/json; ]]>
    - +
    This attribute is an object with property definitions that define the valid values of instance object property values. When the instance value is an object, the property values of the instance object MUST conform to the property definitions in this object. In this object, each property definition's value MUST be a schema, and the property's name MUST be the name of the instance property that it defines. The instance property value MUST be valid according to the schema from the property definition. Properties are considered unordered, the order of the instance properties MAY be in any order.
    - +
    This attribute is an object that defines the schema for a set of property names of an object instance. The name of each property of this attribute's object is a regular expression pattern in the ECMA 262/Perl 5 format, while the value is a schema. If the pattern matches the name of a property on the instance object, the value of the instance's property MUST be valid against the pattern name's schema value.
    - +
    This attribute defines a schema for all properties that are not explicitly defined in an object type definition. If specified, the value MUST be a schema or a boolean. If false is provided, no additional properties are allowed beyond the properties defined in the schema. The default value is an empty schema which allows any value for additional properties.
    - +
    This attribute defines the allowed items in an instance array, and MUST be a schema or an array of schemas. The default value is an empty schema which allows any value for items in the instance array. When this attribute value is a schema and the instance value is an array, then all the items in the array MUST be valid according to the schema. When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST conform to the schema in the corresponding position for this array. This called tuple typing. When tuple typing is used, additional items are allowed, disallowed, or constrained by the "additionalItems" attribute using the same rules as "additionalProperties" for objects.
    - +
    This provides a definition for additional items in an array instance when tuple definitions of the items is provided. This can be false to indicate additional items in the array are not allowed, or it can be a schema that defines the schema of the additional items.
    - +
    This attribute indicates if the instance must have a value, and not be undefined. This is false by default, making the instance optional.
    - +
    This attribute is an object that defines the requirements of a property on an instance object. If an object instance has a property with the same name as a property in this attribute's object, then the instance must be valid against the attribute's property value (hereafter referred to as the "dependency value"). The dependency value can take one of two forms: - + If the dependency value is a string, then the instance object MUST have a property with the same name as the dependency value. @@ -398,36 +398,36 @@ Content-Type: application/json;
    - +
    This attribute defines the minimum value of the instance property when the type of the instance value is a number.
    - +
    This attribute defines the maximum value of the instance property when the type of the instance value is a number.
    - +
    This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "minimum" attribute. This is false by default, meaning the instance value can be greater then or equal to the minimum value.
    - +
    This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "maximum" attribute. This is false by default, meaning the instance value can be less then or equal to the maximum value.
    - +
    This attribute defines the minimum number of values in an array when the array is the instance value.
    - +
    This attribute defines the maximum number of values in an array when the array is the instance value.
    - +
    This attribute indicates that all items in an array instance MUST be unique (contains no two identical values). Two instance are consider equal if they are both of the same type and: - + are null; or are booleans/numbers/strings and have the same value; or @@ -436,41 +436,41 @@ Content-Type: application/json;
    - +
    When the instance value is a string, this provides a regular expression that a string instance MUST match in order to be valid. Regular expressions SHOULD follow the regular expression specification from ECMA 262/Perl 5
    - +
    When the instance value is a string, this defines the minimum length of the string.
    - +
    When the instance value is a string, this defines the maximum length of the string.
    - +
    This provides an enumeration of all possible values that are valid for the instance property. This MUST be an array, and each item in the array represents a possible value for the instance value. If this attribute is defined, the instance value MUST be one of the values in the array in order for the schema to be valid. Comparison of enum values uses the same algorithm as defined in "uniqueItems".
    - +
    This attribute defines the default value of the instance when the instance is undefined.
    - +
    This attribute is a string that provides a short description of the instance property.
    - +
    This attribute is a string that provides a full description of the of purpose the instance property.
    - +
    This property defines the type of data, content type, or microformat to be expected in the instance property values. A format attribute MAY be one of the values listed below, and if so, SHOULD adhere to the semantics describing for the format. A format SHOULD only be used to give meaning to primitive types (string, integer, number, or boolean). Validators MAY (but are not required to) validate that the instance values conform to a format. - + The following formats are predefined: - + This SHOULD be a date in ISO 8601 format of YYYY-MM-DDThh:mm:ssZ in UTC time. This is the recommended form of date/timestamp. This SHOULD be a date in the format of YYYY-MM-DD. It is recommended that you use the "date-time" format instead of "date" unless you need to transfer only the date part. @@ -487,18 +487,18 @@ Content-Type: application/json; This SHOULD be a host-name. - + Additional custom formats MAY be created. These custom formats MAY be expressed as an URI, and this URI MAY reference a schema of that format.
    - +
    This attribute defines what value the number instance must be divisible by with no remainder (the result of the division must be an integer.) The value of this attribute SHOULD NOT be 0.
    - +
    This attribute takes the same values as the "type" attribute, however if the instance matches the type or if this value is an array and the instance matches any type or schema in the array, then this instance is not valid.
    - +
    The value of this property MUST be another schema which will provide a base schema which the current schema will inherit from. The inheritance rules are such that any instance that is valid according to the current schema MUST be valid according to the referenced schema. This MAY also be an array, in which case, the instance MUST be valid for all the schemas in the array. A schema that extends another schema MAY define additional attributes, constrain existing attributes, or add other constraints. @@ -506,7 +506,7 @@ Content-Type: application/json; instance against all constraints in the extending schema as well as the extended schema(s). More optimized implementations that merge schemas are possible, but are not required. Some examples of using "extends": - +
    - +
    - +
    This attribute defines the current URI of this schema (this attribute is @@ -553,28 +553,28 @@ Content-Type: application/json; is also used to construct relative references such as for $ref.
    - +
    - This attribute defines a URI of a schema that contains the full representation of this schema. - When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. + This attribute defines a URI of a schema that contains the full representation of this schema. + When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. This URI MAY be relative or absolute, and relative URIs SHOULD be resolved against the URI of the current schema.
    - +
    - This attribute defines a URI of a JSON Schema that is the schema of the current schema. + This attribute defines a URI of a JSON Schema that is the schema of the current schema. When this attribute is defined, a validator SHOULD use the schema referenced by the value's URI (if known and available) when resolving Hyper Schemalinks. - + - A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. + A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. Therefore, it is RECOMMENDED that all schema authors include this attribute in their schemas to prevent conflicts with future JSON Schema specification changes.
    - +
    The following attributes are specified in addition to those @@ -586,28 +586,28 @@ Content-Type: application/json; essentially describes plain JSON (no constraints on the structures). Addition of attributes provides additive information for user agents. - +
    - The value of the links property MUST be an array, where each item + The value of the links property MUST be an array, where each item in the array is a link description object which describes the link relations of the instances. - +
    - A link description object is used to describe link relations. In - the context of a schema, it defines the link relations of the + A link description object is used to describe link relations. In + the context of a schema, it defines the link relations of the instances of the schema, and can be parameterized by the instance values. The link description format can be used on its own in regular (non-schema documents), and use of this format can be declared by referencing the normative link description - schema as the the schema for the data structure that uses the - links. The URI of the normative link description schema is: + schema as the the schema for the data structure that uses the + links. The URI of the normative link description schema is: http://json-schema.org/links (latest version) or http://json-schema.org/draft-03/links (draft-03 version). - +
    The value of the "href" link description property @@ -615,19 +615,19 @@ Content-Type: application/json; of the instance property SHOULD be resolved as a URI-Reference per RFC 3986 and MAY be a relative URI. The base URI to be used for relative resolution SHOULD be the URI used to retrieve the instance object (not the schema) - when used within a schema. Also, when links are used within a schema, the URI - SHOULD be parametrized by the property values of the instance + when used within a schema. Also, when links are used within a schema, the URI + SHOULD be parametrized by the property values of the instance object, if property values exist for the corresponding variables in the template (otherwise they MAY be provided from alternate sources, like user input). - + Instance property values SHOULD be substituted into the URIs where matching braces ('{', '}') are found surrounding zero or more characters, creating an expanded URI. Instance property value substitutions are resolved by using the text between the braces to denote the property name - from the instance to get the value to substitute. - + from the instance to get the value to substitute. +
    For example, if an href value is defined: @@ -637,7 +637,7 @@ http://somesite.com/{id} Then it would be resolved by replace the value of the "id" property value from the instance object.
    - +
    If the value of the "id" property was "45", the expanded URI would be: @@ -646,23 +646,23 @@ http://somesite.com/45 ]]>
    - - If matching braces are found with the string "@" (no quotes) between the braces, then the + + If matching braces are found with the string "@" (no quotes) between the braces, then the actual instance value SHOULD be used to replace the braces, rather than a property value. - This should only be used in situations where the instance is a scalar (string, + This should only be used in situations where the instance is a scalar (string, boolean, or number), and not for objects or arrays.
    - +
    - The value of the "rel" property indicates the name of the + The value of the "rel" property indicates the name of the relation to the target resource. The relation to the target SHOULD be interpreted as specifically from the instance object that the schema (or sub-schema) applies to, not just the top level resource that contains the object within its hierarchy. If a resource JSON representation contains a sub object with a property interpreted as a link, that sub-object holds the relation with the target. A relation to target from the top level resource MUST be indicated with the schema describing the top level JSON representation. - + Relationship definitions SHOULD NOT be media type dependent, and users are encouraged to utilize existing accepted relation definitions, including those in existing relation registries (see RFC 4287). However, we define these relations here for clarity of normative interpretation within the context of JSON hyper schema defined relations: - + If the relation value is "self", when this property is encountered in @@ -670,15 +670,15 @@ http://somesite.com/45 treated as a full representation of the target resource identified by the specified URI. - + This indicates that the target of the link is the full representation for the instance object. The object that contains this link possibly may not be the full representation. - + This indicates the target of the link is the schema for the instance object. This MAY be used to specifically denote the schemas of objects within a JSON object hierarchy, facilitating polymorphic type data structures. - + This relation indicates that the target of the link SHOULD be treated as the root or the body of the representation for the @@ -688,7 +688,7 @@ http://somesite.com/45 - + The following relations are applicable for schemas (the schema as the "from" resource in the relation): @@ -697,7 +697,7 @@ http://somesite.com/45 This indicates a target to use for creating new instances of a schema. This link definition SHOULD be a submission link with a non-safe method (like POST). - +
    For example, if a schema is defined: @@ -718,7 +718,7 @@ http://somesite.com/45 ]]>
    - +
    And if a collection of instance resource's JSON representation was retrieved: @@ -742,37 +742,37 @@ GET /Resource/ The "children" collection would be located at "/Resource/?upId=thing".
    - +
    This property value is a schema that defines the expected structure of the JSON representation of the target of the link.
    - +
    - The following properties also apply to link definition objects, and - provide functionality analogous to HTML forms, in providing a + The following properties also apply to link definition objects, and + provide functionality analogous to HTML forms, in providing a means for submitting extra (often user supplied) information to send to a server. - +
    - This attribute defines which method can be used to access the target resource. - In an HTTP environment, this would be "GET" or "POST" (other HTTP methods - such as "PUT" and "DELETE" have semantics that are clearly implied by - accessed resources, and do not need to be defined here). + This attribute defines which method can be used to access the target resource. + In an HTTP environment, this would be "GET" or "POST" (other HTTP methods + such as "PUT" and "DELETE" have semantics that are clearly implied by + accessed resources, and do not need to be defined here). This defaults to "GET".
    - +
    If present, this property indicates a query media type format that the server - supports for querying or posting to the collection of instances at the target - resource. The query can be + supports for querying or posting to the collection of instances at the target + resource. The query can be suffixed to the target URI to query the collection with property-based constraints on the resources that SHOULD be returned from the server or used to post data to the resource (depending on the method). - +
    For example, with the following schema: @@ -793,7 +793,7 @@ GET /Resource/ This indicates that the client can query the server for instances that have a specific name.
    - +
    For example: @@ -803,23 +803,23 @@ GET /Resource/
    - If no enctype or method is specified, only the single URI specified by - the href property is defined. If the method is POST, "application/json" is + If no enctype or method is specified, only the single URI specified by + the href property is defined. If the method is POST, "application/json" is the default media type.
    - +
    This attribute contains a schema which defines the acceptable structure of the submitted - request (for a GET request, this schema would define the properties for the query string + request (for a GET request, this schema would define the properties for the query string and for a POST request, this would define the body).
    - +
    This property indicates the fragment resolution protocol to use for @@ -829,12 +829,12 @@ GET /Resource/ protocol is "slash-delimited", which is defined below. Other fragment resolution protocols MAY be used, but are not defined in this document. - + The fragment identifier is based on RFC 2396, Sec 5, and defines the mechanism for resolving references to entities within a document. - +
    With the slash-delimited fragment resolution protocol, the fragment @@ -852,15 +852,15 @@ GET /Resource/ item in array the array with the index defined by the next property reference token (which MUST be a number). The target is successively updated for each property reference token, until the entire fragment has - been traversed. + been traversed. - + - Property names SHOULD be URI-encoded. In particular, any "/" in a - property name MUST be encoded to avoid being interpreted as a property + Property names SHOULD be URI-encoded. In particular, any "/" in a + property name MUST be encoded to avoid being interpreted as a property delimiter. - +
    For example, for the following JSON representation: @@ -879,7 +879,7 @@ GET /Resource/ ]]>
    - +
    The following fragment identifiers would be resolved: @@ -889,10 +889,10 @@ fragment identifier resolution # self, the root of the resource itself #/foo the object referred to by the foo property #/foo/another%20prop the object referred to by the "another prop" - property of the object referred to by the + property of the object referred to by the "foo" property #/foo/another%20prop/baz the string referred to by the value of "baz" - property of the "another prop" property of + property of the "another prop" property of the object referred to by the "foo" property #/foo/anArray/0 the first object in the "anArray" array ]]> @@ -900,61 +900,61 @@ fragment identifier resolution
    - +
    - The dot-delimited fragment resolution protocol is the same as - slash-delimited fragment resolution protocol except that the "." character - (\x2E) is used as the delimiter between property names (instead of "/") and + The dot-delimited fragment resolution protocol is the same as + slash-delimited fragment resolution protocol except that the "." character + (\x2E) is used as the delimiter between property names (instead of "/") and the path does not need to start with a ".". For example, #.foo and #foo are a valid fragment identifiers for referencing the value of the foo propery.
    - +
    This attribute indicates that the instance property SHOULD NOT be changed. Attempts by a user agent to modify the value of this property are expected to be rejected by a server.
    - +
    If the instance property value is a string, this attribute defines that the string SHOULD be interpreted as binary data and decoded using the encoding named by this schema property. RFC 2045, Sec 6.1 lists the possible values for this property.
    - +
    - This attribute is a URI that defines what the instance's URI MUST start with in order to validate. - The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, + This attribute is a URI that defines what the instance's URI MUST start with in order to validate. + The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, and is relative to the instance's URI. - + - When multiple schemas have been referenced for an instance, the user agent - can determine if this schema is applicable for a particular instance by + When multiple schemas have been referenced for an instance, the user agent + can determine if this schema is applicable for a particular instance by determining if the URI of the instance begins with the the value of the "pathStart" - attribute. If the URI of the instance does not start with this URI, - or if another schema specifies a starting URI that is longer and also matches the - instance, this schema SHOULD NOT be applied to the instance. Any schema - that does not have a pathStart attribute SHOULD be considered applicable + attribute. If the URI of the instance does not start with this URI, + or if another schema specifies a starting URI that is longer and also matches the + instance, this schema SHOULD NOT be applied to the instance. Any schema + that does not have a pathStart attribute SHOULD be considered applicable to all the instances for which it is referenced.
    - +
    This attribute defines the media type of the instance representations that this schema is defining.
    - +
    - This specification is a sub-type of the JSON format, and - consequently the security considerations are generally the same as RFC 4627. + This specification is a sub-type of the JSON format, and + consequently the security considerations are generally the same as RFC 4627. However, an additional issue is that when link relation of "self" - is used to denote a full representation of an object, the user agent + is used to denote a full representation of an object, the user agent SHOULD NOT consider the representation to be the authoritative representation of the resource denoted by the target URI if the target URI is not - equivalent to or a sub-path of the the URI used to request the resource + equivalent to or a sub-path of the the URI used to request the resource representation which contains the target URI with the "self" link. - +
    For example, if a hyper schema was defined: @@ -968,7 +968,7 @@ fragment identifier resolution ]]>
    - +
    And a resource was requested from somesite.com: @@ -1005,22 +1005,22 @@ Content-Type: application/json; profile=/schema-for-this-data
    - +
    The proposed MIME media type for JSON Schema is "application/schema+json". Type name: application Subtype name: schema+json Required parameters: profile - The value of the profile parameter SHOULD be a URI (relative or absolute) that - refers to the schema used to define the structure of this structure (the + The value of the profile parameter SHOULD be a URI (relative or absolute) that + refers to the schema used to define the structure of this structure (the meta-schema). Normally the value would be http://json-schema.org/draft-03/hyper-schema, but it is allowable to use other schemas that extend the hyper schema's meta- schema. Optional parameters: pretty The value of the pretty parameter MAY be true or false to indicate if additional whitespace has been included to make the JSON representation easier to read. - +
    This registry is maintained by IANA per RFC 4287 and this specification adds @@ -1032,7 +1032,7 @@ Content-Type: application/json; profile=/schema-for-this-data
    - + @@ -1080,7 +1080,7 @@ Content-Type: application/json; profile=/schema-for-this-data Added "$ref" and "$schema" attributes. - + Replaced "maxDecimal" attribute with "divisibleBy" attribute. @@ -1090,13 +1090,13 @@ Content-Type: application/json; profile=/schema-for-this-data Added "targetSchema" attribute to link description object. - + Fixed category and updates from template. - + Initial draft. @@ -1105,7 +1105,7 @@ Content-Type: application/json; profile=/schema-for-this-data - +
    diff --git a/deps/npm/node_modules/json-schema/draft-zyp-json-schema-04.xml b/deps/npm/node_modules/json-schema/draft-zyp-json-schema-04.xml index 22fb3290df1472..f9c1ea5a0c00a2 100644 --- a/deps/npm/node_modules/json-schema/draft-zyp-json-schema-04.xml +++ b/deps/npm/node_modules/json-schema/draft-zyp-json-schema-04.xml @@ -23,7 +23,7 @@ A JSON Media Type for Describing the Structure and Meaning of JSON Documents - + SitePen (USA)
    @@ -36,7 +36,7 @@ kris@sitepen.com
    - +
    @@ -47,7 +47,7 @@ gary.court@gmail.com
    - + Internet Engineering Task Force JSON @@ -57,48 +57,48 @@ Notation Hyper Schema Hypermedia - + - JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", - a JSON based format for defining the structure of JSON data. JSON Schema provides a contract for what JSON - data is required for a given application and how to interact with it. JSON - Schema is intended to define validation, documentation, hyperlink - navigation, and interaction control of JSON data. + JSON (JavaScript Object Notation) Schema defines the media type "application/schema+json", + a JSON based format for defining the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data.
    - +
    - JSON (JavaScript Object Notation) Schema is a JSON media type for defining - the structure of JSON data. JSON Schema provides a contract for what JSON - data is required for a given application and how to interact with it. JSON - Schema is intended to define validation, documentation, hyperlink - navigation, and interaction control of JSON data. + JSON (JavaScript Object Notation) Schema is a JSON media type for defining + the structure of JSON data. JSON Schema provides a contract for what JSON + data is required for a given application and how to interact with it. JSON + Schema is intended to define validation, documentation, hyperlink + navigation, and interaction control of JSON data.
    - +
    - - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. - + - The terms "JSON", "JSON text", "JSON value", "member", "element", "object", - "array", "number", "string", "boolean", "true", "false", and "null" in this + The terms "JSON", "JSON text", "JSON value", "member", "element", "object", + "array", "number", "string", "boolean", "true", "false", and "null" in this document are to be interpreted as defined in RFC 4627. - + This specification also uses the following defined terms: - + A JSON Schema object. Equivalent to "JSON value" as defined in RFC 4627. @@ -108,35 +108,35 @@
    - +
    - JSON Schema defines the media type "application/schema+json" for - describing the structure of JSON text. JSON Schemas are also written in JSON and includes facilities + JSON Schema defines the media type "application/schema+json" for + describing the structure of JSON text. JSON Schemas are also written in JSON and includes facilities for describing the structure of JSON in terms of allowable values, descriptions, and interpreting relations with other resources. - This document is organized into several separate definitions. The first - definition is the core schema specification. This definition is primary + This document is organized into several separate definitions. The first + definition is the core schema specification. This definition is primary concerned with describing a JSON structure and specifying valid elements in the structure. The second definition is the Hyper Schema specification which is intended to define elements in a structure that can be interpreted as hyperlinks. - Hyper Schema builds on JSON Schema to describe the hyperlink structure of + Hyper Schema builds on JSON Schema to describe the hyperlink structure of JSON values. This allows user agents to be able to successfully navigate documents containing JSON based on their schemas. - Cumulatively JSON Schema acts as meta-JSON that can be used to define the + Cumulatively JSON Schema acts as meta-JSON that can be used to define the required type and constraints on JSON values, as well as define the meaning of the JSON values for the purpose of describing a resource and determining - hyperlinks within the representation. + hyperlinks within the representation.
    An example JSON Schema that describes products might look like: - - This schema defines the properties of the instance, + This schema defines the properties of the instance, the required properties (id, name, and price), as well as an optional property (tags). This also defines the link relations of the instance.
    - +
    The JSON Schema media type does not attempt to dictate the structure of JSON @@ -195,7 +195,7 @@ This specification is protocol agnostic. The underlying protocol (such as HTTP) should sufficiently define the semantics of the client-server interface, the retrieval of resource - representations linked to by JSON representations, and modification of + representations linked to by JSON representations, and modification of those resources. The goal of this format is to sufficiently describe JSON structures such that one can utilize existing information available in existing JSON @@ -204,35 +204,35 @@
    - +
    JSON values are correlated to their schema by the "describedby" relation, where the schema is the target of the relation. JSON values MUST be of the "application/json" media type or - any other subtype. Consequently, dictating how a JSON value should + any other subtype. Consequently, dictating how a JSON value should specify the relation to the schema is beyond the normative scope of this document since this document specifically defines the JSON Schema media type, and no other. It is RECOMMNENDED that JSON values specify their schema so that user agents can interpret the instance and retain the self-descriptive characteristics. This avoides the need for out-of-band information about instance data. Two approaches are recommended for declaring the - relation to the schema that describes the meaning of a JSON instance's (or collection + relation to the schema that describes the meaning of a JSON instance's (or collection of instances) structure. A MIME type parameter named "profile" or a relation of "describedby" (which could be specified by a Link header) may be used: - +
    -
    - + or if the content is being transferred by a protocol (such as HTTP) that provides headers, a Link header can be used: - +
    ; rel="describedby" ]]>
    - - Instances MAY specify multiple schemas, to indicate all the schemas that - are applicable to the data, and the data SHOULD be valid by all the schemas. - The instance data MAY have multiple schemas - that it is described by (the instance data SHOULD be valid for those schemas). - Or if the document is a collection of instances, the collection MAY contain - instances from different schemas. The mechanism for referencing a schema is - determined by the media type of the instance (if it provides a method for + + Instances MAY specify multiple schemas, to indicate all the schemas that + are applicable to the data, and the data SHOULD be valid by all the schemas. + The instance data MAY have multiple schemas + that it is described by (the instance data SHOULD be valid for those schemas). + Or if the document is a collection of instances, the collection MAY contain + instances from different schemas. The mechanism for referencing a schema is + determined by the media type of the instance (if it provides a method for referencing schemas).
    - +
    - JSON Schemas can themselves be described using JSON Schemas. + JSON Schemas can themselves be described using JSON Schemas. A self-describing JSON Schema for the core JSON Schema can - be found at http://json-schema.org/schema for the latest version or - http://json-schema.org/draft-04/schema for the draft-04 version. The hyper schema - self-description can be found at http://json-schema.org/hyper-schema + be found at http://json-schema.org/schema for the latest version or + http://json-schema.org/draft-04/schema for the draft-04 version. The hyper schema + self-description can be found at http://json-schema.org/hyper-schema or http://json-schema.org/draft-04/hyper-schema. All schemas used within a protocol with a media type specified SHOULD include a MIME parameter that refers to the self-descriptive hyper schema or another schema that extends this hyper schema: - +
    - @@ -273,15 +273,15 @@ Content-Type: application/json;
    - +
    - A JSON Schema is a JSON object that defines various attributes + A JSON Schema is a JSON object that defines various attributes (including usage and valid values) of a JSON value. JSON Schema has recursive capabilities; there are a number of elements in the structure that allow for nested JSON Schemas. - +
    An example JSON Schema could look like: @@ -305,17 +305,17 @@ Content-Type: application/json; ]]>
    - + A JSON Schema object MAY have any of the following optional properties: - + - +
    - This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. + This attribute defines what the primitive type or the schema of the instance MUST be in order to validate. This attribute can take one of two forms: @@ -332,16 +332,16 @@ Content-Type: application/json; Instance MAY be of any type, including null. - + An array of one or more simple or schema types. - The instance value is valid if it is of the same type as one of the simple types, or valid by one of the schemas, in the array. + The instance value is valid if it is of the same type as one of the simple types, or valid by one of the schemas, in the array. - - If this attribute is not specified, then all value types are accepted. + + If this attribute is not specified, then all value types are accepted. - +
    For example, a schema that defines if an instance can be a string or a number would be: @@ -352,37 +352,37 @@ Content-Type: application/json; ]]>
    - +
    This attribute is an object with properties that specify the schemas for the properties of the instance object. - In this attribute's object, each property value MUST be a schema. + In this attribute's object, each property value MUST be a schema. When the instance value is an object, the value of the instance's properties MUST be valid according to the schemas with the same property names specified in this attribute. Objects are unordered, so therefore the order of the instance properties or attribute properties MUST NOT determine validation success.
    - +
    - This attribute is an object that defines the schema for a set of property names of an object instance. - The name of each property of this attribute's object is a regular expression pattern in the ECMA 262/Perl 5 format, while the value is a schema. + This attribute is an object that defines the schema for a set of property names of an object instance. + The name of each property of this attribute's object is a regular expression pattern in the ECMA 262/Perl 5 format, while the value is a schema. If the pattern matches the name of a property on the instance object, the value of the instance's property MUST be valid against the pattern name's schema value.
    - +
    - This attribute specifies how any instance property that is not explicitly defined by either the "properties" or "patternProperties" attributes (hereafter referred to as "additional properties") is handled. If specified, the value MUST be a schema or a boolean. + This attribute specifies how any instance property that is not explicitly defined by either the "properties" or "patternProperties" attributes (hereafter referred to as "additional properties") is handled. If specified, the value MUST be a schema or a boolean. If a schema is provided, then all additional properties MUST be valid according to the schema. If false is provided, then no additional properties are allowed. The default value is an empty schema, which allows any value for additional properties.
    - +
    This attribute provides the allowed items in an array instance. If specified, this attribute MUST be a schema or an array of schemas. When this attribute value is a schema and the instance value is an array, then all the items in the array MUST be valid according to the schema. When this attribute value is an array of schemas and the instance value is an array, each position in the instance array MUST be valid according to the schema in the corresponding position for this array. This called tuple typing. When tuple typing is used, additional items are allowed, disallowed, or constrained by the "additionalItems" attribute the same way as "additionalProperties" for objects is.
    - +
    This attribute specifies how any item in the array instance that is not explicitly defined by "items" (hereafter referred to as "additional items") is handled. If specified, the value MUST be a schema or a boolean. If a schema is provided: @@ -395,16 +395,16 @@ Content-Type: application/json; If false is provided, then any additional items in the array are not allowed. The default value is an empty schema, which allows any value for additional items.
    - +
    This attribute is an array of strings that defines all the property names that must exist on the object instance.
    - +
    This attribute is an object that specifies the requirements of a property on an object instance. If an object instance has a property with the same name as a property in this attribute's object, then the instance must be valid against the attribute's property value (hereafter referred to as the "dependency value"). The dependency value can take one of two forms: - + If the dependency value is a string, then the instance object MUST have a property with the same name as the dependency value. @@ -416,44 +416,44 @@ Content-Type: application/json;
    - +
    This attribute defines the minimum value of the instance property when the type of the instance value is a number.
    - +
    This attribute defines the maximum value of the instance property when the type of the instance value is a number.
    - +
    This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "minimum" attribute. This is false by default, meaning the instance value can be greater then or equal to the minimum value.
    - +
    This attribute indicates if the value of the instance (if the instance is a number) can not equal the number defined by the "maximum" attribute. This is false by default, meaning the instance value can be less then or equal to the maximum value.
    - +
    This attribute defines the minimum number of values in an array when the array is the instance value.
    - +
    This attribute defines the maximum number of values in an array when the array is the instance value.
    - +
    This attribute defines the minimum number of properties required on an object instance.
    - +
    This attribute defines the maximum number of properties the object instance can have.
    - +
    This attribute indicates that all items in an array instance MUST be unique (contains no two identical values). Two instance are consider equal if they are both of the same type and: - + are null; or are booleans/numbers/strings and have the same value; or @@ -462,43 +462,43 @@ Content-Type: application/json;
    - +
    When the instance value is a string, this provides a regular expression that a string instance MUST match in order to be valid. Regular expressions SHOULD follow the regular expression specification from ECMA 262/Perl 5
    - +
    When the instance value is a string, this defines the minimum length of the string.
    - +
    When the instance value is a string, this defines the maximum length of the string.
    - +
    This provides an enumeration of all possible values that are valid for the instance property. This MUST be an array, and each item in the array represents a possible value for the instance value. If this attribute is defined, the instance value MUST be one of the values in the array in order for the schema to be valid. Comparison of enum values uses the same algorithm as defined in "uniqueItems".
    - +
    This attribute defines the default value of the instance when the instance is undefined.
    - +
    This attribute is a string that provides a short description of the instance property.
    - +
    This attribute is a string that provides a full description of the of purpose the instance property.
    - +
    This attribute defines what value the number instance must be divisible by with no remainder (the result of the division must be an integer.) The value of this attribute SHOULD NOT be 0.
    - +
    This attribute takes the same values as the "type" attribute, however if the instance matches the type or if this value is an array and the instance matches any type or schema in the array, then this instance is not valid.
    - +
    The value of this property MUST be another schema which will provide a base schema which the current schema will inherit from. The inheritance rules are such that any instance that is valid according to the current schema MUST be valid according to the referenced schema. This MAY also be an array, in which case, the instance MUST be valid for all the schemas in the array. A schema that extends another schema MAY define additional attributes, constrain existing attributes, or add other constraints. @@ -506,7 +506,7 @@ Content-Type: application/json; instance against all constraints in the extending schema as well as the extended schema(s). More optimized implementations that merge schemas are possible, but are not required. Some examples of using "extends": - +
    - +
    - +
    This attribute defines the current URI of this schema (this attribute is @@ -553,28 +553,28 @@ Content-Type: application/json; is also used to construct relative references such as for $ref.
    - +
    - This attribute defines a URI of a schema that contains the full representation of this schema. - When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. + This attribute defines a URI of a schema that contains the full representation of this schema. + When a validator encounters this attribute, it SHOULD replace the current schema with the schema referenced by the value's URI (if known and available) and re-validate the instance. This URI MAY be relative or absolute, and relative URIs SHOULD be resolved against the URI of the current schema.
    - +
    - This attribute defines a URI of a JSON Schema that is the schema of the current schema. + This attribute defines a URI of a JSON Schema that is the schema of the current schema. When this attribute is defined, a validator SHOULD use the schema referenced by the value's URI (if known and available) when resolving Hyper Schemalinks. - + - A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. + A validator MAY use this attribute's value to determine which version of JSON Schema the current schema is written in, and provide the appropriate validation features and behavior. Therefore, it is RECOMMENDED that all schema authors include this attribute in their schemas to prevent conflicts with future JSON Schema specification changes.
    - +
    The following attributes are specified in addition to those @@ -586,30 +586,30 @@ Content-Type: application/json; essentially describes plain JSON (no constraints on the structures). Addition of attributes provides additive information for user agents. - +
    - The value of the links property MUST be an array, where each item + The value of the links property MUST be an array, where each item in the array is a link description object which describes the link relations of the instances. - + - +
    - A link description object is used to describe link relations. In - the context of a schema, it defines the link relations of the + A link description object is used to describe link relations. In + the context of a schema, it defines the link relations of the instances of the schema, and can be parameterized by the instance - values. The link description format can be used without JSON Schema, + values. The link description format can be used without JSON Schema, and use of this format can be declared by referencing the normative link description - schema as the the schema for the data structure that uses the - links. The URI of the normative link description schema is: + schema as the the schema for the data structure that uses the + links. The URI of the normative link description schema is: http://json-schema.org/links (latest version) or http://json-schema.org/draft-04/links (draft-04 version). - +
    The value of the "href" link description property @@ -617,19 +617,19 @@ Content-Type: application/json; of the instance property SHOULD be resolved as a URI-Reference per RFC 3986 and MAY be a relative URI. The base URI to be used for relative resolution SHOULD be the URI used to retrieve the instance object (not the schema) - when used within a schema. Also, when links are used within a schema, the URI - SHOULD be parametrized by the property values of the instance + when used within a schema. Also, when links are used within a schema, the URI + SHOULD be parametrized by the property values of the instance object, if property values exist for the corresponding variables in the template (otherwise they MAY be provided from alternate sources, like user input). - + Instance property values SHOULD be substituted into the URIs where matching braces ('{', '}') are found surrounding zero or more characters, creating an expanded URI. Instance property value substitutions are resolved by using the text between the braces to denote the property name - from the instance to get the value to substitute. - + from the instance to get the value to substitute. +
    For example, if an href value is defined: @@ -639,7 +639,7 @@ http://somesite.com/{id} Then it would be resolved by replace the value of the "id" property value from the instance object.
    - +
    If the value of the "id" property was "45", the expanded URI would be: @@ -648,23 +648,23 @@ http://somesite.com/45 ]]>
    - - If matching braces are found with the string "@" (no quotes) between the braces, then the + + If matching braces are found with the string "@" (no quotes) between the braces, then the actual instance value SHOULD be used to replace the braces, rather than a property value. - This should only be used in situations where the instance is a scalar (string, + This should only be used in situations where the instance is a scalar (string, boolean, or number), and not for objects or arrays.
    - +
    - The value of the "rel" property indicates the name of the + The value of the "rel" property indicates the name of the relation to the target resource. The relation to the target SHOULD be interpreted as specifically from the instance object that the schema (or sub-schema) applies to, not just the top level resource that contains the object within its hierarchy. If a resource JSON representation contains a sub object with a property interpreted as a link, that sub-object holds the relation with the target. A relation to target from the top level resource MUST be indicated with the schema describing the top level JSON representation. - + Relationship definitions SHOULD NOT be media type dependent, and users are encouraged to utilize existing accepted relation definitions, including those in existing relation registries (see RFC 4287). However, we define these relations here for clarity of normative interpretation within the context of JSON hyper schema defined relations: - + If the relation value is "self", when this property is encountered in @@ -672,15 +672,15 @@ http://somesite.com/45 treated as a full representation of the target resource identified by the specified URI. - + This indicates that the target of the link is the full representation for the instance object. The object that contains this link possibly may not be the full representation. - + This indicates the target of the link is the schema for the instance object. This MAY be used to specifically denote the schemas of objects within a JSON object hierarchy, facilitating polymorphic type data structures. - + This relation indicates that the target of the link SHOULD be treated as the root or the body of the representation for the @@ -690,7 +690,7 @@ http://somesite.com/45 - + The following relations are applicable for schemas (the schema as the "from" resource in the relation): @@ -699,7 +699,7 @@ http://somesite.com/45 This indicates a target to use for creating new instances of a schema. This link definition SHOULD be a submission link with a non-safe method (like POST). - +
    For example, if a schema is defined: @@ -720,7 +720,7 @@ http://somesite.com/45 ]]>
    - +
    And if a collection of instance resource's JSON representation was retrieved: @@ -744,41 +744,41 @@ GET /Resource/ The "children" collection would be located at "/Resource/?upId=thing".
    - +
    This property value is a string that defines the templating language used in the "href" attribute. If no templating language is defined, then the default Link Description Object templating langauge is used.
    - +
    This property value is a schema that defines the expected structure of the JSON representation of the target of the link.
    - +
    - The following properties also apply to link definition objects, and - provide functionality analogous to HTML forms, in providing a + The following properties also apply to link definition objects, and + provide functionality analogous to HTML forms, in providing a means for submitting extra (often user supplied) information to send to a server. - +
    - This attribute defines which method can be used to access the target resource. - In an HTTP environment, this would be "GET" or "POST" (other HTTP methods - such as "PUT" and "DELETE" have semantics that are clearly implied by - accessed resources, and do not need to be defined here). + This attribute defines which method can be used to access the target resource. + In an HTTP environment, this would be "GET" or "POST" (other HTTP methods + such as "PUT" and "DELETE" have semantics that are clearly implied by + accessed resources, and do not need to be defined here). This defaults to "GET".
    - +
    If present, this property indicates a query media type format that the server - supports for querying or posting to the collection of instances at the target - resource. The query can be + supports for querying or posting to the collection of instances at the target + resource. The query can be suffixed to the target URI to query the collection with property-based constraints on the resources that SHOULD be returned from the server or used to post data to the resource (depending on the method). - +
    For example, with the following schema: @@ -799,7 +799,7 @@ GET /Resource/ This indicates that the client can query the server for instances that have a specific name.
    - +
    For example: @@ -809,23 +809,23 @@ GET /Resource/
    - If no enctype or method is specified, only the single URI specified by - the href property is defined. If the method is POST, "application/json" is + If no enctype or method is specified, only the single URI specified by + the href property is defined. If the method is POST, "application/json" is the default media type.
    - +
    This attribute contains a schema which defines the acceptable structure of the submitted - request (for a GET request, this schema would define the properties for the query string + request (for a GET request, this schema would define the properties for the query string and for a POST request, this would define the body).
    - +
    This property indicates the fragment resolution protocol to use for @@ -835,62 +835,62 @@ GET /Resource/ protocol is "json-pointer", which is defined below. Other fragment resolution protocols MAY be used, but are not defined in this document. - + The fragment identifier is based on RFC 3986, Sec 5, and defines the mechanism for resolving references to entities within a document. - +
    The "json-pointer" fragment resolution protocol uses a JSON Pointer to resolve fragment identifiers in URIs within instance representations.
    - + - +
    This attribute indicates that the instance value SHOULD NOT be changed. Attempts by a user agent to modify the value of this property are expected to be rejected by a server.
    - +
    If the instance property value is a string, this attribute defines that the string SHOULD be interpreted as binary data and decoded using the encoding named by this schema property. RFC 2045, Sec 6.1 lists the possible values for this property.
    - +
    - This attribute is a URI that defines what the instance's URI MUST start with in order to validate. - The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, + This attribute is a URI that defines what the instance's URI MUST start with in order to validate. + The value of the "pathStart" attribute MUST be resolved as per RFC 3986, Sec 5, and is relative to the instance's URI. - + - When multiple schemas have been referenced for an instance, the user agent - can determine if this schema is applicable for a particular instance by + When multiple schemas have been referenced for an instance, the user agent + can determine if this schema is applicable for a particular instance by determining if the URI of the instance begins with the the value of the "pathStart" - attribute. If the URI of the instance does not start with this URI, - or if another schema specifies a starting URI that is longer and also matches the - instance, this schema SHOULD NOT be applied to the instance. Any schema - that does not have a pathStart attribute SHOULD be considered applicable + attribute. If the URI of the instance does not start with this URI, + or if another schema specifies a starting URI that is longer and also matches the + instance, this schema SHOULD NOT be applied to the instance. Any schema + that does not have a pathStart attribute SHOULD be considered applicable to all the instances for which it is referenced.
    - +
    This attribute defines the media type of the instance representations that this schema is defining.
    - +
    - This specification is a sub-type of the JSON format, and - consequently the security considerations are generally the same as RFC 4627. + This specification is a sub-type of the JSON format, and + consequently the security considerations are generally the same as RFC 4627. However, an additional issue is that when link relation of "self" - is used to denote a full representation of an object, the user agent + is used to denote a full representation of an object, the user agent SHOULD NOT consider the representation to be the authoritative representation of the resource denoted by the target URI if the target URI is not - equivalent to or a sub-path of the the URI used to request the resource + equivalent to or a sub-path of the the URI used to request the resource representation which contains the target URI with the "self" link. - +
    For example, if a hyper schema was defined: @@ -904,7 +904,7 @@ GET /Resource/ ]]>
    - +
    And a resource was requested from somesite.com: @@ -941,22 +941,22 @@ Content-Type: application/json; profile=/schema-for-this-data
    - +
    The proposed MIME media type for JSON Schema is "application/schema+json". Type name: application Subtype name: schema+json Required parameters: profile - The value of the profile parameter SHOULD be a URI (relative or absolute) that - refers to the schema used to define the structure of this structure (the + The value of the profile parameter SHOULD be a URI (relative or absolute) that + refers to the schema used to define the structure of this structure (the meta-schema). Normally the value would be http://json-schema.org/draft-04/hyper-schema, but it is allowable to use other schemas that extend the hyper schema's meta- schema. Optional parameters: pretty The value of the pretty parameter MAY be true or false to indicate if additional whitespace has been included to make the JSON representation easier to read. - +
    This registry is maintained by IANA per RFC 4287 and this specification adds @@ -968,7 +968,7 @@ Content-Type: application/json; profile=/schema-for-this-data
    - + @@ -1019,7 +1019,7 @@ Content-Type: application/json; profile=/schema-for-this-data Improved wording of many sections.
    - + Added example and verbiage to "extends" attribute. @@ -1043,7 +1043,7 @@ Content-Type: application/json; profile=/schema-for-this-data Added "$ref" and "$schema" attributes. - + Replaced "maxDecimal" attribute with "divisibleBy" attribute. @@ -1053,13 +1053,13 @@ Content-Type: application/json; profile=/schema-for-this-data Added "targetSchema" attribute to link description object. - + Fixed category and updates from template. - + Initial draft. diff --git a/deps/npm/node_modules/json-schema/lib/links.js b/deps/npm/node_modules/json-schema/lib/links.js index 2ef3f9fb7d0afe..2f450ff61d2976 100644 --- a/deps/npm/node_modules/json-schema/lib/links.js +++ b/deps/npm/node_modules/json-schema/lib/links.js @@ -1,4 +1,4 @@ -/** +/** * JSON Schema link handler * Copyright (c) 2007 Kris Zyp SitePen (www.sitepen.com) * Licensed under the MIT (MIT-LICENSE.txt) license. @@ -25,11 +25,11 @@ exports.getLink = function(relation, instance, schema){ // gets the URI of the link for the given relation based on the instance and schema // for example: // getLink( - // "brother", - // {"brother_id":33}, + // "brother", + // {"brother_id":33}, // {links:[{rel:"brother", href:"Brother/{brother_id}"}]}) -> // "Brother/33" - var links = schema.__linkTemplates; + var links = schema.__linkTemplates; if(!links){ links = {}; var schemaLinks = schema.links; diff --git a/deps/npm/node_modules/json-schema/lib/validate.js b/deps/npm/node_modules/json-schema/lib/validate.js index 4b6108800aafb5..4d0b537941e3cc 100644 --- a/deps/npm/node_modules/json-schema/lib/validate.js +++ b/deps/npm/node_modules/json-schema/lib/validate.js @@ -207,8 +207,8 @@ var validate = exports._validate = function(/*Any*/instance,/*Object*/schema,/*O if(typeof instance != 'object' || instance instanceof Array){ errors.push({property:path,message:"an object is required"}); } - - for(var i in objTypeDef){ + + for(var i in objTypeDef){ if(objTypeDef.hasOwnProperty(i)){ var value = instance[i]; // skip _not_ specified properties diff --git a/deps/npm/node_modules/json-stringify-safe/CHANGELOG.md b/deps/npm/node_modules/json-stringify-safe/CHANGELOG.md index c5147d77f6c943..42bcb60af47a50 100644 --- a/deps/npm/node_modules/json-stringify-safe/CHANGELOG.md +++ b/deps/npm/node_modules/json-stringify-safe/CHANGELOG.md @@ -1,8 +1,8 @@ ## Unreleased - Fixes stringify to only take ancestors into account when checking - circularity. + circularity. It previously assumed every visited object was circular which led to [false - positives][issue9]. + positives][issue9]. Uses the tiny serializer I wrote for [Must.js][must] a year and a half ago. - Fixes calling the `replacer` function in the proper context (`thisArg`). - Fixes calling the `cycleReplacer` function in the proper context (`thisArg`). diff --git a/deps/npm/node_modules/jsonparse/LICENSE b/deps/npm/node_modules/jsonparse/LICENSE index ed1e50c3d34b58..6dc24be5e5027a 100644 --- a/deps/npm/node_modules/jsonparse/LICENSE +++ b/deps/npm/node_modules/jsonparse/LICENSE @@ -2,23 +2,23 @@ The MIT License Copyright (c) 2012 Tim Caswell -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/jsonparse/README.markdown b/deps/npm/node_modules/jsonparse/README.markdown index c5425f8c3af964..0f405d359fe6cb 100644 --- a/deps/npm/node_modules/jsonparse/README.markdown +++ b/deps/npm/node_modules/jsonparse/README.markdown @@ -8,3 +8,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/jsonparse/test/surrogate.js b/deps/npm/node_modules/jsonparse/test/surrogate.js index 33351c73cc193b..c048f370660d2d 100644 --- a/deps/npm/node_modules/jsonparse/test/surrogate.js +++ b/deps/npm/node_modules/jsonparse/test/surrogate.js @@ -23,3 +23,4 @@ test('parse chunked surrogate pair', function (t) { p.write('"\\uD83D'); p.write('\\uDE0B"'); }); + diff --git a/deps/npm/node_modules/libnpx/libnpx.1 b/deps/npm/node_modules/libnpx/libnpx.1 index 8fb05f222df0f5..4215202da8e244 100644 --- a/deps/npm/node_modules/libnpx/libnpx.1 +++ b/deps/npm/node_modules/libnpx/libnpx.1 @@ -172,3 +172,4 @@ This work is released by its authors into the public domain under CC0\-1\.0\. Se \fBnpm\-config(7)\fP .RE + diff --git a/deps/npm/node_modules/libnpx/locales/nn.json b/deps/npm/node_modules/libnpx/locales/nn.json index 6eef4268fd2493..de23e798ef130a 100644 --- a/deps/npm/node_modules/libnpx/locales/nn.json +++ b/deps/npm/node_modules/libnpx/locales/nn.json @@ -27,3 +27,4 @@ "Suppress output from npx itself. Subcommands will not be affected.": "Skjul kommandoer frå npx. Sub-kommandoer vil ikkje rørast.", "Extra node argument when calling a node binary.": "Ekstra node-argument når ein node-binærfil blir kalt." } + \ No newline at end of file diff --git a/deps/npm/node_modules/lock-verify/LICENSE b/deps/npm/node_modules/lock-verify/LICENSE index e0040f6659d374..83e7c4c62903d7 100644 --- a/deps/npm/node_modules/lock-verify/LICENSE +++ b/deps/npm/node_modules/lock-verify/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/make-fetch-happen/CHANGELOG.md b/deps/npm/node_modules/make-fetch-happen/CHANGELOG.md index eb28e410f2b707..c73bd4de4fafce 100644 --- a/deps/npm/node_modules/make-fetch-happen/CHANGELOG.md +++ b/deps/npm/node_modules/make-fetch-happen/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +
    +## [5.0.2](https://github.com/zkat/make-fetch-happen/compare/v5.0.1...v5.0.2) (2019-11-14) + + +### Bug Fixes + +* **streams:** only provide a size and not a boolean to highWaterMark & update travis environments ([a367a14](https://github.com/zkat/make-fetch-happen/commit/a367a14)) +* `highWaterMark` bug @ v5 ([#10](https://github.com/zkat/make-fetch-happen/issues/10)) ([4e4f4e0](https://github.com/zkat/make-fetch-happen/commit/4e4f4e0)) + + + + +## [5.0.1](https://github.com/zkat/make-fetch-happen/compare/v5.0.0...v5.0.1) (2019-10-23) + + + # [5.0.0](https://github.com/zkat/make-fetch-happen/compare/v4.0.2...v5.0.0) (2019-07-15) diff --git a/deps/npm/node_modules/make-fetch-happen/cache.js b/deps/npm/node_modules/make-fetch-happen/cache.js index f842ba19da2e1f..f00de14a8844a8 100644 --- a/deps/npm/node_modules/make-fetch-happen/cache.js +++ b/deps/npm/node_modules/make-fetch-happen/cache.js @@ -169,7 +169,7 @@ module.exports = class Cache { cacheTargetStream ? cacheTargetStream.end(done) : done() }) const oldBody = response.body - const newBody = through({highWaterMark: fitInMemory && MAX_MEM_SIZE}) + const newBody = through({highWaterMark: MAX_MEM_SIZE}) response.body = newBody oldBody.once('error', err => newBody.emit('error', err)) newBody.once('error', err => oldBody.emit('error', err)) diff --git a/deps/npm/node_modules/make-fetch-happen/package.json b/deps/npm/node_modules/make-fetch-happen/package.json index d405b7b31fe576..a2c7397bc8c4f8 100644 --- a/deps/npm/node_modules/make-fetch-happen/package.json +++ b/deps/npm/node_modules/make-fetch-happen/package.json @@ -1,19 +1,19 @@ { - "_from": "make-fetch-happen@5.0.0", - "_id": "make-fetch-happen@5.0.0", + "_from": "make-fetch-happen@5.0.2", + "_id": "make-fetch-happen@5.0.2", "_inBundle": false, - "_integrity": "sha512-nFr/vpL1Jc60etMVKeaLOqfGjMMb3tAHFVJWxHOFCFS04Zmd7kGlMxo0l1tzfhoQje0/UPnd0X8OeGUiXXnfPA==", + "_integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==", "_location": "/make-fetch-happen", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "make-fetch-happen@5.0.0", + "raw": "make-fetch-happen@5.0.2", "name": "make-fetch-happen", "escapedName": "make-fetch-happen", - "rawSpec": "5.0.0", + "rawSpec": "5.0.2", "saveSpec": null, - "fetchSpec": "5.0.0" + "fetchSpec": "5.0.2" }, "_requiredBy": [ "#USER", @@ -21,10 +21,10 @@ "/npm-registry-fetch", "/pacote" ], - "_resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz", - "_shasum": "a8e3fe41d3415dd656fe7b8e8172e1fb4458b38d", - "_spec": "make-fetch-happen@5.0.0", - "_where": "/Users/isaacs/dev/npm/cli", + "_resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz", + "_shasum": "aa8387104f2687edca01c8687ee45013d02d19bd", + "_spec": "make-fetch-happen@5.0.2", + "_where": "/Users/claudiahdz/npm/cli", "author": { "name": "Kat Marchán", "email": "kzm@zkat.tech" @@ -38,7 +38,7 @@ "cacache": "^12.0.0", "http-cache-semantics": "^3.8.1", "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", + "https-proxy-agent": "^2.2.3", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "node-fetch-npm": "^2.0.2", @@ -85,7 +85,7 @@ "url": "git+https://github.com/zkat/make-fetch-happen.git" }, "scripts": { - "postrelease": "npm publish && git push --follow-tags", + "postrelease": "npm publish --tag=legacy && git push --follow-tags", "prerelease": "npm t", "pretest": "standard", "release": "standard-version -s", @@ -93,5 +93,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "5.0.0" + "version": "5.0.2" } diff --git a/deps/npm/node_modules/minimist/index.js b/deps/npm/node_modules/minimist/index.js index a5793ceccec488..584f551a6da734 100644 --- a/deps/npm/node_modules/minimist/index.js +++ b/deps/npm/node_modules/minimist/index.js @@ -1,16 +1,16 @@ module.exports = function (args, opts) { if (!opts) opts = {}; - + var flags = { bools : {}, strings : {} }; - + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { flags.bools[key] = true; }); - + [].concat(opts.string).filter(Boolean).forEach(function (key) { flags.strings[key] = true; }); - + var aliases = {}; Object.keys(opts.alias || {}).forEach(function (key) { aliases[key] = [].concat(opts.alias[key]); @@ -20,14 +20,14 @@ module.exports = function (args, opts) { })); }); }); - + var defaults = opts['default'] || {}; - + var argv = { _ : [] }; Object.keys(flags.bools).forEach(function (key) { setArg(key, defaults[key] === undefined ? false : defaults[key]); }); - + var notFlags = []; if (args.indexOf('--') !== -1) { @@ -40,15 +40,15 @@ module.exports = function (args, opts) { ? Number(val) : val ; setKey(argv, key.split('.'), value); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), value); }); } - + for (var i = 0; i < args.length; i++) { var arg = args[i]; - + if (/^--.+=/.test(arg)) { // Using [\s\S] instead of . because js doesn't support the // 'dotall' regex modifier. See: @@ -79,23 +79,23 @@ module.exports = function (args, opts) { } else if (/^-[^-]+/.test(arg)) { var letters = arg.slice(1,-1).split(''); - + var broken = false; for (var j = 0; j < letters.length; j++) { var next = arg.slice(j+2); - + if (next === '-') { setArg(letters[j], next) continue; } - + if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { setArg(letters[j], next); broken = true; break; } - + if (letters[j+1] && letters[j+1].match(/\W/)) { setArg(letters[j], arg.slice(j+2)); broken = true; @@ -105,7 +105,7 @@ module.exports = function (args, opts) { setArg(letters[j], flags.strings[letters[j]] ? '' : true); } } - + var key = arg.slice(-1)[0]; if (!broken && key !== '-') { if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) @@ -129,17 +129,17 @@ module.exports = function (args, opts) { ); } } - + Object.keys(defaults).forEach(function (key) { if (!hasKey(argv, key.split('.'))) { setKey(argv, key.split('.'), defaults[key]); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), defaults[key]); }); } }); - + notFlags.forEach(function(key) { argv._.push(key); }); @@ -163,7 +163,7 @@ function setKey (obj, keys, value) { if (o[key] === undefined) o[key] = {}; o = o[key]; }); - + var key = keys[keys.length - 1]; if (o[key] === undefined || typeof o[key] === 'boolean') { o[key] = value; diff --git a/deps/npm/node_modules/minimist/test/parse.js b/deps/npm/node_modules/minimist/test/parse.js index 47e92237fb0bbc..8a90646696628e 100644 --- a/deps/npm/node_modules/minimist/test/parse.js +++ b/deps/npm/node_modules/minimist/test/parse.js @@ -14,7 +14,7 @@ test('parse args', function (t) { ); t.end(); }); - + test('comprehensive', function (t) { t.deepEqual( parse([ @@ -80,13 +80,13 @@ test('flag boolean value', function (t) { boolean: [ 't', 'verbose' ], default: { verbose: true } }); - + t.deepEqual(argv, { verbose: false, t: true, _: ['moo'] }); - + t.deepEqual(typeof argv.verbose, 'boolean'); t.deepEqual(typeof argv.t, 'boolean'); t.end(); @@ -97,13 +97,13 @@ test('flag boolean default false', function (t) { boolean: ['t', 'verbose'], default: { verbose: false, t: false } }); - + t.deepEqual(argv, { verbose: false, t: false, _: ['moo'] }); - + t.deepEqual(typeof argv.verbose, 'boolean'); t.deepEqual(typeof argv.t, 'boolean'); t.end(); @@ -114,14 +114,14 @@ test('boolean groups', function (t) { var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], { boolean: ['x','y','z'] }); - + t.deepEqual(argv, { x : true, y : false, z : true, _ : [ 'one', 'two', 'three' ] }); - + t.deepEqual(typeof argv.x, 'boolean'); t.deepEqual(typeof argv.y, 'boolean'); t.deepEqual(typeof argv.z, 'boolean'); @@ -131,7 +131,7 @@ test('boolean groups', function (t) { test('newlines in params' , function (t) { var args = parse([ '-s', "X\nX" ]) t.deepEqual(args, { _ : [], s : "X\nX" }); - + // reproduce in bash: // VALUE="new // line" @@ -145,7 +145,7 @@ test('strings' , function (t) { var s = parse([ '-s', '0001234' ], { string: 's' }).s; t.equal(s, '0001234'); t.equal(typeof s, 'string'); - + var x = parse([ '-x', '56' ], { string: 'x' }).x; t.equal(x, '56'); t.equal(typeof x, 'string'); @@ -222,7 +222,7 @@ test('nested dotted objects', function (t) { '--foo.quux.quibble', '5', '--foo.quux.o_O', '--beep.boop' ]); - + t.same(argv.foo, { bar : 3, baz : 4, @@ -254,9 +254,9 @@ test('boolean and alias with chainable api', function (t) { h: true, '_': [ 'derp' ] }; - + t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); + t.same(propertyArgv, expected); t.end(); }); @@ -295,7 +295,7 @@ test('boolean and alias using explicit true', function (t) { }; t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); + t.same(propertyArgv, expected); t.end(); }); @@ -311,7 +311,7 @@ test('boolean and --x=true', function(t) { parsed = parse(['--boool', '--other=false'], { boolean: 'boool' }); - + t.same(parsed.boool, true); t.same(parsed.other, 'false'); t.end(); diff --git a/deps/npm/node_modules/minimist/test/parse_modified.js b/deps/npm/node_modules/minimist/test/parse_modified.js index 7c4c2abe397797..21851b036ee6d9 100644 --- a/deps/npm/node_modules/minimist/test/parse_modified.js +++ b/deps/npm/node_modules/minimist/test/parse_modified.js @@ -3,7 +3,7 @@ var test = require('tape'); test('parse with modifier functions' , function (t) { t.plan(1); - + var argv = parse([ '-b', '123' ], { boolean: 'b' }); t.deepEqual(argv, { b: true, _: ['123'] }); }); diff --git a/deps/npm/node_modules/minimist/test/short.js b/deps/npm/node_modules/minimist/test/short.js index ac18880f1eb50c..d513a1c2529095 100644 --- a/deps/npm/node_modules/minimist/test/short.js +++ b/deps/npm/node_modules/minimist/test/short.js @@ -43,7 +43,7 @@ test('short', function (t) { ); t.end(); }); - + test('mixed short bool and capture', function (t) { t.same( parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), @@ -54,7 +54,7 @@ test('mixed short bool and capture', function (t) { ); t.end(); }); - + test('short and long', function (t) { t.deepEqual( parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), diff --git a/deps/npm/node_modules/move-concurrently/LICENSE b/deps/npm/node_modules/move-concurrently/LICENSE index e0040f6659d374..83e7c4c62903d7 100644 --- a/deps/npm/node_modules/move-concurrently/LICENSE +++ b/deps/npm/node_modules/move-concurrently/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/move-concurrently/node_modules/aproba/LICENSE b/deps/npm/node_modules/move-concurrently/node_modules/aproba/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/move-concurrently/node_modules/aproba/LICENSE +++ b/deps/npm/node_modules/move-concurrently/node_modules/aproba/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/move-concurrently/node_modules/aproba/README.md b/deps/npm/node_modules/move-concurrently/node_modules/aproba/README.md index e94799201ce046..0bfc594c56a372 100644 --- a/deps/npm/node_modules/move-concurrently/node_modules/aproba/README.md +++ b/deps/npm/node_modules/move-concurrently/node_modules/aproba/README.md @@ -84,10 +84,11 @@ I wanted a very simple argument validator. It needed to do two things: 2. Not encourage an infinite bikeshed of DSLs This is why types are specified by a single character and there's no such -thing as an optional argument. +thing as an optional argument. This is not intended to validate user data. This is specifically about asserting the interface of your functions. If you need greater validation, I encourage you to write them by hand or look elsewhere. + diff --git a/deps/npm/node_modules/node-fetch-npm/LICENSE.md b/deps/npm/node_modules/node-fetch-npm/LICENSE.md index 492632ff69000f..660ffecb58b02f 100644 --- a/deps/npm/node_modules/node-fetch-npm/LICENSE.md +++ b/deps/npm/node_modules/node-fetch-npm/LICENSE.md @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md b/deps/npm/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md index bc89b7e273d142..b5bed7fdd1ea61 100644 --- a/deps/npm/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md +++ b/deps/npm/node_modules/node-gyp/.github/ISSUE_TEMPLATE.md @@ -24,3 +24,4 @@ Paste your log here, between the backticks. It can be: + diff --git a/deps/npm/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md b/deps/npm/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md index 9be6968ea8e88a..10156d89af112e 100644 --- a/deps/npm/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md +++ b/deps/npm/node_modules/node-gyp/.github/PULL_REQUEST_TEMPLATE.md @@ -14,3 +14,4 @@ Contributor guide: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md ##### Description of change + diff --git a/deps/npm/node_modules/node-gyp/CHANGELOG.md b/deps/npm/node_modules/node-gyp/CHANGELOG.md index f982c5a3d61601..ecc51b360dd183 100644 --- a/deps/npm/node_modules/node-gyp/CHANGELOG.md +++ b/deps/npm/node_modules/node-gyp/CHANGELOG.md @@ -130,11 +130,11 @@ v3.8.0 2018-08-09 * [[`94c39c604e`](https://github.com/nodejs/node-gyp/commit/94c39c604e)] - **gyp**: fix ninja build failure (GYP patch) (Daniel Bevenius) [nodejs/node#12484](https://github.com/nodejs/node/pull/12484) * [[`e8ea74e0fa`](https://github.com/nodejs/node-gyp/commit/e8ea74e0fa)] - **tools**: patch gyp to avoid xcrun errors (Ujjwal Sharma) [nodejs/node#21520](https://github.com/nodejs/node/pull/21520) * [[`ea9aff44f2`](https://github.com/nodejs/node-gyp/commit/ea9aff44f2)] - **tools**: fix "the the" typos in comments (Masashi Hirano) [nodejs/node#20716](https://github.com/nodejs/node/pull/20716) -* [[`207e5aa4fd`](https://github.com/nodejs/node-gyp/commit/207e5aa4fd)] - **gyp**: implement LD/LDXX for ninja and FIPS (Sam Roberts) +* [[`207e5aa4fd`](https://github.com/nodejs/node-gyp/commit/207e5aa4fd)] - **gyp**: implement LD/LDXX for ninja and FIPS (Sam Roberts) * [[`b416c5f4b7`](https://github.com/nodejs/node-gyp/commit/b416c5f4b7)] - **gyp**: enable cctest to use objects (gyp part) (Daniel Bevenius) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450) * [[`40692d016b`](https://github.com/nodejs/node-gyp/commit/40692d016b)] - **gyp**: add compile\_commands.json gyp generator (Ben Noordhuis) [nodejs/node#12450](https://github.com/nodejs/node/pull/12450) * [[`fc3c4e2b10`](https://github.com/nodejs/node-gyp/commit/fc3c4e2b10)] - **gyp**: float gyp patch for long filenames (Anna Henningsen) [nodejs/node#7963](https://github.com/nodejs/node/pull/7963) -* [[`8aedbfdef6`](https://github.com/nodejs/node-gyp/commit/8aedbfdef6)] - **gyp**: backport GYP fix to fix AIX shared suffix (Stewart Addison) +* [[`8aedbfdef6`](https://github.com/nodejs/node-gyp/commit/8aedbfdef6)] - **gyp**: backport GYP fix to fix AIX shared suffix (Stewart Addison) * [[`6cd84b84fc`](https://github.com/nodejs/node-gyp/commit/6cd84b84fc)] - **test**: formatting and minor fixes for execFileSync replacement (Rod Vagg) [#1521](https://github.com/nodejs/node-gyp/pull/1521) * [[`60e421363f`](https://github.com/nodejs/node-gyp/commit/60e421363f)] - **test**: added test/processExecSync.js for when execFileSync is not available. (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492) * [[`969447c5bd`](https://github.com/nodejs/node-gyp/commit/969447c5bd)] - **deps**: bump request to 2.8.7, fixes heok/hawk issues (Rohit Hazra) [#1492](https://github.com/nodejs/node-gyp/pull/1492) @@ -203,7 +203,7 @@ v3.6.0 2017-03-16 v3.5.0 2017-01-10 ================= -* [[`762d19a39e`](https://github.com/nodejs/node-gyp/commit/762d19a39e)] - \[doc\] merge History.md and CHANGELOG.md (Rod Vagg) +* [[`762d19a39e`](https://github.com/nodejs/node-gyp/commit/762d19a39e)] - \[doc\] merge History.md and CHANGELOG.md (Rod Vagg) * [[`80fc5c3d31`](https://github.com/nodejs/node-gyp/commit/80fc5c3d31)] - Fix deprecated dependency warning (Simone Primarosa) [#1069](https://github.com/nodejs/node-gyp/pull/1069) * [[`05c44944fd`](https://github.com/nodejs/node-gyp/commit/05c44944fd)] - Open the build file with universal-newlines mode (Guy Margalit) [#1053](https://github.com/nodejs/node-gyp/pull/1053) * [[`37ae7be114`](https://github.com/nodejs/node-gyp/commit/37ae7be114)] - Try python launcher when stock python is python 3. (Ben Noordhuis) [#992](https://github.com/nodejs/node-gyp/pull/992) @@ -265,7 +265,7 @@ v3.2.0 2015-11-25 * [[`0e2dfda1f3`](https://github.com/nodejs/node-gyp/commit/0e2dfda1f3)] - Fix test/test-options when run through `npm test`. (Ben Noordhuis) [#755](https://github.com/nodejs/node-gyp/pull/755) * [[`9bfa0876b4`](https://github.com/nodejs/node-gyp/commit/9bfa0876b4)] - Add support for AIX (Michael Dawson) [#753](https://github.com/nodejs/node-gyp/pull/753) * [[`a8d441a0a2`](https://github.com/nodejs/node-gyp/commit/a8d441a0a2)] - Update README for Windows 10 support. (Jason Williams) [#766](https://github.com/nodejs/node-gyp/pull/766) -* [[`d1d6015276`](https://github.com/nodejs/node-gyp/commit/d1d6015276)] - Update broken links and switch to HTTPS. (andrew morton) +* [[`d1d6015276`](https://github.com/nodejs/node-gyp/commit/d1d6015276)] - Update broken links and switch to HTTPS. (andrew morton) v3.1.0 2015-11-14 ================= diff --git a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/common.py b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/common.py index f595c947bcb0f9..071ad7e242c2e2 100644 --- a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/common.py +++ b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/common.py @@ -631,3 +631,4 @@ def IsCygwin(): return "CYGWIN" in str(stdout) except Exception: return False + diff --git a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py index a227eb832fea7e..6b49ad6760051e 100644 --- a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +++ b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py @@ -422,3 +422,4 @@ def GenerateOutput(target_list, target_dicts, data, params): for config_name in config_names: GenerateOutputForConfig(target_list, target_dicts, data, params, config_name) + diff --git a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py index 01fe4134343038..6fe9c1f6c7c22b 100644 --- a/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py +++ b/deps/npm/node_modules/node-gyp/gyp/pylib/gyp/ordered_dict.py @@ -286,3 +286,4 @@ def viewvalues(self): def viewitems(self): "od.viewitems() -> a set-like object providing a view on od's items" return ItemsView(self) + diff --git a/deps/npm/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec b/deps/npm/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec index ab1312e6ee72a8..3b3506d319e0f2 100644 --- a/deps/npm/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec +++ b/deps/npm/node_modules/node-gyp/gyp/tools/Xcode/Specifications/gyp.xclangspec @@ -2,7 +2,7 @@ Copyright (c) 2011 Google Inc. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. - + gyp.xclangspec GYP language specification for Xcode 3 @@ -35,9 +35,9 @@ { Identifier = "xcode.lang.gyp.target.declarator"; Syntax = { - Words = ( - "'target_name'", - ); + Words = ( + "'target_name'", + ); Type = "xcode.syntax.identifier.type"; }; }, @@ -54,12 +54,12 @@ End = "'"; }; }, - + { Identifier = "xcode.lang.gyp.comma"; Syntax = { Words = ( ",", ); - + }; }, @@ -107,14 +107,14 @@ Syntax = { Tokenizer = "xcode.lang.gyp.lexer"; Rules = ( - "xcode.lang.gyp.assignment.lhs", - ":", + "xcode.lang.gyp.assignment.lhs", + ":", "xcode.lang.gyp.assignment.rhs", ); }; - + }, - + { Identifier = "xcode.lang.gyp.target.declaration"; Syntax = { @@ -126,7 +126,7 @@ ); }; }, - + { Identifier = "xcode.lang.gyp.target.name"; Syntax = { @@ -134,27 +134,27 @@ Rules = ( "xcode.lang.gyp.string.singlequote", ); - Type = "xcode.syntax.definition.function"; + Type = "xcode.syntax.definition.function"; }; }, - + { Identifier = "xcode.lang.gyp.assignment.lhs"; Syntax = { Tokenizer = "xcode.lang.gyp.lexer"; Rules = ( - "xcode.lang.gyp.string.singlequote", + "xcode.lang.gyp.string.singlequote", ); - Type = "xcode.syntax.identifier.type"; + Type = "xcode.syntax.identifier.type"; }; }, - + { Identifier = "xcode.lang.gyp.assignment.rhs"; Syntax = { - Tokenizer = "xcode.lang.gyp.lexer"; + Tokenizer = "xcode.lang.gyp.lexer"; Rules = ( - "xcode.lang.gyp.string.singlequote?", + "xcode.lang.gyp.string.singlequote?", "xcode.lang.gyp.array?", "xcode.lang.gyp.dictionary?", "xcode.lang.number?", diff --git a/deps/npm/node_modules/normalize-package-data/node_modules/resolve/test/resolver/cup.coffee b/deps/npm/node_modules/normalize-package-data/node_modules/resolve/test/resolver/cup.coffee index e69de29bb2d1d6..8b137891791fe9 100644 --- a/deps/npm/node_modules/normalize-package-data/node_modules/resolve/test/resolver/cup.coffee +++ b/deps/npm/node_modules/normalize-package-data/node_modules/resolve/test/resolver/cup.coffee @@ -0,0 +1 @@ + diff --git a/deps/npm/node_modules/oauth-sign/README.md b/deps/npm/node_modules/oauth-sign/README.md index d1a136a3891b08..549cbbafa49196 100644 --- a/deps/npm/node_modules/oauth-sign/README.md +++ b/deps/npm/node_modules/oauth-sign/README.md @@ -1,7 +1,7 @@ oauth-sign ========== -OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. +OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module. ## Supported Method Signatures diff --git a/deps/npm/node_modules/oauth-sign/index.js b/deps/npm/node_modules/oauth-sign/index.js index 3dabf53ed93cec..6482f77b54be85 100644 --- a/deps/npm/node_modules/oauth-sign/index.js +++ b/deps/npm/node_modules/oauth-sign/index.js @@ -42,7 +42,7 @@ function compare (a, b) { } function generateBase (httpMethod, base_uri, params) { - // adapted from https://dev.twitter.com/docs/auth/oauth and + // adapted from https://dev.twitter.com/docs/auth/oauth and // https://dev.twitter.com/docs/auth/creating-signature // Parameter normalization diff --git a/deps/npm/node_modules/object-keys/.editorconfig b/deps/npm/node_modules/object-keys/.editorconfig index 572e9793f03233..eaa214161f5cdb 100644 --- a/deps/npm/node_modules/object-keys/.editorconfig +++ b/deps/npm/node_modules/object-keys/.editorconfig @@ -10,3 +10,4 @@ spaces_around_operators = true; trim_trailing_whitespace = true; spaces_in_brackets = false; end_of_line = lf; + diff --git a/deps/npm/node_modules/object-keys/.jscs.json b/deps/npm/node_modules/object-keys/.jscs.json index 76f7cb186e68da..47828965125a06 100644 --- a/deps/npm/node_modules/object-keys/.jscs.json +++ b/deps/npm/node_modules/object-keys/.jscs.json @@ -172,3 +172,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/object-keys/README.md b/deps/npm/node_modules/object-keys/README.md index dbcf1a8c3d4188..ed4c277023a8a4 100644 --- a/deps/npm/node_modules/object-keys/README.md +++ b/deps/npm/node_modules/object-keys/README.md @@ -73,3 +73,4 @@ Simply clone the repo, `npm install`, and run `npm test` [license-url]: LICENSE [downloads-image]: http://img.shields.io/npm/dm/object-keys.svg [downloads-url]: http://npm-stat.com/charts.html?package=object-keys + diff --git a/deps/npm/node_modules/object.getownpropertydescriptors/.editorconfig b/deps/npm/node_modules/object.getownpropertydescriptors/.editorconfig index 572e9793f03233..eaa214161f5cdb 100644 --- a/deps/npm/node_modules/object.getownpropertydescriptors/.editorconfig +++ b/deps/npm/node_modules/object.getownpropertydescriptors/.editorconfig @@ -10,3 +10,4 @@ spaces_around_operators = true; trim_trailing_whitespace = true; spaces_in_brackets = false; end_of_line = lf; + diff --git a/deps/npm/node_modules/object.getownpropertydescriptors/.jscs.json b/deps/npm/node_modules/object.getownpropertydescriptors/.jscs.json index 7296cbab09bdf5..3d099c4b1192c4 100644 --- a/deps/npm/node_modules/object.getownpropertydescriptors/.jscs.json +++ b/deps/npm/node_modules/object.getownpropertydescriptors/.jscs.json @@ -173,3 +173,4 @@ "requireUseStrict": true } + diff --git a/deps/npm/node_modules/object.getownpropertydescriptors/LICENSE b/deps/npm/node_modules/object.getownpropertydescriptors/LICENSE index fcf5754efe64ab..b43df444e51828 100644 --- a/deps/npm/node_modules/object.getownpropertydescriptors/LICENSE +++ b/deps/npm/node_modules/object.getownpropertydescriptors/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/pacote/CHANGELOG.md b/deps/npm/node_modules/pacote/CHANGELOG.md index 4ed92beb68213d..6896c4739ce532 100644 --- a/deps/npm/node_modules/pacote/CHANGELOG.md +++ b/deps/npm/node_modules/pacote/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [9.5.9](https://github.com/npm/pacote/compare/v9.5.8...v9.5.9) (2019-10-29) + + +### Bug Fixes + +* include peerDependenciesMeta in manifest ([7a400d3](https://github.com/npm/pacote/commit/7a400d3)), closes [/github.com/npm/cli/pull/224#issuecomment-547666807](https://github.com//github.com/npm/cli/pull/224/issues/issuecomment-547666807) + + + ## [9.5.8](https://github.com/npm/pacote/compare/v9.5.7...v9.5.8) (2019-08-20) diff --git a/deps/npm/node_modules/pacote/lib/fetchers/git.js b/deps/npm/node_modules/pacote/lib/fetchers/git.js index a1579d1f943125..7913be81687912 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/git.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/git.js @@ -166,7 +166,7 @@ function withTmp (opts, cb) { } } -// Only certain whitelisted hosted gits support shadow cloning +// Only certain whitelisted hosted gits support shallow cloning const SHALLOW_HOSTS = new Set(['github', 'gist', 'gitlab', 'bitbucket']) function cloneRepo (spec, repo, resolvedRef, rawRef, tmp, opts) { const ref = resolvedRef ? resolvedRef.ref : rawRef diff --git a/deps/npm/node_modules/pacote/lib/finalize-manifest.js b/deps/npm/node_modules/pacote/lib/finalize-manifest.js index f047517945192f..d1d0f4e563eed2 100644 --- a/deps/npm/node_modules/pacote/lib/finalize-manifest.js +++ b/deps/npm/node_modules/pacote/lib/finalize-manifest.js @@ -83,6 +83,7 @@ function Manifest (pkg, fromTarball, fullMetadata) { this.os = pkg.os || fromTarball.os this.dependencies = pkg.dependencies || {} this.optionalDependencies = pkg.optionalDependencies || {} + this.peerDependenciesMeta = pkg.peerDependenciesMeta || {} this.devDependencies = pkg.devDependencies || {} const bundled = ( pkg.bundledDependencies || diff --git a/deps/npm/node_modules/pacote/node_modules/minipass/README.md b/deps/npm/node_modules/pacote/node_modules/minipass/README.md index 7a83c59ffd709f..c989beea0e6d97 100644 --- a/deps/npm/node_modules/pacote/node_modules/minipass/README.md +++ b/deps/npm/node_modules/pacote/node_modules/minipass/README.md @@ -24,25 +24,374 @@ If you set `objectMode: true` in the options, then whatever is written will be emitted. Otherwise, it'll do a minimal amount of Buffer copying to ensure proper Streams semantics when `read(n)` is called. +`objectMode` can also be set by doing `stream.objectMode = true`, or by +writing any non-string/non-buffer data. `objectMode` cannot be set to +false once it is set. + This is not a `through` or `through2` stream. It doesn't transform the data, it just passes it right through. If you want to transform the data, extend the class, and override the `write()` method. Once you're done transforming the data however you want, call `super.write()` with the transform output. -For an example of a stream that extends MiniPass to provide transform -capabilities, check out [minizlib](http://npm.im/minizlib). +For some examples of streams that extend Minipass in various ways, check +out: + +- [minizlib](http://npm.im/minizlib) +- [fs-minipass](http://npm.im/fs-minipass) +- [tar](http://npm.im/tar) +- [minipass-collect](http://npm.im/minipass-collect) +- [minipass-flush](http://npm.im/minipass-flush) +- [minipass-pipeline](http://npm.im/minipass-pipeline) +- [tap](http://npm.im/tap) +- [tap-parser](http://npm.im/tap) +- [treport](http://npm.im/tap) + +## Differences from Node.js Streams + +There are several things that make Minipass streams different from (and in +some ways superior to) Node.js core streams. + +Please read these caveats if you are familiar with noode-core streams and +intend to use Minipass streams in your programs. + +### Timing + +Minipass streams are designed to support synchronous use-cases. Thus, data +is emitted as soon as it is available, always. It is buffered until read, +but no longer. Another way to look at it is that Minipass streams are +exactly as synchronous as the logic that writes into them. + +This can be surprising if your code relies on `PassThrough.write()` always +providing data on the next tick rather than the current one, or being able +to call `resume()` and not have the entire buffer disappear immediately. + +However, without this synchronicity guarantee, there would be no way for +Minipass to achieve the speeds it does, or support the synchronous use +cases that it does. Simply put, waiting takes time. + +This non-deferring approach makes Minipass streams much easier to reason +about, especially in the context of Promises and other flow-control +mechanisms. + +### No High/Low Water Marks + +Node.js core streams will optimistically fill up a buffer, returning `true` +on all writes until the limit is hit, even if the data has nowhere to go. +Then, they will not attempt to draw more data in until the buffer size dips +below a minimum value. + +Minipass streams are much simpler. The `write()` method will return `true` +if the data has somewhere to go (which is to say, given the timing +guarantees, that the data is already there by the time `write()` returns). + +If the data has nowhere to go, then `write()` returns false, and the data +sits in a buffer, to be drained out immediately as soon as anyone consumes +it. + +### Hazards of Buffering (or: Why Minipass Is So Fast) + +Since data written to a Minipass stream is immediately written all the way +through the pipeline, and `write()` always returns true/false based on +whether the data was fully flushed, backpressure is communicated +immediately to the upstream caller. This minimizes buffering. + +Consider this case: + +```js +const {PassThrough} = require('stream') +const p1 = new PassThrough({ highWaterMark: 1024 }) +const p2 = new PassThrough({ highWaterMark: 1024 }) +const p3 = new PassThrough({ highWaterMark: 1024 }) +const p4 = new PassThrough({ highWaterMark: 1024 }) + +p1.pipe(p2).pipe(p3).pipe(p4) +p4.on('data', () => console.log('made it through')) + +// this returns false and buffers, then writes to p2 on next tick (1) +// p2 returns false and buffers, pausing p1, then writes to p3 on next tick (2) +// p3 returns false and buffers, pausing p2, then writes to p4 on next tick (3) +// p4 returns false and buffers, pausing p3, then emits 'data' and 'drain' +// on next tick (4) +// p3 sees p4's 'drain' event, and calls resume(), emitting 'resume' and +// 'drain' on next tick (5) +// p2 sees p3's 'drain', calls resume(), emits 'resume' and 'drain' on next tick (6) +// p1 sees p2's 'drain', calls resume(), emits 'resume' and 'drain' on next +// tick (7) + +p1.write(Buffer.alloc(2048)) // returns false +``` + +Along the way, the data was buffered and deferred at each stage, and +multiple event deferrals happened, for an unblocked pipeline where it was +perfectly safe to write all the way through! + +Furthermore, setting a `highWaterMark` of `1024` might lead someone reading +the code to think an advisory maximum of 1KiB is being set for the +pipeline. However, the actual advisory buffering level is the _sum_ of +`highWaterMark` values, since each one has its own bucket. + +Consider the Minipass case: + +```js +const m1 = new Minipass() +const m2 = new Minipass() +const m3 = new Minipass() +const m4 = new Minipass() + +m1.pipe(m2).pipe(m3).pipe(m4) +m4.on('data', () => console.log('made it through')) + +// m1 is flowing, so it writes the data to m2 immediately +// m2 is flowing, so it writes the data to m3 immediately +// m3 is flowing, so it writes the data to m4 immediately +// m4 is flowing, so it fires the 'data' event immediately, returns true +// m4's write returned true, so m3 is still flowing, returns true +// m3's write returned true, so m2 is still flowing, returns true +// m2's write returned true, so m1 is still flowing, returns true +// No event deferrals or buffering along the way! + +m1.write(Buffer.alloc(2048)) // returns true +``` + +It is extremely unlikely that you _don't_ want to buffer any data written, +or _ever_ buffer data that can be flushed all the way through. Neither +node-core streams nor Minipass ever fail to buffer written data, but +node-core streams do a lot of unnecessary buffering and pausing. + +As always, the faster implementation is the one that does less stuff and +waits less time to do it. + +### Immediately emit `end` for empty streams (when not paused) + +If a stream is not paused, and `end()` is called before writing any data +into it, then it will emit `end` immediately. + +If you have logic that occurs on the `end` event which you don't want to +potentially happen immediately (for example, closing file descriptors, +moving on to the next entry in an archive parse stream, etc.) then be sure +to call `stream.pause()` on creation, and then `stream.resume()` once you +are ready to respond to the `end` event. + +### Emit `end` When Asked + +One hazard of immediately emitting `'end'` is that you may not yet have had +a chance to add a listener. In order to avoid this hazard, Minipass +streams safely re-emit the `'end'` event if a new listener is added after +`'end'` has been emitted. + +Ie, if you do `stream.on('end', someFunction)`, and the stream has already +emitted `end`, then it will call the handler right away. (You can think of +this somewhat like attaching a new `.then(fn)` to a previously-resolved +Promise.) + +To prevent calling handlers multiple times who would not expect multiple +ends to occur, all listeners are removed from the `'end'` event whenever it +is emitted. + +### Impact of "immediate flow" on Tee-streams + +A "tee stream" is a stream piping to multiple destinations: + +```js +const tee = new Minipass() +t.pipe(dest1) +t.pipe(dest2) +t.write('foo') // goes to both destinations +``` + +Since Minipass streams _immediately_ process any pending data through the +pipeline when a new pipe destination is added, this can have surprising +effects, especially when a stream comes in from some other function and may +or may not have data in its buffer. + +```js +// WARNING! WILL LOSE DATA! +const src = new Minipass() +src.write('foo') +src.pipe(dest1) // 'foo' chunk flows to dest1 immediately, and is gone +src.pipe(dest2) // gets nothing! +``` + +The solution is to create a dedicated tee-stream junction that pipes to +both locations, and then pipe to _that_ instead. + +```js +// Safe example: tee to both places +const src = new Minipass() +src.write('foo') +const tee = new Minipass() +tee.pipe(dest1) +tee.pipe(dest2) +stream.pipe(tee) // tee gets 'foo', pipes to both locations +``` + +The same caveat applies to `on('data')` event listeners. The first one +added will _immediately_ receive all of the data, leaving nothing for the +second: + +```js +// WARNING! WILL LOSE DATA! +const src = new Minipass() +src.write('foo') +src.on('data', handler1) // receives 'foo' right away +src.on('data', handler2) // nothing to see here! +``` + +Using a dedicated tee-stream can be used in this case as well: + +```js +// Safe example: tee to both data handlers +const src = new Minipass() +src.write('foo') +const tee = new Minipass() +tee.on('data', handler1) +tee.on('data', handler2) +src.pipe(tee) +``` ## USAGE +It's a stream! Use it like a stream and it'll most likely do what you want. + ```js -const MiniPass = require('minipass') -const mp = new MiniPass(options) // optional: { encoding } +const Minipass = require('minipass') +const mp = new Minipass(options) // optional: { encoding, objectMode } mp.write('foo') mp.pipe(someOtherStream) mp.end('bar') ``` +### OPTIONS + +* `encoding` How would you like the data coming _out_ of the stream to be + encoded? Accepts any values that can be passed to `Buffer.toString()`. +* `objectMode` Emit data exactly as it comes in. This will be flipped on + by default if you write() something other than a string or Buffer at any + point. Setting `objectMode: true` will prevent setting any encoding + value. + +### API + +Implements the user-facing portions of Node.js's `Readable` and `Writable` +streams. + +### Methods + +* `write(chunk, [encoding], [callback])` - Put data in. (Note that, in the + base Minipass class, the same data will come out.) Returns `false` if + the stream will buffer the next write, or true if it's still in + "flowing" mode. +* `end([chunk, [encoding]], [callback])` - Signal that you have no more + data to write. This will queue an `end` event to be fired when all the + data has been consumed. +* `setEncoding(encoding)` - Set the encoding for data coming of the + stream. This can only be done once. +* `pause()` - No more data for a while, please. This also prevents `end` + from being emitted for empty streams until the stream is resumed. +* `resume()` - Resume the stream. If there's data in the buffer, it is + all discarded. Any buffered events are immediately emitted. +* `pipe(dest)` - Send all output to the stream provided. There is no way + to unpipe. When data is emitted, it is immediately written to any and + all pipe destinations. +* `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are EventEmitters. + Some events are given special treatment, however. (See below under + "events".) +* `promise()` - Returns a Promise that resolves when the stream emits + `end`, or rejects if the stream emits `error`. +* `collect()` - Return a Promise that resolves on `end` with an array + containing each chunk of data that was emitted, or rejects if the + stream emits `error`. Note that this consumes the stream data. +* `concat()` - Same as `collect()`, but concatenates the data into a + single Buffer object. Will reject the returned promise if the stream is + in objectMode, or if it goes into objectMode by the end of the data. +* `read(n)` - Consume `n` bytes of data out of the buffer. If `n` is not + provided, then consume all of it. If `n` bytes are not available, then + it returns null. **Note** consuming streams in this way is less + efficient, and can lead to unnecessary Buffer copying. +* `destroy([er])` - Destroy the stream. If an error is provided, then an + `'error'` event is emitted. If the stream has a `close()` method, and + has not emitted a `'close'` event yet, then `stream.close()` will be + called. Any Promises returned by `.promise()`, `.collect()` or + `.concat()` will be rejected. After being destroyed, writing to the + stream will emit an error. No more data will be emitted if the stream is + destroyed, even if it was previously buffered. + +### Properties + +* `bufferLength` Read-only. Total number of bytes buffered, or in the case + of objectMode, the total number of objects. +* `encoding` The encoding that has been set. (Setting this is equivalent + to calling `setEncoding(enc)` and has the same prohibition against + setting multiple times.) +* `flowing` Read-only. Boolean indicating whether a chunk written to the + stream will be immediately emitted. +* `emittedEnd` Read-only. Boolean indicating whether the end-ish events + (ie, `end`, `prefinish`, `finish`) have been emitted. Note that + listening on any end-ish event will immediateyl re-emit it if it has + already been emitted. +* `writable` Whether the stream is writable. Default `true`. Set to + `false` when `end()` +* `readable` Whether the stream is readable. Default `true`. +* `buffer` A [yallist](http://npm.im/yallist) linked list of chunks written + to the stream that have not yet been emitted. (It's probably a bad idea + to mess with this.) +* `pipes` A [yallist](http://npm.im/yallist) linked list of streams that + this stream is piping into. (It's probably a bad idea to mess with + this.) +* `destroyed` A getter that indicates whether the stream was destroyed. +* `paused` True if the stream has been explicitly paused, otherwise false. +* `objectMode` Indicates whether the stream is in `objectMode`. Once set + to `true`, it cannot be set to `false`. + +### Events + +* `data` Emitted when there's data to read. Argument is the data to read. + This is never emitted while not flowing. If a listener is attached, that + will resume the stream. +* `end` Emitted when there's no more data to read. This will be emitted + immediately for empty streams when `end()` is called. If a listener is + attached, and `end` was already emitted, then it will be emitted again. + All listeners are removed when `end` is emitted. +* `prefinish` An end-ish event that follows the same logic as `end` and is + emitted in the same conditions where `end` is emitted. Emitted after + `'end'`. +* `finish` An end-ish event that follows the same logic as `end` and is + emitted in the same conditions where `end` is emitted. Emitted after + `'prefinish'`. +* `close` An indication that an underlying resource has been released. + Minipass does not emit this event, but will defer it until after `end` + has been emitted, since it throws off some stream libraries otherwise. +* `drain` Emitted when the internal buffer empties, and it is again + suitable to `write()` into the stream. +* `readable` Emitted when data is buffered and ready to be read by a + consumer. +* `resume` Emitted when stream changes state from buffering to flowing + mode. (Ie, when `resume` is called, `pipe` is called, or a `data` event + listener is added.) + +### Static Methods + +* `Minipass.isStream(stream)` Returns `true` if the argument is a stream, + and false otherwise. To be considered a stream, the object must be + either an instance of Minipass, or an EventEmitter that has either a + `pipe()` method, or both `write()` and `end()` methods. (Pretty much any + stream in node-land will return `true` for this.) + +## EXAMPLES + +Here are some examples of things you can do with Minipass streams. + +### simple "are you done yet" promise + +```js +mp.promise().then(() => { + // stream is finished +}, er => { + // stream emitted an error +}) +``` + ### collecting ```js @@ -57,6 +406,19 @@ mp.collect().then(all => { }) ``` +### collecting into a single blob + +This is a bit slower because it concatenates the data into one chunk for +you, but if you're going to do it yourself anyway, it's convenient this +way: + +```js +mp.concat().then(onebigchunk => { + // onebigchunk is a string if the stream + // had an encoding set, or a buffer otherwise. +}) +``` + ### iteration You can iterate over streams synchronously or asynchronously in @@ -122,3 +484,123 @@ async function consume () { consume().then(res => console.log(res)) // logs `foo\n` 5 times, and then `ok` ``` + +### subclass that `console.log()`s everything written into it + +```js +class Logger extends Minipass { + write (chunk, encoding, callback) { + console.log('WRITE', chunk, encoding) + return super.write(chunk, encoding, callback) + } + end (chunk, encoding, callback) { + console.log('END', chunk, encoding) + return super.end(chunk, encoding, callback) + } +} + +someSource.pipe(new Logger()).pipe(someDest) +``` + +### same thing, but using an inline anonymous class + +```js +// js classes are fun +someSource + .pipe(new (class extends Minipass { + emit (ev, ...data) { + // let's also log events, because debugging some weird thing + console.log('EMIT', ev) + return super.emit(ev, ...data) + } + write (chunk, encoding, callback) { + console.log('WRITE', chunk, encoding) + return super.write(chunk, encoding, callback) + } + end (chunk, encoding, callback) { + console.log('END', chunk, encoding) + return super.end(chunk, encoding, callback) + } + })) + .pipe(someDest) +``` + +### subclass that defers 'end' for some reason + +```js +class SlowEnd extends Minipass { + emit (ev, ...args) { + if (ev === 'end') { + console.log('going to end, hold on a sec') + setTimeout(() => { + console.log('ok, ready to end now') + super.emit('end', ...args) + }, 100) + } else { + return super.emit(ev, ...args) + } + } +} +``` + +### transform that creates newline-delimited JSON + +```js +class NDJSONEncode extends Minipass { + write (obj, cb) { + try { + // JSON.stringify can throw, emit an error on that + return super.write(JSON.stringify(obj) + '\n', 'utf8', cb) + } catch (er) { + this.emit('error', er) + } + } + end (obj, cb) { + if (typeof obj === 'function') { + cb = obj + obj = undefined + } + if (obj !== undefined) { + this.write(obj) + } + return super.end(cb) + } +} +``` + +### transform that parses newline-delimited JSON + +```js +class NDJSONDecode extends Minipass { + constructor (options) { + // always be in object mode, as far as Minipass is concerned + super({ objectMode: true }) + this._jsonBuffer = '' + } + write (chunk, encoding, cb) { + if (typeof chunk === 'string' && + typeof encoding === 'string' && + encoding !== 'utf8') { + chunk = Buffer.from(chunk, encoding).toString() + } else if (Buffer.isBuffer(chunk)) + chunk = chunk.toString() + } + if (typeof encoding === 'function') { + cb = encoding + } + const jsonData = (this._jsonBuffer + chunk).split('\n') + this._jsonBuffer = jsonData.pop() + for (let i = 0; i < jsonData.length; i++) { + let parsed + try { + super.write(parsed) + } catch (er) { + this.emit('error', er) + continue + } + } + if (cb) + cb() + } +} +``` diff --git a/deps/npm/node_modules/pacote/node_modules/minipass/index.js b/deps/npm/node_modules/pacote/node_modules/minipass/index.js index de472c36e76847..c072352d448a97 100644 --- a/deps/npm/node_modules/pacote/node_modules/minipass/index.js +++ b/deps/npm/node_modules/pacote/node_modules/minipass/index.js @@ -1,39 +1,62 @@ 'use strict' const EE = require('events') const Yallist = require('yallist') +const SD = require('string_decoder').StringDecoder + const EOF = Symbol('EOF') const MAYBE_EMIT_END = Symbol('maybeEmitEnd') const EMITTED_END = Symbol('emittedEnd') +const EMITTING_END = Symbol('emittingEnd') const CLOSED = Symbol('closed') const READ = Symbol('read') const FLUSH = Symbol('flush') -const doIter = process.env._MP_NO_ITERATOR_SYMBOLS_ !== '1' -const ASYNCITERATOR = doIter && Symbol.asyncIterator || Symbol('asyncIterator not implemented') -const ITERATOR = doIter && Symbol.iterator || Symbol('iterator not implemented') const FLUSHCHUNK = Symbol('flushChunk') -const SD = require('string_decoder').StringDecoder const ENCODING = Symbol('encoding') const DECODER = Symbol('decoder') const FLOWING = Symbol('flowing') +const PAUSED = Symbol('paused') const RESUME = Symbol('resume') const BUFFERLENGTH = Symbol('bufferLength') const BUFFERPUSH = Symbol('bufferPush') const BUFFERSHIFT = Symbol('bufferShift') const OBJECTMODE = Symbol('objectMode') +const DESTROYED = Symbol('destroyed') + +// TODO remove when Node v8 support drops +const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1' +const ASYNCITERATOR = doIter && Symbol.asyncIterator + || Symbol('asyncIterator not implemented') +const ITERATOR = doIter && Symbol.iterator + || Symbol('iterator not implemented') // Buffer in node 4.x < 4.5.0 doesn't have working Buffer.from // or Buffer.alloc, and Buffer in node 10 deprecated the ctor. // .M, this is fine .\^/M.. -let B = Buffer -/* istanbul ignore next */ -if (!B.alloc) { - B = require('safe-buffer').Buffer -} - -module.exports = class MiniPass extends EE { +const B = Buffer.alloc ? Buffer + : /* istanbul ignore next */ require('safe-buffer').Buffer + +// events that mean 'the stream is over' +// these are treated specially, and re-emitted +// if they are listened for after emitting. +const isEndish = ev => + ev === 'end' || + ev === 'finish' || + ev === 'prefinish' + +const isArrayBuffer = b => b instanceof ArrayBuffer || + typeof b === 'object' && + b.constructor && + b.constructor.name === 'ArrayBuffer' && + b.byteLength >= 0 + +const isArrayBufferView = b => !B.isBuffer(b) && ArrayBuffer.isView(b) + +module.exports = class Minipass extends EE { constructor (options) { super() this[FLOWING] = false + // whether we're explicitly paused + this[PAUSED] = false this.pipes = new Yallist() this.buffer = new Yallist() this[OBJECTMODE] = options && options.objectMode || false @@ -46,10 +69,12 @@ module.exports = class MiniPass extends EE { this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null this[EOF] = false this[EMITTED_END] = false + this[EMITTING_END] = false this[CLOSED] = false this.writable = true this.readable = true this[BUFFERLENGTH] = 0 + this[DESTROYED] = false } get bufferLength () { return this[BUFFERLENGTH] } @@ -76,16 +101,52 @@ module.exports = class MiniPass extends EE { this.encoding = enc } + get objectMode () { return this[OBJECTMODE] } + set objectMode (ॐ ) { this[OBJECTMODE] = this[OBJECTMODE] || !!ॐ } + write (chunk, encoding, cb) { if (this[EOF]) throw new Error('write after end') + if (this[DESTROYED]) { + this.emit('error', Object.assign( + new Error('Cannot call write after a stream was destroyed'), + { code: 'ERR_STREAM_DESTROYED' } + )) + return true + } + if (typeof encoding === 'function') cb = encoding, encoding = 'utf8' if (!encoding) encoding = 'utf8' + // convert array buffers and typed array views into buffers + // at some point in the future, we may want to do the opposite! + // leave strings and buffers as-is + // anything else switches us into object mode + if (!this[OBJECTMODE] && !B.isBuffer(chunk)) { + if (isArrayBufferView(chunk)) + chunk = B.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) + else if (isArrayBuffer(chunk)) + chunk = B.from(chunk) + else if (typeof chunk !== 'string') + // use the setter so we throw if we have encoding set + this.objectMode = true + } + + // this ensures at this point that the chunk is a buffer or string + // don't buffer it up or send it to the decoder + if (!this.objectMode && !chunk.length) { + const ret = this.flowing + if (this[BUFFERLENGTH] !== 0) + this.emit('readable') + if (cb) + cb() + return ret + } + // fast-path writing strings of same encoding to a stream with // an empty buffer, skipping the buffer/decoder dance if (typeof chunk === 'string' && !this[OBJECTMODE] && @@ -102,13 +163,17 @@ module.exports = class MiniPass extends EE { ? (this.emit('data', chunk), this.flowing) : (this[BUFFERPUSH](chunk), false) } finally { - this.emit('readable') + if (this[BUFFERLENGTH] !== 0) + this.emit('readable') if (cb) cb() } } read (n) { + if (this[DESTROYED]) + return null + try { if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) return null @@ -161,12 +226,22 @@ module.exports = class MiniPass extends EE { this.once('end', cb) this[EOF] = true this.writable = false - if (this.flowing) + + // if we haven't written anything, then go ahead and emit, + // even if we're not reading. + // we'll re-emit if a new 'end' listener is added anyway. + // This makes MP more suitable to write-only use cases. + if (this.flowing || !this[PAUSED]) this[MAYBE_EMIT_END]() + return this } // don't let the internal resume be overwritten [RESUME] () { + if (this[DESTROYED]) + return + + this[PAUSED] = false this[FLOWING] = true this.emit('resume') if (this.buffer.length) @@ -183,12 +258,21 @@ module.exports = class MiniPass extends EE { pause () { this[FLOWING] = false + this[PAUSED] = true + } + + get destroyed () { + return this[DESTROYED] } get flowing () { return this[FLOWING] } + get paused () { + return this[PAUSED] + } + [BUFFERPUSH] (chunk) { if (this[OBJECTMODE]) this[BUFFERLENGTH] += 1 @@ -219,13 +303,24 @@ module.exports = class MiniPass extends EE { } pipe (dest, opts) { + if (this[DESTROYED]) + return + + const ended = this[EMITTED_END] + opts = opts || {} if (dest === process.stdout || dest === process.stderr) - (opts = opts || {}).end = false + opts.end = false + else + opts.end = opts.end !== false + const p = { dest: dest, opts: opts, ondrain: _ => this[RESUME]() } this.pipes.push(p) dest.on('drain', p.ondrain) this[RESUME]() + // piping an ended stream ends immediately + if (ended && p.opts.end) + p.dest.end() return dest } @@ -239,9 +334,9 @@ module.exports = class MiniPass extends EE { } finally { if (ev === 'data' && !this.pipes.length && !this.flowing) this[RESUME]() - else if (ev === 'end' && this[EMITTED_END]) { - super.emit('end') - this.removeAllListeners('end') + else if (isEndish(ev) && this[EMITTED_END]) { + super.emit(ev) + this.removeAllListeners(ev) } } } @@ -251,23 +346,34 @@ module.exports = class MiniPass extends EE { } [MAYBE_EMIT_END] () { - if (!this[EMITTED_END] && this.buffer.length === 0 && this[EOF]) { + if (!this[EMITTING_END] && + !this[EMITTED_END] && + !this[DESTROYED] && + this.buffer.length === 0 && + this[EOF]) { + this[EMITTING_END] = true this.emit('end') this.emit('prefinish') this.emit('finish') if (this[CLOSED]) this.emit('close') + this[EMITTING_END] = false } } emit (ev, data) { - if (ev === 'data') { + // error and close are only events allowed after calling destroy() + if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED]) + return + else if (ev === 'data') { if (!data) return if (this.pipes.length) - this.pipes.forEach(p => p.dest.write(data) || this.pause()) + this.pipes.forEach(p => + p.dest.write(data) === false && this.pause()) } else if (ev === 'end') { + // only actual end gets this treatment if (this[EMITTED_END] === true) return @@ -284,16 +390,17 @@ module.exports = class MiniPass extends EE { this.pipes.forEach(p => { p.dest.removeListener('drain', p.ondrain) - if (!p.opts || p.opts.end !== false) + if (p.opts.end) p.dest.end() }) } else if (ev === 'close') { this[CLOSED] = true // don't emit close before 'end' and 'finish' - if (!this[EMITTED_END]) + if (!this[EMITTED_END] && !this[DESTROYED]) return } + // TODO: replace with a spread operator when Node v4 support drops const args = new Array(arguments.length) args[0] = ev args[1] = data @@ -306,20 +413,40 @@ module.exports = class MiniPass extends EE { try { return super.emit.apply(this, args) } finally { - if (ev !== 'end') + if (!isEndish(ev)) this[MAYBE_EMIT_END]() else - this.removeAllListeners('end') + this.removeAllListeners(ev) } } // const all = await stream.collect() collect () { + const buf = [] + buf.dataLength = 0 + this.on('data', c => { + buf.push(c) + buf.dataLength += c.length + }) + return this.promise().then(() => buf) + } + + // const data = await stream.concat() + concat () { + return this[OBJECTMODE] + ? Promise.reject(new Error('cannot concat in objectMode')) + : this.collect().then(buf => + this[OBJECTMODE] + ? Promise.reject(new Error('cannot concat in objectMode')) + : this[ENCODING] ? buf.join('') : B.concat(buf, buf.dataLength)) + } + + // stream.promise().then(() => done, er => emitted error) + promise () { return new Promise((resolve, reject) => { - const buf = [] - this.on('data', c => buf.push(c)) - this.on('end', () => resolve(buf)) - this.on('error', reject) + this.on(DESTROYED, () => reject(new Error('stream destroyed'))) + this.on('end', () => resolve()) + this.on('error', er => reject(er)) }) } @@ -351,9 +478,11 @@ module.exports = class MiniPass extends EE { this.removeListener('data', ondata) resolve({ done: true }) } + const ondestroy = () => onerr(new Error('stream destroyed')) return new Promise((res, rej) => { reject = rej resolve = res + this.once(DESTROYED, ondestroy) this.once('error', onerr) this.once('end', onend) this.once('data', ondata) @@ -372,4 +501,37 @@ module.exports = class MiniPass extends EE { } return { next } } + + destroy (er) { + if (this[DESTROYED]) { + if (er) + this.emit('error', er) + else + this.emit(DESTROYED) + return this + } + + this[DESTROYED] = true + + // throw away all buffered data, it's never coming out + this.buffer = new Yallist() + this[BUFFERLENGTH] = 0 + + if (typeof this.close === 'function' && !this[CLOSED]) + this.close() + + if (er) + this.emit('error', er) + else // if no error to emit, still reject pending promises + this.emit(DESTROYED) + + return this + } + + static isStream (s) { + return !!s && (s instanceof Minipass || s instanceof EE && ( + typeof s.pipe === 'function' || // readable + (typeof s.write === 'function' && typeof s.end === 'function') // writable + )) + } } diff --git a/deps/npm/node_modules/pacote/node_modules/minipass/package.json b/deps/npm/node_modules/pacote/node_modules/minipass/package.json index d2adc87994780f..59adc63528e772 100644 --- a/deps/npm/node_modules/pacote/node_modules/minipass/package.json +++ b/deps/npm/node_modules/pacote/node_modules/minipass/package.json @@ -1,8 +1,8 @@ { "_from": "minipass@^2.3.5", - "_id": "minipass@2.3.5", + "_id": "minipass@2.9.0", "_inBundle": false, - "_integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "_integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "_location": "/pacote/minipass", "_phantomChildren": {}, "_requested": { @@ -18,10 +18,10 @@ "_requiredBy": [ "/pacote" ], - "_resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "_shasum": "cacebe492022497f656b0f0f51e2682a9ed2d848", + "_resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "_shasum": "e713762e7d3e32fed803115cf93e04bca9fcc9a6", "_spec": "minipass@^2.3.5", - "_where": "/Users/zkat/Documents/code/work/npm/node_modules/pacote", + "_where": "/Users/ruyadorno/Documents/workspace/cli/node_modules/pacote", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", @@ -39,7 +39,7 @@ "description": "minimal implementation of a PassThrough stream", "devDependencies": { "end-of-stream": "^1.4.0", - "tap": "^12.0.1", + "tap": "^14.6.5", "through2": "^2.0.3" }, "files": [ @@ -58,10 +58,13 @@ "url": "git+https://github.com/isaacs/minipass.git" }, "scripts": { - "postpublish": "git push origin --all; git push origin --tags", + "postpublish": "git push origin --follow-tags", "postversion": "npm publish", "preversion": "npm test", - "test": "tap test/*.js --100" + "test": "tap" }, - "version": "2.3.5" + "tap": { + "check-coverage": true + }, + "version": "2.9.0" } diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json index 58826586a35207..a60ed752703539 100644 --- a/deps/npm/node_modules/pacote/package.json +++ b/deps/npm/node_modules/pacote/package.json @@ -1,8 +1,8 @@ { - "_from": "pacote@9.5.8", - "_id": "pacote@9.5.8", + "_from": "pacote@9.5.9", + "_id": "pacote@9.5.9", "_inBundle": false, - "_integrity": "sha512-0Tl8Oi/K0Lo4MZmH0/6IsT3gpGf9eEAznLXEQPKgPq7FscnbUOyopnVpwXlnQdIbCUaojWy1Wd7VMyqfVsRrIw==", + "_integrity": "sha512-S1nYW9ly+3btn3VmwRAk2LG3TEh8mkrFdY+psbnHSk8oPODbZ28uG0Z0d3yI0EpqcpLR6BukoVRf3H4IbGCkPQ==", "_location": "/pacote", "_phantomChildren": { "safe-buffer": "5.1.2", @@ -11,12 +11,12 @@ "_requested": { "type": "version", "registry": true, - "raw": "pacote@9.5.8", + "raw": "pacote@9.5.9", "name": "pacote", "escapedName": "pacote", - "rawSpec": "9.5.8", + "rawSpec": "9.5.9", "saveSpec": null, - "fetchSpec": "9.5.8" + "fetchSpec": "9.5.9" }, "_requiredBy": [ "#USER", @@ -24,10 +24,10 @@ "/libcipm", "/libnpm" ], - "_resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.8.tgz", - "_shasum": "23480efdc4fa74515855c9ecf39cf64078f99786", - "_spec": "pacote@9.5.8", - "_where": "/Users/isaacs/dev/npm/cli", + "_resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.9.tgz", + "_shasum": "fa3a08629c9390b2b99769c55b2cc137e1a24df3", + "_spec": "pacote@9.5.9", + "_where": "/Users/ruyadorno/Documents/workspace/cli", "author": { "name": "Kat Marchán", "email": "kzm@sykosomatic.org" @@ -119,5 +119,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "9.5.8" + "version": "9.5.9" } diff --git a/deps/npm/node_modules/parallel-transform/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/parallel-transform/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/parallel-transform/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/parallel-transform/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/parallel-transform/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/parallel-transform/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/parallel-transform/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/parallel-transform/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/process-nextick-args/index.js b/deps/npm/node_modules/process-nextick-args/index.js index ce045c6560a728..5f585e8e767d14 100644 --- a/deps/npm/node_modules/process-nextick-args/index.js +++ b/deps/npm/node_modules/process-nextick-args/index.js @@ -41,3 +41,4 @@ function nextTick(fn, arg1, arg2, arg3) { }); } } + diff --git a/deps/npm/node_modules/promise-inflight/LICENSE b/deps/npm/node_modules/promise-inflight/LICENSE index e0040f6659d374..83e7c4c62903d7 100644 --- a/deps/npm/node_modules/promise-inflight/LICENSE +++ b/deps/npm/node_modules/promise-inflight/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/promise-retry/README.md b/deps/npm/node_modules/promise-retry/README.md index 85c3bc57e85761..c50328374e5649 100644 --- a/deps/npm/node_modules/promise-retry/README.md +++ b/deps/npm/node_modules/promise-retry/README.md @@ -28,7 +28,7 @@ they were rather difficult to use or do not offer an easy way to do conditional ### promiseRetry(fn, [options]) Calls `fn` until the returned promise ends up fulfilled or rejected with an error different than -a `retry` error. +a `retry` error. The `options` argument is an object which maps to the [retry](https://github.com/tim-kos/node-retry) module options: - `retries`: The maximum amount of times to retry the operation. Default is `10`. @@ -38,7 +38,7 @@ The `options` argument is an object which maps to the [retry](https://github.com - `randomize`: Randomizes the timeouts by multiplying with a factor between `1` to `2`. Default is `false`. -The `fn` function will receive a `retry` function as its first argument that should be called with an error whenever you want to retry `fn`. The `retry` function will always throw an error. +The `fn` function will receive a `retry` function as its first argument that should be called with an error whenever you want to retry `fn`. The `retry` function will always throw an error. If there's retries left, it will throw a special `retry` error that will be handled internally to call `fn` again. If there's no retries left, it will throw the actual error passed to it. diff --git a/deps/npm/node_modules/promise-retry/node_modules/retry/Makefile b/deps/npm/node_modules/promise-retry/node_modules/retry/Makefile index 98e7167bbe359f..eee21a99dfc9ec 100644 --- a/deps/npm/node_modules/promise-retry/node_modules/retry/Makefile +++ b/deps/npm/node_modules/promise-retry/node_modules/retry/Makefile @@ -19,3 +19,4 @@ release-patch: test npm publish .PHONY: test + diff --git a/deps/npm/node_modules/promzard/example/substack-input.js b/deps/npm/node_modules/promzard/example/substack-input.js index c049c20f9a2736..bf7aedb82d41fd 100644 --- a/deps/npm/node_modules/promzard/example/substack-input.js +++ b/deps/npm/node_modules/promzard/example/substack-input.js @@ -17,7 +17,7 @@ module.exports = { ; } catch (e) {} - + return prompt('description', value); })(), "main" : prompt('entry point', 'index.js'), diff --git a/deps/npm/node_modules/promzard/promzard.js b/deps/npm/node_modules/promzard/promzard.js index 424152a802eb02..da1abca9535e4f 100644 --- a/deps/npm/node_modules/promzard/promzard.js +++ b/deps/npm/node_modules/promzard/promzard.js @@ -235,3 +235,4 @@ PromZard.prototype.prompt = function (pdt, cb) { read({ prompt: prompt + ':' , default: def }, cb) } + diff --git a/deps/npm/node_modules/promzard/test/simple.js b/deps/npm/node_modules/promzard/test/simple.js index bcf8791113ead7..034a86475afbd5 100644 --- a/deps/npm/node_modules/promzard/test/simple.js +++ b/deps/npm/node_modules/promzard/test/simple.js @@ -3,7 +3,7 @@ var promzard = require('../'); test('simple', function (t) { t.plan(1); - + var ctx = { tmpdir : '/tmp' } var file = __dirname + '/simple.input'; promzard(file, ctx, function (err, output) { @@ -19,11 +19,11 @@ test('simple', function (t) { output ); }); - + setTimeout(function () { process.stdin.emit('data', '\n'); }, 100); - + setTimeout(function () { process.stdin.emit('data', '55\n'); }, 200); diff --git a/deps/npm/node_modules/protoduck/LICENSE b/deps/npm/node_modules/protoduck/LICENSE index 1e0a1d6f8df2f3..ab41caa64b86cf 100644 --- a/deps/npm/node_modules/protoduck/LICENSE +++ b/deps/npm/node_modules/protoduck/LICENSE @@ -18,3 +18,4 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/deps/npm/node_modules/psl/karma.conf.js b/deps/npm/node_modules/psl/karma.conf.js index 4626baf45f86fe..f5b99819c79032 100644 --- a/deps/npm/node_modules/psl/karma.conf.js +++ b/deps/npm/node_modules/psl/karma.conf.js @@ -35,3 +35,4 @@ module.exports = function (config) { }); }; + diff --git a/deps/npm/node_modules/qrcode-terminal/LICENSE b/deps/npm/node_modules/qrcode-terminal/LICENSE index 54831bb9e2bebe..07e74fd549beb4 100644 --- a/deps/npm/node_modules/qrcode-terminal/LICENSE +++ b/deps/npm/node_modules/qrcode-terminal/LICENSE @@ -214,7 +214,7 @@ This product also include the following software: Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php - The word "QR Code" is registered trademark of + The word "QR Code" is registered trademark of DENSO WAVE INCORPORATED http://www.denso-wave.com/qrcode/faqpatent-e.html diff --git a/deps/npm/node_modules/qrcode-terminal/README.md b/deps/npm/node_modules/qrcode-terminal/README.md index 8fdcae2637f038..f5c830f20f45bd 100644 --- a/deps/npm/node_modules/qrcode-terminal/README.md +++ b/deps/npm/node_modules/qrcode-terminal/README.md @@ -23,7 +23,7 @@ To display some data to the terminal just call: qrcode.generate('This will be a QRCode, eh!'); You can even specify the error level (default is 'L'): - + qrcode.setErrorLevel('Q'); qrcode.generate('This will be a QRCode with error level Q!'); @@ -79,3 +79,4 @@ To run tests run `npm test` [travis-ci-url]: https://travis-ci.org/gtanner/qrcode-terminal [basic-example-img]: https://raw.github.com/gtanner/qrcode-terminal/master/example/basic.png [node-qrcode-url]: https://github.com/soldair/node-qrcode + diff --git a/deps/npm/node_modules/qrcode-terminal/example/callback.js b/deps/npm/node_modules/qrcode-terminal/example/callback.js index fe4a2a6c587a79..5aa6814e1be8b3 100644 --- a/deps/npm/node_modules/qrcode-terminal/example/callback.js +++ b/deps/npm/node_modules/qrcode-terminal/example/callback.js @@ -1,4 +1,4 @@ var qrcode = require('../lib/main'); -qrcode.generate('someone sets it up', function (str) { +qrcode.generate('someone sets it up', function (str) { console.log(str); }); diff --git a/deps/npm/node_modules/qrcode-terminal/lib/main.js b/deps/npm/node_modules/qrcode-terminal/lib/main.js index 37c63b1c57ac3d..488cc1aea9802b 100644 --- a/deps/npm/node_modules/qrcode-terminal/lib/main.js +++ b/deps/npm/node_modules/qrcode-terminal/lib/main.js @@ -83,7 +83,7 @@ module.exports = { output += border + '\n'; qrcode.modules.forEach(function (row) { output += white; - output += row.map(toCell).join(''); + output += row.map(toCell).join(''); output += white + '\n'; }); output += border; diff --git a/deps/npm/node_modules/qrcode-terminal/test/main.js b/deps/npm/node_modules/qrcode-terminal/test/main.js index d6d6c45623a261..71cf3f957d165c 100644 --- a/deps/npm/node_modules/qrcode-terminal/test/main.js +++ b/deps/npm/node_modules/qrcode-terminal/test/main.js @@ -57,7 +57,7 @@ describe('in the main module', function() { it('should not allow other levels', function() { qrcode.setErrorLevel = 'something'; expect(qrcode.error).to.be(1); - }); + }); }); }); }); diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js index 8460b910b791f4..94bf74f0e897de 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js @@ -10,7 +10,7 @@ QR8bitByte.prototype = { getLength : function() { return this.data.length; }, - + write : function(buffer) { for (var i = 0; i < this.data.length; i++) { // not JIS ... diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js index 3e857b53457a9f..e2861f68d1b38a 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js @@ -9,28 +9,28 @@ QRBitBuffer.prototype = { var bufIndex = Math.floor(index / 8); return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; }, - + put : function(num, length) { for (var i = 0; i < length; i++) { this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); } }, - + getLengthInBits : function() { return this.length; }, - + putBit : function(bit) { - + var bufIndex = Math.floor(this.length / 8); if (this.buffer.length <= bufIndex) { this.buffer.push(0); } - + if (bit) { this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) ); } - + this.length++; } }; diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js index 14e08fbaa3f37f..9b4b30099d0333 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js @@ -4,3 +4,4 @@ module.exports = { Q : 3, H : 2 }; + diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRMath.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRMath.js index 11e324c9819cf1..8f4a0370ebb32a 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRMath.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRMath.js @@ -1,33 +1,33 @@ var QRMath = { glog : function(n) { - + if (n < 1) { throw new Error("glog(" + n + ")"); } - + return QRMath.LOG_TABLE[n]; }, - + gexp : function(n) { - + while (n < 0) { n += 255; } - + while (n >= 256) { n -= 255; } - + return QRMath.EXP_TABLE[n]; }, - + EXP_TABLE : new Array(256), - + LOG_TABLE : new Array(256) }; - + for (var i = 0; i < 8; i++) { QRMath.EXP_TABLE[i] = 1 << i; } diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js index f8754cbcb46152..0c05f38ef32468 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js @@ -22,42 +22,42 @@ QRPolynomial.prototype = { get : function(index) { return this.num[index]; }, - + getLength : function() { return this.num.length; }, - + multiply : function(e) { - + var num = new Array(this.getLength() + e.getLength() - 1); - + for (var i = 0; i < this.getLength(); i++) { for (var j = 0; j < e.getLength(); j++) { num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i) ) + QRMath.glog(e.get(j) ) ); } } - + return new QRPolynomial(num, 0); }, - + mod : function(e) { - + if (this.getLength() - e.getLength() < 0) { return this; } - + var ratio = QRMath.glog(this.get(0) ) - QRMath.glog(e.get(0) ); - + var num = new Array(this.getLength() ); - + for (var i = 0; i < this.getLength(); i++) { num[i] = this.get(i); } - + for (var x = 0; x < e.getLength(); x++) { num[x] ^= QRMath.gexp(QRMath.glog(e.get(x) ) + ratio); } - + // recursive call return new QRPolynomial(num, 0).mod(e); } diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js index becd24d4dd342e..d150af17460799 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js @@ -17,7 +17,7 @@ QRRSBlock.RS_BLOCK_TABLE = [ [1, 26, 16], [1, 26, 13], [1, 26, 9], - + // 2 [1, 44, 34], [1, 44, 28], @@ -30,43 +30,43 @@ QRRSBlock.RS_BLOCK_TABLE = [ [2, 35, 17], [2, 35, 13], - // 4 + // 4 [1, 100, 80], [2, 50, 32], [2, 50, 24], [4, 25, 9], - + // 5 [1, 134, 108], [2, 67, 43], [2, 33, 15, 2, 34, 16], [2, 33, 11, 2, 34, 12], - + // 6 [2, 86, 68], [4, 43, 27], [4, 43, 19], [4, 43, 15], - - // 7 + + // 7 [2, 98, 78], [4, 49, 31], [2, 32, 14, 4, 33, 15], [4, 39, 13, 1, 40, 14], - + // 8 [2, 121, 97], [2, 60, 38, 2, 61, 39], [4, 40, 18, 2, 41, 19], [4, 40, 14, 2, 41, 15], - + // 9 [2, 146, 116], [3, 58, 36, 2, 59, 37], [4, 36, 16, 4, 37, 17], [4, 36, 12, 4, 37, 13], - - // 10 + + // 10 [2, 86, 68, 2, 87, 69], [4, 69, 43, 1, 70, 44], [6, 43, 19, 2, 44, 20], @@ -254,17 +254,17 @@ QRRSBlock.RS_BLOCK_TABLE = [ ]; QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { - + var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); - + if (rsBlock === undefined) { throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); } var length = rsBlock.length / 3; - + var list = []; - + for (var i = 0; i < length; i++) { var count = rsBlock[i * 3 + 0]; @@ -272,10 +272,10 @@ QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { var dataCount = rsBlock[i * 3 + 2]; for (var j = 0; j < count; j++) { - list.push(new QRRSBlock(totalCount, dataCount) ); + list.push(new QRRSBlock(totalCount, dataCount) ); } } - + return list; }; diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js index 31008cb4667afe..e5b7d5b3cc542b 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js @@ -16,7 +16,7 @@ var QRUtil = { [6, 24, 42], [6, 26, 46], [6, 28, 50], - [6, 30, 54], + [6, 30, 54], [6, 32, 58], [6, 34, 62], [6, 26, 46, 66], @@ -55,7 +55,7 @@ var QRUtil = { getBCHTypeInfo : function(data) { var d = data << 10; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { - d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); + d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); } return ( (data << 10) | d) ^ QRUtil.G15_MASK; }, @@ -63,7 +63,7 @@ var QRUtil = { getBCHTypeNumber : function(data) { var d = data << 12; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { - d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); + d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); } return (data << 12) | d; }, @@ -85,9 +85,9 @@ var QRUtil = { }, getMask : function(maskPattern, i, j) { - + switch (maskPattern) { - + case QRMaskPattern.PATTERN000 : return (i + j) % 2 === 0; case QRMaskPattern.PATTERN001 : return i % 2 === 0; case QRMaskPattern.PATTERN010 : return j % 3 === 0; @@ -160,15 +160,15 @@ var QRUtil = { }, getLostPoint : function(qrCode) { - + var moduleCount = qrCode.getModuleCount(); var lostPoint = 0; - var row = 0; + var row = 0; var col = 0; - + // LEVEL1 - + for (row = 0; row < moduleCount; row++) { for (col = 0; col < moduleCount; col++) { @@ -223,12 +223,12 @@ var QRUtil = { for (row = 0; row < moduleCount; row++) { for (col = 0; col < moduleCount - 6; col++) { - if (qrCode.isDark(row, col) && - !qrCode.isDark(row, col + 1) && - qrCode.isDark(row, col + 2) && - qrCode.isDark(row, col + 3) && - qrCode.isDark(row, col + 4) && - !qrCode.isDark(row, col + 5) && + if (qrCode.isDark(row, col) && + !qrCode.isDark(row, col + 1) && + qrCode.isDark(row, col + 2) && + qrCode.isDark(row, col + 3) && + qrCode.isDark(row, col + 4) && + !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6) ) { lostPoint += 40; } @@ -250,7 +250,7 @@ var QRUtil = { } // LEVEL4 - + var darkCount = 0; for (col = 0; col < moduleCount; col++) { @@ -260,11 +260,11 @@ var QRUtil = { } } } - + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; lostPoint += ratio * 10; - return lostPoint; + return lostPoint; } }; diff --git a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/index.js b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/index.js index 0fb6c39362e079..10eb8eb0a06aa5 100644 --- a/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/index.js +++ b/deps/npm/node_modules/qrcode-terminal/vendor/QRCode/index.js @@ -8,7 +8,7 @@ // Licensed under the MIT license: // http://www.opensource.org/licenses/mit-license.php // -// The word "QR Code" is registered trademark of +// The word "QR Code" is registered trademark of // DENSO WAVE INCORPORATED // http://www.denso-wave.com/qrcode/faqpatent-e.html // @@ -32,13 +32,13 @@ function QRCode(typeNumber, errorCorrectLevel) { } QRCode.prototype = { - + addData : function(data) { var newData = new QR8bitByte(data); this.dataList.push(newData); this.dataCache = null; }, - + isDark : function(row, col) { if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { throw new Error(row + "," + col); @@ -49,7 +49,7 @@ QRCode.prototype = { getModuleCount : function() { return this.moduleCount; }, - + make : function() { // Calculate automatically typeNumber if provided is < 1 if (this.typeNumber < 1 ){ @@ -76,96 +76,96 @@ QRCode.prototype = { } this.makeImpl(false, this.getBestMaskPattern() ); }, - + makeImpl : function(test, maskPattern) { - + this.moduleCount = this.typeNumber * 4 + 17; this.modules = new Array(this.moduleCount); - + for (var row = 0; row < this.moduleCount; row++) { - + this.modules[row] = new Array(this.moduleCount); - + for (var col = 0; col < this.moduleCount; col++) { this.modules[row][col] = null;//(col + row) % 3; } } - + this.setupPositionProbePattern(0, 0); this.setupPositionProbePattern(this.moduleCount - 7, 0); this.setupPositionProbePattern(0, this.moduleCount - 7); this.setupPositionAdjustPattern(); this.setupTimingPattern(); this.setupTypeInfo(test, maskPattern); - + if (this.typeNumber >= 7) { this.setupTypeNumber(test); } - + if (this.dataCache === null) { this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); } - + this.mapData(this.dataCache, maskPattern); }, setupPositionProbePattern : function(row, col) { - + for (var r = -1; r <= 7; r++) { - + if (row + r <= -1 || this.moduleCount <= row + r) continue; - + for (var c = -1; c <= 7; c++) { - + if (col + c <= -1 || this.moduleCount <= col + c) continue; - - if ( (0 <= r && r <= 6 && (c === 0 || c === 6) ) || - (0 <= c && c <= 6 && (r === 0 || r === 6) ) || + + if ( (0 <= r && r <= 6 && (c === 0 || c === 6) ) || + (0 <= c && c <= 6 && (r === 0 || r === 6) ) || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { this.modules[row + r][col + c] = true; } else { this.modules[row + r][col + c] = false; } - } - } + } + } }, - + getBestMaskPattern : function() { - + var minLostPoint = 0; var pattern = 0; - + for (var i = 0; i < 8; i++) { - + this.makeImpl(true, i); - + var lostPoint = QRUtil.getLostPoint(this); - + if (i === 0 || minLostPoint > lostPoint) { minLostPoint = lostPoint; pattern = i; } } - + return pattern; }, - + createMovieClip : function(target_mc, instance_name, depth) { - + var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); var cs = 1; - + this.make(); for (var row = 0; row < this.modules.length; row++) { - + var y = row * cs; - + for (var col = 0; col < this.modules[row].length; col++) { - + var x = col * cs; var dark = this.modules[row][col]; - + if (dark) { qr_mc.beginFill(0, 100); qr_mc.moveTo(x, y); @@ -176,19 +176,19 @@ QRCode.prototype = { } } } - + return qr_mc; }, setupTimingPattern : function() { - + for (var r = 8; r < this.moduleCount - 8; r++) { if (this.modules[r][6] !== null) { continue; } this.modules[r][6] = (r % 2 === 0); } - + for (var c = 8; c < this.moduleCount - 8; c++) { if (this.modules[6][c] !== null) { continue; @@ -196,27 +196,27 @@ QRCode.prototype = { this.modules[6][c] = (c % 2 === 0); } }, - + setupPositionAdjustPattern : function() { - + var pos = QRUtil.getPatternPosition(this.typeNumber); - + for (var i = 0; i < pos.length; i++) { - + for (var j = 0; j < pos.length; j++) { - + var row = pos[i]; var col = pos[j]; - + if (this.modules[row][col] !== null) { continue; } - + for (var r = -2; r <= 2; r++) { - + for (var c = -2; c <= 2; c++) { - - if (Math.abs(r) === 2 || + + if (Math.abs(r) === 2 || Math.abs(c) === 2 || (r === 0 && c === 0) ) { this.modules[row + r][col + c] = true; @@ -228,34 +228,34 @@ QRCode.prototype = { } } }, - + setupTypeNumber : function(test) { - + var bits = QRUtil.getBCHTypeNumber(this.typeNumber); var mod; - + for (var i = 0; i < 18; i++) { mod = (!test && ( (bits >> i) & 1) === 1); this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; } - + for (var x = 0; x < 18; x++) { mod = (!test && ( (bits >> x) & 1) === 1); this.modules[x % 3 + this.moduleCount - 8 - 3][Math.floor(x / 3)] = mod; } }, - + setupTypeInfo : function(test, maskPattern) { - + var data = (this.errorCorrectLevel << 3) | maskPattern; var bits = QRUtil.getBCHTypeInfo(data); var mod; - - // vertical + + // vertical for (var v = 0; v < 15; v++) { - + mod = (!test && ( (bits >> v) & 1) === 1); - + if (v < 6) { this.modules[v][8] = mod; } else if (v < 8) { @@ -264,12 +264,12 @@ QRCode.prototype = { this.modules[this.moduleCount - 15 + v][8] = mod; } } - + // horizontal for (var h = 0; h < 15; h++) { - + mod = (!test && ( (bits >> h) & 1) === 1); - + if (h < 8) { this.modules[8][this.moduleCount - h - 1] = mod; } else if (h < 9) { @@ -278,53 +278,53 @@ QRCode.prototype = { this.modules[8][15 - h - 1] = mod; } } - + // fixed module this.modules[this.moduleCount - 8][8] = (!test); - + }, - + mapData : function(data, maskPattern) { - + var inc = -1; var row = this.moduleCount - 1; var bitIndex = 7; var byteIndex = 0; - + for (var col = this.moduleCount - 1; col > 0; col -= 2) { - + if (col === 6) col--; - + while (true) { - + for (var c = 0; c < 2; c++) { - + if (this.modules[row][col - c] === null) { - + var dark = false; - + if (byteIndex < data.length) { dark = ( ( (data[byteIndex] >>> bitIndex) & 1) === 1); } - + var mask = QRUtil.getMask(maskPattern, row, col - c); - + if (mask) { dark = !dark; } - + this.modules[row][col - c] = dark; bitIndex--; - + if (bitIndex === -1) { byteIndex++; bitIndex = 7; } } } - + row += inc; - + if (row < 0 || this.moduleCount <= row) { row -= inc; inc = -inc; @@ -332,7 +332,7 @@ QRCode.prototype = { } } } - + } }; @@ -341,11 +341,11 @@ QRCode.PAD0 = 0xEC; QRCode.PAD1 = 0x11; QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { - + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); - + var buffer = new QRBitBuffer(); - + for (var i = 0; i < dataList.length; i++) { var data = dataList[i]; buffer.put(data.mode, 4); @@ -360,10 +360,10 @@ QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { } if (buffer.getLengthInBits() > totalDataCount * 8) { - throw new Error("code length overflow. (" + - buffer.getLengthInBits() + - ">" + - totalDataCount * 8 + + throw new Error("code length overflow. (" + + buffer.getLengthInBits() + + ">" + + totalDataCount * 8 + ")"); } @@ -379,12 +379,12 @@ QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { // padding while (true) { - + if (buffer.getLengthInBits() >= totalDataCount * 8) { break; } buffer.put(QRCode.PAD0, 8); - + if (buffer.getLengthInBits() >= totalDataCount * 8) { break; } @@ -397,13 +397,13 @@ QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { QRCode.createBytes = function(buffer, rsBlocks) { var offset = 0; - + var maxDcCount = 0; var maxEcCount = 0; - + var dcdata = new Array(rsBlocks.length); var ecdata = new Array(rsBlocks.length); - + for (var r = 0; r < rsBlocks.length; r++) { var dcCount = rsBlocks[r].dataCount; @@ -411,14 +411,14 @@ QRCode.createBytes = function(buffer, rsBlocks) { maxDcCount = Math.max(maxDcCount, dcCount); maxEcCount = Math.max(maxEcCount, ecCount); - + dcdata[r] = new Array(dcCount); - + for (var i = 0; i < dcdata[r].length; i++) { dcdata[r][i] = 0xff & buffer.buffer[i + offset]; } offset += dcCount; - + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); @@ -430,7 +430,7 @@ QRCode.createBytes = function(buffer, rsBlocks) { } } - + var totalCodeCount = 0; for (var y = 0; y < rsBlocks.length; y++) { totalCodeCount += rsBlocks[y].totalCount; diff --git a/deps/npm/node_modules/qw/LICENSE b/deps/npm/node_modules/qw/LICENSE index 74bf5afb713c4f..51bcf57ee3d16a 100644 --- a/deps/npm/node_modules/qw/LICENSE +++ b/deps/npm/node_modules/qw/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/qw/README.md b/deps/npm/node_modules/qw/README.md index 55ba17a91f7865..e42fc66d52d3e4 100644 --- a/deps/npm/node_modules/qw/README.md +++ b/deps/npm/node_modules/qw/README.md @@ -32,3 +32,4 @@ const mywords = [ 'product=' + (23 * 5), 'also', '"escaping a string"' ] This uses template strings to bring over this little common convenience from Perl-land. + diff --git a/deps/npm/node_modules/rc/LICENSE.BSD b/deps/npm/node_modules/rc/LICENSE.BSD index c6f2e5490c08d3..96bb796aa5f2d2 100644 --- a/deps/npm/node_modules/rc/LICENSE.BSD +++ b/deps/npm/node_modules/rc/LICENSE.BSD @@ -2,13 +2,13 @@ Copyright (c) 2013, Dominic Tarr All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -22,5 +22,5 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, +of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. diff --git a/deps/npm/node_modules/rc/LICENSE.MIT b/deps/npm/node_modules/rc/LICENSE.MIT index 49e7da41fec2be..6eafbd734a6e06 100644 --- a/deps/npm/node_modules/rc/LICENSE.MIT +++ b/deps/npm/node_modules/rc/LICENSE.MIT @@ -2,23 +2,23 @@ The MIT License Copyright (c) 2011 Dominic Tarr -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/rc/README.md b/deps/npm/node_modules/rc/README.md index 0a411d3629baf6..e6522e26788f14 100644 --- a/deps/npm/node_modules/rc/README.md +++ b/deps/npm/node_modules/rc/README.md @@ -191,7 +191,7 @@ Here is the expected output from various commands: } ``` *Now the `port` comes from the `config.json` file specified (overriding the value from `.myapprc`), and `foo` value is overriden by command-line despite also being specified in the `config.json` file.* - + ## Advanced Usage @@ -219,7 +219,7 @@ such as strict, valid JSON only. ## Note on Performance -`rc` is running `fs.statSync`-- so make sure you don't use it in a hot code path (e.g. a request handler) +`rc` is running `fs.statSync`-- so make sure you don't use it in a hot code path (e.g. a request handler) ## License diff --git a/deps/npm/node_modules/rc/browser.js b/deps/npm/node_modules/rc/browser.js index 9ea1a3e395db5b..8c230c5cd2d397 100644 --- a/deps/npm/node_modules/rc/browser.js +++ b/deps/npm/node_modules/rc/browser.js @@ -1,5 +1,5 @@ -// when this is loaded into the browser, +// when this is loaded into the browser, // just use the defaults... module.exports = function (name, defaults) { diff --git a/deps/npm/node_modules/rc/lib/utils.js b/deps/npm/node_modules/rc/lib/utils.js index 52c201f7e18066..8b3beffa3295b6 100644 --- a/deps/npm/node_modules/rc/lib/utils.js +++ b/deps/npm/node_modules/rc/lib/utils.js @@ -100,3 +100,5 @@ var find = exports.find = function () { } return find(process.cwd(), rel) } + + diff --git a/deps/npm/node_modules/rc/node_modules/minimist/index.js b/deps/npm/node_modules/rc/node_modules/minimist/index.js index e06783fb1c7499..6a0559d58133a8 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/index.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/index.js @@ -1,6 +1,6 @@ module.exports = function (args, opts) { if (!opts) opts = {}; - + var flags = { bools : {}, strings : {}, unknownFn: null }; if (typeof opts['unknown'] === 'function') { @@ -14,7 +14,7 @@ module.exports = function (args, opts) { flags.bools[key] = true; }); } - + var aliases = {}; Object.keys(opts.alias || {}).forEach(function (key) { aliases[key] = [].concat(opts.alias[key]); @@ -33,12 +33,12 @@ module.exports = function (args, opts) { }); var defaults = opts['default'] || {}; - + var argv = { _ : [] }; Object.keys(flags.bools).forEach(function (key) { setArg(key, defaults[key] === undefined ? false : defaults[key]); }); - + var notFlags = []; if (args.indexOf('--') !== -1) { @@ -60,7 +60,7 @@ module.exports = function (args, opts) { ? Number(val) : val ; setKey(argv, key.split('.'), value); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), value); }); @@ -84,7 +84,7 @@ module.exports = function (args, opts) { o[key] = [ o[key], value ]; } } - + function aliasIsBoolean(key) { return aliases[key].some(function (x) { return flags.bools[x]; @@ -93,7 +93,7 @@ module.exports = function (args, opts) { for (var i = 0; i < args.length; i++) { var arg = args[i]; - + if (/^--.+=/.test(arg)) { // Using [\s\S] instead of . because js doesn't support the // 'dotall' regex modifier. See: @@ -130,29 +130,29 @@ module.exports = function (args, opts) { } else if (/^-[^-]+/.test(arg)) { var letters = arg.slice(1,-1).split(''); - + var broken = false; for (var j = 0; j < letters.length; j++) { var next = arg.slice(j+2); - + if (next === '-') { setArg(letters[j], next, arg) continue; } - + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { setArg(letters[j], next.split('=')[1], arg); broken = true; break; } - + if (/[A-Za-z]/.test(letters[j]) && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { setArg(letters[j], next, arg); broken = true; break; } - + if (letters[j+1] && letters[j+1].match(/\W/)) { setArg(letters[j], arg.slice(j+2), arg); broken = true; @@ -162,7 +162,7 @@ module.exports = function (args, opts) { setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); } } - + var key = arg.slice(-1)[0]; if (!broken && key !== '-') { if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) @@ -192,17 +192,17 @@ module.exports = function (args, opts) { } } } - + Object.keys(defaults).forEach(function (key) { if (!hasKey(argv, key.split('.'))) { setKey(argv, key.split('.'), defaults[key]); - + (aliases[key] || []).forEach(function (x) { setKey(argv, x.split('.'), defaults[key]); }); } }); - + if (opts['--']) { argv['--'] = new Array(); notFlags.forEach(function(key) { @@ -233,3 +233,4 @@ function isNumber (x) { if (/^0x[0-9a-f]+$/i.test(x)) return true; return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); } + diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/all_bool.js b/deps/npm/node_modules/rc/node_modules/minimist/test/all_bool.js index 25df1654bc99d9..ac835483d9a659 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/all_bool.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/all_bool.js @@ -5,12 +5,12 @@ test('flag boolean true (default all --args to boolean)', function (t) { var argv = parse(['moo', '--honk', 'cow'], { boolean: true }); - + t.deepEqual(argv, { honk: true, _: ['moo', 'cow'] }); - + t.deepEqual(typeof argv.honk, 'boolean'); t.end(); }); @@ -19,14 +19,14 @@ test('flag boolean true only affects double hyphen arguments without equals sign var argv = parse(['moo', '--honk', 'cow', '-p', '55', '--tacos=good'], { boolean: true }); - + t.deepEqual(argv, { honk: true, tacos: 'good', p: 55, _: ['moo', 'cow'] }); - + t.deepEqual(typeof argv.honk, 'boolean'); t.end(); }); diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/bool.js b/deps/npm/node_modules/rc/node_modules/minimist/test/bool.js index 6e793e4b640eb6..14b0717cefd5e9 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/bool.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/bool.js @@ -6,13 +6,13 @@ test('flag boolean default false', function (t) { boolean: ['t', 'verbose'], default: { verbose: false, t: false } }); - + t.deepEqual(argv, { verbose: false, t: false, _: ['moo'] }); - + t.deepEqual(typeof argv.verbose, 'boolean'); t.deepEqual(typeof argv.t, 'boolean'); t.end(); @@ -23,14 +23,14 @@ test('boolean groups', function (t) { var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], { boolean: ['x','y','z'] }); - + t.deepEqual(argv, { x : true, y : false, z : true, _ : [ 'one', 'two', 'three' ] }); - + t.deepEqual(typeof argv.x, 'boolean'); t.deepEqual(typeof argv.y, 'boolean'); t.deepEqual(typeof argv.z, 'boolean'); @@ -55,9 +55,9 @@ test('boolean and alias with chainable api', function (t) { h: true, '_': [ 'derp' ] }; - + t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); + t.same(propertyArgv, expected); t.end(); }); @@ -119,7 +119,7 @@ test('boolean and alias using explicit true', function (t) { }; t.same(aliasedArgv, expected); - t.same(propertyArgv, expected); + t.same(propertyArgv, expected); t.end(); }); @@ -135,7 +135,7 @@ test('boolean and --x=true', function(t) { parsed = parse(['--boool', '--other=false'], { boolean: 'boool' }); - + t.same(parsed.boool, true); t.same(parsed.other, 'false'); t.end(); diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/kv_short.js b/deps/npm/node_modules/rc/node_modules/minimist/test/kv_short.js index ae880be4661dd5..f813b305057b0a 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/kv_short.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/kv_short.js @@ -3,14 +3,14 @@ var test = require('tape'); test('short -k=v' , function (t) { t.plan(1); - + var argv = parse([ '-b=123' ]); t.deepEqual(argv, { b: 123, _: [] }); }); test('multi short -k=v' , function (t) { t.plan(1); - + var argv = parse([ '-a=whatever', '-b=robots' ]); t.deepEqual(argv, { a: 'whatever', b: 'robots', _: [] }); }); diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/parse.js b/deps/npm/node_modules/rc/node_modules/minimist/test/parse.js index 58f24572c47d86..7b4a2a17c0dda5 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/parse.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/parse.js @@ -14,7 +14,7 @@ test('parse args', function (t) { ); t.end(); }); - + test('comprehensive', function (t) { t.deepEqual( parse([ @@ -54,13 +54,13 @@ test('flag boolean value', function (t) { boolean: [ 't', 'verbose' ], default: { verbose: true } }); - + t.deepEqual(argv, { verbose: false, t: true, _: ['moo'] }); - + t.deepEqual(typeof argv.verbose, 'boolean'); t.deepEqual(typeof argv.t, 'boolean'); t.end(); @@ -69,7 +69,7 @@ test('flag boolean value', function (t) { test('newlines in params' , function (t) { var args = parse([ '-s', "X\nX" ]) t.deepEqual(args, { _ : [], s : "X\nX" }); - + // reproduce in bash: // VALUE="new // line" @@ -83,7 +83,7 @@ test('strings' , function (t) { var s = parse([ '-s', '0001234' ], { string: 's' }).s; t.equal(s, '0001234'); t.equal(typeof s, 'string'); - + var x = parse([ '-x', '56' ], { string: 'x' }).x; t.equal(x, '56'); t.equal(typeof x, 'string'); @@ -183,7 +183,7 @@ test('nested dotted objects', function (t) { '--foo.quux.quibble', '5', '--foo.quux.o_O', '--beep.boop' ]); - + t.same(argv.foo, { bar : 3, baz : 4, diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/parse_modified.js b/deps/npm/node_modules/rc/node_modules/minimist/test/parse_modified.js index a22248532f0c6f..ab620dc5e4dc39 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/parse_modified.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/parse_modified.js @@ -3,7 +3,7 @@ var test = require('tape'); test('parse with modifier functions' , function (t) { t.plan(1); - + var argv = parse([ '-b', '123' ], { boolean: 'b' }); t.deepEqual(argv, { b: true, _: [123] }); }); diff --git a/deps/npm/node_modules/rc/node_modules/minimist/test/short.js b/deps/npm/node_modules/rc/node_modules/minimist/test/short.js index ac18880f1eb50c..d513a1c2529095 100644 --- a/deps/npm/node_modules/rc/node_modules/minimist/test/short.js +++ b/deps/npm/node_modules/rc/node_modules/minimist/test/short.js @@ -43,7 +43,7 @@ test('short', function (t) { ); t.end(); }); - + test('mixed short bool and capture', function (t) { t.same( parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), @@ -54,7 +54,7 @@ test('mixed short bool and capture', function (t) { ); t.end(); }); - + test('short and long', function (t) { t.deepEqual( parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), diff --git a/deps/npm/node_modules/rc/test/ini.js b/deps/npm/node_modules/rc/test/ini.js index cdb1990062d69a..e6857f8b382cf9 100644 --- a/deps/npm/node_modules/rc/test/ini.js +++ b/deps/npm/node_modules/rc/test/ini.js @@ -13,3 +13,4 @@ function test(obj) { test({hello: true}) + diff --git a/deps/npm/node_modules/read-cmd-shim/LICENSE b/deps/npm/node_modules/read-cmd-shim/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/read-cmd-shim/LICENSE +++ b/deps/npm/node_modules/read-cmd-shim/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/read-cmd-shim/index.js b/deps/npm/node_modules/read-cmd-shim/index.js index f565ababe4e035..3af2512f6cb432 100644 --- a/deps/npm/node_modules/read-cmd-shim/index.js +++ b/deps/npm/node_modules/read-cmd-shim/index.js @@ -4,11 +4,18 @@ var fs = require('graceful-fs') function extractPath (path, cmdshimContents) { if (/[.]cmd$/.test(path)) { return extractPathFromCmd(cmdshimContents) + } else if (/[.]ps1$/.test(path)) { + return extractPathFromPowershell(cmdshimContents) } else { return extractPathFromCygwin(cmdshimContents) } } +function extractPathFromPowershell (cmdshimContents) { + var matches = cmdshimContents.match(/"[$]basedir[/]([^"]+?)"\s+[$]args/) + return matches && matches[1] +} + function extractPathFromCmd (cmdshimContents) { var matches = cmdshimContents.match(/"%(?:~dp0|dp0%)\\([^"]+?)"\s+%[*]/) return matches && matches[1] diff --git a/deps/npm/node_modules/read-cmd-shim/package.json b/deps/npm/node_modules/read-cmd-shim/package.json index df2fe27e7b1705..101651109d4ff5 100644 --- a/deps/npm/node_modules/read-cmd-shim/package.json +++ b/deps/npm/node_modules/read-cmd-shim/package.json @@ -1,29 +1,29 @@ { - "_from": "read-cmd-shim@1.0.4", - "_id": "read-cmd-shim@1.0.4", + "_from": "read-cmd-shim@1.0.5", + "_id": "read-cmd-shim@1.0.5", "_inBundle": false, - "_integrity": "sha512-Pqpl3qJ/QdOIjRYA0q5DND/gLvGOfpIz/fYVDGYpOXfW/lFrIttmLsBnd6IkyK10+JHU9zhsaudfvrQTBB9YFQ==", + "_integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==", "_location": "/read-cmd-shim", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "read-cmd-shim@1.0.4", + "raw": "read-cmd-shim@1.0.5", "name": "read-cmd-shim", "escapedName": "read-cmd-shim", - "rawSpec": "1.0.4", + "rawSpec": "1.0.5", "saveSpec": null, - "fetchSpec": "1.0.4" + "fetchSpec": "1.0.5" }, "_requiredBy": [ "#USER", "/", "/gentle-fs" ], - "_resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.4.tgz", - "_shasum": "b4a53d43376211b45243f0072b6e603a8e37640d", - "_spec": "read-cmd-shim@1.0.4", - "_where": "/Users/claudiahdz/npm/cli", + "_resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz", + "_shasum": "87e43eba50098ba5a32d0ceb583ab8e43b961c16", + "_spec": "read-cmd-shim@1.0.5", + "_where": "/Users/ruyadorno/Documents/workspace/cli", "author": { "name": "Rebecca Turner", "email": "me@re-becca.org", @@ -59,5 +59,5 @@ "pretest": "standard", "test": "tap test/*.js --100" }, - "version": "1.0.4" + "version": "1.0.5" } diff --git a/deps/npm/node_modules/require-directory/README.markdown b/deps/npm/node_modules/require-directory/README.markdown index 879844560f0c3b..926a063ed1f897 100644 --- a/deps/npm/node_modules/require-directory/README.markdown +++ b/deps/npm/node_modules/require-directory/README.markdown @@ -181,3 +181,4 @@ $ npm test ## Author [Troy Goode](https://github.com/TroyGoode) ([troygoode@gmail.com](mailto:troygoode@gmail.com)) + diff --git a/deps/npm/node_modules/retry/Readme.md b/deps/npm/node_modules/retry/Readme.md index 1c888deee9c9d4..16e28ec267d6da 100644 --- a/deps/npm/node_modules/retry/Readme.md +++ b/deps/npm/node_modules/retry/Readme.md @@ -66,7 +66,7 @@ Creates a new `RetryOperation` object. `options` is the same as `retry.timeouts( * `forever`: Whether to retry forever, defaults to `false`. * `unref`: Whether to [unref](https://nodejs.org/api/timers.html#timers_unref) the setTimeout's, defaults to `false`. -* `maxRetryTime`: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is `Infinity`. +* `maxRetryTime`: The maximum time (in milliseconds) that the retried operation is allowed to run. Default is `Infinity`. ### retry.timeouts([options]) diff --git a/deps/npm/node_modules/run-queue/node_modules/aproba/LICENSE b/deps/npm/node_modules/run-queue/node_modules/aproba/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/run-queue/node_modules/aproba/LICENSE +++ b/deps/npm/node_modules/run-queue/node_modules/aproba/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/run-queue/node_modules/aproba/README.md b/deps/npm/node_modules/run-queue/node_modules/aproba/README.md index e94799201ce046..0bfc594c56a372 100644 --- a/deps/npm/node_modules/run-queue/node_modules/aproba/README.md +++ b/deps/npm/node_modules/run-queue/node_modules/aproba/README.md @@ -84,10 +84,11 @@ I wanted a very simple argument validator. It needed to do two things: 2. Not encourage an infinite bikeshed of DSLs This is why types are specified by a single character and there's no such -thing as an optional argument. +thing as an optional argument. This is not intended to validate user data. This is specifically about asserting the interface of your functions. If you need greater validation, I encourage you to write them by hand or look elsewhere. + diff --git a/deps/npm/node_modules/smart-buffer/.travis.yml b/deps/npm/node_modules/smart-buffer/.travis.yml index 19111ce3999177..eec71cecaab482 100644 --- a/deps/npm/node_modules/smart-buffer/.travis.yml +++ b/deps/npm/node_modules/smart-buffer/.travis.yml @@ -1,8 +1,9 @@ language: node_js node_js: - - 4 - 6 - - 7 + - 8 + - 10 + - 12 - stable before_script: diff --git a/deps/npm/node_modules/smart-buffer/build/smartbuffer.js b/deps/npm/node_modules/smart-buffer/build/smartbuffer.js index b1fcead2aa2bc4..fc7d3aa0267dae 100644 --- a/deps/npm/node_modules/smart-buffer/build/smartbuffer.js +++ b/deps/npm/node_modules/smart-buffer/build/smartbuffer.js @@ -144,6 +144,26 @@ class SmartBuffer { readInt32LE(offset) { return this._readNumberValue(Buffer.prototype.readInt32LE, 4, offset); } + /** + * Reads a BigInt64BE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigInt64BE(offset) { + utils_1.bigIntAndBufferInt64Check('readBigInt64BE'); + return this._readNumberValue(Buffer.prototype.readBigInt64BE, 8, offset); + } + /** + * Reads a BigInt64LE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigInt64LE(offset) { + utils_1.bigIntAndBufferInt64Check('readBigInt64LE'); + return this._readNumberValue(Buffer.prototype.readBigInt64LE, 8, offset); + } /** * Writes an Int8 value to the current write position (or at optional offset). * @@ -255,6 +275,54 @@ class SmartBuffer { insertInt32LE(value, offset) { return this._insertNumberValue(Buffer.prototype.writeInt32LE, 4, value, offset); } + /** + * Writes a BigInt64BE value to the current write position (or at optional offset). + * + * @param value { BigInt } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigInt64BE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigInt64BE'); + return this._writeNumberValue(Buffer.prototype.writeBigInt64BE, 8, value, offset); + } + /** + * Inserts a BigInt64BE value at the given offset value. + * + * @param value { BigInt } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigInt64BE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigInt64BE'); + return this._insertNumberValue(Buffer.prototype.writeBigInt64BE, 8, value, offset); + } + /** + * Writes a BigInt64LE value to the current write position (or at optional offset). + * + * @param value { BigInt } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigInt64LE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigInt64LE'); + return this._writeNumberValue(Buffer.prototype.writeBigInt64LE, 8, value, offset); + } + /** + * Inserts a Int64LE value at the given offset value. + * + * @param value { BigInt } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigInt64LE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigInt64LE'); + return this._insertNumberValue(Buffer.prototype.writeBigInt64LE, 8, value, offset); + } // Unsigned Integers /** * Reads an UInt8 value from the current read position or an optionally provided offset. @@ -301,6 +369,26 @@ class SmartBuffer { readUInt32LE(offset) { return this._readNumberValue(Buffer.prototype.readUInt32LE, 4, offset); } + /** + * Reads a BigUInt64BE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigUInt64BE(offset) { + utils_1.bigIntAndBufferInt64Check('readBigUInt64BE'); + return this._readNumberValue(Buffer.prototype.readBigUInt64BE, 8, offset); + } + /** + * Reads a BigUInt64LE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigUInt64LE(offset) { + utils_1.bigIntAndBufferInt64Check('readBigUInt64LE'); + return this._readNumberValue(Buffer.prototype.readBigUInt64LE, 8, offset); + } /** * Writes an UInt8 value to the current write position (or at optional offset). * @@ -411,6 +499,54 @@ class SmartBuffer { insertUInt32LE(value, offset) { return this._insertNumberValue(Buffer.prototype.writeUInt32LE, 4, value, offset); } + /** + * Writes a BigUInt64BE value to the current write position (or at optional offset). + * + * @param value { Number } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigUInt64BE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigUInt64BE'); + return this._writeNumberValue(Buffer.prototype.writeBigUInt64BE, 8, value, offset); + } + /** + * Inserts a BigUInt64BE value at the given offset value. + * + * @param value { Number } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigUInt64BE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigUInt64BE'); + return this._insertNumberValue(Buffer.prototype.writeBigUInt64BE, 8, value, offset); + } + /** + * Writes a BigUInt64LE value to the current write position (or at optional offset). + * + * @param value { Number } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigUInt64LE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigUInt64LE'); + return this._writeNumberValue(Buffer.prototype.writeBigUInt64LE, 8, value, offset); + } + /** + * Inserts a BigUInt64LE value at the given offset value. + * + * @param value { Number } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigUInt64LE(value, offset) { + utils_1.bigIntAndBufferInt64Check('writeBigUInt64LE'); + return this._insertNumberValue(Buffer.prototype.writeBigUInt64LE, 8, value, offset); + } // Floating Point /** * Reads an FloatBE value from the current read position or an optionally provided offset. @@ -1015,11 +1151,13 @@ class SmartBuffer { /** * Reads a numeric number value using the provided function. * + * @typeparam T { number | bigint } The type of the value to be read + * * @param func { Function(offset: number) => number } The function to read data on the internal Buffer with. * @param byteSize { Number } The number of bytes read. * @param offset { Number } The offset to read from (optional). When this is not provided, the managed readOffset is used instead. * - * @param { Number } + * @returns { T } the number value */ _readNumberValue(func, byteSize, offset) { this.ensureReadable(byteSize, offset); @@ -1034,11 +1172,14 @@ class SmartBuffer { /** * Inserts a numeric number value based on the given offset and value. * - * @param func { Function(offset: number, offset?) => number} The function to write data on the internal Buffer with. + * @typeparam T { number | bigint } The type of the value to be written + * + * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. * @param byteSize { Number } The number of bytes written. - * @param value { Number } The number value to write. + * @param value { T } The number value to write. * @param offset { Number } the offset to write the number at (REQUIRED). * + * @returns SmartBuffer this buffer */ _insertNumberValue(func, byteSize, value, offset) { // Check for invalid offset values. @@ -1054,11 +1195,14 @@ class SmartBuffer { /** * Writes a numeric number value based on the given offset and value. * - * @param func { Function(offset: number, offset?) => number} The function to write data on the internal Buffer with. + * @typeparam T { number | bigint } The type of the value to be written + * + * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. * @param byteSize { Number } The number of bytes written. - * @param value { Number } The number value to write. + * @param value { T } The number value to write. * @param offset { Number } the offset to write the number at (REQUIRED). * + * @returns SmartBuffer this buffer */ _writeNumberValue(func, byteSize, value, offset) { // If an offset was provided, validate it. diff --git a/deps/npm/node_modules/smart-buffer/build/smartbuffer.js.map b/deps/npm/node_modules/smart-buffer/build/smartbuffer.js.map index cf6ee6eca1720d..b4c68c7acf4de5 100644 --- a/deps/npm/node_modules/smart-buffer/build/smartbuffer.js.map +++ b/deps/npm/node_modules/smart-buffer/build/smartbuffer.js.map @@ -1 +1 @@ -{"version":3,"file":"smartbuffer.js","sourceRoot":"","sources":["../src/smartbuffer.ts"],"names":[],"mappings":";;AAAA,mCAAwH;AAcxH,kDAAkD;AAClD,MAAM,wBAAwB,GAAW,IAAI,CAAC;AAE9C,kEAAkE;AAClE,MAAM,4BAA4B,GAAmB,MAAM,CAAC;AAE5D;IAQE;;;;OAIG;IACH,YAAY,OAA4B;QAZjC,WAAM,GAAW,CAAC,CAAC;QAElB,cAAS,GAAmB,4BAA4B,CAAC;QAEzD,iBAAY,GAAW,CAAC,CAAC;QACzB,gBAAW,GAAW,CAAC,CAAC;QAQ9B,EAAE,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC9C,sBAAsB;YACtB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACrB,qBAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;YACpC,CAAC;YAED,iCAAiC;YACjC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACjB,EAAE,CAAC,CAAC,uBAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;oBACtD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChD,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,wBAAwB,CAAC,CAAC;gBACnD,CAAC;gBACD,2BAA2B;YAC7B,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxB,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,YAAY,MAAM,CAAC,CAAC,CAAC;oBACnC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;oBAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;gBACpC,CAAC;gBAAC,IAAI,CAAC,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,mEAAmE;YACnE,EAAE,CAAC,CAAC,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;YACrD,CAAC;YAED,oCAAoC;YACpC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,QAAyB;QAC5D,MAAM,CAAC,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,UAAU,CAAC,IAAY,EAAE,QAAyB;QAC9D,MAAM,CAAC,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,OAA2B;QACnD,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAA2B;QACrD,MAAM,WAAW,GAAuB,OAAO,CAAC;QAEhD,MAAM,CAAC,CACL,WAAW;YACX,CAAC,WAAW,CAAC,QAAQ,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,CAAC,CACzG,CAAC;IACJ,CAAC;IAED,kBAAkB;IAElB;;;;;OAKG;IACH,QAAQ,CAAC,MAAe;QACtB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,KAAa,EAAE,MAAe;QACtC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED,oBAAoB;IAEpB;;;;;OAKG;IACH,SAAS,CAAC,MAAe;QACvB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAe;QACvC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAc;QACvC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED,iBAAiB;IAEjB;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED,wBAAwB;IAExB;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED,UAAU;IAEV;;;;;;;;OAQG;IACH,UAAU,CAAC,IAA8B,EAAE,QAAyB;QAClE,IAAI,SAAS,CAAC;QAEd,kBAAkB;QAClB,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC7B,wBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7D,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;QAC7C,CAAC;QAED,iBAAiB;QACjB,EAAE,CAAC,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC;YACpC,qBAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAEpH,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACnE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QAClF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,QAAyB;QACpC,EAAE,CAAC,CAAC,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC;YACpC,qBAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAED,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;gBAC3B,OAAO,GAAG,CAAC,CAAC;gBACZ,KAAK,CAAC;YACR,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAE/B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACrE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QACpF,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzF,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED,UAAU;IAEV;;;;;;OAMG;IACH,UAAU,CAAC,MAAe;QACxB,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC;YAClC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAErE,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE3D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc;QACxC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAe;QACxC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpD,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;gBAC3B,OAAO,GAAG,CAAC,CAAC;gBACZ,KAAK,CAAC;YACR,CAAC;QACH,CAAC;QAED,aAAa;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9C,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,mCAAmC;QACnC,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC;YAClC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAED,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE9F,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU;QACZ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU,CAAC,MAAc;QAC3B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW;QACb,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW,CAAC,MAAc;QAC5B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ,CAAC,QAAwB;QACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;QAExB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,cAAc;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAyB;QAChC,MAAM,WAAW,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAE7E,8BAA8B;QAC9B,qBAAa,CAAC,WAAW,CAAC,CAAC;QAE3B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACK,aAAa,CACnB,KAAa,EACb,QAAiB,EACjB,IAA8B,EAC9B,QAAyB;QAEzB,IAAI,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC;QAClC,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,mBAAmB;QACnB,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC7B,SAAS,GAAG,IAAI,CAAC;YACjB,qBAAqB;QACvB,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;YACpC,qBAAa,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,mCAAmC;QACnC,EAAE,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC;YACjC,qBAAa,CAAC,QAAQ,CAAC,CAAC;YACxB,WAAW,GAAG,QAAQ,CAAC;QACzB,CAAC;QAED,kCAAkC;QAClC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAEzD,mDAAmD;QACnD,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,CAAC;QAED,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAE5D,0CAA0C;QAC1C,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;QAClC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,mFAAmF;YACnF,EAAE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;YAC1E,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;YAClC,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAC,KAAa,EAAE,QAAiB,EAAE,MAAe;QACrE,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,mDAAmD;QACnD,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjD,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjD,CAAC;QAED,qBAAqB;QACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAElC,0CAA0C;QAC1C,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;QACpC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,mFAAmF;YACnF,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;gBAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5E,CAAC;YAAC,IAAI,CAAC,CAAC;gBACN,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;YACpC,CAAC;QACH,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,MAAc,EAAE,MAAe;QACpD,gDAAgD;QAChD,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;QAEjC,qCAAqC;QACrC,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC;YAClC,mCAAmC;YACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;YAEzB,8BAA8B;YAC9B,SAAS,GAAG,MAAM,CAAC;QACrB,CAAC;QAED,8GAA8G;QAC9G,EAAE,CAAC,CAAC,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAc;QACzD,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,mDAAmD;QACnD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;QAE/C,kIAAkI;QAClI,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9E,CAAC;QAED,qCAAqC;QACrC,EAAE,CAAC,CAAC,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;QACpC,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAe;QAC1D,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,wCAAwC;QACxC,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;QAE7C,8FAA8F;QAC9F,EAAE,CAAC,CAAC,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,SAAiB;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAEpC,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YACtB,IAAI,SAAS,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;gBAC1B,SAAS,GAAG,SAAS,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,gBAAgB,CAAC,IAAgC,EAAE,QAAgB,EAAE,MAAe;QAC1F,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEtC,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE5F,2EAA2E;QAC3E,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;QAC/B,CAAC;QAED,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CACxB,IAAgD,EAChD,QAAgB,EAChB,KAAa,EACb,MAAc;QAEd,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAExC,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAErC,2CAA2C;QAC3C,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB,CACvB,IAAgD,EAChD,QAAgB,EAChB,KAAa,EACb,MAAe;QAEf,0CAA0C;QAC1C,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC/B,gEAAgE;YAChE,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,2BAA2B,CAAC,CAAC;YACtD,CAAC;YAED,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAED,uDAAuD;QACvD,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAExC,mFAAmF;QACnF,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;QACxE,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,mGAAmG;YACnG,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;QAChC,CAAC;QAED,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;CACF;AAE4B,kCAAW"} \ No newline at end of file +{"version":3,"file":"smartbuffer.js","sourceRoot":"","sources":["../src/smartbuffer.ts"],"names":[],"mappings":";;AAAA,mCAGiB;AAcjB,kDAAkD;AAClD,MAAM,wBAAwB,GAAW,IAAI,CAAC;AAE9C,kEAAkE;AAClE,MAAM,4BAA4B,GAAmB,MAAM,CAAC;AAE5D,MAAM,WAAW;IAQf;;;;OAIG;IACH,YAAY,OAA4B;QAZjC,WAAM,GAAW,CAAC,CAAC;QAElB,cAAS,GAAmB,4BAA4B,CAAC;QAEzD,iBAAY,GAAW,CAAC,CAAC;QACzB,gBAAW,GAAW,CAAC,CAAC;QAQ9B,IAAI,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE;YAC7C,sBAAsB;YACtB,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,qBAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC;aACnC;YAED,iCAAiC;YACjC,IAAI,OAAO,CAAC,IAAI,EAAE;gBAChB,IAAI,uBAAe,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE;oBACrD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iBAC/C;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,wBAAwB,CAAC,CAAC;iBAClD;gBACD,2BAA2B;aAC5B;iBAAM,IAAI,OAAO,CAAC,IAAI,EAAE;gBACvB,IAAI,OAAO,CAAC,IAAI,YAAY,MAAM,EAAE;oBAClC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;oBAC1B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;iBACnC;qBAAM;oBACL,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;iBACpD;aACF;iBAAM;gBACL,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;aAC3D;SACF;aAAM;YACL,mEAAmE;YACnE,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE;gBAClC,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;aACpD;YAED,oCAAoC;YACpC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;SAC3D;IACH,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,QAAQ,CAAC,IAAY,EAAE,QAAyB;QAC5D,OAAO,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,UAAU,CAAC,IAAY,EAAE,QAAyB;QAC9D,OAAO,IAAI,IAAI,CAAC;YACd,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,WAAW,CAAC,OAA2B;QACnD,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAA2B;QACrD,MAAM,WAAW,GAAuB,OAAO,CAAC;QAEhD,OAAO,CACL,WAAW;YACX,CAAC,WAAW,CAAC,QAAQ,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,CAAC,CACzG,CAAC;IACJ,CAAC;IAED,kBAAkB;IAElB;;;;;OAKG;IACH,QAAQ,CAAC,MAAe;QACtB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAe;QAC5B,iCAAyB,CAAC,gBAAgB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,MAAe;QAC5B,iCAAyB,CAAC,gBAAgB,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,KAAa,EAAE,MAAe;QACtC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,KAAa,EAAE,MAAe;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAc;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,KAAa,EAAE,MAAe;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACpF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAc;QAC5C,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED,oBAAoB;IAEpB;;;;;OAKG;IACH,SAAS,CAAC,MAAe;QACvB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAe;QAC7B,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAe;QAC7B,iCAAyB,CAAC,iBAAiB,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,KAAa,EAAE,MAAe;QACvC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAc;QACvC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAe;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,KAAa,EAAE,MAAc;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,KAAa,EAAE,MAAe;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;;OAOG;IACH,iBAAiB,CAAC,KAAa,EAAE,MAAc;QAC7C,iCAAyB,CAAC,kBAAkB,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtF,CAAC;IAED,iBAAiB;IAEjB;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAe;QACzC,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED,wBAAwB;IAExB;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAe;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACzE,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClF,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,OAAO,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACnF,CAAC;IAED,UAAU;IAEV;;;;;;;;OAQG;IACH,UAAU,CAAC,IAA8B,EAAE,QAAyB;QAClE,IAAI,SAAS,CAAC;QAEd,kBAAkB;QAClB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,wBAAgB,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;SAC5D;aAAM;YACL,QAAQ,GAAG,IAAI,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;SAC5C;QAED,iBAAiB;QACjB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;SACzB;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAEpH,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACnE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED;;;;;;;;OAQG;IACH,WAAW,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QAClF,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,QAAyB;QACpC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;YACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;SACzB;QAED,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACnD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBAC1B,OAAO,GAAG,CAAC,CAAC;gBACZ,MAAM;aACP;SACF;QAED,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAE/B,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;OAQG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc,EAAE,QAAyB;QACrE,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,KAAa,EAAE,IAA8B,EAAE,QAAyB;QACpF,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU;IAEV;;;;;;OAMG;IACH,UAAU,CAAC,MAAe;QACxB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAErE,oBAAoB;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE3D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,KAAa,EAAE,MAAc;QACxC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,KAAa,EAAE,MAAe;QACxC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,+DAA+D;QAC/D,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,6EAA6E;QAC7E,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACnD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;gBAC1B,OAAO,GAAG,CAAC,CAAC;gBACZ,MAAM;aACP;SACF;QAED,aAAa;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAE1D,wCAAwC;QACxC,IAAI,CAAC,WAAW,GAAG,OAAO,GAAG,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,KAAa,EAAE,MAAc;QAC1C,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,eAAe;QACf,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,KAAa,EAAE,MAAe;QAC1C,mCAAmC;QACnC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,eAAe;QACf,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE9F,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACH,IAAI,UAAU,CAAC,MAAc;QAC3B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,IAAI,WAAW,CAAC,MAAc;QAC5B,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,oBAAoB;QACpB,yBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ,CAAC,QAAwB;QACnC,qBAAa,CAAC,QAAQ,CAAC,CAAC;QAExB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAyB;QAChC,MAAM,WAAW,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAE7E,8BAA8B;QAC9B,qBAAa,CAAC,WAAW,CAAC,CAAC;QAE3B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACK,aAAa,CACnB,KAAa,EACb,QAAiB,EACjB,IAA8B,EAC9B,QAAyB;QAEzB,IAAI,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC;QAClC,IAAI,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QAEjC,mBAAmB;QACnB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,SAAS,GAAG,IAAI,CAAC;YACjB,qBAAqB;SACtB;aAAM,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YACnC,qBAAa,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,GAAG,IAAI,CAAC;SACpB;QAED,mCAAmC;QACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;YAChC,qBAAa,CAAC,QAAQ,CAAC,CAAC;YACxB,WAAW,GAAG,QAAQ,CAAC;SACxB;QAED,kCAAkC;QAClC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAEzD,mDAAmD;QACnD,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;SAC9C;aAAM;YACL,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;SAC9C;QAED,cAAc;QACd,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAE5D,0CAA0C;QAC1C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;SACjC;aAAM;YACL,mFAAmF;YACnF,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;gBAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC;aACzE;iBAAM;gBACL,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC;aACjC;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,aAAa,CAAC,KAAa,EAAE,QAAiB,EAAE,MAAe;QACrE,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,mDAAmD;QACnD,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SAChD;aAAM;YACL,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SAChD;QAED,qBAAqB;QACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAElC,0CAA0C;QAC1C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;SACnC;aAAM;YACL,mFAAmF;YACnF,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;gBAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;aAC3E;iBAAM;gBACL,2FAA2F;gBAC3F,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;aACnC;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACK,cAAc,CAAC,MAAc,EAAE,MAAe;QACpD,gDAAgD;QAChD,IAAI,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC;QAEjC,qCAAqC;QACrC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,mCAAmC;YACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;YAEzB,8BAA8B;YAC9B,SAAS,GAAG,MAAM,CAAC;SACpB;QAED,8GAA8G;QAC9G,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACrD,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,0BAA0B,CAAC,CAAC;SACpD;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAc;QACzD,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,mDAAmD;QACnD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC;QAE/C,kIAAkI;QAClI,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;SAC7E;QAED,qCAAqC;QACrC,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;YACrC,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;SAC3B;IACH,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,UAAkB,EAAE,MAAe;QAC1D,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,wCAAwC;QACxC,IAAI,CAAC,eAAe,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;QAE7C,8FAA8F;QAC9F,IAAI,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;YACxC,IAAI,CAAC,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;SACtC;IACH,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,SAAiB;QACvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAEpC,IAAI,SAAS,GAAG,SAAS,EAAE;YACzB,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YACtB,IAAI,SAAS,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,SAAS,GAAG,SAAS,EAAE;gBACzB,SAAS,GAAG,SAAS,CAAC;aACvB;YACD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;SACxC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACK,gBAAgB,CAAI,IAA2B,EAAE,QAAgB,EAAE,MAAe;QACxF,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEtC,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAE5F,2EAA2E;QAC3E,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;YACjC,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC;SAC9B;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;OAWG;IACK,kBAAkB,CACxB,IAA2C,EAC3C,QAAgB,EAChB,KAAQ,EACR,MAAc;QAEd,mCAAmC;QACnC,wBAAgB,CAAC,MAAM,CAAC,CAAC;QAEzB,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAExC,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAErC,2CAA2C;QAC3C,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;OAWG;IACK,iBAAiB,CACvB,IAA2C,EAC3C,QAAgB,EAChB,KAAQ,EACR,MAAe;QAEf,0CAA0C;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,gEAAgE;YAChE,IAAI,MAAM,GAAG,CAAC,EAAE;gBACd,MAAM,IAAI,KAAK,CAAC,cAAM,CAAC,2BAA2B,CAAC,CAAC;aACrD;YAED,wBAAgB,CAAC,MAAM,CAAC,CAAC;SAC1B;QAED,uDAAuD;QACvD,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;QAE1E,0EAA0E;QAC1E,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAExC,mFAAmF;QACnF,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;YAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;SACvE;aAAM;YACL,mGAAmG;YACnG,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC;SAC/B;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAE4B,kCAAW"} \ No newline at end of file diff --git a/deps/npm/node_modules/smart-buffer/build/utils.js b/deps/npm/node_modules/smart-buffer/build/utils.js index 76b330cd9a7bac..6d55981234aa83 100644 --- a/deps/npm/node_modules/smart-buffer/build/utils.js +++ b/deps/npm/node_modules/smart-buffer/build/utils.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const buffer_1 = require("buffer"); /** * Error strings */ @@ -24,7 +25,7 @@ exports.ERRORS = ERRORS; * @param { String } encoding The encoding string to check. */ function checkEncoding(encoding) { - if (!Buffer.isEncoding(encoding)) { + if (!buffer_1.Buffer.isEncoding(encoding)) { throw new Error(ERRORS.INVALID_ENCODING); } } @@ -92,4 +93,16 @@ exports.checkTargetOffset = checkTargetOffset; function isInteger(value) { return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; } +/** + * Throws if Node.js version is too low to support bigint + */ +function bigIntAndBufferInt64Check(bufferMethod) { + if (typeof BigInt === 'undefined') { + throw new Error('Platform does not support JS BigInt type.'); + } + if (typeof buffer_1.Buffer.prototype[bufferMethod] === 'undefined') { + throw new Error(`Platform does not support Buffer.prototype.${bufferMethod}.`); + } +} +exports.bigIntAndBufferInt64Check = bigIntAndBufferInt64Check; //# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/deps/npm/node_modules/smart-buffer/build/utils.js.map b/deps/npm/node_modules/smart-buffer/build/utils.js.map index 905148c086eca6..fc7388d3b7010c 100644 --- a/deps/npm/node_modules/smart-buffer/build/utils.js.map +++ b/deps/npm/node_modules/smart-buffer/build/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAEA;;GAEG;AACH,MAAM,MAAM,GAAG;IACb,gBAAgB,EAAE,kGAAkG;IACpH,wBAAwB,EAAE,wEAAwE;IAClG,0BAA0B,EAAE,gDAAgD;IAC5E,0BAA0B,EAAE,2FAA2F;IACvH,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,qBAAqB,EAAE,sEAAsE;IAC7F,qBAAqB,EAAE,yFAAyF;IAChH,0BAA0B,EAAE,0DAA0D;IACtF,2BAA2B,EAAE,2DAA2D;CACzF,CAAC;AA6EO,wBAAM;AA3Ef;;;;GAIG;AACH,uBAAuB,QAAwB;IAC7C,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAkEiC,sCAAa;AAhE/C;;;;GAIG;AACH,yBAAyB,KAAa;IACpC,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAyDgB,0CAAe;AAvDhC;;;;;GAKG;AACH,kCAAkC,KAAU,EAAE,MAAe;IAC3D,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC;QAC9B,oCAAoC;QACpC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAAC,IAAI,CAAC,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,0BAA0B,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AA+BkE,4CAAgB;AA7BnF;;;;GAIG;AACH,0BAA0B,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAsBgD,4CAAgB;AApBjE;;;;;GAKG;AACH,2BAA2B,MAAc,EAAE,IAAiB;IAC1D,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAUoF,8CAAiB;AARtG;;;GAGG;AACH,mBAAmB,KAAa;IAC9B,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AACrF,CAAC"} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AACA,mCAAgC;AAEhC;;GAEG;AACH,MAAM,MAAM,GAAG;IACb,gBAAgB,EAAE,kGAAkG;IACpH,wBAAwB,EAAE,wEAAwE;IAClG,0BAA0B,EAAE,gDAAgD;IAC5E,0BAA0B,EAAE,2FAA2F;IACvH,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,cAAc,EAAE,uCAAuC;IACvD,yBAAyB,EAAE,oEAAoE;IAC/F,qBAAqB,EAAE,sEAAsE;IAC7F,qBAAqB,EAAE,yFAAyF;IAChH,0BAA0B,EAAE,0DAA0D;IACtF,2BAA2B,EAAE,2DAA2D;CACzF,CAAC;AAuGA,wBAAM;AArGR;;;;GAIG;AACH,SAAS,aAAa,CAAC,QAAwB;IAC7C,IAAI,CAAC,eAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;KAC1C;AACH,CAAC;AA4F0B,sCAAa;AA1FxC;;;;GAIG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAmFS,0CAAe;AAjFzB;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,KAAU,EAAE,MAAe;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,oCAAoC;QACpC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;SACzE;KACF;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC;KAC/F;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC;AA0DC,4CAAgB;AAxDlB;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,MAAW;IACnC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAgDyC,4CAAgB;AA9C1D;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,IAAiB;IAC1D,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;KAC/C;AACH,CAAC;AAqCmB,8CAAiB;AAnCrC;;;GAGG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;AACrF,CAAC;AAcD;;GAEG;AACH,SAAS,yBAAyB,CAAC,YAA0B;IAC3D,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC9D;IAED,IAAI,OAAO,eAAM,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,WAAW,EAAE;QACzD,MAAM,IAAI,KAAK,CAAC,8CAA8C,YAAY,GAAG,CAAC,CAAC;KAChF;AACH,CAAC;AAIsC,8DAAyB"} \ No newline at end of file diff --git a/deps/npm/node_modules/smart-buffer/docs/CHANGELOG.md b/deps/npm/node_modules/smart-buffer/docs/CHANGELOG.md index 15c02d50f376dc..1199a4d6d2353a 100644 --- a/deps/npm/node_modules/smart-buffer/docs/CHANGELOG.md +++ b/deps/npm/node_modules/smart-buffer/docs/CHANGELOG.md @@ -1,4 +1,9 @@ # Change Log +## 4.1.0 +> Released 07/24/2019 +* Adds int64 support for node v12+ +* Drops support for node v4 + ## 4.0 > Released 10/21/2017 * Major breaking changes arriving in v4. diff --git a/deps/npm/node_modules/smart-buffer/docs/README_v3.md b/deps/npm/node_modules/smart-buffer/docs/README_v3.md index 638f188d41fb37..b7c48b8b5444ee 100644 --- a/deps/npm/node_modules/smart-buffer/docs/README_v3.md +++ b/deps/npm/node_modules/smart-buffer/docs/README_v3.md @@ -12,7 +12,7 @@ I created smart-buffer because I wanted to simplify the process of using Buffer Key Features: * Proxies all of the Buffer write and read functions. * Keeps track of read and write positions for you. -* Grows the internal Buffer as you add data to it. +* Grows the internal Buffer as you add data to it. * Useful string operations. (Null terminating strings) * Allows for inserting values at specific points in the internal Buffer. * Built in TypeScript @@ -39,7 +39,7 @@ or `yarn add smart-buffer` -Note: The published NPM package includes the built javascript library. +Note: The published NPM package includes the built javascript library. If you cloned this repo and wish to build the library manually use: `tsc -p ./` @@ -75,7 +75,7 @@ function createLoginPacket(username, password, age, country) { packet.writeUInt8(age); packet.writeStringNT(country); packet.writeUInt16LE(packet.length - 2, 2); - + return packet.toBuffer(); } ``` @@ -102,13 +102,13 @@ let logininfo = { }; /* -{ +{ packetType: 96, (0x0060) packetLength: 30, username: 'Josh', password: 'secret123', age: 22, - country: 'United States' + country: 'United States' }; */ ``` @@ -124,11 +124,11 @@ let SmartBuffer = require('smart-buffer'); // Creating SmartBuffer from existing Buffer let buff = SmartBuffer.fromBuffer(buffer); // Creates instance from buffer. (Uses default utf8 encoding) -let buff = SmartBuffer.fromBuffer(buffer, 'ascii'); // Creates instance from buffer with ascii encoding for Strings. +let buff = SmartBuffer.fromBuffer(buffer, 'ascii'); // Creates instance from buffer with ascii encoding for Strings. // Creating SmartBuffer with specified internal Buffer size. let buff = SmartBuffer.fromSize(1024); // Creates instance with internal Buffer size of 1024. -let buff = SmartBuffer.fromSize(1024, 'utf8'); // Creates instance with intenral Buffer size of 1024, and utf8 encoding. +let buff = SmartBuffer.fromSize(1024, 'utf8'); // Creates instance with intenral Buffer size of 1024, and utf8 encoding. // Creating SmartBuffer with options object. This one specifies size and encoding. let buff = SmartBuffer.fromOptions({ @@ -170,11 +170,15 @@ Supported Operations: * readInt16LE * readInt32BE * readInt32LE +* readBigInt64LE +* readBigInt64BE * readUInt8 * readUInt16BE * readUInt16LE * readUInt32BE * readUInt32LE +* readBigUInt64LE +* readBigUInt64BE * readFloatBE * readFloatLE * readDoubleBE @@ -190,7 +194,7 @@ let num = reader.readInt8(); When reading String values, you can either choose to read a null terminated string, or a string of a specified length. ### SmartBuffer.readStringNT( [encoding] ) -> `String` **String encoding to use** - Defaults to the encoding set in the constructor. +> `String` **String encoding to use** - Defaults to the encoding set in the constructor. returns `String` @@ -229,7 +233,7 @@ returns `Buffer` ## Writing Data -smart-buffer supports all of the common write functions you will find in the vanilla Buffer class. The only difference is, you do not need to specify which location to write to in your Buffer by default. You do however have the option of **inserting** a piece of data into your smart-buffer at a given location. +smart-buffer supports all of the common write functions you will find in the vanilla Buffer class. The only difference is, you do not need to specify which location to write to in your Buffer by default. You do however have the option of **inserting** a piece of data into your smart-buffer at a given location. ## Writing Numeric Values @@ -243,11 +247,15 @@ Supported Operations: * writeInt16LE * writeInt32BE * writeInt32LE +* writeBigInt64BE +* writeBigInt64LE * writeUInt8 * writeUInt16BE * writeUInt16LE * writeUInt32BE * writeUInt32LE +* writeBigUInt64BE +* writeBigUInt64LE * writeFloatBE * writeFloatLE * writeDoubleBE @@ -258,9 +266,9 @@ The following signature is the same for all the above functions: ### SmartBuffer.writeInt8( value, [offset] ) > `Number` **A valid Int8 number** -> `Number` **The position to insert this value at** +> `Number` **The position to insert this value at** -returns this +returns this > Note: All write operations return `this` to allow for chaining. diff --git a/deps/npm/node_modules/smart-buffer/package.json b/deps/npm/node_modules/smart-buffer/package.json index ca94fd0908658f..c6d3c31214cf3d 100644 --- a/deps/npm/node_modules/smart-buffer/package.json +++ b/deps/npm/node_modules/smart-buffer/package.json @@ -1,27 +1,27 @@ { - "_from": "smart-buffer@4.0.2", - "_id": "smart-buffer@4.0.2", + "_from": "smart-buffer@^4.1.0", + "_id": "smart-buffer@4.1.0", "_inBundle": false, - "_integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", + "_integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==", "_location": "/smart-buffer", "_phantomChildren": {}, "_requested": { - "type": "version", + "type": "range", "registry": true, - "raw": "smart-buffer@4.0.2", + "raw": "smart-buffer@^4.1.0", "name": "smart-buffer", "escapedName": "smart-buffer", - "rawSpec": "4.0.2", + "rawSpec": "^4.1.0", "saveSpec": null, - "fetchSpec": "4.0.2" + "fetchSpec": "^4.1.0" }, "_requiredBy": [ "/socks" ], - "_resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", - "_shasum": "5207858c3815cc69110703c6b94e46c15634395d", - "_spec": "smart-buffer@4.0.2", - "_where": "/Users/isaacs/dev/npm/cli/node_modules/socks", + "_resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "_shasum": "91605c25d91652f4661ea69ccf45f1b331ca21ba", + "_spec": "smart-buffer@^4.1.0", + "_where": "/Users/claudiahdz/npm/cli/node_modules/socks", "author": { "name": "Josh Glazebrook" }, @@ -33,22 +33,22 @@ "deprecated": false, "description": "smart-buffer is a Buffer wrapper that adds automatic read & write offset tracking, string operations, data insertions, and more.", "devDependencies": { - "@types/chai": "4.0.4", - "@types/mocha": "^2.2.44", - "@types/node": "^8.0.51", - "chai": "4.1.2", - "coveralls": "3.0.0", + "@types/chai": "4.1.7", + "@types/mocha": "5.2.7", + "@types/node": "^12.0.0", + "chai": "4.2.0", + "coveralls": "3.0.5", "istanbul": "^0.4.5", - "mocha": "4.0.1", + "mocha": "6.2.0", "mocha-lcov-reporter": "^1.3.0", - "nyc": "^11.3.0", - "source-map-support": "0.5.0", - "ts-node": "3.3.0", - "tslint": "5.8.0", - "typescript": "2.6.1" + "nyc": "14.1.1", + "source-map-support": "0.5.12", + "ts-node": "8.3.0", + "tslint": "5.18.0", + "typescript": "^3.2.1" }, "engines": { - "node": ">= 4.0.0", + "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "homepage": "https://github.com/JoshGlazebrook/smart-buffer/", @@ -97,8 +97,8 @@ "coveralls": "NODE_ENV=test nyc npm test && nyc report --reporter=text-lcov | coveralls", "lint": "tslint --type-check --project tsconfig.json 'src/**/*.ts'", "prepublish": "npm install -g typescript && npm run build", - "test": "NODE_ENV=test mocha --recursive --compilers ts:ts-node/register test/**/*.ts" + "test": "NODE_ENV=test mocha --recursive --require ts-node/register test/**/*.ts" }, "typings": "typings/smartbuffer.d.ts", - "version": "4.0.2" + "version": "4.1.0" } diff --git a/deps/npm/node_modules/smart-buffer/typings/smartbuffer.d.ts b/deps/npm/node_modules/smart-buffer/typings/smartbuffer.d.ts index 19456754b43813..d07379b2983a44 100644 --- a/deps/npm/node_modules/smart-buffer/typings/smartbuffer.d.ts +++ b/deps/npm/node_modules/smart-buffer/typings/smartbuffer.d.ts @@ -82,6 +82,20 @@ declare class SmartBuffer { * @return { Number } */ readInt32LE(offset?: number): number; + /** + * Reads a BigInt64BE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigInt64BE(offset?: number): bigint; + /** + * Reads a BigInt64LE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigInt64LE(offset?: number): bigint; /** * Writes an Int8 value to the current write position (or at optional offset). * @@ -172,6 +186,42 @@ declare class SmartBuffer { * @return this */ insertInt32LE(value: number, offset: number): SmartBuffer; + /** + * Writes a BigInt64BE value to the current write position (or at optional offset). + * + * @param value { BigInt } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigInt64BE(value: bigint, offset?: number): SmartBuffer; + /** + * Inserts a BigInt64BE value at the given offset value. + * + * @param value { BigInt } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigInt64BE(value: bigint, offset: number): SmartBuffer; + /** + * Writes a BigInt64LE value to the current write position (or at optional offset). + * + * @param value { BigInt } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigInt64LE(value: bigint, offset?: number): SmartBuffer; + /** + * Inserts a Int64LE value at the given offset value. + * + * @param value { BigInt } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigInt64LE(value: bigint, offset: number): SmartBuffer; /** * Reads an UInt8 value from the current read position or an optionally provided offset. * @@ -207,6 +257,20 @@ declare class SmartBuffer { * @return { Number } */ readUInt32LE(offset?: number): number; + /** + * Reads a BigUInt64BE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigUInt64BE(offset?: number): bigint; + /** + * Reads a BigUInt64LE value from the current read position or an optionally provided offset. + * + * @param offset { Number } The offset to read data from (optional) + * @return { BigInt } + */ + readBigUInt64LE(offset?: number): bigint; /** * Writes an UInt8 value to the current write position (or at optional offset). * @@ -297,6 +361,42 @@ declare class SmartBuffer { * @return this */ insertUInt32LE(value: number, offset: number): SmartBuffer; + /** + * Writes a BigUInt64BE value to the current write position (or at optional offset). + * + * @param value { Number } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigUInt64BE(value: bigint, offset?: number): SmartBuffer; + /** + * Inserts a BigUInt64BE value at the given offset value. + * + * @param value { Number } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigUInt64BE(value: bigint, offset: number): SmartBuffer; + /** + * Writes a BigUInt64LE value to the current write position (or at optional offset). + * + * @param value { Number } The value to write. + * @param offset { Number } The offset to write the value at. + * + * @return this + */ + writeBigUInt64LE(value: bigint, offset?: number): SmartBuffer; + /** + * Inserts a BigUInt64LE value at the given offset value. + * + * @param value { Number } The value to insert. + * @param offset { Number } The offset to insert the value at. + * + * @return this + */ + insertBigUInt64LE(value: bigint, offset: number): SmartBuffer; /** * Reads an FloatBE value from the current read position or an optionally provided offset. * @@ -521,10 +621,10 @@ declare class SmartBuffer { * @return { Number } */ /** - * Sets the read offset value of the SmartBuffer instance. - * - * @param offset { Number } - The offset value to set. - */ + * Sets the read offset value of the SmartBuffer instance. + * + * @param offset { Number } - The offset value to set. + */ readOffset: number; /** * Gets the current write offset value of the SmartBuffer instance. @@ -532,10 +632,10 @@ declare class SmartBuffer { * @return { Number } */ /** - * Sets the write offset value of the SmartBuffer instance. - * - * @param offset { Number } - The offset value to set. - */ + * Sets the write offset value of the SmartBuffer instance. + * + * @param offset { Number } - The offset value to set. + */ writeOffset: number; /** * Gets the currently set string encoding of the SmartBuffer instance. @@ -543,10 +643,10 @@ declare class SmartBuffer { * @return { BufferEncoding } The string Buffer encoding currently set. */ /** - * Sets the string encoding of the SmartBuffer instance. - * - * @param encoding { BufferEncoding } The string Buffer encoding to set. - */ + * Sets the string encoding of the SmartBuffer instance. + * + * @param encoding { BufferEncoding } The string Buffer encoding to set. + */ encoding: BufferEncoding; /** * Gets the underlying internal Buffer. (This includes unmanaged data in the Buffer) @@ -578,70 +678,78 @@ declare class SmartBuffer { * @param arg2 { Number | String } The offset to insert the string at, or the BufferEncoding to use. * @param encoding { String } The BufferEncoding to use for writing strings (defaults to instance encoding). */ - private _handleString(value, isInsert, arg3?, encoding?); + private _handleString; /** * Handles writing or insert of a Buffer. * * @param value { Buffer } The Buffer to write. * @param offset { Number } The offset to write the Buffer to. */ - private _handleBuffer(value, isInsert, offset?); + private _handleBuffer; /** * Ensures that the internal Buffer is large enough to read data. * * @param length { Number } The length of the data that needs to be read. * @param offset { Number } The offset of the data that needs to be read. */ - private ensureReadable(length, offset?); + private ensureReadable; /** * Ensures that the internal Buffer is large enough to insert data. * * @param dataLength { Number } The length of the data that needs to be written. * @param offset { Number } The offset of the data to be written. */ - private ensureInsertable(dataLength, offset); + private ensureInsertable; /** * Ensures that the internal Buffer is large enough to write data. * * @param dataLength { Number } The length of the data that needs to be written. * @param offset { Number } The offset of the data to be written (defaults to writeOffset). */ - private _ensureWriteable(dataLength, offset?); + private _ensureWriteable; /** * Ensures that the internal Buffer is large enough to write at least the given amount of data. * * @param minLength { Number } The minimum length of the data needs to be written. */ - private _ensureCapacity(minLength); + private _ensureCapacity; /** * Reads a numeric number value using the provided function. * + * @typeparam T { number | bigint } The type of the value to be read + * * @param func { Function(offset: number) => number } The function to read data on the internal Buffer with. * @param byteSize { Number } The number of bytes read. * @param offset { Number } The offset to read from (optional). When this is not provided, the managed readOffset is used instead. * - * @param { Number } + * @returns { T } the number value */ - private _readNumberValue(func, byteSize, offset?); + private _readNumberValue; /** * Inserts a numeric number value based on the given offset and value. * - * @param func { Function(offset: number, offset?) => number} The function to write data on the internal Buffer with. + * @typeparam T { number | bigint } The type of the value to be written + * + * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. * @param byteSize { Number } The number of bytes written. - * @param value { Number } The number value to write. + * @param value { T } The number value to write. * @param offset { Number } the offset to write the number at (REQUIRED). * + * @returns SmartBuffer this buffer */ - private _insertNumberValue(func, byteSize, value, offset); + private _insertNumberValue; /** * Writes a numeric number value based on the given offset and value. * - * @param func { Function(offset: number, offset?) => number} The function to write data on the internal Buffer with. + * @typeparam T { number | bigint } The type of the value to be written + * + * @param func { Function(offset: T, offset?) => number} The function to write data on the internal Buffer with. * @param byteSize { Number } The number of bytes written. - * @param value { Number } The number value to write. + * @param value { T } The number value to write. * @param offset { Number } the offset to write the number at (REQUIRED). * + * @returns SmartBuffer this buffer */ - private _writeNumberValue(func, byteSize, value, offset?); + private _writeNumberValue; } export { SmartBufferOptions, SmartBuffer }; diff --git a/deps/npm/node_modules/smart-buffer/typings/utils.d.ts b/deps/npm/node_modules/smart-buffer/typings/utils.d.ts index 951b85a5b88f11..b32b4d44c04c1d 100644 --- a/deps/npm/node_modules/smart-buffer/typings/utils.d.ts +++ b/deps/npm/node_modules/smart-buffer/typings/utils.d.ts @@ -1,5 +1,6 @@ /// import { SmartBuffer } from './smartbuffer'; +import { Buffer } from 'buffer'; /** * Error strings */ @@ -48,4 +49,18 @@ declare function checkOffsetValue(offset: any): void; * @param { SmartBuffer } buff The SmartBuffer instance to check against. */ declare function checkTargetOffset(offset: number, buff: SmartBuffer): void; -export { ERRORS, isFiniteInteger, checkEncoding, checkOffsetValue, checkLengthValue, checkTargetOffset }; +interface Buffer { + readBigInt64BE(offset?: number): bigint; + readBigInt64LE(offset?: number): bigint; + readBigUInt64BE(offset?: number): bigint; + readBigUInt64LE(offset?: number): bigint; + writeBigInt64BE(value: bigint, offset?: number): number; + writeBigInt64LE(value: bigint, offset?: number): number; + writeBigUInt64BE(value: bigint, offset?: number): number; + writeBigUInt64LE(value: bigint, offset?: number): number; +} +/** + * Throws if Node.js version is too low to support bigint + */ +declare function bigIntAndBufferInt64Check(bufferMethod: keyof Buffer): void; +export { ERRORS, isFiniteInteger, checkEncoding, checkOffsetValue, checkLengthValue, checkTargetOffset, bigIntAndBufferInt64Check }; diff --git a/deps/npm/node_modules/smart-buffer/yarn.lock b/deps/npm/node_modules/smart-buffer/yarn.lock deleted file mode 100644 index 567b06f6cec7bf..00000000000000 --- a/deps/npm/node_modules/smart-buffer/yarn.lock +++ /dev/null @@ -1,1849 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/chai@4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.4.tgz#fe86315d9a66827feeb16f73bc954688ec950e18" - -"@types/mocha@^2.2.44": - version "2.2.44" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e" - -"@types/node@^8.0.51": - version "8.0.51" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" - -abbrev@1, abbrev@1.0.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - -ajv@^5.1.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.3.tgz#c06f598778c44c6b161abafe3466b81ad1814ed2" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - json-schema-traverse "^0.3.0" - json-stable-stringify "^1.0.1" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" - dependencies: - color-convert "^1.9.0" - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - dependencies: - default-require-extensions "^1.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" - -async@1.x, async@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-code-frame@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" - dependencies: - chalk "^1.1.0" - esutils "^2.0.2" - js-tokens "^3.0.0" - -babel-generator@^6.18.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-runtime@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-template@^6.16.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babylon "^6.11.0" - lodash "^4.2.0" - -babel-traverse@^6.18.0, babel-traverse@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babylon "^6.15.0" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-types@^6.18.0, babel-types@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babylon@^6.11.0, babylon@^6.15.0, babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -balanced-match@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -brace-expansion@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59" - dependencies: - balanced-match "^0.4.1" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - -builtin-modules@^1.0.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -caching-transform@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" - dependencies: - md5-hex "^1.2.0" - mkdirp "^0.5.1" - write-file-atomic "^1.1.4" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chai@4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" - dependencies: - assertion-error "^1.0.1" - check-error "^1.0.1" - deep-eql "^3.0.0" - get-func-name "^2.0.0" - pathval "^1.0.0" - type-detect "^4.0.0" - -chalk@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -check-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -color-convert@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@2.11.0, commander@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -convert-source-map@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" - -core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -coveralls@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.0.tgz#22ef730330538080d29b8c151dc9146afde88a99" - dependencies: - js-yaml "^3.6.1" - lcov-parse "^0.0.10" - log-driver "^1.2.5" - minimist "^1.2.0" - request "^2.79.0" - -cross-spawn@^4, cross-spawn@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - -debug@3.1.0, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - -debug@^2.2.0: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - -decamelize@^1.0.0, decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -deep-eql@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - dependencies: - type-detect "^4.0.0" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - dependencies: - strip-bom "^2.0.0" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -diff@3.3.1, diff@^3.1.0, diff@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" - -esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -execa@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" - dependencies: - cross-spawn "^4.0.0" - get-stream "^2.2.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreground-child@^1.5.3, foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@7.1.2, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^9.0.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -growl@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" - -handlebars@^4.0.1, handlebars@^4.0.3: - version "4.0.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.7.tgz#e97325aeb8ea0b9e12b9c4dd73c4c312ad0ede59" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -hosted-git-info@^2.1.4: - version "2.4.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -invariant@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-number@^2.0.2, is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -istanbul-lib-coverage@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" - -istanbul-lib-hook@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz#250b30b3531e5d3251299fdd64b0b2c9db6b558e" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.1.1" - semver "^5.3.0" - -istanbul-lib-report@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz#922be27c13b9511b979bd1587359f69798c1d425" - dependencies: - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz#750578602435f28a0c04ee6d7d9e0f2960e62c1c" - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.3.tgz#3b9e1e8defb6d18b1d425da8e8b32c5a163f2d10" - dependencies: - handlebars "^4.0.3" - -istanbul@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" - dependencies: - abbrev "1.0.x" - async "1.x" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" - -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - -js-tokens@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" - -js-yaml@3.x, js-yaml@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsprim@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" - dependencies: - assert-plus "1.0.0" - extsprintf "1.0.2" - json-schema "0.2.3" - verror "1.3.6" - -kind-of@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.0.tgz#b58abe4d5c044ad33726a8c1525b48cf891bff07" - dependencies: - is-buffer "^1.1.5" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -lcov-parse@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash@^4.2.0: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -log-driver@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -lru-cache@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" - dependencies: - pseudomap "^1.0.1" - yallist "^2.0.0" - -make-error@^1.1.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.2.3.tgz#6c4402df732e0977ac6faf754a5074b3d2b1d19d" - -md5-hex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -merge-source-map@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.3.tgz#da1415f2722a5119db07b14c4f973410863a2abf" - dependencies: - source-map "^0.5.3" - -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.17: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" - -"minimatch@2 || 3", minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8, minimist@~0.0.1: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -mocha-lcov-reporter@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/mocha-lcov-reporter/-/mocha-lcov-reporter-1.3.0.tgz#469bdef4f8afc9a116056f079df6182d0afb0384" - -mocha@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-4.0.1.tgz#0aee5a95cf69a4618820f5e51fa31717117daf1b" - dependencies: - browser-stdout "1.3.0" - commander "2.11.0" - debug "3.1.0" - diff "3.3.1" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.3" - he "1.1.1" - mkdirp "0.5.1" - supports-color "4.4.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -nyc@^11.3.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.3.0.tgz#a42bc17b3cfa41f7b15eb602bc98b2633ddd76f0" - dependencies: - archy "^1.0.0" - arrify "^1.0.1" - caching-transform "^1.0.0" - convert-source-map "^1.3.0" - debug-log "^1.0.1" - default-require-extensions "^1.0.0" - find-cache-dir "^0.1.1" - find-up "^2.1.0" - foreground-child "^1.5.3" - glob "^7.0.6" - istanbul-lib-coverage "^1.1.1" - istanbul-lib-hook "^1.1.0" - istanbul-lib-instrument "^1.9.1" - istanbul-lib-report "^1.1.2" - istanbul-lib-source-maps "^1.2.2" - istanbul-reports "^1.1.3" - md5-hex "^1.2.0" - merge-source-map "^1.0.2" - micromatch "^2.3.11" - mkdirp "^0.5.0" - resolve-from "^2.0.0" - rimraf "^2.5.4" - signal-exit "^3.0.1" - spawn-wrap "=1.3.8" - test-exclude "^4.1.1" - yargs "^10.0.3" - yargs-parser "^8.0.0" - -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -once@1.x, once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4" - dependencies: - execa "^0.5.0" - lcid "^1.0.0" - mem "^1.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pathval@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" - dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -regenerator-runtime@^0.10.0: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -remove-trailing-separator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@^2.79.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - -resolve@1.1.x: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - -resolve@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" - dependencies: - path-parse "^1.0.5" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@^2.3.3, rimraf@^2.5.4, rimraf@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" - dependencies: - glob "^7.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - -sntp@2.x.x: - version "2.0.2" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.0.2.tgz#5064110f0af85f7cfdb7d6b67a40028ce52b4b2b" - dependencies: - hoek "4.x.x" - -source-map-support@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.0.tgz#2018a7ad2bdf8faf2691e5fddab26bed5a2bacab" - dependencies: - source-map "^0.6.0" - -source-map-support@^0.4.0: - version "0.4.15" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" - dependencies: - source-map "^0.5.6" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -source-map@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - dependencies: - amdefine ">=0.0.4" - -spawn-wrap@=1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.3.3" - signal-exit "^3.0.2" - which "^1.2.4" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^3.0.0" - -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-json-comments@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -supports-color@4.4.0, supports-color@^4.0.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" - dependencies: - has-flag "^2.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.1.0, supports-color@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - -test-exclude@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -to-fast-properties@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -ts-node@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-3.3.0.tgz#c13c6a3024e30be1180dd53038fc209289d4bf69" - dependencies: - arrify "^1.0.0" - chalk "^2.0.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.0" - tsconfig "^6.0.0" - v8flags "^3.0.0" - yn "^2.0.0" - -tsconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/tsconfig/-/tsconfig-6.0.0.tgz#6b0e8376003d7af1864f8df8f89dd0059ffcd032" - dependencies: - strip-bom "^3.0.0" - strip-json-comments "^2.0.0" - -tslib@^1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec" - -tslint@5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.8.0.tgz#1f49ad5b2e77c76c3af4ddcae552ae4e3612eb13" - dependencies: - babel-code-frame "^6.22.0" - builtin-modules "^1.1.1" - chalk "^2.1.0" - commander "^2.9.0" - diff "^3.2.0" - glob "^7.1.1" - minimatch "^3.0.4" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.7.1" - tsutils "^2.12.1" - -tsutils@^2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.12.1.tgz#f4d95ce3391c8971e46e54c4cf0edb0a21dd5b24" - dependencies: - tslib "^1.7.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -type-detect@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" - -typescript@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.1.tgz#ef39cdea27abac0b500242d6726ab90e0c846631" - -uglify-js@^2.6: - version "2.8.22" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - -uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -v8flags@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.0.0.tgz#4be9604488e0c4123645def705b1848d16b8e01f" - dependencies: - user-home "^1.1.1" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -verror@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" - dependencies: - extsprintf "1.0.2" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.1.1, which@^1.2.4, which@^1.2.9: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" - dependencies: - isexe "^2.0.0" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@^1.0.0, wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^1.1.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" - dependencies: - camelcase "^4.1.0" - -yargs@^10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-10.0.3.tgz#6542debd9080ad517ec5048fb454efe9e4d4aaae" - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^8.0.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" diff --git a/deps/npm/node_modules/socks/.travis.yml b/deps/npm/node_modules/socks/.travis.yml index 9366dacc42be7e..f3f06280551fe9 100644 --- a/deps/npm/node_modules/socks/.travis.yml +++ b/deps/npm/node_modules/socks/.travis.yml @@ -2,6 +2,8 @@ language: node_js node_js: - 6 - 8 + - 10 + - 12 - stable before_install: diff --git a/deps/npm/node_modules/socks/build/client/socksclient.js b/deps/npm/node_modules/socks/build/client/socksclient.js index 10871ff625c265..5eb80ce911dcdb 100644 --- a/deps/npm/node_modules/socks/build/client/socksclient.js +++ b/deps/npm/node_modules/socks/build/client/socksclient.js @@ -1,9 +1,10 @@ "use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; @@ -225,7 +226,7 @@ class SocksClient extends events_1.EventEmitter { this._socket.emit('connect'); } else { - this._socket.connect(this._options.proxy.port, this._options.proxy.host || this._options.proxy.ipaddress); + this._socket.connect(this.getSocketOptions()); if (this._options.set_tcp_nodelay !== undefined && this._options.set_tcp_nodelay !== null) { this._socket.setNoDelay(!!this._options.set_tcp_nodelay); @@ -242,6 +243,10 @@ class SocksClient extends events_1.EventEmitter { }); }); } + // Socket options (defaults host/port to options.proxy.host/options.proxy.port) + getSocketOptions() { + return Object.assign(Object.assign({}, this._options.socket_options), { host: this._options.proxy.host || this._options.proxy.ipaddress, port: this._options.proxy.port }); + } /** * Handles internal Socks timeout callback. * Note: If the Socks client is not BoundWaitingForConnection or Established, the connection will be closed. diff --git a/deps/npm/node_modules/socks/build/client/socksclient.js.map b/deps/npm/node_modules/socks/build/client/socksclient.js.map index ac57b4b6c152a2..eb73a25856978a 100644 --- a/deps/npm/node_modules/socks/build/client/socksclient.js.map +++ b/deps/npm/node_modules/socks/build/client/socksclient.js.map @@ -1 +1 @@ -{"version":3,"file":"socksclient.js","sourceRoot":"","sources":["../../src/client/socksclient.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,mCAAsC;AACtC,2BAA2B;AAC3B,yBAAyB;AACzB,+CAA2C;AAC3C,mDAiB6B;AAC7B,+CAG2B;AAC3B,2DAAwD;AACxD,yCAAgE;AA0BhE,iBAAkB,SAAQ,qBAAY;IAepC,YAAY,OAA2B;QACrC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,qBACR,OAAO,CACX,CAAC;QAEF,8BAA8B;QAC9B,oCAA0B,CAAC,OAAO,CAAC,CAAC;QAEpC,gBAAgB;QAChB,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,OAAO,CAAC;IACxC,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CACrB,OAA2B,EAC3B,QAAmB;QAEnB,8BAA8B;QAC9B,oCAA0B,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAEjD,OAAO,IAAI,OAAO,CAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAiC,EAAE,EAAE;gBAC/D,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,OAAO,CAAC,IAAI,CAAC,CAAC;iBACf;YACH,CAAC,CAAC,CAAC;YAEH,kDAAkD;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,qBAAqB,CAC1B,OAAgC,EAChC,QAAmB;QAEnB,mCAAmC;QACnC,yCAA+B,CAAC,OAAO,CAAC,CAAC;QAEzC,kBAAkB;QAClB,IAAI,OAAO,CAAC,cAAc,EAAE;YAC1B,mBAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC/B;QAED,OAAO,IAAI,OAAO,CAA8B,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;YACxE,IAAI,IAAgB,CAAC;YAErB,IAAI;gBACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAErC,0HAA0H;oBAC1H,MAAM,eAAe,GACnB,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;wBAC9B,CAAC,CAAC,OAAO,CAAC,WAAW;wBACrB,CAAC,CAAC;4BACE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;4BACtC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;yBAClC,CAAC;oBAER,4CAA4C;oBAC5C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,gBAAgB,CAAC;wBAChD,OAAO,EAAE,SAAS;wBAClB,KAAK,EAAE,SAAS;wBAChB,WAAW,EAAE,eAAe;wBAC5B,8HAA8H;qBAC/H,CAAC,CAAC;oBAEH,wCAAwC;oBACxC,IAAI,CAAC,IAAI,EAAE;wBACT,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;qBACtB;iBACF;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACjC,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC3B;aACF;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;aACF;QACH,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,OAA6B;QACjD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QAE1C,qBAAqB;QACrB,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACvC,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;SAC3C;QAED,OAAO;QACP,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,OAAO;QACP,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAY;QAC/B,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAEpB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAmB,IAAI,CAAC,SAAS,EAAE,CAAC;QAClD,IAAI,UAAU,CAAC;QAEf,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YACpC,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;SAC/C;aAAM,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YAC3C,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;SAC/C;aAAM;YACL,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;SAChD;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEvC,OAAO;YACL,WAAW;YACX,UAAU,EAAE;gBACV,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,UAAU;aACjB;YACD,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAY,KAAK;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAY,KAAK,CAAC,QAA0B;QAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,4BAAgB,CAAC,KAAK,EAAE;YAC1C,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;SACxB;IACH,CAAC;IAED;;;OAGG;IACI,OAAO,CAAC,eAAwB;QACrC,IAAI,CAAC,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAEzC,+CAA+C;QAC/C,MAAM,KAAK,GAAG,UAAU,CACtB,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,EACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,2BAAe,CACzC,CAAC;QAEF,8EAA8E;QAC9E,IAAI,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE;YACpD,KAAK,CAAC,KAAK,EAAE,CAAC;SACf;QAED,yGAAyG;QACzG,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC;SAChC;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;SACjC;QAED,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAE9C,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,IAAI,6BAAa,EAAE,CAAC;QAE1C,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAC9B;aAAM;YACJ,IAAI,CAAC,OAAsB,CAAC,OAAO,CAClC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EACxB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAC1D,CAAC;YACF,IACE,IAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,SAAS;gBAC3C,IAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,IAAI,EACtC;gBACC,IAAI,CAAC,OAAsB,CAAC,UAAU,CACrC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAChC,CAAC;aACH;SACF;QAED,6FAA6F;QAC7F,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE;YAC7C,YAAY,CAAC,GAAG,EAAE;gBAChB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;oBAClC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CACxC,IAAI,CAAC,cAAc,CAAC,MAAM,CAC3B,CAAC;oBAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBACtC;gBACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,oBAAoB;QAC1B,IACE,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW;YAC3C,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EACzD;YACA,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,uBAAuB,CAAC,CAAC;SACnD;IACH,CAAC;IAED;;OAEG;IACK,SAAS;QACf,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,SAAS,CAAC;QAExC,0BAA0B;QAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;YAClC,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;QAED,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,oBAAoB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,cAAc,CAAC,IAAY;QACjC;;;UAGE;QACF,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEjC,6BAA6B;QAC7B,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,mFAAmF;QACnF,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,6BAA6B,EAAE;YACpE,gDAAgD;YAChD,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,oBAAoB,EAAE;gBACxD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBAClC,4CAA4C;oBAC5C,IAAI,CAAC,kCAAkC,EAAE,CAAC;iBAC3C;qBAAM;oBACL,wDAAwD;oBACxD,IAAI,CAAC,oCAAoC,EAAE,CAAC;iBAC7C;gBACD,wDAAwD;aACzD;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kDAAkD,EAAE,CAAC;gBAC1D,6DAA6D;aAC9D;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kCAAkC,EAAE,CAAC;gBAC1C,mEAAmE;aACpE;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EAAE;gBACpE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBAClC,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;qBAAM;oBACL,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;aACF;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW,EAAE;gBACtD,8CAA8C;aAC/C;iBAAM;gBACL,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,aAAa,CAAC,CAAC;aACzC;SACF;IACH,CAAC;IAED;;;OAGG;IACK,OAAO;QACb,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACK,OAAO,CAAC,GAAU;QACxB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,6FAA6F;QAC7F,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,GAAW;QAC9B,2FAA2F;QAC3F,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,KAAK,EAAE;YACzC,+BAA+B;YAC/B,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,KAAK,CAAC;YAEpC,iBAAiB;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAEvB,4BAA4B;YAC5B,IAAI,CAAC,4BAA4B,EAAE,CAAC;YAEpC,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,uBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;SAC9D;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAEhD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnD,iBAAiB;QACjB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,sBAAsB;SACvB;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,6BAA6B,OAAO,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CACzE,CAAC;SACH;aAAM;YACL,gBAAgB;YAChB,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBAC7D,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAEpB,MAAM,UAAU,GAAoB;oBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;oBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBACvC,CAAC;gBAEF,yCAAyC;gBACzC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBACD,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,yBAAyB,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;gBAEzD,mBAAmB;aACpB;iBAAM;gBACL,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;aACpD;SACF;IACH,CAAC;IAED;;;OAGG;IACK,sCAAsC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,0CAA0C,OAClD,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,GAAG,CACJ,CAAC;SACH;aAAM;YACL,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YAEpB,MAAM,UAAU,GAAoB;gBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;gBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aACvC,CAAC;YAEF,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;YAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;SAChE;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,6FAA6F;QAC7F,sHAAsH;QACtH,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC9D,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,QAAQ,CAAC,CAAC;SACtC;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,MAAM,CAAC,CAAC;SACpC;QAED,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,8BAA8B,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,oBAAoB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,oCAAoC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,yCAAyC,CAAC,CAAC;SACrE;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YAC3B,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,+CAA+C,CAAC,CAAC;SAC3E;aAAM;YACL,6EAA6E;YAC7E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,MAAM,EAAE;gBACjC,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,0EAA0E;aAC3E;iBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,QAAQ,EAAE;gBAC1C,IAAI,CAAC,gCAAgC,EAAE,CAAC;aACzC;iBAAM;gBACL,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,4CAA4C,CAAC,CAAC;aACxE;SACF;IACH,CAAC;IAED;;;;OAIG;IACK,gCAAgC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAEpD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE3B,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,oCAAoC,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,kBAAkB,CAAC;IACnD,CAAC;IAED;;;OAGG;IACK,kDAAkD;QACxD,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,8BAA8B,CAAC;QAE7D,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,0BAA0B,CAAC,CAAC;SACtD;aAAM;YACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;SACjC;IACH,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAE/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,sBAAsB;QACtB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC/D;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YACrD,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC/D;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAClD;QACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnD,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,oBAAoB,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,kBAAkB,CAAC;IACnD,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,mCAAmC,MAC3C,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAG,uCAA2B,CAAC,sBAAsB,CACnE,UAAU,CACX,CAAC,CAAC,qCAAqC;gBAExC,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iCAAiC;iBAC/E,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,6BAA6B;YAC7B,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,qBAAqB,CAAC;YAEpD,gEAAgE;YAChE,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,OAAO,EAAE;gBAChE,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;aACpD;iBAAM,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBACpE;mHACmG;gBACnG,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,yBAAyB,CAAC;gBACxD,IAAI,CAAC,6BAA6B;oBAChC,uCAA2B,CAAC,oBAAoB,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;gBACzD;;;kBAGE;aACH;iBAAM,IACL,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,SAAS,EAC9D;gBACA,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;aAChE;SACF;IACH,CAAC;IAED;;OAEG;IACK,sCAAsC;QAC5C,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,0CAA0C,MAClD,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAG,uCAA2B,CAAC,sBAAsB,CACnE,UAAU,CACX,CAAC,CAAC,8BAA8B;gBAEjC,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iCAAiC;iBAC/E,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;YAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;SAChE;IACH,CAAC;IAED,IAAI,kBAAkB;QACpB,yBACK,IAAI,CAAC,QAAQ,EAChB;IACJ,CAAC;CACF;AAGC,kCAAW"} \ No newline at end of file +{"version":3,"file":"socksclient.js","sourceRoot":"","sources":["../../src/client/socksclient.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,mCAAsC;AACtC,2BAA2B;AAC3B,yBAAyB;AACzB,+CAA2C;AAC3C,mDAiB6B;AAC7B,+CAG2B;AAC3B,2DAAwD;AACxD,yCAAgE;AA0BhE,MAAM,WAAY,SAAQ,qBAAY;IAepC,YAAY,OAA2B;QACrC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,QAAQ,qBACR,OAAO,CACX,CAAC;QAEF,8BAA8B;QAC9B,oCAA0B,CAAC,OAAO,CAAC,CAAC;QAEpC,gBAAgB;QAChB,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,OAAO,CAAC;IACxC,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CACrB,OAA2B,EAC3B,QAAmB;QAEnB,8BAA8B;QAC9B,oCAA0B,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAEjD,OAAO,IAAI,OAAO,CAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;YACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,IAAiC,EAAE,EAAE;gBAC/D,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACrB,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,OAAO,CAAC,IAAI,CAAC,CAAC;iBACf;YACH,CAAC,CAAC,CAAC;YAEH,kDAAkD;YAClD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClC,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,qBAAqB,CAC1B,OAAgC,EAChC,QAAmB;QAEnB,mCAAmC;QACnC,yCAA+B,CAAC,OAAO,CAAC,CAAC;QAEzC,kBAAkB;QAClB,IAAI,OAAO,CAAC,cAAc,EAAE;YAC1B,mBAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAC/B;QAED,OAAO,IAAI,OAAO,CAA8B,CAAO,OAAO,EAAE,MAAM,EAAE,EAAE;YACxE,IAAI,IAAgB,CAAC;YAErB,IAAI;gBACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAErC,0HAA0H;oBAC1H,MAAM,eAAe,GACnB,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;wBAC9B,CAAC,CAAC,OAAO,CAAC,WAAW;wBACrB,CAAC,CAAC;4BACE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;4BACtC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;yBAClC,CAAC;oBAER,4CAA4C;oBAC5C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,gBAAgB,CAAC;wBAChD,OAAO,EAAE,SAAS;wBAClB,KAAK,EAAE,SAAS;wBAChB,WAAW,EAAE,eAAe;wBAC5B,8HAA8H;qBAC/H,CAAC,CAAC;oBAEH,wCAAwC;oBACxC,IAAI,CAAC,IAAI,EAAE;wBACT,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;qBACtB;iBACF;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBACjC,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC3B;aACF;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE;oBAClC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACd,OAAO,EAAE,CAAC,CAAC,oDAAoD;iBAChE;qBAAM;oBACL,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;aACF;QACH,CAAC,CAAA,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,OAA6B;QACjD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QAE1C,qBAAqB;QACrB,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YACvC,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;SACxD;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;SAC3C;QAED,OAAO;QACP,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE5C,OAAO;QACP,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAY;QAC/B,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAEpB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAmB,IAAI,CAAC,SAAS,EAAE,CAAC;QAClD,IAAI,UAAU,CAAC;QAEf,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YACpC,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;SAC/C;aAAM,IAAI,QAAQ,KAAK,0BAAc,CAAC,IAAI,EAAE;YAC3C,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;SAC/C;aAAM;YACL,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;SAChD;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEvC,OAAO;YACL,WAAW;YACX,UAAU,EAAE;gBACV,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,UAAU;aACjB;YACD,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,IAAY,KAAK;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAY,KAAK,CAAC,QAA0B;QAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,4BAAgB,CAAC,KAAK,EAAE;YAC1C,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;SACxB;IACH,CAAC;IAED;;;OAGG;IACI,OAAO,CAAC,eAAwB;QACrC,IAAI,CAAC,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,CAAC,GAAU,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAEzC,+CAA+C;QAC/C,MAAM,KAAK,GAAG,UAAU,CACtB,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,EACjC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,2BAAe,CACzC,CAAC;QAEF,8EAA8E;QAC9E,IAAI,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE;YACpD,KAAK,CAAC,KAAK,EAAE,CAAC;SACf;QAED,yGAAyG;QACzG,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC;SAChC;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;SACjC;QAED,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAE9C,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,cAAc,GAAG,IAAI,6BAAa,EAAE,CAAC;QAE1C,IAAI,eAAe,EAAE;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SAC9B;aAAM;YACJ,IAAI,CAAC,OAAsB,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAE9D,IACE,IAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,SAAS;gBAC3C,IAAI,CAAC,QAAQ,CAAC,eAAe,KAAK,IAAI,EACtC;gBACC,IAAI,CAAC,OAAsB,CAAC,UAAU,CACrC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAChC,CAAC;aACH;SACF;QAED,6FAA6F;QAC7F,IAAI,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE;YAC7C,YAAY,CAAC,GAAG,EAAE;gBAChB,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;oBAClC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CACxC,IAAI,CAAC,cAAc,CAAC,MAAM,CAC3B,CAAC;oBAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBACtC;gBACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IACvE,gBAAgB;QACtB,uCACK,IAAI,CAAC,QAAQ,CAAC,cAAc,KAC/B,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAC/D,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAC9B;IACJ,CAAC;IAED;;;OAGG;IACK,oBAAoB;QAC1B,IACE,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW;YAC3C,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EACzD;YACA,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,uBAAuB,CAAC,CAAC;SACnD;IACH,CAAC;IAED;;OAEG;IACK,SAAS;QACf,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,SAAS,CAAC;QAExC,0BAA0B;QAC1B,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;YAClC,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,0BAA0B,EAAE,CAAC;SACnC;QAED,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,oBAAoB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,cAAc,CAAC,IAAY;QACjC;;;UAGE;QACF,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEjC,6BAA6B;QAC7B,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,mFAAmF;QACnF,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,6BAA6B,EAAE;YACpE,gDAAgD;YAChD,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,oBAAoB,EAAE;gBACxD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBAClC,4CAA4C;oBAC5C,IAAI,CAAC,kCAAkC,EAAE,CAAC;iBAC3C;qBAAM;oBACL,wDAAwD;oBACxD,IAAI,CAAC,oCAAoC,EAAE,CAAC;iBAC7C;gBACD,wDAAwD;aACzD;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kDAAkD,EAAE,CAAC;gBAC1D,6DAA6D;aAC9D;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,kBAAkB,EAAE;gBAC7D,IAAI,CAAC,kCAAkC,EAAE,CAAC;gBAC1C,mEAAmE;aACpE;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,yBAAyB,EAAE;gBACpE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;oBAClC,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;qBAAM;oBACL,IAAI,CAAC,sCAAsC,EAAE,CAAC;iBAC/C;aACF;iBAAM,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,WAAW,EAAE;gBACtD,8CAA8C;aAC/C;iBAAM;gBACL,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,aAAa,CAAC,CAAC;aACzC;SACF;IACH,CAAC;IAED;;;OAGG;IACK,OAAO;QACb,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,YAAY,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACK,OAAO,CAAC,GAAU;QACxB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,6FAA6F;QAC7F,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,GAAW;QAC9B,2FAA2F;QAC3F,IAAI,IAAI,CAAC,KAAK,KAAK,4BAAgB,CAAC,KAAK,EAAE;YACzC,+BAA+B;YAC/B,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,KAAK,CAAC;YAEpC,iBAAiB;YACjB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAEvB,4BAA4B;YAC5B,IAAI,CAAC,4BAA4B,EAAE,CAAC;YAEpC,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,uBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;SAC9D;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAEhD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnD,iBAAiB;QACjB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,sBAAsB;SACvB;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SACpD;QAED,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,6BAA6B,OAAO,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CACzE,CAAC;SACH;aAAM;YACL,gBAAgB;YAChB,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBAC7D,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAEpB,MAAM,UAAU,GAAoB;oBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;oBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;iBACvC,CAAC;gBAEF,yCAAyC;gBACzC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBACD,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,yBAAyB,CAAC;gBACxD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;gBAEzD,mBAAmB;aACpB;iBAAM;gBACL,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;aACpD;SACF;IACH,CAAC;IAED;;;OAGG;IACK,sCAAsC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YACtC,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,0CAA0C,OAClD,0BAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,GAAG,CACJ,CAAC;SACH;aAAM;YACL,MAAM,IAAI,GAAG,0BAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;YAEpB,MAAM,UAAU,GAAoB;gBAClC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;gBACzB,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;aACvC,CAAC;YAEF,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;YAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;SAChE;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B;QAChC,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,6FAA6F;QAC7F,sHAAsH;QACtH,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;YAC9D,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,QAAQ,CAAC,CAAC;SACtC;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,UAAU,CAAC,sBAAU,CAAC,MAAM,CAAC,CAAC;SACpC;QAED,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,8BAA8B,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,oBAAoB,CAAC;IACrD,CAAC;IAED;;;OAGG;IACK,oCAAoC;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,yCAAyC,CAAC,CAAC;SACrE;aAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YAC3B,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,+CAA+C,CAAC,CAAC;SAC3E;aAAM;YACL,6EAA6E;YAC7E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,MAAM,EAAE;gBACjC,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,0EAA0E;aAC3E;iBAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,sBAAU,CAAC,QAAQ,EAAE;gBAC1C,IAAI,CAAC,gCAAgC,EAAE,CAAC;aACzC;iBAAM;gBACL,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,4CAA4C,CAAC,CAAC;aACxE;SACF;IACH,CAAC;IAED;;;;OAIG;IACK,gCAAgC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAEpD,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE3B,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,oCAAoC,CAAC;QACnE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,kBAAkB,CAAC;IACnD,CAAC;IAED;;;OAGG;IACK,kDAAkD;QACxD,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,8BAA8B,CAAC;QAE7D,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,YAAY,CAAC,kBAAM,CAAC,0BAA0B,CAAC,CAAC;SACtD;aAAM;YACL,IAAI,CAAC,wBAAwB,EAAE,CAAC;SACjC;IACH,CAAC;IAED;;OAEG;IACK,wBAAwB;QAC9B,MAAM,IAAI,GAAG,IAAI,0BAAW,EAAE,CAAC;QAE/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,CAAC,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAEtB,sBAAsB;QACtB,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC9C,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC/D;aAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YACrD,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;SAC/D;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,0BAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAClD;QACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEnD,IAAI,CAAC,6BAA6B;YAChC,uCAA2B,CAAC,oBAAoB,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,kBAAkB,CAAC;IACnD,CAAC;IAED;;;OAGG;IACK,kCAAkC;QACxC,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,mCAAmC,MAC3C,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAG,uCAA2B,CAAC,sBAAsB,CACnE,UAAU,CACX,CAAC,CAAC,qCAAqC;gBAExC,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iCAAiC;iBAC/E,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,6BAA6B;YAC7B,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,qBAAqB,CAAC;YAEpD,gEAAgE;YAChE,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,OAAO,EAAE;gBAChE,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;aACpD;iBAAM,IAAI,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,IAAI,EAAE;gBACpE;mHACmG;gBACnG,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,yBAAyB,CAAC;gBACxD,IAAI,CAAC,6BAA6B;oBAChC,uCAA2B,CAAC,oBAAoB,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;gBACzD;;;kBAGE;aACH;iBAAM,IACL,wBAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,wBAAY,CAAC,SAAS,EAC9D;gBACA,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;gBAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;aAChE;SACF;IACH,CAAC;IAED;;OAEG;IACK,sCAAsC;QAC5C,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE3C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,0BAAc,CAAC,OAAO,EAAE;YAC9D,IAAI,CAAC,YAAY,CACf,GAAG,kBAAM,CAAC,0CAA0C,MAClD,0BAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAC1B,EAAE,CACH,CAAC;SACH;aAAM;YACL,oBAAoB;YACpB,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YAE9B,IAAI,UAA2B,CAAC;YAChC,IAAI,IAAiB,CAAC;YAEtB,OAAO;YACP,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBACvC,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBAEF,4DAA4D;gBAC5D,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE;oBACjC,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;iBACjD;gBAED,WAAW;aACZ;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,QAAQ,EAAE;gBAClD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC7B,MAAM,UAAU,GAAG,uCAA2B,CAAC,sBAAsB,CACnE,UAAU,CACX,CAAC,CAAC,8BAA8B;gBAEjC,8BAA8B;gBAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,iCAAiC;iBAC/E,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;oBACjC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;gBACF,OAAO;aACR;iBAAM,IAAI,WAAW,KAAK,0BAAc,CAAC,IAAI,EAAE;gBAC9C,8BAA8B;gBAC9B,MAAM,UAAU,GAAG,uCAA2B,CAAC,kBAAkB,CAAC;gBAClE,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,UAAU,EAAE;oBAC3C,IAAI,CAAC,6BAA6B,GAAG,UAAU,CAAC;oBAChD,OAAO;iBACR;gBAED,IAAI,GAAG,0BAAW,CAAC,UAAU,CAC3B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAC7C,CAAC;gBAEF,UAAU,GAAG;oBACX,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE;iBAC1B,CAAC;aACH;YAED,IAAI,CAAC,KAAK,GAAG,4BAAgB,CAAC,WAAW,CAAC;YAC1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;SAChE;IACH,CAAC;IAED,IAAI,kBAAkB;QACpB,yBACK,IAAI,CAAC,QAAQ,EAChB;IACJ,CAAC;CACF;AAGC,kCAAW"} \ No newline at end of file diff --git a/deps/npm/node_modules/socks/build/common/constants.js.map b/deps/npm/node_modules/socks/build/common/constants.js.map index cd5e6690bc913b..a8677f72d7f1ab 100644 --- a/deps/npm/node_modules/socks/build/common/constants.js.map +++ b/deps/npm/node_modules/socks/build/common/constants.js.map @@ -1 +1 @@ -{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":";;AAIA,MAAM,eAAe,GAAG,KAAK,CAAC;AA2L5B,0CAAe;AAvLjB,kBAAkB;AAClB,MAAM,MAAM,GAAG;IACb,mBAAmB,EAAE,wFAAwF;IAC7G,+BAA+B,EAAE,oGAAoG;IACrI,wBAAwB,EAAE,8FAA8F;IACxH,oCAAoC,EAAE,2CAA2C;IACjF,uCAAuC,EAAE,uFAAuF;IAChI,8BAA8B,EAAE,4CAA4C;IAC5E,gCAAgC,EAAE,8EAA8E;IAChH,sCAAsC,EAAE,2DAA2D;IACnG,gBAAgB,EAAE,mBAAmB;IACrC,YAAY,EAAE,eAAe;IAC7B,uBAAuB,EAAE,4BAA4B;IACrD,aAAa,EAAE,qDAAqD;IACpE,8BAA8B,EAAE,4CAA4C;IAC5E,6BAA6B,EAAE,kCAAkC;IACjE,uCAAuC,EAAE,6CAA6C;IACtF,0CAA0C,EAAE,iDAAiD;IAC7F,qCAAqC,EAAE,oDAAoD;IAC3F,yCAAyC,EAAE,mEAAmE;IAC9G,+CAA+C,EAAE,6EAA6E;IAC9H,4CAA4C,EAAE,yEAAyE;IACvH,0BAA0B,EAAE,8BAA8B;IAC1D,2BAA2B,EAAE,kDAAkD;IAC/E,mCAAmC,EAAE,kCAAkC;IACvE,uCAAuC,EAAE,sDAAsD;IAC/F,0CAA0C,EAAE,iDAAiD;CAC9F,CAAC;AA6JA,wBAAM;AA3JR,MAAM,2BAA2B,GAAG;IAClC,8BAA8B,EAAE,CAAC;IACjC,oCAAoC,EAAE,CAAC;IACvC,gDAAgD;IAChD,oBAAoB,EAAE,CAAC;IACvB,kBAAkB,EAAE,EAAE;IACtB,kBAAkB,EAAE,EAAE;IACtB,sBAAsB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,cAAc,GAAG,CAAC;IACtE,gDAAgD;IAChD,cAAc,EAAE,CAAC,CAAC,2BAA2B;CAC9C,CAAC;AAiKA,kEAA2B;AA7J7B,IAAK,YAIJ;AAJD,WAAK,YAAY;IACf,qDAAc,CAAA;IACd,+CAAW,CAAA;IACX,yDAAgB,CAAA;AAClB,CAAC,EAJI,YAAY,KAAZ,YAAY,QAIhB;AA2IC,oCAAY;AAzId,IAAK,cAKJ;AALD,WAAK,cAAc;IACjB,0DAAc,CAAA;IACd,wDAAa,CAAA;IACb,4DAAe,CAAA;IACf,sEAAoB,CAAA;AACtB,CAAC,EALI,cAAc,KAAd,cAAc,QAKlB;AAqIC,wCAAc;AAnIhB,IAAK,UAIJ;AAJD,WAAK,UAAU;IACb,+CAAa,CAAA;IACb,+CAAa,CAAA;IACb,mDAAe,CAAA;AACjB,CAAC,EAJI,UAAU,KAAV,UAAU,QAId;AAgIC,gCAAU;AA9HZ,IAAK,cAUJ;AAVD,WAAK,cAAc;IACjB,yDAAc,CAAA;IACd,yDAAc,CAAA;IACd,+DAAiB,CAAA;IACjB,+EAAyB,CAAA;IACzB,yEAAsB,CAAA;IACtB,6EAAwB,CAAA;IACxB,+DAAiB,CAAA;IACjB,iFAA0B,CAAA;IAC1B,iFAA0B,CAAA;AAC5B,CAAC,EAVI,cAAc,KAAd,cAAc,QAUlB;AAsHC,wCAAc;AApHhB,IAAK,cAIJ;AAJD,WAAK,cAAc;IACjB,mDAAW,CAAA;IACX,2DAAe,CAAA;IACf,mDAAW,CAAA;AACb,CAAC,EAJI,cAAc,KAAd,cAAc,QAIlB;AA+GC,wCAAc;AA7GhB,IAAK,gBAcJ;AAdD,WAAK,gBAAgB;IACnB,6DAAW,CAAA;IACX,mEAAc,CAAA;IACd,iEAAa,CAAA;IACb,uFAAwB,CAAA;IACxB,+GAAoC,CAAA;IACpC,mFAAsB,CAAA;IACtB,2GAAkC,CAAA;IAClC,mFAAsB,CAAA;IACtB,yFAAyB,CAAA;IACzB,iGAA6B,CAAA;IAC7B,sEAAgB,CAAA;IAChB,wEAAiB,CAAA;IACjB,0DAAU,CAAA;AACZ,CAAC,EAdI,gBAAgB,KAAhB,gBAAgB,QAcpB;AAiGC,4CAAgB"} \ No newline at end of file +{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":";;AAIA,MAAM,eAAe,GAAG,KAAK,CAAC;AA6L5B,0CAAe;AAzLjB,kBAAkB;AAClB,MAAM,MAAM,GAAG;IACb,mBAAmB,EAAE,wFAAwF;IAC7G,+BAA+B,EAAE,oGAAoG;IACrI,wBAAwB,EAAE,8FAA8F;IACxH,oCAAoC,EAAE,2CAA2C;IACjF,uCAAuC,EAAE,uFAAuF;IAChI,8BAA8B,EAAE,4CAA4C;IAC5E,gCAAgC,EAAE,8EAA8E;IAChH,sCAAsC,EAAE,2DAA2D;IACnG,gBAAgB,EAAE,mBAAmB;IACrC,YAAY,EAAE,eAAe;IAC7B,uBAAuB,EAAE,4BAA4B;IACrD,aAAa,EAAE,qDAAqD;IACpE,8BAA8B,EAAE,4CAA4C;IAC5E,6BAA6B,EAAE,kCAAkC;IACjE,uCAAuC,EAAE,6CAA6C;IACtF,0CAA0C,EAAE,iDAAiD;IAC7F,qCAAqC,EAAE,oDAAoD;IAC3F,yCAAyC,EAAE,mEAAmE;IAC9G,+CAA+C,EAAE,6EAA6E;IAC9H,4CAA4C,EAAE,yEAAyE;IACvH,0BAA0B,EAAE,8BAA8B;IAC1D,2BAA2B,EAAE,kDAAkD;IAC/E,mCAAmC,EAAE,kCAAkC;IACvE,uCAAuC,EAAE,sDAAsD;IAC/F,0CAA0C,EAAE,iDAAiD;CAC9F,CAAC;AA+JA,wBAAM;AA7JR,MAAM,2BAA2B,GAAG;IAClC,8BAA8B,EAAE,CAAC;IACjC,oCAAoC,EAAE,CAAC;IACvC,gDAAgD;IAChD,oBAAoB,EAAE,CAAC;IACvB,kBAAkB,EAAE,EAAE;IACtB,kBAAkB,EAAE,EAAE;IACtB,sBAAsB,EAAE,CAAC,cAAsB,EAAE,EAAE,CAAC,cAAc,GAAG,CAAC;IACtE,gDAAgD;IAChD,cAAc,EAAE,CAAC,CAAC,2BAA2B;CAC9C,CAAC;AAmKA,kEAA2B;AA/J7B,IAAK,YAIJ;AAJD,WAAK,YAAY;IACf,qDAAc,CAAA;IACd,+CAAW,CAAA;IACX,yDAAgB,CAAA;AAClB,CAAC,EAJI,YAAY,KAAZ,YAAY,QAIhB;AA6IC,oCAAY;AA3Id,IAAK,cAKJ;AALD,WAAK,cAAc;IACjB,0DAAc,CAAA;IACd,wDAAa,CAAA;IACb,4DAAe,CAAA;IACf,sEAAoB,CAAA;AACtB,CAAC,EALI,cAAc,KAAd,cAAc,QAKlB;AAuIC,wCAAc;AArIhB,IAAK,UAIJ;AAJD,WAAK,UAAU;IACb,+CAAa,CAAA;IACb,+CAAa,CAAA;IACb,mDAAe,CAAA;AACjB,CAAC,EAJI,UAAU,KAAV,UAAU,QAId;AAkIC,gCAAU;AAhIZ,IAAK,cAUJ;AAVD,WAAK,cAAc;IACjB,yDAAc,CAAA;IACd,yDAAc,CAAA;IACd,+DAAiB,CAAA;IACjB,+EAAyB,CAAA;IACzB,yEAAsB,CAAA;IACtB,6EAAwB,CAAA;IACxB,+DAAiB,CAAA;IACjB,iFAA0B,CAAA;IAC1B,iFAA0B,CAAA;AAC5B,CAAC,EAVI,cAAc,KAAd,cAAc,QAUlB;AAwHC,wCAAc;AAtHhB,IAAK,cAIJ;AAJD,WAAK,cAAc;IACjB,mDAAW,CAAA;IACX,2DAAe,CAAA;IACf,mDAAW,CAAA;AACb,CAAC,EAJI,cAAc,KAAd,cAAc,QAIlB;AAiHC,wCAAc;AA/GhB,IAAK,gBAcJ;AAdD,WAAK,gBAAgB;IACnB,6DAAW,CAAA;IACX,mEAAc,CAAA;IACd,iEAAa,CAAA;IACb,uFAAwB,CAAA;IACxB,+GAAoC,CAAA;IACpC,mFAAsB,CAAA;IACtB,2GAAkC,CAAA;IAClC,mFAAsB,CAAA;IACtB,yFAAyB,CAAA;IACzB,iGAA6B,CAAA;IAC7B,sEAAgB,CAAA;IAChB,wEAAiB,CAAA;IACjB,0DAAU,CAAA;AACZ,CAAC,EAdI,gBAAgB,KAAhB,gBAAgB,QAcpB;AAmGC,4CAAgB"} \ No newline at end of file diff --git a/deps/npm/node_modules/socks/build/common/helpers.js.map b/deps/npm/node_modules/socks/build/common/helpers.js.map index 66fca6fafa177e..f02465f135174f 100644 --- a/deps/npm/node_modules/socks/build/common/helpers.js.map +++ b/deps/npm/node_modules/socks/build/common/helpers.js.map @@ -1 +1 @@ -{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/common/helpers.ts"],"names":[],"mappings":";;AAKA,iCAA0C;AAC1C,2CAA+D;AAC/D,iCAAiC;AAEjC;;;;GAIG;AACH,oCACE,OAA2B,EAC3B,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;IAEnD,8BAA8B;IAC9B,IAAI,CAAC,wBAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAClC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;KACjE;IAED,6CAA6C;IAC7C,IAAI,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE;QACpD,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;KAC7E;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,2BAA2B;IAC3B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC;KAC5E;IAED,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;IAED,sCAAsC;IACtC,IACE,OAAO,CAAC,eAAe;QACvB,CAAC,CAAC,OAAO,CAAC,eAAe,YAAY,MAAM,CAAC,MAAM,CAAC,EACnD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,uCAAuC,EAC9C,OAAO,CACR,CAAC;KACH;AACH,CAAC;AA0FQ,gEAA0B;AAxFnC;;;GAGG;AACH,yCAAyC,OAAgC;IACvE,2CAA2C;IAC3C,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;QACjC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;KACtE;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,4BAA4B;IAC5B,IACE,CAAC,CACC,OAAO,CAAC,OAAO;QACf,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAC5B,EACD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,sCAAsC,EAC7C,OAAO,CACR,CAAC;KACH;IAED,mBAAmB;IACnB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAiB,EAAE,EAAE;QAC5C,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,8BAA8B,EACrC,OAAO,CACR,CAAC;SACH;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;AACH,CAAC;AAuCoC,0EAA+B;AArCpE;;;GAGG;AACH,gCAAgC,UAA2B;IACzD,OAAO,CACL,UAAU;QACV,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,UAAU,CAAC,IAAI,IAAI,CAAC;QACpB,UAAU,CAAC,IAAI,IAAI,KAAK,CACzB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,2BAA2B,KAAiB;IAC1C,OAAO,CACL,KAAK;QACL,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC;QACvE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,KAAK,CAAC,IAAI,IAAI,CAAC;QACf,KAAK,CAAC,IAAI,IAAI,KAAK;QACnB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,6BAA6B,KAAa;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC;AAChD,CAAC"} \ No newline at end of file +{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/common/helpers.ts"],"names":[],"mappings":";;AAKA,iCAA0C;AAC1C,2CAA+D;AAC/D,iCAAiC;AAEjC;;;;GAIG;AACH,SAAS,0BAA0B,CACjC,OAA2B,EAC3B,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC;IAEnD,8BAA8B;IAC9B,IAAI,CAAC,wBAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAClC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;KACjE;IAED,6CAA6C;IAC7C,IAAI,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE;QACpD,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAC;KAC7E;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,2BAA2B;IAC3B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACrC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC;KAC5E;IAED,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;IAED,sCAAsC;IACtC,IACE,OAAO,CAAC,eAAe;QACvB,CAAC,CAAC,OAAO,CAAC,eAAe,YAAY,MAAM,CAAC,MAAM,CAAC,EACnD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,uCAAuC,EAC9C,OAAO,CACR,CAAC;KACH;AACH,CAAC;AA0FQ,gEAA0B;AAxFnC;;;GAGG;AACH,SAAS,+BAA+B,CAAC,OAAgC;IACvE,2CAA2C;IAC3C,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE;QACjC,MAAM,IAAI,uBAAgB,CAAC,kBAAM,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;KACtE;IAED,oBAAoB;IACpB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QAChD,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,oCAAoC,EAC3C,OAAO,CACR,CAAC;KACH;IAED,4BAA4B;IAC5B,IACE,CAAC,CACC,OAAO,CAAC,OAAO;QACf,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAC5B,EACD;QACA,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,sCAAsC,EAC7C,OAAO,CACR,CAAC;KACH;IAED,mBAAmB;IACnB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAiB,EAAE,EAAE;QAC5C,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,8BAA8B,EACrC,OAAO,CACR,CAAC;SACH;IACH,CAAC,CAAC,CAAC;IAEH,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAC5D,MAAM,IAAI,uBAAgB,CACxB,kBAAM,CAAC,gCAAgC,EACvC,OAAO,CACR,CAAC;KACH;AACH,CAAC;AAuCoC,0EAA+B;AArCpE;;;GAGG;AACH,SAAS,sBAAsB,CAAC,UAA2B;IACzD,OAAO,CACL,UAAU;QACV,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ;QACnC,UAAU,CAAC,IAAI,IAAI,CAAC;QACpB,UAAU,CAAC,IAAI,IAAI,KAAK,CACzB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAiB;IAC1C,OAAO,CACL,KAAK;QACL,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC;QACvE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,KAAK,CAAC,IAAI,IAAI,CAAC;QACf,KAAK,CAAC,IAAI,IAAI,KAAK;QACnB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC;AAChD,CAAC"} \ No newline at end of file diff --git a/deps/npm/node_modules/socks/build/common/receivebuffer.js.map b/deps/npm/node_modules/socks/build/common/receivebuffer.js.map index 12c94b011ea857..ed6ab3ac919d49 100644 --- a/deps/npm/node_modules/socks/build/common/receivebuffer.js.map +++ b/deps/npm/node_modules/socks/build/common/receivebuffer.js.map @@ -1 +1 @@ -{"version":3,"file":"receivebuffer.js","sourceRoot":"","sources":["../../src/common/receivebuffer.ts"],"names":[],"mappings":";;AAAA;IAKE,YAAY,OAAe,IAAI;QAC7B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;SACH;QAED,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAC/B,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,EACxC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAClC,CACF,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,MAAc;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;YACzB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;YACzB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;QAEvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAEQ,sCAAa"} \ No newline at end of file +{"version":3,"file":"receivebuffer.js","sourceRoot":"","sources":["../../src/common/receivebuffer.ts"],"names":[],"mappings":";;AAAA,MAAM,aAAa;IAKjB,YAAY,OAAe,IAAI;QAC7B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC1B,MAAM,IAAI,KAAK,CACb,6DAA6D,CAC9D,CAAC;SACH;QAED,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACrD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAC/B,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,EACxC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAClC,CACF,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACxB;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,MAAc;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;YACzB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,GAAG,CAAC,MAAc;QAChB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE;YACzB,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;SACH;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC;QAEvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAEQ,sCAAa"} \ No newline at end of file diff --git a/deps/npm/node_modules/socks/build/common/util.js.map b/deps/npm/node_modules/socks/build/common/util.js.map index 21ad0c1b42775a..40f971c60aefdd 100644 --- a/deps/npm/node_modules/socks/build/common/util.js.map +++ b/deps/npm/node_modules/socks/build/common/util.js.map @@ -1 +1 @@ -{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/common/util.ts"],"names":[],"mappings":";;AAEA;;GAEG;AACH,sBAAuB,SAAQ,KAAK;IAClC,YACE,OAAe,EACR,OAAqD;QAE5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,YAAO,GAAP,OAAO,CAA8C;IAG9D,CAAC;CACF;AAuBwB,4CAAgB;AArBzC;;;GAGG;AACH,sBAAsB,KAAY;IAChC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QACzC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7C;AACH,CAAC;AAY0C,oCAAY"} \ No newline at end of file +{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/common/util.ts"],"names":[],"mappings":";;AAEA;;GAEG;AACH,MAAM,gBAAiB,SAAQ,KAAK;IAClC,YACE,OAAe,EACR,OAAqD;QAE5D,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,YAAO,GAAP,OAAO,CAA8C;IAG9D,CAAC;CACF;AAuBwB,4CAAgB;AArBzC;;;GAGG;AACH,SAAS,YAAY,CAAC,KAAY;IAChC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QACzC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7C;AACH,CAAC;AAY0C,oCAAY"} \ No newline at end of file diff --git a/deps/npm/node_modules/socks/package.json b/deps/npm/node_modules/socks/package.json index 01402a426ac315..1dc66256633ff5 100644 --- a/deps/npm/node_modules/socks/package.json +++ b/deps/npm/node_modules/socks/package.json @@ -1,8 +1,8 @@ { "_from": "socks@~2.3.2", - "_id": "socks@2.3.2", + "_id": "socks@2.3.3", "_inBundle": false, - "_integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==", + "_integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", "_location": "/socks", "_phantomChildren": {}, "_requested": { @@ -18,10 +18,10 @@ "_requiredBy": [ "/socks-proxy-agent" ], - "_resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz", - "_shasum": "ade388e9e6d87fdb11649c15746c578922a5883e", + "_resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", + "_shasum": "01129f0a5d534d2b897712ed8aceab7ee65d78e3", "_spec": "socks@~2.3.2", - "_where": "/Users/isaacs/dev/npm/cli/node_modules/socks-proxy-agent", + "_where": "/Users/claudiahdz/npm/cli/node_modules/socks-proxy-agent", "author": { "name": "Josh Glazebrook" }, @@ -35,25 +35,25 @@ } ], "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "4.0.2" + "ip": "1.1.5", + "smart-buffer": "^4.1.0" }, "deprecated": false, "description": "Fully featured SOCKS proxy client supporting SOCKSv4, SOCKSv4a, and SOCKSv5. Includes Bind and Associate functionality.", "devDependencies": { - "@types/chai": "4.1.2", - "@types/ip": "^0.0.30", - "@types/mocha": "5.0.0", - "@types/node": "9.6.2", + "@types/chai": "4.2.4", + "@types/ip": "1.1.0", + "@types/mocha": "5.2.7", + "@types/node": "12.12.6", "chai": "^4.1.2", "coveralls": "^3.0.0", - "mocha": "5.0.5", - "nyc": "11.6.0", + "mocha": "6.2.2", + "nyc": "14.1.1", "prettier": "^1.9.2", "socks5-server": "^0.1.1", - "ts-node": "5.0.1", + "ts-node": "8.4.1", "tslint": "^5.8.0", - "typescript": "2.8.1" + "typescript": "3.7.2" }, "engines": { "node": ">= 6.0.0", @@ -106,8 +106,8 @@ "coveralls": "NODE_ENV=test nyc npm test && nyc report --reporter=text-lcov | coveralls", "lint": "tslint --project tsconfig.json 'src/**/*.ts'", "prepublish": "npm install -g typescript && npm run build", - "test": "NODE_ENV=test mocha --recursive --compilers ts:ts-node/register test/**/*.ts" + "test": "NODE_ENV=test mocha --recursive --require ts-node/register test/**/*.ts" }, "typings": "typings", - "version": "2.3.2" + "version": "2.3.3" } diff --git a/deps/npm/node_modules/socks/typings/client/socksclient.d.ts b/deps/npm/node_modules/socks/typings/client/socksclient.d.ts index 33e1c25fc5ef73..bd0b6ff4d2d604 100644 --- a/deps/npm/node_modules/socks/typings/client/socksclient.d.ts +++ b/deps/npm/node_modules/socks/typings/client/socksclient.d.ts @@ -3,7 +3,7 @@ import { EventEmitter } from 'events'; import { SocksClientOptions, SocksClientChainOptions, SocksRemoteHost, SocksProxy, SocksClientBoundEvent, SocksClientEstablishedEvent, SocksUDPFrameDetails } from '../common/constants'; import { SocksClientError } from '../common/util'; import { Duplex } from 'stream'; -interface SocksClient { +declare interface SocksClient { on(event: 'error', listener: (err: SocksClientError) => void): this; on(event: 'bound', listener: (info: SocksClientBoundEvent) => void): this; on(event: 'established', listener: (info: SocksClientEstablishedEvent) => void): this; @@ -59,99 +59,101 @@ declare class SocksClient extends EventEmitter implements SocksClient { /** * Gets the SocksClient internal state. */ + private get state(); /** * Internal state setter. If the SocksClient is in an error state, it cannot be changed to a non error state. */ - private state; + private set state(value); /** * Starts the connection establishment to the proxy and destination. * @param existing_socket Connected socket to use instead of creating a new one (internal use). */ connect(existing_socket?: Duplex): void; + private getSocketOptions; /** * Handles internal Socks timeout callback. * Note: If the Socks client is not BoundWaitingForConnection or Established, the connection will be closed. */ - private onEstablishedTimeout(); + private onEstablishedTimeout; /** * Handles Socket connect event. */ - private onConnect(); + private onConnect; /** * Handles Socket data event. * @param data */ - private onDataReceived(data); + private onDataReceived; /** * Handles processing of the data we have received. */ - private processData(); + private processData; /** * Handles Socket close event. * @param had_error */ - private onClose(); + private onClose; /** * Handles Socket error event. * @param err */ - private onError(err); + private onError; /** * Removes internal event listeners on the underlying Socket. */ - private removeInternalSocketHandlers(); + private removeInternalSocketHandlers; /** * Closes and destroys the underlying Socket. Emits an error event. * @param err { String } An error string to include in error event. */ - private _closeSocket(err); + private _closeSocket; /** * Sends initial Socks v4 handshake request. */ - private sendSocks4InitialHandshake(); + private sendSocks4InitialHandshake; /** * Handles Socks v4 handshake response. * @param data */ - private handleSocks4FinalHandshakeResponse(); + private handleSocks4FinalHandshakeResponse; /** * Handles Socks v4 incoming connection request (BIND) * @param data */ - private handleSocks4IncomingConnectionResponse(); + private handleSocks4IncomingConnectionResponse; /** * Sends initial Socks v5 handshake request. */ - private sendSocks5InitialHandshake(); + private sendSocks5InitialHandshake; /** * Handles initial Socks v5 handshake response. * @param data */ - private handleInitialSocks5HandshakeResponse(); + private handleInitialSocks5HandshakeResponse; /** * Sends Socks v5 user & password auth handshake. * * Note: No auth and user/pass are currently supported. */ - private sendSocks5UserPassAuthentication(); + private sendSocks5UserPassAuthentication; /** * Handles Socks v5 auth handshake response. * @param data */ - private handleInitialSocks5AuthenticationHandshakeResponse(); + private handleInitialSocks5AuthenticationHandshakeResponse; /** * Sends Socks v5 final handshake request. */ - private sendSocks5CommandRequest(); + private sendSocks5CommandRequest; /** * Handles Socks v5 final handshake response. * @param data */ - private handleSocks5FinalHandshakeResponse(); + private handleSocks5FinalHandshakeResponse; /** * Handles Socks v5 incoming connection request (BIND). */ - private handleSocks5IncomingConnectionResponse(); - readonly socksClientOptions: SocksClientOptions; + private handleSocks5IncomingConnectionResponse; + get socksClientOptions(): SocksClientOptions; } export { SocksClient, SocksClientOptions, SocksClientChainOptions, SocksRemoteHost, SocksProxy, SocksUDPFrameDetails }; diff --git a/deps/npm/node_modules/socks/typings/common/constants.d.ts b/deps/npm/node_modules/socks/typings/common/constants.d.ts index c8870be6234e4c..546fe3cfd967bc 100644 --- a/deps/npm/node_modules/socks/typings/common/constants.d.ts +++ b/deps/npm/node_modules/socks/typings/common/constants.d.ts @@ -1,6 +1,6 @@ /// import { Duplex } from 'stream'; -import { Socket } from 'net'; +import { Socket, SocketConnectOpts } from 'net'; import { RequireOnlyOne } from './util'; declare const DEFAULT_TIMEOUT = 30000; declare type SocksProxyType = 4 | 5; @@ -44,18 +44,18 @@ declare type SocksCommandOption = 'connect' | 'bind' | 'associate'; declare enum SocksCommand { connect = 1, bind = 2, - associate = 3, + associate = 3 } declare enum Socks4Response { Granted = 90, Failed = 91, Rejected = 92, - RejectedIdent = 93, + RejectedIdent = 93 } declare enum Socks5Auth { NoAuth = 0, GSSApi = 1, - UserPass = 2, + UserPass = 2 } declare enum Socks5Response { Granted = 0, @@ -66,12 +66,12 @@ declare enum Socks5Response { ConnectionRefused = 5, TTLExpired = 6, CommandNotSupported = 7, - AddressNotSupported = 8, + AddressNotSupported = 8 } declare enum Socks5HostType { IPv4 = 1, Hostname = 3, - IPv6 = 4, + IPv6 = 4 } declare enum SocksClientState { Created = 0, @@ -86,7 +86,7 @@ declare enum SocksClientState { BoundWaitingForConnection = 9, Established = 10, Disconnected = 11, - Error = 99, + Error = 99 } /** * Represents a SocksProxy @@ -116,6 +116,7 @@ interface SocksClientOptions { timeout?: number; existing_socket?: Duplex; set_tcp_nodelay?: boolean; + socket_options?: SocketConnectOpts; } /** * SocksClient chain connection options. diff --git a/deps/npm/node_modules/socks/typings/common/receiveBuffer.d.ts b/deps/npm/node_modules/socks/typings/common/receiveBuffer.d.ts index fe506a035785b9..7af56db12198f3 100644 --- a/deps/npm/node_modules/socks/typings/common/receiveBuffer.d.ts +++ b/deps/npm/node_modules/socks/typings/common/receiveBuffer.d.ts @@ -4,7 +4,7 @@ declare class ReceiveBuffer { private _offset; private _originalSize; constructor(size?: number); - readonly length: number; + get length(): number; append(data: Buffer): number; peek(length: number): Buffer; get(length: number): Buffer; diff --git a/deps/npm/node_modules/socks/yarn.lock b/deps/npm/node_modules/socks/yarn.lock deleted file mode 100644 index f8256b2779d931..00000000000000 --- a/deps/npm/node_modules/socks/yarn.lock +++ /dev/null @@ -1,2300 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/chai@4.1.2": - version "4.1.2" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.2.tgz#f1af664769cfb50af805431c407425ed619daa21" - -"@types/ip@^0.0.30": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/ip/-/ip-0.0.30.tgz#60c3309ce1cecdd7293245bbffc201ecb6f8c344" - -"@types/mocha@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.0.0.tgz#a3014921991066193f6c8e47290d4d598dfd19e6" - -"@types/node@9.6.2": - version "9.6.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.2.tgz#e49ac1adb458835e95ca6487bc20f916b37aff23" - -ajv@^5.1.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - dependencies: - color-convert "^1.9.0" - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - dependencies: - default-require-extensions "^1.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - -async@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -atob@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.0.tgz#ab2b150e51d7b122b9efc8d7340c06b6c41076bc" - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - -aws4@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-generator@^6.18.0: - version "6.26.1" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.7" - trim-right "^1.0.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.16.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.18.0, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.18.0, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - dependencies: - tweetnacl "^0.14.3" - -boom@4.x.x: - version "4.3.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" - dependencies: - hoek "4.x.x" - -boom@5.x.x: - version "5.2.0" - resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" - dependencies: - hoek "4.x.x" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -braces@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - define-property "^1.0.0" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - kind-of "^6.0.2" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - -builtin-modules@^1.0.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -caching-transform@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" - dependencies: - md5-hex "^1.2.0" - mkdirp "^0.5.1" - write-file-atomic "^1.1.4" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chai@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" - dependencies: - assertion-error "^1.0.1" - check-error "^1.0.1" - deep-eql "^3.0.0" - get-func-name "^2.0.0" - pathval "^1.0.0" - type-detect "^4.0.0" - -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -check-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.0.0.tgz#743d4650e05f36d1ed2575b59638d87322bfbbcc" - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -commander@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" - -commander@^2.12.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -convert-source-map@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - -core-js@^2.4.0: - version "2.5.4" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0" - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -coveralls@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.0.tgz#22ef730330538080d29b8c151dc9146afde88a99" - dependencies: - js-yaml "^3.6.1" - lcov-parse "^0.0.10" - log-driver "^1.2.5" - minimist "^1.2.0" - request "^2.79.0" - -cross-spawn@^4: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cryptiles@3.x.x: - version "3.1.2" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" - dependencies: - boom "5.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - -debug@3.1.0, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - -decamelize@^1.0.0, decamelize@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - -deep-eql@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - dependencies: - type-detect "^4.0.0" - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - dependencies: - strip-bom "^2.0.0" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -diff@3.5.0, diff@^3.1.0, diff@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0, extsprintf@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreground-child@^1.5.3, foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - dependencies: - map-cache "^0.2.2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@7.1.2, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -graceful-fs@^4.1.11, graceful-fs@^4.1.2: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -growl@1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" - -handlebars@^4.0.3: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - -har-validator@~5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" - dependencies: - ajv "^5.1.0" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hawk@~6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" - dependencies: - boom "4.x.x" - cryptiles "3.x.x" - hoek "4.x.x" - sntp "2.x.x" - -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - -hoek@4.x.x: - version "4.2.0" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" - -hosted-git-info@^2.1.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.6.0.tgz#23235b29ab230c576aab0d4f13fc046b0b038222" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -invariant@^2.2.2: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - dependencies: - kind-of "^6.0.0" - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - -is-odd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" - dependencies: - is-number "^4.0.0" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - dependencies: - isobject "^3.0.1" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - -isarray@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -istanbul-lib-coverage@^1.1.2, istanbul-lib-coverage@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" - -istanbul-lib-hook@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.1.0.tgz#8538d970372cb3716d53e55523dd54b557a8d89b" - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.10.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.2.0" - semver "^5.3.0" - -istanbul-lib-report@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.3.tgz#2df12188c0fa77990c0d2176d2d0ba3394188259" - dependencies: - istanbul-lib-coverage "^1.1.2" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.3.tgz#20fb54b14e14b3fb6edb6aca3571fd2143db44e6" - dependencies: - debug "^3.1.0" - istanbul-lib-coverage "^1.1.2" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.1.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554" - dependencies: - handlebars "^4.0.3" - -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@^3.6.1: - version "3.10.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^3.7.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -lcov-parse@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash@^4.17.4: - version "4.17.5" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" - -log-driver@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -lru-cache@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -make-error@^1.1.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - dependencies: - object-visit "^1.0.0" - -md5-hex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -merge-source-map@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - dependencies: - source-map "^0.6.1" - -micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - -mime-types@^2.1.12, mime-types@~2.1.17: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - dependencies: - mime-db "~1.30.0" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -mocha@5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.5.tgz#e228e3386b9387a4710007a641f127b00be44b52" - dependencies: - browser-stdout "1.3.1" - commander "2.11.0" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.3" - he "1.1.1" - mkdirp "0.5.1" - supports-color "4.4.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -nanomatch@^1.2.9: - version "1.2.9" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-odd "^2.0.0" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -normalize-package-data@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -nyc@11.6.0: - version "11.6.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.6.0.tgz#d9c7b51ffceb6bba099a4683a6adc1b331b98853" - dependencies: - archy "^1.0.0" - arrify "^1.0.1" - caching-transform "^1.0.0" - convert-source-map "^1.5.1" - debug-log "^1.0.1" - default-require-extensions "^1.0.0" - find-cache-dir "^0.1.1" - find-up "^2.1.0" - foreground-child "^1.5.3" - glob "^7.0.6" - istanbul-lib-coverage "^1.1.2" - istanbul-lib-hook "^1.1.0" - istanbul-lib-instrument "^1.10.0" - istanbul-lib-report "^1.1.3" - istanbul-lib-source-maps "^1.2.3" - istanbul-reports "^1.1.4" - md5-hex "^1.2.0" - merge-source-map "^1.0.2" - micromatch "^2.3.11" - mkdirp "^0.5.0" - resolve-from "^2.0.0" - rimraf "^2.5.4" - signal-exit "^3.0.1" - spawn-wrap "^1.4.2" - test-exclude "^4.2.0" - yargs "11.1.0" - yargs-parser "^8.0.0" - -oauth-sign@~0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - dependencies: - isobject "^3.0.0" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - dependencies: - isobject "^3.0.1" - -once@^1.3.0, once@^1.3.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.2.0.tgz#0e92b6bedcb59f022c13d0f1949dc82d15909f1c" - dependencies: - p-try "^1.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pathval@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -prettier@^1.9.2: - version "1.11.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - -regex-cache@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" - dependencies: - is-equal-shallow "^0.1.3" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@^2.79.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - -resolve@^1.3.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.6.0.tgz#0fbd21278b27b4004481c395349e7aba60a9ff5c" - dependencies: - path-parse "^1.0.5" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - dependencies: - glob "^7.0.5" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - dependencies: - ret "~0.1.10" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - -smart-buffer@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.2.tgz#5207858c3815cc69110703c6b94e46c15634395d" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sntp@2.x.x: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" - dependencies: - hoek "4.x.x" - -socks5-server@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/socks5-server/-/socks5-server-0.1.1.tgz#6542d277bcb55b68c2910430d4112ccca58c0189" - dependencies: - debug "^2.2.0" - ip "^1.1.0" - once "^1.3.3" - -source-map-resolve@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" - dependencies: - atob "^2.0.0" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.5.3: - version "0.5.4" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" - dependencies: - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - -spawn-wrap@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.6.2" - signal-exit "^3.0.2" - which "^1.3.0" - -spdx-correct@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -supports-color@4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" - dependencies: - has-flag "^2.0.0" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" - dependencies: - has-flag "^3.0.0" - -test-exclude@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" - dependencies: - arrify "^1.0.1" - micromatch "^3.1.8" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -tough-cookie@~2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - dependencies: - punycode "^1.4.1" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -ts-node@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81" - dependencies: - arrify "^1.0.0" - chalk "^2.3.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.5.3" - yn "^2.0.0" - -tslib@^1.8.0, tslib@^1.8.1: - version "1.9.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" - -tslint@^5.8.0: - version "5.9.1" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" - dependencies: - babel-code-frame "^6.22.0" - builtin-modules "^1.1.1" - chalk "^2.3.0" - commander "^2.12.1" - diff "^3.2.0" - glob "^7.1.1" - js-yaml "^3.7.0" - minimatch "^3.0.4" - resolve "^1.3.2" - semver "^5.3.0" - tslib "^1.8.0" - tsutils "^2.12.1" - -tsutils@^2.12.1: - version "2.26.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.26.0.tgz#706240d63bcf1ae1797d1716738d6c6be0d0848b" - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-detect@^4.0.0: - version "4.0.5" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2" - -typescript@2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624" - -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -use@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" - dependencies: - kind-of "^6.0.2" - -uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -validate-npm-package-license@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.9, which@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" - dependencies: - isexe "^2.0.0" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^1.1.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.1.0.tgz#f1376a33b6629a5d063782944da732631e966950" - dependencies: - camelcase "^4.1.0" - -yargs-parser@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" - dependencies: - camelcase "^4.1.0" - -yargs@11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" - dependencies: - cliui "^4.0.0" - decamelize "^1.1.1" - find-up "^2.1.0" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^9.0.2" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" diff --git a/deps/npm/node_modules/sorted-union-stream/node_modules/from2/index.js b/deps/npm/node_modules/sorted-union-stream/node_modules/from2/index.js index d83be0b5546051..1e58cdee1fad55 100644 --- a/deps/npm/node_modules/sorted-union-stream/node_modules/from2/index.js +++ b/deps/npm/node_modules/sorted-union-stream/node_modules/from2/index.js @@ -20,7 +20,7 @@ function from2(opts, read) { read = opts opts = {} } - + if (Array.isArray(read)) read = toFunction(read) var rs = new Proto(opts) diff --git a/deps/npm/node_modules/sorted-union-stream/node_modules/isarray/build/build.js b/deps/npm/node_modules/sorted-union-stream/node_modules/isarray/build/build.js index e1856ef0943728..ec58596aeebe4e 100644 --- a/deps/npm/node_modules/sorted-union-stream/node_modules/isarray/build/build.js +++ b/deps/npm/node_modules/sorted-union-stream/node_modules/isarray/build/build.js @@ -206,3 +206,4 @@ module.exports = Array.isArray || function (arr) { }); require.alias("isarray/index.js", "isarray/index.js"); + diff --git a/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/README.md b/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/README.md index 9e9b6eee9f349f..e46b823903d2c6 100644 --- a/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/README.md +++ b/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/README.md @@ -12,3 +12,4 @@ If you want to guarantee a stable streams base, regardless of what version of No **readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. **readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/float.patch b/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/float.patch index 7abb6dc30b21bf..b984607a41cc1f 100644 --- a/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/float.patch +++ b/deps/npm/node_modules/sorted-union-stream/node_modules/readable-stream/float.patch @@ -3,36 +3,36 @@ index c5a741c..a2e0d8e 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -26,8 +26,8 @@ - + module.exports = Duplex; var util = require('util'); -var Readable = require('_stream_readable'); -var Writable = require('_stream_writable'); +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); - + util.inherits(Duplex, Readable); - + diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js index a5e9864..330c247 100644 --- a/lib/_stream_passthrough.js +++ b/lib/_stream_passthrough.js @@ -25,7 +25,7 @@ - + module.exports = PassThrough; - + -var Transform = require('_stream_transform'); +var Transform = require('./_stream_transform'); var util = require('util'); util.inherits(PassThrough, Transform); - + diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 0c3fe3e..90a8298 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -23,10 +23,34 @@ module.exports = Readable; Readable.ReadableState = ReadableState; - + var EE = require('events').EventEmitter; +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; @@ -63,12 +63,12 @@ index 0c3fe3e..90a8298 100644 +} catch (er) { + debug = function() {}; +} - + util.inherits(Readable, Stream); - + @@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) { - - + + function onEofChunk(stream, state) { - if (state.decoder && !state.ended) { + if (state.decoder && !state.ended && state.decoder.end) { @@ -80,9 +80,9 @@ index b1f9fcc..b0caf57 100644 --- a/lib/_stream_transform.js +++ b/lib/_stream_transform.js @@ -64,8 +64,14 @@ - + module.exports = Transform; - + -var Duplex = require('_stream_duplex'); +var Duplex = require('./_stream_duplex'); var util = require('util'); @@ -93,15 +93,15 @@ index b1f9fcc..b0caf57 100644 + } +} util.inherits(Transform, Duplex); - - + + diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index ba2e920..f49288b 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -27,6 +27,12 @@ module.exports = Writable; Writable.WritableState = WritableState; - + var util = require('util'); +if (!util.isUndefined) { + var utilIs = require('core-util-is'); @@ -110,7 +110,7 @@ index ba2e920..f49288b 100644 + } +} var Stream = require('stream'); - + util.inherits(Writable, Stream); @@ -119,7 +125,7 @@ function WritableState(options, stream) { function Writable(options) { @@ -119,29 +119,29 @@ index ba2e920..f49288b 100644 - if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) + if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex'))) return new Writable(options); - + this._writableState = new WritableState(options, this); diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js index e3787e4..8cd2127 100644 --- a/test/simple/test-stream-big-push.js +++ b/test/simple/test-stream-big-push.js @@ -21,7 +21,7 @@ - + var common = require('../common'); var assert = require('assert'); -var stream = require('stream'); +var stream = require('../../'); var str = 'asdfasdfasdfasdfasdf'; - + var r = new stream.Readable({ diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js index bb73777..d40efc7 100644 --- a/test/simple/test-stream-end-paused.js +++ b/test/simple/test-stream-end-paused.js @@ -25,7 +25,7 @@ var gotEnd = false; - + // Make sure we don't miss the end event for paused 0-length streams - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; var stream = new Readable(); @@ -154,13 +154,13 @@ index b46ee90..0be8366 100644 @@ -22,8 +22,8 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('_stream_readable'); -var Writable = require('_stream_writable'); +var Readable = require('../../lib/_stream_readable'); +var Writable = require('../../lib/_stream_writable'); var util = require('util'); - + util.inherits(TestReadable, Readable); diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js deleted file mode 100644 @@ -295,12 +295,12 @@ index c5d724b..c7d6b7d 100644 --- a/test/simple/test-stream-pipe-error-handling.js +++ b/test/simple/test-stream-pipe-error-handling.js @@ -21,7 +21,7 @@ - + var common = require('../common'); var assert = require('assert'); -var Stream = require('stream').Stream; +var Stream = require('../../').Stream; - + (function testErrorListenerCatches() { var source = new Stream(); diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js @@ -309,25 +309,25 @@ index cb9d5fe..56f8d61 100644 +++ b/test/simple/test-stream-pipe-event.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. - + var common = require('../common'); -var stream = require('stream'); +var stream = require('../../'); var assert = require('assert'); var util = require('util'); - + diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js index f2e6ec2..a5c9bf9 100644 --- a/test/simple/test-stream-push-order.js +++ b/test/simple/test-stream-push-order.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. - + var common = require('../common.js'); -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; var assert = require('assert'); - + var s = new Readable({ diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js index 06f43dc..1701a9a 100644 @@ -336,11 +336,11 @@ index 06f43dc..1701a9a 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; var util = require('util'); - + util.inherits(MyStream, Readable); diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js index ba6a577..a8e6f7b 100644 @@ -349,10 +349,10 @@ index ba6a577..a8e6f7b 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; - + (function first() { // First test, not reading when the readable is added. diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js @@ -362,10 +362,10 @@ index 2891ad6..11689ba 100644 @@ -27,7 +27,7 @@ var assert = require('assert'); // more data continuously, but without triggering a nextTick // warning or RangeError. - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; - + // throw an error if we trigger a nextTick warning. process.throwDeprecation = true; diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js @@ -373,12 +373,12 @@ index 0c96476..7827538 100644 --- a/test/simple/test-stream-unshift-empty-chunk.js +++ b/test/simple/test-stream-unshift-empty-chunk.js @@ -24,7 +24,7 @@ var assert = require('assert'); - - // This test verifies that stream.unshift(Buffer(0)) or + + // This test verifies that stream.unshift(Buffer(0)) or // stream.unshift('') does not set state.reading=false. -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; - + var r = new Readable(); var nChunks = 10; diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js @@ -388,14 +388,14 @@ index 83fd9fa..17c18aa 100644 @@ -29,7 +29,7 @@ var assert = require('assert'); // 3. push() after the EOF signaling null is an error. // 4. _read() is not called after pushing the EOF null chunk. - + -var stream = require('stream'); +var stream = require('../../'); var hwm = 10; var r = stream.Readable({ highWaterMark: hwm }); var chunks = 10; @@ -51,7 +51,14 @@ r._read = function(n) { - + function push(fast) { assert(!pushedNull, 'push() after null push'); - var c = pos >= data.length ? null : data.slice(pos, pos + n); @@ -417,10 +417,10 @@ index 5b49e6e..b5321f3 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var stream = require('stream'); +var stream = require('../../'); - + var queue = []; for (var decode = 0; decode < 2; decode++) { diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js @@ -428,26 +428,26 @@ index 3814bf0..248c1be 100644 --- a/test/simple/test-stream2-basic.js +++ b/test/simple/test-stream2-basic.js @@ -21,7 +21,7 @@ - - + + var common = require('../common.js'); -var R = require('_stream_readable'); +var R = require('../../lib/_stream_readable'); var assert = require('assert'); - + var util = require('util'); diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js index 6cdd4e9..f0fa84b 100644 --- a/test/simple/test-stream2-compatibility.js +++ b/test/simple/test-stream2-compatibility.js @@ -21,7 +21,7 @@ - - + + var common = require('../common.js'); -var R = require('_stream_readable'); +var R = require('../../lib/_stream_readable'); var assert = require('assert'); - + var util = require('util'); diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js index 39b274f..006a19b 100644 @@ -455,12 +455,12 @@ index 39b274f..006a19b 100644 +++ b/test/simple/test-stream2-finish-pipe.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. - + var common = require('../common.js'); -var stream = require('stream'); +var stream = require('../../'); var Buffer = require('buffer').Buffer; - + var r = new stream.Readable(); diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js deleted file mode 100644 @@ -605,7 +605,7 @@ index 2fbfbca..667985b 100644 @@ -30,7 +30,7 @@ var PUSHSIZE = 20; var PUSHCOUNT = 1000; var HWM = 50; - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; var r = new Readable({ @@ -613,7 +613,7 @@ index 2fbfbca..667985b 100644 }); @@ -39,23 +39,23 @@ var rs = r._readableState; r._read = push; - + r.on('readable', function() { - console.error('>> readable'); + //console.error('>> readable'); @@ -624,7 +624,7 @@ index 2fbfbca..667985b 100644 - console.error(' < %j (%d remain)', ret && ret.length, rs.length); + //console.error(' < %j (%d remain)', ret && ret.length, rs.length); } while (ret && ret.length === READSIZE); - + - console.error('<< after read()', - ret && ret.length, - rs.needReadable, @@ -634,24 +634,24 @@ index 2fbfbca..667985b 100644 + // rs.needReadable, + // rs.length); }); - + var endEmitted = false; r.on('end', function() { endEmitted = true; - console.error('end'); + //console.error('end'); }); - + var pushes = 0; @@ -64,11 +64,11 @@ function push() { return; - + if (pushes++ === PUSHCOUNT) { - console.error(' push(EOF)'); + //console.error(' push(EOF)'); return r.push(null); } - + - console.error(' push #%d', pushes); + //console.error(' push #%d', pushes); if (r.push(new Buffer(PUSHSIZE))) @@ -662,27 +662,27 @@ index 3e6931d..ff47d89 100644 --- a/test/simple/test-stream2-objects.js +++ b/test/simple/test-stream2-objects.js @@ -21,8 +21,8 @@ - - + + var common = require('../common.js'); -var Readable = require('_stream_readable'); -var Writable = require('_stream_writable'); +var Readable = require('../../lib/_stream_readable'); +var Writable = require('../../lib/_stream_writable'); var assert = require('assert'); - + // tiny node-tap lookalike. diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js index cf7531c..e3f3e4e 100644 --- a/test/simple/test-stream2-pipe-error-handling.js +++ b/test/simple/test-stream2-pipe-error-handling.js @@ -21,7 +21,7 @@ - + var common = require('../common'); var assert = require('assert'); -var stream = require('stream'); +var stream = require('../../'); - + (function testErrorListenerCatches() { var count = 1000; diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js @@ -691,12 +691,12 @@ index 5e8e3cb..53b2616 100755 +++ b/test/simple/test-stream2-pipe-error-once-listener.js @@ -24,7 +24,7 @@ var common = require('../common.js'); var assert = require('assert'); - + var util = require('util'); -var stream = require('stream'); +var stream = require('../../'); - - + + var Read = function() { diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js index b63edc3..eb2b0e9 100644 @@ -704,7 +704,7 @@ index b63edc3..eb2b0e9 100644 +++ b/test/simple/test-stream2-push.js @@ -20,7 +20,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. - + var common = require('../common.js'); -var stream = require('stream'); +var stream = require('../../'); @@ -716,14 +716,14 @@ index e8a7305..9740a47 100644 --- a/test/simple/test-stream2-read-sync-stack.js +++ b/test/simple/test-stream2-read-sync-stack.js @@ -21,7 +21,7 @@ - + var common = require('../common'); var assert = require('assert'); -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; var r = new Readable(); var N = 256 * 1024; - + diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js index cd30178..4b1659d 100644 --- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js @@ -731,13 +731,13 @@ index cd30178..4b1659d 100644 @@ -22,10 +22,9 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('stream').Readable; +var Readable = require('../../').Readable; - + test1(); -test2(); - + function test1() { var r = new Readable(); @@ -88,31 +87,3 @@ function test1() { @@ -777,12 +777,12 @@ index 7c96ffe..04a96f5 100644 --- a/test/simple/test-stream2-readable-from-list.js +++ b/test/simple/test-stream2-readable-from-list.js @@ -21,7 +21,7 @@ - + var assert = require('assert'); var common = require('../common.js'); -var fromList = require('_stream_readable')._fromList; +var fromList = require('../../lib/_stream_readable')._fromList; - + // tiny node-tap lookalike. var tests = []; diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js @@ -792,23 +792,23 @@ index 675da8e..51fd3d5 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var Stream = require('stream'); +var Stream = require('../../'); var Readable = Stream.Readable; - + var r = new Readable(); diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js index 7314ae7..c971898 100644 --- a/test/simple/test-stream2-readable-non-empty-end.js +++ b/test/simple/test-stream2-readable-non-empty-end.js @@ -21,7 +21,7 @@ - + var assert = require('assert'); var common = require('../common.js'); -var Readable = require('_stream_readable'); +var Readable = require('../../lib/_stream_readable'); - + var len = 0; var chunks = new Array(10); diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js @@ -818,11 +818,11 @@ index 2e5cf25..fd8a3dc 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('_stream_readable'); +var Readable = require('../../lib/_stream_readable'); var EE = require('events').EventEmitter; - + var oldStream = new EE(); diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js index 90eea01..6b177f7 100644 @@ -831,40 +831,40 @@ index 90eea01..6b177f7 100644 @@ -22,8 +22,8 @@ var common = require('../common'); var assert = require('assert'); - + -var Readable = require('_stream_readable'); -var Writable = require('_stream_writable'); +var Readable = require('../../lib/_stream_readable'); +var Writable = require('../../lib/_stream_writable'); var EE = require('events').EventEmitter; - + var testRuns = 0, completedRuns = 0; diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js index 5d2c32a..685531b 100644 --- a/test/simple/test-stream2-set-encoding.js +++ b/test/simple/test-stream2-set-encoding.js @@ -22,7 +22,7 @@ - + var common = require('../common.js'); var assert = require('assert'); -var R = require('_stream_readable'); +var R = require('../../lib/_stream_readable'); var util = require('util'); - + // tiny node-tap lookalike. diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js index 9c9ddd8..a0cacc6 100644 --- a/test/simple/test-stream2-transform.js +++ b/test/simple/test-stream2-transform.js @@ -21,8 +21,8 @@ - + var assert = require('assert'); var common = require('../common.js'); -var PassThrough = require('_stream_passthrough'); -var Transform = require('_stream_transform'); +var PassThrough = require('../../').PassThrough; +var Transform = require('../../').Transform; - + // tiny node-tap lookalike. var tests = []; diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js @@ -872,41 +872,41 @@ index d66dc3c..365b327 100644 --- a/test/simple/test-stream2-unpipe-drain.js +++ b/test/simple/test-stream2-unpipe-drain.js @@ -22,7 +22,7 @@ - + var common = require('../common.js'); var assert = require('assert'); -var stream = require('stream'); +var stream = require('../../'); var crypto = require('crypto'); - + var util = require('util'); diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js index 99f8746..17c92ae 100644 --- a/test/simple/test-stream2-unpipe-leak.js +++ b/test/simple/test-stream2-unpipe-leak.js @@ -22,7 +22,7 @@ - + var common = require('../common.js'); var assert = require('assert'); -var stream = require('stream'); +var stream = require('../../'); - + var chunk = new Buffer('hallo'); - + diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js index 704100c..209c3a6 100644 --- a/test/simple/test-stream2-writable.js +++ b/test/simple/test-stream2-writable.js @@ -20,8 +20,8 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. - + var common = require('../common.js'); -var W = require('_stream_writable'); -var D = require('_stream_duplex'); +var W = require('../../').Writable; +var D = require('../../').Duplex; var assert = require('assert'); - + var util = require('util'); diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js index b91bde3..2f72c15 100644 @@ -915,8 +915,9 @@ index b91bde3..2f72c15 100644 @@ -22,7 +22,7 @@ var common = require('../common'); var assert = require('assert'); - + -var stream = require('stream'); +var stream = require('../../'); var Readable = stream.Readable; var Writable = stream.Writable; + diff --git a/deps/npm/node_modules/sshpk/README.md b/deps/npm/node_modules/sshpk/README.md index 1db08035764e91..310c2ee98cdbe0 100644 --- a/deps/npm/node_modules/sshpk/README.md +++ b/deps/npm/node_modules/sshpk/README.md @@ -4,7 +4,7 @@ sshpk Parse, convert, fingerprint and use SSH keys (both public and private) in pure node -- no `ssh-keygen` or other external dependencies. -Supports RSA, DSA, ECDSA (nistp-\*) and ED25519 key types, in PEM (PKCS#1, +Supports RSA, DSA, ECDSA (nistp-\*) and ED25519 key types, in PEM (PKCS#1, PKCS#8) and OpenSSH formats. This library has been extracted from @@ -124,10 +124,10 @@ Parameters - `ssh`: standard OpenSSH format, - `pkcs1`, `pkcs8`: variants of `pem` - `rfc4253`: raw OpenSSH wire format - - `openssh`: new post-OpenSSH 6.5 internal format, produced by + - `openssh`: new post-OpenSSH 6.5 internal format, produced by `ssh-keygen -o` - `options` -- Optional Object, extra options, with keys: - - `filename` -- Optional String, name for the key being parsed + - `filename` -- Optional String, name for the key being parsed (eg. the filename that was opened). Used to generate Error messages - `passphrase` -- Optional String, encryption passphrase used to decrypt an @@ -282,7 +282,7 @@ a Buffer. Parameters -- `format` -- String name of format to use, valid options are listed under +- `format` -- String name of format to use, valid options are listed under `parsePrivateKey`. Note that ED25519 keys default to `openssh` format instead (as they have no `pkcs1` representation). diff --git a/deps/npm/node_modules/sshpk/man/man1/sshpk-conv.1 b/deps/npm/node_modules/sshpk/man/man1/sshpk-conv.1 index d03b3067395d34..0887dce2728fb2 100644 --- a/deps/npm/node_modules/sshpk/man/man1/sshpk-conv.1 +++ b/deps/npm/node_modules/sshpk/man/man1/sshpk-conv.1 @@ -13,7 +13,7 @@ Reads in a public or private key and converts it between different formats, particularly formats used in the SSH protocol and the well\-known PEM PKCS#1/7 formats. .PP -In the second form, with the \fB\fC\-i\fR option given, identifies a key and prints to +In the second form, with the \fB\fC\-i\fR option given, identifies a key and prints to stderr information about its nature, size and fingerprint. .SH EXAMPLES .PP @@ -76,7 +76,7 @@ MIIDpAIBAAKCAQEA6T/GYJndb1TRH3+NL.... .SH OPTIONS .TP \fB\fC\-i, \-\-identify\fR -Instead of converting the key, output identifying information about it to +Instead of converting the key, output identifying information about it to stderr, including its type, size and fingerprints. .TP \fB\fC\-p, \-\-private\fR @@ -125,7 +125,7 @@ The internal binary format of keys when sent over the wire in the SSH protocol. This is also the format that the \fB\fCssh\-agent\fR uses in its protocol. .SH SEE ALSO .PP -.BR ssh-keygen (1), +.BR ssh-keygen (1), .BR openssl (1) .SH BUGS .PP diff --git a/deps/npm/node_modules/stream-iterate/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/stream-iterate/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/stream-iterate/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/stream-iterate/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/stream-iterate/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/stream-iterate/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/stream-iterate/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/stream-iterate/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/stringify-package/README.md b/deps/npm/node_modules/stringify-package/README.md index 1df31378711636..1ba4f5a330d175 100644 --- a/deps/npm/node_modules/stringify-package/README.md +++ b/deps/npm/node_modules/stringify-package/README.md @@ -28,11 +28,11 @@ fs.writeFile('package.json', stringifyPackage(pkg), 'utf8', cb(err) => { ### Features -* Ensures consistent file indentation +* Ensures consistent file indentation To match existing file indentation, [`detect-indent`](https://npm.im/detect-indent) is recommended. -* Ensures consistent newlines +* Ensures consistent newlines To match existing newline characters, [`detect-newline`](https://npm.im/detect-newline) is recommended. diff --git a/deps/npm/node_modules/strip-json-comments/readme.md b/deps/npm/node_modules/strip-json-comments/readme.md index 5a3447147434d8..0ee58dfe3a2e9b 100644 --- a/deps/npm/node_modules/strip-json-comments/readme.md +++ b/deps/npm/node_modules/strip-json-comments/readme.md @@ -47,7 +47,7 @@ Accepts a string with JSON and returns a string without comments. ##### whitespace -Type: `boolean` +Type: `boolean` Default: `true` Replace comments with whitespace instead of stripping them entirely. diff --git a/deps/npm/node_modules/through/LICENSE.MIT b/deps/npm/node_modules/through/LICENSE.MIT index 49e7da41fec2be..6eafbd734a6e06 100644 --- a/deps/npm/node_modules/through/LICENSE.MIT +++ b/deps/npm/node_modules/through/LICENSE.MIT @@ -2,23 +2,23 @@ The MIT License Copyright (c) 2011 Dominic Tarr -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/deps/npm/node_modules/through/index.js b/deps/npm/node_modules/through/index.js index 9f443ffd2b1936..ca5fc5901fd875 100644 --- a/deps/npm/node_modules/through/index.js +++ b/deps/npm/node_modules/through/index.js @@ -105,3 +105,4 @@ function through (write, end, opts) { } return stream } + diff --git a/deps/npm/node_modules/through/readme.markdown b/deps/npm/node_modules/through/readme.markdown index 4939fffe422cf5..cb34c8135f53eb 100644 --- a/deps/npm/node_modules/through/readme.markdown +++ b/deps/npm/node_modules/through/readme.markdown @@ -3,14 +3,14 @@ [![build status](https://secure.travis-ci.org/dominictarr/through.png)](http://travis-ci.org/dominictarr/through) [![testling badge](https://ci.testling.com/dominictarr/through.png)](https://ci.testling.com/dominictarr/through) -Easy way to create a `Stream` that is both `readable` and `writable`. +Easy way to create a `Stream` that is both `readable` and `writable`. * Pass in optional `write` and `end` methods. * `through` takes care of pause/resume logic if you use `this.queue(data)` instead of `this.emit('data', data)`. * Use `this.pause()` and `this.resume()` to manage flow. * Check `this.paused` to see current flow state. (`write` always returns `!this.paused`). -This function is the basis for most of the synchronous streams in +This function is the basis for most of the synchronous streams in [event-stream](http://github.com/dominictarr/event-stream). ``` js @@ -32,7 +32,7 @@ var through = require('through') through(function write(data) { this.emit('data', data) - //this.pause() + //this.pause() }, function end () { //optional this.emit('end') diff --git a/deps/npm/node_modules/through/test/async.js b/deps/npm/node_modules/through/test/async.js index f6fc95f4ffad8f..46bdbaebcbc09b 100644 --- a/deps/npm/node_modules/through/test/async.js +++ b/deps/npm/node_modules/through/test/async.js @@ -4,7 +4,7 @@ var through = require('../') var tape = require('tape') tape('simple async example', function (t) { - + var n = 0, expected = [1,2,3,4,5], actual = [] from(expected) .pipe(through(function(data) { diff --git a/deps/npm/node_modules/through/test/auto-destroy.js b/deps/npm/node_modules/through/test/auto-destroy.js index 305fff23d35d9b..9a8fd0006f5b80 100644 --- a/deps/npm/node_modules/through/test/auto-destroy.js +++ b/deps/npm/node_modules/through/test/auto-destroy.js @@ -27,3 +27,4 @@ test('end before close', function (assert) { assert.ok(closed) assert.end() }) + diff --git a/deps/npm/node_modules/through/test/index.js b/deps/npm/node_modules/through/test/index.js index 1d9523f40e495a..96da82f97c74cf 100644 --- a/deps/npm/node_modules/through/test/index.js +++ b/deps/npm/node_modules/through/test/index.js @@ -15,7 +15,7 @@ function write(array, stream) { while(array.length) if(stream.write(array.shift()) === false) return stream.once('drain', next) - + stream.end() } @@ -59,15 +59,15 @@ test('simple defaults', function(assert) { test('simple functions', function(assert) { var l = 1000 - , expected = [] + , expected = [] while(l--) expected.push(l * Math.random()) var t = through(function (data) { this.emit('data', data*2) - }) + }) var s = spec(t).through().pausable() - + read(t, function (err, actual) { assert.ifError(err) @@ -85,12 +85,12 @@ test('simple functions', function(assert) { test('pauses', function(assert) { var l = 1000 - , expected = [] + , expected = [] while(l--) expected.push(l) //Math.random()) - var t = through() - + var t = through() + var s = spec(t) .through() .pausable() diff --git a/deps/npm/node_modules/through2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md b/deps/npm/node_modules/through2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md index c141a99c26c638..83275f192e4077 100644 --- a/deps/npm/node_modules/through2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +++ b/deps/npm/node_modules/through2/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md @@ -56,3 +56,5 @@ simpler stream creation * add isPaused/isFlowing * add new docs section * move isPaused to that section + + diff --git a/deps/npm/node_modules/through2/node_modules/string_decoder/LICENSE b/deps/npm/node_modules/through2/node_modules/string_decoder/LICENSE index 2873b3b2e59507..778edb20730ef4 100644 --- a/deps/npm/node_modules/through2/node_modules/string_decoder/LICENSE +++ b/deps/npm/node_modules/through2/node_modules/string_decoder/LICENSE @@ -45,3 +45,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ + diff --git a/deps/npm/node_modules/through2/through2.js b/deps/npm/node_modules/through2/through2.js index ef13980d7b9dd3..5b7a880e829a41 100644 --- a/deps/npm/node_modules/through2/through2.js +++ b/deps/npm/node_modules/through2/through2.js @@ -12,7 +12,7 @@ inherits(DestroyableTransform, Transform) DestroyableTransform.prototype.destroy = function(err) { if (this._destroyed) return this._destroyed = true - + var self = this process.nextTick(function() { if (err) diff --git a/deps/npm/node_modules/timed-out/readme.md b/deps/npm/node_modules/timed-out/readme.md index d0eb92341ebc08..fa0a0356507cf5 100644 --- a/deps/npm/node_modules/timed-out/readme.md +++ b/deps/npm/node_modules/timed-out/readme.md @@ -20,14 +20,14 @@ timeout(req, 2000); // Set 2 seconds limit ##### request -*Required* +*Required* Type: [`ClientRequest`](http://nodejs.org/api/http.html#http_class_http_clientrequest) The request to watch on. ##### time -*Required* +*Required* Type: `number` or `object` Time in milliseconds to wait for `connect` event on socket and also time to wait on inactive socket. diff --git a/deps/npm/node_modules/tweetnacl/CHANGELOG.md b/deps/npm/node_modules/tweetnacl/CHANGELOG.md index b6deabce4495d1..92a4fdc56ac53f 100644 --- a/deps/npm/node_modules/tweetnacl/CHANGELOG.md +++ b/deps/npm/node_modules/tweetnacl/CHANGELOG.md @@ -181,18 +181,18 @@ v0.10.0 * **Signature API breaking change!** `nacl.sign` and `nacl.sign.open` now deal with signed messages, and new `nacl.sign.detached` and `nacl.sign.detached.verify` are available. - + Previously, `nacl.sign` returned a signature, and `nacl.sign.open` accepted a message and "detached" signature. This was unlike NaCl's API, which dealt with signed messages (concatenation of signature and message). - + The new API is: nacl.sign(message, secretKey) -> signedMessage nacl.sign.open(signedMessage, publicKey) -> message | null Since detached signatures are common, two new API functions were introduced: - + nacl.sign.detached(message, secretKey) -> signature nacl.sign.detached.verify(message, signature, publicKey) -> true | false diff --git a/deps/npm/node_modules/typedarray/test/server/undef_globals.js b/deps/npm/node_modules/typedarray/test/server/undef_globals.js index e57dabdcebc9c1..425950f9fc9ed7 100644 --- a/deps/npm/node_modules/typedarray/test/server/undef_globals.js +++ b/deps/npm/node_modules/typedarray/test/server/undef_globals.js @@ -11,7 +11,7 @@ test('u8a without globals', function (t) { vm.runInNewContext(src, c); var TA = c.module.exports; var ua = new(TA.Uint8Array)(5); - + t.equal(ua.length, 5); ua[1] = 256 + 55; t.equal(ua[1], 55); diff --git a/deps/npm/node_modules/unique-slug/README.md b/deps/npm/node_modules/unique-slug/README.md index 08f7a7b48fcd24..52de4277db20a0 100644 --- a/deps/npm/node_modules/unique-slug/README.md +++ b/deps/npm/node_modules/unique-slug/README.md @@ -17,3 +17,4 @@ hex. If *str* is not passed in, it will be 4 bytes coverted into 8 hex characters, generated by `crypto.pseudoRandomBytes`. + diff --git a/deps/npm/node_modules/uuid/lib/bytesToUuid.js b/deps/npm/node_modules/uuid/lib/bytesToUuid.js index f201a8885463ab..847c482843c820 100644 --- a/deps/npm/node_modules/uuid/lib/bytesToUuid.js +++ b/deps/npm/node_modules/uuid/lib/bytesToUuid.js @@ -11,7 +11,7 @@ function bytesToUuid(buf, offset) { var i = offset || 0; var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], + return ([bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', diff --git a/deps/npm/node_modules/wcwidth/LICENSE b/deps/npm/node_modules/wcwidth/LICENSE index 14deaf94b8162d..313ef1e888e41b 100644 --- a/deps/npm/node_modules/wcwidth/LICENSE +++ b/deps/npm/node_modules/wcwidth/LICENSE @@ -27,3 +27,4 @@ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/deps/npm/node_modules/wcwidth/docs/index.md b/deps/npm/node_modules/wcwidth/docs/index.md index 64c1f3f7cd8a8a..5c5126d03287b4 100644 --- a/deps/npm/node_modules/wcwidth/docs/index.md +++ b/deps/npm/node_modules/wcwidth/docs/index.md @@ -60,3 +60,6 @@ for any purpose and without fee is hereby granted. The author disclaims all warranties with regard to this software. Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c + + + diff --git a/deps/npm/node_modules/wide-align/LICENSE b/deps/npm/node_modules/wide-align/LICENSE index 2a4982dc40cb69..f4be44d881b2d9 100644 --- a/deps/npm/node_modules/wide-align/LICENSE +++ b/deps/npm/node_modules/wide-align/LICENSE @@ -11,3 +11,4 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + diff --git a/deps/npm/node_modules/wide-align/README.md b/deps/npm/node_modules/wide-align/README.md index 4cbb017556118d..32f1be04f09776 100644 --- a/deps/npm/node_modules/wide-align/README.md +++ b/deps/npm/node_modules/wide-align/README.md @@ -40,7 +40,7 @@ Returns *str* with spaces to the left such that it is *length* chars long. ### Origins -These functions were originally taken from +These functions were originally taken from [cliui](https://npmjs.com/package/cliui). Changes include switching to the MUCH faster pad generation function from [lodash](https://npmjs.com/package/lodash), making center alignment pad diff --git a/deps/npm/node_modules/wide-align/align.js b/deps/npm/node_modules/wide-align/align.js index 9e8359c6c718e3..4f94ca4cde19b5 100644 --- a/deps/npm/node_modules/wide-align/align.js +++ b/deps/npm/node_modules/wide-align/align.js @@ -56,7 +56,7 @@ function alignCenter (str, width) { var strWidth = stringWidth(trimmed) if (strWidth < width) { - var padLeftBy = parseInt((width - strWidth) / 2, 10) + var padLeftBy = parseInt((width - strWidth) / 2, 10) padLeft = createPadding(padLeftBy) padRight = createPadding(width - (strWidth + padLeftBy)) } diff --git a/deps/npm/node_modules/widest-line/index.js b/deps/npm/node_modules/widest-line/index.js index 284a0251e410fc..173cec4f296bb8 100644 --- a/deps/npm/node_modules/widest-line/index.js +++ b/deps/npm/node_modules/widest-line/index.js @@ -2,3 +2,4 @@ const stringWidth = require('string-width'); module.exports = input => Math.max.apply(null, input.split('\n').map(x => stringWidth(x))); + diff --git a/deps/npm/node_modules/yargs-parser/CHANGELOG.md b/deps/npm/node_modules/yargs-parser/CHANGELOG.md index f75cfa0ec3ec14..a0186f2330f1c1 100644 --- a/deps/npm/node_modules/yargs-parser/CHANGELOG.md +++ b/deps/npm/node_modules/yargs-parser/CHANGELOG.md @@ -75,7 +75,7 @@ All notable changes to this project will be documented in this file. See [standa ### BREAKING CHANGES -* strings that fail `Number.isSafeInteger()` are no longer coerced into numbers. +* strings that fail `Number.isSafeInteger()` are no longer coerced into numbers. diff --git a/deps/npm/package.json b/deps/npm/package.json index d051bfca9ba65b..6fad0e829f1c54 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "6.12.1", + "version": "6.13.1", "name": "npm", "description": "a package manager for JavaScript", "keywords": [ @@ -110,14 +110,14 @@ "once": "~1.4.0", "opener": "^1.5.1", "osenv": "^0.1.5", - "pacote": "^9.5.8", + "pacote": "^9.5.9", "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", "qrcode-terminal": "^0.12.0", "query-string": "^6.8.2", "qw": "~1.0.1", "read": "~1.0.7", - "read-cmd-shim": "^1.0.4", + "read-cmd-shim": "^1.0.5", "read-installed": "~4.0.3", "read-package-json": "^2.1.0", "read-package-tree": "^5.3.1", @@ -291,7 +291,7 @@ }, "scripts": { "dumpconf": "env | grep npm | sort | uniq", - "prepare": "node bin/npm-cli.js rebuild && node bin/npm-cli.js --no-audit --no-timing prune --prefix=. --no-global && rimraf test/*/*/node_modules && make -j4 doc", + "prepare": "node bin/npm-cli.js rebuild && node bin/npm-cli.js --no-audit --no-timing prune --prefix=. --no-global && rimraf test/*/*/node_modules && make -j4 mandocs", "preversion": "bash scripts/update-authors.sh && git add AUTHORS && git commit -m \"update AUTHORS\" || true", "licenses": "licensee --production --errors-only", "tap": "tap -J --timeout 300 --no-esm", diff --git a/deps/npm/scripts/doc-build.sh b/deps/npm/scripts/doc-build.sh deleted file mode 100755 index a37a5e2618fa87..00000000000000 --- a/deps/npm/scripts/doc-build.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env bash - -if [[ $DEBUG != "" ]]; then - set -x -fi -set -o errexit -set -o pipefail - -src=$1 -dest=$2 -name=$(basename ${src%.*}) -date=$(date -u +'%Y-%m-%d %H:%M:%S') -version=$(node bin/npm-cli.js -v) - -mkdir -p $(dirname $dest) - -html_replace_tokens () { - local url=$1 - sed "s|@NAME@|$name|g" \ - | sed "s|@DATE@|$date|g" \ - | sed "s|@URL@|$url|g" \ - | sed "s|@VERSION@|$version|g" \ - | perl -p -e 's/]*)>([^\(]*\([0-9]\)) -- (.*?)<\/h1>/

    \2<\/h1>

    \3<\/p>/g' \ - | perl -p -e 's/npm-npm/npm/g' \ - | perl -p -e 's/([^"-])(npm-)?README(?!\.html)(\(1\))?/\1README<\/a>/g' \ - | perl -p -e 's/<a href="[^"]+README.html">README<\/a><\/title>/<title>README<\/title>/g' \ - | perl -p -e 's/([^"-])([^\(> ]+)(\(1\))/\1<a href="..\/cli\/\2.html">\2\3<\/a>/g' \ - | perl -p -e 's/([^"-])([^\(> ]+)(\(3\))/\1<a href="..\/api\/\2.html">\2\3<\/a>/g' \ - | perl -p -e 's/([^"-])([^\(> ]+)(\(5\))/\1<a href="..\/files\/\2.html">\2\3<\/a>/g' \ - | perl -p -e 's/([^"-])([^\(> ]+)(\(7\))/\1<a href="..\/misc\/\2.html">\2\3<\/a>/g' \ - | perl -p -e 's/\([1357]\)<\/a><\/h1>/<\/a><\/h1>/g' \ - | (if [ $(basename $(dirname $dest)) == "doc" ]; then - perl -p -e 's/ href="\.\.\// href="/g' - else - cat - fi) -} - -man_replace_tokens () { - sed "s|@VERSION@|$version|g" \ - | perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(1\)/npm help \2/g' \ - | perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(([57])\)/npm help \3 \2/g' \ - | perl -p -e 's/(npm\\-)?([a-zA-Z\\\.\-]*)\(3\)/npm apihelp \2/g' \ - | perl -p -e 's/npm\(1\)/npm help npm/g' \ - | perl -p -e 's/npm\(3\)/npm apihelp npm/g' -} - -case $dest in - *.[1357]) - ./node_modules/.bin/marked-man --roff $src \ - | man_replace_tokens > $dest - exit $? - ;; - *.html) - url=${dest/html\//} - (cat html/dochead.html && \ - cat $src | ./node_modules/.bin/marked && - cat html/docfoot.html)\ - | html_replace_tokens $url \ - > $dest - exit $? - ;; - *) - echo "Invalid destination type: $dest" >&2 - exit 1 - ;; -esac diff --git a/deps/npm/scripts/docs-build.js b/deps/npm/scripts/docs-build.js new file mode 100644 index 00000000000000..e3cd2e9826f1e6 --- /dev/null +++ b/deps/npm/scripts/docs-build.js @@ -0,0 +1,28 @@ +#!/usr/bin/env node + +var fs = require('fs') +var marked = require('marked-man') +var npm = require('../lib/npm.js') +var args = process.argv.slice(2) +var src = args[0] +var dest = args[1] || src + +fs.readFile(src, 'utf8', function (err, data) { + if (err) return console.log(err) + + function replacer (match, p1) { + return 'npm help ' + p1.replace(/npm /, '') + } + + var result = data.replace(/@VERSION@/g, npm.version) + .replace(/---([\s\S]+)---/g, '') + .replace(/\[([^\]]+)\]\(\/cli-commands\/([^)]+)\)/g, replacer) + .replace(/\[([^\]]+)\]\(\/configuring-npm\/([^)]+)\)/g, replacer) + .replace(/\[([^\]]+)\]\(\/using-npm\/([^)]+)\)/g, replacer) + .replace(/(# .*)\s+(## (.*))/g, '$1 - $3') + .trim() + + fs.writeFile(dest, marked(result), 'utf8', function (err) { + if (err) return console.log(err) + }) +}) diff --git a/deps/npm/scripts/index-build.js b/deps/npm/scripts/index-build.js deleted file mode 100755 index e782716d772918..00000000000000 --- a/deps/npm/scripts/index-build.js +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env node -var fs = require('fs') -var path = require('path') -var root = path.resolve(__dirname, '..') -var glob = require('glob') -var conversion = { 'cli': 1, 'api': 3, 'files': 5, 'misc': 7 } - -glob(root + '/{README.md,doc/*/*.md}', function (er, files) { - if (er) throw er - - output(files.map(function (f) { - var b = path.basename(f) - if (b === 'README.md') return [0, b] - if (b === 'index.md') return null - var s = conversion[path.basename(path.dirname(f))] - return [s, f] - }).filter(function (f) { - return f - }).sort(function (a, b) { - return (a[0] === b[0]) - ? (path.basename(a[1]) === 'npm.md' ? -1 - : path.basename(b[1]) === 'npm.md' ? 1 - : a[1] > b[1] ? 1 : -1) - : a[0] - b[0] - })) -}) - -function output (files) { - console.log( - 'npm-index(7) -- Index of all npm documentation\n' + - '==============================================\n') - - writeLines(files, 0) - writeLines(files, 1, 'Command Line Documentation', 'Using npm on the command line') - writeLines(files, 3, 'API Documentation', 'Using npm in your Node programs') - writeLines(files, 5, 'Files', 'File system structures npm uses') - writeLines(files, 7, 'Misc', 'Various other bits and bobs') -} - -function writeLines (files, sxn, heading, desc) { - if (heading) { - console.log('## %s\n\n%s\n', heading, desc) - } - files.filter(function (f) { - return f[0] === sxn - }).forEach(writeLine) -} - -function writeLine (sd) { - var sxn = sd[0] || 1 - var doc = sd[1] - var d = path.basename(doc, '.md') - - var content = fs.readFileSync(doc, 'utf8').split('\n')[0].split('-- ')[1] - - console.log('### %s(%d)\n', d, sxn) - console.log(content + '\n') -} diff --git a/deps/npm/test/common-tap.js b/deps/npm/test/common-tap.js index d8dc8a10d870e4..9e38c7690fa71e 100644 --- a/deps/npm/test/common-tap.js +++ b/deps/npm/test/common-tap.js @@ -193,7 +193,8 @@ exports.makeGitRepo = function (params, cb) { git.chainableExec(['config', 'user.name', user], opts), git.chainableExec(['config', 'user.email', email], opts), // don't time out tests waiting for a gpg passphrase or 2fa - git.chainableExec(['config', 'commit.gpgsign', 'false'], opts), + git.chainableExec(['config', 'commit.gpgSign', 'false'], opts), + git.chainableExec(['config', 'tag.gpgSign', 'false'], opts), git.chainableExec(['config', 'tag.forceSignAnnotated', 'false'], opts), git.chainableExec(['add'].concat(added), opts), git.chainableExec(['commit', '-m', message], opts) @@ -216,17 +217,15 @@ exports.readBinLink = function (path) { exports.skipIfWindows = function (why) { if (!isWindows) return - console.log('1..1') if (!why) why = 'this test not available on windows' - console.log('ok 1 # skip ' + why) + require('tap').plan(0, why) process.exit(0) } exports.pendIfWindows = function (why) { if (!isWindows) return - console.log('1..1') if (!why) why = 'this test is pending further changes on windows' - console.log('not ok 1 # todo ' + why) + require('tap').fail(' ', { todo: why, diagnostic: false }) process.exit(0) } diff --git a/deps/npm/test/fake-registry.md b/deps/npm/test/fake-registry.md index 766c0972dcd3e5..604fda41670bec 100644 --- a/deps/npm/test/fake-registry.md +++ b/deps/npm/test/fake-registry.md @@ -160,7 +160,7 @@ compatibility mode and the default value of port comes from `common.port`. ### done() -Resets all of the configured mocks. +Resets all of the configured mocks. ### close() diff --git a/deps/npm/test/fixtures/config/userconfig-with-gc b/deps/npm/test/fixtures/config/userconfig-with-gc index a3a837eb78dd47..b00d5195bd8361 100644 --- a/deps/npm/test/fixtures/config/userconfig-with-gc +++ b/deps/npm/test/fixtures/config/userconfig-with-gc @@ -1,4 +1,4 @@ -globalconfig = /Users/mperrotte/npminc/cli/test/fixtures/config/globalconfig +globalconfig = /Users/claudiahdz/npm/cli/test/fixtures/config/globalconfig email = i@izs.me env-thing = ${random_env_var} init.author.name = Isaac Z. Schlueter diff --git a/deps/npm/test/tap/404-parent.js b/deps/npm/test/tap/404-parent.js index 306a4bc4bf2543..ee9623c545505f 100644 --- a/deps/npm/test/tap/404-parent.js +++ b/deps/npm/test/tap/404-parent.js @@ -1,7 +1,6 @@ var common = require('../common-tap.js') var test = require('tap').test var npm = require('../../') -var osenv = require('osenv') var path = require('path') var fs = require('fs') var rimraf = require('rimraf') @@ -10,20 +9,15 @@ var mr = require('npm-registry-mock') test('404-parent: if parent exists, specify parent in error message', function (t) { setup() - rimraf.sync(path.resolve(pkg, 'node_modules')) - performInstall(function (err) { - t.ok(err instanceof Error, 'error was returned') - t.equal(err.parent, '404-parent', "error's parent set") - t.end() + rimraf(path.resolve(pkg, 'node_modules'), () => { + performInstall(function (err) { + t.ok(err instanceof Error, 'error was returned') + t.equal(err.parent, '404-parent', "error's parent set") + t.end() + }) }) }) -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) - function setup () { fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ author: 'Evan Lucas', diff --git a/deps/npm/test/tap/access.js b/deps/npm/test/tap/access.js index 2998bbf63b2d52..4183c46b538c0e 100644 --- a/deps/npm/test/tap/access.js +++ b/deps/npm/test/tap/access.js @@ -73,8 +73,7 @@ test('npm access public when no package passed and no package.json', function (t function (er, code, stdout, stderr) { t.ifError(er, 'npm access') t.match(stderr, /no package name passed to command and no package.json found/) - rimraf.sync(missing) - t.end() + rimraf(missing, t.end) }) }) @@ -95,8 +94,7 @@ test('npm access public when no package passed and invalid package.json', functi function (er, code, stdout, stderr) { t.ifError(er, 'npm access') t.match(stderr, /Failed to parse json/) - rimraf.sync(invalid) - t.end() + rimraf(invalid, t.end) }) }) @@ -405,8 +403,7 @@ test('npm access ls-packages with no package specified or package.json', functio function (er, code, stdout, stderr) { t.ifError(er, 'npm access ls-packages') t.same(JSON.parse(stdout), clientPackages) - rimraf.sync(missing) - t.end() + rimraf(missing, t.end) } ) }) @@ -557,7 +554,6 @@ test('npm access blerg', function (t) { test('cleanup', function (t) { t.pass('cleaned up') - rimraf.sync(pkg) server.done() server.close() t.end() diff --git a/deps/npm/test/tap/add-remote-git-file.js b/deps/npm/test/tap/add-remote-git-file.js index 7d64609072dda0..483c6368c6490a 100644 --- a/deps/npm/test/tap/add-remote-git-file.js +++ b/deps/npm/test/tap/add-remote-git-file.js @@ -4,17 +4,16 @@ var fs = require('fs') var resolve = require('path').resolve var url = require('url') -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../lib/npm.js') var fetchPackageMetadata = require('../../lib/fetch-package-metadata.js') var common = require('../common-tap.js') -var pkg = common.pkg -var repo = common.pkg + '-repo' +var pkg = resolve(common.pkg, 'package') +var repo = resolve(common.pkg, 'repo') +mkdirp.sync(pkg) var git var cloneURL = 'git+file://' + resolve(pkg, 'child.git') @@ -25,7 +24,6 @@ var pjChild = JSON.stringify({ }, null, 2) + '\n' test('setup', function (t) { - bootstrap() setup(function (er, r) { t.ifError(er, 'git started up successfully') @@ -70,16 +68,6 @@ test('save install', function (t) { }) }) -test('clean', function (t) { - cleanup() - t.end() -}) - -function bootstrap () { - cleanup() - mkdirp.sync(pkg) -} - function setup (cb) { mkdirp.sync(repo) fs.writeFileSync(resolve(repo, 'package.json'), pjChild) @@ -95,9 +83,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(repo) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/add-remote-git-shrinkwrap.js b/deps/npm/test/tap/add-remote-git-shrinkwrap.js index 0daf2922e76455..01a033e89451ff 100644 --- a/deps/npm/test/tap/add-remote-git-shrinkwrap.js +++ b/deps/npm/test/tap/add-remote-git-shrinkwrap.js @@ -1,16 +1,14 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../lib/npm.js') var common = require('../common-tap.js') -var pkg = common.pkg -var repo = pkg + '-repo' +var pkg = resolve(common.pkg, 'package') +var repo = resolve(common.pkg, 'repo') var daemon var daemonPID @@ -30,7 +28,8 @@ var pjChild = JSON.stringify({ }, null, 2) + '\n' test('setup', function (t) { - bootstrap() + mkdirp.sync(pkg) + fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) setup(function (er, r) { t.ifError(er, 'git started up successfully') @@ -85,19 +84,10 @@ test('shrinkwrap gets correct _from and _resolved (#7121)', function (t) { }) test('clean', function (t) { - daemon.on('close', function () { - cleanup() - t.end() - }) + daemon.on('close', t.end) process.kill(daemonPID) }) -function bootstrap () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) -} - function setup (cb) { mkdirp.sync(repo) fs.writeFileSync(resolve(repo, 'package.json'), pjChild) @@ -145,9 +135,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(repo) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/add-remote-git-submodule.js b/deps/npm/test/tap/add-remote-git-submodule.js index 43b30f7a65bcb5..54f2819fb330e3 100644 --- a/deps/npm/test/tap/add-remote-git-submodule.js +++ b/deps/npm/test/tap/add-remote-git-submodule.js @@ -1,7 +1,7 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') +var cwd = process.cwd() var mkdirp = require('mkdirp') var rimraf = require('rimraf') var test = require('tap').test @@ -9,8 +9,8 @@ var test = require('tap').test var npm = require('../../lib/npm.js') var common = require('../common-tap.js') -var pkg = common.pkg -var repos = pkg + '-repos' +var pkg = resolve(common.pkg, 'package') +var repos = resolve(common.pkg, 'repos') var subwt = resolve(repos, 'subwt') var topwt = resolve(repos, 'topwt') var suburl = 'git://localhost:' + common.gitPort + '/sub.git' @@ -62,14 +62,13 @@ test('has file in submodule', function (t) { test('clean', function (t) { daemon.on('close', function () { - cleanup() t.end() }) process.kill(daemonPID) }) function bootstrap (t) { - process.chdir(osenv.tmpdir()) + process.chdir(cwd) rimraf.sync(pkg) mkdirp.sync(pkg) process.chdir(pkg) @@ -141,9 +140,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(repos) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/add-remote-git.js b/deps/npm/test/tap/add-remote-git.js index 44294924f15a77..2a619634391110 100644 --- a/deps/npm/test/tap/add-remote-git.js +++ b/deps/npm/test/tap/add-remote-git.js @@ -1,16 +1,14 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../lib/npm.js') var common = require('../common-tap.js') -var pkg = common.pkg -var repo = pkg + '-repo' +var pkg = resolve(common.pkg, 'package') +var repo = resolve(pkg, 'repo') var daemon var daemonPID @@ -30,7 +28,8 @@ var pjChild = JSON.stringify({ }, null, 2) + '\n' test('setup', function (t) { - bootstrap() + mkdirp.sync(pkg) + fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) setup(function (er, r) { t.ifError(er, 'git started up successfully') @@ -47,25 +46,15 @@ test('install from repo', function (t) { process.chdir(pkg) npm.commands.install('.', [], function (er) { t.ifError(er, 'npm installed via git') - t.end() }) }) test('clean', function (t) { - daemon.on('close', function () { - cleanup() - t.end() - }) + daemon.on('close', t.end) process.kill(daemonPID) }) -function bootstrap () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) -} - function setup (cb) { mkdirp.sync(repo) fs.writeFileSync(resolve(repo, 'package.json'), pjChild) @@ -113,9 +102,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(repo) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/all-package-metadata.js b/deps/npm/test/tap/all-package-metadata.js index 153878500acbae..75afa9bad2c0c7 100644 --- a/deps/npm/test/tap/all-package-metadata.js +++ b/deps/npm/test/tap/all-package-metadata.js @@ -26,8 +26,8 @@ function setup () { mkdirp.sync(cacheBase) } -function cleanup () { - rimraf.sync(PKG_DIR) +function cleanup (cb) { + rimraf(PKG_DIR, cb) } test('setup', function (t) { @@ -88,8 +88,7 @@ test('allPackageMetadata full request', function (t) { } }, 'cache contents based on what was written') server.done() - cleanup() - t.end() + cleanup(t.end) }) }) @@ -126,8 +125,7 @@ test('allPackageMetadata cache only', function (t) { t.ok(fileData, 'cache contents written to the right file') t.deepEquals(fileData, cacheContents, 'cacheContents written directly') server.done() - cleanup() - t.end() + cleanup(t.end) }) }) @@ -188,8 +186,7 @@ test('createEntryStream merged stream', function (t) { t.ok(fileData, 'cache contents written to the right file') t.deepEquals(fileData, cacheContents, 'cache updated correctly') server.done() - cleanup() - t.end() + cleanup(t.end) }) }) @@ -205,14 +202,11 @@ test('allPackageMetadata no sources', function (t) { t.ok(err, 'no sources, got an error') t.match(err.message, /No search sources available/, 'useful error message') server.done() - cleanup() - t.end() + cleanup(t.end) }) }) test('cleanup', function (t) { - cleanup() server.close() - t.pass('all done') - t.done() + cleanup(t.end) }) diff --git a/deps/npm/test/tap/audit.js b/deps/npm/test/tap/audit.js index 631eedf276e37e..ca3da87a3af62b 100644 --- a/deps/npm/test/tap/audit.js +++ b/deps/npm/test/tap/audit.js @@ -27,6 +27,66 @@ function tmock (t) { }) } +const quickAuditResult = { + actions: [], + advisories: { + '1316': { + findings: [ + { + version: '1.0.0', + paths: [ + 'baddep' + ] + } + ], + 'id': 1316, + 'created': '2019-11-14T15:29:41.991Z', + 'updated': '2019-11-14T19:35:30.677Z', + 'deleted': null, + 'title': 'Arbitrary Code Execution', + 'found_by': { + 'link': '', + 'name': 'François Lajeunesse-Robert', + 'email': '' + }, + 'reported_by': { + 'link': '', + 'name': 'François Lajeunesse-Robert', + 'email': '' + }, + 'module_name': 'baddep', + 'cves': [], + 'vulnerable_versions': '<4.5.2', + 'patched_versions': '>=4.5.2', + 'overview': 'a nice overview of the advisory', + 'recommendation': 'how you should fix it', + 'references': '', + 'access': 'public', + 'severity': 'high', + 'cwe': 'CWE-79', + 'metadata': { + 'module_type': '', + 'exploitability': 6, + 'affected_components': '' + }, + 'url': 'https://npmjs.com/advisories/1234542069' + } + }, + 'muted': [], + 'metadata': { + 'vulnerabilities': { + 'info': 0, + 'low': 0, + 'moderate': 0, + 'high': 1, + 'critical': 0 + }, + 'dependencies': 1, + 'devDependencies': 0, + 'totalDependencies': 1 + } +} + test('exits with zero exit code for vulnerabilities below the `audit-level` flag', t => { const fixture = new Tacks(new Dir({ 'package.json': new File({ @@ -40,7 +100,7 @@ test('exits with zero exit code for vulnerabilities below the `audit-level` flag fixture.create(testDir) return tmock(t).then(srv => { srv.filteringRequestBody(req => 'ok') - srv.post('/-/npm/v1/security/audits/quick', 'ok').reply(200, 'yeah') + srv.post('/-/npm/v1/security/audits/quick', 'ok').reply(200, quickAuditResult) srv.get('/baddep').twice().reply(200, { name: 'baddep', 'dist-tags': { @@ -75,6 +135,8 @@ test('exits with zero exit code for vulnerabilities below the `audit-level` flag '--registry', common.registry, '--cache', path.join(testDir, 'npm-cache') ], EXEC_OPTS).then(([code, stdout, stderr]) => { + const result = JSON.parse(stdout) + t.same(result.audit, quickAuditResult, 'printed quick audit result') srv.filteringRequestBody(req => 'ok') srv.post('/-/npm/v1/security/audits', 'ok').reply(200, { actions: [{ @@ -102,6 +164,62 @@ test('exits with zero exit code for vulnerabilities below the `audit-level` flag }) }) +test('shows quick audit results summary for human', t => { + const fixture = new Tacks(new Dir({ + 'package.json': new File({ + name: 'foo', + version: '1.0.0', + dependencies: { + baddep: '1.0.0' + } + }) + })) + fixture.create(testDir) + return tmock(t).then(srv => { + srv.filteringRequestBody(req => 'ok') + srv.post('/-/npm/v1/security/audits/quick', 'ok').reply(200, quickAuditResult) + srv.get('/baddep').twice().reply(200, { + name: 'baddep', + 'dist-tags': { + 'latest': '1.2.3' + }, + versions: { + '1.0.0': { + name: 'baddep', + version: '1.0.0', + _hasShrinkwrap: false, + dist: { + shasum: 'deadbeef', + tarball: common.registry + '/idk/-/idk-1.0.0.tgz' + } + }, + '1.2.3': { + name: 'baddep', + version: '1.2.3', + _hasShrinkwrap: false, + dist: { + shasum: 'deadbeef', + tarball: common.registry + '/idk/-/idk-1.2.3.tgz' + } + } + } + }) + return common.npm([ + 'install', + '--audit', + '--no-json', + '--package-lock-only', + '--registry', common.registry, + '--cache', path.join(testDir, 'npm-cache') + ], EXEC_OPTS).then(([code, stdout, stderr]) => { + t.match(stdout, new RegExp('added 1 package and audited 1 package in .*\\n' + + 'found 1 high severity vulnerability\\n' + + ' run `npm audit fix` to fix them, or `npm audit` for details\\n'), + 'shows quick audit result') + }) + }) +}) + test('exits with non-zero exit code for vulnerabilities at the `audit-level` flag', t => { const fixture = new Tacks(new Dir({ 'package.json': new File({ diff --git a/deps/npm/test/tap/bearer-token-check.js b/deps/npm/test/tap/bearer-token-check.js index 21c6b0beb2c2f0..86602b303c9f0d 100644 --- a/deps/npm/test/tap/bearer-token-check.js +++ b/deps/npm/test/tap/bearer-token-check.js @@ -4,9 +4,7 @@ var writeFileSync = require('graceful-fs').writeFileSync var fs = require('fs') var mkdirp = require('mkdirp') var http = require('http') -var osenv = require('osenv') -var rimraf = require('rimraf') -var test = require('tap').test +const t = require('tap') var common = require('../common-tap.js') var toNerfDart = require('../../lib/config/nerf-dart.js') @@ -38,14 +36,42 @@ server.on('request', (req, res) => { } }) -test('setup', function (t) { - server.listen(common.port, () => { - setup() - t.done() - }) +var contents = '@scoped:registry=' + common.registry + '\n' + + toNerfDart(common.registry) + ':_authToken=0xabad1dea\n' + +var json = { + name: 'test-package-install', + version: '1.0.0', + dependencies: { + '@scoped/underscore': '1.3.1' + } +} + +var shrinkwrap = { + name: 'test-package-install', + version: '1.0.0', + dependencies: { + '@scoped/underscore': { + resolved: tarballURL, + version: '1.3.1' + } + } +} + +t.teardown(() => server.close()) + +t.test('setup', function (t) { + mkdirp.sync(modules) + writeFileSync(resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') + writeFileSync(outfile, contents) + writeFileSync( + resolve(pkg, 'npm-shrinkwrap.json'), + JSON.stringify(shrinkwrap, null, 2) + '\n' + ) + server.listen(common.port, t.end) }) -test('authed npm install with tarball not on registry', function (t) { +t.test('authed npm install with tarball not on registry', function (t) { common.npm( [ 'install', @@ -81,48 +107,3 @@ test('authed npm install with tarball not on registry', function (t) { } ) }) - -test('cleanup', function (t) { - server.close(() => { - cleanup() - t.end() - }) -}) - -var contents = '@scoped:registry=' + common.registry + '\n' + - toNerfDart(common.registry) + ':_authToken=0xabad1dea\n' - -var json = { - name: 'test-package-install', - version: '1.0.0', - dependencies: { - '@scoped/underscore': '1.3.1' - } -} - -var shrinkwrap = { - name: 'test-package-install', - version: '1.0.0', - dependencies: { - '@scoped/underscore': { - resolved: tarballURL, - version: '1.3.1' - } - } -} - -function setup () { - cleanup() - mkdirp.sync(modules) - writeFileSync(resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') - writeFileSync(outfile, contents) - writeFileSync( - resolve(pkg, 'npm-shrinkwrap.json'), - JSON.stringify(shrinkwrap, null, 2) + '\n' - ) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/bitbucket-https-url-with-creds-package.js b/deps/npm/test/tap/bitbucket-https-url-with-creds-package.js index 4891b9886bd8b2..f0f14dcb344755 100644 --- a/deps/npm/test/tap/bitbucket-https-url-with-creds-package.js +++ b/deps/npm/test/tap/bitbucket-https-url-with-creds-package.js @@ -5,10 +5,7 @@ const BB = require('bluebird') var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -64,22 +61,10 @@ test('bitbucket-https-url-with-creds-package', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/bitbucket-https-url-with-creds.js b/deps/npm/test/tap/bitbucket-https-url-with-creds.js index 7f7e7eee4810a1..703d0d9a6ab60a 100644 --- a/deps/npm/test/tap/bitbucket-https-url-with-creds.js +++ b/deps/npm/test/tap/bitbucket-https-url-with-creds.js @@ -6,9 +6,7 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -61,13 +59,7 @@ test('bitbucket-https-url-with-creds', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -75,8 +67,3 @@ function setup () { ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/bitbucket-shortcut-package.js b/deps/npm/test/tap/bitbucket-shortcut-package.js index ef606f4aa3e0c0..a148c598c68705 100644 --- a/deps/npm/test/tap/bitbucket-shortcut-package.js +++ b/deps/npm/test/tap/bitbucket-shortcut-package.js @@ -6,9 +6,7 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -65,13 +63,7 @@ test('bitbucket-shortcut', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -79,8 +71,3 @@ function setup () { ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/bitbucket-shortcut.js b/deps/npm/test/tap/bitbucket-shortcut.js index fe1c4179755c40..6d750f869a306c 100644 --- a/deps/npm/test/tap/bitbucket-shortcut.js +++ b/deps/npm/test/tap/bitbucket-shortcut.js @@ -6,9 +6,7 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -62,13 +60,7 @@ test('bitbucket-shortcut', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -76,8 +68,3 @@ function setup () { ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/build-already-built.js b/deps/npm/test/tap/build-already-built.js index 1e7359a558fa32..3410432ab22448 100644 --- a/deps/npm/test/tap/build-already-built.js +++ b/deps/npm/test/tap/build-already-built.js @@ -2,8 +2,6 @@ // message "already built" should not be error var test = require('tap').test var path = require('path') -var osenv = require('osenv') -var rimraf = require('rimraf') var npmlog = require('npmlog') var mkdirp = require('mkdirp') var requireInject = require('require-inject') @@ -12,13 +10,7 @@ var npm = require('../../lib/npm.js') const common = require('../common-tap.js') var PKG_DIR = common.pkg -var fakePkg = 'foo' - -test('setup', function (t) { - cleanup() - - t.end() -}) +var fakePkg = path.resolve(PKG_DIR, 'foo') test("issue #6735 build 'already built' message", function (t) { npm.load({ loglevel: 'warn' }, function () { @@ -66,14 +58,3 @@ test("issue #6735 build 'already built' message", function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(PKG_DIR) -} diff --git a/deps/npm/test/tap/cache-eacces-error-message.js b/deps/npm/test/tap/cache-eacces-error-message.js index aa112eba439213..fe76875c3e0247 100644 --- a/deps/npm/test/tap/cache-eacces-error-message.js +++ b/deps/npm/test/tap/cache-eacces-error-message.js @@ -1,14 +1,11 @@ const npm = require('../../lib/npm.js') const t = require('tap') -if (process.platform === 'win32') { - t.plan(0, 'this is a unix-only thing') - process.exit(0) -} +const common = require('../common-tap.js') -const errorMessage = require('../../lib/utils/error-message.js') +common.skipIfWindows('this is a unix-only thing') -const common = require('../common-tap.js') +const errorMessage = require('../../lib/utils/error-message.js') t.plan(1) diff --git a/deps/npm/test/tap/check-cpu-reqs.js b/deps/npm/test/tap/check-cpu-reqs.js index 0a36492430badf..d70660b05887fc 100644 --- a/deps/npm/test/tap/check-cpu-reqs.js +++ b/deps/npm/test/tap/check-cpu-reqs.js @@ -2,9 +2,7 @@ var path = require('path') var fs = require('fs') var test = require('tap').test -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var common = require('../common-tap.js') var base = common.pkg @@ -41,18 +39,7 @@ test('force install bad cpu', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} - function setup () { - cleanup() mkdirp.sync(path.resolve(installFrom, 'node_modules')) fs.writeFileSync( path.join(installFrom, 'package.json'), diff --git a/deps/npm/test/tap/check-engine-reqs.js b/deps/npm/test/tap/check-engine-reqs.js index fa25e28dd60edf..eec07562885c91 100644 --- a/deps/npm/test/tap/check-engine-reqs.js +++ b/deps/npm/test/tap/check-engine-reqs.js @@ -2,9 +2,7 @@ var path = require('path') var fs = require('fs') var test = require('tap').test -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var common = require('../common-tap.js') var base = common.pkg @@ -54,18 +52,7 @@ test('warns on bad engine not strict', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} - function setup () { - cleanup() mkdirp.sync(path.resolve(installFrom, 'node_modules')) fs.writeFileSync( path.join(installFrom, 'package.json'), diff --git a/deps/npm/test/tap/check-install-self.js b/deps/npm/test/tap/check-install-self.js index e7591b55e09393..63901a12df6718 100644 --- a/deps/npm/test/tap/check-install-self.js +++ b/deps/npm/test/tap/check-install-self.js @@ -2,9 +2,7 @@ var path = require('path') var fs = require('fs') var test = require('tap').test -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var common = require('../common-tap.js') var base = common.pkg @@ -43,18 +41,7 @@ test('force install self', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} - function setup () { - cleanup() mkdirp.sync(path.resolve(installFrom, 'node_modules')) fs.writeFileSync( path.join(installFrom, 'package.json'), diff --git a/deps/npm/test/tap/check-os-reqs.js b/deps/npm/test/tap/check-os-reqs.js index 6c43fa61aa637f..66dcbd5328e06c 100644 --- a/deps/npm/test/tap/check-os-reqs.js +++ b/deps/npm/test/tap/check-os-reqs.js @@ -2,9 +2,7 @@ var path = require('path') var fs = require('fs') var test = require('tap').test -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var common = require('../common-tap.js') var base = common.pkg @@ -41,18 +39,7 @@ test('force install bad os', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} - function setup () { - cleanup() mkdirp.sync(path.resolve(installFrom, 'node_modules')) fs.writeFileSync( path.join(installFrom, 'package.json'), diff --git a/deps/npm/test/tap/circular-dep.js b/deps/npm/test/tap/circular-dep.js index 624ea3800a9062..f7e018d02346c7 100644 --- a/deps/npm/test/tap/circular-dep.js +++ b/deps/npm/test/tap/circular-dep.js @@ -4,8 +4,6 @@ var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -75,13 +73,11 @@ test('installing a package that depends on the current package', function (t) { }) test('cleanup', function (t) { - cleanup() server.close() t.end() }) function setup (cb) { - cleanup() mkdirp.sync(minimist) fs.writeFileSync( path.join(minimist, 'package.json'), @@ -95,8 +91,3 @@ function setup (cb) { cb() }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/config-meta.js b/deps/npm/test/tap/config-meta.js index 97918b8897f8f8..a98d5e6c4dabd2 100644 --- a/deps/npm/test/tap/config-meta.js +++ b/deps/npm/test/tap/config-meta.js @@ -11,7 +11,7 @@ var root = path.resolve(__dirname, '..', '..') var lib = path.resolve(root, 'lib') var bin = path.resolve(root, 'bin') var nm = path.resolve(root, 'node_modules') -var doc = path.resolve(root, 'doc/misc/npm-config.md') +var doc = path.resolve(root, 'docs/content/using-npm/config.md') var FILES = [] var CONFS = {} var DOC = {} @@ -85,12 +85,12 @@ test('get lines', function (t) { test('get docs', function (t) { var d = fs.readFileSync(doc, 'utf8').split(/\r|\n/) // walk down until the '## Config Settings' section - for (var i = 0; i < d.length && d[i] !== '## Config Settings'; i++); + for (var i = 0; i < d.length && d[i] !== '### Config Settings'; i++); i++ // now gather up all the ^###\s lines until the next ^##\s - for (; i < d.length && !d[i].match(/^## /); i++) { - if (d[i].match(/^### /)) { - DOC[ d[i].replace(/^### /, '').trim() ] = true + for (; i < d.length && !d[i].match(/^### /); i++) { + if (d[i].match(/^#### /)) { + DOC[ d[i].replace(/^#### /, '').trim() ] = true } } t.pass('read the docs') diff --git a/deps/npm/test/tap/config-new-cafile.js b/deps/npm/test/tap/config-new-cafile.js index bd5792f3e3ff7d..e4cc65ec747a6e 100644 --- a/deps/npm/test/tap/config-new-cafile.js +++ b/deps/npm/test/tap/config-new-cafile.js @@ -3,22 +3,17 @@ const common = require('../common-tap.js') var path = require('path') var fs = require('graceful-fs') var test = require('tap').test -var mkdirp = require('mkdirp') var rimraf = require('rimraf') -var osenv = require('osenv') var npmconf = require('../../lib/config/core.js') var dir = common.pkg var beep = path.resolve(dir, 'beep.pem') var npmrc = path.resolve(dir, 'npmrc') -test('setup', function (t) { - bootstrap() - t.end() -}) - test('can set new cafile when old is gone', function (t) { t.plan(5) + fs.writeFileSync(npmrc, '') + fs.writeFileSync(beep, '') npmconf.load({ userconfig: npmrc }, function (error, conf) { npmconf.loaded = false t.ifError(error) @@ -40,19 +35,3 @@ test('can set new cafile when old is gone', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function bootstrap () { - mkdirp.sync(dir) - fs.writeFileSync(npmrc, '') - fs.writeFileSync(beep, '') -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(dir) -} diff --git a/deps/npm/test/tap/correct-mkdir.js b/deps/npm/test/tap/correct-mkdir.js index 30907d725ca08a..175fb34a003bca 100644 --- a/deps/npm/test/tap/correct-mkdir.js +++ b/deps/npm/test/tap/correct-mkdir.js @@ -5,11 +5,7 @@ var assert = require('assert') var requireInject = require('require-inject') const common = require('../common-tap.js') var cache_dir = common.pkg - -if (process.platform === 'win32') { - t.plan(0, 'windows does not use correct-mkdir behavior') - process.exit(0) -} +common.skipIfWindows('windows does not use correct-mkdir behavior') test('correct-mkdir: no race conditions', function (t) { var mock_fs = {} diff --git a/deps/npm/test/tap/do-not-remove-other-bins.js b/deps/npm/test/tap/do-not-remove-other-bins.js index 4e6b0d27b2f537..a614043221f0df 100644 --- a/deps/npm/test/tap/do-not-remove-other-bins.js +++ b/deps/npm/test/tap/do-not-remove-other-bins.js @@ -3,8 +3,6 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -41,7 +39,6 @@ var EXEC_OPTS = { } test('setup', function (t) { - cleanup() mkdirp.sync(path.join(installPath, 'node_modules')) mkdirp.sync(packageApath) fs.writeFileSync( @@ -118,14 +115,3 @@ test('verify postremoval bins', function (t) { t.is(bin, path.join(installPath, 'node_modules', 'b')) t.end() }) - -test('cleanup', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} diff --git a/deps/npm/test/tap/fund.js b/deps/npm/test/tap/fund.js new file mode 100644 index 00000000000000..364dc1b6f81795 --- /dev/null +++ b/deps/npm/test/tap/fund.js @@ -0,0 +1,296 @@ +'use strict' + +const fs = require('fs') +const path = require('path') + +const test = require('tap').test +const Tacks = require('tacks') +const Dir = Tacks.Dir +const File = Tacks.File +const common = require('../common-tap.js') +const isWindows = require('../../lib/utils/is-windows.js') + +const base = common.pkg +const noFunding = path.join(base, 'no-funding-package') +const maintainerOwnsAllDeps = path.join(base, 'maintainer-owns-all-deps') +const nestedNoFundingPackages = path.join(base, 'nested-no-funding-packages') + +function getFixturePackage ({ name, version, dependencies, funding }, extras) { + const getDeps = () => Object + .keys(dependencies) + .reduce((res, dep) => (Object.assign({}, res, { + [dep]: '*' + })), {}) + + return Dir(Object.assign({ + 'package.json': File({ + name, + version: version || '1.0.0', + funding: (funding === undefined) ? { + type: 'individual', + url: 'http://example.com/donate' + } : funding, + dependencies: dependencies && getDeps(dependencies) + }) + }, extras)) +} + +const fixture = new Tacks(Dir({ + 'no-funding-package': Dir({ + 'package.json': File({ + name: 'no-funding-package', + version: '0.0.0' + }) + }), + 'maintainer-owns-all-deps': getFixturePackage({ + name: 'maintainer-owns-all-deps', + dependencies: { + 'dep-foo': '*', + 'dep-bar': '*' + } + }, { + node_modules: Dir({ + 'dep-foo': getFixturePackage({ + name: 'dep-foo', + dependencies: { + 'dep-sub-foo': '*' + } + }, { + node_modules: Dir({ + 'dep-sub-foo': getFixturePackage({ + name: 'dep-sub-foo' + }) + }) + }), + 'dep-bar': getFixturePackage({ + name: 'dep-bar' + }) + }) + }), + 'nested-no-funding-packages': getFixturePackage({ + name: 'nested-no-funding-packages', + funding: null, + dependencies: { + foo: '*' + }, + devDependencies: { + lorem: '*' + } + }, { + node_modules: Dir({ + foo: getFixturePackage({ + name: 'foo', + dependencies: { + bar: '*' + }, + funding: null + }, { + node_modules: Dir({ + bar: getFixturePackage({ + name: 'bar' + }, { + node_modules: Dir({ + 'sub-bar': getFixturePackage({ + name: 'sub-bar', + funding: 'https://example.com/sponsor' + }) + }) + }) + }) + }), + lorem: getFixturePackage({ + name: 'lorem', + funding: { + url: 'https://example.com/lorem' + } + }) + }) + }) +})) + +function checkOutput (t, { code, stdout, stderr }) { + t.is(code, 0, `exited code 0`) + t.is(stderr, '', 'no warnings') +} + +function jsonTest (t, { assertionMsg, expected, stdout }) { + let parsed = JSON.parse(stdout) + t.deepEqual(parsed, expected, assertionMsg) +} + +function snapshotTest (t, { stdout, assertionMsg }) { + t.matchSnapshot(stdout, assertionMsg) +} + +function testFundCmd ({ title, assertionMsg, args = [], opts = {}, output = checkOutput, assertion = snapshotTest, expected }) { + const validate = (t) => (err, code, stdout, stderr) => { + if (err) throw err + + output(t, { code, stdout, stderr }) + assertion(t, { assertionMsg, expected, stdout }) + } + + return test(title, (t) => { + t.plan(3) + common.npm(['fund', '--unicode=false'].concat(args), opts, validate(t)) + }) +} + +test('setup', function (t) { + fixture.remove(base) + fixture.create(base) + t.end() +}) + +testFundCmd({ + title: 'fund with no package containing funding', + assertionMsg: 'should print empty funding info', + opts: { cwd: noFunding } +}) + +testFundCmd({ + title: 'fund in which same maintainer owns all its deps', + assertionMsg: 'should print stack packages together', + opts: { cwd: maintainerOwnsAllDeps } +}) + +testFundCmd({ + title: 'fund in which same maintainer owns all its deps, using --json option', + assertionMsg: 'should print stack packages together', + args: ['--json'], + opts: { cwd: maintainerOwnsAllDeps }, + assertion: jsonTest, + expected: { + length: 3, + name: 'maintainer-owns-all-deps', + version: '1.0.0', + funding: { type: 'individual', url: 'http://example.com/donate' }, + dependencies: { + 'dep-bar': { + version: '1.0.0', + funding: { type: 'individual', url: 'http://example.com/donate' } + }, + 'dep-foo': { + version: '1.0.0', + funding: { type: 'individual', url: 'http://example.com/donate' }, + dependencies: { + 'dep-sub-foo': { + version: '1.0.0', + funding: { type: 'individual', url: 'http://example.com/donate' } + } + } + } + } + } +}) + +testFundCmd({ + title: 'fund containing multi-level nested deps with no funding', + assertionMsg: 'should omit dependencies with no funding declared', + opts: { cwd: nestedNoFundingPackages } +}) + +testFundCmd({ + title: 'fund containing multi-level nested deps with no funding, using --json option', + assertionMsg: 'should omit dependencies with no funding declared', + args: ['--json'], + opts: { cwd: nestedNoFundingPackages }, + assertion: jsonTest, + expected: { + length: 3, + name: 'nested-no-funding-packages', + version: '1.0.0', + dependencies: { + lorem: { version: '1.0.0', funding: { url: 'https://example.com/lorem' } }, + bar: { + version: '1.0.0', + funding: { type: 'individual', url: 'http://example.com/donate' }, + dependencies: { + 'sub-bar': { + version: '1.0.0', + funding: { url: 'https://example.com/sponsor' } + } + } + } + } + } +}) + +testFundCmd({ + title: 'fund does not support global', + assertionMsg: 'should throw EFUNDGLOBAL error', + args: ['--global'], + output: (t, { code, stdout, stderr }) => { + t.is(code, 1, `exited code 0`) + const [ errCode, errCmd ] = stderr.split('\n') + t.matchSnapshot(`${errCode}\n${errCmd}`, 'should write error msgs to stderr') + } +}) + +testFundCmd({ + title: 'fund does not support global, using --json option', + assertionMsg: 'should throw EFUNDGLOBAL error', + args: ['--global', '--json'], + output: (t, { code, stdout, stderr }) => { + t.is(code, 1, `exited code 0`) + const [ errCode, errCmd ] = stderr.split('\n') + t.matchSnapshot(`${errCode}\n${errCmd}`, 'should write error msgs to stderr') + }, + assertion: jsonTest, + expected: { + error: { + code: 'EFUNDGLOBAL', + summary: '`npm fund` does not support globals', + detail: '' + } + } +}) + +testFundCmd({ + title: 'fund using package argument with no browser', + assertionMsg: 'should open funding url', + args: ['.', '--no-browser'], + opts: { cwd: maintainerOwnsAllDeps } +}) + +testFundCmd({ + title: 'fund using package argument with no browser, using --json option', + assertionMsg: 'should open funding url', + args: ['.', '--json', '--no-browser'], + opts: { cwd: maintainerOwnsAllDeps }, + assertion: jsonTest, + expected: { + title: 'individual funding available at the following URL', + url: 'http://example.com/donate' + } +}) + +if (!isWindows) { + test('fund using package argument', function (t) { + const fakeBrowser = path.join(common.pkg, '_script.sh') + const outFile = path.join(common.pkg, '_output') + + const s = '#!/usr/bin/env bash\n' + + 'echo "$@" > ' + JSON.stringify(common.pkg) + '/_output\n' + fs.writeFileSync(fakeBrowser, s) + fs.chmodSync(fakeBrowser, '0755') + + common.npm([ + 'fund', '.', + '--loglevel=silent', + '--browser=' + fakeBrowser + ], { cwd: maintainerOwnsAllDeps }, function (err, code, stdout, stderr) { + t.ifError(err, 'repo command ran without error') + t.equal(code, 0, 'exit ok') + var res = fs.readFileSync(outFile, 'utf8') + t.equal(res, 'http://example.com/donate\n') + t.end() + }) + }) +} + +test('cleanup', function (t) { + t.pass(base) + fixture.remove(base) + t.end() +}) diff --git a/deps/npm/test/tap/gist-short-shortcut-package.js b/deps/npm/test/tap/gist-short-shortcut-package.js index e5e67f21a05dc6..601d53a8276661 100644 --- a/deps/npm/test/tap/gist-short-shortcut-package.js +++ b/deps/npm/test/tap/gist-short-shortcut-package.js @@ -3,9 +3,7 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -63,13 +61,7 @@ test('gist-short-shortcut-package', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -77,8 +69,3 @@ function setup () { ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/gist-short-shortcut.js b/deps/npm/test/tap/gist-short-shortcut.js index 2fcf63d53ede1d..82c9ae17502dd8 100644 --- a/deps/npm/test/tap/gist-short-shortcut.js +++ b/deps/npm/test/tap/gist-short-shortcut.js @@ -3,9 +3,7 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -60,13 +58,7 @@ test('gist-shortcut', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -74,8 +66,3 @@ function setup () { ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/gist-shortcut-package.js b/deps/npm/test/tap/gist-shortcut-package.js index 06b4383583aad0..28e57357cc3937 100644 --- a/deps/npm/test/tap/gist-shortcut-package.js +++ b/deps/npm/test/tap/gist-shortcut-package.js @@ -2,10 +2,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -20,12 +17,8 @@ var json = { } } -test('setup', function (t) { - setup() - t.end() -}) - test('gist-shortcut-package', function (t) { + setup() var cloneUrls = [ ['git://gist.github.com/deadbeef.git', 'GitHub gist shortcuts try git URLs first'], ['https://gist.github.com/deadbeef.git', 'GitHub gist shortcuts try HTTPS URLs second'], @@ -63,22 +56,10 @@ test('gist-shortcut-package', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup () { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) process.chdir(pkg) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/gist-shortcut.js b/deps/npm/test/tap/gist-shortcut.js index e5f200f5fdeb1c..ca86d6bc55058a 100644 --- a/deps/npm/test/tap/gist-shortcut.js +++ b/deps/npm/test/tap/gist-shortcut.js @@ -2,10 +2,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -17,12 +14,12 @@ var json = { version: '0.0.0' } -test('setup', function (t) { - setup() - t.end() -}) - test('gist-shortcut', function (t) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) var cloneUrls = [ ['git://gist.github.com/deadbeef.git', 'GitHub gist shortcuts try git URLs first'], ['https://gist.github.com/deadbeef.git', 'GitHub gist shortcuts try HTTPS URLs second'], @@ -59,23 +56,3 @@ test('gist-shortcut', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/git-dependency-install-link.js b/deps/npm/test/tap/git-dependency-install-link.js index 44438e7f958253..d80beab057f4da 100644 --- a/deps/npm/test/tap/git-dependency-install-link.js +++ b/deps/npm/test/tap/git-dependency-install-link.js @@ -1,7 +1,6 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') var rimraf = require('rimraf') var test = require('tap').test @@ -11,9 +10,9 @@ var mr = require('npm-registry-mock') var npm = require('../../lib/npm.js') var common = require('../common-tap.js') -var pkg = common.pkg -var repo = pkg + '-repo' -var prefix = pkg + '-prefix' +var pkg = resolve(common.pkg, 'package') +var repo = resolve(common.pkg, 'repo') +var prefix = resolve(common.pkg, 'prefix') var cache = common.cache var daemon @@ -42,8 +41,8 @@ var pjChild = JSON.stringify({ }, null, 2) + '\n' test('setup', function (t) { - bootstrap() - setup(function (er, r) { + t.test('bootstrap', t => bootstrap(t.end)) + t.test('setup', t => setup(function (er, r) { t.ifError(er, 'git started up successfully') if (!er) { @@ -59,7 +58,8 @@ test('setup', function (t) { t.end() }) - }) + })) + t.end() }) test('install from git repo [no --link]', function (t) { @@ -103,20 +103,20 @@ test('install from git repo [with --link]', function (t) { test('clean', function (t) { mockRegistry.close() - daemon.on('close', function () { - cleanup() - t.end() - }) + daemon.on('close', t.end) process.kill(daemonPID) }) -function bootstrap () { - rimraf.sync(repo) - rimraf.sync(pkg) - mkdirp.sync(pkg) - mkdirp.sync(cache) +function bootstrap (cb) { + rimraf(repo, () => { + rimraf(pkg, () => { + mkdirp.sync(pkg) + mkdirp.sync(cache) - fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) + fs.writeFileSync(resolve(pkg, 'package.json'), pjParent) + cb() + }) + }) } function setup (cb) { @@ -170,10 +170,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(repo) - rimraf.sync(prefix) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/git-prepare.js b/deps/npm/test/tap/git-prepare.js index 37534fbfc430fc..072f4dfc447fc9 100644 --- a/deps/npm/test/tap/git-prepare.js +++ b/deps/npm/test/tap/git-prepare.js @@ -3,8 +3,6 @@ const fs = require('fs') const path = require('path') -const osenv = require('osenv') -const rimraf = require('rimraf') const test = require('tap').test const mr = require('npm-registry-mock') @@ -68,7 +66,7 @@ const fixture = new Tacks(Dir({ })) test('setup', function (t) { - bootstrap() + fixture.create(testdir) setup(function (er, r) { t.ifError(er, 'git started up successfully') @@ -115,17 +113,10 @@ test('install from git repo with prepare script', function (t) { test('clean', function (t) { mockRegistry.close() - daemon.on('close', function () { - cleanup() - t.end() - }) + daemon.on('close', t.end) process.kill(daemonPID) }) -function bootstrap () { - fixture.create(testdir) -} - function setup (cb) { npm.load({ prefix: testdir, @@ -173,8 +164,3 @@ function setup (cb) { }, cb) }) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(testdir) -} diff --git a/deps/npm/test/tap/github-shortcut-package.js b/deps/npm/test/tap/github-shortcut-package.js index db153ba352e55e..444520308a2452 100644 --- a/deps/npm/test/tap/github-shortcut-package.js +++ b/deps/npm/test/tap/github-shortcut-package.js @@ -2,10 +2,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -20,12 +17,12 @@ var json = { } } -test('setup', function (t) { - setup() - t.end() -}) - test('github-shortcut-package', function (t) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) var cloneUrls = [ ['git://github.com/foo/private.git', 'GitHub shortcuts try git URLs first'], ['https://github.com/foo/private.git', 'GitHub shortcuts try HTTPS URLs second'], @@ -62,23 +59,3 @@ test('github-shortcut-package', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/github-shortcut.js b/deps/npm/test/tap/github-shortcut.js index 0c89d428fa1af6..59c7e39ea948ff 100644 --- a/deps/npm/test/tap/github-shortcut.js +++ b/deps/npm/test/tap/github-shortcut.js @@ -5,10 +5,7 @@ const BB = require('bluebird') const fs = require('graceful-fs') const path = require('path') -const mkdirp = require('mkdirp') -const osenv = require('osenv') const requireInject = require('require-inject') -const rimraf = require('rimraf') const test = require('tap').test const common = require('../common-tap.js') @@ -20,12 +17,12 @@ const json = { version: '0.0.0' } -test('setup', function (t) { - setup() - t.end() -}) - test('github-shortcut', function (t) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) const cloneUrls = [ ['git://github.com/foo/private.git', 'GitHub shortcuts try git URLs first'], ['https://github.com/foo/private.git', 'GitHub shortcuts try HTTPS URLs second'], @@ -62,23 +59,3 @@ test('github-shortcut', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/gitlab-shortcut-package.js b/deps/npm/test/tap/gitlab-shortcut-package.js index 4f5b43851d88bd..9b431ff7b66f09 100644 --- a/deps/npm/test/tap/gitlab-shortcut-package.js +++ b/deps/npm/test/tap/gitlab-shortcut-package.js @@ -2,10 +2,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -20,12 +17,12 @@ var json = { } } -test('setup', function (t) { - setup() - t.end() -}) - test('gitlab-shortcut-package', function (t) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) var cloneUrls = [ ['https://gitlab.com/foo/private.git', 'GitLab shortcuts try HTTPS URLs second'], ['ssh://git@gitlab.com/foo/private.git', 'GitLab shortcuts try SSH first'] @@ -61,23 +58,3 @@ test('gitlab-shortcut-package', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/gitlab-shortcut.js b/deps/npm/test/tap/gitlab-shortcut.js index e6bd54765a089c..344311b45f26c2 100644 --- a/deps/npm/test/tap/gitlab-shortcut.js +++ b/deps/npm/test/tap/gitlab-shortcut.js @@ -2,10 +2,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') var requireInject = require('require-inject') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -17,12 +14,12 @@ var json = { version: '0.0.0' } -test('setup', function (t) { - setup() - t.end() -}) - test('gitlab-shortcut', function (t) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) var cloneUrls = [ ['https://gitlab.com/foo/private.git', 'GitLab shortcuts try HTTPS URLs second'], ['ssh://git@gitlab.com/foo/private.git', 'GitLab shortcuts try SSH first'] @@ -58,23 +55,3 @@ test('gitlab-shortcut', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/graceful-restart.js b/deps/npm/test/tap/graceful-restart.js index 740561bd79efa4..787aa988949b64 100644 --- a/deps/npm/test/tap/graceful-restart.js +++ b/deps/npm/test/tap/graceful-restart.js @@ -1,13 +1,7 @@ var fs = require('fs') var resolve = require('path').resolve - -var osenv = require('osenv') -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test - var common = require('../common-tap.js') - var pkg = common.pkg var outGraceless = [ @@ -60,11 +54,6 @@ var pjGraceful = JSON.stringify({ } }, null, 2) + '\n' -test('setup', function (t) { - bootstrap() - t.end() -}) - test('graceless restart', function (t) { fs.writeFileSync(resolve(pkg, 'package.json'), pjGraceless) createChild(['run-script', 'restart'], function (err, code, out) { @@ -85,20 +74,6 @@ test('graceful restart', function (t) { }) }) -test('clean', function (t) { - cleanup() - t.end() -}) - -function bootstrap () { - mkdirp.sync(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - function createChild (args, cb) { var env = { HOME: process.env.HOME, diff --git a/deps/npm/test/tap/ignore-install-link.js b/deps/npm/test/tap/ignore-install-link.js index a2caa23dfdb561..038b9448d78179 100644 --- a/deps/npm/test/tap/ignore-install-link.js +++ b/deps/npm/test/tap/ignore-install-link.js @@ -1,8 +1,5 @@ -if (process.platform === 'win32') { - require('tap').plan(0, 'symlinks are weird on windows, skip this test') - process.exit(0) -} var common = require('../common-tap.js') +common.skipIfWindows('symlinks are weird on windows') var test = require('tap').test var path = require('path') var fs = require('fs') diff --git a/deps/npm/test/tap/init-interrupt.js b/deps/npm/test/tap/init-interrupt.js index 114bb2bacba274..38c38053e590db 100644 --- a/deps/npm/test/tap/init-interrupt.js +++ b/deps/npm/test/tap/init-interrupt.js @@ -2,21 +2,12 @@ // if 'npm init' is interrupted with ^C, don't report // 'init written successfully' var test = require('tap').test -var osenv = require('osenv') -var rimraf = require('rimraf') var npmlog = require('npmlog') var requireInject = require('require-inject') var npm = require('../../lib/npm.js') -const common = require('../common-tap.js') -var PKG_DIR = common.pkg - -test('setup', function (t) { - cleanup() - - t.end() -}) +require('../common-tap.js') test('issue #6684 remove confusing message', function (t) { var initJsonMock = function (dir, input, config, cb) { @@ -45,14 +36,3 @@ test('issue #6684 remove confusing message', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(PKG_DIR) -} diff --git a/deps/npm/test/tap/install-at-locally.js b/deps/npm/test/tap/install-at-locally.js index 705c2df1196424..e4920d22d14aa9 100644 --- a/deps/npm/test/tap/install-at-locally.js +++ b/deps/npm/test/tap/install-at-locally.js @@ -2,7 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test @@ -17,11 +16,6 @@ var json = { version: '0.0.0' } -test('setup', function (t) { - cleanup() - t.end() -}) - test('\'npm install ./package@1.2.3\' should install local pkg', function (t) { var target = './package@1.2.3' setup(target) @@ -46,18 +40,8 @@ test('\'npm install install/at/locally@./package@1.2.3\' should install local pk }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - function setup (target) { - cleanup() + rimraf.sync(pkg) var root = path.resolve(pkg, target) mkdirp.sync(root) fs.writeFileSync( @@ -65,5 +49,4 @@ function setup (target) { JSON.stringify(json, null, 2) ) mkdirp.sync(path.resolve(pkg, 'node_modules')) - process.chdir(pkg) } diff --git a/deps/npm/test/tap/install-at-sub-path-locally.js b/deps/npm/test/tap/install-at-sub-path-locally.js index 08b64746af6786..931d29bbd26422 100644 --- a/deps/npm/test/tap/install-at-sub-path-locally.js +++ b/deps/npm/test/tap/install-at-sub-path-locally.js @@ -2,13 +2,11 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var pkg = common.pkg +var pkg = path.resolve(common.pkg, 'package') var EXEC_OPTS = { cwd: pkg, stdio: [0, 1, 2] } @@ -20,12 +18,17 @@ var json = { var target = '../package@1.2.3' test('setup', function (t) { - cleanup() + var root = path.resolve(pkg, target) + mkdirp.sync(root) + fs.writeFileSync( + path.join(root, 'package.json'), + JSON.stringify(json, null, 2) + ) + mkdirp.sync(path.resolve(pkg, 'node_modules')) t.end() }) test('\'npm install ../package@1.2.3\' should install local pkg from sub path', function (t) { - setup() common.npm(['install', '--loglevel=silent', target], EXEC_OPTS, function (err, code) { if (err) throw err var p = path.resolve(pkg, 'node_modules/install-at-sub-path-locally-mock/package.json') @@ -44,26 +47,3 @@ test('\'running npm install ../package@1.2.3\' should not break on sub path re-i t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - rimraf.sync(path.resolve(pkg, target)) -} - -function setup () { - cleanup() - var root = path.resolve(pkg, target) - mkdirp.sync(root) - fs.writeFileSync( - path.join(root, 'package.json'), - JSON.stringify(json, null, 2) - ) - mkdirp.sync(path.resolve(pkg, 'node_modules')) - process.chdir(pkg) -} diff --git a/deps/npm/test/tap/install-bad-dep-format.js b/deps/npm/test/tap/install-bad-dep-format.js index d01996f1552127..9d9a41383598df 100644 --- a/deps/npm/test/tap/install-bad-dep-format.js +++ b/deps/npm/test/tap/install-bad-dep-format.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -18,8 +16,13 @@ var json = { } test('invalid url format returns appropriate error', function (t) { - setup(json) - common.npm(['install'], {}, function (err, code, stdout, stderr) { + var pkgPath = path.resolve(common.pkg, json.name) + mkdirp.sync(pkgPath) + fs.writeFileSync( + path.join(pkgPath, 'package.json'), + JSON.stringify(json, null, 2) + ) + common.npm(['install'], {cwd: pkgPath}, function (err, code, stdout, stderr) { t.ifError(err, 'install ran without error') t.equals(code, 1, 'install exited with code 1') t.match(stderr, @@ -28,31 +31,3 @@ test('invalid url format returns appropriate error', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup (json) { - cleanup() - process.chdir(mkPkg(json)) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - var pkgs = [json] - pkgs.forEach(function (json) { - rimraf.sync(path.resolve(common.pkg, json.name)) - }) -} - -function mkPkg (json) { - var pkgPath = path.resolve(common.pkg, json.name) - mkdirp.sync(pkgPath) - fs.writeFileSync( - path.join(pkgPath, 'package.json'), - JSON.stringify(json, null, 2) - ) - return pkgPath -} diff --git a/deps/npm/test/tap/install-bad-man.js b/deps/npm/test/tap/install-bad-man.js index 98c8e9a7e04538..0aa83a21c541a7 100644 --- a/deps/npm/test/tap/install-bad-man.js +++ b/deps/npm/test/tap/install-bad-man.js @@ -1,15 +1,13 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var pkg = common.pkg -var target = pkg + '-target' +var pkg = resolve(common.pkg, 'package') +var target = resolve(common.pkg, 'target') var EXEC_OPTS = { cwd: target @@ -21,11 +19,17 @@ var json = { man: [ './install-bad-man.1.lol' ] } -common.pendIfWindows('man pages do not get installed on Windows') +common.skipIfWindows('man pages do not get installed on Windows') test('setup', function (t) { - setup() - t.pass('setup ran') + mkdirp.sync(pkg) + // make sure it installs locally + mkdirp.sync(resolve(target, 'node_modules')) + fs.writeFileSync( + resolve(pkg, 'package.json'), + JSON.stringify(json, null, 2) + '\n' + ) + fs.writeFileSync(resolve(pkg, 'install-bad-man.1.lol'), 'lol\n') t.end() }) @@ -55,27 +59,3 @@ test("install from repo on 'OS X'", function (t) { } ) }) - -test('clean', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - // make sure it installs locally - mkdirp.sync(resolve(target, 'node_modules')) - fs.writeFileSync( - resolve(pkg, 'package.json'), - JSON.stringify(json, null, 2) + '\n' - ) - fs.writeFileSync(resolve(pkg, 'install-bad-man.1.lol'), 'lol\n') -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - rimraf.sync(target) -} diff --git a/deps/npm/test/tap/install-bin-null.js b/deps/npm/test/tap/install-bin-null.js index 7a87a2e0bbc270..2ad75eb59940aa 100644 --- a/deps/npm/test/tap/install-bin-null.js +++ b/deps/npm/test/tap/install-bin-null.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -43,49 +41,33 @@ var grandchildPkg = { var pkgs = [childPkgA, childPkgB, grandchildPkg] -test('the grandchild has bin:null', function (t) { - setup() - common.npm(['install'], EXEC_OPTS, function (err, code, stdout, stderr) { - t.ifErr(err, 'npm link finished without error') - t.equal(code, 0, 'exited ok') - t.ok(stdout, 'output indicating success') - t.notOk(stderr, 'no output stderr') - t.end() - }) -}) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() +test('setup', t => { mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(parentPkg, null, 2) ) pkgs.forEach(function (json) { - process.chdir(mkPkg(json)) + var pkgPath = path.resolve(pkg, json.name) + mkdirp.sync(pkgPath) + fs.writeFileSync( + path.join(pkgPath, 'package.json'), + JSON.stringify(json, null, 2) + ) }) fs.writeFileSync( path.join(pkg, childPkgA.name, 'index.js'), '' ) -} + t.end() +}) -function mkPkg (json) { - var pkgPath = path.resolve(pkg, json.name) - mkdirp.sync(pkgPath) - fs.writeFileSync( - path.join(pkgPath, 'package.json'), - JSON.stringify(json, null, 2) - ) - return pkgPath -} +test('the grandchild has bin:null', function (t) { + common.npm(['install'], EXEC_OPTS, function (err, code, stdout, stderr) { + t.ifErr(err, 'npm link finished without error') + t.equal(code, 0, 'exited ok') + t.ok(stdout, 'output indicating success') + t.notOk(stderr, 'no output stderr') + t.end() + }) +}) diff --git a/deps/npm/test/tap/install-cli-only-development.js b/deps/npm/test/tap/install-cli-only-development.js index a68c0f8aac0a25..6f03931d80e9cd 100644 --- a/deps/npm/test/tap/install-cli-only-development.js +++ b/deps/npm/test/tap/install-cli-only-development.js @@ -3,9 +3,8 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') -var test = require('tap').test +const t = require('tap') var common = require('../common-tap.js') @@ -37,13 +36,29 @@ var devDependency = { version: '0.0.0' } -test('setup', function (t) { - setup() - t.pass('setup ran') +t.test('setup', t => { + mkdirp.sync(path.join(pkg, 'dependency')) + fs.writeFileSync( + path.join(pkg, 'dependency', 'package.json'), + JSON.stringify(dependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'dev-dependency')) + fs.writeFileSync( + path.join(pkg, 'dev-dependency', 'package.json'), + JSON.stringify(devDependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + t.end() }) -test('\'npm install --only=development\' should only install devDependencies', function (t) { +t.test('\'npm install --only=development\' should only install devDependencies', function (t) { common.npm(['install', '--only=development'], EXEC_OPTS, function (err, code) { t.ifError(err, 'install development successful') t.equal(code, 0, 'npm install did not raise error code') @@ -57,14 +72,11 @@ test('\'npm install --only=development\' should only install devDependencies', f existsSync(path.resolve(pkg, 'node_modules/dependency/package.json')), 'dependency was NOT installed' ) - t.end() + rimraf(path.join(pkg, 'node_modules'), t.end) }) }) -test('\'npm install --only=development\' should only install devDependencies regardless of npm.config.get(\'production\')', function (t) { - cleanup() - setup() - +t.test('\'npm install --only=development\' should only install devDependencies regardless of npm.config.get(\'production\')', function (t) { common.npm(['install', '--only=development', '--production'], EXEC_OPTS, function (err, code) { t.ifError(err, 'install development successful') t.equal(code, 0, 'npm install did not raise error code') @@ -78,38 +90,6 @@ test('\'npm install --only=development\' should only install devDependencies reg existsSync(path.resolve(pkg, 'node_modules/dependency/package.json')), 'dependency was NOT installed' ) - t.end() + rimraf(path.join(pkg, 'node_modules'), t.end) }) }) - -test('cleanup', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - mkdirp.sync(path.join(pkg, 'dependency')) - fs.writeFileSync( - path.join(pkg, 'dependency', 'package.json'), - JSON.stringify(dependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'dev-dependency')) - fs.writeFileSync( - path.join(pkg, 'dev-dependency', 'package.json'), - JSON.stringify(devDependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-cli-only-production.js b/deps/npm/test/tap/install-cli-only-production.js index e43692d3d7c9cf..63863ff934d93a 100644 --- a/deps/npm/test/tap/install-cli-only-production.js +++ b/deps/npm/test/tap/install-cli-only-production.js @@ -3,8 +3,6 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -59,7 +57,6 @@ test('setup', function (t) { JSON.stringify(json, null, 2) ) - process.chdir(pkg) t.end() }) @@ -82,9 +79,3 @@ test('\'npm install --only=production\' should only install dependencies', funct t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) diff --git a/deps/npm/test/tap/install-cli-only-shrinkwrap.js b/deps/npm/test/tap/install-cli-only-shrinkwrap.js index e3a4685d9c459d..004593d782c227 100644 --- a/deps/npm/test/tap/install-cli-only-shrinkwrap.js +++ b/deps/npm/test/tap/install-cli-only-shrinkwrap.js @@ -3,7 +3,6 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test @@ -55,9 +54,27 @@ var devDependency = { } test('setup', function (t) { - cleanup() - setup() - t.pass('setup ran') + mkdirp.sync(path.join(pkg, 'dependency')) + fs.writeFileSync( + path.join(pkg, 'dependency', 'package.json'), + JSON.stringify(dependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'dev-dependency')) + fs.writeFileSync( + path.join(pkg, 'dev-dependency', 'package.json'), + JSON.stringify(devDependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + fs.writeFileSync( + path.join(pkg, 'npm-shrinkwrap.json'), + JSON.stringify(shrinkwrap, null, 2) + ) t.end() }) @@ -77,13 +94,11 @@ test('\'npm install --only=development\' should only install devDependencies', f existsSync(path.resolve(pkg, 'node_modules/dependency/package.json')), 'dependency was NOT installed' ) - t.end() + rimraf(path.join(pkg, 'node_modules'), t.end) }) }) test('\'npm install --only=production\' should only install dependencies', function (t) { - cleanup() - setup() common.npm(['install', '--only=production'], EXEC_OPTS, function (err, code, stdout, stderr) { if (err) throw err t.comment(stdout.trim()) @@ -99,42 +114,6 @@ test('\'npm install --only=production\' should only install dependencies', funct existsSync(path.resolve(pkg, 'node_modules/dev-dependency/package.json')), 'devDependency was NOT installed' ) - t.end() + rimraf(path.join(pkg, 'node_modules'), t.end) }) }) - -test('cleanup', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - mkdirp.sync(path.join(pkg, 'dependency')) - fs.writeFileSync( - path.join(pkg, 'dependency', 'package.json'), - JSON.stringify(dependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'dev-dependency')) - fs.writeFileSync( - path.join(pkg, 'dev-dependency', 'package.json'), - JSON.stringify(devDependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - fs.writeFileSync( - path.join(pkg, 'npm-shrinkwrap.json'), - JSON.stringify(shrinkwrap, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-cli-production-nosave.js b/deps/npm/test/tap/install-cli-production-nosave.js index 46b3460b7232c1..23f54949964734 100644 --- a/deps/npm/test/tap/install-cli-production-nosave.js +++ b/deps/npm/test/tap/install-cli-production-nosave.js @@ -3,12 +3,9 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') -var test = require('tap').test +var t = require('tap') var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -21,16 +18,20 @@ var PACKAGE_JSON1 = { } } -test('setup', function (t) { - setup() +t.test('setup', function (t) { + mkdirp.sync(path.resolve(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(PACKAGE_JSON1, null, 2) + ) mr({ port: common.port }, function (er, s) { t.ifError(er, 'started mock registry') - server = s + t.parent.teardown(() => s.close()) t.end() }) }) -test('install --production <module> without --save exits successfully', function (t) { +t.test('install --production <module> without --save exits successfully', function (t) { common.npm( [ '--registry', common.registry, @@ -45,25 +46,3 @@ test('install --production <module> without --save exits successfully', function } ) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(PACKAGE_JSON1, null, 2) - ) - - process.chdir(pkg) -} diff --git a/deps/npm/test/tap/install-cli-production.js b/deps/npm/test/tap/install-cli-production.js index 4c88add92fffcf..d083b4295738b0 100644 --- a/deps/npm/test/tap/install-cli-production.js +++ b/deps/npm/test/tap/install-cli-production.js @@ -3,8 +3,6 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -59,7 +57,6 @@ test('setup', function (t) { JSON.stringify(json, null, 2) ) - process.chdir(pkg) t.end() }) @@ -80,9 +77,3 @@ test('\'npm install --production\' should only install dependencies', function ( t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) diff --git a/deps/npm/test/tap/install-cli-unicode.js b/deps/npm/test/tap/install-cli-unicode.js index 2691db96d06777..930066db5fe54d 100644 --- a/deps/npm/test/tap/install-cli-unicode.js +++ b/deps/npm/test/tap/install-cli-unicode.js @@ -1,14 +1,10 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -28,15 +24,13 @@ var json = { } test('setup', function (t) { - rimraf.sync(pkg) - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) mr({ port: common.port }, function (er, s) { - server = s + t.parent.teardown(() => s.close()) t.end() }) }) @@ -61,11 +55,3 @@ test('does not use unicode with --unicode false', function (t) { } ) }) - -test('cleanup', function (t) { - server.close() - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - - t.end() -}) diff --git a/deps/npm/test/tap/install-duplicate-deps-warning.js b/deps/npm/test/tap/install-duplicate-deps-warning.js index 05eccd8e43b03f..869476ccd17ef1 100644 --- a/deps/npm/test/tap/install-duplicate-deps-warning.js +++ b/deps/npm/test/tap/install-duplicate-deps-warning.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -21,21 +18,16 @@ var json = { } } -test('setup', function (t) { +test('npm install with duplicate dependencies, different versions', function (t) { + t.plan(1) t.comment('test for https://github.com/npm/npm/issues/6725') - cleanup() - mkdirp.sync(pkg) + fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) process.chdir(pkg) - console.dir(pkg) - t.end() -}) -test('npm install with duplicate dependencies, different versions', function (t) { - t.plan(1) mr({ port: common.port }, function (er, s) { var opts = { cache: common.cache, @@ -57,13 +49,3 @@ test('npm install with duplicate dependencies, different versions', function (t) }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-from-local-multipath.js b/deps/npm/test/tap/install-from-local-multipath.js index 83dbdadde9e55e..e35794dca986cb 100644 --- a/deps/npm/test/tap/install-from-local-multipath.js +++ b/deps/npm/test/tap/install-from-local-multipath.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -115,7 +113,6 @@ var child2Lock = { } test('setup', function (t) { - rimraf.sync(pkg) mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -174,9 +171,3 @@ test('\'npm install\' should install local packages', function (t) { } ) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(root) - t.end() -}) diff --git a/deps/npm/test/tap/install-from-local.js b/deps/npm/test/tap/install-from-local.js index a3e63b359dbea2..1ab94243ff3cad 100644 --- a/deps/npm/test/tap/install-from-local.js +++ b/deps/npm/test/tap/install-from-local.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -37,7 +35,6 @@ var localDevDependency = { } test('setup', function (t) { - rimraf.sync(pkg) mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -90,9 +87,3 @@ test('\'npm install\' should install local packages', function (t) { } ) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(root) - t.end() -}) diff --git a/deps/npm/test/tap/install-link-scripts.js b/deps/npm/test/tap/install-link-scripts.js index 3553e6377370aa..52e50c6e9fb0a5 100644 --- a/deps/npm/test/tap/install-link-scripts.js +++ b/deps/npm/test/tap/install-link-scripts.js @@ -1,16 +1,12 @@ -if (process.platform === 'win32') { - require('tap').plan(0, 'links are weird on windows, skip this') - process.exit(0) -} var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') -var test = require('tap').test +const t = require('tap') var common = require('../common-tap.js') +common.skipIfWindows('links are weird on windows') var pkg = common.pkg var tmp = path.join(pkg, 'tmp') @@ -40,9 +36,29 @@ console.log('hey sup') process.env.npm_config_prefix = tmp -test('plain install', function (t) { - setup() +t.beforeEach(cb => { + rimraf(pkg, er => { + if (er) { + return cb(er) + } + mkdirp.sync(tmp) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + + mkdirp.sync(path.join(dep, 'bin')) + fs.writeFileSync( + path.join(dep, 'package.json'), + JSON.stringify(dependency, null, 2) + ) + fs.writeFileSync(path.join(dep, 'bin', 'foo'), foo) + fs.chmod(path.join(dep, 'bin', 'foo'), '0755') + cb() + }) +}) +t.test('plain install', function (t) { common.npm( [ 'install', dep, @@ -59,9 +75,7 @@ test('plain install', function (t) { ) }) -test('link', function (t) { - setup() - +t.test('link', function (t) { common.npm( [ 'link', @@ -78,9 +92,7 @@ test('link', function (t) { ) }) -test('install --link', function (t) { - setup() - +t.test('install --link', function (t) { common.npm( [ 'link', @@ -107,30 +119,3 @@ test('install --link', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(tmp) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - - mkdirp.sync(path.join(dep, 'bin')) - fs.writeFileSync( - path.join(dep, 'package.json'), - JSON.stringify(dependency, null, 2) - ) - fs.writeFileSync(path.join(dep, 'bin', 'foo'), foo) - fs.chmod(path.join(dep, 'bin', 'foo'), '0755') -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-man.js b/deps/npm/test/tap/install-man.js index 720b4c217b3757..8c4b89015151fc 100644 --- a/deps/npm/test/tap/install-man.js +++ b/deps/npm/test/tap/install-man.js @@ -1,15 +1,13 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var pkg = common.pkg -var target = pkg + '-target' +var pkg = resolve(common.pkg, 'package') +var target = resolve(common.pkg, 'target') common.pendIfWindows('man pages do not get installed on Windows') @@ -24,8 +22,14 @@ var json = { } test('setup', function (t) { - setup() - t.pass('setup ran') + mkdirp.sync(pkg) + // make sure it installs locally + mkdirp.sync(resolve(target, 'node_modules')) + fs.writeFileSync( + resolve(pkg, 'package.json'), + JSON.stringify(json, null, 2) + '\n' + ) + fs.writeFileSync(resolve(pkg, 'install-man.1'), 'THIS IS A MANPAGE\n') t.end() }) @@ -51,27 +55,3 @@ test('install man page', function (t) { } ) }) - -test('clean', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - // make sure it installs locally - mkdirp.sync(resolve(target, 'node_modules')) - fs.writeFileSync( - resolve(pkg, 'package.json'), - JSON.stringify(json, null, 2) + '\n' - ) - fs.writeFileSync(resolve(pkg, 'install-man.1'), 'THIS IS A MANPAGE\n') -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - rimraf.sync(target) -} diff --git a/deps/npm/test/tap/install-mention-funding.js b/deps/npm/test/tap/install-mention-funding.js new file mode 100644 index 00000000000000..3e9b81f24070b6 --- /dev/null +++ b/deps/npm/test/tap/install-mention-funding.js @@ -0,0 +1,127 @@ +'use strict' +const path = require('path') +const test = require('tap').test +const Tacks = require('tacks') +const Dir = Tacks.Dir +const File = Tacks.File +const common = require('../common-tap.js') + +const base = common.pkg +const singlePackage = path.join(base, 'single-funding-package') +const multiplePackages = path.join(base, 'top-level-funding') + +function getFixturePackage ({ name, version, dependencies, funding }) { + return Dir({ + 'package.json': File({ + name, + version: version || '1.0.0', + funding: funding || { + type: 'individual', + url: 'http://example.com/donate' + }, + dependencies: dependencies || {} + }) + }) +} + +const fixture = new Tacks(Dir({ + 'package.json': File({}), + 'single-funding-package': getFixturePackage({ + name: 'single-funding-package' + }), + 'top-level-funding': getFixturePackage({ + name: 'top-level-funding', + dependencies: { + 'dep-foo': 'file:../dep-foo', + 'dep-bar': 'file:../dep-bar' + } + }), + 'dep-foo': getFixturePackage({ + name: 'dep-foo', + funding: { + type: 'corporate', + url: 'https://corp.example.com/sponsor' + }, + dependencies: { + 'sub-dep-bar': 'file:../sub-dep-bar' + } + }), + 'dep-bar': getFixturePackage({ + name: 'dep-bar', + version: '2.1.0', + dependencies: { + 'sub-dep-bar': 'file:../sub-dep-bar' + } + }), + 'sub-dep-bar': getFixturePackage({ + name: 'sub-dep-bar', + funding: { + type: 'foo', + url: 'http://example.com/foo' + } + }) +})) + +test('mention npm fund upon installing single dependency', function (t) { + setup(t) + common.npm(['install', '--no-save', singlePackage], {cwd: base}, function (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'installed successfully') + t.is(stderr, '', 'no warnings') + t.includes(stdout, '1 package is looking for funding', 'should print amount of packages needing funding') + t.includes(stdout, ' run `npm fund` for details', 'should print npm fund mention') + t.end() + }) +}) + +test('mention npm fund upon installing multiple dependencies', function (t) { + setup(t) + common.npm(['install', '--no-save', multiplePackages], {cwd: base}, function (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'installed successfully') + t.is(stderr, '', 'no warnings') + t.includes(stdout, '4 packages are looking for funding', 'should print amount of packages needing funding') + t.includes(stdout, ' run `npm fund` for details', 'should print npm fund mention') + t.end() + }) +}) + +test('skips mention npm fund using --no-fund option', function (t) { + setup(t) + common.npm(['install', '--no-save', '--no-fund', multiplePackages], {cwd: base}, function (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'installed successfully') + t.is(stderr, '', 'no warnings') + t.doesNotHave(stdout, '4 packages are looking for funding', 'should print amount of packages needing funding') + t.doesNotHave(stdout, ' run `npm fund` for details', 'should print npm fund mention') + t.end() + }) +}) + +test('mention packages looking for funding using --json', function (t) { + setup(t) + common.npm(['install', '--no-save', '--json', multiplePackages], {cwd: base}, function (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'installed successfully') + t.is(stderr, '', 'no warnings') + const res = JSON.parse(stdout) + t.match(res.funding, '4 packages are looking for funding', 'should print amount of packages needing funding') + t.end() + }) +}) + +test('cleanup', function (t) { + cleanup() + t.end() +}) + +function setup (t) { + fixture.create(base) + t.teardown(() => { + cleanup() + }) +} + +function cleanup () { + fixture.remove(base) +} diff --git a/deps/npm/test/tap/install-noargs-dev.js b/deps/npm/test/tap/install-noargs-dev.js index 4716dc2243b537..53422b9b5bc234 100644 --- a/deps/npm/test/tap/install-noargs-dev.js +++ b/deps/npm/test/tap/install-noargs-dev.js @@ -3,12 +3,9 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -31,10 +28,14 @@ var PACKAGE_JSON2 = { } test('setup', function (t) { - setup() + mkdirp.sync(path.resolve(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(PACKAGE_JSON1, null, 2) + ) mr({ port: common.port }, function (er, s) { t.ifError(er, 'started mock registry') - server = s + t.parent.teardown(() => s.close()) t.end() }) }) @@ -87,25 +88,3 @@ test('install noargs installs updated devDependencies', function (t) { } ) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(PACKAGE_JSON1, null, 2) - ) - - process.chdir(pkg) -} diff --git a/deps/npm/test/tap/install-package-json-order.js b/deps/npm/test/tap/install-package-json-order.js index 2e780def2696f3..45ce882620c7b4 100644 --- a/deps/npm/test/tap/install-package-json-order.js +++ b/deps/npm/test/tap/install-package-json-order.js @@ -1,6 +1,5 @@ var test = require('tap').test var path = require('path') -var rimraf = require('rimraf') var mkdirp = require('mkdirp') var spawn = require('child_process').spawn var npm = require.resolve('../../bin/npm-cli.js') @@ -9,20 +8,26 @@ const common = require('../common-tap.js') var pkg = common.pkg var workdir = path.join(pkg, 'workdir') var tmp = path.join(pkg, 'tmp') -var cache = common.cache var fs = require('fs') -var osenv = require('osenv') test('package.json sorting after install', function (t) { var packageJson = path.resolve(pkg, 'package.json') var installedPackage = path.resolve(workdir, 'node_modules/install-package-json-order/package.json') - cleanup() - mkdirp.sync(cache) mkdirp.sync(tmp) mkdirp.sync(workdir) - setup() + + fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ + 'name': 'install-package-json-order', + 'version': '0.0.0', + 'array': [ 'one', 'two', 'three' ] + }, null, 2), 'utf8') + + fs.writeFileSync(path.resolve(workdir, 'package.json'), JSON.stringify({ + 'name': 'install-package-json-order-work', + 'version': '0.0.0' + }, null, 2), 'utf8') var before = JSON.parse(fs.readFileSync(packageJson).toString()) var child = spawn(node, [npm, 'install', pkg], { cwd: workdir }) @@ -35,29 +40,3 @@ test('package.json sorting after install', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - mkdirp.sync(pkg) - - fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ - 'name': 'install-package-json-order', - 'version': '0.0.0', - 'array': [ 'one', 'two', 'three' ] - }, null, 2), 'utf8') - fs.writeFileSync(path.resolve(workdir, 'package.json'), JSON.stringify({ - 'name': 'install-package-json-order-work', - 'version': '0.0.0' - }, null, 2), 'utf8') -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(cache) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-property-conflicts.js b/deps/npm/test/tap/install-property-conflicts.js index c8f58e139fbccd..a98f8570c62bdc 100644 --- a/deps/npm/test/tap/install-property-conflicts.js +++ b/deps/npm/test/tap/install-property-conflicts.js @@ -1,9 +1,7 @@ var fs = require('fs') var resolve = require('path').resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -22,8 +20,12 @@ var json = { } test('setup', function (t) { - setup() - t.pass('setup ran') + // make sure it installs locally + mkdirp.sync(resolve(target, 'node_modules')) + fs.writeFileSync( + resolve(pkg, 'package.json'), + JSON.stringify(json, null, 2) + '\n' + ) t.end() }) @@ -49,26 +51,3 @@ test('install package with a `type` property', function (t) { } ) }) - -test('clean', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(pkg) - // make sure it installs locally - mkdirp.sync(resolve(target, 'node_modules')) - fs.writeFileSync( - resolve(pkg, 'package.json'), - JSON.stringify(json, null, 2) + '\n' - ) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - rimraf.sync(target) -} diff --git a/deps/npm/test/tap/install-save-consistent-newlines.js b/deps/npm/test/tap/install-save-consistent-newlines.js index acea57c987bfb9..dfe41c649d2afa 100644 --- a/deps/npm/test/tap/install-save-consistent-newlines.js +++ b/deps/npm/test/tap/install-save-consistent-newlines.js @@ -5,7 +5,6 @@ const path = require('path') const mkdirp = require('mkdirp') const mr = require('npm-registry-mock') -const osenv = require('osenv') const rimraf = require('rimraf') const test = require('tap').test @@ -21,102 +20,79 @@ const json = { description: 'fixture' } -var server - -test('setup', function (t) { - setup('\n') +test('mock registry', function (t) { mr({ port: common.port }, function (er, s) { - server = s + t.parent.teardown(() => s.close()) t.end() }) }) -test('\'npm install --save\' should keep the original package.json line endings (LF)', function (t) { - common.npm( - [ - '--loglevel', 'silent', - '--registry', common.registry, - '--save', - 'install', 'underscore@1.3.1' - ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm ran without issue') - t.notOk(code, 'npm install exited without raising an error code') - - const pkgPath = path.resolve(pkg, 'package.json') - const pkgStr = fs.readFileSync(pkgPath, 'utf8') - - t.match(pkgStr, '\n') - t.notMatch(pkgStr, '\r') +const runTest = (t, opts) => { + t.test('setup', setup(opts.ending)) + t.test('check', check(opts)) + t.end() +} - const pkgLockPath = path.resolve(pkg, 'package-lock.json') - const pkgLockStr = fs.readFileSync(pkgLockPath, 'utf8') +const setup = lineEnding => t => { + rimraf(pkg, er => { + if (er) { + throw er + } + mkdirp.sync(path.resolve(pkg, 'node_modules')) - t.match(pkgLockStr, '\n') - t.notMatch(pkgLockStr, '\r') + var jsonStr = JSON.stringify(json, null, 2) - t.end() + if (lineEnding === '\r\n') { + jsonStr = jsonStr.replace(/\n/g, '\r\n') } - ) -}) -test('\'npm install --save\' should keep the original package.json line endings (CRLF)', function (t) { - setup('\r\n') + fs.writeFileSync( + path.join(pkg, 'package.json'), + jsonStr + ) - common.npm( - [ - '--loglevel', 'silent', - '--registry', common.registry, - '--save', - 'install', 'underscore@1.3.1' - ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm ran without issue') - t.notOk(code, 'npm install exited without raising an error code') + t.end() + }) +} - const pkgPath = path.resolve(pkg, 'package.json') - const pkgStr = fs.readFileSync(pkgPath, 'utf8') +const check = opts => t => common.npm( + [ + '--loglevel', 'silent', + '--registry', common.registry, + '--save', + 'install', 'underscore@1.3.1' + ], + EXEC_OPTS +).then(([code, err, out]) => { + t.notOk(code, 'npm install exited without raising an error code') - t.match(pkgStr, '\r\n') - t.notMatch(pkgStr, /[^\r]\n/) + const pkgPath = path.resolve(pkg, 'package.json') + const pkgStr = fs.readFileSync(pkgPath, 'utf8') - const pkgLockPath = path.resolve(pkg, 'package-lock.json') - const pkgLockStr = fs.readFileSync(pkgLockPath, 'utf8') + t.match(pkgStr, opts.match) + t.notMatch(pkgStr, opts.notMatch) - t.match(pkgLockStr, '\r\n') - t.notMatch(pkgLockStr, /[^\r]\n/) + const pkgLockPath = path.resolve(pkg, 'package-lock.json') + const pkgLockStr = fs.readFileSync(pkgLockPath, 'utf8') - t.end() - } - ) -}) + t.match(pkgLockStr, opts.match) + t.notMatch(pkgLockStr, opts.notMatch) -test('cleanup', function (t) { - server.close() - cleanup() t.end() }) -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup (lineEnding) { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - - var jsonStr = JSON.stringify(json, null, 2) - - if (lineEnding === '\r\n') { - jsonStr = jsonStr.replace(/\n/g, '\r\n') - } +test('keep LF line endings', t => { + runTest(t, { + ending: '\n', + match: '\n', + notMatch: '\r' + }) +}) - fs.writeFileSync( - path.join(pkg, 'package.json'), - jsonStr - ) - process.chdir(pkg) -} +test('keep CRLF line endings', t => { + runTest(t, { + ending: '\r\n', + match: '\r\n', + notMatch: /[^\r]\n/ + }) +}) diff --git a/deps/npm/test/tap/install-save-exact.js b/deps/npm/test/tap/install-save-exact.js index 3d57ead361be8f..efa1e636138a17 100644 --- a/deps/npm/test/tap/install-save-exact.js +++ b/deps/npm/test/tap/install-save-exact.js @@ -3,12 +3,10 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -20,53 +18,32 @@ var json = { description: 'fixture' } -test('setup', function (t) { - setup() +test('mock registry', function (t) { mr({ port: common.port }, function (er, s) { - server = s + t.parent.teardown(() => s.close()) t.end() }) }) -test('\'npm install --save --save-exact\' should install local pkg', function (t) { - common.npm( - [ - '--loglevel', 'silent', - '--registry', common.registry, - '--save', - '--save-exact', - 'install', 'underscore@1.3.1' - ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm ran without issue') - t.notOk(code, 'npm install exited without raising an error code') - - var p = path.resolve(pkg, 'node_modules/underscore/package.json') - t.ok(JSON.parse(fs.readFileSync(p))) - - p = path.resolve(pkg, 'package.json') - var pkgJson = JSON.parse(fs.readFileSync(p, 'utf8')) - - t.same( - pkgJson.dependencies, - { 'underscore': '1.3.1' }, - 'underscore dependency should specify exactly 1.3.1' - ) - - t.end() - } - ) -}) - -test('\'npm install --save-dev --save-exact\' should install local pkg', function (t) { - setup() +const setup = t => { + t.test('destroy', t => rimraf(pkg, t.end)) + t.test('create', t => { + mkdirp.sync(path.resolve(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + t.end() + }) + t.end() +} +const check = (savearg, deptype) => t => { common.npm( [ '--loglevel', 'silent', '--registry', common.registry, - '--save-dev', + savearg, '--save-exact', 'install', 'underscore@1.3.1' ], @@ -82,7 +59,7 @@ test('\'npm install --save-dev --save-exact\' should install local pkg', functio var pkgJson = JSON.parse(fs.readFileSync(p, 'utf8')) t.same( - pkgJson.devDependencies, + pkgJson[deptype], { 'underscore': '1.3.1' }, 'underscore dependency should specify exactly 1.3.1' ) @@ -90,25 +67,16 @@ test('\'npm install --save-dev --save-exact\' should install local pkg', functio t.end() } ) -}) +} -test('cleanup', function (t) { - server.close() - cleanup() +test('\'npm install --save --save-exact\' should install local pkg', function (t) { + t.test('setup', setup) + t.test('check', check('--save', 'dependencies')) t.end() }) -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} +test('\'npm install --save-dev --save-exact\' should install local pkg', function (t) { + t.test('setup', setup) + t.test('check', check('--save-dev', 'devDependencies')) + t.end() +}) diff --git a/deps/npm/test/tap/install-save-local.js b/deps/npm/test/tap/install-save-local.js index 8f4f5ecb0023e6..8b6597952813da 100644 --- a/deps/npm/test/tap/install-save-local.js +++ b/deps/npm/test/tap/install-save-local.js @@ -2,7 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test @@ -28,168 +27,155 @@ var localDevDependency = { version: '0.0.0' } -test('setup', function (t) { - setup() +test('setup deps in root', t => { + mkdirp.sync(path.join(root, 'package-local-dependency')) + fs.writeFileSync( + path.join(root, 'package-local-dependency', 'package.json'), + JSON.stringify(localDependency, null, 2) + ) + + mkdirp.sync(path.join(root, 'package-local-dev-dependency')) + fs.writeFileSync( + path.join(root, 'package-local-dev-dependency', 'package.json'), + JSON.stringify(localDevDependency, null, 2) + ) + t.end() }) test('\'npm install --save ../local/path\' should save to package.json', function (t) { - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--loglevel', 'silent', '--save', 'install', '../package-local-dependency' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var dependencyPackageJson = path.join( - pkg, 'node_modules', 'package-local-dependency', 'package.json' - ) - t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) - - var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) - t.is(Object.keys(pkgJson.dependencies).length, 1, 'only one dep') - t.ok( - /file:.*?[/]package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), - 'local package saved correctly' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var dependencyPackageJson = path.join( + pkg, 'node_modules', 'package-local-dependency', 'package.json' + ) + t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) + + var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) + t.is(Object.keys(pkgJson.dependencies).length, 1, 'only one dep') + t.ok( + /file:.*?[/]package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), + 'local package saved correctly' + ) + })) }) test('\'npm install --save local/path\' should save to package.json', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--loglevel', 'silent', '--save', 'install', 'package-local-dependency/' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var dependencyPackageJson = path.join( - pkg, 'node_modules', 'package-local-dependency', 'package.json' - ) - t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) - - var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) - t.is(Object.keys(pkgJson.dependencies).length, 1, 'only one dep') - t.ok( - /file:package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), - 'local package saved correctly' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code, out, err]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var dependencyPackageJson = path.join( + pkg, 'node_modules', 'package-local-dependency', 'package.json' + ) + t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) + + var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) + t.is(Object.keys(pkgJson.dependencies).length, 1, 'only one dep') + t.ok( + /file:package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), + 'local package saved correctly' + ) + })) }) test('\'npm install --save-dev ../local/path\' should save to package.json', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--loglevel', 'silent', '--save-dev', 'install', '../package-local-dev-dependency' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var dependencyPackageJson = path.resolve( - pkg, 'node_modules', 'package-local-dev-dependency', 'package.json' - ) - t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) - - var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) - t.is(Object.keys(pkgJson.devDependencies).length, 1, 'only one dep') - t.ok( - /file:.*?[/\\]package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), - 'local package saved correctly' - ) - - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var dependencyPackageJson = path.resolve( + pkg, 'node_modules', 'package-local-dev-dependency', 'package.json' + ) + t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) + + var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) + t.is(Object.keys(pkgJson.devDependencies).length, 1, 'only one dep') + t.ok( + /file:.*?[/\\]package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), + 'local package saved correctly' + ) + + t.end() + })) }) + test('\'npm install --save-dev local/path\' should save to package.json', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--loglevel', 'silent', '--save-dev', 'install', 'package-local-dev-dependency/' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var dependencyPackageJson = path.resolve( - pkg, 'node_modules', 'package-local-dev-dependency', 'package.json' - ) - t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) - - var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) - t.is(Object.keys(pkgJson.devDependencies).length, 1, 'only one dep') - t.ok( - /file:package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), - 'local package saved correctly' - ) - - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var dependencyPackageJson = path.resolve( + pkg, 'node_modules', 'package-local-dev-dependency', 'package.json' + ) + t.ok(JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8'))) + + var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) + t.is(Object.keys(pkgJson.devDependencies).length, 1, 'only one dep') + t.ok( + /file:package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), + 'local package saved correctly' + ) + + t.end() + })) }) -test('cleanup', function (t) { - cleanup() +function setup (t) { + t.test('destroy', t => rimraf(pkg, t.end)) + t.test('create', t => { + mkdirp.sync(pkg) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'package-local-dependency')) + fs.writeFileSync( + path.join(pkg, 'package-local-dependency', 'package.json'), + JSON.stringify(localDependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'package-local-dev-dependency')) + fs.writeFileSync( + path.join(pkg, 'package-local-dev-dependency', 'package.json'), + JSON.stringify(localDevDependency, null, 2) + ) + t.end() + }) t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - process.chdir(__dirname) - rimraf.sync(root) -} - -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - - mkdirp.sync(path.join(root, 'package-local-dependency')) - fs.writeFileSync( - path.join(root, 'package-local-dependency', 'package.json'), - JSON.stringify(localDependency, null, 2) - ) - - mkdirp.sync(path.join(root, 'package-local-dev-dependency')) - fs.writeFileSync( - path.join(root, 'package-local-dev-dependency', 'package.json'), - JSON.stringify(localDevDependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'package-local-dependency')) - fs.writeFileSync( - path.join(pkg, 'package-local-dependency', 'package.json'), - JSON.stringify(localDependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'package-local-dev-dependency')) - fs.writeFileSync( - path.join(pkg, 'package-local-dev-dependency', 'package.json'), - JSON.stringify(localDevDependency, null, 2) - ) - process.chdir(pkg) } diff --git a/deps/npm/test/tap/install-save-prefix.js b/deps/npm/test/tap/install-save-prefix.js index 001e24d873558a..d61608e1cfd21d 100644 --- a/deps/npm/test/tap/install-save-prefix.js +++ b/deps/npm/test/tap/install-save-prefix.js @@ -1,14 +1,11 @@ var fs = require('fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -19,17 +16,18 @@ var json = { version: '0.0.1' } -test('setup', function (t) { - setup() +test('start mock reg', function (t) { mr({ port: common.port }, function (er, s) { t.ifError(er, 'started mock registry') - server = s + t.parent.teardown(() => s.close()) t.end() }) }) test('install --save with \'^\' save prefix should accept minor updates', function (t) { - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--registry', common.registry, '--loglevel', 'silent', @@ -37,31 +35,30 @@ test('install --save with \'^\' save prefix should accept minor updates', functi '--save', 'install', 'underscore@latest' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') - t.ok(JSON.parse(fs.readFileSync(p))) - - var pkgJson = JSON.parse(fs.readFileSync( - path.join(pkg, 'package.json'), - 'utf8' - )) - t.deepEqual( - pkgJson.dependencies, - { 'underscore': '^1.5.1' }, - 'got expected save prefix and version of 1.5.1' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + console.error('back from install!', code) + t.equal(code, 0, 'npm install exited with code 0') + + var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') + t.ok(JSON.parse(fs.readFileSync(p))) + + var pkgJson = JSON.parse(fs.readFileSync( + path.join(pkg, 'package.json'), + 'utf8' + )) + t.deepEqual( + pkgJson.dependencies, + { 'underscore': '^1.5.1' }, + 'got expected save prefix and version of 1.5.1' + ) + })) }) test('install --save-dev with \'^\' save prefix should accept minor dev updates', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--registry', common.registry, '--loglevel', 'silent', @@ -69,31 +66,30 @@ test('install --save-dev with \'^\' save prefix should accept minor dev updates' '--save-dev', 'install', 'underscore@1.3.1' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') - t.ok(JSON.parse(fs.readFileSync(p))) - - var pkgJson = JSON.parse(fs.readFileSync( - path.join(pkg, 'package.json'), - 'utf8' - )) - t.deepEqual( - pkgJson.devDependencies, - { 'underscore': '^1.3.1' }, - 'got expected save prefix and version of 1.3.1' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') + t.ok(JSON.parse(fs.readFileSync(p))) + + var pkgJson = JSON.parse(fs.readFileSync( + path.join(pkg, 'package.json'), + 'utf8' + )) + t.deepEqual( + pkgJson.devDependencies, + { 'underscore': '^1.3.1' }, + 'got expected save prefix and version of 1.3.1' + ) + t.end() + })) }) test('install --save with \'~\' save prefix should accept patch updates', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--registry', common.registry, '--loglevel', 'silent', @@ -101,31 +97,29 @@ test('install --save with \'~\' save prefix should accept patch updates', functi '--save', 'install', 'underscore@1.3.1' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') - t.ok(JSON.parse(fs.readFileSync(p))) - - var pkgJson = JSON.parse(fs.readFileSync( - path.join(pkg, 'package.json'), - 'utf8' - )) - t.deepEqual( - pkgJson.dependencies, - { 'underscore': '~1.3.1' }, - 'got expected save prefix and version of 1.3.1' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.equal(code, 0, 'npm install exited with code 0') + + var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') + t.ok(JSON.parse(fs.readFileSync(p))) + + var pkgJson = JSON.parse(fs.readFileSync( + path.join(pkg, 'package.json'), + 'utf8' + )) + t.deepEqual( + pkgJson.dependencies, + { 'underscore': '~1.3.1' }, + 'got expected save prefix and version of 1.3.1' + ) + })) }) test('install --save-dev with \'~\' save prefix should accept patch updates', function (t) { - setup() - common.npm( + t.plan(2) + t.test('setup', setup) + t.test('run test', t => common.npm( [ '--registry', common.registry, '--loglevel', 'silent', @@ -133,46 +127,38 @@ test('install --save-dev with \'~\' save prefix should accept patch updates', fu '--save-dev', 'install', 'underscore@1.3.1' ], - EXEC_OPTS, - function (err, code) { - t.ifError(err, 'npm install ran without issue') - t.notOk(code, 'npm install exited with code 0') - - var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') - t.ok(JSON.parse(fs.readFileSync(p))) - - var pkgJson = JSON.parse(fs.readFileSync( - path.join(pkg, 'package.json'), - 'utf8' - )) - t.deepEqual( - pkgJson.devDependencies, - { 'underscore': '~1.3.1' }, - 'got expected save prefix and version of 1.3.1' - ) - t.end() - } - ) + EXEC_OPTS + ).then(([code]) => { + t.notOk(code, 'npm install exited with code 0') + + var p = path.join(pkg, 'node_modules', 'underscore', 'package.json') + t.ok(JSON.parse(fs.readFileSync(p))) + + var pkgJson = JSON.parse(fs.readFileSync( + path.join(pkg, 'package.json'), + 'utf8' + )) + t.deepEqual( + pkgJson.devDependencies, + { 'underscore': '~1.3.1' }, + 'got expected save prefix and version of 1.3.1' + ) + })) }) -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) +function setup (t) { + t.test('destroy', t => { + t.plan(2) + rimraf(path.resolve(pkg, 'node_modules'), () => t.pass('node_modules')) + rimraf(path.resolve(pkg, 'pacakage-lock.json'), () => t.pass('lock file')) + }) + t.test('create', t => { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + t.end() + }) - process.chdir(pkg) + t.end() } diff --git a/deps/npm/test/tap/install-scoped-already-installed.js b/deps/npm/test/tap/install-scoped-already-installed.js index 707d82a44353ed..d4655f4a9a7483 100644 --- a/deps/npm/test/tap/install-scoped-already-installed.js +++ b/deps/npm/test/tap/install-scoped-already-installed.js @@ -3,8 +3,6 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -37,7 +35,6 @@ var scopedDependency = { } test('setup', function (t) { - rimraf.sync(root) mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -56,7 +53,6 @@ test('setup', function (t) { JSON.stringify(scopedDependency, null, 2) ) - process.chdir(pkg) t.end() }) @@ -118,12 +114,6 @@ test('installing already installed local scoped package', function (t) { ) }) -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(root) - t.end() -}) - function contains (list, element) { var matcher = new RegExp(element.replace(/\//g, '[\\\\/]') + '$') for (var i = 0; i < list.length; ++i) { diff --git a/deps/npm/test/tap/install-scoped-link.js b/deps/npm/test/tap/install-scoped-link.js index 920e7e3d4531af..a0c9c61a9843ce 100644 --- a/deps/npm/test/tap/install-scoped-link.js +++ b/deps/npm/test/tap/install-scoped-link.js @@ -4,16 +4,15 @@ var path = require('path') var existsSync = fs.existsSync || path.existsSync var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var escapeExecPath = require('../../lib/utils/escape-exec-path') var common = require('../common-tap.js') -var pkg = common.pkg -var work = pkg + '-TEST' +var resolve = require('path').resolve +var pkg = resolve(common.pkg, 'package') +var work = resolve(common.pkg, 'TEST') var modules = path.join(work, 'node_modules') var EXEC_OPTS = { cwd: work } @@ -29,7 +28,6 @@ var json = { } test('setup', function (t) { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -73,14 +71,3 @@ test('installing package with links', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(work) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-scoped-with-peer-dependency.js b/deps/npm/test/tap/install-scoped-with-peer-dependency.js index 477a04a1055dd3..016f5f0453b31c 100644 --- a/deps/npm/test/tap/install-scoped-with-peer-dependency.js +++ b/deps/npm/test/tap/install-scoped-with-peer-dependency.js @@ -2,15 +2,13 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') var pkg = common.pkg var local = path.join(pkg, 'package') -var EXEC_OPTS = { } +var EXEC_OPTS = { cwd: pkg } var json = { name: '@scope/package', @@ -21,8 +19,12 @@ var json = { } test('setup', function (t) { - setup() - + mkdirp.sync(local) + mkdirp.sync(path.resolve(pkg, 'node_modules')) + fs.writeFileSync( + path.join(local, 'package.json'), + JSON.stringify(json, null, 2) + ) t.end() }) @@ -36,24 +38,3 @@ test('it should install peerDependencies in same tree level as the parent packag t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(local) - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(local, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-shrinkwrapped-git.js b/deps/npm/test/tap/install-shrinkwrapped-git.js index f74e185bfbad0e..3cdc2b91291d4d 100644 --- a/deps/npm/test/tap/install-shrinkwrapped-git.js +++ b/deps/npm/test/tap/install-shrinkwrapped-git.js @@ -3,7 +3,6 @@ var fs = require('fs') var path = require('path') var resolve = path.resolve -var osenv = require('osenv') var mkdirp = require('mkdirp') var rimraf = require('rimraf') var test = require('tap').test @@ -32,16 +31,31 @@ var childPackageJSON = JSON.stringify({ }) test('setup', function (t) { - cleanup() - setup(function (err, result) { - t.ifError(err, 'git started up successfully') + mkdirp.sync(parentPath) + fs.writeFileSync(resolve(parentPath, 'package.json'), parentPackageJSON) + process.chdir(parentPath) - if (!err) { - gitDaemon = result[result.length - 2] - gitDaemonPID = result[result.length - 1] - } + // Setup child + mkdirp.sync(childPath) + fs.writeFileSync(resolve(childPath, 'package.json'), childPackageJSON) + + // Setup npm and then git + npm.load({ + registry: common.registry, + loglevel: 'silent', + save: true // Always install packages with --save + }, function () { + // It's important to initialize git after npm because it uses config + initializeGit(function (err, result) { + t.ifError(err, 'git started up successfully') - t.end() + if (!err) { + gitDaemon = result[result.length - 2] + gitDaemonPID = result[result.length - 1] + } + + t.end() + }) }) }) @@ -85,39 +99,10 @@ test('shrinkwrapped git dependency got updated', function (t) { }) test('clean', function (t) { - gitDaemon.on('close', function () { - cleanup() - t.end() - }) + gitDaemon.on('close', t.end) process.kill(gitDaemonPID) }) -function setup (cb) { - // Setup parent package - mkdirp.sync(parentPath) - fs.writeFileSync(resolve(parentPath, 'package.json'), parentPackageJSON) - process.chdir(parentPath) - - // Setup child - mkdirp.sync(childPath) - fs.writeFileSync(resolve(childPath, 'package.json'), childPackageJSON) - - // Setup npm and then git - npm.load({ - registry: common.registry, - loglevel: 'silent', - save: true // Always install packages with --save - }, function () { - // It's important to initialize git after npm because it uses config - initializeGit(cb) - }) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(mockPath) -} - function prepareChildAndGetRefs (cb) { var opts = { cwd: childPath, env: { PATH: process.env.PATH } } chain([ diff --git a/deps/npm/test/tap/install-test-cli-without-package-lock.js b/deps/npm/test/tap/install-test-cli-without-package-lock.js index 468277d74d209f..603043af8fd381 100644 --- a/deps/npm/test/tap/install-test-cli-without-package-lock.js +++ b/deps/npm/test/tap/install-test-cli-without-package-lock.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -28,8 +26,23 @@ var dependency = { } test('setup', function (t) { - setup() - t.pass('setup ran') + mkdirp.sync(path.join(pkg, 'dependency')) + fs.writeFileSync( + path.join(pkg, 'dependency', 'package.json'), + JSON.stringify(dependency, null, 2) + ) + + mkdirp.sync(path.join(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + + // Disable package-lock + fs.writeFileSync( + path.join(pkg, '.npmrc'), + 'package-lock=false\n' + ) t.end() }) @@ -49,35 +62,3 @@ test('\'npm install-test\' should not generate package-lock.json.*', function (t t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.pass('cleaned up') - t.end() -}) - -function setup () { - mkdirp.sync(path.join(pkg, 'dependency')) - fs.writeFileSync( - path.join(pkg, 'dependency', 'package.json'), - JSON.stringify(dependency, null, 2) - ) - - mkdirp.sync(path.join(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - - // Disable package-lock - fs.writeFileSync( - path.join(pkg, '.npmrc'), - 'package-lock=false\n' - ) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install-with-dev-dep-duplicate.js b/deps/npm/test/tap/install-with-dev-dep-duplicate.js index 01ba38a1123a98..7d8586f47d4ad1 100644 --- a/deps/npm/test/tap/install-with-dev-dep-duplicate.js +++ b/deps/npm/test/tap/install-with-dev-dep-duplicate.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -42,13 +39,19 @@ test('prefers version from dependencies over devDependencies', function (t) { mr({ port: common.port }, function (er, s) { setup(function (err) { - if (err) return t.fail(err) + if (err) { + throw err + } npm.install('.', function (err) { - if (err) return t.fail(err) + if (err) { + throw err + } npm.commands.ls([], true, function (err, _, results) { - if (err) return t.fail(err) + if (err) { + throw err + } // these contain full paths so we can't do an exact match // with them @@ -63,14 +66,7 @@ test('prefers version from dependencies over devDependencies', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - function setup (cb) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -83,8 +79,3 @@ function setup (cb) { } npm.load(opts, cb) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/install.fund.js b/deps/npm/test/tap/install.fund.js new file mode 100644 index 00000000000000..fca5fb3afd123c --- /dev/null +++ b/deps/npm/test/tap/install.fund.js @@ -0,0 +1,99 @@ +'use strict' + +const { test } = require('tap') +const { getPrintFundingReport } = require('../../lib/install/fund') + +test('message when there are no funding found', (t) => { + t.equal( + getPrintFundingReport({}), + '', + 'should not print any message if missing info' + ) + t.equal( + getPrintFundingReport({ + name: 'foo', + version: '1.0.0', + dependencies: {} + }), + '', + 'should not print any message if package has no dependencies' + ) + t.equal( + getPrintFundingReport({ + fund: true, + idealTree: { + name: 'foo', + version: '1.0.0', + dependencies: { + bar: {}, + lorem: {} + } + } + }), + '', + 'should not print any message if no package has funding info' + ) + t.end() +}) + +test('print appropriate message for a single package', (t) => { + t.equal( + getPrintFundingReport({ + fund: true, + idealTree: { + name: 'foo', + version: '1.0.0', + children: [ + { + package: { + name: 'bar', + version: '1.0.0', + funding: { type: 'foo', url: 'http://example.com' } + } + } + ] + } + }).replace(/[\r\n]+/g, '\n'), + `\n1 package is looking for funding\n run \`npm fund\` for details\n`, + 'should print single package message' + ) + t.end() +}) + +test('print appropriate message for many packages', (t) => { + t.equal( + getPrintFundingReport({ + fund: true, + idealTree: { + name: 'foo', + version: '1.0.0', + children: [ + { + package: { + name: 'bar', + version: '1.0.0', + funding: { type: 'foo', url: 'http://example.com' } + } + }, + { + package: { + name: 'lorem', + version: '1.0.0', + funding: { type: 'foo', url: 'http://example.com' } + } + }, + { + package: { + name: 'ipsum', + version: '1.0.0', + funding: { type: 'foo', url: 'http://example.com' } + } + } + ] + } + }).replace(/[\r\n]+/g, '\n'), + `\n3 packages are looking for funding\n run \`npm fund\` for details\n`, + 'should print many package message' + ) + t.end() +}) diff --git a/deps/npm/test/tap/it.js b/deps/npm/test/tap/it.js index 9b716139a3814a..bb59bc6f5e9044 100644 --- a/deps/npm/test/tap/it.js +++ b/deps/npm/test/tap/it.js @@ -2,9 +2,7 @@ var join = require('path').join var statSync = require('graceful-fs').statSync var writeFileSync = require('graceful-fs').writeFileSync -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test @@ -23,55 +21,45 @@ var json = { } } -var server - test('run up the mock registry', function (t) { mr({ port: common.port }, function (err, s) { if (err) throw err - server = s + t.parent.teardown(() => s.close()) t.end() }) }) +const check = args => t => + common.npm(args.concat('--registry=' + common.registry), { cwd: pkg }) + .then(([code, stdout, stderr]) => { + t.equal(code, 0, 'command ran without error') + t.ok(statSync(installed), 'package was installed') + t.equal(require(installed).version, '1.5.1', 'underscore got installed as expected') + t.match(stdout, /hax/, 'found expected test output') + t.notOk(stderr, 'stderr should be empty') + }) + test('npm install-test', function (t) { - setup() - common.npm(['install-test', '--no-shrinkwrap', '--registry=' + common.registry], { cwd: pkg }, function (err, code, stdout, stderr) { - if (err) throw err - t.equal(code, 0, 'command ran without error') - t.ok(statSync(installed), 'package was installed') - t.equal(require(installed).version, '1.5.1', 'underscore got installed as expected') - t.match(stdout, /hax/, 'found expected test output') - t.notOk(stderr, 'stderr should be empty') - t.end() - }) + t.plan(2) + t.test('setup', setup) + t.test('check', check(['install-test', '--no-shrinkwrap'])) }) test('npm it (the form most people will use)', function (t) { - setup() - common.npm(['it', '--registry=' + common.registry], { cwd: pkg }, function (err, code, stdout, stderr) { - if (err) throw err - t.equal(code, 0, 'command ran without error') - t.ok(statSync(installed), 'package was installed') - t.equal(require(installed).version, '1.5.1', 'underscore got installed as expected') - t.match(stdout, /hax/, 'found expected test output') - t.notOk(stderr, 'stderr should be empty') - t.end() - }) + t.plan(2) + t.test('setup', setup) + t.test('check', check(['it'])) }) -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - server.close() - cleanup() +function setup (t) { + t.test('destroy', t => { + t.plan(2) + rimraf(join(pkg, 'node_modules'), () => t.pass('node_modules')) + rimraf(join(pkg, 'package-lock.json'), () => t.pass('lock file')) + }) + t.test('create', t => { + writeFileSync(join(pkg, 'package.json'), JSON.stringify(json, null, 2)) + t.end() + }) t.end() -}) - -function cleanup () { - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(pkg) - writeFileSync(join(pkg, 'package.json'), JSON.stringify(json, null, 2)) } diff --git a/deps/npm/test/tap/lifecycle-INIT_CWD.js b/deps/npm/test/tap/lifecycle-INIT_CWD.js index 3e9c1c8257f460..fbedd3849c7085 100644 --- a/deps/npm/test/tap/lifecycle-INIT_CWD.js +++ b/deps/npm/test/tap/lifecycle-INIT_CWD.js @@ -2,8 +2,6 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -20,39 +18,19 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) mkdirp.sync(subdir) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) - - process.chdir(subdir) - t.end() -}) - -test('make sure the env.INIT_CWD is correct', function (t) { - common.npm(['run-script', 'initcwd'], { - cwd: subdir - }, function (er, code, stdout) { - if (er) throw er - t.equal(code, 0, 'exit code') - stdout = stdout.trim().split(/\r|\n/).pop() - var actual = stdout - - t.equal(actual, subdir) - t.end() - }) -}) - -test('cleanup', function (t) { - cleanup() t.end() }) -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(subdir) - rimraf.sync(pkg) -} +test('make sure the env.INIT_CWD is correct', t => + common.npm(['run-script', 'initcwd'], { cwd: subdir }) + .then(([code, stdout, stderr]) => { + t.equal(code, 0, 'exit code') + stdout = stdout.trim().split(/\r|\n/).pop() + var actual = stdout + t.equal(actual, subdir) + })) diff --git a/deps/npm/test/tap/lifecycle-order.js b/deps/npm/test/tap/lifecycle-order.js index 8f2b2ba4a70b8e..ac6c07925c52bf 100644 --- a/deps/npm/test/tap/lifecycle-order.js +++ b/deps/npm/test/tap/lifecycle-order.js @@ -1,13 +1,7 @@ var fs = require('graceful-fs') var path = require('path') - -var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test - var common = require('../common-tap.js') - var pkg = common.pkg var json = { @@ -21,37 +15,19 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) - - process.chdir(pkg) t.end() }) -test('lifecycle scripts execute in the proper order', function (t) { - common.npm('install', {cwd: pkg}, function (err, code, stdout, stderr) { - if (err) throw err +test('lifecycle scripts execute in the proper order', t => + common.npm('install', {cwd: pkg}).then(([code, stdout, stderr]) => { t.is(code, 0, 'no error') // All three files should exist t.ok(fs.existsSync(path.join(pkg, 'preinstall-step')), 'preinstall ok') t.ok(fs.existsSync(path.join(pkg, 'install-step')), 'install ok') t.ok(fs.existsSync(path.join(pkg, 'postinstall-step')), 'postinstall ok') - - t.end() - }) -}) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} + })) diff --git a/deps/npm/test/tap/link.js b/deps/npm/test/tap/link.js index f0339194a26265..2d2d63de214156 100644 --- a/deps/npm/test/tap/link.js +++ b/deps/npm/test/tap/link.js @@ -1,7 +1,5 @@ var mkdirp = require('mkdirp') -var osenv = require('osenv') var path = require('path') -var rimraf = require('rimraf') var test = require('tap').test var lstatSync = require('fs').lstatSync var writeFileSync = require('fs').writeFileSync @@ -72,7 +70,28 @@ var insideInstallJSON = { } test('setup', function (t) { - setup() + mkdirp.sync(linkRoot) + mkdirp.sync(link) + writeFileSync( + path.join(link, 'package.json'), + JSON.stringify(readJSON, null, 2) + ) + mkdirp.sync(linkScoped) + writeFileSync( + path.join(linkScoped, 'package.json'), + JSON.stringify(readScopedJSON, null, 2) + ) + mkdirp.sync(linkInstall) + writeFileSync( + path.join(linkInstall, 'package.json'), + JSON.stringify(installJSON, null, 2) + ) + mkdirp.sync(linkInside) + writeFileSync( + path.join(linkInside, 'package.json'), + JSON.stringify(insideInstallJSON, null, 2) + ) + writeFileSync(configPath, config) common.npm(['ls', '-g', '--depth=0'], OPTS, function (err, c, out) { t.ifError(err) t.equal(c, 0, 'set up ok') @@ -173,50 +192,14 @@ test('ls the linked packages', function (t) { }) test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) + process.chdir(common.pkg) common.npm(['rm', 'foo'], OPTS, function (err, code) { t.ifError(err, 'npm removed the linked package without error') t.equal(code, 0, 'cleanup foo in local ok') common.npm(['rm', '-g', 'foo'], OPTS, function (err, code) { t.ifError(err, 'npm removed the global package without error') t.equal(code, 0, 'cleanup foo in global ok') - - cleanup() t.end() }) }) }) - -function cleanup () { - rimraf.sync(linkRoot) - rimraf.sync(link) - rimraf.sync(linkScoped) - rimraf.sync(linkInstall) - rimraf.sync(linkInside) -} - -function setup () { - cleanup() - mkdirp.sync(linkRoot) - mkdirp.sync(link) - writeFileSync( - path.join(link, 'package.json'), - JSON.stringify(readJSON, null, 2) - ) - mkdirp.sync(linkScoped) - writeFileSync( - path.join(linkScoped, 'package.json'), - JSON.stringify(readScopedJSON, null, 2) - ) - mkdirp.sync(linkInstall) - writeFileSync( - path.join(linkInstall, 'package.json'), - JSON.stringify(installJSON, null, 2) - ) - mkdirp.sync(linkInside) - writeFileSync( - path.join(linkInside, 'package.json'), - JSON.stringify(insideInstallJSON, null, 2) - ) - writeFileSync(configPath, config) -} diff --git a/deps/npm/test/tap/locker.js b/deps/npm/test/tap/locker.js index 5ee64196fe9804..1df6fda7102dce 100644 --- a/deps/npm/test/tap/locker.js +++ b/deps/npm/test/tap/locker.js @@ -2,8 +2,6 @@ var test = require('tap').test var path = require('path') var fs = require('graceful-fs') var crypto = require('crypto') -var rimraf = require('rimraf') -var osenv = require('osenv') var mkdirp = require('mkdirp') var npm = require('../../') var locker = require('../../lib/utils/locker.js') @@ -16,13 +14,7 @@ var cache = path.join(pkg, '/cache') var tmp = path.join(pkg, '/tmp') var nm = path.join(pkg, '/node_modules') -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - test('setup', function (t) { - cleanup() mkdirp.sync(cache) mkdirp.sync(tmp) t.end() @@ -83,8 +75,3 @@ test('unlocking out of order errors out', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) diff --git a/deps/npm/test/tap/ls-depth-cli.js b/deps/npm/test/tap/ls-depth-cli.js index 6bb2f3cd124f7f..55142b3ad167b2 100644 --- a/deps/npm/test/tap/ls-depth-cli.js +++ b/deps/npm/test/tap/ls-depth-cli.js @@ -1,11 +1,8 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var Bluebird = require('bluebird') var mr = Bluebird.promisify(require('npm-registry-mock')) -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -29,8 +26,6 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -199,13 +194,3 @@ test('npm ls --depth=1 --parseable --long', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/ls-depth-unmet.js b/deps/npm/test/tap/ls-depth-unmet.js index 7a2ed4dacc2a2e..bf032efe9c9aa0 100644 --- a/deps/npm/test/tap/ls-depth-unmet.js +++ b/deps/npm/test/tap/ls-depth-unmet.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -25,8 +22,6 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -160,13 +155,3 @@ test('npm ls --depth=Infinity', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/ls-env.js b/deps/npm/test/tap/ls-env.js index e3fbece3b04a1b..5d9d7cd06b2cf6 100644 --- a/deps/npm/test/tap/ls-env.js +++ b/deps/npm/test/tap/ls-env.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -22,8 +19,6 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -123,13 +118,3 @@ test('npm ls --only=prod', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/ls-l-depth-0.js b/deps/npm/test/tap/ls-l-depth-0.js index b2516c9fa24496..8e707a1d399b5f 100644 --- a/deps/npm/test/tap/ls-l-depth-0.js +++ b/deps/npm/test/tap/ls-l-depth-0.js @@ -1,13 +1,10 @@ -var cat = require('graceful-fs').writeFileSync +var writeFileSync = require('graceful-fs').writeFileSync var resolve = require('path').resolve var mkdirp = require('mkdirp') var Bluebird = require('bluebird') var mr = Bluebird.promisify(require('npm-registry-mock')) -var rimraf = require('rimraf') var test = require('tap').test -var tmpdir = require('osenv').tmpdir - var common = require('../common-tap.js') var pkg = common.pkg @@ -25,8 +22,6 @@ var expected = ' file:glock-1.8.7.tgz\n' + '\n' -var server - var EXEC_OPTS = { cwd: pkg } var fixture = { @@ -44,9 +39,12 @@ var fixture = { var deppack test('setup', function (t) { - setup() + mkdirp.sync(modules) + mkdirp.sync(dep) + + writeFileSync(resolve(dep, 'package.json'), JSON.stringify(fixture)) return mr({ port: common.port }).then((s) => { - server = s + t.parent.teardown(() => s.close()) return common.npm(['pack', dep], EXEC_OPTS) }).spread((code, stdout) => { t.is(code, 0, 'pack') @@ -100,24 +98,3 @@ test('#6311: npm ll --depth=0 duplicates listing', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - server.close() - - t.end() -}) - -function cleanup () { - process.chdir(tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - - mkdirp.sync(modules) - mkdirp.sync(dep) - - cat(resolve(dep, 'package.json'), JSON.stringify(fixture)) -} diff --git a/deps/npm/test/tap/ls-production-and-dev.js b/deps/npm/test/tap/ls-production-and-dev.js index a39e643786f09e..5836c8fc137146 100644 --- a/deps/npm/test/tap/ls-production-and-dev.js +++ b/deps/npm/test/tap/ls-production-and-dev.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -27,8 +24,6 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -160,13 +155,3 @@ test('npm ls --only=prod', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/no-global-warns.js b/deps/npm/test/tap/no-global-warns.js index 538ab8b359daf9..1c39fd79549c06 100644 --- a/deps/npm/test/tap/no-global-warns.js +++ b/deps/npm/test/tap/no-global-warns.js @@ -2,8 +2,6 @@ var path = require('path') var test = require('tap').test var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var writeFileSync = require('fs').writeFileSync var common = require('../common-tap.js') @@ -38,7 +36,13 @@ var installJSON = { } test('setup', function (t) { - setup() + mkdirp.sync(mockGlobal) + mkdirp.sync(toInstall) + writeFileSync( + path.join(toInstall, 'package.json'), + JSON.stringify(installJSON, null, 2) + ) + writeFileSync(configPath, config) t.end() }) @@ -59,24 +63,3 @@ test('no-global-warns', function (t) { t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - cleanup() - t.end() -}) - -function cleanup () { - rimraf.sync(base) -} - -function setup () { - cleanup() - mkdirp.sync(mockGlobal) - mkdirp.sync(toInstall) - writeFileSync( - path.join(toInstall, 'package.json'), - JSON.stringify(installJSON, null, 2) - ) - writeFileSync(configPath, config) -} diff --git a/deps/npm/test/tap/no-scan-full-global-dir.js b/deps/npm/test/tap/no-scan-full-global-dir.js index 7856ff33f41f2d..7501b881c98cc9 100644 --- a/deps/npm/test/tap/no-scan-full-global-dir.js +++ b/deps/npm/test/tap/no-scan-full-global-dir.js @@ -3,7 +3,6 @@ var fs = require('fs') var path = require('path') var test = require('tap').test var requireInject = require('require-inject') -var osenv = require('osenv') var npm = require('../../lib/npm.js') // XXX update this when rpt's realpath.js is extracted out @@ -25,8 +24,6 @@ Object.keys(packages).forEach(function (name) { files[path.join(packages[name].path, 'package.json')] = packages[name].package }) -process.chdir(osenv.tmpdir()) - var mockReaddir = function (name, cb) { if (dirs[name]) return cb(null, dirs[name]) var er = new Error('No such mock: ' + name) diff --git a/deps/npm/test/tap/optional-metadep-rollback-collision.js b/deps/npm/test/tap/optional-metadep-rollback-collision.js index d665a123bff903..b62d63d7f760f6 100644 --- a/deps/npm/test/tap/optional-metadep-rollback-collision.js +++ b/deps/npm/test/tap/optional-metadep-rollback-collision.js @@ -4,8 +4,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -64,7 +62,7 @@ var opdep_json = { } } -var blart = function () { /* +var blart = ` var rando = require('crypto').randomBytes var resolve = require('path').resolve @@ -116,18 +114,15 @@ mkdirp(BASEDIR, function go () { keepItGoingLouder = {} }, 3 * 1000) }) -*/ }.toString().split('\n').slice(1, -1).join('\n') +` -let badServer -let mockServer test('setup', function (t) { - cleanup() - badServer = createServer(function (req, res) { + const badServer = createServer(function (req, res) { setTimeout(function () { res.writeHead(404) res.end() }, 1000) - }).listen(serverPort) + }).listen(serverPort, () => t.parent.teardown(() => badServer.close())) mkdirp.sync(pkg) fs.writeFileSync( @@ -154,36 +149,36 @@ test('setup', function (t) { JSON.stringify(opdep_json, null, 2) ) mr({ port: common.port }, function (er, server) { - mockServer = server + t.parent.teardown(() => server.close()) t.end() }) }) -test('go go test racer', function (t) { - return common.npm( - [ - '--prefix', pkg, - '--fetch-retries', '0', - '--loglevel', 'error', - '--no-progress', - '--registry', common.registry, - '--parseable', - '--cache', cache, - 'install' - ], - { - cwd: pkg, - env: { - PATH: process.env.PATH, - Path: process.env.Path - }, - stdio: 'pipe' - }).spread((code, stdout, stderr) => { - t.comment(stdout.trim()) - t.comment(stderr.trim()) - t.is(code, 0, 'npm install exited with code 0') - t.notOk(/not ok/.test(stdout), 'should not contain the string \'not ok\'') - }) -}) + +test('go go test racer', t => common.npm( + [ + '--prefix', pkg, + '--fetch-retries', '0', + '--loglevel', 'error', + '--no-progress', + '--registry', common.registry, + '--parseable', + '--cache', cache, + 'install' + ], + { + cwd: pkg, + env: { + PATH: process.env.PATH, + Path: process.env.Path + }, + stdio: 'pipe' + } +).spread((code, stdout, stderr) => { + t.comment(stdout.trim()) + t.comment(stderr.trim()) + t.is(code, 0, 'npm install exited with code 0') + t.notOk(/not ok/.test(stdout), 'should not contain the string \'not ok\'') +})) test('verify results', function (t) { t.throws(function () { @@ -191,16 +186,3 @@ test('verify results', function (t) { }) t.end() }) - -test('cleanup', function (t) { - mockServer.close() - badServer.close() - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/outdated-depth.js b/deps/npm/test/tap/outdated-depth.js index 8e272e60027b16..368d32230abf06 100644 --- a/deps/npm/test/tap/outdated-depth.js +++ b/deps/npm/test/tap/outdated-depth.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../') @@ -22,8 +19,6 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -79,13 +74,3 @@ test('outdated depth zero', function (t) { ) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/peer-deps.js b/deps/npm/test/tap/peer-deps.js index 463a5ec47908d8..558fe9c4e6d965 100644 --- a/deps/npm/test/tap/peer-deps.js +++ b/deps/npm/test/tap/peer-deps.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -23,6 +20,17 @@ var json = { } } +function setup (cb) { + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) + process.chdir(pkg) + + var opts = { cache: common.cache, registry: common.registry } + npm.load(opts, cb) +} + test('installs the peer dependency directory structure', function (t) { mr({ port: common.port }, function (er, s) { setup(function (err) { @@ -42,26 +50,3 @@ test('installs the peer dependency directory structure', function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function setup (cb) { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - process.chdir(pkg) - - var opts = { cache: common.cache, registry: common.registry } - npm.load(opts, cb) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/publish-config.js b/deps/npm/test/tap/publish-config.js index 7d617df2c40326..0d6406316b4a09 100644 --- a/deps/npm/test/tap/publish-config.js +++ b/deps/npm/test/tap/publish-config.js @@ -3,7 +3,6 @@ const common = require('../common-tap.js') const test = require('tap').test const fs = require('fs') -const osenv = require('osenv') const pkg = common.pkg fs.writeFileSync(pkg + '/package.json', JSON.stringify({ @@ -58,7 +57,7 @@ test(function (t) { HOME: process.env.HOME, Path: process.env.PATH, PATH: process.env.PATH, - USERPROFILE: osenv.home() + USERPROFILE: process.env.USERPROFILE } }, function (err, code, stdout, stderr) { t.comment(stdout) diff --git a/deps/npm/test/tap/publish-invalid-semver-tag.js b/deps/npm/test/tap/publish-invalid-semver-tag.js index fed064bb4e0da3..b5d499f3772482 100644 --- a/deps/npm/test/tap/publish-invalid-semver-tag.js +++ b/deps/npm/test/tap/publish-invalid-semver-tag.js @@ -2,54 +2,52 @@ var common = require('../common-tap.js') var test = require('tap').test var npm = require('../../lib/npm.js') var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var path = require('path') var fs = require('fs') var mr = require('npm-registry-mock') -var osenv = require('osenv') - var PKG_DIR = common.pkg -var CACHE_DIR = common.cache +let cacheIteration = 0 +let CACHE_DIR var DEFAULT_PKG = { 'name': 'examples', 'version': '1.2.3' } -var mockServer - -const chownr = require('chownr') -const fixOwner = ( - process.getuid && process.getuid() === 0 && - process.env.SUDO_UID && process.env.SUDO_GID -) ? (path) => chownr.sync(path, +process.env.SUDO_UID, +process.env.SUDO_GID) - : () => {} - +const isRoot = process.getuid && process.getuid() === 0 +const sudoUID = isRoot ? +process.env.SUDO_UID : null +const sudoGID = isRoot ? +process.env.SUDO_GID : null +const { chownSync } = require('fs') function resetPackage (options) { - rimraf.sync(CACHE_DIR) + CACHE_DIR = path.resolve(common.cache, '' + cacheIteration++) mkdirp.sync(CACHE_DIR) - fixOwner(CACHE_DIR) + npm.config.set('cache', CACHE_DIR) + + if (isRoot && sudoUID && sudoGID) { + chownSync(CACHE_DIR, sudoUID, sudoGID) + } fs.writeFileSync(path.resolve(PKG_DIR, 'package.json'), DEFAULT_PKG) } test('setup', function (t) { - process.chdir(osenv.tmpdir()) mkdirp.sync(PKG_DIR) process.chdir(PKG_DIR) - resetPackage({}) - mr({ port: common.port }, function (er, server) { + if (er) { + throw er + } + t.parent.teardown(() => server.close()) npm.load({ - cache: CACHE_DIR, + cache: common.cache, registry: common.registry, cwd: PKG_DIR }, function (err) { - t.ifError(err, 'started server') - mockServer = server - + if (err) { + throw err + } t.end() }) }) @@ -76,12 +74,3 @@ test('attempt publish with semver-like version', function (t) { t.end() }) }) - -test('cleanup', function (t) { - mockServer.close() - - process.chdir(osenv.tmpdir()) - rimraf.sync(PKG_DIR) - - t.end() -}) diff --git a/deps/npm/test/tap/repo.js b/deps/npm/test/tap/repo.js index 0ee50af192cb19..3e97fdeaed2283 100644 --- a/deps/npm/test/tap/repo.js +++ b/deps/npm/test/tap/repo.js @@ -41,6 +41,41 @@ test('npm repo underscore', function (t) { }) }) +test('npm repo underscore --json', function (t) { + mr({ port: common.port }, function (er, s) { + common.npm([ + 'repo', 'underscore', + '--json', + '--registry=' + common.registry, + '--loglevel=silent', + '--no-browser' + ], opts, function (err, code, stdout, stderr) { + t.ifError(err, 'repo command ran without error') + t.equal(code, 0, 'exit ok') + t.matchSnapshot(stdout, 'should print json result') + s.close() + t.end() + }) + }) +}) + +test('npm repo underscore --no-browser', function (t) { + mr({ port: common.port }, function (er, s) { + common.npm([ + 'repo', 'underscore', + '--no-browser', + '--registry=' + common.registry, + '--loglevel=silent' + ], opts, function (err, code, stdout, stderr) { + t.ifError(err, 'repo command ran without error') + t.equal(code, 0, 'exit ok') + t.matchSnapshot(stdout, 'should print alternative msg') + s.close() + t.end() + }) + }) +}) + test('npm repo optimist - github (https://)', function (t) { mr({ port: common.port }, function (er, s) { common.npm([ diff --git a/deps/npm/test/tap/scripts-whitespace-windows.js b/deps/npm/test/tap/scripts-whitespace-windows.js index 06f06e36eb2a69..9a301dca526d05 100644 --- a/deps/npm/test/tap/scripts-whitespace-windows.js +++ b/deps/npm/test/tap/scripts-whitespace-windows.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -43,7 +41,6 @@ if (process.argv.length === 8) */ }.toString().split('\n').slice(1, -1).join('\n') test('setup', function (t) { - cleanup() mkdirp.sync(tmp) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -89,13 +86,3 @@ test('test', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/semver-doc.js b/deps/npm/test/tap/semver-doc.js index 31c75fffd8ad7b..1cc978201c7a47 100644 --- a/deps/npm/test/tap/semver-doc.js +++ b/deps/npm/test/tap/semver-doc.js @@ -3,7 +3,7 @@ var test = require('tap').test test('semver doc is up to date', function (t) { var path = require('path') var moddoc = path.join(__dirname, '../../node_modules/semver/README.md') - var mydoc = path.join(__dirname, '../../doc/misc/semver.md') + var mydoc = path.join(__dirname, '../../docs/content/using-npm/semver.md') var fs = require('fs') var mod = fs.readFileSync(moddoc, 'utf8').replace(/semver\(1\)/, 'semver(7)') var my = fs.readFileSync(mydoc, 'utf8') diff --git a/deps/npm/test/tap/shrinkwrap-_auth.js b/deps/npm/test/tap/shrinkwrap-_auth.js index 156bd9667cb83f..2987e3eec0ace8 100644 --- a/deps/npm/test/tap/shrinkwrap-_auth.js +++ b/deps/npm/test/tap/shrinkwrap-_auth.js @@ -5,11 +5,10 @@ var path = require('path') var writeFileSync = require('graceful-fs').writeFileSync var mkdirp = require('mkdirp') -var osenv = require('osenv') var http = require('http') -var rimraf = require('rimraf') var ssri = require('ssri') -var test = require('tap').test +var t = require('tap') +var test = t.test var common = require('../common-tap.js') @@ -23,7 +22,34 @@ var tarball = path.resolve(__dirname, '../fixtures/scoped-underscore-1.3.1.tgz') var tarballIntegrity = ssri.fromData(fs.readFileSync(tarball)).toString() var _auth = '0xabad1dea' + +var contents = '_auth=' + _auth + '\n' + + '\'always-auth\'=true\n' + +var json = { + name: 'test-package-install', + version: '1.0.0', + dependencies: { + '@scoped/underscore': '1.0.0' + } +} + +var shrinkwrap = { + name: 'test-package-install', + version: '1.0.0', + lockfileVersion: 1, + dependencies: { + '@scoped/underscore': { + resolved: tarballURL, + integrity: tarballIntegrity, + version: '1.3.1' + } + } +} + var server = http.createServer() +t.teardown(() => server.close()) + const errors = [] server.on('request', (req, res) => { const auth = 'Basic ' + _auth @@ -44,10 +70,14 @@ server.on('request', (req, res) => { }) test('setup', function (t) { - server.listen(common.port, () => { - setup() - t.done() - }) + mkdirp.sync(modules) + writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') + writeFileSync(outfile, contents) + writeFileSync( + path.resolve(pkg, 'npm-shrinkwrap.json'), + JSON.stringify(shrinkwrap, null, 2) + '\n' + ) + server.listen(common.port, t.end) }) test('authed npm install with shrinkwrapped global package using _auth', function (t) { @@ -77,50 +107,3 @@ test('authed npm install with shrinkwrapped global package using _auth', functio } ) }) - -test('cleanup', function (t) { - server.close(() => { - cleanup() - t.end() - }) -}) - -var contents = '_auth=' + _auth + '\n' + - '\'always-auth\'=true\n' - -var json = { - name: 'test-package-install', - version: '1.0.0', - dependencies: { - '@scoped/underscore': '1.0.0' - } -} - -var shrinkwrap = { - name: 'test-package-install', - version: '1.0.0', - lockfileVersion: 1, - dependencies: { - '@scoped/underscore': { - resolved: tarballURL, - integrity: tarballIntegrity, - version: '1.3.1' - } - } -} - -function setup () { - cleanup() - mkdirp.sync(modules) - writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') - writeFileSync(outfile, contents) - writeFileSync( - path.resolve(pkg, 'npm-shrinkwrap.json'), - JSON.stringify(shrinkwrap, null, 2) + '\n' - ) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-dev-dependency.js b/deps/npm/test/tap/shrinkwrap-dev-dependency.js index 066372e617105d..973cb5435b8f24 100644 --- a/deps/npm/test/tap/shrinkwrap-dev-dependency.js +++ b/deps/npm/test/tap/shrinkwrap-dev-dependency.js @@ -1,10 +1,7 @@ var fs = require('fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -46,26 +43,11 @@ var json = { } } -function setup () { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2)) - process.chdir(pkg) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -test('setup', function (t) { - setup() - t.end() -}) - test("shrinkwrap doesn't strip out the dependency", function (t) { t.plan(3) - setup() + + fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2)) + process.chdir(pkg) mr({port: common.port}, function (er, s) { common.npm(opts.concat(['install', '.']), {stdio: [0, 'pipe', 2]}, function (err, code) { @@ -86,8 +68,3 @@ test("shrinkwrap doesn't strip out the dependency", function (t) { }) }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) diff --git a/deps/npm/test/tap/shrinkwrap-empty-deps.js b/deps/npm/test/tap/shrinkwrap-empty-deps.js index af9b4810afaf61..3c68845745a943 100644 --- a/deps/npm/test/tap/shrinkwrap-empty-deps.js +++ b/deps/npm/test/tap/shrinkwrap-empty-deps.js @@ -2,11 +2,8 @@ const common = require('../common-tap.js') const fs = require('fs') -const mkdirp = require('mkdirp') const mr = require('npm-registry-mock') -const osenv = require('osenv') const path = require('path') -const rimraf = require('rimraf') const test = require('tap').test const pkg = common.pkg @@ -22,8 +19,6 @@ const json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -61,14 +56,3 @@ test('returns a list of removed items', function (t) { ) }) }) - -test('cleanup', function (t) { - cleanup() - - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-extra-metadata.js b/deps/npm/test/tap/shrinkwrap-extra-metadata.js index a5ff721a7a8160..6e652e2db07147 100644 --- a/deps/npm/test/tap/shrinkwrap-extra-metadata.js +++ b/deps/npm/test/tap/shrinkwrap-extra-metadata.js @@ -2,12 +2,9 @@ const common = require('../common-tap.js') const fs = require('fs') -const mkdirp = require('mkdirp') const mr = require('npm-registry-mock') const npm = require('../../lib/npm.js') -const osenv = require('osenv') const path = require('path') -const rimraf = require('rimraf') const test = require('tap').test const pkg = common.pkg @@ -19,8 +16,6 @@ const json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) @@ -32,6 +27,7 @@ test('setup', function (t) { test('adds additional metadata fields from the pkglock spec', function (t) { mr({ port: common.port }, function (er, s) { + t.teardown(() => s.close()) common.npm( [ '--registry', common.registry, @@ -56,21 +52,9 @@ test('adds additional metadata fields from the pkglock spec', function (t) { 'shrinkwrap wrote the expected metadata fields' ) - s.close() t.end() }) } ) }) }) - -test('cleanup', function (t) { - cleanup() - - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-global-auth.js b/deps/npm/test/tap/shrinkwrap-global-auth.js index e860abd2fe1a85..e14a328a43a518 100644 --- a/deps/npm/test/tap/shrinkwrap-global-auth.js +++ b/deps/npm/test/tap/shrinkwrap-global-auth.js @@ -6,8 +6,6 @@ var writeFileSync = require('graceful-fs').writeFileSync var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var ssri = require('ssri') var test = require('tap').test @@ -22,7 +20,30 @@ var tarballURL = common.registry + tarballPath var tarball = path.resolve(__dirname, '../fixtures/scoped-underscore-1.3.1.tgz') var tarballIntegrity = ssri.fromData(fs.readFileSync(tarball)).toString() -var server +var contents = 'registry=' + common.registry + '\n' + + '_authToken=0xabad1dea\n' + + '\'always-auth\'=true\n' + +var json = { + name: 'test-package-install', + version: '1.0.0', + dependencies: { + '@scoped/underscore': '1.0.0' + } +} + +var shrinkwrap = { + name: 'test-package-install', + version: '1.0.0', + lockfileVersion: 1, + dependencies: { + '@scoped/underscore': { + resolved: tarballURL, + integrity: tarballIntegrity, + version: '1.3.1' + } + } +} function mocks (server) { var auth = 'Bearer 0xabad1dea' @@ -34,10 +55,16 @@ function mocks (server) { } test('setup', function (t) { + mkdirp.sync(modules) + writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') + writeFileSync(outfile, contents) + writeFileSync( + path.resolve(pkg, 'npm-shrinkwrap.json'), + JSON.stringify(shrinkwrap, null, 2) + '\n' + ) mr({ port: common.port, plugin: mocks }, function (er, s) { - server = s + t.parent.teardown(() => s.close()) t.ok(s, 'set up mock registry') - setup() t.end() }) }) @@ -68,50 +95,3 @@ test('authed npm install with shrinkwrapped global package', function (t) { } ) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -var contents = 'registry=' + common.registry + '\n' + - '_authToken=0xabad1dea\n' + - '\'always-auth\'=true\n' - -var json = { - name: 'test-package-install', - version: '1.0.0', - dependencies: { - '@scoped/underscore': '1.0.0' - } -} - -var shrinkwrap = { - name: 'test-package-install', - version: '1.0.0', - lockfileVersion: 1, - dependencies: { - '@scoped/underscore': { - resolved: tarballURL, - integrity: tarballIntegrity, - version: '1.3.1' - } - } -} - -function setup () { - cleanup() - mkdirp.sync(modules) - writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') - writeFileSync(outfile, contents) - writeFileSync( - path.resolve(pkg, 'npm-shrinkwrap.json'), - JSON.stringify(shrinkwrap, null, 2) + '\n' - ) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-lifecycle.js b/deps/npm/test/tap/shrinkwrap-lifecycle.js index 5ed35e186843b2..6e6bc4c2872b2a 100644 --- a/deps/npm/test/tap/shrinkwrap-lifecycle.js +++ b/deps/npm/test/tap/shrinkwrap-lifecycle.js @@ -1,16 +1,10 @@ var fs = require('graceful-fs') var path = require('path') - -var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test - var common = require('../common-tap.js') var pkg = common.pkg test('npm shrinkwrap execution order', function (t) { - setup() fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ author: 'Simen Bekkhus', name: 'shrinkwrap-lifecycle', @@ -22,7 +16,7 @@ test('npm shrinkwrap execution order', function (t) { postshrinkwrap: 'echo this happens third' } }), 'utf8') - common.npm(['shrinkwrap', '--loglevel=error'], [], function (err, code, stdout, stderr) { + common.npm(['shrinkwrap', '--loglevel=error'], { cwd: pkg }, function (err, code, stdout, stderr) { if (err) throw err t.comment(stdout) @@ -41,14 +35,3 @@ test('npm shrinkwrap execution order', function (t) { t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) - -function setup () { - mkdirp.sync(pkg) - process.chdir(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-optional-dependency.js b/deps/npm/test/tap/shrinkwrap-optional-dependency.js index 621e6c4c595e16..a08d1538490db9 100644 --- a/deps/npm/test/tap/shrinkwrap-optional-dependency.js +++ b/deps/npm/test/tap/shrinkwrap-optional-dependency.js @@ -3,8 +3,6 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -22,17 +20,17 @@ test('shrinkwrap does not fail on missing optional dependency', function (t) { } mr({port: common.port, mocks: mocks}, function (er, s) { - function fail (err) { - s.close() // Close on failure to allow node to exit - t.fail(err) - } - + t.parent.teardown(() => s.close()) setup(function (err) { - if (err) return fail(err) + if (err) { + throw err + } // Install without the optional dependency npm.install('.', function (err) { - if (err) return fail(err) + if (err) { + throw err + } // Pretend the optional dependency was specified, but somehow failed to load: json.optionalDependencies = { @@ -41,7 +39,9 @@ test('shrinkwrap does not fail on missing optional dependency', function (t) { writePackage() npm.commands.shrinkwrap([], true, function (err, results) { - if (err) return fail(err) + if (err) { + throw err + } t.deepEqual(results.dependencies, desired.dependencies) s.close() @@ -52,11 +52,6 @@ test('shrinkwrap does not fail on missing optional dependency', function (t) { }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - var desired = { name: 'npm-test-shrinkwrap-optional-dependency', version: '0.0.0', @@ -83,19 +78,14 @@ function writePackage () { } function setup (cb) { - cleanup() mkdirp.sync(pkg) writePackage() process.chdir(pkg) var opts = { cache: common.cache, - registry: common.registry + registry: common.registry, + cwd: pkg } npm.load(opts, cb) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-optional-property.js b/deps/npm/test/tap/shrinkwrap-optional-property.js index f9b37f2f30e194..c2dc8585aec1cf 100644 --- a/deps/npm/test/tap/shrinkwrap-optional-property.js +++ b/deps/npm/test/tap/shrinkwrap-optional-property.js @@ -1,10 +1,7 @@ var fs = require('fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -16,22 +13,24 @@ test('shrinkwrap adds optional property when optional dependency', function (t) t.plan(1) mr({port: common.port}, function (er, s) { - function fail (err) { - s.close() // Close on failure to allow node to exit - t.fail(err) - } - + t.parent.teardown(() => s.close()) setup(function (err) { - if (err) return fail(err) + if (err) { + throw err + } // Install with the optional dependency npm.install('.', function (err) { - if (err) return fail(err) + if (err) { + throw err + } writePackage() npm.commands.shrinkwrap([], true, function (err, results) { - if (err) return fail(err) + if (err) { + throw err + } t.deepEqual(results.dependencies, desired.dependencies) s.close() @@ -42,11 +41,6 @@ test('shrinkwrap adds optional property when optional dependency', function (t) }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - var desired = { name: 'npm-test-shrinkwrap-optional-dependency', version: '0.0.0', @@ -82,8 +76,6 @@ function writePackage () { } function setup (cb) { - cleanup() - mkdirp.sync(pkg) writePackage() process.chdir(pkg) @@ -93,8 +85,3 @@ function setup (cb) { } npm.load(opts, cb) } - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js b/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js index 96ebe2249e1c75..1e4e9d7438a2c8 100644 --- a/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js +++ b/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js @@ -1,10 +1,7 @@ var fs = require('fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -21,13 +18,42 @@ function reportOutput (t, fh, out) { t.comment(prefix + trimmed.split(/\n/).join('\n' + prefix)) } -var server +var desired = { + name: 'npm-test-shrinkwrap-prod-dependency', + version: '0.0.0', + dependencies: { + request: { + version: '0.9.0', + resolved: common.registry + '/request/-/request-0.9.0.tgz', + integrity: 'sha1-EEn1mm9GWI5tAwkh+7hMovDCcU4=' + }, + underscore: { + dev: true, + version: '1.5.1', + resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz', + integrity: 'sha1-0r3oF9F2/63olKtxRY5oKhS4bck=' + } + } +} + +var json = { + author: 'Domenic Denicola', + name: 'npm-test-shrinkwrap-prod-dependency', + version: '0.0.0', + dependencies: { + request: '0.9.0' + }, + devDependencies: { + underscore: '1.5.1' + } +} + test("shrinkwrap --also=development doesn't strip out prod dependencies", function (t) { t.plan(4) mr({port: common.port}, function (er, s) { - server = s - setup() + t.parent.teardown(() => s.close()) + fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2)) common.npm(['install', '.'].concat(opts), {cwd: pkg}, function (err, code, stdout, stderr) { if (err) return t.fail(err) t.is(code, 0, 'install') @@ -57,50 +83,3 @@ test("shrinkwrap --also=development doesn't strip out prod dependencies", functi }) }) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -var desired = { - name: 'npm-test-shrinkwrap-prod-dependency', - version: '0.0.0', - dependencies: { - request: { - version: '0.9.0', - resolved: common.registry + '/request/-/request-0.9.0.tgz', - integrity: 'sha1-EEn1mm9GWI5tAwkh+7hMovDCcU4=' - }, - underscore: { - dev: true, - version: '1.5.1', - resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz', - integrity: 'sha1-0r3oF9F2/63olKtxRY5oKhS4bck=' - } - } -} - -var json = { - author: 'Domenic Denicola', - name: 'npm-test-shrinkwrap-prod-dependency', - version: '0.0.0', - dependencies: { - request: '0.9.0' - }, - devDependencies: { - underscore: '1.5.1' - } -} - -function setup (opts) { - cleanup() - mkdirp.sync(pkg) - fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2)) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/shrinkwrap-prod-dependency.js b/deps/npm/test/tap/shrinkwrap-prod-dependency.js index 6c175af819bcd6..bf6d98bf801521 100644 --- a/deps/npm/test/tap/shrinkwrap-prod-dependency.js +++ b/deps/npm/test/tap/shrinkwrap-prod-dependency.js @@ -3,8 +3,6 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../') @@ -12,34 +10,6 @@ var npm = require('../../') var common = require('../common-tap.js') var pkg = common.pkg -test("shrinkwrap --dev doesn't strip out prod dependencies", function (t) { - t.plan(1) - - mr({port: common.port}, function (er, s) { - setup({}, function (err) { - if (err) return t.fail(err) - - npm.install('.', function (err) { - if (err) return t.fail(err) - - npm.config.set('dev', true) - npm.commands.shrinkwrap([], true, function (err, results) { - if (err) return t.fail(err) - - t.deepEqual(results.dependencies, desired.dependencies) - s.close() - t.end() - }) - }) - }) - }) -}) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - var desired = { name: 'npm-test-shrinkwrap-prod-dependency', version: '0.0.0', @@ -70,8 +40,7 @@ var json = { } } -function setup (opts, cb) { - cleanup() +test('setup', function (t) { mkdirp.sync(pkg) fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2)) process.chdir(pkg) @@ -81,14 +50,27 @@ function setup (opts, cb) { registry: common.registry } - for (var key in opts) { - allOpts[key] = opts[key] - } + npm.load(allOpts, t.end) +}) - npm.load(allOpts, cb) -} +test('mock registry', t => { + mr({port: common.port}, function (er, s) { + t.parent.teardown(() => s.close()) + t.end() + }) +}) -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} +test("shrinkwrap --dev doesn't strip out prod dependencies", t => { + t.plan(1) + npm.install('.', function (err) { + if (err) return t.fail(err) + + npm.config.set('dev', true) + npm.commands.shrinkwrap([], true, function (err, results) { + if (err) return t.fail(err) + + t.deepEqual(results.dependencies, desired.dependencies) + t.end() + }) + }) +}) diff --git a/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js b/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js index a71408e54f5ab1..1c35bf226b9136 100644 --- a/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js +++ b/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js @@ -1,12 +1,8 @@ /* eslint-disable camelcase */ var fs = require('fs') var path = require('path') - var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test - var common = require('../common-tap.js') var base = common.pkg @@ -74,7 +70,6 @@ function writeJson (filename, obj) { } test('setup', function (t) { - cleanup() writeJson(installme_pkg, installme_pkg_json) writeJson(example_pkg, example_pkg_json) writeJson(example_shrinkwrap, example_shrinkwrap_json) @@ -95,13 +90,3 @@ test('install --save-dev leaves prod deps alone', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} diff --git a/deps/npm/test/tap/shrinkwrap-save-with-existing-dev-deps.js b/deps/npm/test/tap/shrinkwrap-save-with-existing-dev-deps.js index 8a3f449fa88653..acf6ac21014d15 100644 --- a/deps/npm/test/tap/shrinkwrap-save-with-existing-dev-deps.js +++ b/deps/npm/test/tap/shrinkwrap-save-with-existing-dev-deps.js @@ -3,8 +3,6 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -63,7 +61,6 @@ function writeJson (filename, obj) { } test('setup', function (t) { - cleanup() writeJson(installme_pkg, installme_pkg_json) writeJson(example_pkg, example_pkg_json) writeJson(example_shrinkwrap, example_shrinkwrap_json) @@ -71,24 +68,12 @@ test('setup', function (t) { t.end() }) -test('install --save leaves dev deps alone', function (t) { - common.npm(['install', '--save', 'file://' + installme], EXEC_OPTS, function (er, code, stdout, stderr) { - t.ifError(er, "spawn didn't catch fire") - t.is(code, 0, 'install completed ok') - t.is(stderr, '', 'install completed without error output') - var shrinkwrap = JSON.parse(fs.readFileSync(example_shrinkwrap)) - t.ok(shrinkwrap.dependencies.installed, "save new install didn't remove dev dep") - t.ok(shrinkwrap.dependencies.installme, 'save new install DID add new dep') - t.end() - }) -}) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(base) -} +test('install --save leaves dev deps alone', t => + common.npm(['install', '--save', 'file://' + installme], EXEC_OPTS) + .then(([code, stdout, stderr]) => { + t.is(code, 0, 'install completed ok') + t.is(stderr, '', 'install completed without error output') + var shrinkwrap = JSON.parse(fs.readFileSync(example_shrinkwrap)) + t.ok(shrinkwrap.dependencies.installed, "save new install didn't remove dev dep") + t.ok(shrinkwrap.dependencies.installme, 'save new install DID add new dep') + })) diff --git a/deps/npm/test/tap/shrinkwrap-scoped-auth.js b/deps/npm/test/tap/shrinkwrap-scoped-auth.js index 3098b8aa12e93e..cc1b2270012ec6 100644 --- a/deps/npm/test/tap/shrinkwrap-scoped-auth.js +++ b/deps/npm/test/tap/shrinkwrap-scoped-auth.js @@ -6,8 +6,6 @@ var writeFileSync = require('graceful-fs').writeFileSync var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var ssri = require('ssri') var test = require('tap').test @@ -22,8 +20,6 @@ var tarballURL = common.registry + tarballPath var tarball = path.resolve(__dirname, '../fixtures/scoped-underscore-1.3.1.tgz') var tarballIntegrity = ssri.fromData(fs.readFileSync(tarball)).toString() -var server - function mocks (server) { var auth = 'Bearer 0xabad1dea' server.get(tarballPath, { authorization: auth }).replyWithFile(200, tarball) @@ -33,11 +29,41 @@ function mocks (server) { }) } +var contents = '@scoped:registry=' + common.registry + '\n' + + toNerfDart(common.registry) + ':_authToken=0xabad1dea\n' + +var json = { + name: 'test-package-install', + version: '1.0.0', + dependencies: { + '@scoped/underscore': '1.0.0' + } +} + +var shrinkwrap = { + name: 'test-package-install', + version: '1.0.0', + lockfileVersion: 1, + dependencies: { + '@scoped/underscore': { + resolved: tarballURL, + integrity: tarballIntegrity, + version: '1.3.1' + } + } +} + test('setup', function (t) { + mkdirp.sync(modules) + writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') + writeFileSync(outfile, contents) + writeFileSync( + path.resolve(pkg, 'npm-shrinkwrap.json'), + JSON.stringify(shrinkwrap, null, 2) + '\n' + ) mr({ port: common.port, plugin: mocks }, function (er, s) { - server = s + t.parent.teardown(() => s.close()) t.ok(s, 'set up mock registry') - setup() t.end() }) }) @@ -68,49 +94,3 @@ test('authed npm install with shrinkwrapped scoped package', function (t) { } ) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -var contents = '@scoped:registry=' + common.registry + '\n' + - toNerfDart(common.registry) + ':_authToken=0xabad1dea\n' - -var json = { - name: 'test-package-install', - version: '1.0.0', - dependencies: { - '@scoped/underscore': '1.0.0' - } -} - -var shrinkwrap = { - name: 'test-package-install', - version: '1.0.0', - lockfileVersion: 1, - dependencies: { - '@scoped/underscore': { - resolved: tarballURL, - integrity: tarballIntegrity, - version: '1.3.1' - } - } -} - -function setup () { - cleanup() - mkdirp.sync(modules) - writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify(json, null, 2) + '\n') - writeFileSync(outfile, contents) - writeFileSync( - path.resolve(pkg, 'npm-shrinkwrap.json'), - JSON.stringify(shrinkwrap, null, 2) + '\n' - ) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/startstop.js b/deps/npm/test/tap/startstop.js index 3491441821d921..dd07352e0dc813 100644 --- a/deps/npm/test/tap/startstop.js +++ b/deps/npm/test/tap/startstop.js @@ -2,8 +2,6 @@ var fs = require('graceful-fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') @@ -33,7 +31,6 @@ function testOutput (t, command, er, code, stdout, stderr) { } test('setup', function (t) { - cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), @@ -62,13 +59,3 @@ test('npm restart', function (t) { t.end() }) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/symlink-cycle.js b/deps/npm/test/tap/symlink-cycle.js index d59a2763bd19c8..ea0c0f53594439 100644 --- a/deps/npm/test/tap/symlink-cycle.js +++ b/deps/npm/test/tap/symlink-cycle.js @@ -3,8 +3,6 @@ var fs = require('fs') var path = require('path') var test = require('tap').test var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var writeFileSync = require('fs').writeFileSync var common = require('../common-tap.js') @@ -27,7 +25,12 @@ var cycleJSON = { } test('setup', function (t) { - setup() + mkdirp.sync(path.join(cycle, 'node_modules')) + writeFileSync( + path.join(cycle, 'package.json'), + JSON.stringify(cycleJSON, null, 2) + ) + fs.symlinkSync(cycle, path.join(cycle, 'node_modules', 'cycle'), 'junction') t.end() }) @@ -39,23 +42,3 @@ test('ls', function (t) { t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - cleanup() - t.end() -}) - -function cleanup () { - rimraf.sync(base) -} - -function setup () { - cleanup() - mkdirp.sync(path.join(cycle, 'node_modules')) - writeFileSync( - path.join(cycle, 'package.json'), - JSON.stringify(cycleJSON, null, 2) - ) - fs.symlinkSync(cycle, path.join(cycle, 'node_modules', 'cycle'), 'junction') -} diff --git a/deps/npm/test/tap/team.js b/deps/npm/test/tap/team.js index 939da45b77883a..17acf82f4b231f 100644 --- a/deps/npm/test/tap/team.js +++ b/deps/npm/test/tap/team.js @@ -88,6 +88,29 @@ test('team destroy', function (t) { }) }) +test('team destroy is not allowed for the default developers team', (t) => { + const teamData = { + name: 'developers', + scope_id: 1234, + created: '2015-07-23T18:07:49.959Z', + updated: '2015-07-23T18:07:49.959Z', + deleted: '2015-07-23T18:27:27.178Z' + } + server.delete('/-/team/myorg/' + teamData.name).reply(405, teamData) + common.npm([ + 'team', 'destroy', 'myorg:' + teamData.name, + '--registry', common.registry, + '--loglevel', 'silent', + '--json' + ], {}, function (err, code, stdout, stderr) { + t.ifError(err, 'npm team') + t.equal(code, 1, 'exited with code 1') + t.equal(stderr, '', 'no error output') + t.match(JSON.parse(stdout), {error: {code: 'E405'}}) + t.end() + }) +}) + test('team add', function (t) { var user = 'zkat' server.put('/-/team/myorg/myteam/user', JSON.stringify({ diff --git a/deps/npm/test/tap/uninstall-package.js b/deps/npm/test/tap/uninstall-package.js index 87fdee22816975..3e0b404b6c4573 100644 --- a/deps/npm/test/tap/uninstall-package.js +++ b/deps/npm/test/tap/uninstall-package.js @@ -1,10 +1,7 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -24,14 +21,10 @@ var json = { } test('setup', function (t) { - cleanup() - mkdirp.sync(pkg) - process.chdir(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) - t.end() }) @@ -90,13 +83,3 @@ test('does not fail if installed package lacks a name somehow', function (t) { } ) }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} diff --git a/deps/npm/test/tap/uninstall-save.js b/deps/npm/test/tap/uninstall-save.js index 0605616e07f03e..bf1683edcab2cc 100644 --- a/deps/npm/test/tap/uninstall-save.js +++ b/deps/npm/test/tap/uninstall-save.js @@ -3,12 +3,10 @@ var path = require('path') var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') -var server var pkg = common.pkg @@ -20,10 +18,14 @@ var json = { } test('setup', function (t) { - setup() + mkdirp.sync(path.resolve(pkg, 'node_modules')) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify(json, null, 2) + ) mr({ port: common.port }, function (er, s) { t.ifError(er, 'started mock registry') - server = s + t.parent.teardown(() => s.close()) t.end() }) }) @@ -68,25 +70,3 @@ test('uninstall --save removes rm-ed package from package.json', function (t) { ) }) }) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() -}) - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(path.resolve(pkg, 'node_modules')) - fs.writeFileSync( - path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) - ) - - process.chdir(pkg) -} diff --git a/deps/npm/test/tap/unpack-foreign-tarball.js b/deps/npm/test/tap/unpack-foreign-tarball.js index 7e965d9f08acce..b3a9026f84ab20 100644 --- a/deps/npm/test/tap/unpack-foreign-tarball.js +++ b/deps/npm/test/tap/unpack-foreign-tarball.js @@ -1,9 +1,8 @@ var fs = require('graceful-fs') var path = require('path') -var test = require('tap').test +var t = require('tap') var mkdirp = require('mkdirp') -var osenv = require('osenv') var rimraf = require('rimraf') var common = require('../common-tap.js') @@ -24,64 +23,62 @@ var EXEC_OPTS = { cwd: pkg } -function verify (t, files, err, code) { +function verify (t, files, code) { if (code) { - t.fail('exited with failure: ' + code) - return t.end() + return t.fail('exited with failure: ' + code) } var actual = fs.readdirSync(target).sort() var expect = files.concat(['.npmignore', 'package.json']).sort() t.same(actual, expect) - t.end() } -test('setup', function (t) { - setup() - t.comment('test for https://github.com/npm/npm/issues/5658') - t.end() -}) +t.comment('test for https://github.com/npm/npm/issues/5658') -test('npmignore only', function (t) { +t.test('npmignore only', function (t) { + t.test('setup', setup) var file = path.resolve(fixtures, 'npmignore.tgz') - common.npm(['install', file], EXEC_OPTS, verify.bind(null, t, ['foo'])) + return t.test('test', t => common.npm(['install', file], EXEC_OPTS) + .then(([code]) => verify(t, ['foo'], code))) }) -test('gitignore only', function (t) { - setup() +t.test('gitignore only', function (t) { + t.test('setup', setup) var file = path.resolve(fixtures, 'gitignore.tgz') - common.npm(['install', file], EXEC_OPTS, verify.bind(null, t, ['foo'])) + return t.test('test', t => common.npm(['install', file], EXEC_OPTS) + .then(([code]) => verify(t, ['foo'], code))) }) -test('gitignore and npmignore', function (t) { - setup() +t.test('gitignore and npmignore', function (t) { + t.test('setup', setup) var file = path.resolve(fixtures, 'gitignore-and-npmignore.tgz') - common.npm(['install', file], EXEC_OPTS, verify.bind(null, t, ['foo', 'bar'])) + return t.test('test', t => common.npm(['install', file], EXEC_OPTS) + .then(([code]) => verify(t, ['foo', 'bar'], code))) }) -test('gitignore and npmignore, not gzipped 1/2', function (t) { - setup() +t.test('gitignore and npmignore, not gzipped 1/2', function (t) { + t.test('setup', setup) var file = path.resolve(fixtures, 'gitignore-and-npmignore.tar') - common.npm(['install', file], EXEC_OPTS, verify.bind(null, t, ['foo', 'bar'])) + return t.test('test', t => common.npm(['install', file], EXEC_OPTS) + .then(([code]) => verify(t, ['foo', 'bar'], code))) }) -test('gitignore and npmignore, not gzipped 2/2', function (t) { - setup() +t.test('gitignore and npmignore, not gzipped 2/2', function (t) { + t.test('setup', setup) var file = path.resolve(fixtures, 'gitignore-and-npmignore-2.tar') - common.npm(['install', file], EXEC_OPTS, verify.bind(null, t, ['foo', 'bar'])) + return t.test('test', t => common.npm(['install', file], EXEC_OPTS) + .then(([code]) => verify(t, ['foo', 'bar'], code))) }) -test('cleanup', function (t) { - cleanup() +function setup (t) { + t.test('destroy', t => { + t.plan(2) + t.test('node_modules', t => rimraf(nm, t.end)) + t.test('tmp', t => rimraf(tmp, t.end)) + }) + t.test('create', t => { + mkdirp.sync(nm) + mkdirp.sync(tmp) + t.end() + }) t.end() -}) - -function setup () { - cleanup() - mkdirp.sync(nm) - mkdirp.sync(tmp) -} - -function cleanup () { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) } diff --git a/deps/npm/test/tap/unpublish-config.js b/deps/npm/test/tap/unpublish-config.js index f358835561eee8..6d5c981d08d958 100644 --- a/deps/npm/test/tap/unpublish-config.js +++ b/deps/npm/test/tap/unpublish-config.js @@ -2,9 +2,6 @@ var fs = require('graceful-fs') var http = require('http') var path = require('path') -var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') @@ -18,8 +15,6 @@ var json = { } test('setup', function (t) { - mkdirp.sync(pkg) - fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json), 'utf8' @@ -63,7 +58,7 @@ test('cursory test of unpublishing with config', function (t) { HOME: process.env.HOME, Path: process.env.PATH, PATH: process.env.PATH, - USERPROFILE: osenv.home() + USERPROFILE: process.env.USERPROFILE } }, function (err, code) { @@ -73,9 +68,3 @@ test('cursory test of unpublishing with config', function (t) { ) }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) diff --git a/deps/npm/test/tap/update-examples.js b/deps/npm/test/tap/update-examples.js index 8b6323ff1c71ac..2217386de8d23f 100644 --- a/deps/npm/test/tap/update-examples.js +++ b/deps/npm/test/tap/update-examples.js @@ -1,11 +1,7 @@ var common = require('../common-tap.js') var test = require('tap').test var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var mr = require('npm-registry-mock') - -var osenv = require('osenv') - var requireInject = require('require-inject') var PKG_DIR = common.pkg @@ -64,7 +60,6 @@ var registryMocks = { } // ** dynamic mocks, cloned from templates and modified ** -var mockServer var mockDepJson = clone(DEP_PKG) var mockInstalled = clone(INSTALLED) var mockParentJson = clone(DEFAULT_PKG) @@ -83,17 +78,20 @@ function extend (a, b) { return a } -const chownr = require('chownr') -const fixOwner = ( - process.getuid && process.getuid() === 0 && - process.env.SUDO_UID && process.env.SUDO_GID -) ? (path) => chownr.sync(path, +process.env.SUDO_UID, +process.env.SUDO_GID) - : () => {} - +const path = require('path') +let cacheIteration = 0 +const isRoot = process.getuid && process.getuid() === 0 +const sudoUID = isRoot ? +process.env.SUDO_UID : null +const sudoGID = isRoot ? +process.env.SUDO_GID : null +const { chownSync } = require('fs') function resetPackage (options) { - rimraf.sync(CACHE_DIR) + CACHE_DIR = path.resolve(common.cache, '' + cacheIteration++) + npm.config.set('cache', CACHE_DIR) mkdirp.sync(CACHE_DIR) - fixOwner(CACHE_DIR) + + if (isRoot && sudoUID && sudoGID) { + chownSync(CACHE_DIR, sudoUID, sudoGID) + } installAskedFor = undefined @@ -145,20 +143,18 @@ var npm = requireInject.installGlobally('../../lib/npm.js', { test('setup', function (t) { t.plan(5) - process.chdir(osenv.tmpdir()) - mkdirp.sync(PKG_DIR) process.chdir(PKG_DIR) t.pass('made ' + PKG_DIR) - resetPackage({}) - mr({ port: common.port, mocks: registryMocks }, function (er, server) { t.pass('mock registry active') - npm.load({ cache: CACHE_DIR, + npm.load({ + cache: CACHE_DIR, registry: common.registry, - cwd: PKG_DIR }, function (err) { + cwd: PKG_DIR + }, function (err) { t.ifError(err, 'started server') - mockServer = server + t.parent.teardown(() => server.close()) t.pass('npm.load complete') @@ -223,12 +219,3 @@ test('update old caret dependency with newer', function (t) { t.end() }) }) - -test('cleanup', function (t) { - mockServer.close() - - process.chdir(osenv.tmpdir()) - rimraf.sync(PKG_DIR) - - t.end() -}) diff --git a/deps/npm/test/tap/url-dependencies.js b/deps/npm/test/tap/url-dependencies.js index 2017151568e094..14da5d1fc4fc7e 100644 --- a/deps/npm/test/tap/url-dependencies.js +++ b/deps/npm/test/tap/url-dependencies.js @@ -1,14 +1,10 @@ var fs = require('graceful-fs') var path = require('path') -var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap') -var server var pkg = common.pkg @@ -27,87 +23,39 @@ var mockRoutes = { } } -test('setup', function (t) { - mr({ port: common.port, mocks: mockRoutes }, function (er, s) { - server = s - t.end() - }) -}) - -test('url-dependencies: download first time', function (t) { - setup() - - performInstall(t, function (output) { - if (!tarballWasFetched(output)) { - t.fail('Tarball was not fetched') - } else { - t.pass('Tarball was fetched') - } - t.end() - }) -}) - -test('url-dependencies: do not download subsequent times', function (t) { - setup() - - performInstall(t, function () { - performInstall(t, function (output) { - if (tarballWasFetched(output)) { - t.fail('Tarball was fetched second time around') - } else { - t.pass('Tarball was not fetched') - } - t.end() - }) - }) -}) - -test('cleanup', function (t) { - server.close() - cleanup() - t.end() +const tarballWasFetched = output => output.includes( + `GET 200 ${common.registry}/underscore/-/underscore-1.3.1.tgz`) + +const performInstall = () => common.npm(['install'], { + cwd: pkg, + env: { + npm_config_registry: common.registry, + npm_config_cache_lock_stale: 1000, + npm_config_cache_lock_wait: 1000, + npm_config_loglevel: 'http', + HOME: process.env.HOME, + Path: process.env.PATH, + PATH: process.env.PATH + } }) -function cleanup () { - // windows fix for locked files - process.chdir(osenv.tmpdir()) - rimraf.sync(path.resolve(pkg)) -} - -function setup () { - cleanup() - mkdirp.sync(pkg) +test('setup', function (t) { fs.writeFileSync( path.join(pkg, 'package.json'), JSON.stringify(json, null, 2) ) -} - -function tarballWasFetched (output) { - return output.indexOf( - 'GET 200 ' + - common.registry + - '/underscore/-/underscore-1.3.1.tgz' - ) > -1 -} - -function performInstall (t, cb) { - var opts = { - cwd: pkg, - env: { - npm_config_registry: common.registry, - npm_config_cache_lock_stale: 1000, - npm_config_cache_lock_wait: 1000, - npm_config_loglevel: 'http', - HOME: process.env.HOME, - Path: process.env.PATH, - PATH: process.env.PATH - } - } - common.npm(['install'], opts, function (err, code, stdout, stderr) { - t.ifError(err, 'install success') - t.notOk(code, 'npm install exited with code 0') + mr({ port: common.port, mocks: mockRoutes }, function (er, s) { + t.parent.teardown(() => s.close()) + t.end() + }) +}) - cb(stderr) +test('url-dependencies: download first time', t => + performInstall().then(([code, _, output]) => { + t.equal(code, 0, 'exited successfully') + t.ok(tarballWasFetched(output), 'download first time') }) -} + .then(() => performInstall()).then(([code, _, output]) => { + t.equal(code, 0, 'exited successfully') + t.notOk(tarballWasFetched(output), 'do not download second time') + })) diff --git a/deps/npm/test/tap/utils.funding.js b/deps/npm/test/tap/utils.funding.js new file mode 100644 index 00000000000000..51b89e5f8d340c --- /dev/null +++ b/deps/npm/test/tap/utils.funding.js @@ -0,0 +1,547 @@ +'use strict' + +const { test } = require('tap') +const { getFundingInfo } = require('../../lib/utils/funding') + +test('empty tree', (t) => { + t.deepEqual( + getFundingInfo({}), + { + name: null, + dependencies: {}, + length: 0 + }, + 'should return empty list' + ) + t.end() +}) + +test('single item missing funding', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'single-item': { + name: 'single-item', + version: '1.0.0' + } + }}), + { + name: 'project', + dependencies: {}, + length: 0 + }, + 'should return empty list' + ) + t.end() +}) + +test('funding object missing url', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'single-item': { + name: 'single-item', + version: '1.0.0', + funding: { + type: 'Foo' + } + } + }}), + { + name: 'project', + dependencies: {}, + length: 0 + }, + 'should return empty list' + ) + t.end() +}) + +test('use path if name is missing', (t) => { + t.deepEqual( + getFundingInfo({ name: undefined, + path: '/tmp/foo', + children: { + 'single-item': { + name: 'single-item', + version: '1.0.0' + } + }}), + { + name: '/tmp/foo', + dependencies: {}, + length: 0 + }, + 'should use path as top level name' + ) + t.end() +}) + +test('single item tree', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'single-item': { + name: 'single-item', + version: '1.0.0', + funding: { + type: 'foo', + url: 'http://example.com' + } + } + }}), + { + name: 'project', + dependencies: { + 'single-item': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'http://example.com' + } + } + }, + length: 1 + }, + 'should return list with a single item' + ) + t.end() +}) + +test('top-level funding info', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + funding: 'http://example.com' + }), + { + name: 'project', + funding: { + url: 'http://example.com' + }, + dependencies: {}, + length: 0 + }, + 'should return top-level item with normalized funding info' + ) + t.end() +}) + +test('use string shorthand', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'single-item': { + name: 'single-item', + version: '1.0.0', + funding: 'http://example.com' + } + }}), + { + name: 'project', + dependencies: { + 'single-item': { + version: '1.0.0', + funding: { + url: 'http://example.com' + } + } + }, + length: 1 + }, + 'should return item with normalized funding info' + ) + t.end() +}) + +test('duplicate items along the tree', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + version: '2.3.4', + dependencies: { + 'single-item': { + name: 'single-item', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'shared-top-first': { + name: 'shared-top-first', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + }, + 'sub-dep': { + name: 'sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'shared-nested-first': { + name: 'shared-nested-first', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'shared-top-first': { + name: 'shared-top-first', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + } + }, + 'shared-nested-first': { + name: 'shared-nested-first', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + }}), + { + name: 'project', + version: '2.3.4', + dependencies: { + 'single-item': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'shared-top-first': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + }, + 'sub-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + }, + 'shared-nested-first': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + }, + length: 4 + }, + 'should return list with a single item' + ) + t.end() +}) + +test('multi-level nested items tree', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'first-level-dep': { + name: 'first-level-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'sub-dep': { + name: 'sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + package: { + name: 'sub-sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: {} + } + } + } + } + } + }}), + { + name: 'project', + dependencies: { + 'first-level-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'sub-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'sub-sub-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + } + } + }, + length: 3 + }, + 'should return list with all items' + ) + t.end() +}) + +test('missing fund nested items tree', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'first-level-dep': { + name: 'first-level-dep', + version: '1.0.0', + funding: { + type: 'foo' + }, + dependencies: { + 'sub-dep': { + name: 'sub-dep', + version: '1.0.0', + dependencies: { + 'sub-sub-dep-01': { + name: 'sub-sub-dep-01', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'non-funding-child': { + name: 'non-funding-child', + version: '1.0.0', + dependencies: { + 'sub-sub-sub-dep': { + name: 'sub-sub-sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + } + }, + 'sub-sub-dep-02': { + name: 'sub-sub-dep-02', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: {} + }, + 'sub-sub-dep-03': { + name: 'sub-sub-dep-03', + version: '1.0.0', + funding: { + type: 'foo', + url: 'git://example.git' + }, + dependencies: { + 'sub-sub-sub-dep-03': { + name: 'sub-sub-sub-dep-03', + version: '1.0.0', + dependencies: { + 'sub-sub-sub-sub-dep': { + name: 'sub-sub-sub-sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'http://example.com' + } + } + } + } + } + } + } + } + } + } + }}), + { + name: 'project', + dependencies: { + 'sub-sub-dep-01': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'sub-sub-sub-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + }, + 'sub-sub-dep-02': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + }, + 'sub-sub-sub-sub-dep': { + version: '1.0.0', + funding: { + type: 'foo', + url: 'http://example.com' + } + } + }, + length: 4 + }, + 'should return list excluding missing funding items' + ) + t.end() +}) + +test('countOnly option', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + 'first-level-dep': { + name: 'first-level-dep', + version: '1.0.0', + funding: { + type: 'foo' + }, + dependencies: { + 'sub-dep': { + name: 'sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'sub-sub-dep': { + name: 'sub-sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + }, + dependencies: {} + } + }, + 'sub-sub-dep': { + name: 'sub-sub-dep', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + }}, { countOnly: true }), + { + length: 2 + }, + 'should return only the length property' + ) + t.end() +}) + +test('handle different versions', (t) => { + t.deepEqual( + getFundingInfo({ name: 'project', + dependencies: { + foo: { + name: 'foo', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + bar: { + name: 'bar', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + }, + lorem: { + dependencies: { + fooo: { + name: 'foo', + version: '2.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + }, + dependencies: { + 'foo-bar': { + name: 'foo-bar', + version: '1.0.0', + funding: { + type: 'foo', + url: 'https://example.com' + } + } + } + } + } + } + } + }, { countOnly: true }), + { + length: 4 + }, + 'should treat different versions as diff packages' + ) + t.end() +}) diff --git a/deps/npm/test/tap/version-allow-same-version.js b/deps/npm/test/tap/version-allow-same-version.js index 6b7978edebece7..41310e4eb2e278 100644 --- a/deps/npm/test/tap/version-allow-same-version.js +++ b/deps/npm/test/tap/version-allow-same-version.js @@ -1,65 +1,40 @@ -var fs = require('graceful-fs') -var path = require('path') +const fs = require('graceful-fs') +const path = require('path') +const t = require('tap') +const common = require('../common-tap.js') +const npm = require('../../') +const pkg = common.pkg +const cache = common.cache +const npmrc = path.resolve(pkg, './.npmrc') +const configContents = 'sign-git-tag=false\n' -var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') -var test = require('tap').test - -var common = require('../common-tap.js') -var npm = require('../../') -var pkg = common.pkg -var cache = common.cache -var npmrc = path.resolve(pkg, './.npmrc') -var configContents = 'sign-git-tag=false\n' - -test('npm version <semver> with same version without --allow-same-version', function (t) { - setup() +t.test('setup', t => { + process.chdir(pkg) + fs.writeFileSync(npmrc, configContents, 'ascii') fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ author: 'Lucas Theisen', name: 'version-allow-same-version', version: '0.0.1', description: 'Test for npm version without --allow-same-version' }), 'utf8') - npm.load({cache: cache, 'allow-same-version': false, registry: common.registry}, function () { - var version = require('../../lib/version') - version(['0.0.1'], function (err) { - t.ok(err) - t.like(err.message, /Version not changed/) - t.end() - }) - }) + npm.load({cache: cache, 'allow-same-version': false, registry: common.registry}, t.end) }) -test('npm version <semver> with same version with --allow-same-version', function (t) { - setup() - fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ - author: 'Lucas Theisen', - name: 'version-allow-same-version', - version: '0.0.1', - description: 'Test for npm version without --allow-same-version' - }), 'utf8') - npm.load({cache: cache, 'allow-same-version': true, registry: common.registry}, function () { - var version = require('../../lib/version') - version(['0.0.1'], - function (err) { t.ok(!err) }, - function () { t.end() }) + +t.test('without --allow-same-version', t => { + npm.config.set('allow-same-version', false) + npm.commands.version(['0.0.1'], function (err) { + t.isa(err, Error, 'got an error') + t.like(err.message, /Version not changed/) + t.end() }) }) -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - // windows fix for locked files - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} -function setup () { - mkdirp.sync(pkg) - mkdirp.sync(path.join(pkg, 'node_modules')) - mkdirp.sync(cache) - fs.writeFileSync(npmrc, configContents, 'ascii') - process.chdir(pkg) -} +t.test('with --allow-same-version', t => { + npm.config.set('allow-same-version', true) + npm.commands.version(['0.0.1'], function (err) { + if (err) { + throw err + } + t.end() + }) +}) diff --git a/deps/npm/test/tap/version-commit-hooks.js b/deps/npm/test/tap/version-commit-hooks.js index 568c82b46b0392..028767ab4e5bab 100644 --- a/deps/npm/test/tap/version-commit-hooks.js +++ b/deps/npm/test/tap/version-commit-hooks.js @@ -1,10 +1,7 @@ -var fs = require('graceful-fs') -var path = require('path') -var osenv = require('osenv') -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') +const fs = require('graceful-fs') +const path = require('path') const common = require('../common-tap.js') -var pkg = common.pkg +const pkg = common.pkg var test = require('tap').test var npm = require('../../') @@ -12,7 +9,6 @@ var npm = require('../../') delete process.env['npm_config_commit_hooks'] test('npm version <semver> with commit-hooks disabled in .npmrc', function (t) { - mkdirp.sync(pkg) var npmrc = path.resolve(pkg, '.npmrc') fs.writeFileSync(npmrc, 'commit-hooks=false\n', 'ascii') process.chdir(pkg) @@ -57,9 +53,3 @@ test('npm version <semver> with commit-hooks enabled (default)', function (t) { t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) - t.end() -}) diff --git a/deps/npm/test/tap/version-consistent-newlines.js b/deps/npm/test/tap/version-consistent-newlines.js index 4387c489e2c770..583874db7a3051 100644 --- a/deps/npm/test/tap/version-consistent-newlines.js +++ b/deps/npm/test/tap/version-consistent-newlines.js @@ -3,11 +3,9 @@ const common = require('../common-tap.js') const test = require('tap').test const npm = require('../../') -const osenv = require('osenv') const path = require('path') const fs = require('fs') const mkdirp = require('mkdirp') -const rimraf = require('rimraf') const requireInject = require('require-inject') const pkg = common.pkg @@ -66,16 +64,7 @@ test('npm version does not alter the line endings in package.json (CRLF)', funct }) }) -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - - rimraf.sync(pkg) - t.end() -}) - function setup (lineEnding) { - mkdirp.sync(pkg) - mkdirp.sync(cache) mkdirp.sync(gitDir) fs.writeFileSync( path.resolve(pkg, 'package.json'), diff --git a/deps/npm/test/tap/version-sub-directory.js b/deps/npm/test/tap/version-sub-directory.js index 809f24e79ffa51..fc4a41f36e5834 100644 --- a/deps/npm/test/tap/version-sub-directory.js +++ b/deps/npm/test/tap/version-sub-directory.js @@ -3,8 +3,6 @@ var fs = require('fs') var path = require('path') var mkdirp = require('mkdirp') -var osenv = require('osenv') -var rimraf = require('rimraf') var test = require('tap').test var npm = require('../../lib/npm.js') @@ -17,7 +15,9 @@ var cache = common.cache var json = { name: 'cat', version: '0.1.2' } test('npm version <semver> from a subdirectory', function (t) { - setup() + mkdirp.sync(subDirectory) + process.chdir(subDirectory) + fs.writeFileSync(packagePath, JSON.stringify(json), 'utf8') npmLoad() function npmLoad () { @@ -54,22 +54,3 @@ test('npm version <semver> from a subdirectory', function (t) { t.end() } }) - -test('cleanup', function (t) { - cleanup() - t.end() -}) - -function cleanup () { - // windows fix for locked files - process.chdir(osenv.tmpdir()) - rimraf.sync(pkg) -} - -function setup () { - cleanup() - mkdirp.sync(cache) - mkdirp.sync(subDirectory) - process.chdir(subDirectory) - fs.writeFileSync(packagePath, JSON.stringify(json), 'utf8') -} diff --git a/deps/npm/test/tap/view.js b/deps/npm/test/tap/view.js index a01fa903a253d4..71d21487ae99c6 100644 --- a/deps/npm/test/tap/view.js +++ b/deps/npm/test/tap/view.js @@ -1,10 +1,14 @@ var common = require('../common-tap.js') -var test = require('tap').test +const t = require('tap') +var test = t.test var osenv = require('osenv') var path = require('path') var fs = require('fs') var rimraf = require('rimraf') var mkdirp = require('mkdirp') + +// this test has to use a tmpdir so that it's outside of +// the current package context of npm. var tmp = osenv.tmpdir() var t1dir = path.resolve(tmp, 'view-local-no-pkg') var t2dir = path.resolve(tmp, 'view-local-notmine') @@ -13,6 +17,15 @@ var mr = require('npm-registry-mock') var server +t.teardown(() => { + rimraf.sync(t1dir) + rimraf.sync(t2dir) + rimraf.sync(t3dir) + if (server) { + server.close() + } +}) + test('setup', function (t) { mkdirp.sync(t1dir) mkdirp.sync(t2dir) @@ -46,7 +59,6 @@ function plugin (server) { } test('npm view . in global mode', function (t) { - process.chdir(t1dir) common.npm([ 'view', '.', @@ -61,7 +73,6 @@ test('npm view . in global mode', function (t) { }) test('npm view --global', function (t) { - process.chdir(t1dir) common.npm([ 'view', '--registry=' + common.registry, @@ -75,7 +86,6 @@ test('npm view --global', function (t) { }) test('npm view . with no package.json', function (t) { - process.chdir(t1dir) common.npm([ 'view', '.', @@ -89,7 +99,6 @@ test('npm view . with no package.json', function (t) { }) test('npm view . with no published package', function (t) { - process.chdir(t3dir) common.npm([ 'view', '.', @@ -103,7 +112,6 @@ test('npm view . with no published package', function (t) { }) test('npm view .', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.', @@ -117,7 +125,6 @@ test('npm view .', function (t) { }) test('npm view . select fields', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.', @@ -132,7 +139,6 @@ test('npm view . select fields', function (t) { }) test('npm view .@<version>', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.@0.0.0', @@ -147,7 +153,6 @@ test('npm view .@<version>', function (t) { }) test('npm view .@<version> version --json', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.@0.0.0', @@ -163,7 +168,6 @@ test('npm view .@<version> version --json', function (t) { }) test('npm view . --json author name version', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.', @@ -186,7 +190,6 @@ test('npm view . --json author name version', function (t) { }) test('npm view .@<version> --json author name version', function (t) { - process.chdir(t2dir) common.npm([ 'view', '.@0.0.0', @@ -376,13 +379,3 @@ test('npm view with valid but non existent package name', function (t) { t.end() }) }) - -test('cleanup', function (t) { - process.chdir(osenv.tmpdir()) - rimraf.sync(t1dir) - rimraf.sync(t2dir) - rimraf.sync(t3dir) - t.pass('cleaned up') - server.close() - t.end() -}) diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 6a9bbd67997311..c7f3cba05c576f 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -79,8 +79,6 @@ /tools/jsfunfuzz/jsfunfuzz /tools/jsfunfuzz/jsfunfuzz.tar.gz /tools/luci-go -/tools/mips_toolchain -/tools/mips_toolchain.tar.gz /tools/oom_dump/oom_dump /tools/oom_dump/oom_dump.o /tools/swarming_client diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index 1198de8f358fbc..40c4f16c813964 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -111,6 +111,7 @@ Johan Bergström <johan@bergstroem.nu> Jonathan Liu <net147@gmail.com> Julien Brianceau <jbriance@cisco.com> JunHo Seo <sejunho@gmail.com> +Junming Huang <kiminghjm@gmail.com> Kang-Hao (Kenny) Lu <kennyluck@csail.mit.edu> Karl Skomski <karl@skomski.com> Kevin Gibbons <bakkot@gmail.com> @@ -124,6 +125,7 @@ Marcin Cieślak <saper@marcincieslak.com> Marcin Wiącek <marcin@mwiacek.com> Mateusz Czeladka <mateusz.szczap@gmail.com> Matheus Marchini <mat@mmarchini.me> +Matheus Marchini <mmarchini@netflix.com> Mathias Bynens <mathias@qiwi.be> Matt Hanselman <mjhanselman@gmail.com> Matthew Sporleder <msporleder@gmail.com> diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index a026749a31db52..0a1f12b5de9cba 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -156,9 +156,7 @@ declare_args() { # List of extra files to snapshot. They will be snapshotted in order so # if files export symbols used by later files, they should go first. - # - # This default is used by cctests. Projects using V8 will want to override. - v8_extra_library_files = [ "//test/cctest/test-extra.js" ] + v8_extra_library_files = [] v8_enable_gdbjit = ((v8_current_cpu == "x86" || v8_current_cpu == "x64") && @@ -204,6 +202,15 @@ declare_args() { v8_enable_regexp_interpreter_threaded_dispatch = true } +# Toggle pointer compression for correctness fuzzing when building the +# clang_x64_pointer_compression toolchain. We'll correctness-compare the +# default build with the clang_x64_pointer_compression build. +if (v8_multi_arch_build && + rebase_path(get_label_info(":d8", "root_out_dir"), root_build_dir) == + "clang_x64_pointer_compression") { + v8_enable_pointer_compression = !v8_enable_pointer_compression +} + # Derived defaults. if (v8_enable_verify_heap == "") { v8_enable_verify_heap = v8_enable_debugging_features @@ -231,7 +238,7 @@ if (v8_enable_snapshot_native_code_counters == "") { v8_enable_snapshot_native_code_counters = v8_enable_debugging_features } if (v8_enable_shared_ro_heap == "") { - v8_enable_shared_ro_heap = !v8_enable_pointer_compression && v8_use_snapshot + v8_enable_shared_ro_heap = !v8_enable_pointer_compression } if (v8_enable_fast_torque == "") { v8_enable_fast_torque = v8_enable_fast_mksnapshot @@ -249,14 +256,14 @@ assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations, assert(!v8_enable_lite_mode || v8_enable_embedded_builtins, "Lite mode requires embedded builtins") -assert(!v8_enable_lite_mode || v8_use_snapshot, - "Lite mode requires a snapshot build") assert( !v8_enable_pointer_compression || !v8_enable_shared_ro_heap, "Pointer compression is not supported with shared read-only heap enabled") -assert(v8_use_snapshot || !v8_enable_shared_ro_heap, - "Shared read-only heap requires snapshot") + +assert(v8_extra_library_files == [], + "v8_extra_library_files is no longer supported. Consider implementing " + + "custom API in C++ instead.") v8_random_seed = "314159265" v8_toolset_for_shell = "host" @@ -431,11 +438,8 @@ config("features") { if (v8_enable_handle_zapping) { defines += [ "ENABLE_HANDLE_ZAPPING" ] } - if (v8_use_snapshot) { - defines += [ "V8_USE_SNAPSHOT" ] - if (v8_enable_snapshot_native_code_counters) { - defines += [ "V8_SNAPSHOT_NATIVE_CODE_COUNTERS" ] - } + if (v8_enable_snapshot_native_code_counters) { + defines += [ "V8_SNAPSHOT_NATIVE_CODE_COUNTERS" ] } if (v8_enable_single_generation) { defines += [ "V8_ENABLE_SINGLE_GENERATION" ] @@ -644,6 +648,30 @@ config("toolchain") { defines += [ "V8_ANDROID_LOG_STDOUT" ] } + # V8_TARGET_OS_ defines. The target OS may differ from host OS e.g. in + # mksnapshot. We additionally set V8_HAVE_TARGET_OS to determine that a + # target OS has in fact been set; otherwise we internally assume that target + # OS == host OS (see v8config.h). + if (target_os == "android") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_ANDROID" ] + } else if (target_os == "fuchsia") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_FUCHSIA" ] + } else if (target_os == "ios") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_IOS" ] + } else if (target_os == "linux") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_LINUX" ] + } else if (target_os == "mac") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_MACOSX" ] + } else if (target_os == "win") { + defines += [ "V8_HAVE_TARGET_OS" ] + defines += [ "V8_TARGET_OS_WIN" ] + } + # TODO(jochen): Support v8_enable_prof on Windows. # TODO(jochen): Add support for compiling with simulators. @@ -895,6 +923,8 @@ action("postmortem-metadata") { "src/objects/code.h", "src/objects/data-handler.h", "src/objects/data-handler-inl.h", + "src/objects/descriptor-array.h", + "src/objects/descriptor-array-inl.h", "src/objects/feedback-cell.h", "src/objects/feedback-cell-inl.h", "src/objects/fixed-array-inl.h", @@ -913,6 +943,7 @@ action("postmortem-metadata") { "src/objects/js-promise-inl.h", "src/objects/js-promise.h", "src/objects/js-regexp-inl.h", + "src/objects/js-regexp.cc", "src/objects/js-regexp.h", "src/objects/js-regexp-string-iterator-inl.h", "src/objects/js-regexp-string-iterator.h", @@ -924,6 +955,8 @@ action("postmortem-metadata") { "src/objects/name-inl.h", "src/objects/oddball-inl.h", "src/objects/oddball.h", + "src/objects/primitive-heap-object.h", + "src/objects/primitive-heap-object-inl.h", "src/objects/scope-info.h", "src/objects/script.h", "src/objects/script-inl.h", @@ -936,6 +969,7 @@ action("postmortem-metadata") { "src/objects/string-inl.h", "src/objects/struct.h", "src/objects/struct-inl.h", + "$target_gen_dir/torque-generated/instance-types-tq.h", ] outputs = [ @@ -944,6 +978,10 @@ action("postmortem-metadata") { args = rebase_path(outputs, root_build_dir) + rebase_path(sources, root_build_dir) + + deps = [ + ":run_torque", + ] } torque_files = [ @@ -993,9 +1031,13 @@ torque_files = [ "src/builtins/proxy-set-prototype-of.tq", "src/builtins/proxy.tq", "src/builtins/reflect.tq", + "src/builtins/regexp-exec.tq", + "src/builtins/regexp-match-all.tq", "src/builtins/regexp-match.tq", "src/builtins/regexp-replace.tq", + "src/builtins/regexp-search.tq", "src/builtins/regexp-source.tq", + "src/builtins/regexp-split.tq", "src/builtins/regexp-test.tq", "src/builtins/regexp.tq", "src/builtins/string.tq", @@ -1047,6 +1089,7 @@ action("run_torque") { outputs = [ "$target_gen_dir/torque-generated/builtin-definitions-tq.h", + "$target_gen_dir/torque-generated/interface-descriptors-tq.inc", "$target_gen_dir/torque-generated/field-offsets-tq.h", "$target_gen_dir/torque-generated/class-verifiers-tq.cc", "$target_gen_dir/torque-generated/class-verifiers-tq.h", @@ -1280,31 +1323,29 @@ template("run_mksnapshot") { } } -if (v8_use_snapshot) { - run_mksnapshot("default") { +run_mksnapshot("default") { + args = [] + if (v8_enable_embedded_builtins) { + embedded_variant = "Default" + } +} +if (emit_builtins_as_inline_asm) { + asm_to_inline_asm("default") { args = [] + } +} +if (v8_use_multi_snapshots) { + run_mksnapshot("trusted") { + args = [ "--no-untrusted-code-mitigations" ] if (v8_enable_embedded_builtins) { - embedded_variant = "Default" + embedded_variant = "Trusted" } } if (emit_builtins_as_inline_asm) { - asm_to_inline_asm("default") { + asm_to_inline_asm("trusted") { args = [] } } - if (v8_use_multi_snapshots) { - run_mksnapshot("trusted") { - args = [ "--no-untrusted-code-mitigations" ] - if (v8_enable_embedded_builtins) { - embedded_variant = "Trusted" - } - } - if (emit_builtins_as_inline_asm) { - asm_to_inline_asm("trusted") { - args = [] - } - } - } } action("v8_dump_build_config") { @@ -1334,7 +1375,6 @@ action("v8_dump_build_config") { "v8_enable_i18n_support=$v8_enable_i18n_support", "v8_enable_verify_predictable=$v8_enable_verify_predictable", "v8_target_cpu=\"$v8_target_cpu\"", - "v8_use_snapshot=$v8_use_snapshot", "v8_enable_embedded_builtins=$v8_enable_embedded_builtins", "v8_enable_verify_csa=$v8_enable_verify_csa", "v8_enable_lite_mode=$v8_enable_lite_mode", @@ -1355,19 +1395,13 @@ action("v8_dump_build_config") { # source_set("v8_maybe_snapshot") { - if (v8_use_snapshot && v8_use_external_startup_data) { + if (v8_use_external_startup_data) { public_deps = [ ":v8_external_snapshot", ] - } else if (v8_use_snapshot) { - public_deps = [ - ":v8_snapshot", - ] } else { - # Ignore v8_use_external_startup_data setting if no snapshot is used. public_deps = [ - ":v8_init", - ":v8_nosnapshot", + ":v8_snapshot", ] } } @@ -1393,7 +1427,7 @@ v8_source_set("v8_nosnapshot") { configs = [ ":internal_config" ] } -if (v8_use_snapshot && !v8_use_external_startup_data) { +if (!v8_use_external_startup_data) { v8_source_set("v8_snapshot") { # Only targets in this file and the top-level visibility target can # depend on this. @@ -1435,7 +1469,7 @@ if (v8_use_snapshot && !v8_use_external_startup_data) { } } -if (v8_use_snapshot && v8_use_external_startup_data) { +if (v8_use_external_startup_data) { v8_source_set("v8_external_snapshot") { visibility = [ ":*" ] # Only targets in this file can depend on this. @@ -1852,6 +1886,8 @@ v8_compiler_sources = [ "src/compiler/machine-operator.h", "src/compiler/map-inference.cc", "src/compiler/map-inference.h", + "src/compiler/memory-lowering.cc", + "src/compiler/memory-lowering.h", "src/compiler/memory-optimizer.cc", "src/compiler/memory-optimizer.h", "src/compiler/node-aux-data.h", @@ -2047,6 +2083,7 @@ v8_source_set("v8_base_without_compiler") { "src/builtins/builtins-api.cc", "src/builtins/builtins-array.cc", "src/builtins/builtins-arraybuffer.cc", + "src/builtins/builtins-async-module.cc", "src/builtins/builtins-bigint.cc", "src/builtins/builtins-call.cc", "src/builtins/builtins-callsite.cc", @@ -2143,6 +2180,7 @@ v8_source_set("v8_base_without_compiler") { "src/codegen/string-constants.h", "src/codegen/tick-counter.cc", "src/codegen/tick-counter.h", + "src/codegen/tnode.h", "src/codegen/turbo-assembler.cc", "src/codegen/turbo-assembler.h", "src/codegen/unoptimized-compilation-info.cc", @@ -2316,6 +2354,8 @@ v8_source_set("v8_base_without_compiler") { "src/heap/mark-compact.h", "src/heap/marking.cc", "src/heap/marking.h", + "src/heap/memory-measurement.cc", + "src/heap/memory-measurement.h", "src/heap/memory-reducer.cc", "src/heap/memory-reducer.h", "src/heap/object-stats.cc", @@ -2337,9 +2377,6 @@ v8_source_set("v8_base_without_compiler") { "src/heap/spaces-inl.h", "src/heap/spaces.cc", "src/heap/spaces.h", - "src/heap/store-buffer-inl.h", - "src/heap/store-buffer.cc", - "src/heap/store-buffer.h", "src/heap/stress-marking-observer.cc", "src/heap/stress-marking-observer.h", "src/heap/stress-scavenge-observer.cc", @@ -2461,6 +2498,8 @@ v8_source_set("v8_base_without_compiler") { "src/objects/api-callbacks.h", "src/objects/arguments-inl.h", "src/objects/arguments.h", + "src/objects/backing-store.cc", + "src/objects/backing-store.h", "src/objects/bigint.cc", "src/objects/bigint.h", "src/objects/cell-inl.h", @@ -2515,6 +2554,7 @@ v8_source_set("v8_base_without_compiler") { "src/objects/heap-object.h", "src/objects/instance-type-inl.h", "src/objects/instance-type.h", + "src/objects/internal-index.h", "src/objects/intl-objects.cc", "src/objects/intl-objects.h", "src/objects/js-array-buffer-inl.h", @@ -2558,6 +2598,7 @@ v8_source_set("v8_base_without_compiler") { "src/objects/js-regexp-inl.h", "src/objects/js-regexp-string-iterator-inl.h", "src/objects/js-regexp-string-iterator.h", + "src/objects/js-regexp.cc", "src/objects/js-regexp.h", "src/objects/js-relative-time-format-inl.h", "src/objects/js-relative-time-format.cc", @@ -2613,6 +2654,11 @@ v8_source_set("v8_base_without_compiler") { "src/objects/ordered-hash-table-inl.h", "src/objects/ordered-hash-table.cc", "src/objects/ordered-hash-table.h", + "src/objects/osr-optimized-code-cache-inl.h", + "src/objects/osr-optimized-code-cache.cc", + "src/objects/osr-optimized-code-cache.h", + "src/objects/primitive-heap-object-inl.h", + "src/objects/primitive-heap-object.h", "src/objects/promise-inl.h", "src/objects/promise.h", "src/objects/property-array-inl.h", @@ -2738,6 +2784,9 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/regexp-bytecode-generator-inl.h", "src/regexp/regexp-bytecode-generator.cc", "src/regexp/regexp-bytecode-generator.h", + "src/regexp/regexp-bytecode-peephole.cc", + "src/regexp/regexp-bytecode-peephole.h", + "src/regexp/regexp-bytecodes.cc", "src/regexp/regexp-bytecodes.h", "src/regexp/regexp-compiler-tonode.cc", "src/regexp/regexp-compiler.cc", @@ -2754,13 +2803,13 @@ v8_source_set("v8_base_without_compiler") { "src/regexp/regexp-nodes.h", "src/regexp/regexp-parser.cc", "src/regexp/regexp-parser.h", - "src/regexp/regexp-special-case.h", "src/regexp/regexp-stack.cc", "src/regexp/regexp-stack.h", "src/regexp/regexp-utils.cc", "src/regexp/regexp-utils.h", "src/regexp/regexp.cc", "src/regexp/regexp.h", + "src/regexp/special-case.h", "src/roots/roots-inl.h", "src/roots/roots.cc", "src/roots/roots.h", @@ -2953,8 +3002,6 @@ v8_source_set("v8_base_without_compiler") { "src/wasm/wasm-js.h", "src/wasm/wasm-limits.h", "src/wasm/wasm-linkage.h", - "src/wasm/wasm-memory.cc", - "src/wasm/wasm-memory.h", "src/wasm/wasm-module-builder.cc", "src/wasm/wasm-module-builder.h", "src/wasm/wasm-module-sourcemap.cc", @@ -3386,6 +3433,7 @@ v8_source_set("torque_base") { "src/torque/global-context.h", "src/torque/implementation-visitor.cc", "src/torque/implementation-visitor.h", + "src/torque/instance-type-generator.cc", "src/torque/instructions.cc", "src/torque/instructions.h", "src/torque/server-data.cc", @@ -3482,7 +3530,6 @@ v8_source_set("torque_ls_base") { v8_component("v8_libbase") { sources = [ - "src/base/adapters.h", "src/base/address-region.h", "src/base/atomic-utils.h", "src/base/atomicops.h", @@ -3668,6 +3715,12 @@ v8_component("v8_libbase") { ] } + if (is_ubsan && (v8_current_cpu == "x86" || v8_current_cpu == "arm" || + v8_current_cpu == "mips")) { + # Special UBSan 32-bit requirement. + sources += [ "src/base/ubsan.cc" ] + } + if (is_tsan && !build_with_chromium) { data += [ "tools/sanitizers/tsan_suppressions.txt" ] } @@ -3840,7 +3893,7 @@ if (current_toolchain == v8_generator_toolchain) { } } -if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) { +if (current_toolchain == v8_snapshot_toolchain) { v8_executable("mksnapshot") { visibility = [ ":*" ] # Only targets in this file can depend on this. @@ -4037,6 +4090,7 @@ group("v8_clusterfuzz") { ":d8(//build/toolchain/linux:clang_x64_v8_arm64)", ":d8(//build/toolchain/linux:clang_x86)", ":d8(//build/toolchain/linux:clang_x86_v8_arm)", + ":d8(tools/clusterfuzz/toolchain:clang_x64_pointer_compression)", ] } } @@ -4115,13 +4169,10 @@ if (is_component_build) { ":torque_ls_base", ":v8_base", ":v8_headers", + ":v8_initializers", ":v8_maybe_snapshot", ] - if (v8_use_snapshot) { - public_deps += [ ":v8_initializers" ] - } - configs = [ ":internal_config" ] public_configs = [ ":external_config" ] @@ -4143,13 +4194,10 @@ if (is_component_build) { ":torque_base", ":torque_ls_base", ":v8_base", + ":v8_initializers", ":v8_maybe_snapshot", ] - if (v8_use_snapshot) { - public_deps += [ ":v8_initializers" ] - } - public_configs = [ ":external_config" ] } } diff --git a/deps/v8/COMMON_OWNERS b/deps/v8/COMMON_OWNERS index 79f14286583397..542c5abd3e044b 100644 --- a/deps/v8/COMMON_OWNERS +++ b/deps/v8/COMMON_OWNERS @@ -4,7 +4,7 @@ bbudge@chromium.org binji@chromium.org bmeurer@chromium.org cbruni@chromium.org -clemensh@chromium.org +clemensb@chromium.org danno@chromium.org delphick@chromium.org gdeepti@chromium.org diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index be6a58859c5394..b3ca3548e865d2 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,3 +1,1618 @@ +2019-10-16: Version 7.9.317 + + Performance and stability improvements on all platforms. + + +2019-10-16: Version 7.9.316 + + Performance and stability improvements on all platforms. + + +2019-10-16: Version 7.9.315 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.314 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.313 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.312 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.311 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.310 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.309 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.308 + + Performance and stability improvements on all platforms. + + +2019-10-15: Version 7.9.307 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.306 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.305 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.304 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.303 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.302 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.301 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.300 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.299 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.298 + + Performance and stability improvements on all platforms. + + +2019-10-14: Version 7.9.297 + + Performance and stability improvements on all platforms. + + +2019-10-13: Version 7.9.296 + + Performance and stability improvements on all platforms. + + +2019-10-12: Version 7.9.295 + + Performance and stability improvements on all platforms. + + +2019-10-12: Version 7.9.294 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.293 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.292 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.291 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.290 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.289 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.288 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.287 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.286 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.285 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.284 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.283 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.282 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.281 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.280 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.279 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.278 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.277 + + Performance and stability improvements on all platforms. + + +2019-10-11: Version 7.9.276 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.275 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.274 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.273 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.272 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.271 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.270 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.269 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.268 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.267 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.266 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.265 + + Performance and stability improvements on all platforms. + + +2019-10-10: Version 7.9.264 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.263 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.262 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.261 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.260 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.259 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.258 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.257 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.256 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.255 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.254 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.253 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.252 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.251 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.250 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.249 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.248 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.247 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.246 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.245 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.244 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.243 + + Performance and stability improvements on all platforms. + + +2019-10-09: Version 7.9.242 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.241 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.240 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.239 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.238 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.237 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.236 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.235 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.234 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.233 + + Performance and stability improvements on all platforms. + + +2019-10-08: Version 7.9.232 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.231 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.230 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.229 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.228 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.227 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.226 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.225 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.224 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.223 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.222 + + Performance and stability improvements on all platforms. + + +2019-10-07: Version 7.9.221 + + Performance and stability improvements on all platforms. + + +2019-10-06: Version 7.9.220 + + Performance and stability improvements on all platforms. + + +2019-10-05: Version 7.9.219 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.218 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.217 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.216 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.215 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.214 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.213 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.212 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.211 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.210 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.209 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.208 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.207 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.206 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.205 + + Performance and stability improvements on all platforms. + + +2019-10-04: Version 7.9.204 + + Performance and stability improvements on all platforms. + + +2019-10-03: Version 7.9.203 + + Performance and stability improvements on all platforms. + + +2019-10-03: Version 7.9.202 + + Performance and stability improvements on all platforms. + + +2019-10-03: Version 7.9.201 + + Performance and stability improvements on all platforms. + + +2019-10-03: Version 7.9.200 + + Performance and stability improvements on all platforms. + + +2019-10-03: Version 7.9.199 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.198 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.197 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.196 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.195 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.194 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.193 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.192 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.191 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.190 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.189 + + Performance and stability improvements on all platforms. + + +2019-10-02: Version 7.9.188 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.187 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.186 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.185 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.184 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.183 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.182 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.181 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.180 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.179 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.178 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.177 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.176 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.175 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.174 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.173 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.172 + + Performance and stability improvements on all platforms. + + +2019-10-01: Version 7.9.171 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.170 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.169 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.168 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.167 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.166 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.165 + + Performance and stability improvements on all platforms. + + +2019-09-30: Version 7.9.164 + + Performance and stability improvements on all platforms. + + +2019-09-29: Version 7.9.163 + + Performance and stability improvements on all platforms. + + +2019-09-28: Version 7.9.162 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.161 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.160 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.159 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.158 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.157 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.156 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.155 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.154 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.153 + + Performance and stability improvements on all platforms. + + +2019-09-27: Version 7.9.152 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.151 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.150 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.149 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.148 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.147 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.146 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.145 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.144 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.143 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.142 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.141 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.140 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.139 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.138 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.137 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.136 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.135 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.134 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.133 + + Performance and stability improvements on all platforms. + + +2019-09-26: Version 7.9.132 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.131 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.130 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.129 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.128 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.127 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.126 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.125 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.124 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.123 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.122 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.121 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.120 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.119 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.118 + + Performance and stability improvements on all platforms. + + +2019-09-25: Version 7.9.117 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.116 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.115 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.114 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.113 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.112 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.111 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.110 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.109 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.108 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.107 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.106 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.105 + + Performance and stability improvements on all platforms. + + +2019-09-24: Version 7.9.104 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.103 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.102 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.101 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.100 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.99 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.98 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.97 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.96 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.95 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.94 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.93 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.92 + + Performance and stability improvements on all platforms. + + +2019-09-23: Version 7.9.91 + + Performance and stability improvements on all platforms. + + +2019-09-22: Version 7.9.90 + + Performance and stability improvements on all platforms. + + +2019-09-21: Version 7.9.89 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.88 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.87 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.86 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.85 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.84 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.83 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.82 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.81 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.80 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.79 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.78 + + Performance and stability improvements on all platforms. + + +2019-09-20: Version 7.9.77 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.76 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.75 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.74 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.73 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.72 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.71 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.70 + + Performance and stability improvements on all platforms. + + +2019-09-19: Version 7.9.69 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.68 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.67 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.66 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.65 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.64 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.63 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.62 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.61 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.60 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.59 + + Performance and stability improvements on all platforms. + + +2019-09-18: Version 7.9.58 + + Performance and stability improvements on all platforms. + + +2019-09-17: Version 7.9.57 + + Performance and stability improvements on all platforms. + + +2019-09-17: Version 7.9.56 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.55 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.54 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.53 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.52 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.51 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.50 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.49 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.48 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.47 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.46 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.45 + + Performance and stability improvements on all platforms. + + +2019-09-16: Version 7.9.44 + + Performance and stability improvements on all platforms. + + +2019-09-14: Version 7.9.43 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.42 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.41 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.40 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.39 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.38 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.37 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.36 + + Performance and stability improvements on all platforms. + + +2019-09-13: Version 7.9.35 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.34 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.33 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.32 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.31 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.30 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.29 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.28 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.27 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.26 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.25 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.24 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.23 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.22 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.21 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.20 + + Performance and stability improvements on all platforms. + + +2019-09-12: Version 7.9.19 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.18 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.17 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.16 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.15 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.14 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.13 + + Performance and stability improvements on all platforms. + + +2019-09-11: Version 7.9.12 + + Performance and stability improvements on all platforms. + + +2019-09-10: Version 7.9.11 + + Performance and stability improvements on all platforms. + + +2019-09-10: Version 7.9.10 + + Performance and stability improvements on all platforms. + + +2019-09-10: Version 7.9.9 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.8 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.7 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.6 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.5 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.4 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.3 + + Performance and stability improvements on all platforms. + + +2019-09-09: Version 7.9.2 + + Performance and stability improvements on all platforms. + + +2019-09-08: Version 7.9.1 + + Performance and stability improvements on all platforms. + + +2019-09-05: Version 7.8.285 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.284 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.283 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.282 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.281 + + Performance and stability improvements on all platforms. + + +2019-09-04: Version 7.8.280 + + Performance and stability improvements on all platforms. + + 2019-09-04: Version 7.8.279 Performance and stability improvements on all platforms. diff --git a/deps/v8/DEPS b/deps/v8/DEPS index a7d4081edb856c..0faa57e5b05c04 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -23,11 +23,10 @@ vars = { 'android_url': 'https://android.googlesource.com', 'download_gcmole': False, 'download_jsfunfuzz': False, - 'download_mips_toolchain': False, 'check_v8_header_includes': False, # GN CIPD package version. - 'gn_version': 'git_revision:152c5144ceed9592c20f0c8fd55769646077569b', + 'gn_version': 'git_revision:ad9e442d92dcd9ee73a557428cfc336b55cbd533', # luci-go CIPD package version. 'luci_go': 'git_revision:7d11fd9e66407c49cb6c8546a2ae45ea993a240c', @@ -72,15 +71,15 @@ vars = { deps = { 'v8/build': - Var('chromium_url') + '/chromium/src/build.git' + '@' + '693faeda4ee025796c7e473d953a5a7b6ad64c93', + Var('chromium_url') + '/chromium/src/build.git' + '@' + '082f11b29976c3be67dddd74bd75c6d1793201c7', 'v8/third_party/depot_tools': - Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'f38bc1796282c61087dcf15abc61b8fd18a68402', + Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'ba97f6065ed1e9336585468dd85e680cf09d5166', 'v8/third_party/icu': - Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '53f6b233a41ec982d8445996247093f7aaf41639', + Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '5005010d694e16571b8dfbf07d70817841f80a69', 'v8/third_party/instrumented_libraries': - Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'b1c3ca20848c117eb935b02c25d441f03e6fbc5e', + Var('chromium_url') + '/chromium/src/third_party/instrumented_libraries.git' + '@' + 'e2897773b97b65f70b0bb15b753c73d9f6e3afdb', 'v8/buildtools': - Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '74cfb57006f83cfe050817526db359d5c8a11628', + Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + 'cf454b247c611167388742c7a31ef138a6031172', 'v8/buildtools/clang_format/script': Var('chromium_url') + '/chromium/llvm-project/cfe/tools/clang-format.git' + '@' + '96636aa0e9f047f17447f2d45a094d0b59ed7917', 'v8/buildtools/linux64': { @@ -122,7 +121,7 @@ deps = { 'v8/base/trace_event/common': Var('chromium_url') + '/chromium/src/base/trace_event/common.git' + '@' + '5e4fce17a9d2439c44a7b57ceecef6df9287ec2f', 'v8/third_party/android_ndk': { - 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '62582753e869484bf0cc7f7e8d184ce0077033c2', + 'url': Var('chromium_url') + '/android_ndk.git' + '@' + '89e8db0cdf323af8bc24de875d7d2a43a66bf10e', 'condition': 'checkout_android', }, 'v8/third_party/android_sdk/public': { @@ -168,7 +167,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/third_party/catapult': { - 'url': Var('chromium_url') + '/catapult.git' + '@' + 'e7c719c3e85f76938bf4fef0ba37c27f89246f71', + 'url': Var('chromium_url') + '/catapult.git' + '@' + 'b9fad2fbcc499b984d88f4c4aec26d162297efae', 'condition': 'checkout_android', }, 'v8/third_party/colorama/src': { @@ -180,19 +179,19 @@ deps = { 'condition': 'checkout_fuchsia', }, 'v8/third_party/googletest/src': - Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + '565f1b848215b77c3732bca345fe76a0431d8b34', + Var('chromium_url') + '/external/github.com/google/googletest.git' + '@' + 'f2fb48c3b3d79a75a88a99fba6576b25d42ec528', 'v8/third_party/jinja2': Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'b41863e42637544c2941b574c7877d3e1f663e25', 'v8/third_party/markupsafe': Var('chromium_url') + '/chromium/src/third_party/markupsafe.git' + '@' + '8f45f5cfa0009d2a70589bcda0349b8cb2b72783', 'v8/tools/swarming_client': - Var('chromium_url') + '/infra/luci/client-py.git' + '@' + '96f125709acfd0b48fc1e5dae7d6ea42291726ac', + Var('chromium_url') + '/infra/luci/client-py.git' + '@' + '885b3febcc170a60f25795304e60927b77d1e92d', 'v8/test/benchmarks/data': Var('chromium_url') + '/v8/deps/third_party/benchmarks.git' + '@' + '05d7188267b4560491ff9155c5ee13e207ecd65f', 'v8/test/mozilla/data': Var('chromium_url') + '/v8/deps/third_party/mozilla-tests.git' + '@' + 'f6c578a10ea707b1a8ab0b88943fe5115ce2b9be', 'v8/test/test262/data': - Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '59a1a016b7cf5cf43f66b274c7d1db4ec6066935', + Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + 'd49777de27240262fa65c3b49dc014839e6897da', 'v8/test/test262/harness': Var('chromium_url') + '/external/github.com/test262-utils/test262-harness-py.git' + '@' + '4555345a943d0c99a9461182705543fb171dda4b', 'v8/third_party/qemu-linux-x64': { @@ -216,7 +215,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/tools/clang': - Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '2fef805e5b05b26a8c87c47865590b5f43218611', + Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + 'c5d85f1e9d3a01e4de2ccf4dfaa7847653ae9121', 'v8/tools/luci-go': { 'packages': [ { @@ -246,7 +245,7 @@ deps = { 'dep_type': 'cipd', }, 'v8/third_party/perfetto': - Var('android_url') + '/platform/external/perfetto.git' + '@' + '01615892494a9a8dc84414962d0a817bf97de2c2', + Var('android_url') + '/platform/external/perfetto.git' + '@' + '28b633cd961b50c4c75bfb7f62eeac79e27c1a79', 'v8/third_party/protobuf': Var('chromium_url') + '/external/github.com/google/protobuf'+ '@' + 'b68a347f56137b4b1a746e8c7438495a6ac1bd91', } @@ -391,13 +390,6 @@ hooks = [ 'action': ['python', 'v8/build/linux/sysroot_scripts/install-sysroot.py', '--arch=x86'], }, - { - 'name': 'sysroot_mips', - 'pattern': '.', - 'condition': '(checkout_linux and checkout_mips)', - 'action': ['python', 'v8/build/linux/sysroot_scripts/install-sysroot.py', - '--arch=mips'], - }, { 'name': 'sysroot_x64', 'pattern': '.', @@ -495,19 +487,6 @@ hooks = [ 'condition': 'host_os == "mac" and checkout_fuchsia', 'action': ['python', 'v8/tools/clang/scripts/download_objdump.py'], }, - { - 'name': 'mips_toolchain', - 'pattern': '.', - 'condition': 'download_mips_toolchain', - 'action': [ 'download_from_google_storage', - '--no_resume', - '--platform=linux', - '--no_auth', - '-u', - '--bucket', 'chromium-v8', - '-s', 'v8/tools/mips_toolchain.tar.gz.sha1', - ], - }, # Download and initialize "vpython" VirtualEnv environment packages. { 'name': 'vpython_common', diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS index 9ab84b1e2759de..e096d3c950fc50 100644 --- a/deps/v8/OWNERS +++ b/deps/v8/OWNERS @@ -16,7 +16,8 @@ per-file BUILD.gn=file:COMMON_OWNERS per-file DEPS=file:INFRA_OWNERS # For Test262 rolls. per-file DEPS=mathias@chromium.org -per-file PRESUBMIT=file:INFRA_OWNERS +per-file DEPS=syg@chromium.org +per-file PRESUBMIT.py=file:INFRA_OWNERS per-file codereview.settings=file:INFRA_OWNERS per-file AUTHORS=file:COMMON_OWNERS diff --git a/deps/v8/PRESUBMIT.py b/deps/v8/PRESUBMIT.py index 201bf55f714b5a..67986d83031c38 100644 --- a/deps/v8/PRESUBMIT.py +++ b/deps/v8/PRESUBMIT.py @@ -32,6 +32,7 @@ """ import json +import os import re import sys @@ -134,8 +135,68 @@ def _CheckUnwantedDependencies(input_api, output_api): # Restore sys.path to what it was before. sys.path = original_sys_path + def _FilesImpactedByDepsChange(files): + all_files = [f.AbsoluteLocalPath() for f in files] + deps_files = [p for p in all_files if IsDepsFile(p)] + impacted_files = union([_CollectImpactedFiles(path) for path in deps_files]) + impacted_file_objs = [ImpactedFile(path) for path in impacted_files] + return impacted_file_objs + + def IsDepsFile(p): + return os.path.isfile(p) and os.path.basename(p) == 'DEPS' + + def union(list_of_lists): + """Ensure no duplicates""" + return set(sum(list_of_lists, [])) + + def _CollectImpactedFiles(deps_file): + # TODO(liviurau): Do not walk paths twice. Then we have no duplicates. + # Higher level DEPS changes may dominate lower level DEPS changes. + # TODO(liviurau): Check if DEPS changed in the right way. + # 'include_rules' impact c++ files but 'vars' or 'deps' do not. + # Maybe we just eval both old and new DEPS content and check + # if the list are the same. + result = [] + parent_dir = os.path.dirname(deps_file) + for relative_f in input_api.change.AllFiles(parent_dir): + abs_f = os.path.join(parent_dir, relative_f) + if CppChecker.IsCppFile(abs_f): + result.append(abs_f) + return result + + class ImpactedFile(object): + """Duck type version of AffectedFile needed to check files under directories + where a DEPS file changed. Extend the interface along the line of + AffectedFile if you need it for other checks.""" + + def __init__(self, path): + self._path = path + + def LocalPath(self): + path = self._path.replace(os.sep, '/') + return os.path.normpath(path) + + def ChangedContents(self): + with open(self._path) as f: + # TODO(liviurau): read only '#include' lines + lines = f.readlines() + return enumerate(lines, start=1) + + def _FilterDuplicates(impacted_files, affected_files): + """"We include all impacted files but exclude affected files that are also + impacted. Files impacted by DEPS changes take precedence before files + affected by direct changes.""" + result = impacted_files[:] + only_paths = set([imf.LocalPath() for imf in impacted_files]) + for af in affected_files: + if not af.LocalPath() in only_paths: + result.append(af) + return result + added_includes = [] - for f in input_api.AffectedFiles(): + affected_files = input_api.AffectedFiles() + impacted_by_deps = _FilesImpactedByDepsChange(affected_files) + for f in _FilterDuplicates(impacted_by_deps, affected_files): if not CppChecker.IsCppFile(f.LocalPath()): continue @@ -301,39 +362,43 @@ def FilterFile(affected_file): return [] +def _CheckGenderNeutralInLicenses(input_api, output_api): + # License files are taken as is, even if they include gendered pronouns. + def LicenseFilter(path): + input_api.FilterSourceFile(path, black_list=_LICENSE_FILE) + + return input_api.canned_checks.CheckGenderNeutral( + input_api, output_api, source_file_filter=LicenseFilter) + + +def _RunTestsWithVPythonSpec(input_api, output_api): + return input_api.RunTests( + input_api.canned_checks.CheckVPythonSpec(input_api, output_api)) + + def _CommonChecks(input_api, output_api): """Checks common to both upload and commit.""" - results = [] # TODO(machenbach): Replace some of those checks, e.g. owners and copyright, # with the canned PanProjectChecks. Need to make sure that the checks all # pass on all existing files. - results.extend(input_api.canned_checks.CheckOwnersFormat( - input_api, output_api)) - results.extend(input_api.canned_checks.CheckOwners( - input_api, output_api)) - results.extend(_CheckCommitMessageBugEntry(input_api, output_api)) - results.extend(input_api.canned_checks.CheckPatchFormatted( - input_api, output_api)) - - # License files are taken as is, even if they include gendered pronouns. - license_filter = lambda path: input_api.FilterSourceFile( - path, black_list=_LICENSE_FILE) - results.extend(input_api.canned_checks.CheckGenderNeutral( - input_api, output_api, source_file_filter=license_filter)) - - results.extend(_V8PresubmitChecks(input_api, output_api)) - results.extend(_CheckUnwantedDependencies(input_api, output_api)) - results.extend( - _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) - results.extend(_CheckHeadersHaveIncludeGuards(input_api, output_api)) - results.extend( - _CheckNoInlineHeaderIncludesInNormalHeaders(input_api, output_api)) - results.extend(_CheckJSONFiles(input_api, output_api)) - results.extend(_CheckMacroUndefs(input_api, output_api)) - results.extend(_CheckNoexceptAnnotations(input_api, output_api)) - results.extend(input_api.RunTests( - input_api.canned_checks.CheckVPythonSpec(input_api, output_api))) - return results + checks = [ + input_api.canned_checks.CheckOwnersFormat, + input_api.canned_checks.CheckOwners, + _CheckCommitMessageBugEntry, + input_api.canned_checks.CheckPatchFormatted, + _CheckGenderNeutralInLicenses, + _V8PresubmitChecks, + _CheckUnwantedDependencies, + _CheckNoProductionCodeUsingTestOnlyFunctions, + _CheckHeadersHaveIncludeGuards, + _CheckNoInlineHeaderIncludesInNormalHeaders, + _CheckJSONFiles, + _CheckMacroUndefs, + _CheckNoexceptAnnotations, + _RunTestsWithVPythonSpec, + ] + + return sum([check(input_api, output_api) for check in checks], []) def _SkipTreeCheck(input_api, output_api): @@ -395,7 +460,7 @@ def _CheckMacroUndefs(input_api, output_api): """ Checks that each #define in a .cc file is eventually followed by an #undef. - TODO(clemensh): This check should eventually be enabled for all cc files via + TODO(clemensb): This check should eventually be enabled for all cc files via tools/presubmit.py (https://crbug.com/v8/6811). """ def FilterFile(affected_file): @@ -404,13 +469,29 @@ def FilterFile(affected_file): white_list = (r'.+\.cc',r'.+\.cpp',r'.+\.c') return input_api.FilterSourceFile(affected_file, white_list=white_list) + def Touches(line): + return line.startswith('+') or line.startswith('-') + + def InvolvesMacros(text): + return define_pattern.match(text) or undef_pattern.match(text) + def TouchesMacros(f): - for line in f.GenerateScmDiff().splitlines(): - if not line.startswith('+') and not line.startswith('-'): - continue - if define_pattern.match(line[1:]) or undef_pattern.match(line[1:]): - return True - return False + return any(Touches(line) and InvolvesMacros(line[1:]) + for line in f.GenerateScmDiff().splitlines()) + + def CollectUndefsWithNoDef(defined_macros, errors, f, line, line_nr): + define_match = define_pattern.match(line) + if define_match: + name = define_match.group(1) + defined_macros[name] = line_nr + undef_match = undef_pattern.match(line) + if undef_match and not "// NOLINT" in line: + name = undef_match.group(1) + if name in defined_macros: + del defined_macros[name] + else: + errors.append('{}:{}: Macro named \'{}\' was not defined before.' + .format(f.LocalPath(), line_nr, name)) define_pattern = input_api.re.compile(r'#define (\w+)') undef_pattern = input_api.re.compile(r'#undef (\w+)') @@ -422,25 +503,9 @@ def TouchesMacros(f): defined_macros = dict() with open(f.LocalPath()) as fh: - line_nr = 0 - for line in fh: - line_nr += 1 - - define_match = define_pattern.match(line) - if define_match: - name = define_match.group(1) - defined_macros[name] = line_nr - - undef_match = undef_pattern.match(line) - if undef_match: - if "// NOLINT" in line: - continue - name = undef_match.group(1) - if not name in defined_macros: - errors.append('{}:{}: Macro named \'{}\' was not defined before.' - .format(f.LocalPath(), line_nr, name)) - else: - del defined_macros[name] + for line_nr, line in enumerate(fh, start=1): + CollectUndefsWithNoDef(defined_macros, errors, f, line, line_nr) + for name, line_nr in sorted(defined_macros.items(), key=lambda e: e[1]): errors.append('{}:{}: Macro missing #undef: {}' .format(f.LocalPath(), line_nr, name)) @@ -463,7 +528,7 @@ def _CheckNoexceptAnnotations(input_api, output_api): Omitting it at some places can result in weird compiler errors if this is mixed with other classes that have the annotation. - TODO(clemensh): This check should eventually be enabled for all files via + TODO(clemensb): This check should eventually be enabled for all files via tools/presubmit.py (https://crbug.com/v8/8616). """ diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni index e55c4cf3468460..2644dea36bffda 100644 --- a/deps/v8/gni/v8.gni +++ b/deps/v8/gni/v8.gni @@ -35,15 +35,6 @@ declare_args() { # on platform and embedder level. v8_enable_raw_heap_snapshots = false - # Enable the snapshot feature, for fast context creation. - # https://v8.dev/blog/custom-startup-snapshots - # TODO(thakis): Make snapshots work in 64-bit win/cross builds, - # https://803591 - # On Mac hosts, 32-bit builds targeting Windows can't use snapshots, see - # https://crbug.com/794838 - v8_use_snapshot = !(is_win && host_os != "win" && target_cpu == "x64") && - !(is_win && host_os == "mac" && target_cpu == "x86") - # Enable several snapshots side-by-side (e.g. default and for trusted code). v8_use_multi_snapshots = false @@ -71,8 +62,8 @@ declare_args() { if (v8_use_external_startup_data == "") { # If not specified as a gn arg, use external startup data by default if - # a snapshot is used and if we're not on ios. - v8_use_external_startup_data = v8_use_snapshot && !is_ios + # we're not on ios. + v8_use_external_startup_data = !is_ios } if (v8_use_multi_snapshots) { @@ -213,9 +204,17 @@ template("v8_executable") { template("v8_component") { component(target_name) { - forward_variables_from(invoker, "*", [ "configs" ]) + forward_variables_from(invoker, + "*", + [ + "configs", + "remove_configs", + ]) configs -= v8_remove_configs configs += v8_add_configs + if (defined(invoker.remove_configs)) { + configs -= invoker.remove_configs + } configs += invoker.configs } } diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS index b64069847bc1cc..1e0794df7a2796 100644 --- a/deps/v8/include/OWNERS +++ b/deps/v8/include/OWNERS @@ -1,6 +1,7 @@ adamk@chromium.org danno@chromium.org ulan@chromium.org +verwaest@chromium.org yangguo@chromium.org per-file *DEPS=file:../COMMON_OWNERS diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl index c4ff51b06078bf..51f3c6f68a113c 100644 --- a/deps/v8/include/js_protocol.pdl +++ b/deps/v8/include/js_protocol.pdl @@ -227,6 +227,15 @@ domain Debugger # Script source. string scriptSource + # Returns bytecode for the WebAssembly script with given id. + command getWasmBytecode + parameters + # Id of the Wasm script to get source for. + Runtime.ScriptId scriptId + returns + # Script source. + binary bytecode + # Returns stack trace with given `stackTraceId`. experimental command getStackTrace parameters @@ -237,7 +246,7 @@ domain Debugger # Stops on the next JavaScript statement. command pause - experimental command pauseOnAsyncCall + experimental deprecated command pauseOnAsyncCall parameters # Debugger will pause when async call with given stack trace is started. Runtime.StackTraceId parentStackTraceId @@ -435,7 +444,7 @@ domain Debugger # Steps into the function call. command stepInto parameters - # Debugger will issue additional Debugger.paused notification if any async task is scheduled + # Debugger will pause on the execution of the first async task which was scheduled # before next pause. experimental optional boolean breakOnAsyncCall @@ -479,9 +488,8 @@ domain Debugger optional Runtime.StackTrace asyncStackTrace # Async stack trace, if any. experimental optional Runtime.StackTraceId asyncStackTraceId - # Just scheduled async call will have this stack trace as parent stack during async execution. - # This field is available only after `Debugger.stepInto` call with `breakOnAsynCall` flag. - experimental optional Runtime.StackTraceId asyncCallStackTraceId + # Never present, will be removed. + experimental deprecated optional Runtime.StackTraceId asyncCallStackTraceId # Fired when the virtual machine resumed execution. event resumed @@ -1243,9 +1251,12 @@ domain Runtime # resolved. optional boolean awaitPromise # Whether to throw an exception if side effect cannot be ruled out during evaluation. + # This implies `disableBreaks` below. experimental optional boolean throwOnSideEffect # Terminate execution after timing out (number of milliseconds). experimental optional TimeDelta timeout + # Disable breakpoints during execution. + experimental optional boolean disableBreaks returns # Evaluation result. RemoteObject result diff --git a/deps/v8/include/libplatform/libplatform.h b/deps/v8/include/libplatform/libplatform.h index 6908aeaa88a1b0..18d585d6d9e314 100644 --- a/deps/v8/include/libplatform/libplatform.h +++ b/deps/v8/include/libplatform/libplatform.h @@ -5,6 +5,8 @@ #ifndef V8_LIBPLATFORM_LIBPLATFORM_H_ #define V8_LIBPLATFORM_LIBPLATFORM_H_ +#include <memory> + #include "libplatform/libplatform-export.h" #include "libplatform/v8-tracing.h" #include "v8-platform.h" // NOLINT(build/include) @@ -70,11 +72,10 @@ V8_PLATFORM_EXPORT void RunIdleTasks(v8::Platform* platform, * The |platform| has to be created using |NewDefaultPlatform|. * */ -V8_PLATFORM_EXPORT V8_DEPRECATE_SOON( - "Access the DefaultPlatform directly", - void SetTracingController( - v8::Platform* platform, - v8::platform::tracing::TracingController* tracing_controller)); +V8_DEPRECATE_SOON("Access the DefaultPlatform directly") +V8_PLATFORM_EXPORT void SetTracingController( + v8::Platform* platform, + v8::platform::tracing::TracingController* tracing_controller); } // namespace platform } // namespace v8 diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h index cfa2aaba96d12e..5f53f21d55302d 100644 --- a/deps/v8/include/v8-inspector.h +++ b/deps/v8/include/v8-inspector.h @@ -24,6 +24,7 @@ namespace Runtime { namespace API { class RemoteObject; class StackTrace; +class StackTraceId; } } namespace Schema { @@ -229,12 +230,20 @@ class V8_EXPORT V8InspectorClient { struct V8_EXPORT V8StackTraceId { uintptr_t id; std::pair<int64_t, int64_t> debugger_id; + bool should_pause = false; V8StackTraceId(); + V8StackTraceId(const V8StackTraceId&) = default; V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id); + V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id, + bool should_pause); + explicit V8StackTraceId(const StringView&); + V8StackTraceId& operator=(const V8StackTraceId&) = default; + V8StackTraceId& operator=(V8StackTraceId&&) noexcept = default; ~V8StackTraceId() = default; bool IsInvalid() const; + std::unique_ptr<StringBuffer> ToString(); }; class V8_EXPORT V8Inspector { diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index 6ecddf45d6ae92..29f391b673a1b8 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -112,6 +112,8 @@ using PlatformSmiTagging = SmiTagging<kApiInt32Size>; using PlatformSmiTagging = SmiTagging<kApiTaggedSize>; #endif +// TODO(ishell): Consinder adding kSmiShiftBits = kSmiShiftSize + kSmiTagSize +// since it's used much more often than the inividual constants. const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize; const int kSmiMinValue = static_cast<int>(PlatformSmiTagging::kSmiMinValue); @@ -327,14 +329,11 @@ class Internals { #ifdef V8_COMPRESS_POINTERS // See v8:7703 or src/ptr-compr.* for details about pointer compression. static constexpr size_t kPtrComprHeapReservationSize = size_t{1} << 32; - static constexpr size_t kPtrComprIsolateRootBias = - kPtrComprHeapReservationSize / 2; static constexpr size_t kPtrComprIsolateRootAlignment = size_t{1} << 32; V8_INLINE static internal::Address GetRootFromOnHeapAddress( internal::Address addr) { - return (addr + kPtrComprIsolateRootBias) & - -static_cast<intptr_t>(kPtrComprIsolateRootAlignment); + return addr & -static_cast<intptr_t>(kPtrComprIsolateRootAlignment); } V8_INLINE static internal::Address DecompressTaggedAnyField( @@ -381,6 +380,10 @@ V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj); // language mode is strict. V8_EXPORT bool ShouldThrowOnError(v8::internal::Isolate* isolate); +// A base class for backing stores, which is needed due to vagaries of +// how static casts work with std::shared_ptr. +class BackingStoreBase {}; + } // namespace internal } // namespace v8 diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index b707fafc49229a..c6e78f238197df 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -367,9 +367,8 @@ class Platform { * |isolate|. Tasks posted for the same isolate should be execute in order of * scheduling. The definition of "foreground" is opaque to V8. */ - V8_DEPRECATE_SOON( - "Use a taskrunner acquired by GetForegroundTaskRunner instead.", - virtual void CallOnForegroundThread(Isolate* isolate, Task* task)) = 0; + V8_DEPRECATED("Use a taskrunner acquired by GetForegroundTaskRunner instead.") + virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0; /** * Schedules a task to be invoked on a foreground thread wrt a specific @@ -377,10 +376,9 @@ class Platform { * Tasks posted for the same isolate should be execute in order of * scheduling. The definition of "foreground" is opaque to V8. */ - V8_DEPRECATE_SOON( - "Use a taskrunner acquired by GetForegroundTaskRunner instead.", - virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, - double delay_in_seconds)) = 0; + V8_DEPRECATED("Use a taskrunner acquired by GetForegroundTaskRunner instead.") + virtual void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, + double delay_in_seconds) = 0; /** * Schedules a task to be invoked on a foreground thread wrt a specific @@ -390,10 +388,8 @@ class Platform { * starved for an arbitrarily long time if no idle time is available. * The definition of "foreground" is opaque to V8. */ - V8_DEPRECATE_SOON( - "Use a taskrunner acquired by GetForegroundTaskRunner instead.", - virtual void CallIdleOnForegroundThread(Isolate* isolate, - IdleTask* task)) { + V8_DEPRECATED("Use a taskrunner acquired by GetForegroundTaskRunner instead.") + virtual void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) { // This must be overriden if |IdleTasksEnabled()|. abort(); } diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 360850b631c7f9..b58534c89d9ffb 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -6,8 +6,10 @@ #define V8_V8_PROFILER_H_ #include <limits.h> +#include <memory> #include <unordered_set> #include <vector> + #include "v8.h" // NOLINT(build/include) /** @@ -143,9 +145,8 @@ class V8_EXPORT CpuProfileNode { unsigned GetHitCount() const; /** Returns function entry UID. */ - V8_DEPRECATE_SOON( - "Use GetScriptId, GetLineNumber, and GetColumnNumber instead.", - unsigned GetCallUid() const); + V8_DEPRECATED("Use GetScriptId, GetLineNumber, and GetColumnNumber instead.") + unsigned GetCallUid() const; /** Returns id of the node. The id is unique within the tree */ unsigned GetNodeId() const; @@ -375,14 +376,14 @@ class V8_EXPORT CpuProfiler { * Recording the forced sample does not contribute to the aggregated * profile statistics. */ - V8_DEPRECATED("Use static CollectSample(Isolate*) instead.", - void CollectSample()); + V8_DEPRECATED("Use static CollectSample(Isolate*) instead.") + void CollectSample(); /** * Tells the profiler whether the embedder is idle. */ - V8_DEPRECATED("Use Isolate::SetIdle(bool) instead.", - void SetIdle(bool is_idle)); + V8_DEPRECATED("Use Isolate::SetIdle(bool) instead.") + void SetIdle(bool is_idle); /** * Generate more detailed source positions to code objects. This results in @@ -989,7 +990,8 @@ struct HeapStatsUpdate { V(LazyCompile) \ V(RegExp) \ V(Script) \ - V(Stub) + V(Stub) \ + V(Relocation) /** * Note that this enum may be extended in the future. Please include a default @@ -1022,10 +1024,12 @@ class V8_EXPORT CodeEvent { const char* GetComment(); static const char* GetCodeEventTypeName(CodeEventType code_event_type); + + uintptr_t GetPreviousCodeStartAddress(); }; /** - * Interface to listen to code creation events. + * Interface to listen to code creation and code relocation events. */ class V8_EXPORT CodeEventHandler { public: @@ -1037,9 +1041,26 @@ class V8_EXPORT CodeEventHandler { explicit CodeEventHandler(Isolate* isolate); virtual ~CodeEventHandler(); + /** + * Handle is called every time a code object is created or moved. Information + * about each code event will be available through the `code_event` + * parameter. + * + * When the CodeEventType is kRelocationType, the code for this CodeEvent has + * moved from `GetPreviousCodeStartAddress()` to `GetCodeStartAddress()`. + */ virtual void Handle(CodeEvent* code_event) = 0; + /** + * Call `Enable()` to starts listening to code creation and code relocation + * events. These events will be handled by `Handle()`. + */ void Enable(); + + /** + * Call `Disable()` to stop listening to code creation and code relocation + * events. + */ void Disable(); private: diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index ef90963d2540d1..8970c573efda6f 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -9,9 +9,9 @@ // NOTE these macros are used by some of the tool scripts and the build // system so their names cannot be changed without changing the scripts. #define V8_MAJOR_VERSION 7 -#define V8_MINOR_VERSION 8 -#define V8_BUILD_NUMBER 279 -#define V8_PATCH_LEVEL 17 +#define V8_MINOR_VERSION 9 +#define V8_BUILD_NUMBER 317 +#define V8_PATCH_LEVEL 23 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 9d0b6a6c65479e..dc75012b2e4921 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -97,6 +97,10 @@ template <class T> class Global; template <class T> class TracedGlobal; +template <class T> +class TracedReference; +template <class T> +class TracedReferenceBase; template<class K, class V, class T> class PersistentValueMap; template <class K, class V, class T> class PersistentValueMapBase; @@ -282,7 +286,8 @@ class Local { V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that); V8_INLINE static Local<T> New(Isolate* isolate, const PersistentBase<T>& that); - V8_INLINE static Local<T> New(Isolate* isolate, const TracedGlobal<T>& that); + V8_INLINE static Local<T> New(Isolate* isolate, + const TracedReferenceBase<T>& that); private: friend class Utils; @@ -312,7 +317,13 @@ class Local { template <class F> friend class ReturnValue; template <class F> + friend class Traced; + template <class F> friend class TracedGlobal; + template <class F> + friend class TracedReferenceBase; + template <class F> + friend class TracedReference; explicit V8_INLINE Local(T* that) : val_(that) {} V8_INLINE static Local<T> New(Isolate* isolate, T* that); @@ -793,22 +804,10 @@ template <class T> using UniquePersistent = Global<T>; /** - * Trait specifying behavior of |TracedGlobal<T>|. + * Deprecated. Use |TracedReference<T>| instead. */ template <typename T> -struct TracedGlobalTrait { - /** - * Specifies whether |TracedGlobal<T>| should clear its handle on destruction. - * - * V8 will *not* clear the embedder-side memory of the handle. The embedder is - * expected to report all |TracedGlobal<T>| handles through - * |EmbedderHeapTracer| upon garabge collection. - * - * See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with - * non-tracing GCs in V8. - */ - static constexpr bool kRequiresExplicitDestruction = true; -}; +struct TracedGlobalTrait {}; /** * A traced handle with copy and move semantics. The handle is to be used @@ -821,15 +820,131 @@ struct TracedGlobalTrait { * |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should * be treated as root or not. * - * For destruction semantics see |TracedGlobalTrait<T>|. + * Note that the base class cannot be instantiated itself. Choose from + * - TracedGlobal + * - TracedReference */ template <typename T> -class TracedGlobal { +class TracedReferenceBase { public: + /** + * Returns true if this TracedReferenceBase is empty, i.e., has not been + * assigned an object. + */ + bool IsEmpty() const { return val_ == nullptr; } + + /** + * If non-empty, destroy the underlying storage cell. |IsEmpty| will return + * true after this call. + */ + V8_INLINE void Reset(); + + /** + * Construct a Local<T> from this handle. + */ + Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); } + + template <class S> + V8_INLINE bool operator==(const TracedReferenceBase<S>& that) const { + internal::Address* a = reinterpret_cast<internal::Address*>(val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + if (a == nullptr) return b == nullptr; + if (b == nullptr) return false; + return *a == *b; + } + + template <class S> + V8_INLINE bool operator==(const Local<S>& that) const { + internal::Address* a = reinterpret_cast<internal::Address*>(val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); + if (a == nullptr) return b == nullptr; + if (b == nullptr) return false; + return *a == *b; + } + + template <class S> + V8_INLINE bool operator!=(const TracedReferenceBase<S>& that) const { + return !operator==(that); + } + + template <class S> + V8_INLINE bool operator!=(const Local<S>& that) const { + return !operator==(that); + } + + /** + * Assigns a wrapper class ID to the handle. + */ + V8_INLINE void SetWrapperClassId(uint16_t class_id); + + /** + * Returns the class ID previously assigned to this handle or 0 if no class ID + * was previously assigned. + */ + V8_INLINE uint16_t WrapperClassId() const; + + /** + * Adds a finalization callback to the handle. The type of this callback is + * similar to WeakCallbackType::kInternalFields, i.e., it will pass the + * parameter and the first two internal fields of the object. + * + * The callback is then supposed to reset the handle in the callback. No + * further V8 API may be called in this callback. In case additional work + * involving V8 needs to be done, a second callback can be scheduled using + * WeakCallbackInfo<void>::SetSecondPassCallback. + */ + V8_INLINE void SetFinalizationCallback( + void* parameter, WeakCallbackInfo<void>::Callback callback); + + template <class S> + V8_INLINE TracedReferenceBase<S>& As() const { + return reinterpret_cast<TracedReferenceBase<S>&>( + const_cast<TracedReferenceBase<T>&>(*this)); + } + + private: + enum DestructionMode { kWithDestructor, kWithoutDestructor }; + + /** + * An empty TracedReferenceBase without storage cell. + */ + TracedReferenceBase() = default; + + V8_INLINE static T* New(Isolate* isolate, T* that, void* slot, + DestructionMode destruction_mode); + + T* val_ = nullptr; + + friend class EmbedderHeapTracer; + template <typename F> + friend class Local; + friend class Object; + template <typename F> + friend class TracedGlobal; + template <typename F> + friend class TracedReference; + template <typename F> + friend class ReturnValue; +}; + +/** + * A traced handle with destructor that clears the handle. For more details see + * TracedReferenceBase. + */ +template <typename T> +class TracedGlobal : public TracedReferenceBase<T> { + public: + using TracedReferenceBase<T>::Reset; + + /** + * Destructor resetting the handle. + */ + ~TracedGlobal() { this->Reset(); } + /** * An empty TracedGlobal without storage cell. */ - TracedGlobal() = default; + TracedGlobal() : TracedReferenceBase<T>() {} /** * Construct a TracedGlobal from a Local. @@ -838,8 +953,9 @@ class TracedGlobal { * pointing to the same object. */ template <class S> - TracedGlobal(Isolate* isolate, Local<S> that) - : val_(New(isolate, *that, &val_)) { + TracedGlobal(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() { + this->val_ = this->New(isolate, that.val_, &this->val_, + TracedReferenceBase<T>::kWithDestructor); TYPE_CHECK(T, S); } @@ -905,18 +1021,6 @@ class TracedGlobal { template <class S> V8_INLINE TracedGlobal& operator=(const TracedGlobal<S>& rhs); - /** - * Returns true if this TracedGlobal is empty, i.e., has not been assigned an - * object. - */ - bool IsEmpty() const { return val_ == nullptr; } - - /** - * If non-empty, destroy the underlying storage cell. |IsEmpty| will return - * true after this call. - */ - V8_INLINE void Reset(); - /** * If non-empty, destroy the underlying storage cell and create a new one with * the contents of other if other is non empty @@ -924,103 +1028,120 @@ class TracedGlobal { template <class S> V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); - /** - * Construct a Local<T> from this handle. - */ - Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); } - template <class S> V8_INLINE TracedGlobal<S>& As() const { return reinterpret_cast<TracedGlobal<S>&>( const_cast<TracedGlobal<T>&>(*this)); } +}; - template <class S> - V8_INLINE bool operator==(const TracedGlobal<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(**this); - internal::Address* b = reinterpret_cast<internal::Address*>(*that); - if (a == nullptr) return b == nullptr; - if (b == nullptr) return false; - return *a == *b; - } +/** + * A traced handle without destructor that clears the handle. The embedder needs + * to ensure that the handle is not accessed once the V8 object has been + * reclaimed. This can happen when the handle is not passed through the + * EmbedderHeapTracer. For more details see TracedReferenceBase. + */ +template <typename T> +class TracedReference : public TracedReferenceBase<T> { + public: + using TracedReferenceBase<T>::Reset; + + /** + * An empty TracedReference without storage cell. + */ + TracedReference() : TracedReferenceBase<T>() {} + /** + * Construct a TracedReference from a Local. + * + * When the Local is non-empty, a new storage cell is created + * pointing to the same object. + */ template <class S> - V8_INLINE bool operator==(const Local<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(**this); - internal::Address* b = reinterpret_cast<internal::Address*>(*that); - if (a == nullptr) return b == nullptr; - if (b == nullptr) return false; - return *a == *b; + TracedReference(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() { + this->val_ = this->New(isolate, that.val_, &this->val_, + TracedReferenceBase<T>::kWithoutDestructor); + TYPE_CHECK(T, S); } - template <class S> - V8_INLINE bool operator!=(const TracedGlobal<S>& that) const { - return !operator==(that); + /** + * Move constructor initializing TracedReference from an + * existing one. + */ + V8_INLINE TracedReference(TracedReference&& other) { + // Forward to operator=. + *this = std::move(other); } - template <class S> - V8_INLINE bool operator!=(const Local<S>& that) const { - return !operator==(that); + /** + * Move constructor initializing TracedReference from an + * existing one. + */ + template <typename S> + V8_INLINE TracedReference(TracedReference<S>&& other) { + // Forward to operator=. + *this = std::move(other); } /** - * Assigns a wrapper class ID to the handle. + * Copy constructor initializing TracedReference from an + * existing one. */ - V8_INLINE void SetWrapperClassId(uint16_t class_id); + V8_INLINE TracedReference(const TracedReference& other) { + // Forward to operator=; + *this = other; + } /** - * Returns the class ID previously assigned to this handle or 0 if no class ID - * was previously assigned. + * Copy constructor initializing TracedReference from an + * existing one. */ - V8_INLINE uint16_t WrapperClassId() const; + template <typename S> + V8_INLINE TracedReference(const TracedReference<S>& other) { + // Forward to operator=; + *this = other; + } /** - * Adds a finalization callback to the handle. The type of this callback is - * similar to WeakCallbackType::kInternalFields, i.e., it will pass the - * parameter and the first two internal fields of the object. - * - * The callback is then supposed to reset the handle in the callback. No - * further V8 API may be called in this callback. In case additional work - * involving V8 needs to be done, a second callback can be scheduled using - * WeakCallbackInfo<void>::SetSecondPassCallback. + * Move assignment operator initializing TracedGlobal from an existing one. */ - V8_INLINE void SetFinalizationCallback( - void* parameter, WeakCallbackInfo<void>::Callback callback); + V8_INLINE TracedReference& operator=(TracedReference&& rhs); - private: - // Wrapping type used when clearing on destruction is required. - struct WrappedForDestruction { - T* value; - - explicit WrappedForDestruction(T* val) : value(val) {} - ~WrappedForDestruction(); - operator T*() const { return value; } - T* operator*() const { return value; } - T* operator->() const { return value; } - WrappedForDestruction& operator=(const WrappedForDestruction& other) { - value = other.value; - return *this; - } - WrappedForDestruction& operator=(T* val) { - value = val; - return *this; - } - }; + /** + * Move assignment operator initializing TracedGlobal from an existing one. + */ + template <class S> + V8_INLINE TracedReference& operator=(TracedReference<S>&& rhs); - V8_INLINE static T* New(Isolate* isolate, T* that, void* slot); + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + V8_INLINE TracedReference& operator=(const TracedReference& rhs); - T* operator*() const { return this->val_; } + /** + * Copy assignment operator initializing TracedGlobal from an existing one. + * + * Note: Prohibited when |other| has a finalization callback set through + * |SetFinalizationCallback|. + */ + template <class S> + V8_INLINE TracedReference& operator=(const TracedReference<S>& rhs); - typename std::conditional< - TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction, - WrappedForDestruction, T*>::type val_{nullptr}; + /** + * If non-empty, destroy the underlying storage cell and create a new one with + * the contents of other if other is non empty + */ + template <class S> + V8_INLINE void Reset(Isolate* isolate, const Local<S>& other); - friend class EmbedderHeapTracer; - template <typename F> - friend class Local; - friend class Object; - template <typename F> - friend class ReturnValue; + template <class S> + V8_INLINE TracedReference<S>& As() const { + return reinterpret_cast<TracedReference<S>&>( + const_cast<TracedReference<T>&>(*this)); + } }; /** @@ -1450,9 +1571,9 @@ class V8_EXPORT Module { "Use the preceding SetSyntheticModuleExport with an Isolate parameter, " "instead of the one that follows. The former will throw a runtime " "error if called for an export that doesn't exist (as per spec); " - "the latter will crash with a failed CHECK().", - void SetSyntheticModuleExport(Local<String> export_name, - Local<Value> export_value)); + "the latter will crash with a failed CHECK().") + void SetSyntheticModuleExport(Local<String> export_name, + Local<Value> export_value); }; /** @@ -1626,10 +1747,12 @@ class V8_EXPORT ScriptCompiler { public: enum Encoding { ONE_BYTE, TWO_BYTE, UTF8 }; +#if defined(_MSC_VER) && _MSC_VER >= 1910 /* Disable on VS2015 */ V8_DEPRECATE_SOON( "This class takes ownership of source_stream, so use the constructor " - "taking a unique_ptr to make these semantics clearer", - StreamedSource(ExternalSourceStream* source_stream, Encoding encoding)); + "taking a unique_ptr to make these semantics clearer") +#endif + StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); StreamedSource(std::unique_ptr<ExternalSourceStream> source_stream, Encoding encoding); ~StreamedSource(); @@ -3405,7 +3528,7 @@ enum class IndexFilter { kIncludeIndices, kSkipIndices }; * kConvertToString will convert integer indices to strings. * kKeepNumbers will return numbers for integer indices. */ -enum class KeyConversionMode { kConvertToString, kKeepNumbers }; +enum class KeyConversionMode { kConvertToString, kKeepNumbers, kNoNumbers }; /** * Integrity level for objects. @@ -3649,8 +3772,9 @@ class V8_EXPORT Object : public Value { return object.val_->InternalFieldCount(); } - /** Same as above, but works for TracedGlobal. */ - V8_INLINE static int InternalFieldCount(const TracedGlobal<Object>& object) { + /** Same as above, but works for TracedReferenceBase. */ + V8_INLINE static int InternalFieldCount( + const TracedReferenceBase<Object>& object) { return object.val_->InternalFieldCount(); } @@ -3675,7 +3799,7 @@ class V8_EXPORT Object : public Value { /** Same as above, but works for TracedGlobal. */ V8_INLINE static void* GetAlignedPointerFromInternalField( - const TracedGlobal<Object>& object, int index) { + const TracedReferenceBase<Object>& object, int index) { return object.val_->GetAlignedPointerFromInternalField(index); } @@ -3965,7 +4089,7 @@ class ReturnValue { template <typename S> V8_INLINE void Set(const Global<S>& handle); template <typename S> - V8_INLINE void Set(const TracedGlobal<S>& handle); + V8_INLINE void Set(const TracedReferenceBase<S>& handle); template <typename S> V8_INLINE void Set(const Local<S> handle); // Fast primitive setters @@ -4720,6 +4844,45 @@ class V8_EXPORT WasmModuleObjectBuilderStreaming final { enum class ArrayBufferCreationMode { kInternalized, kExternalized }; +/** + * A wrapper around the backing store (i.e. the raw memory) of an array buffer. + * + * The allocation and destruction of backing stores is generally managed by + * V8. Clients should always use standard C++ memory ownership types (i.e. + * std::unique_ptr and std::shared_ptr) to manage lifetimes of backing stores + * properly, since V8 internal objects may alias backing stores. + * + * This object does not keep the underlying |ArrayBuffer::Allocator| alive by + * default. Use Isolate::CreateParams::array_buffer_allocator_shared when + * creating the Isolate to make it hold a reference to the allocator itself. + */ +class V8_EXPORT BackingStore : public v8::internal::BackingStoreBase { + public: + ~BackingStore(); + + /** + * Return a pointer to the beginning of the memory block for this backing + * store. The pointer is only valid as long as this backing store object + * lives. + */ + void* Data() const; + + /** + * The length (in bytes) of this backing store. + */ + size_t ByteLength() const; + + private: + BackingStore(); +}; + +/** + * This callback is used only if the memory block for this backing store cannot + * be allocated with an ArrayBuffer::Allocator. In such cases the destructor + * of this backing store object invokes the callback to free the memory block. + */ +using BackingStoreDeleterCallback = void (*)(void* data, size_t length, + void* deleter_data); /** * An instance of the built-in ArrayBuffer constructor (ES6 draft 15.13.5). @@ -4856,6 +5019,44 @@ class V8_EXPORT ArrayBuffer : public Object { Isolate* isolate, void* data, size_t byte_length, ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); + /** + * Create a new ArrayBuffer with an existing backing store. + * The created array keeps a reference to the backing store until the array + * is garbage collected. Note that the IsExternal bit does not affect this + * reference from the array to the backing store. + * + * In future IsExternal bit will be removed. Until then the bit is set as + * follows. If the backing store does not own the underlying buffer, then + * the array is created in externalized state. Otherwise, the array is created + * in internalized state. In the latter case the array can be transitioned + * to the externalized state using Externalize(backing_store). + */ + static Local<ArrayBuffer> New(Isolate* isolate, + std::shared_ptr<BackingStore> backing_store); + + /** + * Returns a new standalone BackingStore that is allocated using the array + * buffer allocator of the isolate. The result can be later passed to + * ArrayBuffer::New. + * + * If the allocator returns nullptr, then the function may cause GCs in the + * given isolate and re-try the allocation. If GCs do not help, then the + * function will crash with an out-of-memory error. + */ + static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate, + size_t byte_length); + /** + * Returns a new standalone BackingStore that takes over the ownership of + * the given buffer. The destructor of the BackingStore invokes the given + * deleter callback. + * + * The result can be later passed to ArrayBuffer::New. The raw pointer + * to the buffer must not be passed again to any V8 API function. + */ + static std::unique_ptr<BackingStore> NewBackingStore( + void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* deleter_data); + /** * Returns true if ArrayBuffer is externalized, that is, does not * own its memory block. @@ -4868,8 +5069,8 @@ class V8_EXPORT ArrayBuffer : public Object { bool IsDetachable() const; // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATED("Use IsDetachable() instead.", - inline bool IsNeuterable() const) { + V8_DEPRECATED("Use IsDetachable() instead.") + inline bool IsNeuterable() const { return IsDetachable(); } @@ -4882,7 +5083,8 @@ class V8_EXPORT ArrayBuffer : public Object { void Detach(); // TODO(913887): fix the use of 'neuter' in the API. - V8_DEPRECATED("Use Detach() instead.", inline void Neuter()) { Detach(); } + V8_DEPRECATED("Use Detach() instead.") + inline void Neuter() { Detach(); } /** * Make this ArrayBuffer external. The pointer to underlying memory block @@ -4892,10 +5094,19 @@ class V8_EXPORT ArrayBuffer : public Object { * * The Data pointer of ArrayBuffer::Contents must be freed using the provided * deleter, which will call ArrayBuffer::Allocator::Free if the buffer - * was allocated with ArraryBuffer::Allocator::Allocate. + * was allocated with ArrayBuffer::Allocator::Allocate. */ Contents Externalize(); + /** + * Marks this ArrayBuffer external given a witness that the embedder + * has fetched the backing store using the new GetBackingStore() function. + * + * With the new lifetime management of backing stores there is no need for + * externalizing, so this function exists only to make the transition easier. + */ + void Externalize(const std::shared_ptr<BackingStore>& backing_store); + /** * Get a pointer to the ArrayBuffer's underlying memory block without * externalizing it. If the ArrayBuffer is not externalized, this pointer @@ -4906,6 +5117,16 @@ class V8_EXPORT ArrayBuffer : public Object { */ Contents GetContents(); + /** + * Get a shared pointer to the backing store of this array buffer. This + * pointer coordinates the lifetime management of the internal storage + * with any live ArrayBuffers on the heap, even across isolates. The embedder + * should not attempt to manage lifetime of the storage through other means. + * + * This function replaces both Externalize() and GetContents(). + */ + std::shared_ptr<BackingStore> GetBackingStore(); + V8_INLINE static ArrayBuffer* Cast(Value* obj); static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; @@ -4914,6 +5135,7 @@ class V8_EXPORT ArrayBuffer : public Object { private: ArrayBuffer(); static void CheckCast(Value* obj); + Contents GetContents(bool externalize); }; @@ -5280,15 +5502,52 @@ class V8_EXPORT SharedArrayBuffer : public Object { Isolate* isolate, void* data, size_t byte_length, ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); + /** + * Create a new SharedArrayBuffer with an existing backing store. + * The created array keeps a reference to the backing store until the array + * is garbage collected. Note that the IsExternal bit does not affect this + * reference from the array to the backing store. + * + * In future IsExternal bit will be removed. Until then the bit is set as + * follows. If the backing store does not own the underlying buffer, then + * the array is created in externalized state. Otherwise, the array is created + * in internalized state. In the latter case the array can be transitioned + * to the externalized state using Externalize(backing_store). + */ + static Local<SharedArrayBuffer> New( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store); + + /** + * Returns a new standalone BackingStore that is allocated using the array + * buffer allocator of the isolate. The result can be later passed to + * SharedArrayBuffer::New. + * + * If the allocator returns nullptr, then the function may cause GCs in the + * given isolate and re-try the allocation. If GCs do not help, then the + * function will crash with an out-of-memory error. + */ + static std::unique_ptr<BackingStore> NewBackingStore(Isolate* isolate, + size_t byte_length); + /** + * Returns a new standalone BackingStore that takes over the ownership of + * the given buffer. The destructor of the BackingStore invokes the given + * deleter callback. + * + * The result can be later passed to SharedArrayBuffer::New. The raw pointer + * to the buffer must not be passed again to any V8 functions. + */ + static std::unique_ptr<BackingStore> NewBackingStore( + void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* deleter_data); + /** * Create a new SharedArrayBuffer over an existing memory block. Propagate * flags to indicate whether the underlying buffer can be grown. */ - V8_DEPRECATED("Use New method with data, and byte_length instead.", - static Local<SharedArrayBuffer> New( - Isolate* isolate, const SharedArrayBuffer::Contents&, - ArrayBufferCreationMode mode = - ArrayBufferCreationMode::kExternalized)); + V8_DEPRECATED("Use New method with data, and byte_length instead.") + static Local<SharedArrayBuffer> New( + Isolate* isolate, const SharedArrayBuffer::Contents&, + ArrayBufferCreationMode mode = ArrayBufferCreationMode::kExternalized); /** * Returns true if SharedArrayBuffer is externalized, that is, does not @@ -5310,6 +5569,15 @@ class V8_EXPORT SharedArrayBuffer : public Object { */ Contents Externalize(); + /** + * Marks this SharedArrayBuffer external given a witness that the embedder + * has fetched the backing store using the new GetBackingStore() function. + * + * With the new lifetime management of backing stores there is no need for + * externalizing, so this function exists only to make the transition easier. + */ + void Externalize(const std::shared_ptr<BackingStore>& backing_store); + /** * Get a pointer to the ArrayBuffer's underlying memory block without * externalizing it. If the ArrayBuffer is not externalized, this pointer @@ -5324,6 +5592,16 @@ class V8_EXPORT SharedArrayBuffer : public Object { */ Contents GetContents(); + /** + * Get a shared pointer to the backing store of this array buffer. This + * pointer coordinates the lifetime management of the internal storage + * with any live ArrayBuffers on the heap, even across isolates. The embedder + * should not attempt to manage lifetime of the storage through other means. + * + * This function replaces both Externalize() and GetContents(). + */ + std::shared_ptr<BackingStore> GetBackingStore(); + V8_INLINE static SharedArrayBuffer* Cast(Value* obj); static const int kInternalFieldCount = V8_ARRAY_BUFFER_INTERNAL_FIELD_COUNT; @@ -5331,6 +5609,7 @@ class V8_EXPORT SharedArrayBuffer : public Object { private: SharedArrayBuffer(); static void CheckCast(Value* obj); + Contents GetContents(bool externalize); }; @@ -6655,34 +6934,26 @@ class V8_EXPORT ResourceConstraints { /** * Deprecated functions. Do not use in new code. */ - V8_DEPRECATE_SOON("Use code_range_size_in_bytes.", - size_t code_range_size() const) { - return code_range_size_ / kMB; - } - V8_DEPRECATE_SOON("Use set_code_range_size_in_bytes.", - void set_code_range_size(size_t limit_in_mb)) { + V8_DEPRECATE_SOON("Use code_range_size_in_bytes.") + size_t code_range_size() const { return code_range_size_ / kMB; } + V8_DEPRECATE_SOON("Use set_code_range_size_in_bytes.") + void set_code_range_size(size_t limit_in_mb) { code_range_size_ = limit_in_mb * kMB; } - V8_DEPRECATE_SOON("Use max_young_generation_size_in_bytes.", - size_t max_semi_space_size_in_kb() const); - V8_DEPRECATE_SOON("Use set_max_young_generation_size_in_bytes.", - void set_max_semi_space_size_in_kb(size_t limit_in_kb)); - V8_DEPRECATE_SOON("Use max_old_generation_size_in_bytes.", - size_t max_old_space_size() const) { - return max_old_generation_size_ / kMB; - } - V8_DEPRECATE_SOON("Use set_max_old_generation_size_in_bytes.", - void set_max_old_space_size(size_t limit_in_mb)) { + V8_DEPRECATE_SOON("Use max_young_generation_size_in_bytes.") + size_t max_semi_space_size_in_kb() const; + V8_DEPRECATE_SOON("Use set_max_young_generation_size_in_bytes.") + void set_max_semi_space_size_in_kb(size_t limit_in_kb); + V8_DEPRECATE_SOON("Use max_old_generation_size_in_bytes.") + size_t max_old_space_size() const { return max_old_generation_size_ / kMB; } + V8_DEPRECATE_SOON("Use set_max_old_generation_size_in_bytes.") + void set_max_old_space_size(size_t limit_in_mb) { max_old_generation_size_ = limit_in_mb * kMB; } - V8_DEPRECATE_SOON("Zone does not pool memory any more.", - size_t max_zone_pool_size() const) { - return max_zone_pool_size_; - } - V8_DEPRECATE_SOON("Zone does not pool memory any more.", - void set_max_zone_pool_size(size_t bytes)) { - max_zone_pool_size_ = bytes; - } + V8_DEPRECATE_SOON("Zone does not pool memory any more.") + size_t max_zone_pool_size() const { return max_zone_pool_size_; } + V8_DEPRECATE_SOON("Zone does not pool memory any more.") + void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; } private: static constexpr size_t kMB = 1048576u; @@ -6756,6 +7027,7 @@ enum class CrashKeyId { kReadonlySpaceFirstPageAddress, kMapSpaceFirstPageAddress, kCodeSpaceFirstPageAddress, + kDumpType, }; typedef void (*AddCrashKeyCallback)(CrashKeyId id, const std::string& value); @@ -7384,7 +7656,8 @@ class V8_EXPORT EmbedderHeapTracer { class V8_EXPORT TracedGlobalHandleVisitor { public: virtual ~TracedGlobalHandleVisitor() = default; - virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& value) = 0; + virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& handle) {} + virtual void VisitTracedReference(const TracedReference<Value>& handle) {} }; /** @@ -7422,13 +7695,12 @@ class V8_EXPORT EmbedderHeapTracer { virtual void RegisterV8References( const std::vector<std::pair<void*, void*> >& embedder_fields) = 0; - void RegisterEmbedderReference(const TracedGlobal<v8::Value>& ref); + void RegisterEmbedderReference(const TracedReferenceBase<v8::Value>& ref); /** * Called at the beginning of a GC cycle. */ - V8_DEPRECATED("Use version with flags.", virtual void TracePrologue()) {} - virtual void TracePrologue(TraceFlags flags); + virtual void TracePrologue(TraceFlags flags) {} /** * Called to advance tracing in the embedder. @@ -7455,8 +7727,7 @@ class V8_EXPORT EmbedderHeapTracer { * overriden to fill a |TraceSummary| that is used by V8 to schedule future * garbage collections. */ - V8_DEPRECATE_SOON("Use version with parameter.", - virtual void TraceEpilogue()) {} + V8_DEPRECATED("Use version with parameter.") virtual void TraceEpilogue() {} virtual void TraceEpilogue(TraceSummary* trace_summary); /** @@ -7483,32 +7754,35 @@ class V8_EXPORT EmbedderHeapTracer { * * If this returns false, then V8 may decide that the object referred to by * such a handle is reclaimed. In that case: - * - No action is required if handles are used with destructors. - * - When run without destructors (by specializing - * |TracedGlobalTrait::kRequiresExplicitDestruction|) V8 calls - * |ResetHandleInNonTracingGC|. + * - No action is required if handles are used with destructors, i.e., by just + * using |TracedGlobal|. + * - When run without destructors, i.e., by using + * |TracedReference|, V8 calls |ResetHandleInNonTracingGC|. * - * Note that the |handle| is different from the |TracedGlobal<T>| handle that - * the embedder holds for retaining the object. The embedder may use - * |TracedGlobal<T>::WrapperClassId()| to distinguish cases where it wants - * handles to be treated as roots from not being treated as roots. + * Note that the |handle| is different from the handle that the embedder holds + * for retaining the object. The embedder may use |WrapperClassId()| to + * distinguish cases where it wants handles to be treated as roots from not + * being treated as roots. */ virtual bool IsRootForNonTracingGC( - const v8::TracedGlobal<v8::Value>& handle) { - return true; - } + const v8::TracedReference<v8::Value>& handle); + virtual bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle); /** * Used in combination with |IsRootForNonTracingGC|. Called by V8 when an * object that is backed by a handle is reclaimed by a non-tracing garbage * collection. It is up to the embedder to reset the original handle. * - * Note that the |handle| is different from the |TracedGlobal<T>| handle that - * the embedder holds for retaining the object. It is up to the embedder to - * find the orignal |TracedGlobal<T>| handle via the object or class id. + * Note that the |handle| is different from the handle that the embedder holds + * for retaining the object. It is up to the embedder to find the original + * handle via the object or class id. */ virtual void ResetHandleInNonTracingGC( - const v8::TracedGlobal<v8::Value>& handle) {} + const v8::TracedReference<v8::Value>& handle); + V8_DEPRECATE_SOON( + "Use TracedReference version when not requiring destructors.") + virtual void ResetHandleInNonTracingGC( + const v8::TracedGlobal<v8::Value>& handle); /* * Called by the embedder to immediately perform a full garbage collection. @@ -7575,6 +7849,8 @@ struct DeserializeInternalFieldsCallback { }; typedef DeserializeInternalFieldsCallback DeserializeEmbedderFieldsCallback; +enum class MeasureMemoryMode { kSummary, kDetailed }; + /** * Isolate represents an isolated instance of the V8 engine. V8 isolates have * completely separate states. Objects from one isolate must not be used in @@ -7635,6 +7911,11 @@ class V8_EXPORT Isolate { /** * The ArrayBuffer::Allocator to use for allocating and freeing the backing * store of ArrayBuffers. + * + * If the shared_ptr version is used, the Isolate instance and every + * |BackingStore| allocated using this allocator hold a std::shared_ptr + * to the allocator, in order to facilitate lifetime + * management for the allocator instance. */ ArrayBuffer::Allocator* array_buffer_allocator; @@ -7658,6 +7939,9 @@ class V8_EXPORT Isolate { bool only_terminate_in_safe_scope; }; + void SetArrayBufferAllocatorShared( + std::shared_ptr<ArrayBuffer::Allocator> allocator); + /** * Stack-allocated class which sets the isolate for all operations @@ -8095,6 +8379,17 @@ class V8_EXPORT Isolate { */ bool GetHeapCodeAndMetadataStatistics(HeapCodeStatistics* object_statistics); + /** + * Enqueues a memory measurement request for the given context and mode. + * This API is experimental and may change significantly. + * + * \param mode Indicates whether the result should include per-context + * memory usage or just the total memory usage. + * \returns a promise that will be resolved with memory usage estimate. + */ + v8::MaybeLocal<v8::Promise> MeasureMemory(v8::Local<v8::Context> context, + MeasureMemoryMode mode); + /** * Get a call stack sample from the isolate. * \param state Execution state. @@ -8156,8 +8451,8 @@ class V8_EXPORT Isolate { Local<Context> GetCurrentContext(); /** Returns the last context entered through V8's C++ API. */ - V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().", - Local<Context> GetEnteredContext()); + V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().") + Local<Context> GetEnteredContext(); /** * Returns either the last context entered through V8's C++ API, or the @@ -8469,18 +8764,16 @@ class V8_EXPORT Isolate { * Executing scripts inside the callback will not re-trigger microtasks and * the callback. */ - V8_DEPRECATE_SOON("Use *WithData version.", - void AddMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback)); + V8_DEPRECATE_SOON("Use *WithData version.") + void AddMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void AddMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); /** * Removes callback that was installed by AddMicrotasksCompletedCallback. */ - V8_DEPRECATE_SOON("Use *WithData version.", - void RemoveMicrotasksCompletedCallback( - MicrotasksCompletedCallback callback)); + V8_DEPRECATE_SOON("Use *WithData version.") + void RemoveMicrotasksCompletedCallback(MicrotasksCompletedCallback callback); void RemoveMicrotasksCompletedCallback( MicrotasksCompletedCallbackWithData callback, void* data = nullptr); @@ -8910,6 +9203,7 @@ class V8_EXPORT V8 { * handled entirely on the embedders' side. * - The call will abort if the data is invalid. */ + V8_DEPRECATED("The natives blob is deprecated (https://crbug.com/v8/7624).") static void SetNativesDataBlob(StartupData* startup_blob); static void SetSnapshotDataBlob(StartupData* startup_blob); @@ -8922,8 +9216,8 @@ class V8_EXPORT V8 { */ static void SetFlagsFromString(const char* str); static void SetFlagsFromString(const char* str, size_t length); - V8_DEPRECATED("use size_t version", - static void SetFlagsFromString(const char* str, int length)); + V8_DEPRECATED("use size_t version") + static void SetFlagsFromString(const char* str, int length); /** * Sets V8 flags from the command line. @@ -9006,8 +9300,11 @@ class V8_EXPORT V8 { * not perform any file IO. */ static void InitializeExternalStartupData(const char* directory_path); + V8_DEPRECATED("The natives blob is deprecated (https://crbug.com/v8/7624).") static void InitializeExternalStartupData(const char* natives_blob, const char* snapshot_blob); + static void InitializeExternalStartupDataFromFile(const char* snapshot_blob); + /** * Sets the v8::Platform to use. This should be invoked before V8 is * initialized. @@ -9040,9 +9337,8 @@ class V8_EXPORT V8 { * \param context The third argument passed to the Linux signal handler, which * points to a ucontext_t structure. */ - V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix", - static bool TryHandleSignal(int signal_number, void* info, - void* context)); + V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix") + static bool TryHandleSignal(int signal_number, void* info, void* context); #endif // V8_OS_POSIX /** @@ -9111,8 +9407,12 @@ class V8_EXPORT V8 { template <class T> friend class Maybe; template <class T> + friend class TracedReferenceBase; + template <class T> friend class TracedGlobal; template <class T> + friend class TracedReference; + template <class T> friend class WeakCallbackInfo; template <class T> friend class Eternal; template <class T> friend class PersistentBase; @@ -9983,7 +10283,7 @@ Local<T> Local<T>::New(Isolate* isolate, const PersistentBase<T>& that) { } template <class T> -Local<T> Local<T>::New(Isolate* isolate, const TracedGlobal<T>& that) { +Local<T> Local<T>::New(Isolate* isolate, const TracedReferenceBase<T>& that) { return New(isolate, that.val_); } @@ -10164,26 +10464,20 @@ Global<T>& Global<T>::operator=(Global<S>&& rhs) { } template <class T> -TracedGlobal<T>::WrappedForDestruction::~WrappedForDestruction() { - if (value == nullptr) return; - V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(value)); - value = nullptr; -} - -template <class T> -T* TracedGlobal<T>::New(Isolate* isolate, T* that, void* slot) { +T* TracedReferenceBase<T>::New(Isolate* isolate, T* that, void* slot, + DestructionMode destruction_mode) { if (that == nullptr) return nullptr; internal::Address* p = reinterpret_cast<internal::Address*>(that); return reinterpret_cast<T*>(V8::GlobalizeTracedReference( reinterpret_cast<internal::Isolate*>(isolate), p, reinterpret_cast<internal::Address*>(slot), - TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction)); + destruction_mode == kWithDestructor)); } template <class T> -void TracedGlobal<T>::Reset() { +void TracedReferenceBase<T>::Reset() { if (IsEmpty()) return; - V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(**this)); + V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(val_)); val_ = nullptr; } @@ -10193,7 +10487,8 @@ void TracedGlobal<T>::Reset(Isolate* isolate, const Local<S>& other) { TYPE_CHECK(T, S); Reset(); if (other.IsEmpty()) return; - this->val_ = New(isolate, other.val_, &val_); + this->val_ = this->New(isolate, other.val_, &this->val_, + TracedReferenceBase<T>::kWithDestructor); } template <class T> @@ -10241,28 +10536,83 @@ TracedGlobal<T>& TracedGlobal<T>::operator=(const TracedGlobal& rhs) { } template <class T> -void TracedGlobal<T>::SetWrapperClassId(uint16_t class_id) { +template <class S> +void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) { + TYPE_CHECK(T, S); + Reset(); + if (other.IsEmpty()) return; + this->val_ = this->New(isolate, other.val_, &this->val_, + TracedReferenceBase<T>::kWithoutDestructor); +} + +template <class T> +template <class S> +TracedReference<T>& TracedReference<T>::operator=(TracedReference<S>&& rhs) { + TYPE_CHECK(T, S); + *this = std::move(rhs.template As<T>()); + return *this; +} + +template <class T> +template <class S> +TracedReference<T>& TracedReference<T>::operator=( + const TracedReference<S>& rhs) { + TYPE_CHECK(T, S); + *this = rhs.template As<T>(); + return *this; +} + +template <class T> +TracedReference<T>& TracedReference<T>::operator=(TracedReference&& rhs) { + if (this != &rhs) { + this->Reset(); + if (rhs.val_ != nullptr) { + this->val_ = rhs.val_; + V8::MoveTracedGlobalReference( + reinterpret_cast<internal::Address**>(&rhs.val_), + reinterpret_cast<internal::Address**>(&this->val_)); + rhs.val_ = nullptr; + } + } + return *this; +} + +template <class T> +TracedReference<T>& TracedReference<T>::operator=(const TracedReference& rhs) { + if (this != &rhs) { + this->Reset(); + if (rhs.val_ != nullptr) { + V8::CopyTracedGlobalReference( + reinterpret_cast<const internal::Address* const*>(&rhs.val_), + reinterpret_cast<internal::Address**>(&this->val_)); + } + } + return *this; +} + +template <class T> +void TracedReferenceBase<T>::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; if (IsEmpty()) return; - internal::Address* obj = reinterpret_cast<internal::Address*>(**this); + internal::Address* obj = reinterpret_cast<internal::Address*>(val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; *reinterpret_cast<uint16_t*>(addr) = class_id; } template <class T> -uint16_t TracedGlobal<T>::WrapperClassId() const { +uint16_t TracedReferenceBase<T>::WrapperClassId() const { typedef internal::Internals I; if (IsEmpty()) return 0; - internal::Address* obj = reinterpret_cast<internal::Address*>(**this); + internal::Address* obj = reinterpret_cast<internal::Address*>(val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; return *reinterpret_cast<uint16_t*>(addr); } template <class T> -void TracedGlobal<T>::SetFinalizationCallback( +void TracedReferenceBase<T>::SetFinalizationCallback( void* parameter, typename WeakCallbackInfo<void>::Callback callback) { - V8::SetFinalizationCallbackTraced( - reinterpret_cast<internal::Address*>(**this), parameter, callback); + V8::SetFinalizationCallbackTraced(reinterpret_cast<internal::Address*>(val_), + parameter, callback); } template <typename T> @@ -10281,12 +10631,12 @@ void ReturnValue<T>::Set(const Global<S>& handle) { template <typename T> template <typename S> -void ReturnValue<T>::Set(const TracedGlobal<S>& handle) { +void ReturnValue<T>::Set(const TracedReferenceBase<S>& handle) { TYPE_CHECK(T, S); if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { - *value_ = *reinterpret_cast<internal::Address*>(*handle); + *value_ = *reinterpret_cast<internal::Address*>(handle.val_); } } diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h index 7670c0e449c7fd..882dc8a23c60af 100644 --- a/deps/v8/include/v8config.h +++ b/deps/v8/include/v8config.h @@ -54,7 +54,7 @@ // ----------------------------------------------------------------------------- -// Operating system detection +// Operating system detection (host) // // V8_OS_ANDROID - Android // V8_OS_BSD - BSDish (Mac OS X, Net/Free/Open/DragonFlyBSD) @@ -122,6 +122,67 @@ # define V8_OS_WIN 1 #endif +// ----------------------------------------------------------------------------- +// Operating system detection (target) +// +// V8_TARGET_OS_ANDROID +// V8_TARGET_OS_FUCHSIA +// V8_TARGET_OS_IOS +// V8_TARGET_OS_LINUX +// V8_TARGET_OS_MACOSX +// V8_TARGET_OS_WIN +// +// If not set explicitly, these fall back to corresponding V8_OS_ values. + +#ifdef V8_HAVE_TARGET_OS + +// The target OS is provided, just check that at least one known value is set. +# if !defined(V8_TARGET_OS_ANDROID) \ + && !defined(V8_TARGET_OS_FUCHSIA) \ + && !defined(V8_TARGET_OS_IOS) \ + && !defined(V8_TARGET_OS_LINUX) \ + && !defined(V8_TARGET_OS_MACOSX) \ + && !defined(V8_TARGET_OS_WIN) +# error No known target OS defined. +# endif + +#else // V8_HAVE_TARGET_OS + +# if defined(V8_TARGET_OS_ANDROID) \ + || defined(V8_TARGET_OS_FUCHSIA) \ + || defined(V8_TARGET_OS_IOS) \ + || defined(V8_TARGET_OS_LINUX) \ + || defined(V8_TARGET_OS_MACOSX) \ + || defined(V8_TARGET_OS_WIN) +# error A target OS is defined but V8_HAVE_TARGET_OS is unset. +# endif + +// Fall back to the detected host OS. +#ifdef V8_OS_ANDROID +# define V8_TARGET_OS_ANDROID +#endif + +#ifdef V8_OS_FUCHSIA +# define V8_TARGET_OS_FUCHSIA +#endif + +#ifdef V8_OS_IOS +# define V8_TARGET_OS_IOS +#endif + +#ifdef V8_OS_LINUX +# define V8_TARGET_OS_LINUX +#endif + +#ifdef V8_OS_MACOSX +# define V8_TARGET_OS_MACOSX +#endif + +#ifdef V8_OS_WIN +# define V8_TARGET_OS_WIN +#endif + +#endif // V8_HAVE_TARGET_OS // ----------------------------------------------------------------------------- // C library detection @@ -169,7 +230,7 @@ // // V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) // supported -// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported +// V8_HAS_ATTRIBUTE_NONNULL - __attribute__((nonnull)) supported // V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported // V8_HAS_ATTRIBUTE_UNUSED - __attribute__((unused)) supported // V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported @@ -188,10 +249,8 @@ // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported // V8_HAS_COMPUTED_GOTO - computed goto/labels as values // supported -// V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported -// V8_HAS_DECLSPEC_NORETURN - __declspec(noreturn) supported // V8_HAS___FORCEINLINE - __forceinline supported // // Note that testing for compilers and/or features must be done using #if @@ -207,9 +266,7 @@ #endif # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) -# define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated)) -# define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE \ - (__has_extension(attribute_deprecated_with_message)) +# define V8_HAS_ATTRIBUTE_NONNULL (__has_attribute(nonnull)) # define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline)) # define V8_HAS_ATTRIBUTE_UNUSED (__has_attribute(unused)) # define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility)) @@ -255,8 +312,6 @@ // Works around "sorry, unimplemented: inlining failed" build errors with // older compilers. # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 4, 0)) -# define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0)) -# define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE (V8_GNUC_PREREQ(4, 5, 0)) # define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0)) # define V8_HAS_ATTRIBUTE_UNUSED (V8_GNUC_PREREQ(2, 95, 0)) # define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0)) @@ -278,10 +333,8 @@ #if defined(_MSC_VER) # define V8_CC_MSVC 1 -# define V8_HAS_DECLSPEC_DEPRECATED 1 # define V8_HAS_DECLSPEC_NOINLINE 1 # define V8_HAS_DECLSPEC_SELECTANY 1 -# define V8_HAS_DECLSPEC_NORETURN 1 # define V8_HAS___FORCEINLINE 1 @@ -306,9 +359,20 @@ # define V8_ASSUME_ALIGNED(ptr, alignment) \ __builtin_assume_aligned((ptr), (alignment)) #else -# define V8_ASSUME_ALIGNED(ptr) (ptr) +# define V8_ASSUME_ALIGNED(ptr, alignment) (ptr) #endif + +// A macro to mark specific arguments as non-null. +// Use like: +// int add(int* x, int y, int* z) V8_NONNULL(1, 3) { return *x + y + *z; } +#if V8_HAS_ATTRIBUTE_NONNULL +# define V8_NONNULL(...) __attribute__((nonnull(__VA_ARGS__))) +#else +# define V8_NONNULL(...) /* NOT SUPPORTED */ +#endif + + // A macro used to tell the compiler to never inline a particular function. // Don't bother for debug builds. // Use like: @@ -323,31 +387,18 @@ // A macro (V8_DEPRECATED) to mark classes or functions as deprecated. -#if defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE -#define V8_DEPRECATED(message, declarator) \ - declarator __attribute__((deprecated(message))) -#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED -#define V8_DEPRECATED(message, declarator) \ - declarator __attribute__((deprecated)) -#elif defined(V8_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED -#define V8_DEPRECATED(message, declarator) __declspec(deprecated) declarator +#if defined(V8_DEPRECATION_WARNINGS) +# define V8_DEPRECATED(message) [[deprecated(message)]] #else -#define V8_DEPRECATED(message, declarator) declarator +# define V8_DEPRECATED(message) #endif // A macro (V8_DEPRECATE_SOON) to make it easier to see what will be deprecated. -#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) && \ - V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE -#define V8_DEPRECATE_SOON(message, declarator) \ - declarator __attribute__((deprecated(message))) -#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_ATTRIBUTE_DEPRECATED -#define V8_DEPRECATE_SOON(message, declarator) \ - declarator __attribute__((deprecated)) -#elif defined(V8_IMMINENT_DEPRECATION_WARNINGS) && V8_HAS_DECLSPEC_DEPRECATED -#define V8_DEPRECATE_SOON(message, declarator) __declspec(deprecated) declarator +#if defined(V8_IMMINENT_DEPRECATION_WARNINGS) +# define V8_DEPRECATE_SOON(message) [[deprecated(message)]] #else -#define V8_DEPRECATE_SOON(message, declarator) declarator +# define V8_DEPRECATE_SOON(message) #endif diff --git a/deps/v8/infra/mb/mb_config.pyl b/deps/v8/infra/mb/mb_config.pyl index d5d192fb20ca94..fed7fa24bfc098 100644 --- a/deps/v8/infra/mb/mb_config.pyl +++ b/deps/v8/infra/mb/mb_config.pyl @@ -99,8 +99,6 @@ 'release_x64_pointer_compression_without_dchecks', 'V8 Linux64 - arm64 - sim - pointer compression - builder': 'release_simulate_arm64_pointer_compression', - 'V8 Linux - noembed': 'release_x86_noembed', - 'V8 Linux - noembed - debug': 'debug_x86_noembed', 'V8 Fuchsia': 'release_x64_fuchsia', 'V8 Fuchsia - debug': 'debug_x64_fuchsia', 'V8 Linux64 - cfi': 'release_x64_cfi', @@ -162,7 +160,6 @@ 'debug_simulate_arm64_no_snap', 'V8 Linux - arm64 - sim - gc stress': 'debug_simulate_arm64', # Mips. - 'V8 Mips - builder': 'release_mips_no_snap_no_i18n', 'V8 Linux - mipsel - sim - builder': 'release_simulate_mipsel', 'V8 Linux - mips64el - sim - builder': 'release_simulate_mips64el', # IBM. @@ -197,7 +194,6 @@ 'v8_android_arm64_n5x_rel_ng': 'release_android_arm64', 'v8_fuchsia_rel_ng': 'release_x64_fuchsia_trybot', 'v8_ios_simulator': 'release_x64_ios_simulator', - 'v8_linux_noembed_rel_ng': 'release_x86_noembed_trybot', 'v8_linux_rel_ng': 'release_x86_gcmole_trybot', 'v8_linux_optional_rel_ng': 'release_x86_trybot', 'v8_linux_verify_csa_rel_ng': 'release_x86_verify_csa', @@ -253,7 +249,6 @@ 'v8_mac64_dbg': 'debug_x64', 'v8_mac64_dbg_ng': 'debug_x64', 'v8_mac64_asan_rel': 'release_x64_asan_no_lsan', - 'v8_mips_compile_rel': 'release_mips_no_snap_no_i18n', 'v8_linux_arm_rel_ng': 'release_simulate_arm_trybot', 'v8_linux_arm_lite_rel_ng': 'release_simulate_arm_lite_trybot', 'v8_linux_arm_dbg': 'debug_simulate_arm', @@ -434,7 +429,7 @@ 'release_x64_cfi_clusterfuzz': [ 'release_bot', 'x64', 'cfi_clusterfuzz'], 'release_x64_msvc': [ - 'release_bot', 'x64', 'msvc'], + 'release_bot_no_goma', 'x64', 'minimal_symbols', 'msvc'], 'release_x64_correctness_fuzzer' : [ 'release_bot', 'x64', 'v8_correctness_fuzzer'], 'release_x64_fuchsia': [ @@ -515,8 +510,6 @@ # Debug configs for x86. 'debug_x86': [ 'debug_bot', 'x86'], - 'debug_x86_noembed': [ - 'debug_bot', 'x86', 'v8_no_enable_embedded_builtins'], 'debug_x86_minimal_symbols': [ 'debug_bot', 'x86', 'minimal_symbols'], 'debug_x86_no_i18n': [ @@ -535,10 +528,6 @@ # Release configs for x86. 'release_x86': [ 'release_bot', 'x86'], - 'release_x86_noembed': [ - 'release_bot', 'x86', 'v8_no_enable_embedded_builtins'], - 'release_x86_noembed_trybot': [ - 'release_trybot', 'x86', 'v8_no_enable_embedded_builtins'], 'release_x86_gcc': [ 'release_bot', 'x86', 'gcc', 'v8_check_header_includes'], 'release_x86_gcc_minimal_symbols': [ @@ -568,11 +557,6 @@ 'release_x86_verify_csa': [ 'release_bot', 'x86', 'dcheck_always_on', 'v8_enable_slow_dchecks', 'v8_verify_csa'], - - # Release configs for mips. - 'release_mips_no_snap_no_i18n': [ - 'release', 'mips', 'no_sysroot', 'static', 'v8_no_i18n', - 'v8_snapshot_none'], }, 'mixins': { @@ -648,8 +632,7 @@ }, 'gcc': { - # TODO(machenbach): Remove cxx11 restriction when updating gcc version. - 'gn_args': 'is_clang=false use_cxx11=true', + 'gn_args': 'is_clang=false', }, 'gcmole': { @@ -685,28 +668,14 @@ 'gn_args': 'symbol_level=1', }, - 'mips': { - 'mixins': ['mips_bundled_toolchain'], - 'gn_args': 'target_cpu="mips"', - }, - - 'mips_bundled_toolchain': { - 'gn_args': 'custom_toolchain="tools/toolchain:mips-bundled" ' - 'ldso_path="tools/mips_toolchain/sysroot/usr/lib/ld.so.1" ' - 'gcc_target_rpath="tools/mips_toolchain/sysroot/usr/lib:' - 'tools/mips_toolchain/mips-mti-linux-gnu/lib:\$ORIGIN/."', - }, - 'msan': { 'mixins': ['v8_enable_test_features'], - 'gn_args': ('is_msan=true msan_track_origins=2 ' - 'use_prebuilt_instrumented_libraries=true'), + 'gn_args': 'is_msan=true msan_track_origins=2', }, 'msan_no_origins': { 'mixins': ['v8_enable_test_features'], - 'gn_args': ('is_msan=true msan_track_origins=0 ' - 'use_prebuilt_instrumented_libraries=true'), + 'gn_args': 'is_msan=true msan_track_origins=0', }, 'msvc': { @@ -717,6 +686,10 @@ 'gn_args': 'use_custom_libcxx=false', }, + 'no_goma': { + 'gn_args': 'use_goma=false', + }, + 'no_sysroot': { 'gn_args': 'use_sysroot=false', }, @@ -733,6 +706,10 @@ 'mixins': ['release', 'static', 'goma'], }, + 'release_bot_no_goma': { + 'mixins': ['release', 'static', 'no_goma'], + }, + 'release_trybot': { 'mixins': ['release_bot', 'minimal_symbols', 'dcheck_always_on'], }, @@ -803,10 +780,6 @@ 'gn_args': 'v8_correctness_fuzzer=true v8_multi_arch_build=true', }, - 'v8_no_enable_embedded_builtins': { - 'gn_args': 'v8_enable_embedded_builtins=false', - }, - 'v8_enable_lite_mode': { 'gn_args': 'v8_enable_lite_mode=true', }, @@ -852,9 +825,9 @@ 'gn_args': 'v8_use_external_startup_data=false', }, - 'v8_snapshot_none': { - 'gn_args': 'v8_use_snapshot=false', - }, + # TODO(https://crbug.com/v8/8531): Remove this config and all bots, since + # no-snapshot was deprecated and removed. + 'v8_snapshot_none': {}, 'v8_verify_heap': { 'gn_args': 'v8_enable_verify_heap=true', diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl index 0d340db00e70de..1b805df9599d12 100644 --- a/deps/v8/infra/testing/builders.pyl +++ b/deps/v8/infra/testing/builders.pyl @@ -43,7 +43,7 @@ {'name': 'v8testing', 'variant': 'default', 'shards': 4}, {'name': 'v8testing', 'variant': 'trusted', 'shards': 4}, {'name': 'mozilla', 'variant': 'default'}, - {'name': 'test262', 'variant': 'default', 'shards': 7}, + {'name': 'test262', 'variant': 'default', 'shards': 9}, ], }, ############################################################################## @@ -60,7 +60,7 @@ {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'test262', 'variant': 'default', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 3}, {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, ], @@ -92,20 +92,12 @@ {'name': 'benchmarks', 'variant': 'extra'}, {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, - {'name': 'test262_variants', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 2}, + {'name': 'test262', 'shards': 2}, + {'name': 'test262', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra'}, ], }, - 'v8_linux_noembed_rel_ng_triggered': { - 'swarming_dimensions' : { - 'os': 'Ubuntu-16.04', - }, - 'tests': [ - {'name': 'v8testing', 'shards': 2}, - ], - }, 'v8_linux_noi18n_rel_ng_triggered': { 'swarming_dimensions' : { 'os': 'Ubuntu-16.04', @@ -145,8 +137,8 @@ {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'optimize_for_size'}, - {'name': 'test262_variants', 'shards': 4}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'shards': 4}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'suffix': 'isolates', 'test_args': ['--isolates'], 'shards': 2}, {'name': 'v8testing', 'variant': 'extra'}, @@ -162,7 +154,7 @@ {'name': 'benchmarks', 'variant': 'code_serializer', 'shards': 1}, {'name': 'd8testing', 'variant': 'code_serializer', 'shards': 1}, {'name': 'mozilla', 'variant': 'code_serializer', 'shards': 1}, - {'name': 'test262_variants', 'variant': 'code_serializer', 'shards': 1}, + {'name': 'test262', 'variant': 'code_serializer', 'shards': 1}, # No SSE3. { 'name': 'mozilla', @@ -229,7 +221,7 @@ {'name': 'mozilla'}, {'name': 'test262', 'variant': 'default'}, {'name': 'v8testing', 'shards': 7}, - {'name': 'v8testing', 'variant': 'extra', 'shards': 3}, + {'name': 'v8testing', 'variant': 'extra', 'shards': 6}, {'name': 'v8testing', 'variant': 'trusted', 'shards': 2}, ], }, @@ -261,7 +253,7 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'test262_variants', 'shards': 7}, + {'name': 'test262', 'shards': 7}, {'name': 'v8testing', 'shards': 3}, {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'variant': 'slow_path'}, @@ -291,7 +283,7 @@ {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'test262', 'variant': 'default'}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 3}, {'name': 'v8testing', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'variant': 'minor_mc', 'shards': 1}, @@ -318,7 +310,7 @@ {'name': 'mjsunit', 'variant': 'stress_sampling'}, {'name': 'webkit', 'variant': 'stress_sampling'}, # Infra staging. - {'name': 'test262_variants', 'variant': 'infra_staging', 'shards': 2}, + {'name': 'test262', 'variant': 'infra_staging', 'shards': 2}, {'name': 'v8testing', 'variant': 'infra_staging', 'shards': 2}, ], }, @@ -345,9 +337,9 @@ {'name': 'mozilla', 'variant': 'assert_types'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'perf_integration'}, - {'name': 'test262_variants', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'assert_types', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 2}, + {'name': 'test262', 'shards': 2}, + {'name': 'test262', 'variant': 'assert_types', 'shards': 2}, + {'name': 'test262', 'variant': 'extra', 'shards': 2}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'assert_types'}, {'name': 'v8testing', 'variant': 'extra'}, @@ -379,8 +371,8 @@ # TODO(machenbach): Add mozilla tests. {'name': 'mjsunit_sp_frame_access'}, {'name': 'optimize_for_size'}, - {'name': 'test262_variants', 'shards': 4}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'shards': 4}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8initializers'}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra'}, @@ -658,8 +650,8 @@ {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'optimize_for_size'}, - {'name': 'test262_variants', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'extra'}, + {'name': 'test262', 'shards': 2}, + {'name': 'test262', 'variant': 'extra'}, {'name': 'v8initializers'}, {'name': 'v8testing'}, {'name': 'v8testing', 'suffix': 'isolates', 'test_args': ['--isolates']}, @@ -712,9 +704,9 @@ {'name': 'mozilla', 'variant': 'code_serializer', 'shards': 1}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'optimize_for_size'}, - {'name': 'test262_variants', 'shards': 6}, - {'name': 'test262_variants', 'variant': 'code_serializer', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'shards': 6}, + {'name': 'test262', 'variant': 'code_serializer', 'shards': 2}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 3}, { 'name': 'v8testing', @@ -761,22 +753,6 @@ }, ], }, - 'V8 Linux - noembed': { - 'swarming_dimensions': { - 'os': 'Ubuntu-16.04', - }, - 'tests': [ - {'name': 'v8testing'}, - ], - }, - 'V8 Linux - noembed - debug': { - 'swarming_dimensions': { - 'os': 'Ubuntu-16.04', - }, - 'tests': [ - {'name': 'v8testing', 'shards': 3}, - ], - }, 'V8 Linux - full debug': { 'swarming_dimensions': { 'os': 'Ubuntu-16.04', @@ -898,9 +874,9 @@ {'name': 'mozilla', 'variant': 'extra'}, {'name': 'optimize_for_size'}, {'name': 'perf_integration'}, - {'name': 'test262_variants', 'shards': 2}, - {'name': 'test262_variants', 'variant': 'assert_types'}, - {'name': 'test262_variants', 'variant': 'extra'}, + {'name': 'test262', 'shards': 2}, + {'name': 'test262', 'variant': 'assert_types'}, + {'name': 'test262', 'variant': 'extra'}, {'name': 'v8initializers'}, {'name': 'v8testing'}, {'name': 'v8testing', 'variant': 'assert_types'}, @@ -957,8 +933,8 @@ {'name': 'mozilla'}, {'name': 'mozilla', 'variant': 'extra'}, {'name': 'optimize_for_size'}, - {'name': 'test262_variants', 'shards': 5}, - {'name': 'test262_variants', 'variant': 'extra', 'shards': 3}, + {'name': 'test262', 'shards': 5}, + {'name': 'test262', 'variant': 'extra', 'shards': 3}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra'}, {'name': 'v8testing', 'variant': 'minor_mc', 'shards': 1}, @@ -1067,7 +1043,7 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'test262_variants', 'shards': 5}, + {'name': 'test262', 'shards': 5}, {'name': 'v8testing', 'shards': 2}, {'name': 'v8testing', 'variant': 'extra'}, {'name': 'v8testing', 'variant': 'slow_path', 'shards': 1}, @@ -1271,7 +1247,7 @@ }, 'tests': [ {'name': 'mozilla', 'variant': 'default'}, - {'name': 'test262', 'variant': 'default', 'shards': 6}, + {'name': 'test262', 'variant': 'default', 'shards': 8}, {'name': 'v8testing', 'variant': 'default', 'shards': 3}, {'name': 'v8testing', 'variant': 'trusted', 'shards': 3}, ], @@ -1411,7 +1387,7 @@ {'name': 'mozilla', 'shards': 4}, {'name': 'test262', 'variant': 'default'}, {'name': 'v8testing', 'shards': 8}, - {'name': 'v8testing', 'variant': 'extra', 'shards': 4}, + {'name': 'v8testing', 'variant': 'extra', 'shards': 6}, {'name': 'v8testing', 'variant': 'trusted', 'shards': 2}, # Armv8-a. { @@ -1585,19 +1561,6 @@ {'name': 'v8testing', 'shards': 7}, ], }, - 'V8 Mips - big endian - nosnap': { - 'swarming_dimensions': { - 'cpu': 'mips-32', - 'os': 'Debian-8.7', - }, - 'swarming_task_attrs': { - 'expiration': 18000, - 'hard_timeout': 18000, - }, - 'tests': [ - {'name': 'v8testing', 'variant': 'default', 'shards': 2}, - ], - }, ############################################################################## # Clusterfuzz. 'V8 NumFuzz': { @@ -1817,9 +1780,9 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'mozilla'}, - {'name': 'test262', 'variant': 'default'}, - {'name': 'v8testing', 'shards': 8}, + {'name': 'mozilla', 'shards': 2}, + {'name': 'test262', 'variant': 'default', 'shards': 2}, + {'name': 'v8testing', 'shards': 10}, ], }, 'V8 arm - sim - stable branch': { @@ -1837,9 +1800,9 @@ 'os': 'Ubuntu-16.04', }, 'tests': [ - {'name': 'mozilla'}, - {'name': 'test262', 'variant': 'default'}, - {'name': 'v8testing', 'shards': 8}, + {'name': 'mozilla', 'shards': 2}, + {'name': 'test262', 'variant': 'default', 'shards': 2}, + {'name': 'v8testing', 'shards': 10}, ], }, 'V8 mips64el - sim - beta branch': { diff --git a/deps/v8/src/api/OWNERS b/deps/v8/src/api/OWNERS index ef5a56dbfcecf3..f51e220309656a 100644 --- a/deps/v8/src/api/OWNERS +++ b/deps/v8/src/api/OWNERS @@ -1,5 +1,5 @@ file:../../include/OWNERS -clemensh@chromium.org +clemensb@chromium.org ishell@chromium.org jkummerow@chromium.org leszeks@chromium.org diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc index 8be7f8558c8dde..c6fdeec9028fa9 100644 --- a/deps/v8/src/api/api.cc +++ b/deps/v8/src/api/api.cc @@ -127,6 +127,11 @@ #endif // V8_OS_WIN64 #endif // V8_OS_WIN +#define TRACE_BS(...) \ + do { \ + if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ + } while (false) + namespace v8 { /* @@ -2631,7 +2636,7 @@ ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript( i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); i::ScriptStreamingData* data = source->impl(); std::unique_ptr<i::BackgroundCompileTask> task = - base::make_unique<i::BackgroundCompileTask>(data, isolate); + std::make_unique<i::BackgroundCompileTask>(data, isolate); data->task = std::move(task); return new ScriptCompiler::ScriptStreamingTask(data); } @@ -3743,6 +3748,42 @@ void v8::WasmModuleObject::CheckCast(Value* that) { "Could not convert to wasm module object"); } +v8::BackingStore::~BackingStore() { + auto i_this = reinterpret_cast<const i::BackingStore*>(this); + i_this->~BackingStore(); // manually call internal destructor +} + +void* v8::BackingStore::Data() const { + return reinterpret_cast<const i::BackingStore*>(this)->buffer_start(); +} + +size_t v8::BackingStore::ByteLength() const { + return reinterpret_cast<const i::BackingStore*>(this)->byte_length(); +} + +std::shared_ptr<v8::BackingStore> v8::ArrayBuffer::GetBackingStore() { + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); + std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore(); + if (!backing_store) { + backing_store = + i::BackingStore::EmptyBackingStore(i::SharedFlag::kNotShared); + } + i::GlobalBackingStoreRegistry::Register(backing_store); + std::shared_ptr<i::BackingStoreBase> bs_base = backing_store; + return std::static_pointer_cast<v8::BackingStore>(bs_base); +} + +std::shared_ptr<v8::BackingStore> v8::SharedArrayBuffer::GetBackingStore() { + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); + std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore(); + if (!backing_store) { + backing_store = i::BackingStore::EmptyBackingStore(i::SharedFlag::kShared); + } + i::GlobalBackingStoreRegistry::Register(backing_store); + std::shared_ptr<i::BackingStoreBase> bs_base = backing_store; + return std::static_pointer_cast<v8::BackingStore>(bs_base); +} + void v8::ArrayBuffer::CheckCast(Value* that) { i::Handle<i::Object> obj = Utils::OpenHandle(that); Utils::ApiCheck( @@ -5307,7 +5348,7 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string, int end = start + length; if ((length == -1) || (length > str->length() - start)) end = str->length(); if (end < 0) return 0; - i::String::WriteToFlat(*str, buffer, start, end); + if (start < end) i::String::WriteToFlat(*str, buffer, start, end); if (!(options & String::NO_NULL_TERMINATION) && (length == -1 || end - start < length)) { buffer[end - start] = '\0'; @@ -5704,6 +5745,11 @@ void v8::V8::InitializeExternalStartupData(const char* natives_blob, i::InitializeExternalStartupData(natives_blob, snapshot_blob); } +// static +void v8::V8::InitializeExternalStartupDataFromFile(const char* snapshot_blob) { + i::InitializeExternalStartupDataFromFile(snapshot_blob); +} + const char* v8::V8::GetVersion() { return i::Version::GetVersion(); } template <typename ObjectType> @@ -7219,20 +7265,78 @@ bool v8::ArrayBuffer::IsDetachable() const { return Utils::OpenHandle(this)->is_detachable(); } -v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() { - i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); - i::Isolate* isolate = self->GetIsolate(); - Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize", - "ArrayBuffer already externalized"); - self->set_is_external(true); +namespace { +// The backing store deleter just deletes the indirection, which downrefs +// the shared pointer. It will get collected normally. +void BackingStoreDeleter(void* buffer, size_t length, void* info) { + std::shared_ptr<i::BackingStore>* bs_indirection = + reinterpret_cast<std::shared_ptr<i::BackingStore>*>(info); + if (bs_indirection) { + i::BackingStore* backing_store = bs_indirection->get(); + TRACE_BS("API:delete bs=%p mem=%p (length=%zu)\n", backing_store, + backing_store->buffer_start(), backing_store->byte_length()); + USE(backing_store); + } + delete bs_indirection; +} - const v8::ArrayBuffer::Contents contents = GetContents(); - isolate->heap()->UnregisterArrayBuffer(*self); +void* MakeDeleterData(std::shared_ptr<i::BackingStore> backing_store) { + if (!backing_store) return nullptr; + TRACE_BS("API:extern bs=%p mem=%p (length=%zu)\n", backing_store.get(), + backing_store->buffer_start(), backing_store->byte_length()); + return new std::shared_ptr<i::BackingStore>(backing_store); +} - // A regular copy is good enough. No move semantics needed. - return contents; +std::shared_ptr<i::BackingStore> LookupOrCreateBackingStore( + i::Isolate* i_isolate, void* data, size_t byte_length, i::SharedFlag shared, + ArrayBufferCreationMode mode) { + // "internalized" means that the storage was allocated by the + // ArrayBufferAllocator and thus should be freed upon destruction. + bool free_on_destruct = mode == ArrayBufferCreationMode::kInternalized; + + // Try to lookup a previously-registered backing store in the global + // registry. If found, use that instead of wrapping an embedder allocation. + std::shared_ptr<i::BackingStore> backing_store = + i::GlobalBackingStoreRegistry::Lookup(data, byte_length); + + if (backing_store) { + // Check invariants for a previously-found backing store. + + // 1. We cannot allow an embedder to first allocate a backing store that + // should not be freed upon destruct, and then allocate an alias that should + // destruct it. The other order is fine. + bool changing_destruct_mode = + free_on_destruct && !backing_store->free_on_destruct(); + Utils::ApiCheck( + !changing_destruct_mode, "v8_[Shared]ArrayBuffer_New", + "previous backing store found that should not be freed on destruct"); + + // 2. We cannot allow embedders to use the same backing store for both + // SharedArrayBuffers and regular ArrayBuffers. + bool changing_shared_flag = + (shared == i::SharedFlag::kShared) != backing_store->is_shared(); + Utils::ApiCheck( + !changing_shared_flag, "v8_[Shared]ArrayBuffer_New", + "previous backing store found that does not match shared flag"); + } else { + // No previous backing store found. + backing_store = i::BackingStore::WrapAllocation( + i_isolate, data, byte_length, shared, free_on_destruct); + + // The embedder already has a direct pointer to the buffer start, so + // globally register the backing store in case they come back with the + // same buffer start and the backing store is marked as free_on_destruct. + i::GlobalBackingStoreRegistry::Register(backing_store); + } + return backing_store; } +std::shared_ptr<i::BackingStore> ToInternal( + std::shared_ptr<i::BackingStoreBase> backing_store) { + return std::static_pointer_cast<i::BackingStore>(backing_store); +} +} // namespace + v8::ArrayBuffer::Contents::Contents(void* data, size_t byte_length, void* allocation_base, size_t allocation_length, @@ -7249,29 +7353,70 @@ v8::ArrayBuffer::Contents::Contents(void* data, size_t byte_length, DCHECK_LE(byte_length_, allocation_length_); } -void WasmMemoryDeleter(void* buffer, size_t lenght, void* info) { - internal::wasm::WasmEngine* engine = - reinterpret_cast<internal::wasm::WasmEngine*>(info); - CHECK(engine->memory_tracker()->FreeWasmMemory(nullptr, buffer)); +v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() { + return GetContents(true); } -void ArrayBufferDeleter(void* buffer, size_t length, void* info) { - v8::ArrayBuffer::Allocator* allocator = - reinterpret_cast<v8::ArrayBuffer::Allocator*>(info); - allocator->Free(buffer, length); +void v8::ArrayBuffer::Externalize( + const std::shared_ptr<BackingStore>& backing_store) { + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); + Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize", + "ArrayBuffer already externalized"); + self->set_is_external(true); + DCHECK_EQ(self->backing_store(), backing_store->Data()); } v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() { + return GetContents(false); +} + +v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents(bool externalize) { + // TODO(titzer): reduce duplication between shared/unshared GetContents() + using BufferType = v8::ArrayBuffer; + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); - Contents contents( - self->backing_store(), self->byte_length(), self->allocation_base(), - self->allocation_length(), - self->is_wasm_memory() ? Allocator::AllocationMode::kReservation - : Allocator::AllocationMode::kNormal, - self->is_wasm_memory() ? WasmMemoryDeleter : ArrayBufferDeleter, - self->is_wasm_memory() - ? static_cast<void*>(self->GetIsolate()->wasm_engine()) - : static_cast<void*>(self->GetIsolate()->array_buffer_allocator())); + + std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore(); + + void* deleter_data = nullptr; + if (externalize) { + Utils::ApiCheck(!self->is_external(), "v8_ArrayBuffer_Externalize", + "ArrayBuffer already externalized"); + self->set_is_external(true); + // When externalizing, upref the shared pointer to the backing store + // and store that as the deleter data. When the embedder calls the deleter + // callback, we will delete the additional (on-heap) shared_ptr. + deleter_data = MakeDeleterData(backing_store); + } + + if (!backing_store) { + // If the array buffer has zero length or was detached, return empty + // contents. + DCHECK_EQ(0, self->byte_length()); + BufferType::Contents contents( + nullptr, 0, nullptr, 0, + v8::ArrayBuffer::Allocator::AllocationMode::kNormal, + BackingStoreDeleter, deleter_data); + return contents; + } + + // Backing stores that given to the embedder might be passed back through + // the API using only the start of the buffer. We need to find such + // backing stores using global registration until the API is changed. + i::GlobalBackingStoreRegistry::Register(backing_store); + + auto allocation_mode = + backing_store->is_wasm_memory() + ? v8::ArrayBuffer::Allocator::AllocationMode::kReservation + : v8::ArrayBuffer::Allocator::AllocationMode::kNormal; + + BufferType::Contents contents(backing_store->buffer_start(), // -- + backing_store->byte_length(), // -- + backing_store->buffer_start(), // -- + backing_store->byte_length(), // -- + allocation_mode, // -- + BackingStoreDeleter, // -- + deleter_data); return contents; } @@ -7296,33 +7441,85 @@ Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); LOG_API(i_isolate, ArrayBuffer, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); - i::Handle<i::JSArrayBuffer> obj = - i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); - // TODO(jbroman): It may be useful in the future to provide a MaybeLocal - // version that throws an exception or otherwise does not crash. - if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length)) { + i::MaybeHandle<i::JSArrayBuffer> result = + i_isolate->factory()->NewJSArrayBufferAndBackingStore( + byte_length, i::InitializedFlag::kZeroInitialized); + + i::Handle<i::JSArrayBuffer> array_buffer; + if (!result.ToHandle(&array_buffer)) { + // TODO(jbroman): It may be useful in the future to provide a MaybeLocal + // version that throws an exception or otherwise does not crash. i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::New"); } - return Utils::ToLocal(obj); + + return Utils::ToLocal(array_buffer); } Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data, size_t byte_length, ArrayBufferCreationMode mode) { // Embedders must guarantee that the external backing store is valid. - CHECK(byte_length == 0 || data != nullptr); + CHECK_IMPLIES(byte_length != 0, data != nullptr); CHECK_LE(byte_length, i::JSArrayBuffer::kMaxByteLength); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); LOG_API(i_isolate, ArrayBuffer, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + + std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore( + i_isolate, data, byte_length, i::SharedFlag::kNotShared, mode); + + i::Handle<i::JSArrayBuffer> obj = + i_isolate->factory()->NewJSArrayBuffer(std::move(backing_store)); + if (mode == ArrayBufferCreationMode::kExternalized) { + obj->set_is_external(true); + } + return Utils::ToLocal(obj); +} + +Local<ArrayBuffer> v8::ArrayBuffer::New( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store) { + CHECK_IMPLIES(backing_store->ByteLength() != 0, + backing_store->Data() != nullptr); + CHECK_LE(backing_store->ByteLength(), i::JSArrayBuffer::kMaxByteLength); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + LOG_API(i_isolate, ArrayBuffer, New); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + std::shared_ptr<i::BackingStore> i_backing_store( + ToInternal(std::move(backing_store))); + Utils::ApiCheck( + !i_backing_store->is_shared(), "v8_ArrayBuffer_New", + "Cannot construct ArrayBuffer with a BackingStore of SharedArrayBuffer"); i::Handle<i::JSArrayBuffer> obj = - i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared); - i::JSArrayBuffer::Setup(obj, i_isolate, - mode == ArrayBufferCreationMode::kExternalized, data, - byte_length); + i_isolate->factory()->NewJSArrayBuffer(std::move(i_backing_store)); return Utils::ToLocal(obj); } +std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore( + Isolate* isolate, size_t byte_length) { + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + LOG_API(i_isolate, ArrayBuffer, NewBackingStore); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + std::unique_ptr<i::BackingStoreBase> backing_store = + i::BackingStore::Allocate(i_isolate, byte_length, + i::SharedFlag::kNotShared, + i::InitializedFlag::kZeroInitialized); + if (!backing_store) { + i::FatalProcessOutOfMemory(i_isolate, "v8::ArrayBuffer::NewBackingStore"); + } + return std::unique_ptr<v8::BackingStore>( + static_cast<v8::BackingStore*>(backing_store.release())); +} + +std::unique_ptr<v8::BackingStore> v8::ArrayBuffer::NewBackingStore( + void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* deleter_data) { + std::unique_ptr<i::BackingStoreBase> backing_store = + i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data, + i::SharedFlag::kNotShared); + return std::unique_ptr<v8::BackingStore>( + static_cast<v8::BackingStore*>(backing_store.release())); +} + Local<ArrayBuffer> v8::ArrayBufferView::Buffer() { i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this); i::Handle<i::JSArrayBuffer> buffer; @@ -7362,9 +7559,9 @@ size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { bool v8::ArrayBufferView::HasBuffer() const { i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this); - i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()), - self->GetIsolate()); - return buffer->backing_store() != nullptr; + if (!self->IsJSTypedArray()) return true; + auto typed_array = i::Handle<i::JSTypedArray>::cast(self); + return !typed_array->is_on_heap(); } size_t v8::ArrayBufferView::ByteOffset() { @@ -7460,13 +7657,16 @@ i::Handle<i::JSArrayBuffer> SetupSharedArrayBuffer( i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); LOG_API(i_isolate, SharedArrayBuffer, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + + std::shared_ptr<i::BackingStore> backing_store = LookupOrCreateBackingStore( + i_isolate, data, byte_length, i::SharedFlag::kShared, mode); + i::Handle<i::JSArrayBuffer> obj = - i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); - bool is_wasm_memory = - i_isolate->wasm_engine()->memory_tracker()->IsWasmMemory(data); - i::JSArrayBuffer::Setup(obj, i_isolate, - mode == ArrayBufferCreationMode::kExternalized, data, - byte_length, i::SharedFlag::kShared, is_wasm_memory); + i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store)); + + if (mode == ArrayBufferCreationMode::kExternalized) { + obj->set_is_external(true); + } return obj; } @@ -7476,20 +7676,6 @@ bool v8::SharedArrayBuffer::IsExternal() const { return Utils::OpenHandle(this)->is_external(); } -v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { - i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); - i::Isolate* isolate = self->GetIsolate(); - Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize", - "SharedArrayBuffer already externalized"); - self->set_is_external(true); - - const v8::SharedArrayBuffer::Contents contents = GetContents(); - isolate->heap()->UnregisterArrayBuffer(*self); - - // A regular copy is good enough. No move semantics needed. - return contents; -} - v8::SharedArrayBuffer::Contents::Contents( void* data, size_t byte_length, void* allocation_base, size_t allocation_length, Allocator::AllocationMode allocation_mode, @@ -7505,20 +7691,72 @@ v8::SharedArrayBuffer::Contents::Contents( DCHECK_LE(byte_length_, allocation_length_); } +v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() { + return GetContents(true); +} + +void v8::SharedArrayBuffer::Externalize( + const std::shared_ptr<BackingStore>& backing_store) { + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); + Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize", + "SharedArrayBuffer already externalized"); + self->set_is_external(true); + + DCHECK_EQ(self->backing_store(), backing_store->Data()); +} + v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() { + return GetContents(false); +} + +v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents( + bool externalize) { + // TODO(titzer): reduce duplication between shared/unshared GetContents() + using BufferType = v8::SharedArrayBuffer; + i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this); - Contents contents( - self->backing_store(), self->byte_length(), self->allocation_base(), - self->allocation_length(), - self->is_wasm_memory() - ? ArrayBuffer::Allocator::AllocationMode::kReservation - : ArrayBuffer::Allocator::AllocationMode::kNormal, - self->is_wasm_memory() - ? reinterpret_cast<Contents::DeleterCallback>(WasmMemoryDeleter) - : reinterpret_cast<Contents::DeleterCallback>(ArrayBufferDeleter), - self->is_wasm_memory() - ? static_cast<void*>(self->GetIsolate()->wasm_engine()) - : static_cast<void*>(self->GetIsolate()->array_buffer_allocator())); + + std::shared_ptr<i::BackingStore> backing_store = self->GetBackingStore(); + + void* deleter_data = nullptr; + if (externalize) { + Utils::ApiCheck(!self->is_external(), "v8_SharedArrayBuffer_Externalize", + "SharedArrayBuffer already externalized"); + self->set_is_external(true); + // When externalizing, upref the shared pointer to the backing store + // and store that as the deleter data. When the embedder calls the deleter + // callback, we will delete the additional (on-heap) shared_ptr. + deleter_data = MakeDeleterData(backing_store); + } + + if (!backing_store) { + // If the array buffer has zero length or was detached, return empty + // contents. + DCHECK_EQ(0, self->byte_length()); + BufferType::Contents contents( + nullptr, 0, nullptr, 0, + v8::ArrayBuffer::Allocator::AllocationMode::kNormal, + BackingStoreDeleter, deleter_data); + return contents; + } + + // Backing stores that given to the embedder might be passed back through + // the API using only the start of the buffer. We need to find such + // backing stores using global registration until the API is changed. + i::GlobalBackingStoreRegistry::Register(backing_store); + + auto allocation_mode = + backing_store->is_wasm_memory() + ? v8::ArrayBuffer::Allocator::AllocationMode::kReservation + : v8::ArrayBuffer::Allocator::AllocationMode::kNormal; + + BufferType::Contents contents(backing_store->buffer_start(), // -- + backing_store->byte_length(), // -- + backing_store->buffer_start(), // -- + backing_store->byte_length(), // -- + allocation_mode, // -- + BackingStoreDeleter, // -- + deleter_data); return contents; } @@ -7533,14 +7771,19 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate, i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); LOG_API(i_isolate, SharedArrayBuffer, New); ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); - i::Handle<i::JSArrayBuffer> obj = - i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared); - // TODO(jbroman): It may be useful in the future to provide a MaybeLocal - // version that throws an exception or otherwise does not crash. - if (!i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true, - i::SharedFlag::kShared)) { + + std::unique_ptr<i::BackingStore> backing_store = + i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared, + i::InitializedFlag::kZeroInitialized); + + if (!backing_store) { + // TODO(jbroman): It may be useful in the future to provide a MaybeLocal + // version that throws an exception or otherwise does not crash. i::FatalProcessOutOfMemory(i_isolate, "v8::SharedArrayBuffer::New"); } + + i::Handle<i::JSArrayBuffer> obj = + i_isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store)); return Utils::ToLocalShared(obj); } @@ -7552,6 +7795,24 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( return Utils::ToLocalShared(buffer); } +Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store) { + CHECK(i::FLAG_harmony_sharedarraybuffer); + CHECK_IMPLIES(backing_store->ByteLength() != 0, + backing_store->Data() != nullptr); + CHECK_LE(backing_store->ByteLength(), i::JSArrayBuffer::kMaxByteLength); + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + LOG_API(i_isolate, SharedArrayBuffer, New); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + std::shared_ptr<i::BackingStore> i_backing_store(ToInternal(backing_store)); + Utils::ApiCheck( + i_backing_store->is_shared(), "v8_SharedArrayBuffer_New", + "Cannot construct SharedArrayBuffer with BackingStore of ArrayBuffer"); + i::Handle<i::JSArrayBuffer> obj = + i_isolate->factory()->NewJSSharedArrayBuffer(std::move(i_backing_store)); + return Utils::ToLocalShared(obj); +} + Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( Isolate* isolate, const SharedArrayBuffer::Contents& contents, ArrayBufferCreationMode mode) { @@ -7560,6 +7821,32 @@ Local<SharedArrayBuffer> v8::SharedArrayBuffer::New( return Utils::ToLocalShared(buffer); } +std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore( + Isolate* isolate, size_t byte_length) { + i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); + LOG_API(i_isolate, SharedArrayBuffer, NewBackingStore); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate); + std::unique_ptr<i::BackingStoreBase> backing_store = + i::BackingStore::Allocate(i_isolate, byte_length, i::SharedFlag::kShared, + i::InitializedFlag::kZeroInitialized); + if (!backing_store) { + i::FatalProcessOutOfMemory(i_isolate, + "v8::SharedArrayBuffer::NewBackingStore"); + } + return std::unique_ptr<v8::BackingStore>( + static_cast<v8::BackingStore*>(backing_store.release())); +} + +std::unique_ptr<v8::BackingStore> v8::SharedArrayBuffer::NewBackingStore( + void* data, size_t byte_length, BackingStoreDeleterCallback deleter, + void* deleter_data) { + std::unique_ptr<i::BackingStoreBase> backing_store = + i::BackingStore::WrapAllocation(data, byte_length, deleter, deleter_data, + i::SharedFlag::kShared); + return std::unique_ptr<v8::BackingStore>( + static_cast<v8::BackingStore*>(backing_store.release())); +} + Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) { i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); LOG_API(i_isolate, Symbol, New); @@ -7899,6 +8186,13 @@ Isolate* Isolate::Allocate() { return reinterpret_cast<Isolate*>(i::Isolate::New()); } +void Isolate::SetArrayBufferAllocatorShared( + std::shared_ptr<ArrayBuffer::Allocator> allocator) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + CHECK_EQ(allocator.get(), isolate->array_buffer_allocator()); + isolate->set_array_buffer_allocator_shared(std::move(allocator)); +} + // static // This is separate so that tests can provide a different |isolate|. void Isolate::Initialize(Isolate* isolate, @@ -8235,6 +8529,15 @@ bool Isolate::GetHeapCodeAndMetadataStatistics( return true; } +v8::MaybeLocal<v8::Promise> Isolate::MeasureMemory( + v8::Local<v8::Context> context, MeasureMemoryMode mode) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this); + i::Handle<i::NativeContext> native_context = + handle(Utils::OpenHandle(*context)->native_context(), isolate); + return v8::Utils::PromiseToLocal( + isolate->heap()->MeasureMemory(native_context, mode)); +} + void Isolate::GetStackSample(const RegisterState& state, void** frames, size_t frames_limit, SampleInfo* sample_info) { RegisterState regs = state; @@ -9062,9 +9365,9 @@ bool debug::Script::GetPossibleBreakpoints( i::Handle<i::Script> script = Utils::OpenHandle(this); if (script->type() == i::Script::TYPE_WASM && this->SourceMappingURL().IsEmpty()) { - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - return module_object.GetPossibleBreakpoints(start, end, locations); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + return i::WasmModuleObject::GetPossibleBreakpoints(native_module, start, + end, locations); } i::Script::InitLineEnds(script); @@ -9113,8 +9416,9 @@ int debug::Script::GetSourceOffset(const debug::Location& location) const { i::Handle<i::Script> script = Utils::OpenHandle(this); if (script->type() == i::Script::TYPE_WASM) { if (this->SourceMappingURL().IsEmpty()) { - return i::WasmModuleObject::cast(script->wasm_module_object()) - .GetFunctionOffset(location.GetLineNumber()) + + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); + return i::wasm::GetWasmFunctionOffset(module, location.GetLineNumber()) + location.GetColumnNumber(); } DCHECK_EQ(0, location.GetLineNumber()); @@ -9202,9 +9506,8 @@ int debug::WasmScript::NumFunctions() const { i::DisallowHeapAllocation no_gc; i::Handle<i::Script> script = Utils::OpenHandle(this); DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - const i::wasm::WasmModule* module = module_object.module(); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); DCHECK_GE(i::kMaxInt, module->functions.size()); return static_cast<int>(module->functions.size()); } @@ -9213,21 +9516,26 @@ int debug::WasmScript::NumImportedFunctions() const { i::DisallowHeapAllocation no_gc; i::Handle<i::Script> script = Utils::OpenHandle(this); DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - const i::wasm::WasmModule* module = module_object.module(); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); DCHECK_GE(i::kMaxInt, module->num_imported_functions); return static_cast<int>(module->num_imported_functions); } +MemorySpan<const uint8_t> debug::WasmScript::Bytecode() const { + i::Handle<i::Script> script = Utils::OpenHandle(this); + i::Vector<const uint8_t> wire_bytes = + script->wasm_native_module()->wire_bytes(); + return {wire_bytes.begin(), wire_bytes.size()}; +} + std::pair<int, int> debug::WasmScript::GetFunctionRange( int function_index) const { i::DisallowHeapAllocation no_gc; i::Handle<i::Script> script = Utils::OpenHandle(this); DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - const i::wasm::WasmModule* module = module_object.module(); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); DCHECK_LE(0, function_index); DCHECK_GT(module->functions.size(), function_index); const i::wasm::WasmFunction& func = module->functions[function_index]; @@ -9241,14 +9549,12 @@ uint32_t debug::WasmScript::GetFunctionHash(int function_index) { i::DisallowHeapAllocation no_gc; i::Handle<i::Script> script = Utils::OpenHandle(this); DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - const i::wasm::WasmModule* module = module_object.module(); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); DCHECK_LE(0, function_index); DCHECK_GT(module->functions.size(), function_index); const i::wasm::WasmFunction& func = module->functions[function_index]; - i::wasm::ModuleWireBytes wire_bytes( - module_object.native_module()->wire_bytes()); + i::wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes()); i::Vector<const i::byte> function_bytes = wire_bytes.GetFunctionBytes(&func); // TODO(herhut): Maybe also take module, name and signature into account. return i::StringHasher::HashSequentialString(function_bytes.begin(), @@ -9260,9 +9566,10 @@ debug::WasmDisassembly debug::WasmScript::DisassembleFunction( i::DisallowHeapAllocation no_gc; i::Handle<i::Script> script = Utils::OpenHandle(this); DCHECK_EQ(i::Script::TYPE_WASM, script->type()); - i::WasmModuleObject module_object = - i::WasmModuleObject::cast(script->wasm_module_object()); - return module_object.DisassembleFunction(function_index); + i::wasm::NativeModule* native_module = script->wasm_native_module(); + const i::wasm::WasmModule* module = native_module->module(); + i::wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes()); + return DisassembleWasmFunction(module, wire_bytes, function_index); } debug::Location::Location(int line_number, int column_number) @@ -9438,7 +9745,7 @@ debug::ConsoleCallArguments::ConsoleCallArguments( } debug::ConsoleCallArguments::ConsoleCallArguments( - internal::BuiltinArguments& args) + const internal::BuiltinArguments& args) : v8::FunctionCallbackInfo<v8::Value>( nullptr, // Drop the first argument (receiver, i.e. the "console" object). @@ -9501,14 +9808,14 @@ v8::Local<debug::GeneratorObject> debug::GeneratorObject::Cast( MaybeLocal<v8::Value> debug::EvaluateGlobal(v8::Isolate* isolate, v8::Local<v8::String> source, - bool throw_on_side_effect) { + EvaluateGlobalMode mode) { i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); PREPARE_FOR_DEBUG_INTERFACE_EXECUTION_WITH_ISOLATE(internal_isolate, Value); Local<Value> result; - has_pending_exception = !ToLocal<Value>( - i::DebugEvaluate::Global(internal_isolate, Utils::OpenHandle(*source), - throw_on_side_effect), - &result); + has_pending_exception = + !ToLocal<Value>(i::DebugEvaluate::Global( + internal_isolate, Utils::OpenHandle(*source), mode), + &result); RETURN_ON_FAILED_EXECUTION(Value); RETURN_ESCAPED(result); } @@ -10009,6 +10316,10 @@ const char* CodeEvent::GetComment() { return reinterpret_cast<i::CodeEvent*>(this)->comment; } +uintptr_t CodeEvent::GetPreviousCodeStartAddress() { + return reinterpret_cast<i::CodeEvent*>(this)->previous_code_start_address; +} + const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) { switch (code_event_type) { case kUnknownType: @@ -10303,17 +10614,6 @@ void Testing::DeoptimizeAll(Isolate* isolate) { i::Deoptimizer::DeoptimizeAll(i_isolate); } -void EmbedderHeapTracer::TracePrologue(TraceFlags flags) { -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#endif - TracePrologue(); -#if __clang__ -#pragma clang diagnostic pop -#endif -} - void EmbedderHeapTracer::TraceEpilogue(TraceSummary* trace_summary) { #if __clang__ #pragma clang diagnostic push @@ -10369,11 +10669,12 @@ void EmbedderHeapTracer::DecreaseAllocatedSize(size_t bytes) { } void EmbedderHeapTracer::RegisterEmbedderReference( - const TracedGlobal<v8::Value>& ref) { + const TracedReferenceBase<v8::Value>& ref) { if (ref.IsEmpty()) return; i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap(); - heap->RegisterExternallyReferencedObject(reinterpret_cast<i::Address*>(*ref)); + heap->RegisterExternallyReferencedObject( + reinterpret_cast<i::Address*>(ref.val_)); } void EmbedderHeapTracer::IterateTracedGlobalHandles( @@ -10383,6 +10684,26 @@ void EmbedderHeapTracer::IterateTracedGlobalHandles( isolate->global_handles()->IterateTracedNodes(visitor); } +bool EmbedderHeapTracer::IsRootForNonTracingGC( + const v8::TracedReference<v8::Value>& handle) { + return true; +} + +bool EmbedderHeapTracer::IsRootForNonTracingGC( + const v8::TracedGlobal<v8::Value>& handle) { + return true; +} + +void EmbedderHeapTracer::ResetHandleInNonTracingGC( + const v8::TracedReference<v8::Value>& handle) { + UNREACHABLE(); +} + +void EmbedderHeapTracer::ResetHandleInNonTracingGC( + const v8::TracedGlobal<v8::Value>& handle) { + UNREACHABLE(); +} + namespace internal { const size_t HandleScopeImplementer::kEnteredContextsOffset = @@ -10473,9 +10794,10 @@ char* HandleScopeImplementer::Iterate(RootVisitor* v, char* storage) { return storage + ArchiveSpacePerThread(); } -DeferredHandles* HandleScopeImplementer::Detach(Address* prev_limit) { - DeferredHandles* deferred = - new DeferredHandles(isolate()->handle_scope_data()->next, isolate()); +std::unique_ptr<DeferredHandles> HandleScopeImplementer::Detach( + Address* prev_limit) { + std::unique_ptr<DeferredHandles> deferred( + new DeferredHandles(isolate()->handle_scope_data()->next, isolate())); while (!blocks_.empty()) { Address* block_start = blocks_.back(); @@ -10584,3 +10906,5 @@ void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info, } // namespace internal } // namespace v8 + +#undef TRACE_BS diff --git a/deps/v8/src/api/api.h b/deps/v8/src/api/api.h index 21bbb3a101549d..907a68c4c26538 100644 --- a/deps/v8/src/api/api.h +++ b/deps/v8/src/api/api.h @@ -5,6 +5,8 @@ #ifndef V8_API_API_H_ #define V8_API_API_H_ +#include <memory> + #include "include/v8-testing.h" #include "src/execution/isolate.h" #include "src/heap/factory.h" @@ -431,7 +433,7 @@ class HandleScopeImplementer { } void BeginDeferredScope(); - DeferredHandles* Detach(Address* prev_limit); + std::unique_ptr<DeferredHandles> Detach(Address* prev_limit); Isolate* isolate_; DetachableVector<Address*> blocks_; diff --git a/deps/v8/src/asmjs/OWNERS b/deps/v8/src/asmjs/OWNERS index 08f39f8d6a2df3..072ba582113ac0 100644 --- a/deps/v8/src/asmjs/OWNERS +++ b/deps/v8/src/asmjs/OWNERS @@ -1,5 +1,5 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org mstarzinger@chromium.org titzer@chromium.org diff --git a/deps/v8/src/asmjs/asm-js.cc b/deps/v8/src/asmjs/asm-js.cc index 7433b6a12cbb72..22714ac16bd41a 100644 --- a/deps/v8/src/asmjs/asm-js.cc +++ b/deps/v8/src/asmjs/asm-js.cc @@ -322,7 +322,7 @@ void AsmJsCompilationJob::RecordHistograms(Isolate* isolate) { std::unique_ptr<UnoptimizedCompilationJob> AsmJs::NewCompilationJob( ParseInfo* parse_info, FunctionLiteral* literal, AccountingAllocator* allocator) { - return base::make_unique<AsmJsCompilationJob>(parse_info, literal, allocator); + return std::make_unique<AsmJsCompilationJob>(parse_info, literal, allocator); } namespace { @@ -387,7 +387,18 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate, ReportInstantiationFailure(script, position, "Requires heap buffer"); return MaybeHandle<Object>(); } - wasm_engine->memory_tracker()->MarkWasmMemoryNotGrowable(memory); + // AsmJs memory must be an ArrayBuffer. + if (memory->is_shared()) { + ReportInstantiationFailure(script, position, + "Invalid heap type: SharedArrayBuffer"); + return MaybeHandle<Object>(); + } + // Mark the buffer as being used as an asm.js memory. This implies two + // things: 1) if the buffer is from a Wasm memory, that memory can no longer + // be grown, since that would detach this buffer, and 2) the buffer cannot + // be postMessage()'d, as that also detaches the buffer. + memory->set_is_asmjs_memory(true); + memory->set_is_detachable(false); size_t size = memory->byte_length(); // Check the asm.js heap size against the valid limits. if (!IsValidAsmjsMemorySize(size)) { diff --git a/deps/v8/src/asmjs/asm-js.h b/deps/v8/src/asmjs/asm-js.h index 3e714cba7a67ed..80a75d0372900c 100644 --- a/deps/v8/src/asmjs/asm-js.h +++ b/deps/v8/src/asmjs/asm-js.h @@ -7,6 +7,8 @@ // Clients of this interface shouldn't depend on lots of asmjs internals. // Do not include anything from src/asmjs here! +#include <memory> + #include "src/common/globals.h" namespace v8 { diff --git a/deps/v8/src/asmjs/asm-parser.cc b/deps/v8/src/asmjs/asm-parser.cc index 6ac39dc89ccf31..33872399262e2a 100644 --- a/deps/v8/src/asmjs/asm-parser.cc +++ b/deps/v8/src/asmjs/asm-parser.cc @@ -387,8 +387,8 @@ void AsmJsParser::ValidateModule() { uint32_t import_index = module_builder_->AddGlobalImport( global_import.import_name, global_import.value_type, false /* mutability */); - start->EmitWithI32V(kExprGetGlobal, import_index); - start->EmitWithI32V(kExprSetGlobal, VarIndex(global_import.var_info)); + start->EmitWithI32V(kExprGlobalGet, import_index); + start->EmitWithI32V(kExprGlobalSet, VarIndex(global_import.var_info)); } start->Emit(kExprEnd); FunctionSig::Builder b(zone(), 0, 0); @@ -952,8 +952,8 @@ void AsmJsParser::ValidateFunctionLocals(size_t param_count, } else { FAIL("Bad local variable definition"); } - current_function_builder_->EmitWithI32V(kExprGetGlobal, - VarIndex(sinfo)); + current_function_builder_->EmitWithI32V(kExprGlobalGet, + VarIndex(sinfo)); current_function_builder_->EmitSetLocal(info->index); } else if (sinfo->type->IsA(stdlib_fround_)) { EXPECT_TOKEN('('); @@ -1447,7 +1447,7 @@ AsmType* AsmJsParser::Identifier() { if (info->kind != VarKind::kGlobal) { FAILn("Undefined global variable"); } - current_function_builder_->EmitWithI32V(kExprGetGlobal, VarIndex(info)); + current_function_builder_->EmitWithI32V(kExprGlobalGet, VarIndex(info)); return info->type; } UNREACHABLE(); @@ -1558,8 +1558,8 @@ AsmType* AsmJsParser::AssignmentExpression() { if (info->kind == VarKind::kLocal) { current_function_builder_->EmitTeeLocal(info->index); } else if (info->kind == VarKind::kGlobal) { - current_function_builder_->EmitWithU32V(kExprSetGlobal, VarIndex(info)); - current_function_builder_->EmitWithU32V(kExprGetGlobal, VarIndex(info)); + current_function_builder_->EmitWithU32V(kExprGlobalSet, VarIndex(info)); + current_function_builder_->EmitWithU32V(kExprGlobalGet, VarIndex(info)); } else { UNREACHABLE(); } @@ -2489,7 +2489,7 @@ void AsmJsParser::ValidateFloatCoercion() { // because imported functions are not allowed to have float return type. call_coercion_position_ = scanner_.Position(); AsmType* ret; - RECURSE(ret = ValidateExpression()); + RECURSE(ret = AssignmentExpression()); if (ret->IsA(AsmType::Floatish())) { // Do nothing, as already a float. } else if (ret->IsA(AsmType::DoubleQ())) { diff --git a/deps/v8/src/ast/ast-function-literal-id-reindexer.cc b/deps/v8/src/ast/ast-function-literal-id-reindexer.cc index 95bd94d8d4d874..b583b5e4214ad4 100644 --- a/deps/v8/src/ast/ast-function-literal-id-reindexer.cc +++ b/deps/v8/src/ast/ast-function-literal-id-reindexer.cc @@ -46,15 +46,28 @@ void AstFunctionLiteralIdReindexer::VisitClassLiteral(ClassLiteral* expr) { if (expr->instance_members_initializer_function() != nullptr) { Visit(expr->instance_members_initializer_function()); } - ZonePtrList<ClassLiteral::Property>* props = expr->properties(); + ZonePtrList<ClassLiteral::Property>* private_members = + expr->private_members(); + for (int i = 0; i < private_members->length(); ++i) { + ClassLiteralProperty* prop = private_members->at(i); + + // Private fields have their key and value present in + // instance_members_initializer_function, so they will + // already have been visited. + if (prop->value()->IsFunctionLiteral()) { + Visit(prop->value()); + } else { + CheckVisited(prop->value()); + } + } + ZonePtrList<ClassLiteral::Property>* props = expr->public_members(); for (int i = 0; i < props->length(); ++i) { ClassLiteralProperty* prop = props->at(i); - // Private fields and public fields with computed names have both their key + // Public fields with computed names have their key // and value present in instance_members_initializer_function, so they will // already have been visited. - if ((prop->is_computed_name() || prop->is_private()) && - !prop->value()->IsFunctionLiteral()) { + if (prop->is_computed_name() && !prop->value()->IsFunctionLiteral()) { if (!prop->key()->IsLiteral()) { CheckVisited(prop->key()); } diff --git a/deps/v8/src/ast/ast-traversal-visitor.h b/deps/v8/src/ast/ast-traversal-visitor.h index 2796e59a8dbb90..a52c5f946e0980 100644 --- a/deps/v8/src/ast/ast-traversal-visitor.h +++ b/deps/v8/src/ast/ast-traversal-visitor.h @@ -490,7 +490,13 @@ void AstTraversalVisitor<Subclass>::VisitClassLiteral(ClassLiteral* expr) { if (expr->instance_members_initializer_function() != nullptr) { RECURSE_EXPRESSION(Visit(expr->instance_members_initializer_function())); } - ZonePtrList<ClassLiteral::Property>* props = expr->properties(); + ZonePtrList<ClassLiteral::Property>* private_members = + expr->private_members(); + for (int i = 0; i < private_members->length(); ++i) { + ClassLiteralProperty* prop = private_members->at(i); + RECURSE_EXPRESSION(Visit(prop->value())); + } + ZonePtrList<ClassLiteral::Property>* props = expr->public_members(); for (int i = 0; i < props->length(); ++i) { ClassLiteralProperty* prop = props->at(i); if (!prop->key()->IsLiteral()) { diff --git a/deps/v8/src/ast/ast.cc b/deps/v8/src/ast/ast.cc index 4b6c4805dedc16..130d34dffa518c 100644 --- a/deps/v8/src/ast/ast.cc +++ b/deps/v8/src/ast/ast.cc @@ -293,6 +293,10 @@ bool FunctionLiteral::requires_brand_initialization() const { return outer->AsClassScope()->brand() != nullptr; } +bool FunctionLiteral::private_name_lookup_skips_outer_class() const { + return scope()->private_name_lookup_skips_outer_class(); +} + ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value, Kind kind, bool is_computed_name) : LiteralProperty(key, value, is_computed_name), @@ -886,7 +890,7 @@ Handle<Object> Literal::BuildValue(Isolate* isolate) const { case kSmi: return handle(Smi::FromInt(smi_), isolate); case kHeapNumber: - return isolate->factory()->NewNumber(number_, AllocationType::kOld); + return isolate->factory()->NewNumber<AllocationType::kOld>(number_); case kString: return string_->string(); case kSymbol: diff --git a/deps/v8/src/ast/ast.h b/deps/v8/src/ast/ast.h index ced9f775dd57bc..d706dbc37fbc7b 100644 --- a/deps/v8/src/ast/ast.h +++ b/deps/v8/src/ast/ast.h @@ -724,11 +724,14 @@ class BreakStatement final : public JumpStatement { class ReturnStatement final : public JumpStatement { public: - enum Type { kNormal, kAsyncReturn }; + enum Type { kNormal, kAsyncReturn, kSyntheticAsyncReturn }; Expression* expression() const { return expression_; } Type type() const { return TypeField::decode(bit_field_); } - bool is_async_return() const { return type() == kAsyncReturn; } + bool is_async_return() const { return type() != kNormal; } + bool is_synthetic_async_return() const { + return type() == kSyntheticAsyncReturn; + } int end_position() const { return end_position_; } @@ -745,7 +748,7 @@ class ReturnStatement final : public JumpStatement { Expression* expression_; int end_position_; - using TypeField = JumpStatement::NextBitField<Type, 1>; + using TypeField = JumpStatement::NextBitField<Type, 2>; }; @@ -917,6 +920,10 @@ class TryCatchStatement final : public TryStatement { outer_catch_prediction != HandlerTable::UNCAUGHT; } + bool is_try_catch_for_async() { + return catch_prediction_ == HandlerTable::ASYNC_AWAIT; + } + private: friend class AstNodeFactory; @@ -2343,6 +2350,8 @@ class FunctionLiteral final : public Expression { bool requires_brand_initialization() const; + bool private_name_lookup_skips_outer_class() const; + ProducedPreparseData* produced_preparse_data() const { return produced_preparse_data_; } @@ -2481,10 +2490,10 @@ class ClassLiteral final : public Expression { using Property = ClassLiteralProperty; ClassScope* scope() const { return scope_; } - Variable* class_variable() const { return class_variable_; } Expression* extends() const { return extends_; } FunctionLiteral* constructor() const { return constructor_; } - ZonePtrList<Property>* properties() const { return properties_; } + ZonePtrList<Property>* public_members() const { return public_members_; } + ZonePtrList<Property>* private_members() const { return private_members_; } int start_position() const { return position(); } int end_position() const { return end_position_; } bool has_name_static_property() const { @@ -2497,6 +2506,9 @@ class ClassLiteral final : public Expression { bool is_anonymous_expression() const { return IsAnonymousExpression::decode(bit_field_); } + bool has_private_methods() const { + return HasPrivateMethods::decode(bit_field_); + } bool IsAnonymousFunctionDefinition() const { return is_anonymous_expression(); } @@ -2512,39 +2524,43 @@ class ClassLiteral final : public Expression { private: friend class AstNodeFactory; - ClassLiteral(ClassScope* scope, Variable* class_variable, Expression* extends, - FunctionLiteral* constructor, ZonePtrList<Property>* properties, + ClassLiteral(ClassScope* scope, Expression* extends, + FunctionLiteral* constructor, + ZonePtrList<Property>* public_members, + ZonePtrList<Property>* private_members, FunctionLiteral* static_fields_initializer, FunctionLiteral* instance_members_initializer_function, int start_position, int end_position, bool has_name_static_property, bool has_static_computed_names, - bool is_anonymous) + bool is_anonymous, bool has_private_methods) : Expression(start_position, kClassLiteral), end_position_(end_position), scope_(scope), - class_variable_(class_variable), extends_(extends), constructor_(constructor), - properties_(properties), + public_members_(public_members), + private_members_(private_members), static_fields_initializer_(static_fields_initializer), instance_members_initializer_function_( instance_members_initializer_function) { bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) | HasStaticComputedNames::encode(has_static_computed_names) | - IsAnonymousExpression::encode(is_anonymous); + IsAnonymousExpression::encode(is_anonymous) | + HasPrivateMethods::encode(has_private_methods); } int end_position_; ClassScope* scope_; - Variable* class_variable_; Expression* extends_; FunctionLiteral* constructor_; - ZonePtrList<Property>* properties_; + ZonePtrList<Property>* public_members_; + ZonePtrList<Property>* private_members_; FunctionLiteral* static_fields_initializer_; FunctionLiteral* instance_members_initializer_function_; using HasNameStaticProperty = Expression::NextBitField<bool, 1>; using HasStaticComputedNames = HasNameStaticProperty::Next<bool, 1>; using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>; + using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>; }; @@ -2885,6 +2901,12 @@ class AstNodeFactory final { expression, ReturnStatement::kAsyncReturn, pos, end_position); } + ReturnStatement* NewSyntheticAsyncReturnStatement( + Expression* expression, int pos, int end_position = kNoSourcePosition) { + return new (zone_) ReturnStatement( + expression, ReturnStatement::kSyntheticAsyncReturn, pos, end_position); + } + WithStatement* NewWithStatement(Scope* scope, Expression* expression, Statement* statement, @@ -3244,18 +3266,19 @@ class AstNodeFactory final { } ClassLiteral* NewClassLiteral( - ClassScope* scope, Variable* variable, Expression* extends, - FunctionLiteral* constructor, - ZonePtrList<ClassLiteral::Property>* properties, + ClassScope* scope, Expression* extends, FunctionLiteral* constructor, + ZonePtrList<ClassLiteral::Property>* public_members, + ZonePtrList<ClassLiteral::Property>* private_members, FunctionLiteral* static_fields_initializer, FunctionLiteral* instance_members_initializer_function, int start_position, int end_position, bool has_name_static_property, - bool has_static_computed_names, bool is_anonymous) { + bool has_static_computed_names, bool is_anonymous, + bool has_private_methods) { return new (zone_) ClassLiteral( - scope, variable, extends, constructor, properties, + scope, extends, constructor, public_members, private_members, static_fields_initializer, instance_members_initializer_function, start_position, end_position, has_name_static_property, - has_static_computed_names, is_anonymous); + has_static_computed_names, is_anonymous, has_private_methods); } NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, diff --git a/deps/v8/src/ast/modules.cc b/deps/v8/src/ast/modules.cc index dbd20f50a80869..9c122fca869c2c 100644 --- a/deps/v8/src/ast/modules.cc +++ b/deps/v8/src/ast/modules.cc @@ -84,11 +84,11 @@ void SourceTextModuleDescriptor::AddStarExport( } namespace { -Handle<HeapObject> ToStringOrUndefined(Isolate* isolate, - const AstRawString* s) { - return (s == nullptr) - ? Handle<HeapObject>::cast(isolate->factory()->undefined_value()) - : Handle<HeapObject>::cast(s->string()); +Handle<PrimitiveHeapObject> ToStringOrUndefined(Isolate* isolate, + const AstRawString* s) { + return (s == nullptr) ? Handle<PrimitiveHeapObject>::cast( + isolate->factory()->undefined_value()) + : Handle<PrimitiveHeapObject>::cast(s->string()); } } // namespace diff --git a/deps/v8/src/ast/prettyprinter.cc b/deps/v8/src/ast/prettyprinter.cc index 581517ee4ec34a..5bf9362fb8c5b7 100644 --- a/deps/v8/src/ast/prettyprinter.cc +++ b/deps/v8/src/ast/prettyprinter.cc @@ -217,8 +217,11 @@ void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) { void CallPrinter::VisitClassLiteral(ClassLiteral* node) { if (node->extends()) Find(node->extends()); - for (int i = 0; i < node->properties()->length(); i++) { - Find(node->properties()->at(i)->value()); + for (int i = 0; i < node->public_members()->length(); i++) { + Find(node->public_members()->at(i)->value()); + } + for (int i = 0; i < node->private_members()->length(); i++) { + Find(node->private_members()->at(i)->value()); } } @@ -1106,7 +1109,8 @@ void AstPrinter::VisitClassLiteral(ClassLiteral* node) { PrintIndentedVisit("INSTANCE MEMBERS INITIALIZER", node->instance_members_initializer_function()); } - PrintClassProperties(node->properties()); + PrintClassProperties(node->private_members()); + PrintClassProperties(node->public_members()); } void AstPrinter::VisitInitializeClassMembersStatement( diff --git a/deps/v8/src/ast/prettyprinter.h b/deps/v8/src/ast/prettyprinter.h index 322fd9fb1437bf..795436d4222fc8 100644 --- a/deps/v8/src/ast/prettyprinter.h +++ b/deps/v8/src/ast/prettyprinter.h @@ -5,10 +5,12 @@ #ifndef V8_AST_PRETTYPRINTER_H_ #define V8_AST_PRETTYPRINTER_H_ +#include <memory> + #include "src/ast/ast.h" #include "src/base/compiler-specific.h" -#include "src/utils/allocation.h" #include "src/objects/function-kind.h" +#include "src/utils/allocation.h" namespace v8 { namespace internal { diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc index c8002dd088c9c7..3e1f8f53ae2111 100644 --- a/deps/v8/src/ast/scopes.cc +++ b/deps/v8/src/ast/scopes.cc @@ -40,7 +40,7 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, - bool* was_added) { + IsStaticFlag is_static_flag, bool* was_added) { // AstRawStrings are unambiguous, i.e., the same string is always represented // by the same AstRawString*. // FIXME(marja): fix the type of Lookup. @@ -51,8 +51,9 @@ Variable* VariableMap::Declare(Zone* zone, Scope* scope, if (*was_added) { // The variable has not been declared yet -> insert it. DCHECK_EQ(name, p->key); - Variable* variable = new (zone) Variable( - scope, name, mode, kind, initialization_flag, maybe_assigned_flag); + Variable* variable = + new (zone) Variable(scope, name, mode, kind, initialization_flag, + maybe_assigned_flag, is_static_flag); p->value = variable; } return reinterpret_cast<Variable*>(p->value); @@ -102,6 +103,9 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) DCHECK_NE(SCRIPT_SCOPE, scope_type); SetDefaults(); set_language_mode(outer_scope->language_mode()); + private_name_lookup_skips_outer_class_ = + outer_scope->is_class_scope() && + outer_scope->AsClassScope()->IsParsingHeritage(); outer_scope_->AddInnerScope(this); } @@ -140,14 +144,18 @@ ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info, set_language_mode(LanguageMode::kStrict); } -ClassScope::ClassScope(Zone* zone, Scope* outer_scope) - : Scope(zone, outer_scope, CLASS_SCOPE) { +ClassScope::ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous) + : Scope(zone, outer_scope, CLASS_SCOPE), + rare_data_and_is_parsing_heritage_(nullptr), + is_anonymous_class_(is_anonymous) { set_language_mode(LanguageMode::kStrict); } -ClassScope::ClassScope(Zone* zone, AstValueFactory* ast_value_factory, +ClassScope::ClassScope(Isolate* isolate, Zone* zone, + AstValueFactory* ast_value_factory, Handle<ScopeInfo> scope_info) - : Scope(zone, CLASS_SCOPE, scope_info) { + : Scope(zone, CLASS_SCOPE, scope_info), + rare_data_and_is_parsing_heritage_(nullptr) { set_language_mode(LanguageMode::kStrict); if (scope_info->HasClassBrand()) { Variable* brand = @@ -155,6 +163,25 @@ ClassScope::ClassScope(Zone* zone, AstValueFactory* ast_value_factory, DCHECK_NOT_NULL(brand); EnsureRareData()->brand = brand; } + + // If the class variable is context-allocated and its index is + // saved for deserialization, deserialize it. + if (scope_info->HasSavedClassVariableIndex()) { + int index = scope_info->SavedClassVariableContextLocalIndex(); + DCHECK_GE(index, 0); + DCHECK_LT(index, scope_info->ContextLocalCount()); + String name = scope_info->ContextLocalName(index); + DCHECK_EQ(scope_info->ContextLocalMode(index), VariableMode::kConst); + DCHECK_EQ(scope_info->ContextLocalInitFlag(index), + InitializationFlag::kNeedsInitialization); + DCHECK_EQ(scope_info->ContextLocalMaybeAssignedFlag(index), + MaybeAssignedFlag::kMaybeAssigned); + Variable* var = DeclareClassVariable( + ast_value_factory, ast_value_factory->GetString(handle(name, isolate)), + kNoSourcePosition); + var->AllocateTo(VariableLocation::CONTEXT, + Context::MIN_CONTEXT_SLOTS + index); + } } Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) @@ -171,6 +198,8 @@ Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) set_language_mode(scope_info->language_mode()); num_heap_slots_ = scope_info->ContextLength(); DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); + private_name_lookup_skips_outer_class_ = + scope_info->PrivateNameLookupSkipsOuterClass(); // We don't really need to use the preparsed scope data; this is just to // shorten the recursion in SetMustUsePreparseData. must_use_preparsed_scope_data_ = true; @@ -222,6 +251,7 @@ void DeclarationScope::SetDefaults() { has_this_reference_ = false; has_this_declaration_ = (is_function_scope() && !is_arrow_scope()) || is_module_scope(); + needs_private_name_context_chain_recalc_ = false; has_rest_ = false; receiver_ = nullptr; new_target_ = nullptr; @@ -270,6 +300,8 @@ void Scope::SetDefaults() { is_declaration_scope_ = false; + private_name_lookup_skips_outer_class_ = false; + must_use_preparsed_scope_data_ = false; } @@ -343,8 +375,8 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, outer_scope = new (zone) DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate)); } else if (scope_info.scope_type() == CLASS_SCOPE) { - outer_scope = new (zone) - ClassScope(zone, ast_value_factory, handle(scope_info, isolate)); + outer_scope = new (zone) ClassScope(isolate, zone, ast_value_factory, + handle(scope_info, isolate)); } else if (scope_info.scope_type() == BLOCK_SCOPE) { if (scope_info.is_declaration_scope()) { outer_scope = new (zone) @@ -546,7 +578,8 @@ bool DeclarationScope::Analyze(ParseInfo* info) { if (scope->must_use_preparsed_scope_data_) { DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE); allow_deref.emplace(); - info->consumed_preparse_data()->RestoreScopeAllocationData(scope); + info->consumed_preparse_data()->RestoreScopeAllocationData( + scope, info->ast_value_factory()); } if (!scope->AllocateVariables(info)) return false; @@ -787,11 +820,13 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) { VariableMode mode; InitializationFlag init_flag; MaybeAssignedFlag maybe_assigned_flag; + IsStaticFlag is_static_flag; { location = VariableLocation::CONTEXT; index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, - &init_flag, &maybe_assigned_flag); + &init_flag, &maybe_assigned_flag, + &is_static_flag); found = index >= 0; } @@ -816,9 +851,9 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) { } bool was_added; - Variable* var = - cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, - init_flag, maybe_assigned_flag, &was_added); + Variable* var = cache->variables_.Declare( + zone(), this, name, mode, NORMAL_VARIABLE, init_flag, maybe_assigned_flag, + IsStaticFlag::kNotStatic, &was_added); DCHECK(was_added); var->AllocateTo(location, index); return var; @@ -1047,7 +1082,7 @@ Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, bool was_added; return cache->variables_.Declare( zone(), this, name, VariableMode::kDynamicGlobal, kind, - kCreatedInitialized, kNotAssigned, &was_added); + kCreatedInitialized, kNotAssigned, IsStaticFlag::kNotStatic, &was_added); // TODO(neis): Mark variable as maybe-assigned? } @@ -1165,9 +1200,9 @@ bool DeclarationScope::AllocateVariables(ParseInfo* info) { // to ensure that UpdateNeedsHoleCheck() can detect import variables. if (is_module_scope()) AsModuleScope()->AllocateModuleVariables(); - ClassScope* closest_class_scope = GetClassScope(); - if (closest_class_scope != nullptr && - !closest_class_scope->ResolvePrivateNames(info)) { + PrivateNameScopeIterator private_name_scope_iter(this); + if (!private_name_scope_iter.Done() && + !private_name_scope_iter.GetScope()->ResolvePrivateNames(info)) { DCHECK(info->pending_error_handler()->has_pending_error()); return false; } @@ -1177,7 +1212,7 @@ bool DeclarationScope::AllocateVariables(ParseInfo* info) { return false; } - // // Don't allocate variables of preparsed scopes. + // Don't allocate variables of preparsed scopes. if (!was_lazily_parsed()) AllocateVariablesRecursively(); return true; @@ -1254,17 +1289,6 @@ int Scope::ContextChainLengthUntilOutermostSloppyEval() const { return result; } -ClassScope* Scope::GetClassScope() { - Scope* scope = this; - while (scope != nullptr && !scope->is_class_scope()) { - scope = scope->outer_scope(); - } - if (scope != nullptr && scope->is_class_scope()) { - return scope->AsClassScope(); - } - return nullptr; -} - DeclarationScope* Scope::GetDeclarationScope() { Scope* scope = this; while (!scope->is_declaration_scope()) { @@ -1688,11 +1712,17 @@ void Scope::Print(int n) { if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) { Indent(n1, "// scope needs home object\n"); } + if (private_name_lookup_skips_outer_class()) { + Indent(n1, "// scope skips outer class for #-names\n"); + } if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); if (is_declaration_scope()) { DeclarationScope* scope = AsDeclarationScope(); if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n"); if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n"); + if (scope->needs_private_name_context_chain_recalc()) { + Indent(n1, "// needs #-name context chain recalc\n"); + } } if (num_stack_slots_ > 0) { Indent(n1, "// "); @@ -1729,15 +1759,24 @@ void Scope::Print(int n) { if (is_class_scope()) { ClassScope* class_scope = AsClassScope(); - if (class_scope->rare_data_ != nullptr) { + if (class_scope->GetRareData() != nullptr) { PrintMap(n1, "// private name vars:\n", - &(class_scope->rare_data_->private_name_map), true, function); + &(class_scope->GetRareData()->private_name_map), true, function); Variable* brand = class_scope->brand(); if (brand != nullptr) { Indent(n1, "// brand var:\n"); PrintVar(n1, brand); } } + if (class_scope->class_variable() != nullptr) { + Indent(n1, "// class var"); + PrintF("%s%s:\n", + class_scope->class_variable()->is_used() ? ", used" : ", unused", + class_scope->should_save_class_variable_index() + ? ", index saved" + : ", index not saved"); + PrintVar(n1, class_scope->class_variable()); + } } // Print inner scopes (disable by providing negative n). @@ -1780,9 +1819,9 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { // Declare a new non-local. DCHECK(IsDynamicVariableMode(mode)); bool was_added; - Variable* var = - variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, - kCreatedInitialized, kNotAssigned, &was_added); + Variable* var = variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE, + kCreatedInitialized, kNotAssigned, + IsStaticFlag::kNotStatic, &was_added); // Allocate it by giving it a dynamic lookup. var->AllocateTo(VariableLocation::LOOKUP, -1); return var; @@ -2103,8 +2142,7 @@ bool Scope::MustAllocateInContext(Variable* var) { if (mode == VariableMode::kTemporary) return false; if (is_catch_scope()) return true; if (is_script_scope() || is_eval_scope()) { - if (IsLexicalVariableMode(mode) || - IsPrivateMethodOrAccessorVariableMode(mode)) { + if (IsLexicalVariableMode(mode)) { return true; } } @@ -2308,6 +2346,47 @@ void Scope::AllocateScopeInfosRecursively(Isolate* isolate, } } +void DeclarationScope::RecalcPrivateNameContextChain() { + // The outermost scope in a class heritage expression is marked to skip the + // class scope during private name resolution. It is possible, however, that + // either the class scope won't require a Context and ScopeInfo, or the + // outermost scope in the heritage position won't. Simply copying the bit from + // full parse into the ScopeInfo will break lazy compilation. In the former + // case the scope that is marked to skip its outer scope will incorrectly skip + // a different class scope than the one we intended to skip. In the latter + // case variables resolved through an inner scope will incorrectly check the + // class scope since we lost the skip bit from the outermost heritage scope. + // + // This method fixes both cases by, in outermost to innermost order, copying + // the value of the skip bit from outer scopes that don't require a Context. + DCHECK(needs_private_name_context_chain_recalc_); + this->ForEach([](Scope* scope) { + Scope* outer = scope->outer_scope(); + if (!outer) return Iteration::kDescend; + if (!outer->NeedsContext()) { + scope->private_name_lookup_skips_outer_class_ = + outer->private_name_lookup_skips_outer_class(); + } + if (!scope->is_function_scope() || + scope->AsDeclarationScope()->ShouldEagerCompile()) { + return Iteration::kDescend; + } + return Iteration::kContinue; + }); +} + +void DeclarationScope::RecordNeedsPrivateNameContextChainRecalc() { + DCHECK_EQ(GetClosureScope(), this); + DeclarationScope* scope; + for (scope = this; scope != nullptr; + scope = scope->outer_scope() != nullptr + ? scope->outer_scope()->GetClosureScope() + : nullptr) { + if (scope->needs_private_name_context_chain_recalc_) return; + scope->needs_private_name_context_chain_recalc_ = true; + } +} + // static void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) { DeclarationScope* scope = info->literal()->scope(); @@ -2318,6 +2397,9 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) { outer_scope = scope->outer_scope_->scope_info_; } + if (scope->needs_private_name_context_chain_recalc()) { + scope->RecalcPrivateNameContextChain(); + } scope->AllocateScopeInfosRecursively(isolate, outer_scope); // The debugger expects all shared function infos to contain a scope info. @@ -2359,14 +2441,20 @@ bool IsComplementaryAccessorPair(VariableMode a, VariableMode b) { } Variable* ClassScope::DeclarePrivateName(const AstRawString* name, - VariableMode mode, bool* was_added) { + VariableMode mode, + IsStaticFlag is_static_flag, + bool* was_added) { Variable* result = EnsureRareData()->private_name_map.Declare( zone(), this, name, mode, NORMAL_VARIABLE, InitializationFlag::kNeedsInitialization, - MaybeAssignedFlag::kMaybeAssigned, was_added); + MaybeAssignedFlag::kMaybeAssigned, is_static_flag, was_added); if (*was_added) { locals_.Add(result); - } else if (IsComplementaryAccessorPair(result->mode(), mode)) { + has_static_private_methods_ |= + (result->is_static() && + IsPrivateMethodOrAccessorVariableMode(result->mode())); + } else if (IsComplementaryAccessorPair(result->mode(), mode) && + result->is_static_flag() == is_static_flag) { *was_added = true; result->set_mode(VariableMode::kPrivateGetterAndSetter); } @@ -2375,38 +2463,42 @@ Variable* ClassScope::DeclarePrivateName(const AstRawString* name, } Variable* ClassScope::LookupLocalPrivateName(const AstRawString* name) { - if (rare_data_ == nullptr) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr) { return nullptr; } - return rare_data_->private_name_map.Lookup(name); + return rare_data->private_name_map.Lookup(name); } UnresolvedList::Iterator ClassScope::GetUnresolvedPrivateNameTail() { - if (rare_data_ == nullptr) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr) { return UnresolvedList::Iterator(); } - return rare_data_->unresolved_private_names.end(); + return rare_data->unresolved_private_names.end(); } void ClassScope::ResetUnresolvedPrivateNameTail(UnresolvedList::Iterator tail) { - if (rare_data_ == nullptr || - rare_data_->unresolved_private_names.end() == tail) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr || + rare_data->unresolved_private_names.end() == tail) { return; } bool tail_is_empty = tail == UnresolvedList::Iterator(); if (tail_is_empty) { // If the saved tail is empty, the list used to be empty, so clear it. - rare_data_->unresolved_private_names.Clear(); + rare_data->unresolved_private_names.Clear(); } else { - rare_data_->unresolved_private_names.Rewind(tail); + rare_data->unresolved_private_names.Rewind(tail); } } void ClassScope::MigrateUnresolvedPrivateNameTail( AstNodeFactory* ast_node_factory, UnresolvedList::Iterator tail) { - if (rare_data_ == nullptr || - rare_data_->unresolved_private_names.end() == tail) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr || + rare_data->unresolved_private_names.end() == tail) { return; } UnresolvedList migrated_names; @@ -2415,9 +2507,9 @@ void ClassScope::MigrateUnresolvedPrivateNameTail( // migrate everything after the head. bool tail_is_empty = tail == UnresolvedList::Iterator(); UnresolvedList::Iterator it = - tail_is_empty ? rare_data_->unresolved_private_names.begin() : tail; + tail_is_empty ? rare_data->unresolved_private_names.begin() : tail; - for (; it != rare_data_->unresolved_private_names.end(); ++it) { + for (; it != rare_data->unresolved_private_names.end(); ++it) { VariableProxy* proxy = *it; VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); migrated_names.Add(copy); @@ -2425,20 +2517,11 @@ void ClassScope::MigrateUnresolvedPrivateNameTail( // Replace with the migrated copies. if (tail_is_empty) { - rare_data_->unresolved_private_names.Clear(); + rare_data->unresolved_private_names.Clear(); } else { - rare_data_->unresolved_private_names.Rewind(tail); + rare_data->unresolved_private_names.Rewind(tail); } - rare_data_->unresolved_private_names.Append(std::move(migrated_names)); -} - -void ClassScope::AddUnresolvedPrivateName(VariableProxy* proxy) { - // During a reparse, already_resolved_ may be true here, because - // the class scope is deserialized while the function scope inside may - // be new. - DCHECK(!proxy->is_resolved()); - DCHECK(proxy->IsPrivateName()); - EnsureRareData()->unresolved_private_names.Add(proxy); + rare_data->unresolved_private_names.Append(std::move(migrated_names)); } Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { @@ -2450,8 +2533,10 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { VariableMode mode; InitializationFlag init_flag; MaybeAssignedFlag maybe_assigned_flag; - int index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, - &init_flag, &maybe_assigned_flag); + IsStaticFlag is_static_flag; + int index = + ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode, &init_flag, + &maybe_assigned_flag, &is_static_flag); if (index < 0) { return nullptr; } @@ -2463,7 +2548,7 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { // Add the found private name to the map to speed up subsequent // lookups for the same name. bool was_added; - Variable* var = DeclarePrivateName(name, mode, &was_added); + Variable* var = DeclarePrivateName(name, mode, is_static_flag, &was_added); DCHECK(was_added); var->AllocateTo(VariableLocation::CONTEXT, index); return var; @@ -2472,15 +2557,14 @@ Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) { Variable* ClassScope::LookupPrivateName(VariableProxy* proxy) { DCHECK(!proxy->is_resolved()); - for (Scope* scope = this; !scope->is_script_scope(); - scope = scope->outer_scope_) { - if (!scope->is_class_scope()) continue; // Only search in class scopes - ClassScope* class_scope = scope->AsClassScope(); + for (PrivateNameScopeIterator scope_iter(this); !scope_iter.Done(); + scope_iter.Next()) { + ClassScope* scope = scope_iter.GetScope(); // Try finding it in the private name map first, if it can't be found, // try the deseralized scope info. - Variable* var = class_scope->LookupLocalPrivateName(proxy->raw_name()); - if (var == nullptr && !class_scope->scope_info_.is_null()) { - var = class_scope->LookupPrivateNameInScopeInfo(proxy->raw_name()); + Variable* var = scope->LookupLocalPrivateName(proxy->raw_name()); + if (var == nullptr && !scope->scope_info_.is_null()) { + var = scope->LookupPrivateNameInScopeInfo(proxy->raw_name()); } if (var != nullptr) { return var; @@ -2490,22 +2574,24 @@ Variable* ClassScope::LookupPrivateName(VariableProxy* proxy) { } bool ClassScope::ResolvePrivateNames(ParseInfo* info) { - if (rare_data_ == nullptr || - rare_data_->unresolved_private_names.is_empty()) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr || rare_data->unresolved_private_names.is_empty()) { return true; } - UnresolvedList& list = rare_data_->unresolved_private_names; + UnresolvedList& list = rare_data->unresolved_private_names; for (VariableProxy* proxy : list) { Variable* var = LookupPrivateName(proxy); if (var == nullptr) { + // It's only possible to fail to resolve private names here if + // this is at the top level or the private name is accessed through eval. + DCHECK(info->is_eval() || outer_scope_->is_script_scope()); Scanner::Location loc = proxy->location(); info->pending_error_handler()->ReportMessageAt( loc.beg_pos, loc.end_pos, MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name()); return false; } else { - var->set_is_used(); proxy->BindTo(var); } } @@ -2517,20 +2603,20 @@ bool ClassScope::ResolvePrivateNames(ParseInfo* info) { } VariableProxy* ClassScope::ResolvePrivateNamesPartially() { - if (rare_data_ == nullptr || - rare_data_->unresolved_private_names.is_empty()) { + RareData* rare_data = GetRareData(); + if (rare_data == nullptr || rare_data->unresolved_private_names.is_empty()) { return nullptr; } - ClassScope* outer_class_scope = - outer_scope_ == nullptr ? nullptr : outer_scope_->GetClassScope(); - UnresolvedList& unresolved = rare_data_->unresolved_private_names; - bool has_private_names = rare_data_->private_name_map.capacity() > 0; + PrivateNameScopeIterator private_name_scope_iter(this); + private_name_scope_iter.Next(); + UnresolvedList& unresolved = rare_data->unresolved_private_names; + bool has_private_names = rare_data->private_name_map.capacity() > 0; // If the class itself does not have private names, nor does it have - // an outer class scope, then we are certain any private name access + // an outer private name scope, then we are certain any private name access // inside cannot be resolved. - if (!has_private_names && outer_class_scope == nullptr && + if (!has_private_names && private_name_scope_iter.Done() && !unresolved.is_empty()) { return unresolved.first(); } @@ -2548,21 +2634,27 @@ VariableProxy* ClassScope::ResolvePrivateNamesPartially() { if (var != nullptr) { var->set_is_used(); proxy->BindTo(var); + // If the variable being accessed is a static private method, we need to + // save the class variable in the context to check that the receiver is + // the class during runtime. + has_explicit_static_private_methods_access_ |= + (var->is_static() && + IsPrivateMethodOrAccessorVariableMode(var->mode())); } } // If the current scope does not have declared private names, // try looking from the outer class scope later. if (var == nullptr) { - // There's no outer class scope so we are certain that the variable + // There's no outer private name scope so we are certain that the variable // cannot be resolved later. - if (outer_class_scope == nullptr) { + if (private_name_scope_iter.Done()) { return proxy; } - // The private name may be found later in the outer class scope, - // so push it to the outer sopce. - outer_class_scope->AddUnresolvedPrivateName(proxy); + // The private name may be found later in the outer private name scope, so + // push it to the outer sopce. + private_name_scope_iter.AddUnresolvedPrivateName(proxy); } proxy = next; @@ -2573,14 +2665,16 @@ VariableProxy* ClassScope::ResolvePrivateNamesPartially() { } Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory, + IsStaticFlag is_static_flag, int class_token_pos) { - DCHECK_IMPLIES(rare_data_ != nullptr, rare_data_->brand == nullptr); + DCHECK_IMPLIES(GetRareData() != nullptr, GetRareData()->brand == nullptr); bool was_added; Variable* brand = Declare(zone(), ast_value_factory->dot_brand_string(), VariableMode::kConst, NORMAL_VARIABLE, InitializationFlag::kNeedsInitialization, MaybeAssignedFlag::kMaybeAssigned, &was_added); DCHECK(was_added); + brand->set_is_static_flag(is_static_flag); brand->ForceContextAllocation(); brand->set_is_used(); EnsureRareData()->brand = brand; @@ -2588,5 +2682,61 @@ Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory, return brand; } +Variable* ClassScope::DeclareClassVariable(AstValueFactory* ast_value_factory, + const AstRawString* name, + int class_token_pos) { + DCHECK_NULL(class_variable_); + bool was_added; + class_variable_ = + Declare(zone(), name == nullptr ? ast_value_factory->dot_string() : name, + VariableMode::kConst, NORMAL_VARIABLE, + InitializationFlag::kNeedsInitialization, + MaybeAssignedFlag::kMaybeAssigned, &was_added); + DCHECK(was_added); + class_variable_->set_initializer_position(class_token_pos); + return class_variable_; +} + +PrivateNameScopeIterator::PrivateNameScopeIterator(Scope* start) + : start_scope_(start), current_scope_(start) { + if (!start->is_class_scope() || start->AsClassScope()->IsParsingHeritage()) { + Next(); + } +} + +void PrivateNameScopeIterator::Next() { + DCHECK(!Done()); + Scope* inner = current_scope_; + Scope* scope = inner->outer_scope(); + while (scope != nullptr) { + if (scope->is_class_scope()) { + if (!inner->private_name_lookup_skips_outer_class()) { + current_scope_ = scope; + return; + } + skipped_any_scopes_ = true; + } + inner = scope; + scope = scope->outer_scope(); + } + current_scope_ = nullptr; +} + +void PrivateNameScopeIterator::AddUnresolvedPrivateName(VariableProxy* proxy) { + // During a reparse, current_scope_->already_resolved_ may be true here, + // because the class scope is deserialized while the function scope inside may + // be new. + DCHECK(!proxy->is_resolved()); + DCHECK(proxy->IsPrivateName()); + GetScope()->EnsureRareData()->unresolved_private_names.Add(proxy); + // Any closure scope that contain uses of private names that skips over a + // class scope due to heritage expressions need private name context chain + // recalculation, since not all scopes require a Context or ScopeInfo. See + // comment in DeclarationScope::RecalcPrivateNameContextChain. + if (V8_UNLIKELY(skipped_any_scopes_)) { + start_scope_->GetClosureScope()->RecordNeedsPrivateNameContextChainRecalc(); + } +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h index 73e6e8fd89755f..30838db28b553c 100644 --- a/deps/v8/src/ast/scopes.h +++ b/deps/v8/src/ast/scopes.h @@ -44,7 +44,7 @@ class VariableMap : public ZoneHashMap { VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, - bool* was_added); + IsStaticFlag is_static_flag, bool* was_added); V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name); void Remove(Variable* var); @@ -360,6 +360,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { bool is_class_scope() const { return scope_type_ == CLASS_SCOPE; } bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; } + bool private_name_lookup_skips_outer_class() const { + return private_name_lookup_skips_outer_class_; + } bool IsAsmModule() const; // Returns true if this scope or any inner scopes that might be eagerly // compiled are asm modules. @@ -464,10 +467,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // sloppy eval call. One if this->sloppy_eval_can_extend_vars(). int ContextChainLengthUntilOutermostSloppyEval() const; - // Find the closest class scope in the current scope and outer scopes. If no - // class scope is found, nullptr will be returned. - ClassScope* GetClassScope(); - // Find the first function, script, eval or (declaration) block scope. This is // the scope where var declarations will be hoisted to in the implementation. DeclarationScope* GetDeclarationScope(); @@ -557,9 +556,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { Variable* Declare(Zone* zone, const AstRawString* name, VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, bool* was_added) { - Variable* result = - variables_.Declare(zone, this, name, mode, kind, initialization_flag, - maybe_assigned_flag, was_added); + // Static variables can only be declared using ClassScope methods. + Variable* result = variables_.Declare( + zone, this, name, mode, kind, initialization_flag, maybe_assigned_flag, + IsStaticFlag::kNotStatic, was_added); if (*was_added) locals_.Add(result); return result; } @@ -713,7 +713,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // This scope's declarations might not be executed in order (e.g., switch). bool scope_nonlinear_ : 1; bool is_hidden_ : 1; - // Temporary workaround that allows masking of 'this' in debug-evalute scopes. + // Temporary workaround that allows masking of 'this' in debug-evaluate + // scopes. bool is_debug_evaluate_scope_ : 1; // True if one of the inner scopes or the scope itself calls eval. @@ -723,6 +724,11 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { // True if it holds 'var' declarations. bool is_declaration_scope_ : 1; + // True if the outer scope is a class scope and should be skipped when + // resolving private names, i.e. if the scope is in a class heritage + // expression. + bool private_name_lookup_skips_outer_class_ : 1; + bool must_use_preparsed_scope_data_ : 1; }; @@ -859,6 +865,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { return IsClassMembersInitializerFunction(function_kind()); } + void set_is_async_module() { + DCHECK(IsModule(function_kind_)); + function_kind_ = kAsyncModule; + } + void DeclareThis(AstValueFactory* ast_value_factory); void DeclareArguments(AstValueFactory* ast_value_factory); void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); @@ -1082,6 +1093,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { GetReceiverScope()->receiver()->ForceContextAllocation(); } + bool needs_private_name_context_chain_recalc() const { + return needs_private_name_context_chain_recalc_; + } + void RecordNeedsPrivateNameContextChainRecalc(); + private: V8_INLINE void AllocateParameter(Variable* var, int index); @@ -1099,6 +1115,12 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { void SetDefaults(); + // Recalculate the private name context chain from the existing skip bit in + // preparation for AllocateScopeInfos. Because the private name scope is + // implemented with a skip bit for scopes in heritage position, that bit may + // need to be recomputed due scopes that do not need contexts. + void RecalcPrivateNameContextChain(); + bool has_simple_parameters_ : 1; // This scope contains an "use asm" annotation. bool is_asm_module_ : 1; @@ -1120,9 +1142,10 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope { bool has_checked_syntax_ : 1; bool has_this_reference_ : 1; bool has_this_declaration_ : 1; + bool needs_private_name_context_chain_recalc_ : 1; // If the scope is a function scope, this is the function kind. - const FunctionKind function_kind_; + FunctionKind function_kind_; int num_parameters_ = 0; @@ -1220,17 +1243,26 @@ class ModuleScope final : public DeclarationScope { class V8_EXPORT_PRIVATE ClassScope : public Scope { public: - ClassScope(Zone* zone, Scope* outer_scope); + ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous); // Deserialization. - ClassScope(Zone* zone, AstValueFactory* ast_value_factory, + ClassScope(Isolate* isolate, Zone* zone, AstValueFactory* ast_value_factory, Handle<ScopeInfo> scope_info); + struct HeritageParsingScope { + explicit HeritageParsingScope(ClassScope* class_scope) + : class_scope_(class_scope) { + class_scope_->SetIsParsingHeritage(true); + } + ~HeritageParsingScope() { class_scope_->SetIsParsingHeritage(false); } + + private: + ClassScope* class_scope_; + }; + // Declare a private name in the private name map and add it to the // local variables of this scope. Variable* DeclarePrivateName(const AstRawString* name, VariableMode mode, - bool* was_added); - - void AddUnresolvedPrivateName(VariableProxy* proxy); + IsStaticFlag is_static_flag, bool* was_added); // Try resolving all unresolved private names found in the current scope. // Called from DeclarationScope::AllocateVariables() when reparsing a @@ -1261,13 +1293,53 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope { void MigrateUnresolvedPrivateNameTail(AstNodeFactory* ast_node_factory, UnresolvedList::Iterator tail); Variable* DeclareBrandVariable(AstValueFactory* ast_value_factory, + IsStaticFlag is_static_flag, int class_token_pos); + + Variable* DeclareClassVariable(AstValueFactory* ast_value_factory, + const AstRawString* name, int class_token_pos); + Variable* brand() { - return rare_data_ == nullptr ? nullptr : rare_data_->brand; + return GetRareData() == nullptr ? nullptr : GetRareData()->brand; + } + + Variable* class_variable() { return class_variable_; } + + V8_INLINE bool IsParsingHeritage() { + return rare_data_and_is_parsing_heritage_.GetPayload(); + } + + // Only maintained when the scope is parsed, not when the scope is + // deserialized. + bool has_static_private_methods() const { + return has_static_private_methods_; + } + + // Returns whether the index of class variable of this class scope should be + // recorded in the ScopeInfo. + // If any inner scope accesses static private names directly, the class + // variable will be forced to be context-allocated. + // The inner scope may also calls eval which may results in access to + // static private names. + // Only maintained when the scope is parsed. + bool should_save_class_variable_index() const { + return should_save_class_variable_index_ || + has_explicit_static_private_methods_access_ || + (has_static_private_methods_ && inner_scope_calls_eval_); + } + + // Only maintained when the scope is parsed. + bool is_anonymous_class() const { return is_anonymous_class_; } + + // Overriden during reparsing + void set_should_save_class_variable_index() { + should_save_class_variable_index_ = true; } private: friend class Scope; + friend class PrivateNameScopeIterator; + // Find the private name declared in the private name map first, // if it cannot be found there, try scope info if there is any. // Returns nullptr if it cannot be found. @@ -1285,14 +1357,53 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope { Variable* brand = nullptr; }; + V8_INLINE RareData* GetRareData() { + return rare_data_and_is_parsing_heritage_.GetPointer(); + } V8_INLINE RareData* EnsureRareData() { - if (rare_data_ == nullptr) { - rare_data_ = new (zone_) RareData(zone_); + if (GetRareData() == nullptr) { + rare_data_and_is_parsing_heritage_.SetPointer(new (zone_) + RareData(zone_)); } - return rare_data_; + return GetRareData(); + } + V8_INLINE void SetIsParsingHeritage(bool v) { + rare_data_and_is_parsing_heritage_.SetPayload(v); } - RareData* rare_data_ = nullptr; + PointerWithPayload<RareData, bool, 1> rare_data_and_is_parsing_heritage_; + Variable* class_variable_ = nullptr; + // These are only maintained when the scope is parsed, not when the + // scope is deserialized. + bool has_static_private_methods_ = false; + bool has_explicit_static_private_methods_access_ = false; + bool is_anonymous_class_ = false; + // This is only maintained during reparsing, restored from the + // preparsed data. + bool should_save_class_variable_index_ = false; +}; + +// Iterate over the private name scope chain. The iteration proceeds from the +// innermost private name scope outwards. +class PrivateNameScopeIterator { + public: + explicit PrivateNameScopeIterator(Scope* start); + + bool Done() const { return current_scope_ == nullptr; } + void Next(); + + // Add an unresolved private name to the current scope. + void AddUnresolvedPrivateName(VariableProxy* proxy); + + ClassScope* GetScope() const { + DCHECK(!Done()); + return current_scope_->AsClassScope(); + } + + private: + bool skipped_any_scopes_ = false; + Scope* start_scope_; + Scope* current_scope_; }; } // namespace internal diff --git a/deps/v8/src/ast/source-range-ast-visitor.cc b/deps/v8/src/ast/source-range-ast-visitor.cc index 2fcf151999ace0..74709916159a9c 100644 --- a/deps/v8/src/ast/source-range-ast-visitor.cc +++ b/deps/v8/src/ast/source-range-ast-visitor.cc @@ -39,6 +39,11 @@ void SourceRangeAstVisitor::VisitFunctionLiteral(FunctionLiteral* expr) { MaybeRemoveLastContinuationRange(stmts); } +void SourceRangeAstVisitor::VisitTryCatchStatement(TryCatchStatement* stmt) { + AstTraversalVisitor::VisitTryCatchStatement(stmt); + MaybeRemoveContinuationRangeOfAsyncReturn(stmt); +} + bool SourceRangeAstVisitor::VisitNode(AstNode* node) { AstNodeSourceRanges* range = source_range_map_->Find(node); @@ -59,11 +64,8 @@ bool SourceRangeAstVisitor::VisitNode(AstNode* node) { return true; } -void SourceRangeAstVisitor::MaybeRemoveLastContinuationRange( - ZonePtrList<Statement>* statements) { - if (statements->is_empty()) return; - - Statement* last_statement = statements->last(); +void SourceRangeAstVisitor::MaybeRemoveContinuationRange( + Statement* last_statement) { AstNodeSourceRanges* last_range = nullptr; if (last_statement->IsExpressionStatement() && @@ -83,5 +85,38 @@ void SourceRangeAstVisitor::MaybeRemoveLastContinuationRange( } } +void SourceRangeAstVisitor::MaybeRemoveLastContinuationRange( + ZonePtrList<Statement>* statements) { + if (statements->is_empty()) return; + MaybeRemoveContinuationRange(statements->last()); +} + +namespace { +Statement* FindLastNonSyntheticReturn(ZonePtrList<Statement>* statements) { + for (int i = statements->length() - 1; i >= 0; --i) { + Statement* stmt = statements->at(i); + if (!stmt->IsReturnStatement()) break; + if (stmt->AsReturnStatement()->is_synthetic_async_return()) continue; + return stmt; + } + return nullptr; +} +} // namespace + +void SourceRangeAstVisitor::MaybeRemoveContinuationRangeOfAsyncReturn( + TryCatchStatement* try_catch_stmt) { + // Detect try-catch inserted by NewTryCatchStatementForAsyncAwait in the + // parser (issued for async functions, including async generators), and + // remove the continuation ranges of return statements corresponding to + // returns at function end in the untransformed source. + if (try_catch_stmt->is_try_catch_for_async()) { + Statement* last_non_synthetic = + FindLastNonSyntheticReturn(try_catch_stmt->try_block()->statements()); + if (last_non_synthetic) { + MaybeRemoveContinuationRange(last_non_synthetic); + } + } +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/ast/source-range-ast-visitor.h b/deps/v8/src/ast/source-range-ast-visitor.h index 4ba5feb2d299f9..8b6b99c434634e 100644 --- a/deps/v8/src/ast/source-range-ast-visitor.h +++ b/deps/v8/src/ast/source-range-ast-visitor.h @@ -37,8 +37,11 @@ class SourceRangeAstVisitor final void VisitSwitchStatement(SwitchStatement* stmt); void VisitFunctionLiteral(FunctionLiteral* expr); bool VisitNode(AstNode* node); + void VisitTryCatchStatement(TryCatchStatement* stmt); + void MaybeRemoveContinuationRange(Statement* last_statement); void MaybeRemoveLastContinuationRange(ZonePtrList<Statement>* stmts); + void MaybeRemoveContinuationRangeOfAsyncReturn(TryCatchStatement* stmt); SourceRangeMap* source_range_map_ = nullptr; std::unordered_set<int> continuation_positions_; diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h index 1ff6f9f4228375..7be99adc7c12ff 100644 --- a/deps/v8/src/ast/variables.h +++ b/deps/v8/src/ast/variables.h @@ -21,7 +21,8 @@ class Variable final : public ZoneObject { public: Variable(Scope* scope, const AstRawString* name, VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, - MaybeAssignedFlag maybe_assigned_flag = kNotAssigned) + MaybeAssignedFlag maybe_assigned_flag = kNotAssigned, + IsStaticFlag is_static_flag = IsStaticFlag::kNotStatic) : scope_(scope), name_(name), local_if_not_shadowed_(nullptr), @@ -35,10 +36,13 @@ class Variable final : public ZoneObject { ForceContextAllocationField::encode(false) | ForceHoleInitializationField::encode(false) | LocationField::encode(VariableLocation::UNALLOCATED) | - VariableKindField::encode(kind)) { + VariableKindField::encode(kind) | + IsStaticFlagField::encode(is_static_flag)) { // Var declared variables never need initialization. DCHECK(!(mode == VariableMode::kVar && initialization_flag == kNeedsInitialization)); + DCHECK_IMPLIES(is_static_flag == IsStaticFlag::kStatic, + IsConstVariableMode(mode)); } explicit Variable(Variable* other); @@ -59,6 +63,14 @@ class Variable final : public ZoneObject { void set_mode(VariableMode mode) { bit_field_ = VariableModeField::update(bit_field_, mode); } + void set_is_static_flag(IsStaticFlag is_static_flag) { + bit_field_ = IsStaticFlagField::update(bit_field_, is_static_flag); + } + IsStaticFlag is_static_flag() const { + return IsStaticFlagField::decode(bit_field_); + } + bool is_static() const { return is_static_flag() == IsStaticFlag::kStatic; } + bool has_forced_context_allocation() const { return ForceContextAllocationField::decode(bit_field_); } @@ -72,6 +84,9 @@ class Variable final : public ZoneObject { MaybeAssignedFlag maybe_assigned() const { return MaybeAssignedFlagField::decode(bit_field_); } + void clear_maybe_assigned() { + bit_field_ = MaybeAssignedFlagField::update(bit_field_, kNotAssigned); + } void SetMaybeAssigned() { if (mode() == VariableMode::kConst) return; @@ -249,6 +264,7 @@ class Variable final : public ZoneObject { using ForceHoleInitializationField = InitializationFlagField::Next<bool, 1>; using MaybeAssignedFlagField = ForceHoleInitializationField::Next<MaybeAssignedFlag, 1>; + using IsStaticFlagField = MaybeAssignedFlagField::Next<IsStaticFlag, 1>; Variable** next() { return &next_; } friend List; diff --git a/deps/v8/src/base/OWNERS b/deps/v8/src/base/OWNERS index 9c6fd3c859ab75..3654b400adad26 100644 --- a/deps/v8/src/base/OWNERS +++ b/deps/v8/src/base/OWNERS @@ -1,4 +1,4 @@ -clemensh@chromium.org +clemensb@chromium.org mlippautz@chromium.org # COMPONENT: Blink>JavaScript diff --git a/deps/v8/src/base/adapters.h b/deps/v8/src/base/adapters.h deleted file mode 100644 index f684b52ccb6dc0..00000000000000 --- a/deps/v8/src/base/adapters.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Slightly adapted for inclusion in V8. -// Copyright 2014 the V8 project authors. All rights reserved. - -#ifndef V8_BASE_ADAPTERS_H_ -#define V8_BASE_ADAPTERS_H_ - -#include <iterator> - -#include "src/base/macros.h" - -namespace v8 { -namespace base { - -// Internal adapter class for implementing base::Reversed. -template <typename T> -class ReversedAdapter { - public: - using Iterator = - std::reverse_iterator<decltype(std::begin(std::declval<T>()))>; - - explicit ReversedAdapter(T& t) : t_(t) {} - ReversedAdapter(const ReversedAdapter& ra) V8_NOEXCEPT = default; - - // TODO(clemensh): Use std::rbegin/std::rend once we have C++14 support. - Iterator begin() const { return Iterator(std::end(t_)); } - Iterator end() const { return Iterator(std::begin(t_)); } - - private: - T& t_; - - DISALLOW_ASSIGN(ReversedAdapter); -}; - -// Reversed returns a container adapter usable in a range-based "for" statement -// for iterating a reversible container in reverse order. -// -// Example: -// -// std::vector<int> v = ...; -// for (int i : base::Reversed(v)) { -// // iterates through v from back to front -// } -template <typename T> -ReversedAdapter<T> Reversed(T&& t) { - return ReversedAdapter<T>(t); -} - -} // namespace base -} // namespace v8 - -#endif // V8_BASE_ADAPTERS_H_ diff --git a/deps/v8/src/base/cpu.cc b/deps/v8/src/base/cpu.cc index 6ab0ffee29ee5a..4f4ac2b3282933 100644 --- a/deps/v8/src/base/cpu.cc +++ b/deps/v8/src/base/cpu.cc @@ -9,6 +9,7 @@ #endif #if V8_OS_LINUX #include <linux/auxvec.h> // AT_HWCAP +extern "C" char** environ; #endif #if V8_GLIBC_PREREQ(2, 16) #include <sys/auxv.h> // getauxval() @@ -16,7 +17,7 @@ #if V8_OS_QNX #include <sys/syspage.h> // cpuinfo #endif -#if V8_OS_LINUX && V8_HOST_ARCH_PPC +#if (V8_OS_LINUX && V8_HOST_ARCH_PPC) || V8_OS_ANDROID #include <elf.h> #endif #if V8_OS_AIX @@ -109,28 +110,25 @@ static V8_INLINE void __cpuid(int cpu_info[4], int info_type) { #define HWCAP_LPAE (1 << 20) static uint32_t ReadELFHWCaps() { - uint32_t result = 0; #if V8_GLIBC_PREREQ(2, 16) - result = static_cast<uint32_t>(getauxval(AT_HWCAP)); + return static_cast<uint32_t>(getauxval(AT_HWCAP)); #else - // Read the ELF HWCAP flags by parsing /proc/self/auxv. - FILE* fp = fopen("/proc/self/auxv", "r"); - if (fp != nullptr) { - struct { uint32_t tag; uint32_t value; } entry; - for (;;) { - size_t n = fread(&entry, sizeof(entry), 1, fp); - if (n == 0 || (entry.tag == 0 && entry.value == 0)) { - break; - } - if (entry.tag == AT_HWCAP) { - result = entry.value; - break; - } + char** head = environ; + while (*head++ != nullptr) { + } +#ifdef __LP64__ + using elf_auxv_t = Elf64_auxv_t; +#else + using elf_auxv_t = Elf32_auxv_t; +#endif + for (elf_auxv_t* entry = reinterpret_cast<elf_auxv_t*>(head); + entry->a_type != AT_NULL; ++entry) { + if (entry->a_type == AT_HWCAP) { + return entry->a_un.a_val; } - fclose(fp); } + return 0u; #endif - return result; } #endif // V8_HOST_ARCH_ARM @@ -608,33 +606,28 @@ CPU::CPU() #ifndef USE_SIMULATOR #if V8_OS_LINUX - // Read processor info from /proc/self/auxv. char* auxv_cpu_type = nullptr; - FILE* fp = fopen("/proc/self/auxv", "r"); - if (fp != nullptr) { + char** head = environ; + while (*head++ != nullptr) { + } #if V8_TARGET_ARCH_PPC64 - Elf64_auxv_t entry; + using elf_auxv_t = Elf64_auxv_t; #else - Elf32_auxv_t entry; + using elf_auxv_t = Elf32_auxv_t; #endif - for (;;) { - size_t n = fread(&entry, sizeof(entry), 1, fp); - if (n == 0 || entry.a_type == AT_NULL) { + for (elf_auxv_t* entry = reinterpret_cast<elf_auxv_t*>(head); + entry->a_type != AT_NULL; ++entry) { + switch (entry->a_type) { + case AT_PLATFORM: + auxv_cpu_type = reinterpret_cast<char*>(entry->a_un.a_val); + break; + case AT_ICACHEBSIZE: + icache_line_size_ = entry->a_un.a_val; + break; + case AT_DCACHEBSIZE: + dcache_line_size_ = entry->a_un.a_val; break; - } - switch (entry.a_type) { - case AT_PLATFORM: - auxv_cpu_type = reinterpret_cast<char*>(entry.a_un.a_val); - break; - case AT_ICACHEBSIZE: - icache_line_size_ = entry.a_un.a_val; - break; - case AT_DCACHEBSIZE: - dcache_line_size_ = entry.a_un.a_val; - break; - } } - fclose(fp); } part_ = -1; diff --git a/deps/v8/src/base/file-utils.cc b/deps/v8/src/base/file-utils.cc index 31b1b411908dc9..6e1c4921440f3c 100644 --- a/deps/v8/src/base/file-utils.cc +++ b/deps/v8/src/base/file-utils.cc @@ -12,24 +12,18 @@ namespace v8 { namespace base { -char* RelativePath(char** buffer, const char* exec_path, const char* name) { +std::unique_ptr<char[]> RelativePath(const char* exec_path, const char* name) { DCHECK(exec_path); - int path_separator = static_cast<int>(strlen(exec_path)) - 1; - while (path_separator >= 0 && - !OS::isDirectorySeparator(exec_path[path_separator])) { - path_separator--; + size_t basename_start = strlen(exec_path); + while (basename_start > 0 && + !OS::isDirectorySeparator(exec_path[basename_start - 1])) { + --basename_start; } - if (path_separator >= 0) { - int name_length = static_cast<int>(strlen(name)); - *buffer = - reinterpret_cast<char*>(calloc(path_separator + name_length + 2, 1)); - *buffer[0] = '\0'; - strncat(*buffer, exec_path, path_separator + 1); - strncat(*buffer, name, name_length); - } else { - *buffer = strdup(name); - } - return *buffer; + size_t name_length = strlen(name); + auto buffer = std::make_unique<char[]>(basename_start + name_length + 1); + if (basename_start > 0) memcpy(buffer.get(), exec_path, basename_start); + memcpy(buffer.get() + basename_start, name, name_length); + return buffer; } } // namespace base diff --git a/deps/v8/src/base/file-utils.h b/deps/v8/src/base/file-utils.h index afd9a1fc253103..84b57fb40b34c6 100644 --- a/deps/v8/src/base/file-utils.h +++ b/deps/v8/src/base/file-utils.h @@ -5,6 +5,8 @@ #ifndef V8_BASE_FILE_UTILS_H_ #define V8_BASE_FILE_UTILS_H_ +#include <memory> + #include "src/base/base-export.h" namespace v8 { @@ -12,8 +14,8 @@ namespace base { // Helper functions to manipulate file paths. -V8_BASE_EXPORT char* RelativePath(char** buffer, const char* exec_path, - const char* name); +V8_BASE_EXPORT +std::unique_ptr<char[]> RelativePath(const char* exec_path, const char* name); } // namespace base } // namespace v8 diff --git a/deps/v8/src/base/free_deleter.h b/deps/v8/src/base/free_deleter.h index 77e4f0ed14a760..a556926685949d 100644 --- a/deps/v8/src/base/free_deleter.h +++ b/deps/v8/src/base/free_deleter.h @@ -9,6 +9,7 @@ #define V8_BASE_FREE_DELETER_H_ #include <stdlib.h> +#include <memory> namespace v8 { namespace base { diff --git a/deps/v8/src/base/iterator.h b/deps/v8/src/base/iterator.h index b081af62aeac55..baaf324e2185b5 100644 --- a/deps/v8/src/base/iterator.h +++ b/deps/v8/src/base/iterator.h @@ -59,6 +59,26 @@ class iterator_range { const_iterator const end_; }; +template <typename ForwardIterator> +auto make_iterator_range(ForwardIterator&& begin, ForwardIterator&& end) { + return iterator_range<ForwardIterator>{std::forward<ForwardIterator>(begin), + std::forward<ForwardIterator>(end)}; +} + +// {Reversed} returns a container adapter usable in a range-based "for" +// statement for iterating a reversible container in reverse order. +// +// Example: +// +// std::vector<int> v = ...; +// for (int i : base::Reversed(v)) { +// // iterates through v from back to front +// } +template <typename T> +auto Reversed(T& t) { // NOLINT(runtime/references): match {rbegin} and {rend} + return make_iterator_range(std::rbegin(t), std::rend(t)); +} + } // namespace base } // namespace v8 diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h index ad70e9820ddb4a..5f52a9893e6a56 100644 --- a/deps/v8/src/base/macros.h +++ b/deps/v8/src/base/macros.h @@ -6,6 +6,7 @@ #define V8_BASE_MACROS_H_ #include <limits> +#include <type_traits> #include "src/base/compiler-specific.h" #include "src/base/logging.h" @@ -232,35 +233,16 @@ struct is_trivially_copyable { // the standard does not, so let's skip this check.) // Trivial non-deleted destructor. std::is_trivially_destructible<T>::value; - -#elif defined(__GNUC__) && __GNUC__ < 5 - // WARNING: - // On older libstdc++ versions, there is no way to correctly implement - // is_trivially_copyable. The workaround below is an approximation (neither - // over- nor underapproximation). E.g. it wrongly returns true if the move - // constructor is non-trivial, and it wrongly returns false if the copy - // constructor is deleted, but copy assignment is trivial. - // TODO(rongjie) Remove this workaround once we require gcc >= 5.0 - static constexpr bool value = - __has_trivial_copy(T) && __has_trivial_destructor(T); - #else static constexpr bool value = std::is_trivially_copyable<T>::value; #endif }; -#if defined(__GNUC__) && __GNUC__ < 5 -// On older libstdc++ versions, base::is_trivially_copyable<T>::value is only an -// approximation (see above), so make ASSERT_{NOT_,}TRIVIALLY_COPYABLE a noop. -#define ASSERT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled") -#define ASSERT_NOT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled") -#else #define ASSERT_TRIVIALLY_COPYABLE(T) \ static_assert(::v8::base::is_trivially_copyable<T>::value, \ #T " should be trivially copyable") #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) \ static_assert(!::v8::base::is_trivially_copyable<T>::value, \ #T " should not be trivially copyable") -#endif // The USE(x, ...) template is used to silence C++ compiler warnings // issued for (yet) unused variables (typically parameters). @@ -407,6 +389,9 @@ bool is_inbounds(float_t v) { constexpr bool kUpperBoundIsMax = static_cast<biggest_int_t>(kUpperBound) == static_cast<biggest_int_t>(std::numeric_limits<int_t>::max()); + // Using USE(var) is only a workaround for a GCC 8.1 bug. + USE(kLowerBoundIsMin); + USE(kUpperBoundIsMax); return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) && (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound)); } diff --git a/deps/v8/src/base/optional.h b/deps/v8/src/base/optional.h index b8df88d8442cab..6610c7ffc33623 100644 --- a/deps/v8/src/base/optional.h +++ b/deps/v8/src/base/optional.h @@ -131,21 +131,8 @@ struct OptionalStorageBase<T, true /* trivially destructible */> { // the condition of constexpr-ness is satisfied because the base class also has // compiler generated constexpr {copy,move} constructors). Note that // placement-new is prohibited in constexpr. -#if defined(__GNUC__) && __GNUC__ < 5 -// gcc <5 does not implement std::is_trivially_copy_constructible. -// Conservatively assume false for this configuration. -// TODO(clemensh): Remove this once we drop support for gcc <5. -#define TRIVIALLY_COPY_CONSTRUCTIBLE(T) false -#define TRIVIALLY_MOVE_CONSTRUCTIBLE(T) false -#else -#define TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - std::is_trivially_copy_constructible<T>::value -#define TRIVIALLY_MOVE_CONSTRUCTIBLE(T) \ - std::is_trivially_move_constructible<T>::value -#endif -template <typename T, bool = TRIVIALLY_COPY_CONSTRUCTIBLE(T), - bool = TRIVIALLY_MOVE_CONSTRUCTIBLE(T)> -#undef TRIVIALLY_COPY_CONSTRUCTIBLE +template <typename T, bool = std::is_trivially_copy_constructible<T>::value, + bool = std::is_trivially_move_constructible<T>::value> struct OptionalStorage : OptionalStorageBase<T> { // This is no trivially {copy,move} constructible case. Other cases are // defined below as specializations. diff --git a/deps/v8/src/base/platform/mutex.h b/deps/v8/src/base/platform/mutex.h index c48cf8d3393c12..5b3b31ec1e5246 100644 --- a/deps/v8/src/base/platform/mutex.h +++ b/deps/v8/src/base/platform/mutex.h @@ -290,6 +290,7 @@ class LockGuard final { }; using MutexGuard = LockGuard<Mutex>; +using RecursiveMutexGuard = LockGuard<RecursiveMutex>; enum MutexSharedType : bool { kShared = true, kExclusive = false }; diff --git a/deps/v8/src/base/platform/platform-openbsd.cc b/deps/v8/src/base/platform/platform-openbsd.cc index c133ffb68d7da6..e4a3cb6f35f0ae 100644 --- a/deps/v8/src/base/platform/platform-openbsd.cc +++ b/deps/v8/src/base/platform/platform-openbsd.cc @@ -107,7 +107,7 @@ void OS::SignalCodeMovingGC() { // it. This injects a GC marker into the stream of events generated // by the kernel and allows us to synchronize V8 code log and the // kernel log. - int size = sysconf(_SC_PAGESIZE); + long size = sysconf(_SC_PAGESIZE); // NOLINT: type more fit than uint64_t FILE* f = fopen(OS::GetGCFakeMMapFile(), "w+"); if (f == nullptr) { OS::PrintError("Failed to open %s\n", OS::GetGCFakeMMapFile()); @@ -116,7 +116,7 @@ void OS::SignalCodeMovingGC() { void* addr = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fileno(f), 0); DCHECK(addr != MAP_FAILED); - OS::Free(addr, size); + CHECK(OS::Free(addr, size)); fclose(f); } diff --git a/deps/v8/src/base/platform/platform-posix.cc b/deps/v8/src/base/platform/platform-posix.cc index c50cdd7a98eefd..99abcd55686c16 100644 --- a/deps/v8/src/base/platform/platform-posix.cc +++ b/deps/v8/src/base/platform/platform-posix.cc @@ -48,6 +48,7 @@ #if V8_OS_MACOSX #include <dlfcn.h> +#include <mach/mach.h> #endif #if V8_OS_LINUX diff --git a/deps/v8/src/base/platform/semaphore.cc b/deps/v8/src/base/platform/semaphore.cc index a7e50f5880467b..66464d8258dc9b 100644 --- a/deps/v8/src/base/platform/semaphore.cc +++ b/deps/v8/src/base/platform/semaphore.cc @@ -5,8 +5,7 @@ #include "src/base/platform/semaphore.h" #if V8_OS_MACOSX -#include <mach/mach_init.h> -#include <mach/task.h> +#include <dispatch/dispatch.h> #endif #include <errno.h> @@ -21,53 +20,23 @@ namespace base { #if V8_OS_MACOSX Semaphore::Semaphore(int count) { - kern_return_t result = semaphore_create( - mach_task_self(), &native_handle_, SYNC_POLICY_FIFO, count); - DCHECK_EQ(KERN_SUCCESS, result); - USE(result); + native_handle_ = dispatch_semaphore_create(count); + DCHECK(native_handle_); } +Semaphore::~Semaphore() { dispatch_release(native_handle_); } -Semaphore::~Semaphore() { - kern_return_t result = semaphore_destroy(mach_task_self(), native_handle_); - DCHECK_EQ(KERN_SUCCESS, result); - USE(result); -} - -void Semaphore::Signal() { - kern_return_t result = semaphore_signal(native_handle_); - DCHECK_EQ(KERN_SUCCESS, result); - USE(result); -} - +void Semaphore::Signal() { dispatch_semaphore_signal(native_handle_); } void Semaphore::Wait() { - while (true) { - kern_return_t result = semaphore_wait(native_handle_); - if (result == KERN_SUCCESS) return; // Semaphore was signalled. - DCHECK_EQ(KERN_ABORTED, result); - } + dispatch_semaphore_wait(native_handle_, DISPATCH_TIME_FOREVER); } bool Semaphore::WaitFor(const TimeDelta& rel_time) { - TimeTicks now = TimeTicks::Now(); - TimeTicks end = now + rel_time; - while (true) { - mach_timespec_t ts; - if (now >= end) { - // Return immediately if semaphore was not signalled. - ts.tv_sec = 0; - ts.tv_nsec = 0; - } else { - ts = (end - now).ToMachTimespec(); - } - kern_return_t result = semaphore_timedwait(native_handle_, ts); - if (result == KERN_SUCCESS) return true; // Semaphore was signalled. - if (result == KERN_OPERATION_TIMED_OUT) return false; // Timeout. - DCHECK_EQ(KERN_ABORTED, result); - now = TimeTicks::Now(); - } + dispatch_time_t timeout = + dispatch_time(DISPATCH_TIME_NOW, rel_time.InNanoseconds()); + return dispatch_semaphore_wait(native_handle_, timeout) == 0; } #elif V8_OS_POSIX diff --git a/deps/v8/src/base/platform/semaphore.h b/deps/v8/src/base/platform/semaphore.h index 11ff0b9199f845..c4937acadd19a7 100644 --- a/deps/v8/src/base/platform/semaphore.h +++ b/deps/v8/src/base/platform/semaphore.h @@ -12,7 +12,7 @@ #endif #if V8_OS_MACOSX -#include <mach/semaphore.h> // NOLINT +#include <dispatch/dispatch.h> // NOLINT #elif V8_OS_POSIX #include <semaphore.h> // NOLINT #endif @@ -50,7 +50,7 @@ class V8_BASE_EXPORT Semaphore final { bool WaitFor(const TimeDelta& rel_time) V8_WARN_UNUSED_RESULT; #if V8_OS_MACOSX - using NativeHandle = semaphore_t; + using NativeHandle = dispatch_semaphore_t; #elif V8_OS_POSIX using NativeHandle = sem_t; #elif V8_OS_WIN diff --git a/deps/v8/src/base/template-utils.h b/deps/v8/src/base/template-utils.h index 530114a8e2faa5..146f8d6e6ae4a7 100644 --- a/deps/v8/src/base/template-utils.h +++ b/deps/v8/src/base/template-utils.h @@ -6,32 +6,20 @@ #define V8_BASE_TEMPLATE_UTILS_H_ #include <array> -#include <memory> +#include <type_traits> +#include <utility> namespace v8 { namespace base { namespace detail { -// make_array_helper statically iteratively creates the index list 0 .. Size-1. -// A specialization for the base case (first index is 0) finally constructs the -// array. -// TODO(clemensh): Use std::index_sequence once we have C++14 support. -template <class Function, std::size_t... Indexes> -struct make_array_helper; - -template <class Function, std::size_t... Indexes> -struct make_array_helper<Function, 0, Indexes...> { - constexpr static std::array<typename std::result_of<Function(size_t)>::type, - sizeof...(Indexes) + 1> - make_array(Function f) { - return {{f(0), f(Indexes)...}}; - } -}; - -template <class Function, std::size_t FirstIndex, std::size_t... Indexes> -struct make_array_helper<Function, FirstIndex, Indexes...> - : make_array_helper<Function, FirstIndex - 1, FirstIndex, Indexes...> {}; +template <typename Function, std::size_t... Indexes> +constexpr inline auto make_array_helper(Function f, + std::index_sequence<Indexes...>) + -> std::array<decltype(f(0)), sizeof...(Indexes)> { + return {{f(Indexes)...}}; +} } // namespace detail @@ -42,18 +30,8 @@ struct make_array_helper<Function, FirstIndex, Indexes...> // [](std::size_t i) { return static_cast<int>(2 * i); }); // The resulting array will be constexpr if the passed function is constexpr. template <std::size_t Size, class Function> -constexpr std::array<typename std::result_of<Function(size_t)>::type, Size> -make_array(Function f) { - static_assert(Size > 0, "Can only create non-empty arrays"); - return detail::make_array_helper<Function, Size - 1>::make_array(f); -} - -// base::make_unique<T>: Construct an object of type T and wrap it in a -// std::unique_ptr. -// Replacement for C++14's std::make_unique. -template <typename T, typename... Args> -std::unique_ptr<T> make_unique(Args&&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); +constexpr auto make_array(Function f) { + return detail::make_array_helper(f, std::make_index_sequence<Size>{}); } // Helper to determine how to pass values: Pass scalars and arrays by value, @@ -80,38 +58,17 @@ struct has_output_operator<T, decltype(void(std::declval<std::ostream&>() << std::declval<T>()))> : std::true_type {}; -namespace detail { - -template <typename Func, typename T, typename... Ts> -struct fold_helper { - static_assert(sizeof...(Ts) == 0, "this is the base case"); - using result_t = typename std::remove_reference<T>::type; - static constexpr T&& fold(Func func, T&& first) { - return std::forward<T>(first); - } -}; +// Fold all arguments from left to right with a given function. +template <typename Func, typename T> +constexpr auto fold(Func func, T&& t) { + return std::forward<T>(t); +} template <typename Func, typename T1, typename T2, typename... Ts> -struct fold_helper<Func, T1, T2, Ts...> { - using folded_t = typename std::result_of<Func(T1, T2)>::type; - using next_fold_helper = fold_helper<Func, folded_t&&, Ts...>; - using result_t = typename next_fold_helper::result_t; - static constexpr result_t fold(Func func, T1&& first, T2&& second, - Ts&&... more) { - return next_fold_helper::fold( - func, func(std::forward<T1>(first), std::forward<T2>(second)), - std::forward<Ts>(more)...); - } -}; - -} // namespace detail - -// Fold all arguments from left to right with a given function. -template <typename Func, typename... Ts> -constexpr auto fold(Func func, Ts&&... more) -> - typename detail::fold_helper<Func, Ts...>::result_t { - return detail::fold_helper<Func, Ts...>::fold(func, - std::forward<Ts>(more)...); +constexpr auto fold(Func func, T1&& first, T2&& second, Ts&&... more) { + auto&& folded = func(std::forward<T1>(first), std::forward<T2>(second)); + return fold(std::move(func), std::forward<decltype(folded)>(folded), + std::forward<Ts>(more)...); } // {is_same<Ts...>::value} is true if all Ts are the same, false otherwise. diff --git a/deps/v8/src/base/ubsan.cc b/deps/v8/src/base/ubsan.cc new file mode 100644 index 00000000000000..fc77156eb1cf6c --- /dev/null +++ b/deps/v8/src/base/ubsan.cc @@ -0,0 +1,50 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdint.h> +#include <limits> + +#include "src/base/build_config.h" + +#if !defined(UNDEFINED_SANITIZER) || !defined(V8_TARGET_ARCH_32_BIT) +#error "This file is only needed for 32-bit UBSan builds." +#endif + +// Compiling with -fsanitize=undefined on 32-bit platforms requires __mulodi4 +// to be available. Usually it comes from libcompiler_rt, which our build +// doesn't provide, so here is a custom implementation (inspired by digit_mul +// in src/objects/bigint.cc). +extern "C" int64_t __mulodi4(int64_t a, int64_t b, int* overflow) { + // Multiply in 32-bit chunks. + // For inputs [AH AL]*[BH BL], the result is: + // + // [AL*BL] // r_low + // + [AL*BH] // r_mid1 + // + [AH*BL] // r_mid2 + // + [AH*BH] // r_high + // = [R4 R3 R2 R1] // high = [R4 R3], low = [R2 R1] + // + // Where of course we must be careful with carries between the columns. + uint64_t a_low = a & 0xFFFFFFFFu; + uint64_t a_high = static_cast<uint64_t>(a) >> 32; + uint64_t b_low = b & 0xFFFFFFFFu; + uint64_t b_high = static_cast<uint64_t>(b) >> 32; + + uint64_t r_low = a_low * b_low; + uint64_t r_mid1 = a_low * b_high; + uint64_t r_mid2 = a_high * b_low; + uint64_t r_high = a_high * b_high; + + uint64_t result1 = r_low + (r_mid1 << 32); + if (result1 < r_low) r_high++; + uint64_t result2 = result1 + (r_mid2 << 32); + if (result2 < result1) r_high++; + r_high += (r_mid1 >> 32) + (r_mid2 >> 32); + int64_t result = static_cast<int64_t>(result2); + uint64_t result_sign = (result >> 63); + uint64_t expected_result_sign = (a >> 63) ^ (b >> 63); + + *overflow = (r_high > 0 || result_sign != expected_result_sign) ? 1 : 0; + return result; +} diff --git a/deps/v8/src/builtins/accessors.cc b/deps/v8/src/builtins/accessors.cc index ea6308622da13b..fa39142cb4cb3c 100644 --- a/deps/v8/src/builtins/accessors.cc +++ b/deps/v8/src/builtins/accessors.cc @@ -16,6 +16,7 @@ #include "src/objects/contexts.h" #include "src/objects/field-index-inl.h" #include "src/objects/js-array-inl.h" +#include "src/objects/js-regexp-inl.h" #include "src/objects/module-inl.h" #include "src/objects/property-details.h" #include "src/objects/prototype.h" @@ -840,5 +841,25 @@ Handle<AccessorInfo> Accessors::MakeErrorStackInfo(Isolate* isolate) { &ErrorStackGetter, &ErrorStackSetter); } +// +// Accessors::RegExpResultIndices +// + +void Accessors::RegExpResultIndicesGetter( + v8::Local<v8::Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); + HandleScope scope(isolate); + Handle<JSRegExpResult> regexp_result( + Handle<JSRegExpResult>::cast(Utils::OpenHandle(*info.Holder()))); + Handle<Object> indices( + JSRegExpResult::GetAndCacheIndices(isolate, regexp_result)); + info.GetReturnValue().Set(Utils::ToLocal(indices)); +} + +Handle<AccessorInfo> Accessors::MakeRegExpResultIndicesInfo(Isolate* isolate) { + return MakeAccessor(isolate, isolate->factory()->indices_string(), + &RegExpResultIndicesGetter, nullptr); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/accessors.h b/deps/v8/src/builtins/accessors.h index 43a65342966e28..b6a8e65446f963 100644 --- a/deps/v8/src/builtins/accessors.h +++ b/deps/v8/src/builtins/accessors.h @@ -43,6 +43,8 @@ class JavaScriptFrame; kHasSideEffectToReceiver) \ V(_, function_prototype, FunctionPrototype, kHasNoSideEffect, \ kHasSideEffectToReceiver) \ + V(_, regexp_result_indices, RegExpResultIndices, kHasSideEffectToReceiver, \ + kHasSideEffectToReceiver) \ V(_, string_length, StringLength, kHasNoSideEffect, kHasSideEffectToReceiver) #define ACCESSOR_SETTER_LIST(V) \ diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc index e9b562620fcee5..164c09db259013 100644 --- a/deps/v8/src/builtins/arm/builtins-arm.cc +++ b/deps/v8/src/builtins/arm/builtins-arm.cc @@ -885,102 +885,70 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register feedback_vector, - Register scratch1, - Register scratch2) { +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry, + Register scratch) { // ----------- S t a t e ------------- // -- r3 : new target (preserved for callee if needed, and caller) // -- r1 : target function (preserved for callee if needed, and caller) - // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK(!AreAliased(feedback_vector, r1, r3, scratch1, scratch2)); - - Label optimized_code_slot_is_weak_ref, fallthrough; + DCHECK(!AreAliased(r1, r3, optimized_code_entry, scratch)); Register closure = r1; - Register optimized_code_entry = scratch1; - - __ ldr( - optimized_code_entry, - FieldMemOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret it as a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); - - { - // Optimized code slot is a Smi optimization marker. - - // Fall through if no optimization trigger. - __ cmp(optimized_code_entry, - Operand(Smi::FromEnum(OptimizationMarker::kNone))); - __ b(eq, &fallthrough); - - // TODO(v8:8394): The logging of first execution will break if - // feedback vectors are not allocated. We need to find a different way of - // logging these events if required. - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); + // Check if the optimized code is marked for deopt. If it is, call the + // runtime to clear it. + Label found_deoptimized_code; + __ ldr(scratch, + FieldMemOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); + __ ldr(scratch, + FieldMemOperand(scratch, CodeDataContainer::kKindSpecificFlagsOffset)); + __ tst(scratch, Operand(1 << Code::kMarkedForDeoptimizationBit)); + __ b(ne, &found_deoptimized_code); - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ cmp( - optimized_code_entry, - Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); - __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); - } - __ jmp(&fallthrough); - } - } + // Optimized code is good, get it into the closure and link the closure + // into the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure); + static_assert(kJavaScriptCallCodeStartRegister == r2, "ABI mismatch"); + __ LoadCodeObjectEntry(r2, optimized_code_entry); + __ Jump(r2); - { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, optimized_code_entry, &fallthrough); - - // Check if the optimized code is marked for deopt. If it is, call the - // runtime to clear it. - Label found_deoptimized_code; - __ ldr(scratch2, FieldMemOperand(optimized_code_entry, - Code::kCodeDataContainerOffset)); - __ ldr( - scratch2, - FieldMemOperand(scratch2, CodeDataContainer::kKindSpecificFlagsOffset)); - __ tst(scratch2, Operand(1 << Code::kMarkedForDeoptimizationBit)); - __ b(ne, &found_deoptimized_code); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - // The feedback vector is no longer used, so re-use it as a scratch - // register. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure); - static_assert(kJavaScriptCallCodeStartRegister == r2, "ABI mismatch"); - __ LoadCodeObjectEntry(r2, optimized_code_entry); - __ Jump(r2); + // Optimized code slot contains deoptimized code, evict it and re-enter + // the closure's code. + __ bind(&found_deoptimized_code); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +} - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, + Register optimization_marker) { + // ----------- S t a t e ------------- + // -- r3 : new target (preserved for callee if needed, and caller) + // -- r1 : target function (preserved for callee if needed, and caller) + // -- feedback vector (preserved for caller if needed) + // -- optimization_marker : a Smi containing a non-zero optimization marker. + // ----------------------------------- + DCHECK(!AreAliased(feedback_vector, r1, r3, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); + + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ cmp(optimization_marker, + Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); + __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); } - - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); } // Advance the current bytecode offset. This simulates what all bytecode @@ -999,7 +967,7 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, ExternalReference::bytecode_size_table_address()); // Check if the bytecode is a Wide or ExtraWide prefix bytecode. - Label process_bytecode, extra_wide; + Label process_bytecode; STATIC_ASSERT(0 == static_cast<int>(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast<int>(interpreter::Bytecode::kExtraWide)); STATIC_ASSERT(2 == static_cast<int>(interpreter::Bytecode::kDebugBreakWide)); @@ -1008,31 +976,34 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, __ cmp(bytecode, Operand(0x3)); __ b(hi, &process_bytecode); __ tst(bytecode, Operand(0x1)); - __ b(ne, &extra_wide); - - // Load the next bytecode and update table to the wide scaled table. + // Load the next bytecode. __ add(bytecode_offset, bytecode_offset, Operand(1)); __ ldrb(bytecode, MemOperand(bytecode_array, bytecode_offset)); + + // Update table to the wide scaled table. __ add(bytecode_size_table, bytecode_size_table, Operand(kIntSize * interpreter::Bytecodes::kBytecodeCount)); - __ jmp(&process_bytecode); - - __ bind(&extra_wide); - // Load the next bytecode and update table to the extra wide scaled table. - __ add(bytecode_offset, bytecode_offset, Operand(1)); - __ ldrb(bytecode, MemOperand(bytecode_array, bytecode_offset)); + // Conditionally update table to the extra wide scaled table. We are taking + // advantage of the fact that the extra wide follows the wide one. __ add(bytecode_size_table, bytecode_size_table, - Operand(2 * kIntSize * interpreter::Bytecodes::kBytecodeCount)); + Operand(kIntSize * interpreter::Bytecodes::kBytecodeCount), LeaveCC, + ne); __ bind(&process_bytecode); // Bailout to the return label if this is a return bytecode. -#define JUMP_IF_EQUAL(NAME) \ - __ cmp(bytecode, Operand(static_cast<int>(interpreter::Bytecode::k##NAME))); \ - __ b(if_return, eq); + + // Create cmp, cmpne, ..., cmpne to check for a return bytecode. + Condition flag = al; +#define JUMP_IF_EQUAL(NAME) \ + __ cmp(bytecode, Operand(static_cast<int>(interpreter::Bytecode::k##NAME)), \ + flag); \ + flag = ne; RETURN_BYTECODE_LIST(JUMP_IF_EQUAL) #undef JUMP_IF_EQUAL + __ b(if_return, eq); + // Otherwise, load the size of the current bytecode and advance the offset. __ ldr(scratch1, MemOperand(bytecode_size_table, bytecode, LSL, 2)); __ add(bytecode_offset, bytecode_offset, scratch1); @@ -1084,9 +1055,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ cmp(r4, Operand(FEEDBACK_VECTOR_TYPE)); __ b(ne, &push_stack_frame); - // Read off the optimized code slot in the feedback vector, and if there - // is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r4, r6); + Register optimized_code_entry = r4; + + // Read off the optimized code slot in the feedback vector. + __ ldr(optimized_code_entry, + FieldMemOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); + + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ cmp(optimized_code_entry, + Operand(Smi::FromEnum(OptimizationMarker::kNone))); + __ b(ne, &optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Increment invocation count for the function. __ ldr(r9, FieldMemOperand(feedback_vector, @@ -1121,28 +1104,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, r0); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size from the BytecodeArray object. __ ldr(r4, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ sub(r9, sp, Operand(r4)); LoadRealStackLimit(masm, r2); __ cmp(r9, Operand(r2)); - __ b(hs, &ok); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ b(lo, &stack_overflow); // If ok, push undefined as the initial value for all register file entries. Label loop_header; Label loop_check; - __ LoadRoot(r9, RootIndex::kUndefinedValue); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ b(&loop_check, al); __ bind(&loop_header); // TODO(rmcilroy): Consider doing more than one push per loop iteration. - __ push(r9); + __ push(kInterpreterAccumulatorRegister); // Continue loop if not done. __ bind(&loop_check); __ sub(r4, r4, Operand(kPointerSize), SetCC); @@ -1157,8 +1138,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ cmp(r9, Operand::Zero()); __ str(r3, MemOperand(fp, r9, LSL, kPointerSizeLog2), ne); - // Load accumulator with undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. @@ -1199,8 +1179,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LeaveInterpreterFrame(masm, r2); __ Jump(lr); + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry, r6); + __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); __ bkpt(0); // Should not return. } @@ -1565,14 +1563,8 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ ldr(r0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ ldr(r0, MemOperand(r0, JavaScriptFrameConstants::kFunctionOffset)); - { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(r0); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -2182,7 +2174,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- r1 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(r1, &non_callable); __ bind(&non_smi); __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE); @@ -2199,12 +2191,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // Check if target is a proxy and call CallProxy external builtin __ cmp(r5, Operand(JS_PROXY_TYPE)); - __ b(ne, &non_function); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ bind(&non_function); // Overwrite the original receiver the (original) target. __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); // Let the "call_as_function_delegate" take care of the rest. @@ -3167,51 +3157,6 @@ void Builtins::Generate_MemCopyUint8Uint8(MacroAssembler* masm) { __ Ret(); } -void Builtins::Generate_MemCopyUint16Uint8(MacroAssembler* masm) { - Register dest = r0; - Register src = r1; - Register chars = r2; - - { - UseScratchRegisterScope temps(masm); - - Register temp1 = r3; - Register temp2 = temps.Acquire(); - Register temp3 = lr; - Register temp4 = r4; - Label loop; - Label not_two; - - __ Push(lr, r4); - __ bic(temp2, chars, Operand(0x3)); - __ add(temp2, dest, Operand(temp2, LSL, 1)); - - __ bind(&loop); - __ ldr(temp1, MemOperand(src, 4, PostIndex)); - __ uxtb16(temp3, temp1); - __ uxtb16(temp4, temp1, 8); - __ pkhbt(temp1, temp3, Operand(temp4, LSL, 16)); - __ str(temp1, MemOperand(dest)); - __ pkhtb(temp1, temp4, Operand(temp3, ASR, 16)); - __ str(temp1, MemOperand(dest, 4)); - __ add(dest, dest, Operand(8)); - __ cmp(dest, temp2); - __ b(&loop, ne); - - __ mov(chars, Operand(chars, LSL, 31), SetCC); // bit0 => ne, bit1 => cs - __ b(¬_two, cc); - __ ldrh(temp1, MemOperand(src, 2, PostIndex)); - __ uxtb(temp3, temp1, 8); - __ mov(temp3, Operand(temp3, LSL, 16)); - __ uxtab(temp3, temp3, temp1); - __ str(temp3, MemOperand(dest, 4, PostIndex)); - __ bind(¬_two); - __ ldrb(temp1, MemOperand(src), ne); - __ strh(temp1, MemOperand(dest), ne); - __ Pop(pc, r4); - } -} - #undef __ } // namespace internal diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc index 4e159a69b7ede8..9edd074e3d023d 100644 --- a/deps/v8/src/builtins/arm64/builtins-arm64.cc +++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc @@ -1001,108 +1001,78 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, OptimizationMarker marker, Runtime::FunctionId function_id) { Label no_match; - __ CompareAndBranch(smi_entry, Operand(Smi::FromEnum(marker)), ne, &no_match); + __ CompareTaggedAndBranch(smi_entry, Operand(Smi::FromEnum(marker)), ne, + &no_match); GenerateTailCallToReturnedCode(masm, function_id); __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register feedback_vector, - Register scratch1, - Register scratch2) { +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry, + Register scratch) { // ----------- S t a t e ------------- // -- x3 : new target (preserved for callee if needed, and caller) // -- x1 : target function (preserved for callee if needed, and caller) - // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK(!AreAliased(feedback_vector, x1, x3, scratch1, scratch2)); - - Label optimized_code_slot_is_weak_ref, fallthrough; + DCHECK(!AreAliased(x1, x3, optimized_code_entry, scratch)); Register closure = x1; - Register optimized_code_entry = scratch1; - - __ LoadAnyTaggedField( - optimized_code_entry, - FieldMemOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); - - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret is at a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); - - { - // Optimized code slot is a Smi optimization marker. - - // Fall through if no optimization trigger. - __ CompareAndBranch(optimized_code_entry, - Operand(Smi::FromEnum(OptimizationMarker::kNone)), eq, - &fallthrough); - - // TODO(v8:8394): The logging of first execution will break if - // feedback vectors are not allocated. We need to find a different way of - // logging these events if required. - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); - - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ Cmp( - optimized_code_entry, - Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); - __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); - } - __ B(&fallthrough); - } - } - { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, optimized_code_entry, &fallthrough); + // Check if the optimized code is marked for deopt. If it is, call the + // runtime to clear it. + Label found_deoptimized_code; + __ LoadTaggedPointerField( + scratch, + FieldMemOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); + __ Ldr(scratch.W(), + FieldMemOperand(scratch, CodeDataContainer::kKindSpecificFlagsOffset)); + __ Tbnz(scratch.W(), Code::kMarkedForDeoptimizationBit, + &found_deoptimized_code); + + // Optimized code is good, get it into the closure and link the closure into + // the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure); + static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch"); + __ LoadCodeObjectEntry(x2, optimized_code_entry); + __ Jump(x2); - // Check if the optimized code is marked for deopt. If it is, call the - // runtime to clear it. - Label found_deoptimized_code; - __ LoadTaggedPointerField( - scratch2, - FieldMemOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); - __ Ldr( - scratch2.W(), - FieldMemOperand(scratch2, CodeDataContainer::kKindSpecificFlagsOffset)); - __ Tbnz(scratch2.W(), Code::kMarkedForDeoptimizationBit, - &found_deoptimized_code); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - // The feedback vector is no longer used, so re-use it as a scratch - // register. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure); - static_assert(kJavaScriptCallCodeStartRegister == x2, "ABI mismatch"); - __ LoadCodeObjectEntry(x2, optimized_code_entry); - __ Jump(x2); + // Optimized code slot contains deoptimized code, evict it and re-enter the + // closure's code. + __ bind(&found_deoptimized_code); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +} - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, + Register optimization_marker) { + // ----------- S t a t e ------------- + // -- x3 : new target (preserved for callee if needed, and caller) + // -- x1 : target function (preserved for callee if needed, and caller) + // -- feedback vector (preserved for caller if needed) + // -- optimization_marker : a Smi containing a non-zero optimization marker. + // ----------------------------------- + DCHECK(!AreAliased(feedback_vector, x1, x3, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); + + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ CmpTagged( + optimization_marker, + Operand(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); + __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); } - - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); } // Advance the current bytecode offset. This simulates what all bytecode @@ -1129,19 +1099,19 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, __ Cmp(bytecode, Operand(0x3)); __ B(hi, &process_bytecode); __ Tst(bytecode, Operand(0x1)); - __ B(ne, &extra_wide); - - // Load the next bytecode and update table to the wide scaled table. + // The code to load the next bytecode is common to both wide and extra wide. + // We can hoist them up here since they do not modify the flags after Tst. __ Add(bytecode_offset, bytecode_offset, Operand(1)); __ Ldrb(bytecode, MemOperand(bytecode_array, bytecode_offset)); + __ B(ne, &extra_wide); + + // Update table to the wide scaled table. __ Add(bytecode_size_table, bytecode_size_table, Operand(kIntSize * interpreter::Bytecodes::kBytecodeCount)); __ B(&process_bytecode); __ Bind(&extra_wide); - // Load the next bytecode and update table to the extra wide scaled table. - __ Add(bytecode_offset, bytecode_offset, Operand(1)); - __ Ldrb(bytecode, MemOperand(bytecode_array, bytecode_offset)); + // Update table to the extra wide scaled table. __ Add(bytecode_size_table, bytecode_size_table, Operand(2 * kIntSize * interpreter::Bytecodes::kBytecodeCount)); @@ -1211,7 +1181,20 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, x7, x4); + Register optimized_code_entry = x7; + __ LoadAnyTaggedField( + optimized_code_entry, + FieldMemOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); + + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ CompareTaggedAndBranch(optimized_code_entry, + Operand(Smi::FromEnum(OptimizationMarker::kNone)), + ne, &optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Increment invocation count for the function. // MaybeTailCallOptimizedCodeSlot preserves feedback_vector, so safe to reuse @@ -1248,13 +1231,13 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, x0); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size from the BytecodeArray object. __ Ldr(w11, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ Sub(x10, sp, Operand(x11)); { UseScratchRegisterScope temps(masm); @@ -1262,21 +1245,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LoadRealStackLimit(masm, scratch); __ Cmp(x10, scratch); } - __ B(hs, &ok); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ Bind(&ok); + __ B(lo, &stack_overflow); // If ok, push undefined as the initial value for all register file entries. // Note: there should always be at least one stack slot for the return // register in the register file. Label loop_header; - __ LoadRoot(x10, RootIndex::kUndefinedValue); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ Lsr(x11, x11, kSystemPointerSizeLog2); // Round up the number of registers to a multiple of 2, to align the stack // to 16 bytes. __ Add(x11, x11, 1); __ Bic(x11, x11, 1); - __ PushMultipleTimes(x10, x11); + __ PushMultipleTimes(kInterpreterAccumulatorRegister, x11); __ Bind(&loop_header); } @@ -1291,8 +1272,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Str(x3, MemOperand(fp, x10, LSL, kSystemPointerSizeLog2)); __ Bind(&no_incoming_new_target_or_generator_register); - // Load accumulator with undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. @@ -1315,9 +1295,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Get bytecode array and bytecode offset from the stack frame. __ Ldr(kInterpreterBytecodeArrayRegister, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ Ldr(kInterpreterBytecodeOffsetRegister, - MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); - __ SmiUntag(kInterpreterBytecodeOffsetRegister); + __ SmiUntag(kInterpreterBytecodeOffsetRegister, + MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Either return, or advance to the next bytecode and dispatch. Label do_return; @@ -1333,9 +1312,28 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LeaveInterpreterFrame(masm, x2); __ Ret(); + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code as opposed to an optimization marker. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry, x4); + __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); __ Unreachable(); // Should not return. + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); + __ Unreachable(); // Should not return. } static void Generate_InterpreterPushArgs(MacroAssembler* masm, @@ -1543,9 +1541,8 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { } // Get the target bytecode offset from the frame. - __ Ldr(kInterpreterBytecodeOffsetRegister, - MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); - __ SmiUntag(kInterpreterBytecodeOffsetRegister); + __ SmiUntag(kInterpreterBytecodeOffsetRegister, + MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Dispatch to the target bytecode. __ Ldrb(x23, MemOperand(kInterpreterBytecodeArrayRegister, @@ -1560,9 +1557,8 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { // Get bytecode array and bytecode offset from the stack frame. __ ldr(kInterpreterBytecodeArrayRegister, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ ldr(kInterpreterBytecodeOffsetRegister, - MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); - __ SmiUntag(kInterpreterBytecodeOffsetRegister); + __ SmiUntag(kInterpreterBytecodeOffsetRegister, + MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Load the current bytecode. __ Ldrb(x1, MemOperand(kInterpreterBytecodeArrayRegister, @@ -1633,7 +1629,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { // Set flags for determining the value of smi-tagged argc. // lt => 1, eq => 2, gt => 3. - __ Cmp(argc, Smi::FromInt(2)); + __ CmpTagged(argc, Smi::FromInt(2)); __ B(gt, &three_args); // One or two arguments. @@ -1769,20 +1765,14 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ Ldr(x0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ Ldr(x0, MemOperand(x0, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ PushArgument(x0); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } // If the code object is null, just return to the caller. Label skip; - __ CompareAndBranch(x0, Smi::zero(), ne, &skip); + __ CompareTaggedAndBranch(x0, Smi::zero(), ne, &skip); __ Ret(); __ Bind(&skip); @@ -1878,8 +1868,8 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { // 3. Tail call with no arguments if argArray is null or undefined. Label no_arguments; - __ Cmp(arg_array, null_value); - __ Ccmp(arg_array, undefined_value, ZFlag, ne); + __ CmpTagged(arg_array, null_value); + __ CcmpTagged(arg_array, undefined_value, ZFlag, ne); __ B(eq, &no_arguments); // 4a. Apply the receiver to the given argArray. @@ -2261,7 +2251,7 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, __ Bind(&loop); __ Sub(len, len, 1); __ LoadAnyTaggedField(scratch, MemOperand(src, kTaggedSize, PostIndex)); - __ Cmp(scratch, the_hole_value); + __ CmpTagged(scratch, the_hole_value); __ Csel(scratch, scratch, undefined_value, ne); __ Poke(scratch, Operand(len, LSL, kSystemPointerSizeLog2)); __ Cbnz(len, &loop); @@ -2319,7 +2309,7 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, __ Ldr(args_fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); __ Ldr(x4, MemOperand(args_fp, CommonFrameConstants::kContextOrFrameTypeOffset)); - __ Cmp(x4, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)); + __ CmpTagged(x4, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)); __ B(eq, &arguments_adaptor); { __ Ldr(scratch, @@ -2626,7 +2616,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- x1 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(x1, &non_callable); __ Bind(&non_smi); __ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE); @@ -2642,12 +2632,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // Check if target is a proxy and call CallProxy external builtin __ Cmp(x5, JS_PROXY_TYPE); - __ B(ne, &non_function); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ Bind(&non_function); // Overwrite the original receiver with the (original) target. __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2)); // Let the "call_as_function_delegate" take care of the rest. @@ -2712,7 +2700,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) { // Patch new.target to [[BoundTargetFunction]] if new.target equals target. { Label done; - __ Cmp(x1, x3); + __ CmpTagged(x1, x3); __ B(ne, &done); __ LoadTaggedPointerField( x3, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset)); diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq index aa5d4cc50a731c..065cd08e4c3bda 100644 --- a/deps/v8/src/builtins/base.tq +++ b/deps/v8/src/builtins/base.tq @@ -90,11 +90,28 @@ type bool generates 'TNode<BoolT>' constexpr 'bool'; type bint generates 'TNode<BInt>' constexpr 'BInt'; type string constexpr 'const char*'; -type NameDictionary extends FixedArray; +// The HashTable inheritance hierarchy doesn't actually look like this in C++ +// because it uses some class templates that we can't yet (and may never) +// express in Torque, but this is the expected organization of instance types. +@abstract @dirtyInstantiatedAbstractClass +extern class HashTable extends FixedArray generates 'TNode<FixedArray>'; +extern class OrderedHashMap extends HashTable; +extern class OrderedHashSet extends HashTable; +extern class OrderedNameDictionary extends HashTable; +extern class NameDictionary extends HashTable; +extern class GlobalDictionary extends HashTable; +extern class SimpleNumberDictionary extends HashTable; +extern class StringTable extends HashTable; +extern class EphemeronHashTable extends HashTable; +type ObjectHashTable extends HashTable + generates 'TNode<ObjectHashTable>'; +extern class NumberDictionary extends HashTable; type RawPtr generates 'TNode<RawPtrT>' constexpr 'void*'; -type Code extends HeapObject generates 'TNode<Code>'; +extern class Code extends HeapObject; type BuiltinPtr extends Smi generates 'TNode<BuiltinPtr>'; + +@abstract extern class Context extends HeapObject { length: Smi; scope_info: ScopeInfo; @@ -102,10 +119,27 @@ extern class Context extends HeapObject { extension: Object; native_context: Object; } -type NativeContext extends Context generates 'TNode<NativeContext>'; +extern class AwaitContext extends Context generates 'TNode<Context>'; +extern class BlockContext extends Context generates 'TNode<Context>'; +extern class CatchContext extends Context generates 'TNode<Context>'; +extern class DebugEvaluateContext extends Context + generates 'TNode<Context>'; +extern class EvalContext extends Context generates 'TNode<Context>'; +extern class FunctionContext extends Context generates 'TNode<Context>'; +extern class ModuleContext extends Context generates 'TNode<Context>'; +extern class NativeContext extends Context; +extern class ScriptContext extends Context generates 'TNode<Context>'; +extern class WithContext extends Context generates 'TNode<Context>'; + +@generateCppClass +@abstract +extern class PrimitiveHeapObject extends HeapObject { +} @generateCppClass -extern class Oddball extends HeapObject { +@apiExposedInstanceTypeValue(0x43) +@highestInstanceTypeWithinParentClassRange +extern class Oddball extends PrimitiveHeapObject { to_number_raw: float64; to_string: String; to_number: Number; @@ -113,13 +147,13 @@ extern class Oddball extends HeapObject { kind: Smi; } -extern class HeapNumber extends HeapObject { value: float64; } +extern class HeapNumber extends PrimitiveHeapObject { value: float64; } type Number = Smi | HeapNumber; type Numeric = Number | BigInt; @abstract @generateCppClass -extern class Name extends HeapObject { +extern class Name extends PrimitiveHeapObject { hash_field: uint32; } // This is the same as Name, but with the information that there are no other @@ -137,6 +171,7 @@ type PrivateSymbol extends Symbol; @abstract @generateCppClass +@reserveBitsInInstanceType(6) extern class String extends Name { length: int32; } @@ -222,20 +257,35 @@ extern class FixedArrayBase extends HeapObject { length: Smi; } -extern class FixedArray extends FixedArrayBase { objects[length]: Object; } +@abstract +@dirtyInstantiatedAbstractClass +extern class FixedArray extends FixedArrayBase { + objects[length]: Object; +} extern class FixedDoubleArray extends FixedArrayBase { floats[length]: float64; } -extern class WeakFixedArray extends HeapObject { length: Smi; } +@abstract +@dirtyInstantiatedAbstractClass +extern class WeakFixedArray extends HeapObject { + length: Smi; +} extern class ByteArray extends FixedArrayBase {} +@hasSameInstanceTypeAsParent +extern class ArrayList extends FixedArray { +} + +extern class ObjectBoilerplateDescription extends FixedArray; +extern class ClosureFeedbackCellArray extends FixedArray; +extern class ScriptContextTable extends FixedArray; + type LayoutDescriptor extends ByteArray generates 'TNode<LayoutDescriptor>'; -type TransitionArray extends WeakFixedArray - generates 'TNode<TransitionArray>'; +extern class TransitionArray extends WeakFixedArray; type InstanceType extends uint16 constexpr 'v8::internal::InstanceType'; @@ -282,6 +332,7 @@ extern class SourcePositionTableWithFrameCache extends Struct { // We make this class abstract because it is missing the variable-sized part, // which is still impossible to express in Torque. @abstract +@dirtyInstantiatedAbstractClass extern class DescriptorArray extends HeapObject { number_of_all_descriptors: uint16; number_of_descriptors: uint16; @@ -327,7 +378,9 @@ intrinsic } } +// JSReceiver corresponds to objects in the JS sense. @abstract +@highestInstanceTypeWithinParentClassRange extern class JSReceiver extends HeapObject { properties_or_hash: FixedArrayBase | PropertyArray | Smi; } @@ -337,6 +390,8 @@ type Constructor extends JSReceiver; @abstract @dirtyInstantiatedAbstractClass @generateCppClass +@apiExposedInstanceTypeValue(0x421) +@highestInstanceTypeWithinParentClassRange extern class JSObject extends JSReceiver { // [elements]: The elements (properties with names that are integers). // @@ -368,6 +423,18 @@ macro NewJSObject(implicit context: Context)(): JSObject { }; } +@abstract +@generateCppClass +@lowestInstanceTypeWithinParentClassRange +extern class JSCustomElementsObject extends JSObject { +} + +@abstract +@generateCppClass +@lowestInstanceTypeWithinParentClassRange +extern class JSSpecialObject extends JSCustomElementsObject { +} + extern macro HasPrototypeSlot(JSFunction): bool; macro GetDerivedMap(implicit context: Context)( @@ -401,7 +468,8 @@ macro AllocateFastOrSlowJSObjectFromMap(implicit context: Context)(map: Map): map, properties, kEmptyFixedArray, kNone, kWithSlackTracking); } -extern class JSFunction extends JSObject { +@highestInstanceTypeWithinParentClassRange +extern class JSFunction extends JSFunctionOrBoundFunction { shared_function_info: SharedFunctionInfo; context: Context; feedback_cell: FeedbackCell; @@ -419,6 +487,7 @@ extern class JSProxy extends JSReceiver { // Just a starting shape for JSObject; properties can move after initialization. @noVerifier +@hasSameInstanceTypeAsParent extern class JSProxyRevocableResult extends JSObject { proxy: JSAny; revoke: JSAny; @@ -436,14 +505,14 @@ macro NewJSProxyRevocableResult(implicit context: Context)( } @generateCppClass -extern class JSGlobalProxy extends JSObject { +extern class JSGlobalProxy extends JSSpecialObject { // [native_context]: the owner native context of this global proxy object. // It is null value if this object is not used by any context. native_context: Object; } @generateCppClass -extern class JSPrimitiveWrapper extends JSObject { +extern class JSPrimitiveWrapper extends JSCustomElementsObject { value: JSAny; } @@ -531,8 +600,6 @@ extern class CallHandlerInfo extends Struct { data: Object; } -type ObjectHashTable extends FixedArray; - @abstract extern class Module extends HeapObject { exports: ObjectHashTable; @@ -569,9 +636,12 @@ extern class SourceTextModule extends Module { // Lazily initialized on first access. It's the hole before first access and // a JSObject afterwards. import_meta: TheHole | JSObject; - + async_parent_modules: ArrayList; + top_level_capability: JSPromise | Undefined; dfs_index: Smi; dfs_ancestor_index: Smi; + pending_async_dependencies: Smi; + flags: Smi; } @generateCppClass @@ -583,7 +653,8 @@ extern class SyntheticModule extends Module { @abstract @generateCppClass -extern class JSModuleNamespace extends JSObject { +@dirtyInstantiatedAbstractClass +extern class JSModuleNamespace extends JSSpecialObject { module: Module; } @@ -606,6 +677,7 @@ extern class JSWeakMap extends JSWeakCollection { } @generateCppClass +@abstract extern class JSCollectionIterator extends JSObject { // The backing hash table mapping keys to values. table: Object; @@ -613,6 +685,20 @@ extern class JSCollectionIterator extends JSObject { index: Object; } +@abstract extern class JSMapIterator extends JSCollectionIterator; +extern class JSMapKeyIterator extends JSMapIterator + generates 'TNode<JSMapIterator>'; +extern class JSMapKeyValueIterator extends JSMapIterator + generates 'TNode<JSMapIterator>'; +extern class JSMapValueIterator extends JSMapIterator + generates 'TNode<JSMapIterator>'; + +@abstract extern class JSSetIterator extends JSCollectionIterator; +extern class JSSetKeyValueIterator extends JSSetIterator + generates 'TNode<JSSetIterator>'; +extern class JSSetValueIterator extends JSSetIterator + generates 'TNode<JSSetIterator>'; + extern class JSMessageObject extends JSObject { // Tagged fields. message_type: Smi; @@ -656,7 +742,7 @@ extern class Script extends Struct { line_ends: Object; id: Smi; eval_from_shared_or_wrapped_arguments: Object; - eval_from_position: Smi; + eval_from_position: Smi | Foreign; // Smi or Managed<wasm::NativeModule> shared_function_infos: Object; flags: Smi; source_url: Object; @@ -669,12 +755,13 @@ extern class EmbedderDataArray extends HeapObject { length: Smi; } -type ScopeInfo extends HeapObject generates 'TNode<ScopeInfo>'; +extern class ScopeInfo extends FixedArray; +@generateCppClass extern class PreparseData extends HeapObject { // TODO(v8:8983): Add declaration for variable-sized region. data_length: int32; - inner_length: int32; + children_length: int32; } extern class InterpreterData extends Struct { @@ -697,13 +784,36 @@ extern class SharedFunctionInfo extends HeapObject { @if(V8_SFI_HAS_UNIQUE_ID) unique_id: int32; } +@abstract +@generateCppClass +extern class UncompiledData extends HeapObject { + inferred_name: String; + start_position: int32; + end_position: int32; +} + +@generateCppClass +extern class UncompiledDataWithoutPreparseData extends UncompiledData { +} + +@generateCppClass +extern class UncompiledDataWithPreparseData extends UncompiledData { + preparse_data: PreparseData; +} + +@abstract +@generateCppClass +@highestInstanceTypeWithinParentClassRange +extern class JSFunctionOrBoundFunction extends JSObject { +} + @generateCppClass -extern class JSBoundFunction extends JSObject { +extern class JSBoundFunction extends JSFunctionOrBoundFunction { // The wrapped function object. bound_target_function: Callable; // The value that is always passed as the this value when calling the wrapped // function. - bound_this: JSAny; + bound_this: JSAny | SourceTextModule; // A list of values whose elements are used as the first arguments to any call // to the wrapped function. bound_arguments: FixedArray; @@ -728,8 +838,6 @@ extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength( FixedArrayBase): intptr; type SloppyArgumentsElements extends FixedArray; -type NumberDictionary extends HeapObject - generates 'TNode<NumberDictionary>'; extern class FreeSpace extends HeapObject { size: Smi; @@ -763,6 +871,8 @@ const PROXY_REVOCABLE_RESULT_MAP_INDEX: constexpr NativeContextSlot generates 'Context::PROXY_REVOCABLE_RESULT_MAP_INDEX'; const REFLECT_APPLY_INDEX: constexpr NativeContextSlot generates 'Context::REFLECT_APPLY_INDEX'; +const REGEXP_FUNCTION_INDEX: constexpr NativeContextSlot + generates 'Context::REGEXP_FUNCTION_INDEX'; const REGEXP_LAST_MATCH_INFO_INDEX: constexpr NativeContextSlot generates 'Context::REGEXP_LAST_MATCH_INFO_INDEX'; const INITIAL_STRING_ITERATOR_MAP_INDEX: constexpr NativeContextSlot @@ -834,7 +944,7 @@ extern class JSDate extends JSObject { cache_stamp: Undefined | Smi | NaN; } -extern class JSGlobalObject extends JSObject { +extern class JSGlobalObject extends JSSpecialObject { native_context: NativeContext; global_proxy: JSGlobalProxy; } @@ -847,9 +957,12 @@ extern class JSAsyncFromSyncIterator extends JSObject { next: Object; } +@generateCppClass extern class JSStringIterator extends JSObject { + // The [[IteratedString]] inobject property. string: String; - next_index: Smi; + // The [[StringIteratorNextIndex]] inobject property. + index: Smi; } @abstract @@ -885,7 +998,7 @@ extern class FunctionTemplateRareData extends Struct { @generateCppClass extern class FunctionTemplateInfo extends TemplateInfo { // Handler invoked when calling an instance of this FunctionTemplateInfo. - // Either CallInfoHandler or Undefined. + // Either CallHandlerInfo or Undefined. call_code: Object; class_name: Object; // If the signature is a FunctionTemplateInfo it is used to check whether the @@ -946,7 +1059,10 @@ const UTF16: const UTF32: constexpr UnicodeEncoding generates 'UnicodeEncoding::UTF32'; -extern class Foreign extends HeapObject { foreign_address: RawPtr; } +@apiExposedInstanceTypeValue(0x46) +extern class Foreign extends HeapObject { + foreign_address: RawPtr; +} @generateCppClass extern class InterceptorInfo extends Struct { @@ -985,6 +1101,7 @@ extern class Cell extends HeapObject { value: Object; } +@abstract extern class DataHandler extends Struct { smi_handler: Smi | Code; validity_cell: Smi | Cell; @@ -996,6 +1113,9 @@ extern class DataHandler extends Struct { @noVerifier weak data_3: Object; } +extern class LoadHandler extends DataHandler; +extern class StoreHandler extends DataHandler; + @abstract @dirtyInstantiatedAbstractClass @generateCppClass @@ -1087,7 +1207,7 @@ extern class ClassPositions extends Struct { end: Smi; } -type WasmInstanceObject extends JSObject; +extern class WasmInstanceObject extends JSObject; extern class WasmExportedFunctionData extends Struct { wrapper_code: Code; @@ -1129,6 +1249,7 @@ extern class WasmIndirectFunctionTable extends Struct { extern class WasmDebugInfo extends Struct { instance: WasmInstanceObject; interpreter_handle: Foreign | Undefined; + interpreter_reference_stack: Cell; locals_names: FixedArray | Undefined; c_wasm_entries: FixedArray | Undefined; c_wasm_entry_map: Foreign | Undefined; // Managed<wasm::SignatureMap> @@ -1305,9 +1426,6 @@ const kStrictReadOnlyProperty: constexpr MessageTemplate const kString: constexpr PrimitiveType generates 'PrimitiveType::kString'; -const kExternalPointerForOnHeapArray: constexpr RawPtr - generates 'JSTypedArray::ExternalPointerForOnHeapArray()'; - const kNameDictionaryInitialCapacity: constexpr int32 generates 'NameDictionary::kInitialCapacity'; @@ -1332,6 +1450,7 @@ extern macro EmptyStringConstant(): EmptyString; extern macro LengthStringConstant(): String; extern macro NanConstant(): NaN; extern macro IteratorSymbolConstant(): Symbol; +extern macro MatchSymbolConstant(): Symbol; const TheHole: TheHole = TheHoleConstant(); const Null: Null = NullConstant(); @@ -1443,15 +1562,30 @@ RegExpBuiltinsAssembler::FastStoreLastIndex(FastJSRegExp, Smi): void; @hasSameInstanceTypeAsParent extern class JSRegExpResult extends JSArray { + // In-object properties: + // The below fields are externally exposed. index: JSAny; input: JSAny; groups: JSAny; + + // The below fields are for internal use only. + cached_indices_or_match_info: JSRegExpResultIndices | RegExpMatchInfo; + names: FixedArray | Undefined; } +@hasSameInstanceTypeAsParent +extern class JSRegExpResultIndices extends JSArray { + // In-object properties: + // The groups field is externally exposed. + groups: JSAny; +} + +transient type FastJSRegExpResult extends JSRegExpResult; + @generateCppClass extern class JSRegExpStringIterator extends JSObject { // The [[IteratingRegExp]] internal property. - iterating_reg_exp: JSAny; + iterating_reg_exp: JSReceiver; // The [[IteratedString]] internal property. iterated_string: String; flags: Smi; @@ -1493,21 +1627,33 @@ extern class AccessorInfo extends Struct { data: Object; } +@generateCppClass extern class AccessorPair extends Struct { getter: Object; setter: Object; } -extern class BreakPoint extends Tuple2 {} -extern class BreakPointInfo extends Tuple2 {} +@hasSameInstanceTypeAsParent +extern class BreakPoint extends Tuple2 { +} +@hasSameInstanceTypeAsParent +extern class BreakPointInfo extends Tuple2 { +} type CoverageInfo extends FixedArray; +@generateCppClass extern class DebugInfo extends Struct { - shared_function_info: SharedFunctionInfo; + shared: SharedFunctionInfo; debugger_hints: Smi; + // Script field from shared function info. script: Undefined | Script; + // The original uninstrumented bytecode array for functions with break + // points - the instrumented bytecode is held in the shared function info. original_bytecode_array: Undefined | BytecodeArray; + // The debug instrumented bytecode array for functions with break points + // - also pointed to by the shared function info. debug_bytecode_array: Undefined | BytecodeArray; + // Fixed array holding status information for each active break point. break_points: FixedArray; flags: Smi; coverage_info: CoverageInfo | Undefined; @@ -1527,12 +1673,15 @@ extern class FeedbackVector extends HeapObject { padding: uint32; } +@generateCppClass extern class FeedbackCell extends Struct { value: Undefined | FeedbackVector | FixedArray; interrupt_budget: int32; } -type AllocationSite extends Struct; +extern class FeedbackMetadata extends HeapObject; + +extern class AllocationSite extends Struct; extern class AllocationMemento extends Struct { allocation_site: AllocationSite; } @@ -1541,9 +1690,7 @@ extern class WasmModuleObject extends JSObject { native_module: Foreign; export_wrappers: FixedArray; script: Script; - weak_instance_list: WeakArrayList; asm_js_offset_table: ByteArray | Undefined; - break_point_infos: FixedArray | Undefined; } extern class WasmTableObject extends JSObject { @@ -1590,22 +1737,35 @@ extern class JSFinalizationGroup extends JSObject { flags: Smi; } +@generateCppClass extern class JSFinalizationGroupCleanupIterator extends JSObject { finalization_group: JSFinalizationGroup; } +@generateCppClass extern class WeakCell extends HeapObject { finalization_group: Undefined | JSFinalizationGroup; target: Undefined | JSReceiver; holdings: Object; + + // For storing doubly linked lists of WeakCells in JSFinalizationGroup's + // "active_cells" and "cleared_cells" lists. prev: Undefined | WeakCell; next: Undefined | WeakCell; + + // For storing doubly linked lists of WeakCells per key in + // JSFinalizationGroup's key-based hashmap. WeakCell also needs to know its + // key, so that we can remove the key from the key_map when we remove the last + // WeakCell associated with it. key: Object; key_list_prev: Undefined | WeakCell; key_list_next: Undefined | WeakCell; } -extern class JSWeakRef extends JSObject { target: Undefined | JSReceiver; } +@generateCppClass +extern class JSWeakRef extends JSObject { + target: Undefined | JSReceiver; +} extern class BytecodeArray extends FixedArrayBase { // TODO(v8:8983): bytecode array object sizes vary based on their contents. @@ -1620,6 +1780,29 @@ extern class BytecodeArray extends FixedArrayBase { bytecode_age: int8; } +extern class Filler extends HeapObject generates 'TNode<HeapObject>'; +extern class CodeDataContainer extends HeapObject; +@abstract +extern class SmallOrderedHashTable extends HeapObject + generates 'TNode<HeapObject>'; +extern class SmallOrderedHashMap extends SmallOrderedHashTable; +extern class SmallOrderedHashSet extends SmallOrderedHashTable; +extern class SmallOrderedNameDictionary extends SmallOrderedHashTable; + +// Various logical subclasses of JSObject, which have their own instance types +// but not their own class definitions: + +// Like JSObject, but created from API function. +@apiExposedInstanceTypeValue(0x420) +extern class JSApiObject extends JSObject generates 'TNode<JSObject>'; +// Like JSApiObject, but requires access checks and/or has interceptors. +@apiExposedInstanceTypeValue(0x410) +extern class JSSpecialApiObject extends JSSpecialObject + generates 'TNode<JSSpecialObject>'; +extern class JSContextExtensionObject extends JSObject + generates 'TNode<JSObject>'; +extern class JSError extends JSObject generates 'TNode<JSObject>'; + extern macro Is64(): constexpr bool; extern macro SelectBooleanConstant(bool): Boolean; @@ -1657,6 +1840,8 @@ extern transitioning builtin HasProperty(implicit context: Context)( extern transitioning macro HasProperty_Inline(implicit context: Context)( JSReceiver, JSAny): Boolean; extern builtin LoadIC(Context, JSAny, JSAny, Smi, FeedbackVector): JSAny; +extern macro CollectCallFeedback( + JSAny, Context, Undefined | FeedbackVector, uintptr); extern macro ThrowRangeError(implicit context: Context)( constexpr MessageTemplate): never; @@ -1674,6 +1859,10 @@ extern macro ThrowTypeError(implicit context: Context)( constexpr MessageTemplate, Object, Object, Object): never; extern transitioning runtime ThrowTypeErrorIfStrict(implicit context: Context)( Smi, Object, Object): void; +extern transitioning runtime ThrowCalledNonCallable(implicit context: Context)( + JSAny): never; +extern transitioning runtime ThrowSymbolIteratorInvalid( + implicit context: Context)(): never; extern transitioning macro ThrowIfNotJSReceiver(implicit context: Context)( JSAny, constexpr MessageTemplate, constexpr string): void; @@ -2232,6 +2421,14 @@ Cast<JSStringIterator>(o: HeapObject): JSStringIterator return HeapObjectToJSStringIterator(o) otherwise CastError; } +Cast<JSRegExpStringIterator>(o: HeapObject): JSRegExpStringIterator + labels CastError { + if (IsJSRegExpStringIterator(o)) { + return %RawDownCast<JSRegExpStringIterator>(o); + } + goto CastError; +} + Cast<JSTypedArray>(o: HeapObject): JSTypedArray labels CastError { if (IsJSTypedArray(o)) return %RawDownCast<JSTypedArray>(o); @@ -2354,12 +2551,25 @@ Cast<JSRegExp>(o: HeapObject): JSRegExp goto CastError; } +Cast<FastJSRegExpResult>(implicit context: Context)(o: HeapObject): + FastJSRegExpResult + labels CastError { + if (regexp::IsFastRegExpResult(o)) return %RawDownCast<FastJSRegExpResult>(o); + goto CastError; +} + Cast<Map>(implicit context: Context)(o: HeapObject): Map labels CastError { if (IsMap(o)) return %RawDownCast<Map>(o); goto CastError; } +Cast<FeedbackVector>(implicit context: Context)(o: HeapObject): FeedbackVector + labels CastError { + if (IsFeedbackVector(o)) return %RawDownCast<FeedbackVector>(o); + goto CastError; +} + Cast<JSPrimitiveWrapper>(o: HeapObject): JSPrimitiveWrapper labels CastError { if (IsJSPrimitiveWrapper(o)) return %RawDownCast<JSPrimitiveWrapper>(o); @@ -2513,6 +2723,7 @@ extern macro Signed(RawPtr): intptr; extern macro TruncateIntPtrToInt32(intptr): int32; extern macro SmiTag(intptr): Smi; extern macro SmiFromInt32(int32): Smi; +extern macro SmiFromUint32(uint32): Smi; extern macro SmiUntag(Smi): intptr; extern macro SmiToInt32(Smi): int32; extern macro RoundIntPtrToFloat64(intptr): float64; @@ -2556,6 +2767,7 @@ extern macro BitcastWordToTaggedSigned(uintptr): Smi; extern macro BitcastWordToTagged(intptr): Object; extern macro BitcastWordToTagged(uintptr): Object; extern macro BitcastTaggedToWord(Tagged): intptr; +extern macro BitcastTaggedToWordForTagAndSmiBits(Tagged): intptr; intrinsic %FromConstexpr<To: type, From: type>(b: From): To; macro FromConstexpr<To: type, From: type>(o: From): To; @@ -2674,7 +2886,7 @@ Convert<Number, uint32>(ui: uint32): Number { return ChangeUint32ToTagged(ui); } Convert<Smi, uint32>(ui: uint32): Smi { - return SmiFromInt32(Signed(ui)); + return SmiFromUint32(ui); } Convert<uintptr, uint32>(ui: uint32): uintptr { return ChangeUint32ToWord(ui); @@ -2811,8 +3023,7 @@ extern macro IsMockArrayBufferAllocatorFlag(): bool; extern macro IsPrototypeTypedArrayPrototype(implicit context: Context)(Map): bool; -extern operator '.data_ptr' macro LoadJSTypedArrayBackingStore(JSTypedArray): - RawPtr; +extern operator '.data_ptr' macro LoadJSTypedArrayDataPtr(JSTypedArray): RawPtr; extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind; extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): @@ -2879,8 +3090,6 @@ extern macro LoadConstructorOrBackPointer(Map): Object; extern macro BasicLoadNumberDictionaryElement(NumberDictionary, intptr): JSAny labels NotData, IfHole; -extern macro BasicStoreNumberDictionaryElement(NumberDictionary, intptr, JSAny) - labels NotData, IfHole, ReadOnly; extern macro IsFastElementsKind(ElementsKind): bool; extern macro IsDoubleElementsKind(ElementsKind): bool; @@ -3255,9 +3464,11 @@ extern macro PerformStackCheck(implicit context: Context)(): void; extern macro IsCallable(HeapObject): bool; extern macro IsConstructor(HeapObject): bool; +extern macro IsFeedbackVector(HeapObject): bool; extern macro IsJSArray(HeapObject): bool; extern macro IsJSProxy(HeapObject): bool; extern macro IsJSRegExp(HeapObject): bool; +extern macro IsJSRegExpStringIterator(HeapObject): bool; extern macro IsMap(HeapObject): bool; extern macro IsJSFunction(HeapObject): bool; extern macro IsJSObject(HeapObject): bool; diff --git a/deps/v8/src/builtins/bigint.tq b/deps/v8/src/builtins/bigint.tq index a1b1cb67809d84..f0409ad23df13f 100644 --- a/deps/v8/src/builtins/bigint.tq +++ b/deps/v8/src/builtins/bigint.tq @@ -7,7 +7,8 @@ // TODO(nicohartmann): Discuss whether types used by multiple builtins should be // in global namespace @noVerifier -extern class BigIntBase extends HeapObject generates 'TNode<BigInt>' { +extern class BigIntBase extends PrimitiveHeapObject + generates 'TNode<BigInt>' { } type BigInt extends BigIntBase; @@ -44,9 +45,6 @@ namespace bigint { MutableBigInt, intptr, uintptr): void; extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr; - @export // Silence unused warning. - // TODO(szuend): Remove @export once macros that are only used in - // asserts are no longer detected as unused. macro IsCanonicalized(bigint: BigIntBase): bool { const length = ReadBigIntLength(bigint); diff --git a/deps/v8/src/builtins/builtins-arguments-gen.cc b/deps/v8/src/builtins/builtins-arguments-gen.cc index c4399175e9846d..fb6169adf86b4b 100644 --- a/deps/v8/src/builtins/builtins-arguments-gen.cc +++ b/deps/v8/src/builtins/builtins-arguments-gen.cc @@ -17,38 +17,34 @@ namespace v8 { namespace internal { -using Node = compiler::Node; - -std::tuple<Node*, Node*, Node*> -ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, - Node* arguments_count, - Node* parameter_map_count, - ParameterMode mode, - int base_size) { +ArgumentsBuiltinsAssembler::ArgumentsAllocationResult +ArgumentsBuiltinsAssembler::AllocateArgumentsObject( + TNode<Map> map, TNode<BInt> arguments_count, + TNode<BInt> parameter_map_count, int base_size) { // Allocate the parameter object (either a Rest parameter object, a strict // argument object or a sloppy arguments object) and the elements/mapped // arguments together. int elements_offset = base_size; - Node* element_count = arguments_count; + TNode<BInt> element_count = arguments_count; if (parameter_map_count != nullptr) { base_size += FixedArray::kHeaderSize; - element_count = IntPtrOrSmiAdd(element_count, parameter_map_count, mode); + element_count = IntPtrOrSmiAdd(element_count, parameter_map_count); } - bool empty = IsIntPtrOrSmiConstantZero(arguments_count, mode); + bool empty = IsIntPtrOrSmiConstantZero(arguments_count); DCHECK_IMPLIES(empty, parameter_map_count == nullptr); TNode<IntPtrT> size = empty ? IntPtrConstant(base_size) - : ElementOffsetFromIndex(element_count, PACKED_ELEMENTS, mode, + : ElementOffsetFromIndex(element_count, PACKED_ELEMENTS, base_size + FixedArray::kHeaderSize); TNode<HeapObject> result = Allocate(size); Comment("Initialize arguments object"); StoreMapNoWriteBarrier(result, map); TNode<FixedArray> empty_fixed_array = EmptyFixedArrayConstant(); StoreObjectField(result, JSArray::kPropertiesOrHashOffset, empty_fixed_array); - TNode<Smi> smi_arguments_count = ParameterToTagged(arguments_count, mode); + TNode<Smi> smi_arguments_count = BIntToSmi(arguments_count); StoreObjectFieldNoWriteBarrier(result, JSArray::kLengthOffset, smi_arguments_count); - Node* arguments = nullptr; + TNode<HeapObject> arguments; if (!empty) { arguments = InnerAllocate(result, elements_offset); StoreObjectFieldNoWriteBarrier(arguments, FixedArray::kLengthOffset, @@ -56,18 +52,17 @@ ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, TNode<Map> fixed_array_map = FixedArrayMapConstant(); StoreMapNoWriteBarrier(arguments, fixed_array_map); } - Node* parameter_map = nullptr; - if (parameter_map_count != nullptr) { + TNode<HeapObject> parameter_map; + if (!parameter_map_count.is_null()) { TNode<IntPtrT> parameter_map_offset = ElementOffsetFromIndex( - arguments_count, PACKED_ELEMENTS, mode, FixedArray::kHeaderSize); - parameter_map = InnerAllocate(CAST(arguments), parameter_map_offset); + arguments_count, PACKED_ELEMENTS, FixedArray::kHeaderSize); + parameter_map = InnerAllocate(arguments, parameter_map_offset); StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, parameter_map); TNode<Map> sloppy_elements_map = SloppyArgumentsElementsMapConstant(); StoreMapNoWriteBarrier(parameter_map, sloppy_elements_map); - parameter_map_count = ParameterToTagged(parameter_map_count, mode); StoreObjectFieldNoWriteBarrier(parameter_map, FixedArray::kLengthOffset, - parameter_map_count); + BIntToSmi(parameter_map_count)); } else { if (empty) { StoreObjectFieldNoWriteBarrier(result, JSArray::kElementsOffset, @@ -77,80 +72,73 @@ ArgumentsBuiltinsAssembler::AllocateArgumentsObject(Node* map, arguments); } } - return std::tuple<Node*, Node*, Node*>(result, arguments, parameter_map); + return {CAST(result), UncheckedCast<FixedArray>(arguments), + UncheckedCast<FixedArray>(parameter_map)}; } -Node* ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs( - Node* map, Node* frame_ptr, Node* arg_count, Node* first_arg, - Node* rest_count, ParameterMode param_mode, int base_size) { +TNode<JSObject> ArgumentsBuiltinsAssembler::ConstructParametersObjectFromArgs( + TNode<Map> map, TNode<RawPtrT> frame_ptr, TNode<BInt> arg_count, + TNode<BInt> first_arg, TNode<BInt> rest_count, int base_size) { // Allocate the parameter object (either a Rest parameter object, a strict // argument object or a sloppy arguments object) and the elements together and // fill in the contents with the arguments above |formal_parameter_count|. - Node* result; - Node* elements; - Node* unused; - std::tie(result, elements, unused) = - AllocateArgumentsObject(map, rest_count, nullptr, param_mode, base_size); - DCHECK_NULL(unused); - CodeStubArguments arguments(this, arg_count, frame_ptr, param_mode); - VARIABLE(offset, MachineType::PointerRepresentation()); - offset.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag)); + ArgumentsAllocationResult alloc_result = + AllocateArgumentsObject(map, rest_count, {}, base_size); + DCHECK(alloc_result.parameter_map.is_null()); + CodeStubArguments arguments(this, arg_count, frame_ptr); + TVARIABLE(IntPtrT, offset, + IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag)); VariableList list({&offset}, zone()); arguments.ForEach( list, - [this, elements, &offset](Node* arg) { - StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, - offset.value(), arg); + [&](TNode<Object> arg) { + StoreNoWriteBarrier(MachineRepresentation::kTagged, + alloc_result.elements, offset.value(), arg); Increment(&offset, kTaggedSize); }, - first_arg, nullptr, param_mode); - return result; + first_arg); + return alloc_result.arguments_object; } -Node* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context, - Node* function) { +TNode<JSObject> ArgumentsBuiltinsAssembler::EmitFastNewRestParameter( + TNode<Context> context, TNode<JSFunction> function) { ParameterMode mode = OptimalParameterMode(); - Node* zero = IntPtrOrSmiConstant(0, mode); + TNode<BInt> zero = BIntConstant(0); - TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount( - CAST(context), UncheckedCast<JSFunction>(function)); + TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount(context, function); - VARIABLE(result, MachineRepresentation::kTagged); + TVARIABLE(JSObject, result); Label no_rest_parameters(this), runtime(this, Label::kDeferred), done(this, &result); - Node* rest_count = - IntPtrOrSmiSub(info.argument_count, info.formal_parameter_count, mode); + TNode<BInt> rest_count = + IntPtrOrSmiSub(info.argument_count, info.formal_parameter_count); TNode<NativeContext> const native_context = LoadNativeContext(context); TNode<Map> const array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero, mode), - &no_rest_parameters); + GotoIf(IntPtrOrSmiLessThanOrEqual(rest_count, zero), &no_rest_parameters); GotoIfFixedArraySizeDoesntFitInNewSpace( rest_count, &runtime, JSArray::kSize + FixedArray::kHeaderSize, mode); // Allocate the Rest JSArray and the elements together and fill in the // contents with the arguments above |formal_parameter_count|. - result.Bind(ConstructParametersObjectFromArgs( + result = ConstructParametersObjectFromArgs( array_map, info.frame, info.argument_count, info.formal_parameter_count, - rest_count, mode, JSArray::kSize)); + rest_count, JSArray::kSize); Goto(&done); BIND(&no_rest_parameters); { - Node* arguments; - Node* elements; - Node* unused; - std::tie(arguments, elements, unused) = - AllocateArgumentsObject(array_map, zero, nullptr, mode, JSArray::kSize); - result.Bind(arguments); + ArgumentsAllocationResult alloc_result = + AllocateArgumentsObject(array_map, zero, {}, JSArray::kSize); + result = alloc_result.arguments_object; Goto(&done); } BIND(&runtime); { - result.Bind(CallRuntime(Runtime::kNewRestParameter, context, function)); + result = CAST(CallRuntime(Runtime::kNewRestParameter, context, function)); Goto(&done); } @@ -158,45 +146,41 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewRestParameter(Node* context, return result.value(); } -Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context, - Node* function) { - VARIABLE(result, MachineRepresentation::kTagged); +TNode<JSObject> ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments( + TNode<Context> context, TNode<JSFunction> function) { + TVARIABLE(JSObject, result); Label done(this, &result), empty(this), runtime(this, Label::kDeferred); ParameterMode mode = OptimalParameterMode(); TNode<BInt> zero = BIntConstant(0); - TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount( - CAST(context), UncheckedCast<JSFunction>(function)); + TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount(context, function); GotoIfFixedArraySizeDoesntFitInNewSpace( info.argument_count, &runtime, JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize, mode); TNode<NativeContext> const native_context = LoadNativeContext(context); - TNode<Object> const map = - LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX); + TNode<Map> map = CAST( + LoadContextElement(native_context, Context::STRICT_ARGUMENTS_MAP_INDEX)); GotoIf(BIntEqual(info.argument_count, zero), &empty); - result.Bind(ConstructParametersObjectFromArgs( - map, info.frame, info.argument_count, zero, info.argument_count, mode, - JSStrictArgumentsObject::kSize)); + result = ConstructParametersObjectFromArgs( + map, info.frame, info.argument_count, zero, info.argument_count, + JSStrictArgumentsObject::kSize); Goto(&done); BIND(&empty); { - Node* arguments; - Node* elements; - Node* unused; - std::tie(arguments, elements, unused) = AllocateArgumentsObject( - map, zero, nullptr, mode, JSStrictArgumentsObject::kSize); - result.Bind(arguments); + ArgumentsAllocationResult alloc_result = + AllocateArgumentsObject(map, zero, {}, JSStrictArgumentsObject::kSize); + result = alloc_result.arguments_object; Goto(&done); } BIND(&runtime); { - result.Bind(CallRuntime(Runtime::kNewStrictArguments, context, function)); + result = CAST(CallRuntime(Runtime::kNewStrictArguments, context, function)); Goto(&done); } @@ -204,9 +188,9 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewStrictArguments(Node* context, return result.value(); } -Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, - Node* function) { - VARIABLE(result, MachineRepresentation::kTagged); +TNode<JSObject> ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments( + TNode<Context> context, TNode<JSFunction> function) { + TVARIABLE(JSObject, result); ParameterMode mode = OptimalParameterMode(); TNode<BInt> zero = BIntConstant(0); @@ -214,8 +198,7 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, Label done(this, &result), empty(this), no_parameters(this), runtime(this, Label::kDeferred); - TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount( - CAST(context), UncheckedCast<JSFunction>(function)); + TorqueStructArgumentsInfo info = GetArgumentsFrameAndCount(context, function); GotoIf(BIntEqual(info.argument_count, zero), &empty); @@ -224,54 +207,55 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, { Comment("Mapped parameter JSSloppyArgumentsObject"); - Node* mapped_count = - IntPtrOrSmiMin(info.argument_count, info.formal_parameter_count, mode); + TNode<BInt> mapped_count = + IntPtrOrSmiMin(info.argument_count, info.formal_parameter_count); - Node* parameter_map_size = - IntPtrOrSmiAdd(mapped_count, IntPtrOrSmiConstant(2, mode), mode); + TNode<BInt> parameter_map_size = + IntPtrOrSmiAdd(mapped_count, BIntConstant(2)); // Verify that the overall allocation will fit in new space. - Node* elements_allocated = - IntPtrOrSmiAdd(info.argument_count, parameter_map_size, mode); + TNode<BInt> elements_allocated = + IntPtrOrSmiAdd(info.argument_count, parameter_map_size); GotoIfFixedArraySizeDoesntFitInNewSpace( elements_allocated, &runtime, JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize * 2, mode); TNode<NativeContext> const native_context = LoadNativeContext(context); - TNode<Object> const map = LoadContextElement( - native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX); - Node* argument_object; - Node* elements; - Node* map_array; - std::tie(argument_object, elements, map_array) = + TNode<Map> const map = CAST(LoadContextElement( + native_context, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)); + ArgumentsAllocationResult alloc_result = AllocateArgumentsObject(map, info.argument_count, parameter_map_size, - mode, JSSloppyArgumentsObject::kSize); - StoreObjectFieldNoWriteBarrier( - argument_object, JSSloppyArgumentsObject::kCalleeOffset, function); - StoreFixedArrayElement(CAST(map_array), 0, context, SKIP_WRITE_BARRIER); - StoreFixedArrayElement(CAST(map_array), 1, elements, SKIP_WRITE_BARRIER); + JSSloppyArgumentsObject::kSize); + StoreObjectFieldNoWriteBarrier(alloc_result.arguments_object, + JSSloppyArgumentsObject::kCalleeOffset, + function); + StoreFixedArrayElement(alloc_result.parameter_map, 0, context, + SKIP_WRITE_BARRIER); + StoreFixedArrayElement(alloc_result.parameter_map, 1, alloc_result.elements, + SKIP_WRITE_BARRIER); Comment("Fill in non-mapped parameters"); TNode<IntPtrT> argument_offset = - ElementOffsetFromIndex(info.argument_count, PACKED_ELEMENTS, mode, + ElementOffsetFromIndex(info.argument_count, PACKED_ELEMENTS, FixedArray::kHeaderSize - kHeapObjectTag); TNode<IntPtrT> mapped_offset = - ElementOffsetFromIndex(mapped_count, PACKED_ELEMENTS, mode, + ElementOffsetFromIndex(mapped_count, PACKED_ELEMENTS, FixedArray::kHeaderSize - kHeapObjectTag); - CodeStubArguments arguments(this, info.argument_count, info.frame, mode); - VARIABLE(current_argument, MachineType::PointerRepresentation()); - current_argument.Bind(arguments.AtIndexPtr(info.argument_count, mode)); + CodeStubArguments arguments(this, info.argument_count, info.frame); + TVARIABLE(RawPtrT, current_argument, + arguments.AtIndexPtr(info.argument_count)); VariableList var_list1({¤t_argument}, zone()); - mapped_offset = UncheckedCast<IntPtrT>(BuildFastLoop( + mapped_offset = BuildFastLoop<IntPtrT>( var_list1, argument_offset, mapped_offset, - [this, elements, ¤t_argument](Node* offset) { + [&](TNode<IntPtrT> offset) { Increment(¤t_argument, kSystemPointerSize); TNode<Object> arg = LoadBufferObject( - UncheckedCast<RawPtrT>(current_argument.value()), 0); - StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset, - arg); + ReinterpretCast<RawPtrT>(current_argument.value()), 0); + StoreNoWriteBarrier(MachineRepresentation::kTagged, + alloc_result.elements, offset, arg); + return; }, - -kTaggedSize, INTPTR_PARAMETERS)); + -kTaggedSize); // Copy the parameter slots and the holes in the arguments. // We need to fill in mapped_count slots. They index the context, @@ -282,32 +266,32 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, // MIN_CONTEXT_SLOTS+argument_count-mapped_count // We loop from right to left. Comment("Fill in mapped parameters"); - VARIABLE(context_index, OptimalParameterRepresentation()); - context_index.Bind(IntPtrOrSmiSub( - IntPtrOrSmiAdd(IntPtrOrSmiConstant(Context::MIN_CONTEXT_SLOTS, mode), - info.formal_parameter_count, mode), - mapped_count, mode)); + TVARIABLE( + BInt, context_index, + IntPtrOrSmiSub(IntPtrOrSmiAdd(BIntConstant(Context::MIN_CONTEXT_SLOTS), + info.formal_parameter_count), + mapped_count)); TNode<Oddball> the_hole = TheHoleConstant(); VariableList var_list2({&context_index}, zone()); const int kParameterMapHeaderSize = FixedArray::OffsetOfElementAt(2); TNode<IntPtrT> adjusted_map_array = IntPtrAdd( - BitcastTaggedToWord(map_array), + BitcastTaggedToWord(alloc_result.parameter_map), IntPtrConstant(kParameterMapHeaderSize - FixedArray::kHeaderSize)); TNode<IntPtrT> zero_offset = ElementOffsetFromIndex( zero, PACKED_ELEMENTS, mode, FixedArray::kHeaderSize - kHeapObjectTag); - BuildFastLoop( + BuildFastLoop<IntPtrT>( var_list2, mapped_offset, zero_offset, - [=, &context_index](Node* offset) { - StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, offset, - the_hole); + [&](TNode<IntPtrT> offset) { + StoreNoWriteBarrier(MachineRepresentation::kTagged, + alloc_result.elements, offset, the_hole); StoreNoWriteBarrier(MachineRepresentation::kTagged, adjusted_map_array, offset, - ParameterToTagged(context_index.value(), mode)); - Increment(&context_index, 1, mode); + BIntToSmi(context_index.value())); + Increment(&context_index); }, - -kTaggedSize, INTPTR_PARAMETERS); + -kTaggedSize); - result.Bind(argument_object); + result = alloc_result.arguments_object; Goto(&done); } @@ -318,11 +302,11 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, info.argument_count, &runtime, JSSloppyArgumentsObject::kSize + FixedArray::kHeaderSize, mode); TNode<NativeContext> const native_context = LoadNativeContext(context); - TNode<Object> const map = - LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); - result.Bind(ConstructParametersObjectFromArgs( - map, info.frame, info.argument_count, zero, info.argument_count, mode, - JSSloppyArgumentsObject::kSize)); + TNode<Map> map = CAST(LoadContextElement( + native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); + result = ConstructParametersObjectFromArgs( + map, info.frame, info.argument_count, zero, info.argument_count, + JSSloppyArgumentsObject::kSize); StoreObjectFieldNoWriteBarrier( result.value(), JSSloppyArgumentsObject::kCalleeOffset, function); Goto(&done); @@ -332,14 +316,11 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, { Comment("Empty JSSloppyArgumentsObject"); TNode<NativeContext> const native_context = LoadNativeContext(context); - TNode<Object> const map = - LoadContextElement(native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX); - Node* arguments; - Node* elements; - Node* unused; - std::tie(arguments, elements, unused) = AllocateArgumentsObject( - map, zero, nullptr, mode, JSSloppyArgumentsObject::kSize); - result.Bind(arguments); + TNode<Map> const map = CAST(LoadContextElement( + native_context, Context::SLOPPY_ARGUMENTS_MAP_INDEX)); + ArgumentsAllocationResult alloc_result = + AllocateArgumentsObject(map, zero, {}, JSSloppyArgumentsObject::kSize); + result = alloc_result.arguments_object; StoreObjectFieldNoWriteBarrier( result.value(), JSSloppyArgumentsObject::kCalleeOffset, function); Goto(&done); @@ -347,7 +328,7 @@ Node* ArgumentsBuiltinsAssembler::EmitFastNewSloppyArguments(Node* context, BIND(&runtime); { - result.Bind(CallRuntime(Runtime::kNewSloppyArguments, context, function)); + result = CAST(CallRuntime(Runtime::kNewSloppyArguments, context, function)); Goto(&done); } diff --git a/deps/v8/src/builtins/builtins-arguments-gen.h b/deps/v8/src/builtins/builtins-arguments-gen.h index 4eeae4bf866482..2565c3e81ff910 100644 --- a/deps/v8/src/builtins/builtins-arguments-gen.h +++ b/deps/v8/src/builtins/builtins-arguments-gen.h @@ -10,7 +10,7 @@ namespace v8 { namespace internal { -using Node = compiler::Node; +// TODO(v8:9396): these declarations pollute the v8::internal scope. using CodeAssemblerState = compiler::CodeAssemblerState; using CodeAssemblerLabel = compiler::CodeAssemblerLabel; @@ -19,19 +19,25 @@ class ArgumentsBuiltinsAssembler : public CodeStubAssembler { explicit ArgumentsBuiltinsAssembler(CodeAssemblerState* state) : CodeStubAssembler(state) {} - Node* EmitFastNewStrictArguments(Node* context, Node* function); - Node* EmitFastNewSloppyArguments(Node* context, Node* function); - Node* EmitFastNewRestParameter(Node* context, Node* function); + TNode<JSObject> EmitFastNewStrictArguments(TNode<Context> context, + TNode<JSFunction> function); + TNode<JSObject> EmitFastNewSloppyArguments(TNode<Context> context, + TNode<JSFunction> function); + TNode<JSObject> EmitFastNewRestParameter(TNode<Context> context, + TNode<JSFunction> function); private: + struct ArgumentsAllocationResult { + TNode<JSObject> arguments_object; + TNode<FixedArray> elements; + TNode<FixedArray> parameter_map; + }; // Allocates an an arguments (either rest, strict or sloppy) together with the // FixedArray elements for the arguments and a parameter map (for sloppy - // arguments only). A tuple is returned with pointers to the arguments object, - // the elements and parameter map in the form: - // <argument object, arguments FixedArray, parameter map or nullptr> - std::tuple<Node*, Node*, Node*> AllocateArgumentsObject( - Node* map, Node* arguments, Node* mapped_arguments, - ParameterMode param_mode, int base_size); + // arguments only, or empty TNode<> otherwise). + ArgumentsAllocationResult AllocateArgumentsObject( + TNode<Map> map, TNode<BInt> arguments, TNode<BInt> mapped_arguments, + int base_size); // For Rest parameters and Strict arguments, the copying of parameters from // the stack into the arguments object is straight-forward and shares much of @@ -40,11 +46,9 @@ class ArgumentsBuiltinsAssembler : public CodeStubAssembler { // and then copies |rest_count| arguments from the stack frame pointed to by // |frame_ptr| starting from |first_arg|. |arg_count| == |first_arg| + // |rest_count|. - Node* ConstructParametersObjectFromArgs(Node* map, Node* frame_ptr, - Node* arg_count, Node* first_arg, - Node* rest_count, - ParameterMode param_mode, - int base_size); + TNode<JSObject> ConstructParametersObjectFromArgs( + TNode<Map> map, TNode<RawPtrT> frame_ptr, TNode<BInt> arg_count, + TNode<BInt> first_arg, TNode<BInt> rest_count, int base_size); }; } // namespace internal diff --git a/deps/v8/src/builtins/builtins-array-gen.cc b/deps/v8/src/builtins/builtins-array-gen.cc index c7d8eb009125da..f176924ae5869b 100644 --- a/deps/v8/src/builtins/builtins-array-gen.cc +++ b/deps/v8/src/builtins/builtins-array-gen.cc @@ -25,10 +25,9 @@ using IteratorRecord = TorqueStructIteratorRecord; ArrayBuiltinsAssembler::ArrayBuiltinsAssembler( compiler::CodeAssemblerState* state) : CodeStubAssembler(state), - k_(this, MachineRepresentation::kTagged), - a_(this, MachineRepresentation::kTagged), - to_(this, MachineRepresentation::kTagged, SmiConstant(0)), - fully_spec_compliant_(this, {&k_, &a_, &to_}) {} + k_(this), + a_(this), + fully_spec_compliant_(this, {&k_, &a_}) {} void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() { // 6. Let A be ? TypedArraySpeciesCreate(O, len). @@ -44,14 +43,16 @@ void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() { LoadJSTypedArrayLength(a))); fast_typed_array_target_ = Word32Equal(LoadElementsKind(original_array), LoadElementsKind(a)); - a_.Bind(a); + a_ = a; } // See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map. -Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { +TNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor( + TNode<Object> k_value, TNode<Object> k) { // 8. c. Let mapped_value be ? Call(callbackfn, T, « kValue, k, O »). - Node* mapped_value = CallJS(CodeFactory::Call(isolate()), context(), - callbackfn(), this_arg(), k_value, k, o()); + TNode<Object> mapped_value = + CallJS(CodeFactory::Call(isolate()), context(), callbackfn(), this_arg(), + k_value, k, o()); Label fast(this), slow(this), done(this), detached(this, Label::kDeferred); // 8. d. Perform ? Set(A, Pk, mapped_value, true). @@ -65,7 +66,7 @@ Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { // 5. If arrayTypeName is "BigUint64Array" or "BigInt64Array", let // numValue be ? ToBigInt(v). // 6. Otherwise, let numValue be ? ToNumber(value). - Node* num_value; + TNode<Object> num_value; if (source_elements_kind_ == BIGINT64_ELEMENTS || source_elements_kind_ == BIGUINT64_ELEMENTS) { num_value = ToBigInt(context(), mapped_value); @@ -78,7 +79,7 @@ Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { Goto(&done); BIND(&slow); - SetPropertyStrict(context(), CAST(a()), CAST(k), CAST(mapped_value)); + SetPropertyStrict(context(), a(), k, mapped_value); Goto(&done); BIND(&detached); @@ -90,32 +91,7 @@ Node* ArrayBuiltinsAssembler::TypedArrayMapProcessor(Node* k_value, Node* k) { return a(); } -void ArrayBuiltinsAssembler::NullPostLoopAction() {} - -void ArrayBuiltinsAssembler::FillFixedArrayWithSmiZero(TNode<FixedArray> array, - TNode<Smi> smi_length) { - CSA_ASSERT(this, Word32BinaryNot(IsFixedDoubleArray(array))); - - TNode<IntPtrT> length = SmiToIntPtr(smi_length); - TNode<IntPtrT> byte_length = TimesTaggedSize(length); - CSA_ASSERT(this, UintPtrLessThan(length, byte_length)); - - static const int32_t fa_base_data_offset = - FixedArray::kHeaderSize - kHeapObjectTag; - TNode<IntPtrT> backing_store = IntPtrAdd(BitcastTaggedToWord(array), - IntPtrConstant(fa_base_data_offset)); - - // Call out to memset to perform initialization. - TNode<ExternalReference> memset = - ExternalConstant(ExternalReference::libc_memset_function()); - STATIC_ASSERT(kSizetSize == kIntptrSize); - CallCFunction(memset, MachineType::Pointer(), - std::make_pair(MachineType::Pointer(), backing_store), - std::make_pair(MachineType::IntPtr(), IntPtrConstant(0)), - std::make_pair(MachineType::UintPtr(), byte_length)); -} - -void ArrayBuiltinsAssembler::ReturnFromBuiltin(Node* value) { +void ArrayBuiltinsAssembler::ReturnFromBuiltin(TNode<Object> value) { if (argc_ == nullptr) { Return(value); } else { @@ -126,8 +102,8 @@ void ArrayBuiltinsAssembler::ReturnFromBuiltin(Node* value) { } void ArrayBuiltinsAssembler::InitIteratingArrayBuiltinBody( - TNode<Context> context, TNode<Object> receiver, Node* callbackfn, - Node* this_arg, TNode<IntPtrT> argc) { + TNode<Context> context, TNode<Object> receiver, TNode<Object> callbackfn, + TNode<Object> this_arg, TNode<IntPtrT> argc) { context_ = context; receiver_ = receiver; callbackfn_ = callbackfn; @@ -137,8 +113,7 @@ void ArrayBuiltinsAssembler::InitIteratingArrayBuiltinBody( void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( const char* name, const BuiltinResultGenerator& generator, - const CallResultProcessor& processor, const PostLoopAction& action, - ForEachDirection direction) { + const CallResultProcessor& processor, ForEachDirection direction) { name_ = name; // ValidateTypedArray: tc39.github.io/ecma262/#sec-validatetypedarray @@ -160,7 +135,7 @@ void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( Label throw_not_callable(this, Label::kDeferred); Label distinguish_types(this); GotoIf(TaggedIsSmi(callbackfn_), &throw_not_callable); - Branch(IsCallableMap(LoadMap(callbackfn_)), &distinguish_types, + Branch(IsCallableMap(LoadMap(CAST(callbackfn_))), &distinguish_types, &throw_not_callable); BIND(&throw_not_typed_array); @@ -192,9 +167,9 @@ void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( generator(this); if (direction == ForEachDirection::kForward) { - k_.Bind(SmiConstant(0)); + k_ = SmiConstant(0); } else { - k_.Bind(NumberDec(len())); + k_ = NumberDec(len()); } CSA_ASSERT(this, IsSafeInteger(k())); TNode<Int32T> elements_kind = LoadMapElementsKind(typed_array_map); @@ -214,26 +189,18 @@ void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody( Goto(&done); // No exception, return success BIND(&done); - action(this); ReturnFromBuiltin(a_.value()); } } void ArrayBuiltinsAssembler::VisitAllTypedArrayElements( - Node* array_buffer, const CallResultProcessor& processor, Label* detached, - ForEachDirection direction, TNode<JSTypedArray> typed_array) { - VariableList list({&a_, &k_, &to_}, zone()); - - FastLoopBody body = [&](Node* index) { - GotoIf(IsDetachedBuffer(CAST(array_buffer)), detached); - TNode<RawPtrT> data_ptr = LoadJSTypedArrayBackingStore(typed_array); - auto value = LoadFixedTypedArrayElementAsTagged( - data_ptr, index, source_elements_kind_, SMI_PARAMETERS); - k_.Bind(index); - a_.Bind(processor(this, value, index)); - }; - Node* start = SmiConstant(0); - Node* end = len_; + TNode<JSArrayBuffer> array_buffer, const CallResultProcessor& processor, + Label* detached, ForEachDirection direction, + TNode<JSTypedArray> typed_array) { + VariableList list({&a_, &k_}, zone()); + + TNode<Smi> start = SmiConstant(0); + TNode<Smi> end = CAST(len_); IndexAdvanceMode advance_mode = IndexAdvanceMode::kPost; int incr = 1; if (direction == ForEachDirection::kReverse) { @@ -241,54 +208,17 @@ void ArrayBuiltinsAssembler::VisitAllTypedArrayElements( advance_mode = IndexAdvanceMode::kPre; incr = -1; } - BuildFastLoop(list, start, end, body, incr, ParameterMode::SMI_PARAMETERS, - advance_mode); -} - -// Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate). -void ArrayBuiltinsAssembler::GenerateArraySpeciesCreate(TNode<Number> len) { - Label runtime(this, Label::kDeferred), done(this); - - TNode<Map> const original_map = LoadMap(o()); - GotoIfNot(InstanceTypeEqual(LoadMapInstanceType(original_map), JS_ARRAY_TYPE), - &runtime); - - GotoIfNot(IsPrototypeInitialArrayPrototype(context(), original_map), - &runtime); - - TNode<PropertyCell> species_protector = ArraySpeciesProtectorConstant(); - TNode<Object> value = - LoadObjectField(species_protector, PropertyCell::kValueOffset); - TNode<Smi> const protector_invalid = SmiConstant(Isolate::kProtectorInvalid); - GotoIf(TaggedEqual(value, protector_invalid), &runtime); - - GotoIfNot(TaggedIsPositiveSmi(len), &runtime); - GotoIfNot(IsValidFastJSArrayCapacity(len, CodeStubAssembler::SMI_PARAMETERS), - &runtime); - - // We need to be conservative and start with holey because the builtins - // that create output arrays aren't guaranteed to be called for every - // element in the input array (maybe the callback deletes an element). - const ElementsKind elements_kind = - GetHoleyElementsKind(GetInitialFastElementsKind()); - TNode<NativeContext> native_context = LoadNativeContext(context()); - TNode<Map> array_map = LoadJSArrayElementsMap(elements_kind, native_context); - a_.Bind(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, len, CAST(len), - nullptr, CodeStubAssembler::SMI_PARAMETERS, - kAllowLargeObjectAllocation)); - - Goto(&done); - - BIND(&runtime); - { - // 5. Let A be ? ArraySpeciesCreate(O, len). - TNode<JSReceiver> constructor = - CAST(CallRuntime(Runtime::kArraySpeciesConstructor, context(), o())); - a_.Bind(Construct(context(), constructor, len)); - Goto(&fully_spec_compliant_); - } - - BIND(&done); + BuildFastLoop<Smi>( + list, start, end, + [&](TNode<Smi> index) { + GotoIf(IsDetachedBuffer(array_buffer), detached); + TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(typed_array); + TNode<Numeric> value = LoadFixedTypedArrayElementAsTagged( + data_ptr, index, source_elements_kind_, SMI_PARAMETERS); + k_ = index; + a_ = processor(this, value, index); + }, + incr, advance_mode); } TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { @@ -297,7 +227,7 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); CSA_ASSERT(this, IsUndefined(Parameter(Descriptor::kJSNewTarget))); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); TNode<Object> receiver = args.GetReceiver(); Label runtime(this, Label::kDeferred); @@ -315,9 +245,7 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { BIND(&fast); { TNode<JSArray> array_receiver = CAST(receiver); - CSA_ASSERT(this, TaggedIsPositiveSmi(LoadJSArrayLength(array_receiver))); - TNode<IntPtrT> length = - LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset); + TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(array_receiver)); Label return_undefined(this), fast_elements(this); GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined); @@ -394,14 +322,12 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) { Label double_transition(this); Label runtime(this, Label::kDeferred); - // TODO(ishell): use constants from Descriptor once the JSFunction linkage - // arguments are reordered. TNode<Int32T> argc = UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); CSA_ASSERT(this, IsUndefined(Parameter(Descriptor::kJSNewTarget))); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); TNode<Object> receiver = args.GetReceiver(); TNode<JSArray> array_receiver; TNode<Int32T> kind; @@ -493,9 +419,9 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) { BIND(&default_label); { args.ForEach( - [this, array_receiver, context](Node* arg) { + [=](TNode<Object> arg) { TNode<Number> length = LoadJSArrayLength(array_receiver); - SetPropertyStrict(context, array_receiver, length, CAST(arg)); + SetPropertyStrict(context, array_receiver, length, arg); }, arg_index.value()); args.PopAndReturn(LoadJSArrayLength(array_receiver)); @@ -515,11 +441,10 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) { TF_BUILTIN(ExtractFastJSArray, ArrayBuiltinsAssembler) { ParameterMode mode = OptimalParameterMode(); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* array = Parameter(Descriptor::kSource); + TNode<JSArray> array = CAST(Parameter(Descriptor::kSource)); Node* begin = TaggedToParameter(Parameter(Descriptor::kBegin), mode); Node* count = TaggedToParameter(Parameter(Descriptor::kCount), mode); - CSA_ASSERT(this, IsJSArray(array)); CSA_ASSERT(this, Word32BinaryNot(IsNoElementsProtectorCellInvalid())); Return(ExtractFastJSArray(context, array, begin, count, mode)); @@ -555,7 +480,7 @@ TF_BUILTIN(CloneFastJSArrayFillingHoles, ArrayBuiltinsAssembler) { Word32BinaryNot(IsNoElementsProtectorCellInvalid()))); ParameterMode mode = OptimalParameterMode(); - Return(CloneFastJSArray(context, array, mode, nullptr, + Return(CloneFastJSArray(context, array, mode, {}, HoleConversionMode::kConvertToUndefined)); } @@ -584,9 +509,9 @@ class ArrayPopulatorAssembler : public CodeStubAssembler { TNode<Map> array_map = CAST(LoadContextElement( context, Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX)); - array = AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, SmiConstant(0), - SmiConstant(0), nullptr, - ParameterMode::SMI_PARAMETERS); + array = + AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, SmiConstant(0), + SmiConstant(0), {}, ParameterMode::SMI_PARAMETERS); Goto(&done); } @@ -626,7 +551,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) { TNode<Int32T> argc = UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); TNode<Object> items = args.GetOptionalArgumentValue(0); TNode<Object> receiver = args.GetReceiver(); @@ -810,8 +735,8 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) { GotoIf(IsUndefined(map_function), &next); CSA_ASSERT(this, IsCallable(CAST(map_function))); - value = CAST(CallJS(CodeFactory::Call(isolate()), context, map_function, - this_arg, value.value(), index.value())); + value = CallJS(CodeFactory::Call(isolate()), context, map_function, + this_arg, value.value(), index.value()); Goto(&next); BIND(&next); } @@ -846,8 +771,7 @@ TF_BUILTIN(TypedArrayPrototypeMap, ArrayBuiltinsAssembler) { GenerateIteratingTypedArrayBuiltinBody( "%TypedArray%.prototype.map", &ArrayBuiltinsAssembler::TypedArrayMapResultGenerator, - &ArrayBuiltinsAssembler::TypedArrayMapProcessor, - &ArrayBuiltinsAssembler::NullPostLoopAction); + &ArrayBuiltinsAssembler::TypedArrayMapProcessor); } TF_BUILTIN(ArrayIsArray, CodeStubAssembler) { @@ -884,15 +808,25 @@ class ArrayIncludesIndexofAssembler : public CodeStubAssembler { void Generate(SearchVariant variant, TNode<IntPtrT> argc, TNode<Context> context); - void GenerateSmiOrObject(SearchVariant variant, Node* context, Node* elements, - TNode<Object> search_element, Node* array_length, - Node* from_index); - void GeneratePackedDoubles(SearchVariant variant, Node* elements, - Node* search_element, Node* array_length, - Node* from_index); - void GenerateHoleyDoubles(SearchVariant variant, Node* elements, - Node* search_element, Node* array_length, - Node* from_index); + void GenerateSmiOrObject(SearchVariant variant, TNode<Context> context, + TNode<FixedArray> elements, + TNode<Object> search_element, + TNode<Smi> array_length, TNode<Smi> from_index); + void GeneratePackedDoubles(SearchVariant variant, + TNode<FixedDoubleArray> elements, + TNode<Object> search_element, + TNode<Smi> array_length, TNode<Smi> from_index); + void GenerateHoleyDoubles(SearchVariant variant, + TNode<FixedDoubleArray> elements, + TNode<Object> search_element, + TNode<Smi> array_length, TNode<Smi> from_index); + + void ReturnIfEmpty(TNode<Smi> length, TNode<Object> value) { + Label done(this); + GotoIf(SmiGreaterThan(length, SmiConstant(0)), &done); + Return(value); + BIND(&done); + } }; void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant, @@ -916,7 +850,7 @@ void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant, BranchIfFastJSArrayForRead(receiver, context, &init_index, &call_runtime); BIND(&init_index); - VARIABLE(index_var, MachineType::PointerRepresentation(), intptr_zero); + TVARIABLE(IntPtrT, index_var, intptr_zero); TNode<JSArray> array = CAST(receiver); // JSArray length is always a positive Smi for fast arrays. @@ -946,14 +880,14 @@ void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant, BIND(&is_smi); { TNode<IntPtrT> intptr_start_from = SmiUntag(CAST(start_from)); - index_var.Bind(intptr_start_from); + index_var = intptr_start_from; GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), intptr_zero), &done); // The fromIndex is negative: add it to the array's length. - index_var.Bind(IntPtrAdd(array_length_untagged, index_var.value())); + index_var = IntPtrAdd(array_length_untagged, index_var.value()); // Clamp negative results at zero. GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), intptr_zero), &done); - index_var.Bind(intptr_zero); + index_var = intptr_zero; Goto(&done); } BIND(&done); @@ -1031,8 +965,7 @@ void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant, BIND(&call_runtime); { - TNode<Object> start_from = - args.GetOptionalArgumentValue(kFromIndexArg, UndefinedConstant()); + TNode<Object> start_from = args.GetOptionalArgumentValue(kFromIndexArg); Runtime::FunctionId function = variant == kIncludes ? Runtime::kArrayIncludes_Slow : Runtime::kArrayIndexOf; @@ -1042,8 +975,9 @@ void ArrayIncludesIndexofAssembler::Generate(SearchVariant variant, } void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( - SearchVariant variant, Node* context, Node* elements, - TNode<Object> search_element, Node* array_length, Node* from_index) { + SearchVariant variant, TNode<Context> context, TNode<FixedArray> elements, + TNode<Object> search_element, TNode<Smi> array_length, + TNode<Smi> from_index) { TVARIABLE(IntPtrT, index_var, SmiUntag(from_index)); TVARIABLE(Float64T, search_num); TNode<IntPtrT> array_length_untagged = SmiUntag(array_length); @@ -1077,7 +1011,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged), &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); GotoIf(TaggedEqual(element_k, search_element), &return_found); Increment(&index_var); @@ -1090,7 +1024,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged), &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); GotoIf(IsUndefined(element_k), &return_found); GotoIf(IsTheHole(element_k), &return_found); @@ -1110,7 +1044,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged), &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); GotoIfNot(TaggedIsSmi(element_k), ¬_smi); Branch(Float64Equal(search_num.value(), SmiToFloat64(CAST(element_k))), &return_found, &continue_loop); @@ -1133,7 +1067,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged), &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); GotoIf(TaggedIsSmi(element_k), &continue_loop); GotoIfNot(IsHeapNumber(CAST(element_k)), &continue_loop); BranchIfFloat64IsNaN(LoadHeapNumberValue(CAST(element_k)), &return_found, @@ -1157,7 +1091,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( GotoIfNot(UintPtrLessThan(index_var.value(), array_length_untagged), &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); GotoIf(TaggedIsSmi(element_k), &continue_loop); GotoIf(TaggedEqual(search_element_string, element_k), &return_found); TNode<Uint16T> element_k_type = LoadInstanceType(CAST(element_k)); @@ -1186,7 +1120,7 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( &return_not_found); TNode<Object> element_k = - UnsafeLoadFixedArrayElement(CAST(elements), index_var.value()); + UnsafeLoadFixedArrayElement(elements, index_var.value()); Label continue_loop(this); GotoIf(TaggedIsSmi(element_k), &continue_loop); GotoIfNot(IsBigInt(CAST(element_k)), &continue_loop); @@ -1213,11 +1147,10 @@ void ArrayIncludesIndexofAssembler::GenerateSmiOrObject( } } -void ArrayIncludesIndexofAssembler::GeneratePackedDoubles(SearchVariant variant, - Node* elements, - Node* search_element, - Node* array_length, - Node* from_index) { +void ArrayIncludesIndexofAssembler::GeneratePackedDoubles( + SearchVariant variant, TNode<FixedDoubleArray> elements, + TNode<Object> search_element, TNode<Smi> array_length, + TNode<Smi> from_index) { TVARIABLE(IntPtrT, index_var, SmiUntag(from_index)); TNode<IntPtrT> array_length_untagged = SmiUntag(array_length); @@ -1228,13 +1161,13 @@ void ArrayIncludesIndexofAssembler::GeneratePackedDoubles(SearchVariant variant, search_num = Float64Constant(0); GotoIfNot(TaggedIsSmi(search_element), &search_notnan); - search_num = SmiToFloat64(search_element); + search_num = SmiToFloat64(CAST(search_element)); Goto(¬_nan_loop); BIND(&search_notnan); - GotoIfNot(IsHeapNumber(search_element), &return_not_found); + GotoIfNot(IsHeapNumber(CAST(search_element)), &return_not_found); - search_num = LoadHeapNumberValue(search_element); + search_num = LoadHeapNumberValue(CAST(search_element)); Label* nan_handling = variant == kIncludes ? &nan_loop : &return_not_found; BranchIfFloat64IsNaN(search_num.value(), nan_handling, ¬_nan_loop); @@ -1282,11 +1215,10 @@ void ArrayIncludesIndexofAssembler::GeneratePackedDoubles(SearchVariant variant, } } -void ArrayIncludesIndexofAssembler::GenerateHoleyDoubles(SearchVariant variant, - Node* elements, - Node* search_element, - Node* array_length, - Node* from_index) { +void ArrayIncludesIndexofAssembler::GenerateHoleyDoubles( + SearchVariant variant, TNode<FixedDoubleArray> elements, + TNode<Object> search_element, TNode<Smi> array_length, + TNode<Smi> from_index) { TVARIABLE(IntPtrT, index_var, SmiUntag(from_index)); TNode<IntPtrT> array_length_untagged = SmiUntag(array_length); @@ -1297,16 +1229,16 @@ void ArrayIncludesIndexofAssembler::GenerateHoleyDoubles(SearchVariant variant, search_num = Float64Constant(0); GotoIfNot(TaggedIsSmi(search_element), &search_notnan); - search_num = SmiToFloat64(search_element); + search_num = SmiToFloat64(CAST(search_element)); Goto(¬_nan_loop); BIND(&search_notnan); if (variant == kIncludes) { GotoIf(IsUndefined(search_element), &hole_loop); } - GotoIfNot(IsHeapNumber(search_element), &return_not_found); + GotoIfNot(IsHeapNumber(CAST(search_element)), &return_not_found); - search_num = LoadHeapNumberValue(search_element); + search_num = LoadHeapNumberValue(CAST(search_element)); Label* nan_handling = variant == kIncludes ? &nan_loop : &return_not_found; BranchIfFloat64IsNaN(search_num.value(), nan_handling, ¬_nan_loop); @@ -1387,32 +1319,34 @@ TF_BUILTIN(ArrayIncludes, ArrayIncludesIndexofAssembler) { TF_BUILTIN(ArrayIncludesSmiOrObject, ArrayIncludesIndexofAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* elements = Parameter(Descriptor::kElements); + TNode<FixedArray> elements = CAST(Parameter(Descriptor::kElements)); TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); GenerateSmiOrObject(kIncludes, context, elements, search_element, array_length, from_index); } TF_BUILTIN(ArrayIncludesPackedDoubles, ArrayIncludesIndexofAssembler) { - Node* elements = Parameter(Descriptor::kElements); - Node* search_element = Parameter(Descriptor::kSearchElement); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements)); + TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); - GeneratePackedDoubles(kIncludes, elements, search_element, array_length, + ReturnIfEmpty(array_length, FalseConstant()); + GeneratePackedDoubles(kIncludes, CAST(elements), search_element, array_length, from_index); } TF_BUILTIN(ArrayIncludesHoleyDoubles, ArrayIncludesIndexofAssembler) { - Node* elements = Parameter(Descriptor::kElements); - Node* search_element = Parameter(Descriptor::kSearchElement); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements)); + TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); - GenerateHoleyDoubles(kIncludes, elements, search_element, array_length, + ReturnIfEmpty(array_length, FalseConstant()); + GenerateHoleyDoubles(kIncludes, CAST(elements), search_element, array_length, from_index); } @@ -1426,32 +1360,34 @@ TF_BUILTIN(ArrayIndexOf, ArrayIncludesIndexofAssembler) { TF_BUILTIN(ArrayIndexOfSmiOrObject, ArrayIncludesIndexofAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* elements = Parameter(Descriptor::kElements); + TNode<FixedArray> elements = CAST(Parameter(Descriptor::kElements)); TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); GenerateSmiOrObject(kIndexOf, context, elements, search_element, array_length, from_index); } TF_BUILTIN(ArrayIndexOfPackedDoubles, ArrayIncludesIndexofAssembler) { - Node* elements = Parameter(Descriptor::kElements); - Node* search_element = Parameter(Descriptor::kSearchElement); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements)); + TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); - GeneratePackedDoubles(kIndexOf, elements, search_element, array_length, + ReturnIfEmpty(array_length, NumberConstant(-1)); + GeneratePackedDoubles(kIndexOf, CAST(elements), search_element, array_length, from_index); } TF_BUILTIN(ArrayIndexOfHoleyDoubles, ArrayIncludesIndexofAssembler) { - Node* elements = Parameter(Descriptor::kElements); - Node* search_element = Parameter(Descriptor::kSearchElement); - Node* array_length = Parameter(Descriptor::kLength); - Node* from_index = Parameter(Descriptor::kFromIndex); + TNode<FixedArrayBase> elements = CAST(Parameter(Descriptor::kElements)); + TNode<Object> search_element = CAST(Parameter(Descriptor::kSearchElement)); + TNode<Smi> array_length = CAST(Parameter(Descriptor::kLength)); + TNode<Smi> from_index = CAST(Parameter(Descriptor::kFromIndex)); - GenerateHoleyDoubles(kIndexOf, elements, search_element, array_length, + ReturnIfEmpty(array_length, NumberConstant(-1)); + GenerateHoleyDoubles(kIndexOf, CAST(elements), search_element, array_length, from_index); } @@ -1484,10 +1420,10 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { const char* method_name = "Array Iterator.prototype.next"; TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* iterator = Parameter(Descriptor::kReceiver); + TNode<Object> maybe_iterator = CAST(Parameter(Descriptor::kReceiver)); - VARIABLE(var_done, MachineRepresentation::kTagged, TrueConstant()); - VARIABLE(var_value, MachineRepresentation::kTagged, UndefinedConstant()); + TVARIABLE(Oddball, var_done, TrueConstant()); + TVARIABLE(Object, var_value, UndefinedConstant()); Label allocate_entry_if_needed(this); Label allocate_iterator_result(this); @@ -1497,9 +1433,11 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { // If O does not have all of the internal slots of an Array Iterator Instance // (22.1.5.3), throw a TypeError exception - ThrowIfNotInstanceType(context, iterator, JS_ARRAY_ITERATOR_TYPE, + ThrowIfNotInstanceType(context, maybe_iterator, JS_ARRAY_ITERATOR_TYPE, method_name); + TNode<JSArrayIterator> iterator = CAST(maybe_iterator); + // Let a be O.[[IteratedObject]]. TNode<JSReceiver> array = CAST(LoadObjectField(iterator, JSArrayIterator::kIteratedObjectOffset)); @@ -1531,8 +1469,8 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { iterator, JSArrayIterator::kNextIndexOffset, ChangeUint32ToTagged(Unsigned(Int32Add(index32, Int32Constant(1))))); - var_done.Bind(FalseConstant()); - var_value.Bind(index); + var_done = FalseConstant(); + var_value = index; GotoIf(Word32Equal(LoadAndUntagToWord32ObjectField( iterator, JSArrayIterator::kKindOffset), @@ -1543,9 +1481,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { TNode<Int32T> elements_kind = LoadMapElementsKind(array_map); TNode<FixedArrayBase> elements = LoadElements(CAST(array)); GotoIfForceSlowPath(&if_generic); - var_value.Bind(LoadFixedArrayBaseElementAsTagged( + var_value = LoadFixedArrayBaseElementAsTagged( elements, Signed(ChangeUint32ToWord(index32)), elements_kind, - &if_generic, &if_hole)); + &if_generic, &if_hole); Goto(&allocate_entry_if_needed); BIND(&if_hole); @@ -1553,7 +1491,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { GotoIf(IsNoElementsProtectorCellInvalid(), &if_generic); GotoIfNot(IsPrototypeInitialArrayPrototype(context, array_map), &if_generic); - var_value.Bind(UndefinedConstant()); + var_value = UndefinedConstant(); Goto(&allocate_entry_if_needed); } } @@ -1572,8 +1510,8 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, NumberInc(index)); - var_done.Bind(FalseConstant()); - var_value.Bind(index); + var_done = FalseConstant(); + var_value = index; Branch(Word32Equal(LoadAndUntagToWord32ObjectField( iterator, JSArrayIterator::kKindOffset), @@ -1609,7 +1547,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { BIND(&if_generic); { - var_value.Bind(GetProperty(context, array, index)); + var_value = GetProperty(context, array, index); Goto(&allocate_entry_if_needed); } @@ -1632,8 +1570,8 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset, SmiInc(CAST(index))); - var_done.Bind(FalseConstant()); - var_value.Bind(index); + var_done = FalseConstant(); + var_value = index; GotoIf(Word32Equal(LoadAndUntagToWord32ObjectField( iterator, JSArrayIterator::kKindOffset), @@ -1641,9 +1579,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { &allocate_iterator_result); TNode<Int32T> elements_kind = LoadMapElementsKind(array_map); - TNode<RawPtrT> data_ptr = LoadJSTypedArrayBackingStore(CAST(array)); - var_value.Bind(LoadFixedTypedArrayElementAsTagged(data_ptr, CAST(index), - elements_kind)); + TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(array)); + var_value = LoadFixedTypedArrayElementAsTagged(data_ptr, CAST(index), + elements_kind); Goto(&allocate_entry_if_needed); } @@ -1654,7 +1592,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { Int32Constant(static_cast<int>(IterationKind::kValues))), &allocate_iterator_result); - Node* result = + TNode<JSObject> result = AllocateJSIteratorResultForEntry(context, index, var_value.value()); Return(result); } @@ -1673,29 +1611,28 @@ class ArrayFlattenAssembler : public CodeStubAssembler { : CodeStubAssembler(state) {} // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray - Node* FlattenIntoArray(Node* context, Node* target, Node* source, - Node* source_length, Node* start, Node* depth, - Node* mapper_function = nullptr, - Node* this_arg = nullptr) { - CSA_ASSERT(this, IsJSReceiver(target)); - CSA_ASSERT(this, IsJSReceiver(source)); + TNode<Number> FlattenIntoArray( + TNode<Context> context, TNode<JSReceiver> target, + TNode<JSReceiver> source, TNode<Number> source_length, + TNode<Number> start, TNode<Number> depth, + base::Optional<TNode<HeapObject>> mapper_function = base::nullopt, + base::Optional<TNode<Object>> this_arg = base::nullopt) { CSA_ASSERT(this, IsNumberPositive(source_length)); CSA_ASSERT(this, IsNumberPositive(start)); - CSA_ASSERT(this, IsNumber(depth)); // 1. Let targetIndex be start. - VARIABLE(var_target_index, MachineRepresentation::kTagged, start); + TVARIABLE(Number, var_target_index, start); // 2. Let sourceIndex be 0. - VARIABLE(var_source_index, MachineRepresentation::kTagged, SmiConstant(0)); + TVARIABLE(Number, var_source_index, SmiConstant(0)); // 3. Repeat... Label loop(this, {&var_target_index, &var_source_index}), done_loop(this); Goto(&loop); BIND(&loop); { - Node* const source_index = var_source_index.value(); - Node* const target_index = var_target_index.value(); + TNode<Number> source_index = var_source_index.value(); + TNode<Number> target_index = var_target_index.value(); // ...while sourceIndex < sourceLen GotoIfNumberGreaterThanOrEqual(source_index, source_length, &done_loop); @@ -1716,16 +1653,16 @@ class ArrayFlattenAssembler : public CodeStubAssembler { GetProperty(context, source, source_index); // ii. If mapperFunction is present, then - if (mapper_function != nullptr) { - CSA_ASSERT(this, Word32Or(IsUndefined(mapper_function), - IsCallable(mapper_function))); - DCHECK_NOT_NULL(this_arg); + if (mapper_function) { + CSA_ASSERT(this, Word32Or(IsUndefined(mapper_function.value()), + IsCallable(mapper_function.value()))); + DCHECK(this_arg.has_value()); // 1. Set element to ? Call(mapperFunction, thisArg , « element, // sourceIndex, source »). - element_maybe_smi = CAST( - CallJS(CodeFactory::Call(isolate()), context, mapper_function, - this_arg, element_maybe_smi, source_index, source)); + element_maybe_smi = CallJS(CodeFactory::Call(isolate()), context, + mapper_function.value(), this_arg.value(), + element_maybe_smi, source_index, source); } // iii. Let shouldFlatten be false. @@ -1752,7 +1689,7 @@ class ArrayFlattenAssembler : public CodeStubAssembler { // 2. Set targetIndex to ? FlattenIntoArray(target, element, // elementLen, targetIndex, // depth - 1). - var_target_index.Bind( + var_target_index = CAST( CallBuiltin(Builtins::kFlattenIntoArray, context, target, element, element_length, target_index, NumberDec(depth))); Goto(&next); @@ -1769,7 +1706,7 @@ class ArrayFlattenAssembler : public CodeStubAssembler { // 2. Set targetIndex to ? FlattenIntoArray(target, element, // elementLen, targetIndex, // depth - 1). - var_target_index.Bind( + var_target_index = CAST( CallBuiltin(Builtins::kFlattenIntoArray, context, target, element, element_length, target_index, NumberDec(depth))); Goto(&next); @@ -1789,7 +1726,7 @@ class ArrayFlattenAssembler : public CodeStubAssembler { target_index, element); // 3. Increase targetIndex by 1. - var_target_index.Bind(NumberInc(target_index)); + var_target_index = NumberInc(target_index); Goto(&next); BIND(&throw_error); @@ -1800,7 +1737,7 @@ class ArrayFlattenAssembler : public CodeStubAssembler { BIND(&next); // d. Increase sourceIndex by 1. - var_source_index.Bind(NumberInc(source_index)); + var_source_index = NumberInc(source_index); Goto(&loop); } @@ -1811,16 +1748,16 @@ class ArrayFlattenAssembler : public CodeStubAssembler { // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray TF_BUILTIN(FlattenIntoArray, ArrayFlattenAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const target = Parameter(Descriptor::kTarget); - Node* const source = Parameter(Descriptor::kSource); - Node* const source_length = Parameter(Descriptor::kSourceLength); - Node* const start = Parameter(Descriptor::kStart); - Node* const depth = Parameter(Descriptor::kDepth); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<JSReceiver> target = CAST(Parameter(Descriptor::kTarget)); + TNode<JSReceiver> source = CAST(Parameter(Descriptor::kSource)); + TNode<Number> source_length = CAST(Parameter(Descriptor::kSourceLength)); + TNode<Number> start = CAST(Parameter(Descriptor::kStart)); + TNode<Number> depth = CAST(Parameter(Descriptor::kDepth)); // FlattenIntoArray might get called recursively, check stack for overflow // manually as it has stub linkage. - PerformStackCheck(CAST(context)); + PerformStackCheck(context); Return( FlattenIntoArray(context, target, source, source_length, start, depth)); @@ -1828,14 +1765,15 @@ TF_BUILTIN(FlattenIntoArray, ArrayFlattenAssembler) { // https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray TF_BUILTIN(FlatMapIntoArray, ArrayFlattenAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const target = Parameter(Descriptor::kTarget); - Node* const source = Parameter(Descriptor::kSource); - Node* const source_length = Parameter(Descriptor::kSourceLength); - Node* const start = Parameter(Descriptor::kStart); - Node* const depth = Parameter(Descriptor::kDepth); - Node* const mapper_function = Parameter(Descriptor::kMapperFunction); - Node* const this_arg = Parameter(Descriptor::kThisArg); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<JSReceiver> target = CAST(Parameter(Descriptor::kTarget)); + TNode<JSReceiver> source = CAST(Parameter(Descriptor::kSource)); + TNode<Number> source_length = CAST(Parameter(Descriptor::kSourceLength)); + TNode<Number> start = CAST(Parameter(Descriptor::kStart)); + TNode<Number> depth = CAST(Parameter(Descriptor::kDepth)); + TNode<HeapObject> mapper_function = + CAST(Parameter(Descriptor::kMapperFunction)); + TNode<Object> this_arg = CAST(Parameter(Descriptor::kThisArg)); Return(FlattenIntoArray(context, target, source, source_length, start, depth, mapper_function, this_arg)); @@ -2127,8 +2065,9 @@ TF_BUILTIN(ArrayConstructorImpl, ArrayBuiltinsAssembler) { } void ArrayBuiltinsAssembler::GenerateConstructor( - Node* context, Node* array_function, Node* array_map, Node* array_size, - Node* allocation_site, ElementsKind elements_kind, + TNode<Context> context, TNode<HeapObject> array_function, + TNode<Map> array_map, TNode<Object> array_size, + TNode<HeapObject> allocation_site, ElementsKind elements_kind, AllocationSiteMode mode) { Label ok(this); Label smi_size(this); @@ -2138,33 +2077,37 @@ void ArrayBuiltinsAssembler::GenerateConstructor( Branch(TaggedIsSmi(array_size), &smi_size, &call_runtime); BIND(&smi_size); - - if (IsFastPackedElementsKind(elements_kind)) { - Label abort(this, Label::kDeferred); - Branch(SmiEqual(CAST(array_size), SmiConstant(0)), &small_smi_size, &abort); - - BIND(&abort); - TNode<Smi> reason = - SmiConstant(AbortReason::kAllocatingNonEmptyPackedArray); - TailCallRuntime(Runtime::kAbort, context, reason); - } else { - int element_size = - IsDoubleElementsKind(elements_kind) ? kDoubleSize : kTaggedSize; - int max_fast_elements = - (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - JSArray::kSize - - AllocationMemento::kSize) / - element_size; - Branch(SmiAboveOrEqual(CAST(array_size), SmiConstant(max_fast_elements)), - &call_runtime, &small_smi_size); - } - - BIND(&small_smi_size); { - TNode<JSArray> array = AllocateJSArray( - elements_kind, CAST(array_map), array_size, CAST(array_size), - mode == DONT_TRACK_ALLOCATION_SITE ? nullptr : allocation_site, - CodeStubAssembler::SMI_PARAMETERS); - Return(array); + TNode<Smi> array_size_smi = CAST(array_size); + + if (IsFastPackedElementsKind(elements_kind)) { + Label abort(this, Label::kDeferred); + Branch(SmiEqual(array_size_smi, SmiConstant(0)), &small_smi_size, &abort); + + BIND(&abort); + TNode<Smi> reason = + SmiConstant(AbortReason::kAllocatingNonEmptyPackedArray); + TailCallRuntime(Runtime::kAbort, context, reason); + } else { + int element_size = + IsDoubleElementsKind(elements_kind) ? kDoubleSize : kTaggedSize; + int max_fast_elements = + (kMaxRegularHeapObjectSize - FixedArray::kHeaderSize - + JSArray::kSize - AllocationMemento::kSize) / + element_size; + Branch(SmiAboveOrEqual(array_size_smi, SmiConstant(max_fast_elements)), + &call_runtime, &small_smi_size); + } + + BIND(&small_smi_size); + { + TNode<JSArray> array = AllocateJSArray( + elements_kind, array_map, array_size_smi, array_size_smi, + mode == DONT_TRACK_ALLOCATION_SITE ? TNode<AllocationSite>() + : CAST(allocation_site), + CodeStubAssembler::SMI_PARAMETERS); + Return(array); + } } BIND(&call_runtime); @@ -2181,8 +2124,9 @@ void ArrayBuiltinsAssembler::GenerateArrayNoArgumentConstructor( Parameter(Descriptor::kFunction), JSFunction::kContextOffset)); bool track_allocation_site = AllocationSite::ShouldTrack(kind) && mode != DISABLE_ALLOCATION_SITES; - Node* allocation_site = - track_allocation_site ? Parameter(Descriptor::kAllocationSite) : nullptr; + TNode<AllocationSite> allocation_site = + track_allocation_site ? CAST(Parameter(Descriptor::kAllocationSite)) + : TNode<AllocationSite>(); TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context); TNode<JSArray> array = AllocateJSArray( kind, array_map, IntPtrConstant(JSArray::kPreallocatedArrayElements), @@ -2194,7 +2138,7 @@ void ArrayBuiltinsAssembler::GenerateArraySingleArgumentConstructor( ElementsKind kind, AllocationSiteOverrideMode mode) { using Descriptor = ArraySingleArgumentConstructorDescriptor; TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* function = Parameter(Descriptor::kFunction); + TNode<HeapObject> function = CAST(Parameter(Descriptor::kFunction)); TNode<NativeContext> native_context = CAST(LoadObjectField(function, JSFunction::kContextOffset)); TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context); @@ -2206,8 +2150,11 @@ void ArrayBuiltinsAssembler::GenerateArraySingleArgumentConstructor( : DONT_TRACK_ALLOCATION_SITE; } - Node* array_size = Parameter(Descriptor::kArraySizeSmiParameter); - Node* allocation_site = Parameter(Descriptor::kAllocationSite); + TNode<Object> array_size = + CAST(Parameter(Descriptor::kArraySizeSmiParameter)); + // allocation_site can be Undefined or an AllocationSite + TNode<HeapObject> allocation_site = + CAST(Parameter(Descriptor::kAllocationSite)); GenerateConstructor(context, function, array_map, array_size, allocation_site, kind, allocation_site_mode); @@ -2219,7 +2166,7 @@ void ArrayBuiltinsAssembler::GenerateArrayNArgumentsConstructor( // Replace incoming JS receiver argument with the target. // TODO(ishell): Avoid replacing the target on the stack and just add it // as another additional parameter for Runtime::kNewArray. - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); args.SetReceiver(target); // Adjust arguments count for the runtime call: +1 for implicit receiver diff --git a/deps/v8/src/builtins/builtins-array-gen.h b/deps/v8/src/builtins/builtins-array-gen.h index 6b8c704038fe39..a19ba1a5da1baa 100644 --- a/deps/v8/src/builtins/builtins-array-gen.h +++ b/deps/v8/src/builtins/builtins-array-gen.h @@ -17,51 +17,13 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler { using BuiltinResultGenerator = std::function<void(ArrayBuiltinsAssembler* masm)>; - using CallResultProcessor = std::function<Node*(ArrayBuiltinsAssembler* masm, - Node* k_value, Node* k)>; - - using PostLoopAction = std::function<void(ArrayBuiltinsAssembler* masm)>; - - void FindResultGenerator(); - - Node* FindProcessor(Node* k_value, Node* k); - - void FindIndexResultGenerator(); - - Node* FindIndexProcessor(Node* k_value, Node* k); - - void ForEachResultGenerator(); - - Node* ForEachProcessor(Node* k_value, Node* k); - - void SomeResultGenerator(); - - Node* SomeProcessor(Node* k_value, Node* k); - - void EveryResultGenerator(); - - Node* EveryProcessor(Node* k_value, Node* k); - - void ReduceResultGenerator(); - - Node* ReduceProcessor(Node* k_value, Node* k); - - void ReducePostLoopAction(); + using CallResultProcessor = std::function<TNode<Object>( + ArrayBuiltinsAssembler* masm, TNode<Object> k_value, TNode<Object> k)>; void TypedArrayMapResultGenerator(); - Node* SpecCompliantMapProcessor(Node* k_value, Node* k); - - Node* FastMapProcessor(Node* k_value, Node* k); - // See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map. - Node* TypedArrayMapProcessor(Node* k_value, Node* k); - - void NullPostLoopAction(); - - // Uses memset to effectively initialize the given FixedArray with Smi zeroes. - void FillFixedArrayWithSmiZero(TNode<FixedArray> array, - TNode<Smi> smi_length); + TNode<Object> TypedArrayMapProcessor(TNode<Object> k_value, TNode<Object> k); TNode<String> CallJSArrayArrayJoinConcatToSequentialString( TNode<FixedArray> fixed_array, TNode<IntPtrT> length, TNode<String> sep, @@ -86,20 +48,22 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler { TNode<IntPtrT> argc() { return argc_; } TNode<JSReceiver> o() { return o_; } TNode<Number> len() { return len_; } - Node* callbackfn() { return callbackfn_; } - Node* this_arg() { return this_arg_; } - TNode<Number> k() { return CAST(k_.value()); } - Node* a() { return a_.value(); } + TNode<Object> callbackfn() { return callbackfn_; } + TNode<Object> this_arg() { return this_arg_; } + TNode<Number> k() { return k_.value(); } + TNode<Object> a() { return a_.value(); } - void ReturnFromBuiltin(Node* value); + void ReturnFromBuiltin(TNode<Object> value); void InitIteratingArrayBuiltinBody(TNode<Context> context, - TNode<Object> receiver, Node* callbackfn, - Node* this_arg, TNode<IntPtrT> argc); + TNode<Object> receiver, + TNode<Object> callbackfn, + TNode<Object> this_arg, + TNode<IntPtrT> argc); void GenerateIteratingTypedArrayBuiltinBody( const char* name, const BuiltinResultGenerator& generator, - const CallResultProcessor& processor, const PostLoopAction& action, + const CallResultProcessor& processor, ForEachDirection direction = ForEachDirection::kForward); void TailCallArrayConstructorStub( @@ -107,23 +71,25 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler { TNode<JSFunction> target, TNode<HeapObject> allocation_site_or_undefined, TNode<Int32T> argc); - void GenerateDispatchToArrayStub( - TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc, - AllocationSiteOverrideMode mode, - TNode<AllocationSite> allocation_site = TNode<AllocationSite>()); + void GenerateDispatchToArrayStub(TNode<Context> context, + TNode<JSFunction> target, TNode<Int32T> argc, + AllocationSiteOverrideMode mode, + TNode<AllocationSite> allocation_site = {}); void CreateArrayDispatchNoArgument( TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc, AllocationSiteOverrideMode mode, - TNode<AllocationSite> allocation_site = TNode<AllocationSite>()); + TNode<AllocationSite> allocation_site = {}); void CreateArrayDispatchSingleArgument( TNode<Context> context, TNode<JSFunction> target, TNode<Int32T> argc, AllocationSiteOverrideMode mode, - TNode<AllocationSite> allocation_site = TNode<AllocationSite>()); + TNode<AllocationSite> allocation_site = {}); - void GenerateConstructor(Node* context, Node* array_function, Node* array_map, - Node* array_size, Node* allocation_site, + void GenerateConstructor(TNode<Context> context, + TNode<HeapObject> array_function, + TNode<Map> array_map, TNode<Object> array_size, + TNode<HeapObject> allocation_site, ElementsKind elements_kind, AllocationSiteMode mode); void GenerateArrayNoArgumentConstructor(ElementsKind kind, AllocationSiteOverrideMode mode); @@ -135,33 +101,22 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler { TNode<HeapObject> maybe_allocation_site); private: - static ElementsKind ElementsKindForInstanceType(InstanceType type); - - void VisitAllTypedArrayElements(Node* array_buffer, + void VisitAllTypedArrayElements(TNode<JSArrayBuffer> array_buffer, const CallResultProcessor& processor, Label* detached, ForEachDirection direction, TNode<JSTypedArray> typed_array); - // Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate). - // This version is specialized to create a zero length array - // of the elements kind of the input array. - void GenerateArraySpeciesCreate(); - - // Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate). - void GenerateArraySpeciesCreate(TNode<Number> len); - - Node* callbackfn_ = nullptr; + TNode<Object> callbackfn_; TNode<JSReceiver> o_; - Node* this_arg_ = nullptr; + TNode<Object> this_arg_; TNode<Number> len_; TNode<Context> context_; TNode<Object> receiver_; TNode<IntPtrT> argc_; - Node* fast_typed_array_target_ = nullptr; + TNode<BoolT> fast_typed_array_target_; const char* name_ = nullptr; - Variable k_; - Variable a_; - Variable to_; + TVariable<Number> k_; + TVariable<Object> a_; Label fully_spec_compliant_; ElementsKind source_elements_kind_ = ElementsKind::NO_ELEMENTS; }; diff --git a/deps/v8/src/builtins/builtins-array.cc b/deps/v8/src/builtins/builtins-array.cc index 6c3e7246492157..8002c069962a10 100644 --- a/deps/v8/src/builtins/builtins-array.cc +++ b/deps/v8/src/builtins/builtins-array.cc @@ -1189,7 +1189,8 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver, static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) { HandleScope handle_scope(isolate); if (!obj->IsJSReceiver()) return Just(false); - if (!isolate->IsIsConcatSpreadableLookupChainIntact(JSReceiver::cast(*obj))) { + if (!Protectors::IsIsConcatSpreadableLookupChainIntact(isolate) || + JSReceiver::cast(*obj).HasProxyInPrototype(isolate)) { // Slow path if @@isConcatSpreadable has been used. Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol()); Handle<Object> value; @@ -1258,7 +1259,7 @@ Object Slow_ArrayConcat(BuiltinArguments* args, Handle<Object> species, // dictionary. bool fast_case = is_array_species && (estimate_nof * 2) >= estimate_result_length && - isolate->IsIsConcatSpreadableLookupChainIntact(); + Protectors::IsIsConcatSpreadableLookupChainIntact(isolate); if (fast_case && kind == PACKED_DOUBLE_ELEMENTS) { Handle<FixedArrayBase> storage = @@ -1406,7 +1407,7 @@ bool IsSimpleArray(Isolate* isolate, Handle<JSArray> obj) { MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, BuiltinArguments* args) { - if (!isolate->IsIsConcatSpreadableLookupChainIntact()) { + if (!Protectors::IsIsConcatSpreadableLookupChainIntact(isolate)) { return MaybeHandle<JSArray>(); } // We shouldn't overflow when adding another len. diff --git a/deps/v8/src/builtins/builtins-arraybuffer.cc b/deps/v8/src/builtins/builtins-arraybuffer.cc index 9ecb1815bcc457..b062b9ca3ce166 100644 --- a/deps/v8/src/builtins/builtins-arraybuffer.cc +++ b/deps/v8/src/builtins/builtins-arraybuffer.cc @@ -30,29 +30,38 @@ namespace { Object ConstructBuffer(Isolate* isolate, Handle<JSFunction> target, Handle<JSReceiver> new_target, Handle<Object> length, - bool initialize) { + InitializedFlag initialized) { + SharedFlag shared = (*target != target->native_context().array_buffer_fun()) + ? SharedFlag::kShared + : SharedFlag::kNotShared; Handle<JSObject> result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, JSObject::New(target, new_target, Handle<AllocationSite>::null())); + auto array_buffer = Handle<JSArrayBuffer>::cast(result); + // Ensure that all fields are initialized because BackingStore::Allocate is + // allowed to GC. Note that we cannot move the allocation of the ArrayBuffer + // after BackingStore::Allocate because of the spec. + array_buffer->Setup(shared, nullptr); + size_t byte_length; if (!TryNumberToSize(*length, &byte_length) || byte_length > JSArrayBuffer::kMaxByteLength) { - JSArrayBuffer::SetupAsEmpty(Handle<JSArrayBuffer>::cast(result), isolate); + // ToNumber failed. THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); } - SharedFlag shared_flag = - (*target == target->native_context().array_buffer_fun()) - ? SharedFlag::kNotShared - : SharedFlag::kShared; - if (!JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer>::cast(result), - isolate, byte_length, initialize, - shared_flag)) { + + auto backing_store = + BackingStore::Allocate(isolate, byte_length, shared, initialized); + if (!backing_store) { + // Allocation of backing store failed. THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewRangeError(MessageTemplate::kArrayBufferAllocationFailed)); } - return *result; + + array_buffer->Attach(std::move(backing_store)); + return *array_buffer; } } // namespace @@ -80,7 +89,8 @@ BUILTIN(ArrayBufferConstructor) { isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); } - return ConstructBuffer(isolate, target, new_target, number_length, true); + return ConstructBuffer(isolate, target, new_target, number_length, + InitializedFlag::kZeroInitialized); } // This is a helper to construct an ArrayBuffer with uinitialized memory. @@ -91,7 +101,8 @@ BUILTIN(ArrayBufferConstructor_DoNotInitialize) { Handle<JSFunction> target(isolate->native_context()->array_buffer_fun(), isolate); Handle<Object> length = args.atOrUndefined(isolate, 1); - return ConstructBuffer(isolate, target, target, length, false); + return ConstructBuffer(isolate, target, target, length, + InitializedFlag::kUninitialized); } // ES6 section 24.1.4.1 get ArrayBuffer.prototype.byteLength diff --git a/deps/v8/src/builtins/builtins-async-function-gen.cc b/deps/v8/src/builtins/builtins-async-function-gen.cc index 6ac37da3f6f6e9..cfd355724e1409 100644 --- a/deps/v8/src/builtins/builtins-async-function-gen.cc +++ b/deps/v8/src/builtins/builtins-async-function-gen.cc @@ -263,7 +263,7 @@ void AsyncFunctionBuiltinsAssembler::AsyncFunctionAwait( TNode<Object> value = CAST(Parameter(Descriptor::kValue)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - TNode<Object> outer_promise = LoadObjectField( + TNode<JSPromise> outer_promise = LoadObjectField<JSPromise>( async_function_object, JSAsyncFunctionObject::kPromiseOffset); Label after_debug_hook(this), call_debug_hook(this, Label::kDeferred); diff --git a/deps/v8/src/builtins/builtins-async-gen.cc b/deps/v8/src/builtins/builtins-async-gen.cc index 70d4eac9c8be28..edcb0272265cde 100644 --- a/deps/v8/src/builtins/builtins-async-gen.cc +++ b/deps/v8/src/builtins/builtins-async-gen.cc @@ -6,6 +6,7 @@ #include "src/builtins/builtins-utils-gen.h" #include "src/heap/factory-inl.h" +#include "src/objects/js-generator.h" #include "src/objects/js-promise.h" #include "src/objects/shared-function-info.h" @@ -23,11 +24,12 @@ class ValueUnwrapContext { } // namespace -Node* AsyncBuiltinsAssembler::AwaitOld(Node* context, Node* generator, - Node* value, Node* outer_promise, - Node* on_resolve_context_index, - Node* on_reject_context_index, - Node* is_predicted_as_caught) { +TNode<Object> AsyncBuiltinsAssembler::AwaitOld( + TNode<Context> context, TNode<JSGeneratorObject> generator, + TNode<Object> value, TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught) { TNode<NativeContext> const native_context = LoadNativeContext(context); static const int kWrappedPromiseOffset = @@ -91,8 +93,7 @@ Node* AsyncBuiltinsAssembler::AwaitOld(Node* context, Node* generator, InitializeNativeClosure(closure_context, native_context, on_reject, on_reject_context_index); - VARIABLE(var_throwaway, MachineRepresentation::kTaggedPointer, - UndefinedConstant()); + TVARIABLE(HeapObject, var_throwaway, UndefinedConstant()); // Deal with PromiseHooks and debug support in the runtime. This // also allocates the throwaway promise, which is only needed in @@ -101,9 +102,9 @@ Node* AsyncBuiltinsAssembler::AwaitOld(Node* context, Node* generator, Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), &if_debugging, &do_resolve_promise); BIND(&if_debugging); - var_throwaway.Bind(CallRuntime(Runtime::kAwaitPromisesInitOld, context, value, - wrapped_value, outer_promise, on_reject, - is_predicted_as_caught)); + var_throwaway = CAST(CallRuntime(Runtime::kAwaitPromisesInitOld, context, + value, wrapped_value, outer_promise, + on_reject, is_predicted_as_caught)); Goto(&do_resolve_promise); BIND(&do_resolve_promise); @@ -114,13 +115,13 @@ Node* AsyncBuiltinsAssembler::AwaitOld(Node* context, Node* generator, on_resolve, on_reject, var_throwaway.value()); } -Node* AsyncBuiltinsAssembler::AwaitOptimized(Node* context, Node* generator, - Node* promise, Node* outer_promise, - Node* on_resolve_context_index, - Node* on_reject_context_index, - Node* is_predicted_as_caught) { +TNode<Object> AsyncBuiltinsAssembler::AwaitOptimized( + TNode<Context> context, TNode<JSGeneratorObject> generator, + TNode<JSPromise> promise, TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught) { TNode<NativeContext> const native_context = LoadNativeContext(context); - CSA_ASSERT(this, IsJSPromise(promise)); static const int kResolveClosureOffset = FixedArray::SizeFor(Context::MIN_CONTEXT_SLOTS); @@ -130,8 +131,8 @@ Node* AsyncBuiltinsAssembler::AwaitOptimized(Node* context, Node* generator, kRejectClosureOffset + JSFunction::kSizeWithoutPrototype; // 2. Let promise be ? PromiseResolve(« promise »). - // Node* const promise = - // CallBuiltin(Builtins::kPromiseResolve, context, promise_fun, value); + // We skip this step, because promise is already guaranteed to be a + // JSPRomise at this point. TNode<HeapObject> base = AllocateInNewSpace(kTotalSize); TNode<Context> closure_context = UncheckedCast<Context>(base); @@ -162,8 +163,7 @@ Node* AsyncBuiltinsAssembler::AwaitOptimized(Node* context, Node* generator, InitializeNativeClosure(closure_context, native_context, on_reject, on_reject_context_index); - VARIABLE(var_throwaway, MachineRepresentation::kTaggedPointer, - UndefinedConstant()); + TVARIABLE(HeapObject, var_throwaway, UndefinedConstant()); // Deal with PromiseHooks and debug support in the runtime. This // also allocates the throwaway promise, which is only needed in @@ -172,9 +172,9 @@ Node* AsyncBuiltinsAssembler::AwaitOptimized(Node* context, Node* generator, Branch(IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate(), &if_debugging, &do_perform_promise_then); BIND(&if_debugging); - var_throwaway.Bind(CallRuntime(Runtime::kAwaitPromisesInit, context, promise, - promise, outer_promise, on_reject, - is_predicted_as_caught)); + var_throwaway = + CAST(CallRuntime(Runtime::kAwaitPromisesInit, context, promise, promise, + outer_promise, on_reject, is_predicted_as_caught)); Goto(&do_perform_promise_then); BIND(&do_perform_promise_then); @@ -182,12 +182,13 @@ Node* AsyncBuiltinsAssembler::AwaitOptimized(Node* context, Node* generator, on_resolve, on_reject, var_throwaway.value()); } -Node* AsyncBuiltinsAssembler::Await(Node* context, Node* generator, Node* value, - Node* outer_promise, - Node* on_resolve_context_index, - Node* on_reject_context_index, - Node* is_predicted_as_caught) { - VARIABLE(result, MachineRepresentation::kTagged); +TNode<Object> AsyncBuiltinsAssembler::Await( + TNode<Context> context, TNode<JSGeneratorObject> generator, + TNode<Object> value, TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught) { + TVARIABLE(Object, result); Label if_old(this), if_new(this), done(this), if_slow_constructor(this, Label::kDeferred); @@ -197,7 +198,8 @@ Node* AsyncBuiltinsAssembler::Await(Node* context, Node* generator, Node* value, // to allocate the wrapper promise and can just use the `AwaitOptimized` // logic. GotoIf(TaggedIsSmi(value), &if_old); - TNode<Map> const value_map = LoadMap(value); + TNode<HeapObject> value_object = CAST(value); + TNode<Map> const value_map = LoadMap(value_object); GotoIfNot(IsJSPromiseMap(value_map), &if_old); // We can skip the "constructor" lookup on {value} if it's [[Prototype]] // is the (initial) Promise.prototype and the @@species protector is @@ -223,25 +225,24 @@ Node* AsyncBuiltinsAssembler::Await(Node* context, Node* generator, Node* value, } BIND(&if_old); - result.Bind(AwaitOld(context, generator, value, outer_promise, - on_resolve_context_index, on_reject_context_index, - is_predicted_as_caught)); + result = AwaitOld(context, generator, value, outer_promise, + on_resolve_context_index, on_reject_context_index, + is_predicted_as_caught); Goto(&done); BIND(&if_new); - result.Bind(AwaitOptimized(context, generator, value, outer_promise, - on_resolve_context_index, on_reject_context_index, - is_predicted_as_caught)); + result = AwaitOptimized(context, generator, CAST(value), outer_promise, + on_resolve_context_index, on_reject_context_index, + is_predicted_as_caught); Goto(&done); BIND(&done); return result.value(); } -void AsyncBuiltinsAssembler::InitializeNativeClosure(Node* context, - Node* native_context, - Node* function, - Node* context_index) { +void AsyncBuiltinsAssembler::InitializeNativeClosure( + TNode<Context> context, TNode<NativeContext> native_context, + TNode<HeapObject> function, TNode<IntPtrT> context_index) { TNode<Map> function_map = CAST(LoadContextElement( native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); // Ensure that we don't have to initialize prototype_or_initial_map field of @@ -276,24 +277,23 @@ void AsyncBuiltinsAssembler::InitializeNativeClosure(Node* context, StoreObjectFieldNoWriteBarrier(function, JSFunction::kCodeOffset, code); } -Node* AsyncBuiltinsAssembler::CreateUnwrapClosure(Node* native_context, - Node* done) { - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<SharedFunctionInfo> const on_fulfilled_shared = CAST(LoadContextElement( +TNode<JSFunction> AsyncBuiltinsAssembler::CreateUnwrapClosure( + TNode<NativeContext> native_context, TNode<Oddball> done) { + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> on_fulfilled_shared = CAST(LoadContextElement( native_context, Context::ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN)); - Node* const closure_context = + const TNode<Context> closure_context = AllocateAsyncIteratorValueUnwrapContext(native_context, done); return AllocateFunctionWithMapAndContext(map, on_fulfilled_shared, closure_context); } -Node* AsyncBuiltinsAssembler::AllocateAsyncIteratorValueUnwrapContext( - Node* native_context, Node* done) { - CSA_ASSERT(this, IsNativeContext(native_context)); +TNode<Context> AsyncBuiltinsAssembler::AllocateAsyncIteratorValueUnwrapContext( + TNode<NativeContext> native_context, TNode<Oddball> done) { CSA_ASSERT(this, IsBoolean(done)); - Node* const context = + TNode<Context> context = CreatePromiseContext(native_context, ValueUnwrapContext::kLength); StoreContextElementNoWriteBarrier(context, ValueUnwrapContext::kDoneSlot, done); @@ -301,8 +301,8 @@ Node* AsyncBuiltinsAssembler::AllocateAsyncIteratorValueUnwrapContext( } TF_BUILTIN(AsyncIteratorValueUnwrap, AsyncBuiltinsAssembler) { - Node* const value = Parameter(Descriptor::kValue); - Node* const context = Parameter(Descriptor::kContext); + TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Object> const done = LoadContextElement(context, ValueUnwrapContext::kDoneSlot); diff --git a/deps/v8/src/builtins/builtins-async-gen.h b/deps/v8/src/builtins/builtins-async-gen.h index 9dafddef2102a6..7b9c944f4acaea 100644 --- a/deps/v8/src/builtins/builtins-async-gen.h +++ b/deps/v8/src/builtins/builtins-async-gen.h @@ -21,20 +21,27 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler { // point to a SharedFunctioninfo instance used to create the closure. The // value following the reject index should be a similar value for the resolve // closure. Returns the Promise-wrapped `value`. - Node* Await(Node* context, Node* generator, Node* value, Node* outer_promise, - Node* on_resolve_context_index, Node* on_reject_context_index, - Node* is_predicted_as_caught); - Node* Await(Node* context, Node* generator, Node* value, Node* outer_promise, - int on_resolve_context_index, int on_reject_context_index, - Node* is_predicted_as_caught) { + TNode<Object> Await(TNode<Context> context, + TNode<JSGeneratorObject> generator, TNode<Object> value, + TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught); + TNode<Object> Await(TNode<Context> context, + TNode<JSGeneratorObject> generator, TNode<Object> value, + TNode<JSPromise> outer_promise, + int on_resolve_context_index, int on_reject_context_index, + TNode<Oddball> is_predicted_as_caught) { return Await(context, generator, value, outer_promise, IntPtrConstant(on_resolve_context_index), IntPtrConstant(on_reject_context_index), is_predicted_as_caught); } - Node* Await(Node* context, Node* generator, Node* value, Node* outer_promise, - int on_resolve_context_index, int on_reject_context_index, - bool is_predicted_as_caught) { + TNode<Object> Await(TNode<Context> context, + TNode<JSGeneratorObject> generator, TNode<Object> value, + TNode<JSPromise> outer_promise, + int on_resolve_context_index, int on_reject_context_index, + bool is_predicted_as_caught) { return Await(context, generator, value, outer_promise, on_resolve_context_index, on_reject_context_index, BooleanConstant(is_predicted_as_caught)); @@ -42,21 +49,30 @@ class AsyncBuiltinsAssembler : public PromiseBuiltinsAssembler { // Return a new built-in function object as defined in // Async Iterator Value Unwrap Functions - Node* CreateUnwrapClosure(Node* const native_context, Node* const done); + TNode<JSFunction> CreateUnwrapClosure(TNode<NativeContext> native_context, + TNode<Oddball> done); private: - void InitializeNativeClosure(Node* context, Node* native_context, - Node* function, Node* context_index); - Node* AllocateAsyncIteratorValueUnwrapContext(Node* native_context, - Node* done); + void InitializeNativeClosure(TNode<Context> context, + TNode<NativeContext> native_context, + TNode<HeapObject> function, + TNode<IntPtrT> context_index); + TNode<Context> AllocateAsyncIteratorValueUnwrapContext( + TNode<NativeContext> native_context, TNode<Oddball> done); - Node* AwaitOld(Node* context, Node* generator, Node* value, - Node* outer_promise, Node* on_resolve_context_index, - Node* on_reject_context_index, Node* is_predicted_as_caught); - Node* AwaitOptimized(Node* context, Node* generator, Node* value, - Node* outer_promise, Node* on_resolve_context_index, - Node* on_reject_context_index, - Node* is_predicted_as_caught); + TNode<Object> AwaitOld(TNode<Context> context, + TNode<JSGeneratorObject> generator, + TNode<Object> value, TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught); + TNode<Object> AwaitOptimized(TNode<Context> context, + TNode<JSGeneratorObject> generator, + TNode<JSPromise> promise, + TNode<JSPromise> outer_promise, + TNode<IntPtrT> on_resolve_context_index, + TNode<IntPtrT> on_reject_context_index, + TNode<Oddball> is_predicted_as_caught); }; } // namespace internal diff --git a/deps/v8/src/builtins/builtins-async-generator-gen.cc b/deps/v8/src/builtins/builtins-async-generator-gen.cc index 8053cf0dc8b268..2ed7e8c83e0663 100644 --- a/deps/v8/src/builtins/builtins-async-generator-gen.cc +++ b/deps/v8/src/builtins/builtins-async-generator-gen.cc @@ -23,146 +23,142 @@ class AsyncGeneratorBuiltinsAssembler : public AsyncBuiltinsAssembler { explicit AsyncGeneratorBuiltinsAssembler(CodeAssemblerState* state) : AsyncBuiltinsAssembler(state) {} - inline Node* TaggedIsAsyncGenerator(Node* tagged_object) { - TNode<BoolT> if_notsmi = TaggedIsNotSmi(tagged_object); - return Select<BoolT>( - if_notsmi, - [=] { - return HasInstanceType(tagged_object, JS_ASYNC_GENERATOR_OBJECT_TYPE); - }, - [=] { return if_notsmi; }); - } - inline Node* LoadGeneratorState(Node* const generator) { - return LoadObjectField(generator, JSGeneratorObject::kContinuationOffset); + inline TNode<Smi> LoadGeneratorState( + const TNode<JSGeneratorObject> generator) { + return LoadObjectField<Smi>(generator, + JSGeneratorObject::kContinuationOffset); } - inline TNode<BoolT> IsGeneratorStateClosed(SloppyTNode<Smi> const state) { + inline TNode<BoolT> IsGeneratorStateClosed(const TNode<Smi> state) { return SmiEqual(state, SmiConstant(JSGeneratorObject::kGeneratorClosed)); } - inline TNode<BoolT> IsGeneratorClosed(Node* const generator) { + inline TNode<BoolT> IsGeneratorClosed( + const TNode<JSGeneratorObject> generator) { return IsGeneratorStateClosed(LoadGeneratorState(generator)); } - inline TNode<BoolT> IsGeneratorStateSuspended(SloppyTNode<Smi> const state) { + inline TNode<BoolT> IsGeneratorStateSuspended(const TNode<Smi> state) { return SmiGreaterThanOrEqual(state, SmiConstant(0)); } - inline TNode<BoolT> IsGeneratorSuspended(Node* const generator) { + inline TNode<BoolT> IsGeneratorSuspended( + const TNode<JSGeneratorObject> generator) { return IsGeneratorStateSuspended(LoadGeneratorState(generator)); } - inline TNode<BoolT> IsGeneratorStateSuspendedAtStart( - SloppyTNode<Smi> const state) { + inline TNode<BoolT> IsGeneratorStateSuspendedAtStart(const TNode<Smi> state) { return SmiEqual(state, SmiConstant(0)); } - inline TNode<BoolT> IsGeneratorStateNotExecuting( - SloppyTNode<Smi> const state) { + inline TNode<BoolT> IsGeneratorStateNotExecuting(const TNode<Smi> state) { return SmiNotEqual(state, SmiConstant(JSGeneratorObject::kGeneratorExecuting)); } - inline TNode<BoolT> IsGeneratorNotExecuting(Node* const generator) { + inline TNode<BoolT> IsGeneratorNotExecuting( + const TNode<JSGeneratorObject> generator) { return IsGeneratorStateNotExecuting(LoadGeneratorState(generator)); } - inline TNode<BoolT> IsGeneratorAwaiting(Node* const generator) { + inline TNode<BoolT> IsGeneratorAwaiting( + const TNode<JSGeneratorObject> generator) { TNode<Object> is_generator_awaiting = LoadObjectField(generator, JSAsyncGeneratorObject::kIsAwaitingOffset); return TaggedEqual(is_generator_awaiting, SmiConstant(1)); } - inline void SetGeneratorAwaiting(Node* const generator) { + inline void SetGeneratorAwaiting(const TNode<JSGeneratorObject> generator) { CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); StoreObjectFieldNoWriteBarrier( generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(1)); CSA_ASSERT(this, IsGeneratorAwaiting(generator)); } - inline void SetGeneratorNotAwaiting(Node* const generator) { + inline void SetGeneratorNotAwaiting( + const TNode<JSGeneratorObject> generator) { CSA_ASSERT(this, IsGeneratorAwaiting(generator)); StoreObjectFieldNoWriteBarrier( generator, JSAsyncGeneratorObject::kIsAwaitingOffset, SmiConstant(0)); CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); } - inline void CloseGenerator(Node* const generator) { + inline void CloseGenerator(const TNode<JSGeneratorObject> generator) { StoreObjectFieldNoWriteBarrier( generator, JSGeneratorObject::kContinuationOffset, SmiConstant(JSGeneratorObject::kGeneratorClosed)); } - inline Node* IsFastJSIterResult(Node* const value, Node* const context) { - CSA_ASSERT(this, TaggedIsNotSmi(value)); - TNode<NativeContext> const native_context = LoadNativeContext(context); - return TaggedEqual( - LoadMap(value), - LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX)); - } - - inline Node* LoadFirstAsyncGeneratorRequestFromQueue(Node* const generator) { - return LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset); + inline TNode<HeapObject> LoadFirstAsyncGeneratorRequestFromQueue( + const TNode<JSGeneratorObject> generator) { + return LoadObjectField<HeapObject>(generator, + JSAsyncGeneratorObject::kQueueOffset); } - inline Node* LoadResumeTypeFromAsyncGeneratorRequest(Node* const request) { - return LoadObjectField(request, AsyncGeneratorRequest::kResumeModeOffset); + inline TNode<Smi> LoadResumeTypeFromAsyncGeneratorRequest( + const TNode<AsyncGeneratorRequest> request) { + return LoadObjectField<Smi>(request, + AsyncGeneratorRequest::kResumeModeOffset); } - inline Node* LoadPromiseFromAsyncGeneratorRequest(Node* const request) { - return LoadObjectField(request, AsyncGeneratorRequest::kPromiseOffset); + inline TNode<JSPromise> LoadPromiseFromAsyncGeneratorRequest( + const TNode<AsyncGeneratorRequest> request) { + return LoadObjectField<JSPromise>(request, + AsyncGeneratorRequest::kPromiseOffset); } - inline Node* LoadValueFromAsyncGeneratorRequest(Node* const request) { + inline TNode<Object> LoadValueFromAsyncGeneratorRequest( + const TNode<AsyncGeneratorRequest> request) { return LoadObjectField(request, AsyncGeneratorRequest::kValueOffset); } - inline TNode<BoolT> IsAbruptResumeType(SloppyTNode<Smi> const resume_type) { + inline TNode<BoolT> IsAbruptResumeType(const TNode<Smi> resume_type) { return SmiNotEqual(resume_type, SmiConstant(JSGeneratorObject::kNext)); } - void AsyncGeneratorEnqueue(CodeStubArguments* args, Node* context, - Node* generator, Node* value, + void AsyncGeneratorEnqueue(CodeStubArguments* args, TNode<Context> context, + TNode<Object> receiver, TNode<Object> value, JSAsyncGeneratorObject::ResumeMode resume_mode, const char* method_name); - Node* TakeFirstAsyncGeneratorRequestFromQueue(Node* generator); - Node* TakeFirstAsyncGeneratorRequestFromQueueIfPresent(Node* generator, - Label* if_not_present); - void AddAsyncGeneratorRequestToQueue(Node* generator, Node* request); + TNode<AsyncGeneratorRequest> TakeFirstAsyncGeneratorRequestFromQueue( + TNode<JSAsyncGeneratorObject> generator); + void AddAsyncGeneratorRequestToQueue(TNode<JSAsyncGeneratorObject> generator, + TNode<AsyncGeneratorRequest> request); - Node* AllocateAsyncGeneratorRequest( - JSAsyncGeneratorObject::ResumeMode resume_mode, Node* resume_value, - Node* promise); + TNode<AsyncGeneratorRequest> AllocateAsyncGeneratorRequest( + JSAsyncGeneratorObject::ResumeMode resume_mode, + TNode<Object> resume_value, TNode<JSPromise> promise); // Shared implementation of the catchable and uncatchable variations of Await // for AsyncGenerators. template <typename Descriptor> void AsyncGeneratorAwait(bool is_catchable); void AsyncGeneratorAwaitResumeClosure( - Node* context, Node* value, + TNode<Context> context, TNode<Object> value, JSAsyncGeneratorObject::ResumeMode resume_mode); }; // Shared implementation for the 3 Async Iterator protocol methods of Async // Generators. void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue( - CodeStubArguments* args, Node* context, Node* generator, Node* value, - JSAsyncGeneratorObject::ResumeMode resume_mode, const char* method_name) { + CodeStubArguments* args, TNode<Context> context, TNode<Object> receiver, + TNode<Object> value, JSAsyncGeneratorObject::ResumeMode resume_mode, + const char* method_name) { // AsyncGeneratorEnqueue produces a new Promise, and appends it to the list // of async generator requests to be executed. If the generator is not // presently executing, then this method will loop through, processing each // request from front to back. // This loop resides in AsyncGeneratorResumeNext. - Node* promise = AllocateAndInitJSPromise(context); - - Label enqueue(this), if_receiverisincompatible(this, Label::kDeferred); + TNode<JSPromise> promise = AllocateAndInitJSPromise(context); - Branch(TaggedIsAsyncGenerator(generator), &enqueue, - &if_receiverisincompatible); + Label if_receiverisincompatible(this, Label::kDeferred); + GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible); + GotoIfNot(HasInstanceType(CAST(receiver), JS_ASYNC_GENERATOR_OBJECT_TYPE), + &if_receiverisincompatible); - BIND(&enqueue); { Label done(this); - Node* const req = + const TNode<JSAsyncGeneratorObject> generator = CAST(receiver); + const TNode<AsyncGeneratorRequest> req = AllocateAsyncGeneratorRequest(resume_mode, value, promise); AddAsyncGeneratorRequestToQueue(generator, req); @@ -171,7 +167,7 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue( // If state is not "executing", then // Perform AsyncGeneratorResumeNext(Generator) // Check if the {receiver} is running or already closed. - TNode<Smi> continuation = CAST(LoadGeneratorState(generator)); + TNode<Smi> continuation = LoadGeneratorState(generator); GotoIf(SmiEqual(continuation, SmiConstant(JSAsyncGeneratorObject::kGeneratorExecuting)), @@ -186,20 +182,18 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue( BIND(&if_receiverisincompatible); { - Node* const error = - MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver, context, - StringConstant(method_name), generator); - - CallBuiltin(Builtins::kRejectPromise, context, promise, error, + CallBuiltin(Builtins::kRejectPromise, context, promise, + MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver, + context, StringConstant(method_name), receiver), TrueConstant()); args->PopAndReturn(promise); } } -Node* AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest( - JSAsyncGeneratorObject::ResumeMode resume_mode, Node* resume_value, - Node* promise) { - CSA_SLOW_ASSERT(this, HasInstanceType(promise, JS_PROMISE_TYPE)); +TNode<AsyncGeneratorRequest> +AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest( + JSAsyncGeneratorObject::ResumeMode resume_mode, TNode<Object> resume_value, + TNode<JSPromise> promise) { TNode<HeapObject> request = Allocate(AsyncGeneratorRequest::kSize); StoreMapNoWriteBarrier(request, RootIndex::kAsyncGeneratorRequestMap); StoreObjectFieldNoWriteBarrier(request, AsyncGeneratorRequest::kNextOffset, @@ -213,15 +207,14 @@ Node* AsyncGeneratorBuiltinsAssembler::AllocateAsyncGeneratorRequest( promise); StoreObjectFieldRoot(request, AsyncGeneratorRequest::kNextOffset, RootIndex::kUndefinedValue); - return request; + return CAST(request); } void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwaitResumeClosure( - Node* context, Node* value, + TNode<Context> context, TNode<Object> value, JSAsyncGeneratorObject::ResumeMode resume_mode) { - TNode<Object> const generator = - LoadContextElement(context, Context::EXTENSION_INDEX); - CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator)); + const TNode<JSAsyncGeneratorObject> generator = + CAST(LoadContextElement(context, Context::EXTENSION_INDEX)); SetGeneratorNotAwaiting(generator); @@ -259,12 +252,13 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorAwait(bool is_catchable) { } void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue( - Node* generator, Node* request) { - VARIABLE(var_current, MachineRepresentation::kTagged); + TNode<JSAsyncGeneratorObject> generator, + TNode<AsyncGeneratorRequest> request) { + TVARIABLE(HeapObject, var_current); Label empty(this), loop(this, &var_current), done(this); - var_current.Bind( - LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset)); + var_current = LoadObjectField<HeapObject>( + generator, JSAsyncGeneratorObject::kQueueOffset); Branch(IsUndefined(var_current.value()), &empty, &loop); BIND(&empty); @@ -276,9 +270,9 @@ void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue( BIND(&loop); { Label loop_next(this), next_empty(this); - Node* current = var_current.value(); - TNode<Object> next = - LoadObjectField(current, AsyncGeneratorRequest::kNextOffset); + TNode<AsyncGeneratorRequest> current = CAST(var_current.value()); + TNode<HeapObject> next = LoadObjectField<HeapObject>( + current, AsyncGeneratorRequest::kNextOffset); Branch(IsUndefined(next), &next_empty, &loop_next); BIND(&next_empty); @@ -289,20 +283,20 @@ void AsyncGeneratorBuiltinsAssembler::AddAsyncGeneratorRequestToQueue( BIND(&loop_next); { - var_current.Bind(next); + var_current = next; Goto(&loop); } } BIND(&done); } -Node* AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue( - Node* generator) { +TNode<AsyncGeneratorRequest> +AsyncGeneratorBuiltinsAssembler::TakeFirstAsyncGeneratorRequestFromQueue( + TNode<JSAsyncGeneratorObject> generator) { // Removes and returns the first AsyncGeneratorRequest from a // JSAsyncGeneratorObject's queue. Asserts that the queue is not empty. - CSA_ASSERT(this, TaggedIsAsyncGenerator(generator)); - TNode<AsyncGeneratorRequest> request = - CAST(LoadObjectField(generator, JSAsyncGeneratorObject::kQueueOffset)); + TNode<AsyncGeneratorRequest> request = LoadObjectField<AsyncGeneratorRequest>( + generator, JSAsyncGeneratorObject::kQueueOffset); TNode<Object> next = LoadObjectField(request, AsyncGeneratorRequest::kNextOffset); @@ -323,7 +317,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeNext, AsyncGeneratorBuiltinsAssembler) { TNode<Object> generator = args.GetReceiver(); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); AsyncGeneratorEnqueue(&args, context, generator, value, JSAsyncGeneratorObject::kNext, @@ -341,7 +335,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeReturn, AsyncGeneratorBuiltinsAssembler) { TNode<Object> generator = args.GetReceiver(); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); AsyncGeneratorEnqueue(&args, context, generator, value, JSAsyncGeneratorObject::kReturn, @@ -359,7 +353,7 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) { TNode<Object> generator = args.GetReceiver(); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); AsyncGeneratorEnqueue(&args, context, generator, value, JSAsyncGeneratorObject::kThrow, @@ -367,15 +361,15 @@ TF_BUILTIN(AsyncGeneratorPrototypeThrow, AsyncGeneratorBuiltinsAssembler) { } TF_BUILTIN(AsyncGeneratorAwaitResolveClosure, AsyncGeneratorBuiltinsAssembler) { - Node* value = Parameter(Descriptor::kValue); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); AsyncGeneratorAwaitResumeClosure(context, value, JSAsyncGeneratorObject::kNext); } TF_BUILTIN(AsyncGeneratorAwaitRejectClosure, AsyncGeneratorBuiltinsAssembler) { - Node* value = Parameter(Descriptor::kValue); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); AsyncGeneratorAwaitResumeClosure(context, value, JSAsyncGeneratorObject::kThrow); } @@ -392,8 +386,9 @@ TF_BUILTIN(AsyncGeneratorAwaitCaught, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { using Descriptor = AsyncGeneratorResumeNextDescriptor; - Node* const generator = Parameter(Descriptor::kGenerator); - Node* const context = Parameter(Descriptor::kContext); + const TNode<JSAsyncGeneratorObject> generator = + CAST(Parameter(Descriptor::kGenerator)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // The penultimate step of proposal-async-iteration/#sec-asyncgeneratorresolve // and proposal-async-iteration/#sec-asyncgeneratorreject both recursively @@ -403,12 +398,10 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { // performs a loop in AsyncGeneratorResumeNext, which continues as long as // there is an AsyncGeneratorRequest in the queue, and as long as the // generator is not suspended due to an AwaitExpression. - VARIABLE(var_state, MachineRepresentation::kTaggedSigned, - LoadGeneratorState(generator)); - VARIABLE(var_next, MachineRepresentation::kTagged, - LoadFirstAsyncGeneratorRequestFromQueue(generator)); - Variable* loop_variables[] = {&var_state, &var_next}; - Label start(this, 2, loop_variables); + TVARIABLE(Smi, var_state, LoadGeneratorState(generator)); + TVARIABLE(HeapObject, var_next, + LoadFirstAsyncGeneratorRequestFromQueue(generator)); + Label start(this, {&var_state, &var_next}); Goto(&start); BIND(&start); @@ -420,9 +413,8 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { // Stop resuming if request queue is empty. ReturnIf(IsUndefined(var_next.value()), UndefinedConstant()); - Node* const next = var_next.value(); - TNode<Smi> const resume_type = - CAST(LoadResumeTypeFromAsyncGeneratorRequest(next)); + const TNode<AsyncGeneratorRequest> next = CAST(var_next.value()); + const TNode<Smi> resume_type = LoadResumeTypeFromAsyncGeneratorRequest(next); Label if_abrupt(this), if_normal(this), resume_generator(this); Branch(IsAbruptResumeType(resume_type), &if_abrupt, &if_normal); @@ -432,11 +424,11 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { GotoIfNot(IsGeneratorStateSuspendedAtStart(var_state.value()), &settle_promise); CloseGenerator(generator); - var_state.Bind(SmiConstant(JSGeneratorObject::kGeneratorClosed)); + var_state = SmiConstant(JSGeneratorObject::kGeneratorClosed); Goto(&settle_promise); BIND(&settle_promise); - Node* next_value = LoadValueFromAsyncGeneratorRequest(next); + TNode<Object> next_value = LoadValueFromAsyncGeneratorRequest(next); Branch(SmiEqual(resume_type, SmiConstant(JSGeneratorObject::kReturn)), &if_return, &if_throw); @@ -457,7 +449,7 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator); CallBuiltin(Builtins::kAsyncGeneratorReject, context, generator, next_value); - var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); + var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator); Goto(&start); } @@ -466,8 +458,8 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { GotoIfNot(IsGeneratorStateClosed(var_state.value()), &resume_generator); CallBuiltin(Builtins::kAsyncGeneratorResolve, context, generator, UndefinedConstant(), TrueConstant()); - var_state.Bind(LoadGeneratorState(generator)); - var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); + var_state = LoadGeneratorState(generator); + var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator); Goto(&start); } @@ -478,19 +470,19 @@ TF_BUILTIN(AsyncGeneratorResumeNext, AsyncGeneratorBuiltinsAssembler) { generator, JSGeneratorObject::kResumeModeOffset, resume_type); CallStub(CodeFactory::ResumeGenerator(isolate()), context, LoadValueFromAsyncGeneratorRequest(next), generator); - var_state.Bind(LoadGeneratorState(generator)); - var_next.Bind(LoadFirstAsyncGeneratorRequestFromQueue(generator)); + var_state = LoadGeneratorState(generator); + var_next = LoadFirstAsyncGeneratorRequestFromQueue(generator); Goto(&start); } } TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) { - Node* const generator = Parameter(Descriptor::kGenerator); - Node* const value = Parameter(Descriptor::kValue); - Node* const done = Parameter(Descriptor::kDone); - Node* const context = Parameter(Descriptor::kContext); + const TNode<JSAsyncGeneratorObject> generator = + CAST(Parameter(Descriptor::kGenerator)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Object> done = CAST(Parameter(Descriptor::kDone)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - CSA_SLOW_ASSERT(this, TaggedIsAsyncGenerator(generator)); CSA_ASSERT(this, Word32BinaryNot(IsGeneratorAwaiting(generator))); // This operation should be called only when the `value` parameter has been @@ -499,11 +491,12 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) { // non-callable value. This can't be checked with assertions due to being // observable, but keep it in mind. - Node* const next = TakeFirstAsyncGeneratorRequestFromQueue(generator); - Node* const promise = LoadPromiseFromAsyncGeneratorRequest(next); + const TNode<AsyncGeneratorRequest> next = + TakeFirstAsyncGeneratorRequestFromQueue(generator); + const TNode<JSPromise> promise = LoadPromiseFromAsyncGeneratorRequest(next); // Let iteratorResult be CreateIterResultObject(value, done). - TNode<HeapObject> const iter_result = Allocate(JSIteratorResult::kSize); + const TNode<HeapObject> iter_result = Allocate(JSIteratorResult::kSize); { TNode<Object> map = LoadContextElement(LoadNativeContext(context), Context::ITERATOR_RESULT_MAP_INDEX); @@ -555,25 +548,30 @@ TF_BUILTIN(AsyncGeneratorResolve, AsyncGeneratorBuiltinsAssembler) { TF_BUILTIN(AsyncGeneratorReject, AsyncGeneratorBuiltinsAssembler) { using Descriptor = AsyncGeneratorRejectDescriptor; - Node* const generator = Parameter(Descriptor::kGenerator); - Node* const value = Parameter(Descriptor::kValue); - Node* const context = Parameter(Descriptor::kContext); + const TNode<JSAsyncGeneratorObject> generator = + CAST(Parameter(Descriptor::kGenerator)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* const next = TakeFirstAsyncGeneratorRequestFromQueue(generator); - Node* const promise = LoadPromiseFromAsyncGeneratorRequest(next); + TNode<AsyncGeneratorRequest> next = + TakeFirstAsyncGeneratorRequestFromQueue(generator); + TNode<JSPromise> promise = LoadPromiseFromAsyncGeneratorRequest(next); Return(CallBuiltin(Builtins::kRejectPromise, context, promise, value, TrueConstant())); } TF_BUILTIN(AsyncGeneratorYield, AsyncGeneratorBuiltinsAssembler) { - Node* const generator = Parameter(Descriptor::kGenerator); - Node* const value = Parameter(Descriptor::kValue); - Node* const is_caught = Parameter(Descriptor::kIsCaught); - Node* const context = Parameter(Descriptor::kContext); + const TNode<JSGeneratorObject> generator = + CAST(Parameter(Descriptor::kGenerator)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - Node* const request = LoadFirstAsyncGeneratorRequestFromQueue(generator); - Node* const outer_promise = LoadPromiseFromAsyncGeneratorRequest(request); + const TNode<AsyncGeneratorRequest> request = + CAST(LoadFirstAsyncGeneratorRequestFromQueue(generator)); + const TNode<JSPromise> outer_promise = + LoadPromiseFromAsyncGeneratorRequest(request); const int on_resolve = Context::ASYNC_GENERATOR_YIELD_RESOLVE_SHARED_FUN; const int on_reject = Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN; @@ -585,10 +583,10 @@ TF_BUILTIN(AsyncGeneratorYield, AsyncGeneratorBuiltinsAssembler) { } TF_BUILTIN(AsyncGeneratorYieldResolveClosure, AsyncGeneratorBuiltinsAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const value = Parameter(Descriptor::kValue); - TNode<Object> const generator = - LoadContextElement(context, Context::EXTENSION_INDEX); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<JSAsyncGeneratorObject> generator = + CAST(LoadContextElement(context, Context::EXTENSION_INDEX)); SetGeneratorNotAwaiting(generator); @@ -617,33 +615,35 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) { // (per proposal-async-iteration/#sec-asyncgeneratorresumenext step 10.b.i) // // In all cases, the final step is to jump back to AsyncGeneratorResumeNext. - Node* const generator = Parameter(Descriptor::kGenerator); - Node* const value = Parameter(Descriptor::kValue); - Node* const is_caught = Parameter(Descriptor::kIsCaught); - Node* const req = LoadFirstAsyncGeneratorRequestFromQueue(generator); - CSA_ASSERT(this, IsNotUndefined(req)); + const TNode<JSGeneratorObject> generator = + CAST(Parameter(Descriptor::kGenerator)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Oddball> is_caught = CAST(Parameter(Descriptor::kIsCaught)); + const TNode<AsyncGeneratorRequest> req = + CAST(LoadFirstAsyncGeneratorRequestFromQueue(generator)); Label perform_await(this); - VARIABLE(var_on_resolve, MachineType::PointerRepresentation(), - IntPtrConstant( - Context::ASYNC_GENERATOR_RETURN_CLOSED_RESOLVE_SHARED_FUN)); - VARIABLE( - var_on_reject, MachineType::PointerRepresentation(), + TVARIABLE(IntPtrT, var_on_resolve, + IntPtrConstant( + Context::ASYNC_GENERATOR_RETURN_CLOSED_RESOLVE_SHARED_FUN)); + TVARIABLE( + IntPtrT, var_on_reject, IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_CLOSED_REJECT_SHARED_FUN)); - Node* const state = LoadGeneratorState(generator); + const TNode<Smi> state = LoadGeneratorState(generator); GotoIf(IsGeneratorStateClosed(state), &perform_await); - var_on_resolve.Bind( - IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN)); - var_on_reject.Bind( - IntPtrConstant(Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN)); + var_on_resolve = + IntPtrConstant(Context::ASYNC_GENERATOR_RETURN_RESOLVE_SHARED_FUN); + var_on_reject = + IntPtrConstant(Context::ASYNC_GENERATOR_AWAIT_REJECT_SHARED_FUN); Goto(&perform_await); BIND(&perform_await); SetGeneratorAwaiting(generator); - Node* const context = Parameter(Descriptor::kContext); - Node* const outer_promise = LoadPromiseFromAsyncGeneratorRequest(req); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<JSPromise> outer_promise = + LoadPromiseFromAsyncGeneratorRequest(req); Await(context, generator, value, outer_promise, var_on_resolve.value(), var_on_reject.value(), is_caught); @@ -656,8 +656,8 @@ TF_BUILTIN(AsyncGeneratorReturn, AsyncGeneratorBuiltinsAssembler) { // proposal-async-iteration/#sec-asyncgeneratoryield step 8.e TF_BUILTIN(AsyncGeneratorReturnResolveClosure, AsyncGeneratorBuiltinsAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const value = Parameter(Descriptor::kValue); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); AsyncGeneratorAwaitResumeClosure(context, value, JSGeneratorObject::kReturn); } @@ -666,10 +666,10 @@ TF_BUILTIN(AsyncGeneratorReturnResolveClosure, // AsyncGeneratorResumeNext. TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure, AsyncGeneratorBuiltinsAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const value = Parameter(Descriptor::kValue); - TNode<Object> const generator = - LoadContextElement(context, Context::EXTENSION_INDEX); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<JSAsyncGeneratorObject> generator = + CAST(LoadContextElement(context, Context::EXTENSION_INDEX)); SetGeneratorNotAwaiting(generator); @@ -684,10 +684,10 @@ TF_BUILTIN(AsyncGeneratorReturnClosedResolveClosure, TF_BUILTIN(AsyncGeneratorReturnClosedRejectClosure, AsyncGeneratorBuiltinsAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const value = Parameter(Descriptor::kValue); - TNode<Object> const generator = - LoadContextElement(context, Context::EXTENSION_INDEX); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<JSAsyncGeneratorObject> generator = + CAST(LoadContextElement(context, Context::EXTENSION_INDEX)); SetGeneratorNotAwaiting(generator); diff --git a/deps/v8/src/builtins/builtins-async-iterator-gen.cc b/deps/v8/src/builtins/builtins-async-iterator-gen.cc index 0b5c5ef8b962cd..39ff8c92172559 100644 --- a/deps/v8/src/builtins/builtins-async-iterator-gen.cc +++ b/deps/v8/src/builtins/builtins-async-iterator-gen.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "src/base/optional.h" #include "src/builtins/builtins-async-gen.h" #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" @@ -20,29 +21,34 @@ class AsyncFromSyncBuiltinsAssembler : public AsyncBuiltinsAssembler { explicit AsyncFromSyncBuiltinsAssembler(compiler::CodeAssemblerState* state) : AsyncBuiltinsAssembler(state) {} - void ThrowIfNotAsyncFromSyncIterator(Node* const context, Node* const object, + void ThrowIfNotAsyncFromSyncIterator(const TNode<Context> context, + const TNode<Object> object, Label* if_exception, - Variable* var_exception, + TVariable<Object>* var_exception, const char* method_name); - using UndefinedMethodHandler = std::function<void( - Node* const context, Node* const promise, Label* if_exception)>; - using SyncIteratorNodeGenerator = std::function<Node*(Node*)>; + using UndefinedMethodHandler = + std::function<void(const TNode<NativeContext> native_context, + const TNode<JSPromise> promise, Label* if_exception)>; + using SyncIteratorNodeGenerator = + std::function<TNode<Object>(TNode<JSReceiver>)>; void Generate_AsyncFromSyncIteratorMethod( - Node* const context, Node* const iterator, Node* const sent_value, + const TNode<Context> context, const TNode<Object> iterator, + const TNode<Object> sent_value, const SyncIteratorNodeGenerator& get_method, const UndefinedMethodHandler& if_method_undefined, const char* operation_name, Label::Type reject_label_type = Label::kDeferred, - Node* const initial_exception_value = nullptr); + base::Optional<TNode<Object>> initial_exception_value = base::nullopt); void Generate_AsyncFromSyncIteratorMethod( - Node* const context, Node* const iterator, Node* const sent_value, - Handle<String> name, const UndefinedMethodHandler& if_method_undefined, + const TNode<Context> context, const TNode<Object> iterator, + const TNode<Object> sent_value, Handle<String> name, + const UndefinedMethodHandler& if_method_undefined, const char* operation_name, Label::Type reject_label_type = Label::kDeferred, - Node* const initial_exception_value = nullptr) { - auto get_method = [=](Node* const sync_iterator) { + base::Optional<TNode<Object>> initial_exception_value = base::nullopt) { + auto get_method = [=](const TNode<JSReceiver> sync_iterator) { return GetProperty(context, sync_iterator, name); }; return Generate_AsyncFromSyncIteratorMethod( @@ -51,26 +57,26 @@ class AsyncFromSyncBuiltinsAssembler : public AsyncBuiltinsAssembler { } // Load "value" and "done" from an iterator result object. If an exception - // is thrown at any point, jumps to te `if_exception` label with exception + // is thrown at any point, jumps to the `if_exception` label with exception // stored in `var_exception`. // // Returns a Pair of Nodes, whose first element is the value of the "value" // property, and whose second element is the value of the "done" property, // converted to a Boolean if needed. - std::pair<Node*, Node*> LoadIteratorResult(Node* const context, - Node* const native_context, - Node* const iter_result, - Label* if_exception, - Variable* var_exception); + std::pair<TNode<Object>, TNode<Oddball>> LoadIteratorResult( + const TNode<Context> context, const TNode<NativeContext> native_context, + const TNode<Object> iter_result, Label* if_exception, + TVariable<Object>* var_exception); }; void AsyncFromSyncBuiltinsAssembler::ThrowIfNotAsyncFromSyncIterator( - Node* const context, Node* const object, Label* if_exception, - Variable* var_exception, const char* method_name) { + const TNode<Context> context, const TNode<Object> object, + Label* if_exception, TVariable<Object>* var_exception, + const char* method_name) { Label if_receiverisincompatible(this, Label::kDeferred), done(this); GotoIf(TaggedIsSmi(object), &if_receiverisincompatible); - Branch(HasInstanceType(object, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE), &done, + Branch(HasInstanceType(CAST(object), JS_ASYNC_FROM_SYNC_ITERATOR_TYPE), &done, &if_receiverisincompatible); BIND(&if_receiverisincompatible); @@ -79,13 +85,13 @@ void AsyncFromSyncBuiltinsAssembler::ThrowIfNotAsyncFromSyncIterator( // internal slot, then // Let badIteratorError be a new TypeError exception. - Node* const error = - MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver, context, - StringConstant(method_name), object); + TNode<HeapObject> error = + CAST(MakeTypeError(MessageTemplate::kIncompatibleMethodReceiver, + context, StringConstant(method_name), object)); // Perform ! Call(promiseCapability.[[Reject]], undefined, // « badIteratorError »). - var_exception->Bind(error); + *var_exception = error; Goto(if_exception); } @@ -93,26 +99,27 @@ void AsyncFromSyncBuiltinsAssembler::ThrowIfNotAsyncFromSyncIterator( } void AsyncFromSyncBuiltinsAssembler::Generate_AsyncFromSyncIteratorMethod( - Node* const context, Node* const iterator, Node* const sent_value, - const SyncIteratorNodeGenerator& get_method, + const TNode<Context> context, const TNode<Object> iterator, + const TNode<Object> sent_value, const SyncIteratorNodeGenerator& get_method, const UndefinedMethodHandler& if_method_undefined, const char* operation_name, Label::Type reject_label_type, - Node* const initial_exception_value) { - TNode<NativeContext> const native_context = LoadNativeContext(context); - Node* const promise = AllocateAndInitJSPromise(context); + base::Optional<TNode<Object>> initial_exception_value) { + const TNode<NativeContext> native_context = LoadNativeContext(context); + const TNode<JSPromise> promise = AllocateAndInitJSPromise(context); - VARIABLE(var_exception, MachineRepresentation::kTagged, - initial_exception_value == nullptr ? UndefinedConstant() - : initial_exception_value); + TVARIABLE( + Object, var_exception, + initial_exception_value ? *initial_exception_value : UndefinedConstant()); Label reject_promise(this, reject_label_type); ThrowIfNotAsyncFromSyncIterator(context, iterator, &reject_promise, &var_exception, operation_name); - TNode<Object> const sync_iterator = - LoadObjectField(iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset); + TNode<JSAsyncFromSyncIterator> async_iterator = CAST(iterator); + const TNode<JSReceiver> sync_iterator = LoadObjectField<JSReceiver>( + async_iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset); - Node* const method = get_method(sync_iterator); + TNode<Object> method = get_method(sync_iterator); if (if_method_undefined) { Label if_isnotundefined(this); @@ -123,21 +130,21 @@ void AsyncFromSyncBuiltinsAssembler::Generate_AsyncFromSyncIteratorMethod( BIND(&if_isnotundefined); } - Node* const iter_result = CallJS(CodeFactory::Call(isolate()), context, - method, sync_iterator, sent_value); + const TNode<Object> iter_result = CallJS( + CodeFactory::Call(isolate()), context, method, sync_iterator, sent_value); GotoIfException(iter_result, &reject_promise, &var_exception); - Node* value; - Node* done; + TNode<Object> value; + TNode<Oddball> done; std::tie(value, done) = LoadIteratorResult( context, native_context, iter_result, &reject_promise, &var_exception); - TNode<JSFunction> const promise_fun = + const TNode<JSFunction> promise_fun = CAST(LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX)); CSA_ASSERT(this, IsConstructor(promise_fun)); // Let valueWrapper be PromiseResolve(%Promise%, « value »). - TNode<Object> const value_wrapper = CallBuiltin( + const TNode<Object> value_wrapper = CallBuiltin( Builtins::kPromiseResolve, native_context, promise_fun, value); // IfAbruptRejectPromise(valueWrapper, promiseCapability). GotoIfException(value_wrapper, &reject_promise, &var_exception); @@ -145,7 +152,8 @@ void AsyncFromSyncBuiltinsAssembler::Generate_AsyncFromSyncIteratorMethod( // Let onFulfilled be a new built-in function object as defined in // Async Iterator Value Unwrap Functions. // Set onFulfilled.[[Done]] to throwDone. - Node* const on_fulfilled = CreateUnwrapClosure(native_context, done); + const TNode<JSFunction> on_fulfilled = + CreateUnwrapClosure(native_context, done); // Perform ! PerformPromiseThen(valueWrapper, // onFulfilled, undefined, promiseCapability). @@ -154,35 +162,39 @@ void AsyncFromSyncBuiltinsAssembler::Generate_AsyncFromSyncIteratorMethod( BIND(&reject_promise); { - Node* const exception = var_exception.value(); + const TNode<Object> exception = var_exception.value(); CallBuiltin(Builtins::kRejectPromise, context, promise, exception, TrueConstant()); Return(promise); } } -std::pair<Node*, Node*> AsyncFromSyncBuiltinsAssembler::LoadIteratorResult( - Node* const context, Node* const native_context, Node* const iter_result, - Label* if_exception, Variable* var_exception) { + +std::pair<TNode<Object>, TNode<Oddball>> +AsyncFromSyncBuiltinsAssembler::LoadIteratorResult( + const TNode<Context> context, const TNode<NativeContext> native_context, + const TNode<Object> iter_result, Label* if_exception, + TVariable<Object>* var_exception) { Label if_fastpath(this), if_slowpath(this), merge(this), to_boolean(this), done(this), if_notanobject(this, Label::kDeferred); GotoIf(TaggedIsSmi(iter_result), &if_notanobject); - TNode<Map> const iter_result_map = LoadMap(iter_result); + const TNode<Map> iter_result_map = LoadMap(CAST(iter_result)); GotoIfNot(IsJSReceiverMap(iter_result_map), &if_notanobject); - TNode<Object> const fast_iter_result_map = + const TNode<Object> fast_iter_result_map = LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX); - VARIABLE(var_value, MachineRepresentation::kTagged); - VARIABLE(var_done, MachineRepresentation::kTagged); + TVARIABLE(Object, var_value); + TVARIABLE(Object, var_done); Branch(TaggedEqual(iter_result_map, fast_iter_result_map), &if_fastpath, &if_slowpath); BIND(&if_fastpath); { - var_done.Bind(LoadObjectField(iter_result, JSIteratorResult::kDoneOffset)); - var_value.Bind( - LoadObjectField(iter_result, JSIteratorResult::kValueOffset)); + TNode<JSObject> fast_iter_result = CAST(iter_result); + var_done = LoadObjectField(fast_iter_result, JSIteratorResult::kDoneOffset); + var_value = + LoadObjectField(fast_iter_result, JSIteratorResult::kValueOffset); Goto(&merge); } @@ -190,18 +202,18 @@ std::pair<Node*, Node*> AsyncFromSyncBuiltinsAssembler::LoadIteratorResult( { // Let nextDone be IteratorComplete(nextResult). // IfAbruptRejectPromise(nextDone, promiseCapability). - TNode<Object> const done = + const TNode<Object> done = GetProperty(context, iter_result, factory()->done_string()); GotoIfException(done, if_exception, var_exception); // Let nextValue be IteratorValue(nextResult). // IfAbruptRejectPromise(nextValue, promiseCapability). - TNode<Object> const value = + const TNode<Object> value = GetProperty(context, iter_result, factory()->value_string()); GotoIfException(value, if_exception, var_exception); - var_value.Bind(value); - var_done.Bind(done); + var_value = value; + var_done = done; Goto(&merge); } @@ -209,27 +221,27 @@ std::pair<Node*, Node*> AsyncFromSyncBuiltinsAssembler::LoadIteratorResult( { // Sync iterator result is not an object --- Produce a TypeError and jump // to the `if_exception` path. - Node* const error = MakeTypeError( - MessageTemplate::kIteratorResultNotAnObject, context, iter_result); - var_exception->Bind(error); + const TNode<Object> error = CAST(MakeTypeError( + MessageTemplate::kIteratorResultNotAnObject, context, iter_result)); + *var_exception = error; Goto(if_exception); } BIND(&merge); // Ensure `iterResult.done` is a Boolean. GotoIf(TaggedIsSmi(var_done.value()), &to_boolean); - Branch(IsBoolean(var_done.value()), &done, &to_boolean); + Branch(IsBoolean(CAST(var_done.value())), &done, &to_boolean); BIND(&to_boolean); { - TNode<Object> const result = + const TNode<Object> result = CallBuiltin(Builtins::kToBoolean, context, var_done.value()); - var_done.Bind(result); + var_done = result; Goto(&done); } BIND(&done); - return std::make_pair(var_value.value(), var_done.value()); + return std::make_pair(var_value.value(), CAST(var_done.value())); } } // namespace @@ -237,12 +249,13 @@ std::pair<Node*, Node*> AsyncFromSyncBuiltinsAssembler::LoadIteratorResult( // https://tc39.github.io/proposal-async-iteration/ // Section #sec-%asyncfromsynciteratorprototype%.next TF_BUILTIN(AsyncFromSyncIteratorPrototypeNext, AsyncFromSyncBuiltinsAssembler) { - Node* const iterator = Parameter(Descriptor::kReceiver); - Node* const value = Parameter(Descriptor::kValue); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> iterator = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - auto get_method = [=](Node* const unused) { - return LoadObjectField(iterator, JSAsyncFromSyncIterator::kNextOffset); + auto get_method = [=](const TNode<JSReceiver> unused) { + return LoadObjectField(CAST(iterator), + JSAsyncFromSyncIterator::kNextOffset); }; Generate_AsyncFromSyncIteratorMethod( context, iterator, value, get_method, UndefinedMethodHandler(), @@ -253,15 +266,16 @@ TF_BUILTIN(AsyncFromSyncIteratorPrototypeNext, AsyncFromSyncBuiltinsAssembler) { // Section #sec-%asyncfromsynciteratorprototype%.return TF_BUILTIN(AsyncFromSyncIteratorPrototypeReturn, AsyncFromSyncBuiltinsAssembler) { - Node* const iterator = Parameter(Descriptor::kReceiver); - Node* const value = Parameter(Descriptor::kValue); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> iterator = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - auto if_return_undefined = [=](Node* const native_context, - Node* const promise, Label* if_exception) { + auto if_return_undefined = [=](const TNode<NativeContext> native_context, + const TNode<JSPromise> promise, + Label* if_exception) { // If return is undefined, then // Let iterResult be ! CreateIterResultObject(value, true) - TNode<Object> const iter_result = CallBuiltin( + const TNode<Object> iter_result = CallBuiltin( Builtins::kCreateIterResultObject, context, value, TrueConstant()); // Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »). @@ -280,11 +294,12 @@ TF_BUILTIN(AsyncFromSyncIteratorPrototypeReturn, // Section #sec-%asyncfromsynciteratorprototype%.throw TF_BUILTIN(AsyncFromSyncIteratorPrototypeThrow, AsyncFromSyncBuiltinsAssembler) { - Node* const iterator = Parameter(Descriptor::kReceiver); - Node* const reason = Parameter(Descriptor::kReason); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> iterator = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> reason = CAST(Parameter(Descriptor::kReason)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - auto if_throw_undefined = [=](Node* const native_context, Node* const promise, + auto if_throw_undefined = [=](const TNode<NativeContext> native_context, + const TNode<JSPromise> promise, Label* if_exception) { Goto(if_exception); }; Generate_AsyncFromSyncIteratorMethod( diff --git a/deps/v8/src/builtins/builtins-async-module.cc b/deps/v8/src/builtins/builtins-async-module.cc new file mode 100644 index 00000000000000..fecdb31cf3cdb9 --- /dev/null +++ b/deps/v8/src/builtins/builtins-async-module.cc @@ -0,0 +1,33 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/builtins/builtins-utils-inl.h" +#include "src/objects/module-inl.h" +#include "src/objects/objects-inl.h" + +namespace v8 { +namespace internal { + +BUILTIN(CallAsyncModuleFulfilled) { + HandleScope handle_scope(isolate); + Handle<SourceTextModule> module( + isolate->global_handles()->Create(*args.at<SourceTextModule>(0))); + SourceTextModule::AsyncModuleExecutionFulfilled(isolate, module); + return ReadOnlyRoots(isolate).undefined_value(); +} + +BUILTIN(CallAsyncModuleRejected) { + HandleScope handle_scope(isolate); + + // Arguments should be a SourceTextModule and an exception object. + DCHECK_EQ(args.length(), 2); + Handle<SourceTextModule> module( + isolate->global_handles()->Create(*args.at<SourceTextModule>(0))); + Handle<Object> exception(args.at(1)); + SourceTextModule::AsyncModuleExecutionRejected(isolate, module, exception); + return ReadOnlyRoots(isolate).undefined_value(); +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/builtins/builtins-bigint.cc b/deps/v8/src/builtins/builtins-bigint.cc index 1201ce97300ec0..30da5207f90b7a 100644 --- a/deps/v8/src/builtins/builtins-bigint.cc +++ b/deps/v8/src/builtins/builtins-bigint.cc @@ -125,26 +125,21 @@ Object BigIntToStringImpl(Handle<Object> receiver, Handle<Object> radix, BUILTIN(BigIntPrototypeToLocaleString) { HandleScope scope(isolate); + const char* method = "BigInt.prototype.toLocaleString"; #ifdef V8_INTL_SUPPORT - if (FLAG_harmony_intl_bigint) { - // 1. Let x be ? thisBigIntValue(this value). - Handle<BigInt> x; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, x, - ThisBigIntValue(isolate, args.receiver(), - "BigInt.prototype.toLocaleString")); - - RETURN_RESULT_OR_FAILURE( - isolate, - Intl::NumberToLocaleString(isolate, x, args.atOrUndefined(isolate, 1), - args.atOrUndefined(isolate, 2))); - } - // Fallbacks to old toString implemention if flag is off or no - // V8_INTL_SUPPORT + // 1. Let x be ? thisBigIntValue(this value). + Handle<BigInt> x; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, x, ThisBigIntValue(isolate, args.receiver(), method)); + + RETURN_RESULT_OR_FAILURE( + isolate, + Intl::NumberToLocaleString(isolate, x, args.atOrUndefined(isolate, 1), + args.atOrUndefined(isolate, 2), method)); + // Fallbacks to old toString implemention if no V8_INTL_SUPPORT #endif // V8_INTL_SUPPORT Handle<Object> radix = isolate->factory()->undefined_value(); - return BigIntToStringImpl(args.receiver(), radix, isolate, - "BigInt.prototype.toLocaleString"); + return BigIntToStringImpl(args.receiver(), radix, isolate, method); } BUILTIN(BigIntPrototypeToString) { diff --git a/deps/v8/src/builtins/builtins-call-gen.cc b/deps/v8/src/builtins/builtins-call-gen.cc index 91370b089679f6..fd1ad5bb67c0de 100644 --- a/deps/v8/src/builtins/builtins-call-gen.cc +++ b/deps/v8/src/builtins/builtins-call-gen.cc @@ -9,6 +9,7 @@ #include "src/codegen/macro-assembler.h" #include "src/common/globals.h" #include "src/execution/isolate.h" +#include "src/execution/protectors.h" #include "src/objects/api-callbacks.h" #include "src/objects/arguments.h" #include "src/objects/property-cell.h" @@ -17,9 +18,6 @@ namespace v8 { namespace internal { -template <typename T> -using TNode = compiler::TNode<T>; - void Builtins::Generate_CallFunction_ReceiverIsNullOrUndefined( MacroAssembler* masm) { Generate_CallFunction(masm, ConvertReceiverMode::kNullOrUndefined); @@ -297,7 +295,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread( TNode<PropertyCell> protector_cell = ArrayIteratorProtectorConstant(); GotoIf( TaggedEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorInvalid)), + SmiConstant(Protectors::kProtectorInvalid)), &if_generic); { // The fast-path accesses the {spread} elements directly. diff --git a/deps/v8/src/builtins/builtins-collections-gen.cc b/deps/v8/src/builtins/builtins-collections-gen.cc index dec4142c65fc9e..c0ca74a577b886 100644 --- a/deps/v8/src/builtins/builtins-collections-gen.cc +++ b/deps/v8/src/builtins/builtins-collections-gen.cc @@ -8,6 +8,7 @@ #include "src/builtins/builtins-iterator-gen.h" #include "src/builtins/builtins-utils-gen.h" #include "src/codegen/code-stub-assembler.h" +#include "src/execution/protectors.h" #include "src/heap/factory-inl.h" #include "src/heap/heap-inl.h" #include "src/objects/hash-table-inl.h" @@ -19,8 +20,6 @@ namespace internal { using compiler::Node; template <class T> -using TNode = compiler::TNode<T>; -template <class T> using TVariable = compiler::TypedCodeAssemblerVariable<T>; class BaseCollectionsAssembler : public CodeStubAssembler { @@ -81,8 +80,8 @@ class BaseCollectionsAssembler : public CodeStubAssembler { TNode<JSReceiver> new_target); // Allocates the backing store for a collection. - virtual TNode<Object> AllocateTable(Variant variant, TNode<Context> context, - TNode<IntPtrT> at_least_space_for) = 0; + virtual TNode<HeapObject> AllocateTable( + Variant variant, TNode<IntPtrT> at_least_space_for) = 0; // Main entry point for a collection constructor builtin. void GenerateConstructor(Variant variant, @@ -124,7 +123,7 @@ class BaseCollectionsAssembler : public CodeStubAssembler { TNode<IntPtrT> EstimatedInitialSize(TNode<Object> initial_entries, TNode<BoolT> is_fast_jsarray); - void GotoIfNotJSReceiver(Node* const obj, Label* if_not_receiver); + void GotoIfNotJSReceiver(TNode<Object> const obj, Label* if_not_receiver); // Determines whether the collection's prototype has been modified. TNode<BoolT> HasInitialCollectionPrototype(Variant variant, @@ -160,8 +159,8 @@ void BaseCollectionsAssembler::AddConstructorEntry( ? LoadKeyValuePairNoSideEffects(context, key_value, if_may_have_side_effects) : LoadKeyValuePair(context, key_value); - Node* key_n = pair.key; - Node* value_n = pair.value; + TNode<Object> key_n = pair.key; + TNode<Object> value_n = pair.value; CallJS(CodeFactory::Call(isolate()), context, add_function, collection, key_n, value_n); } else { @@ -183,7 +182,7 @@ void BaseCollectionsAssembler::AddConstructorEntries( Goto(&allocate_table); BIND(&allocate_table); { - TNode<Object> table = AllocateTable(variant, context, at_least_space_for); + TNode<HeapObject> table = AllocateTable(variant, at_least_space_for); StoreObjectField(collection, GetTableOffset(variant), table); GotoIf(IsNullOrUndefined(initial_entries), &exit); GotoIfInitialAddFunctionModified(variant, CAST(native_context), @@ -261,7 +260,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray( &if_doubles); BIND(&if_smiorobjects); { - auto set_entry = [&](Node* index) { + auto set_entry = [&](TNode<IntPtrT> index) { TNode<Object> element = LoadAndNormalizeFixedArrayElement( CAST(elements), UncheckedCast<IntPtrT>(index)); AddConstructorEntry(variant, context, collection, add_func, element, @@ -272,8 +271,8 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray( // elements, a fast loop is used. This assumes that adding an element // to the collection does not call user code that could mutate the elements // or collection. - BuildFastLoop(IntPtrConstant(0), length, set_entry, 1, - ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + BuildFastLoop<IntPtrT>(IntPtrConstant(0), length, set_entry, 1, + IndexAdvanceMode::kPost); Goto(&exit); } BIND(&if_doubles); @@ -288,13 +287,13 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray( element); } else { DCHECK(variant == kSet || variant == kWeakSet); - auto set_entry = [&](Node* index) { + auto set_entry = [&](TNode<IntPtrT> index) { TNode<Object> entry = LoadAndNormalizeFixedDoubleArrayElement( elements, UncheckedCast<IntPtrT>(index)); AddConstructorEntry(variant, context, collection, add_func, entry); }; - BuildFastLoop(IntPtrConstant(0), length, set_entry, 1, - ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + BuildFastLoop<IntPtrT>(IntPtrConstant(0), length, set_entry, 1, + IndexAdvanceMode::kPost); Goto(&exit); } } @@ -523,10 +522,10 @@ TNode<IntPtrT> BaseCollectionsAssembler::EstimatedInitialSize( [=] { return IntPtrConstant(0); }); } -void BaseCollectionsAssembler::GotoIfNotJSReceiver(Node* const obj, +void BaseCollectionsAssembler::GotoIfNotJSReceiver(TNode<Object> const obj, Label* if_not_receiver) { GotoIf(TaggedIsSmi(obj), if_not_receiver); - GotoIfNot(IsJSReceiver(obj), if_not_receiver); + GotoIfNot(IsJSReceiver(CAST(obj)), if_not_receiver); } TNode<Map> BaseCollectionsAssembler::GetInitialCollectionPrototype( @@ -608,22 +607,24 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler { protected: template <typename IteratorType> - Node* AllocateJSCollectionIterator(SloppyTNode<Context> context, - int map_index, Node* collection); - TNode<Object> AllocateTable(Variant variant, TNode<Context> context, - TNode<IntPtrT> at_least_space_for) override; - TNode<IntPtrT> GetHash(SloppyTNode<HeapObject> const key); - TNode<IntPtrT> CallGetHashRaw(SloppyTNode<HeapObject> const key); - TNode<Smi> CallGetOrCreateHashRaw(SloppyTNode<HeapObject> const key); + TNode<HeapObject> AllocateJSCollectionIterator( + const TNode<Context> context, int map_index, + const TNode<HeapObject> collection); + TNode<HeapObject> AllocateTable(Variant variant, + TNode<IntPtrT> at_least_space_for) override; + TNode<IntPtrT> GetHash(const TNode<HeapObject> key); + TNode<IntPtrT> CallGetHashRaw(const TNode<HeapObject> key); + TNode<Smi> CallGetOrCreateHashRaw(const TNode<HeapObject> key); // Transitions the iterator to the non obsolete backing store. // This is a NOP if the [table] is not obsolete. - using UpdateInTransition = - std::function<void(Node* const table, Node* const index)>; + template <typename TableType> + using UpdateInTransition = std::function<void(const TNode<TableType> table, + const TNode<IntPtrT> index)>; template <typename TableType> std::pair<TNode<TableType>, TNode<IntPtrT>> Transition( TNode<TableType> const table, TNode<IntPtrT> const index, - UpdateInTransition const& update_in_transition); + UpdateInTransition<TableType> const& update_in_transition); template <typename IteratorType, typename TableType> std::pair<TNode<TableType>, TNode<IntPtrT>> TransitionAndUpdate( TNode<IteratorType> const iterator); @@ -635,35 +636,33 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler { // The {result} variable will contain the entry index if the key was found, // or the hash code otherwise. template <typename CollectionType> - void FindOrderedHashTableEntryForSmiKey(Node* table, - SloppyTNode<Smi> key_tagged, - Variable* result, Label* entry_found, - Label* not_found); - void SameValueZeroSmi(SloppyTNode<Smi> key_smi, - SloppyTNode<Object> candidate_key, Label* if_same, - Label* if_not_same); + void FindOrderedHashTableEntryForSmiKey(TNode<CollectionType> table, + TNode<Smi> key_tagged, + TVariable<IntPtrT>* result, + Label* entry_found, Label* not_found); + void SameValueZeroSmi(TNode<Smi> key_smi, TNode<Object> candidate_key, + Label* if_same, Label* if_not_same); // Specialization for heap numbers. // The {result} variable will contain the entry index if the key was found, // or the hash code otherwise. - void SameValueZeroHeapNumber(SloppyTNode<Float64T> key_float, - SloppyTNode<Object> candidate_key, - Label* if_same, Label* if_not_same); + void SameValueZeroHeapNumber(TNode<Float64T> key_float, + TNode<Object> candidate_key, Label* if_same, + Label* if_not_same); template <typename CollectionType> void FindOrderedHashTableEntryForHeapNumberKey( - SloppyTNode<Context> context, Node* table, - SloppyTNode<HeapNumber> key_heap_number, Variable* result, - Label* entry_found, Label* not_found); + TNode<CollectionType> table, TNode<HeapNumber> key_heap_number, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found); // Specialization for bigints. // The {result} variable will contain the entry index if the key was found, // or the hash code otherwise. - void SameValueZeroBigInt(Node* key, Node* candidate_key, Label* if_same, - Label* if_not_same); + void SameValueZeroBigInt(TNode<BigInt> key, TNode<Object> candidate_key, + Label* if_same, Label* if_not_same); template <typename CollectionType> - void FindOrderedHashTableEntryForBigIntKey(SloppyTNode<Context> context, - Node* table, Node* key, - Variable* result, + void FindOrderedHashTableEntryForBigIntKey(TNode<CollectionType> table, + TNode<BigInt> key_big_int, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found); @@ -671,14 +670,14 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler { // The {result} variable will contain the entry index if the key was found, // or the hash code otherwise. template <typename CollectionType> - void FindOrderedHashTableEntryForStringKey( - SloppyTNode<Context> context, Node* table, SloppyTNode<String> key_tagged, - Variable* result, Label* entry_found, Label* not_found); - TNode<IntPtrT> ComputeStringHash(TNode<Context> context, - TNode<String> string_key); - void SameValueZeroString(SloppyTNode<Context> context, - SloppyTNode<String> key_string, - SloppyTNode<Object> candidate_key, Label* if_same, + void FindOrderedHashTableEntryForStringKey(TNode<CollectionType> table, + TNode<String> key_tagged, + TVariable<IntPtrT>* result, + Label* entry_found, + Label* not_found); + TNode<IntPtrT> ComputeStringHash(TNode<String> string_key); + void SameValueZeroString(TNode<String> key_string, + TNode<Object> candidate_key, Label* if_same, Label* if_not_same); // Specialization for non-strings, non-numbers. For those we only need @@ -687,26 +686,32 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler { // or the hash code otherwise. If the hash-code has not been computed, it // should be Smi -1. template <typename CollectionType> - void FindOrderedHashTableEntryForOtherKey( - SloppyTNode<Context> context, Node* table, SloppyTNode<HeapObject> key, - Variable* result, Label* entry_found, Label* not_found); + void FindOrderedHashTableEntryForOtherKey(TNode<CollectionType> table, + TNode<HeapObject> key_heap_object, + TVariable<IntPtrT>* result, + Label* entry_found, + Label* not_found); template <typename CollectionType> - void TryLookupOrderedHashTableIndex(Node* const table, Node* const key, - Node* const context, Variable* result, + void TryLookupOrderedHashTableIndex(const TNode<CollectionType> table, + const TNode<Object> key, + TVariable<IntPtrT>* result, Label* if_entry_found, Label* if_not_found); - Node* NormalizeNumberKey(Node* key); + const TNode<Object> NormalizeNumberKey(const TNode<Object> key); void StoreOrderedHashMapNewEntry(TNode<OrderedHashMap> const table, - Node* const key, Node* const value, - Node* const hash, - Node* const number_of_buckets, - Node* const occupancy); + const TNode<Object> key, + const TNode<Object> value, + const TNode<IntPtrT> hash, + const TNode<IntPtrT> number_of_buckets, + const TNode<IntPtrT> occupancy); + void StoreOrderedHashSetNewEntry(TNode<OrderedHashSet> const table, - Node* const key, Node* const hash, - Node* const number_of_buckets, - Node* const occupancy); + const TNode<Object> key, + const TNode<IntPtrT> hash, + const TNode<IntPtrT> number_of_buckets, + const TNode<IntPtrT> occupancy); // Create a JSArray with PACKED_ELEMENTS kind from a Map.prototype.keys() or // Map.prototype.values() iterator. The iterator is assumed to satisfy @@ -727,11 +732,97 @@ class CollectionsBuiltinsAssembler : public BaseCollectionsAssembler { void BranchIfMapIteratorProtectorValid(Label* if_true, Label* if_false); void BranchIfSetIteratorProtectorValid(Label* if_true, Label* if_false); + + // Builds code that finds OrderedHashTable entry for a key with hash code + // {hash} with using the comparison code generated by {key_compare}. The code + // jumps to {entry_found} if the key is found, or to {not_found} if the key + // was not found. In the {entry_found} branch, the variable + // entry_start_position will be bound to the index of the entry (relative to + // OrderedHashTable::kHashTableStartIndex). + // + // The {CollectionType} template parameter stands for the particular instance + // of OrderedHashTable, it should be OrderedHashMap or OrderedHashSet. + template <typename CollectionType> + void FindOrderedHashTableEntry( + Node* table, Node* hash, + const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, + Variable* entry_start_position, Label* entry_found, Label* not_found); }; +template <typename CollectionType> +void CollectionsBuiltinsAssembler::FindOrderedHashTableEntry( + Node* table, Node* hash, + const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, + Variable* entry_start_position, Label* entry_found, Label* not_found) { + // Get the index of the bucket. + TNode<IntPtrT> const number_of_buckets = + SmiUntag(CAST(UnsafeLoadFixedArrayElement( + CAST(table), CollectionType::NumberOfBucketsIndex()))); + TNode<WordT> const bucket = + WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1))); + TNode<IntPtrT> const first_entry = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + CAST(table), bucket, + CollectionType::HashTableStartIndex() * kTaggedSize))); + + // Walk the bucket chain. + TNode<IntPtrT> entry_start; + Label if_key_found(this); + { + TVARIABLE(IntPtrT, var_entry, first_entry); + Label loop(this, {&var_entry, entry_start_position}), + continue_next_entry(this); + Goto(&loop); + BIND(&loop); + + // If the entry index is the not-found sentinel, we are done. + GotoIf(IntPtrEqual(var_entry.value(), + IntPtrConstant(CollectionType::kNotFound)), + not_found); + + // Make sure the entry index is within range. + CSA_ASSERT( + this, + UintPtrLessThan( + var_entry.value(), + SmiUntag(SmiAdd( + CAST(UnsafeLoadFixedArrayElement( + CAST(table), CollectionType::NumberOfElementsIndex())), + CAST(UnsafeLoadFixedArrayElement( + CAST(table), + CollectionType::NumberOfDeletedElementsIndex())))))); + + // Compute the index of the entry relative to kHashTableStartIndex. + entry_start = + IntPtrAdd(IntPtrMul(var_entry.value(), + IntPtrConstant(CollectionType::kEntrySize)), + number_of_buckets); + + // Load the key from the entry. + TNode<Object> const candidate_key = UnsafeLoadFixedArrayElement( + CAST(table), entry_start, + CollectionType::HashTableStartIndex() * kTaggedSize); + + key_compare(candidate_key, &if_key_found, &continue_next_entry); + + BIND(&continue_next_entry); + // Load the index of the next entry in the bucket chain. + var_entry = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + CAST(table), entry_start, + (CollectionType::HashTableStartIndex() + CollectionType::kChainOffset) * + kTaggedSize))); + + Goto(&loop); + } + + BIND(&if_key_found); + entry_start_position->Bind(entry_start); + Goto(entry_found); +} + template <typename IteratorType> -Node* CollectionsBuiltinsAssembler::AllocateJSCollectionIterator( - SloppyTNode<Context> context, int map_index, Node* collection) { +TNode<HeapObject> CollectionsBuiltinsAssembler::AllocateJSCollectionIterator( + TNode<Context> const context, int map_index, + TNode<HeapObject> const collection) { TNode<Object> const table = LoadObjectField(collection, JSCollection::kTableOffset); TNode<NativeContext> const native_context = LoadNativeContext(context); @@ -749,9 +840,8 @@ Node* CollectionsBuiltinsAssembler::AllocateJSCollectionIterator( return iterator; } -TNode<Object> CollectionsBuiltinsAssembler::AllocateTable( - Variant variant, TNode<Context> context, - TNode<IntPtrT> at_least_space_for) { +TNode<HeapObject> CollectionsBuiltinsAssembler::AllocateTable( + Variant variant, TNode<IntPtrT> at_least_space_for) { return CAST((variant == kMap || variant == kWeakMap) ? AllocateOrderedHashTable<OrderedHashMap>() : AllocateOrderedHashTable<OrderedHashSet>()); @@ -778,7 +868,7 @@ TF_BUILTIN(SetConstructor, CollectionsBuiltinsAssembler) { } TNode<Smi> CollectionsBuiltinsAssembler::CallGetOrCreateHashRaw( - SloppyTNode<HeapObject> const key) { + const TNode<HeapObject> key) { TNode<ExternalReference> const function_addr = ExternalConstant(ExternalReference::get_or_create_hash_raw()); TNode<ExternalReference> const isolate_ptr = @@ -787,15 +877,15 @@ TNode<Smi> CollectionsBuiltinsAssembler::CallGetOrCreateHashRaw( MachineType type_ptr = MachineType::Pointer(); MachineType type_tagged = MachineType::AnyTagged(); - Node* const result = CallCFunction(function_addr, type_tagged, - std::make_pair(type_ptr, isolate_ptr), - std::make_pair(type_tagged, key)); + TNode<Smi> result = CAST(CallCFunction(function_addr, type_tagged, + std::make_pair(type_ptr, isolate_ptr), + std::make_pair(type_tagged, key))); - return CAST(result); + return result; } TNode<IntPtrT> CollectionsBuiltinsAssembler::CallGetHashRaw( - SloppyTNode<HeapObject> const key) { + const TNode<HeapObject> key) { TNode<ExternalReference> const function_addr = ExternalConstant(ExternalReference::orderedhashmap_gethash_raw()); TNode<ExternalReference> const isolate_ptr = @@ -804,15 +894,15 @@ TNode<IntPtrT> CollectionsBuiltinsAssembler::CallGetHashRaw( MachineType type_ptr = MachineType::Pointer(); MachineType type_tagged = MachineType::AnyTagged(); - Node* const result = CallCFunction(function_addr, type_tagged, - std::make_pair(type_ptr, isolate_ptr), - std::make_pair(type_tagged, key)); + TNode<Smi> result = CAST(CallCFunction(function_addr, type_tagged, + std::make_pair(type_ptr, isolate_ptr), + std::make_pair(type_tagged, key))); return SmiUntag(result); } TNode<IntPtrT> CollectionsBuiltinsAssembler::GetHash( - SloppyTNode<HeapObject> const key) { + const TNode<HeapObject> key) { TVARIABLE(IntPtrT, var_hash); Label if_receiver(this), if_other(this), done(this); Branch(IsJSReceiver(key), &if_receiver, &if_other); @@ -833,9 +923,10 @@ TNode<IntPtrT> CollectionsBuiltinsAssembler::GetHash( return var_hash.value(); } -void CollectionsBuiltinsAssembler::SameValueZeroSmi( - SloppyTNode<Smi> key_smi, SloppyTNode<Object> candidate_key, Label* if_same, - Label* if_not_same) { +void CollectionsBuiltinsAssembler::SameValueZeroSmi(TNode<Smi> key_smi, + TNode<Object> candidate_key, + Label* if_same, + Label* if_not_same) { // If the key is the same, we are done. GotoIf(TaggedEqual(candidate_key, key_smi), if_same); @@ -862,7 +953,7 @@ void CollectionsBuiltinsAssembler::BranchIfMapIteratorProtectorValid( DCHECK(isolate()->heap()->map_iterator_protector().IsPropertyCell()); Branch( TaggedEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorValid)), + SmiConstant(Protectors::kProtectorValid)), if_true, if_false); } @@ -921,7 +1012,7 @@ void CollectionsBuiltinsAssembler::BranchIfSetIteratorProtectorValid( DCHECK(isolate()->heap()->set_iterator_protector().IsPropertyCell()); Branch( TaggedEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorValid)), + SmiConstant(Protectors::kProtectorValid)), if_true, if_false); } @@ -998,15 +1089,15 @@ TNode<JSArray> CollectionsBuiltinsAssembler::MapIteratorToList( TNode<Map> array_map = LoadJSArrayElementsMap(kind, LoadNativeContext(context)); TNode<JSArray> array = - AllocateJSArray(kind, array_map, size, SmiTag(size), nullptr, + AllocateJSArray(kind, array_map, size, SmiTag(size), {}, INTPTR_PARAMETERS, kAllowLargeObjectAllocation); TNode<FixedArray> elements = CAST(LoadElements(array)); const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; TNode<IntPtrT> first_to_element_offset = - ElementOffsetFromIndex(IntPtrConstant(0), kind, INTPTR_PARAMETERS, 0); - VARIABLE( - var_offset, MachineType::PointerRepresentation(), + ElementOffsetFromIndex(IntPtrConstant(0), kind, 0); + TVARIABLE( + IntPtrT, var_offset, IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset))); TVARIABLE(IntPtrT, var_index, index); VariableList vars({&var_index, &var_offset}, zone()); @@ -1053,8 +1144,7 @@ TNode<JSArray> CollectionsBuiltinsAssembler::MapIteratorToList( { // Increment the array offset and continue the loop to the next entry. var_index = cur_index; - var_offset.Bind( - IntPtrAdd(var_offset.value(), IntPtrConstant(kTaggedSize))); + var_offset = IntPtrAdd(var_offset.value(), IntPtrConstant(kTaggedSize)); Goto(&loop); } } @@ -1111,15 +1201,15 @@ TNode<JSArray> CollectionsBuiltinsAssembler::SetOrSetIteratorToList( TNode<Map> array_map = LoadJSArrayElementsMap(kind, LoadNativeContext(context)); TNode<JSArray> array = - AllocateJSArray(kind, array_map, size, SmiTag(size), nullptr, + AllocateJSArray(kind, array_map, size, SmiTag(size), {}, INTPTR_PARAMETERS, kAllowLargeObjectAllocation); TNode<FixedArray> elements = CAST(LoadElements(array)); const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; TNode<IntPtrT> first_to_element_offset = - ElementOffsetFromIndex(IntPtrConstant(0), kind, INTPTR_PARAMETERS, 0); - VARIABLE( - var_offset, MachineType::PointerRepresentation(), + ElementOffsetFromIndex(IntPtrConstant(0), kind, 0); + TVARIABLE( + IntPtrT, var_offset, IntPtrAdd(first_to_element_offset, IntPtrConstant(first_element_offset))); TVARIABLE(IntPtrT, var_index, IntPtrConstant(0)); Label done(this), finalize(this, {&var_index}), @@ -1139,7 +1229,7 @@ TNode<JSArray> CollectionsBuiltinsAssembler::SetOrSetIteratorToList( Store(elements, var_offset.value(), entry_key); var_index = cur_index; - var_offset.Bind(IntPtrAdd(var_offset.value(), IntPtrConstant(kTaggedSize))); + var_offset = IntPtrAdd(var_offset.value(), IntPtrConstant(kTaggedSize)); Goto(&loop); } @@ -1164,13 +1254,13 @@ TF_BUILTIN(SetOrSetIteratorToList, CollectionsBuiltinsAssembler) { template <typename CollectionType> void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey( - Node* table, SloppyTNode<Smi> smi_key, Variable* result, Label* entry_found, - Label* not_found) { + TNode<CollectionType> table, TNode<Smi> smi_key, TVariable<IntPtrT>* result, + Label* entry_found, Label* not_found) { TNode<IntPtrT> const key_untagged = SmiUntag(smi_key); TNode<IntPtrT> const hash = ChangeInt32ToIntPtr(ComputeUnseededHash(key_untagged)); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); - result->Bind(hash); + *result = hash; FindOrderedHashTableEntry<CollectionType>( table, hash, [&](TNode<Object> other_key, Label* if_same, Label* if_not_same) { @@ -1181,28 +1271,26 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForSmiKey( template <typename CollectionType> void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForStringKey( - SloppyTNode<Context> context, Node* table, SloppyTNode<String> key_tagged, - Variable* result, Label* entry_found, Label* not_found) { - TNode<IntPtrT> const hash = ComputeStringHash(context, key_tagged); + TNode<CollectionType> table, TNode<String> key_tagged, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found) { + TNode<IntPtrT> const hash = ComputeStringHash(key_tagged); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); - result->Bind(hash); + *result = hash; FindOrderedHashTableEntry<CollectionType>( table, hash, [&](TNode<Object> other_key, Label* if_same, Label* if_not_same) { - SameValueZeroString(context, key_tagged, other_key, if_same, - if_not_same); + SameValueZeroString(key_tagged, other_key, if_same, if_not_same); }, result, entry_found, not_found); } template <typename CollectionType> void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForHeapNumberKey( - SloppyTNode<Context> context, Node* table, - SloppyTNode<HeapNumber> key_heap_number, Variable* result, - Label* entry_found, Label* not_found) { + TNode<CollectionType> table, TNode<HeapNumber> key_heap_number, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found) { TNode<IntPtrT> const hash = CallGetHashRaw(key_heap_number); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); - result->Bind(hash); + *result = hash; TNode<Float64T> const key_float = LoadHeapNumberValue(key_heap_number); FindOrderedHashTableEntry<CollectionType>( table, hash, @@ -1214,36 +1302,36 @@ void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForHeapNumberKey( template <typename CollectionType> void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForBigIntKey( - SloppyTNode<Context> context, Node* table, Node* key, Variable* result, - Label* entry_found, Label* not_found) { - TNode<IntPtrT> const hash = CallGetHashRaw(key); + TNode<CollectionType> table, TNode<BigInt> key_big_int, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found) { + TNode<IntPtrT> const hash = CallGetHashRaw(key_big_int); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); - result->Bind(hash); + *result = hash; FindOrderedHashTableEntry<CollectionType>( table, hash, [&](TNode<Object> other_key, Label* if_same, Label* if_not_same) { - SameValueZeroBigInt(key, other_key, if_same, if_not_same); + SameValueZeroBigInt(key_big_int, other_key, if_same, if_not_same); }, result, entry_found, not_found); } template <typename CollectionType> void CollectionsBuiltinsAssembler::FindOrderedHashTableEntryForOtherKey( - SloppyTNode<Context> context, Node* table, SloppyTNode<HeapObject> key, - Variable* result, Label* entry_found, Label* not_found) { - TNode<IntPtrT> const hash = GetHash(key); + TNode<CollectionType> table, TNode<HeapObject> key_heap_object, + TVariable<IntPtrT>* result, Label* entry_found, Label* not_found) { + TNode<IntPtrT> const hash = GetHash(key_heap_object); CSA_ASSERT(this, IntPtrGreaterThanOrEqual(hash, IntPtrConstant(0))); - result->Bind(hash); + *result = hash; FindOrderedHashTableEntry<CollectionType>( table, hash, [&](TNode<Object> other_key, Label* if_same, Label* if_not_same) { - Branch(TaggedEqual(key, other_key), if_same, if_not_same); + Branch(TaggedEqual(key_heap_object, other_key), if_same, if_not_same); }, result, entry_found, not_found); } TNode<IntPtrT> CollectionsBuiltinsAssembler::ComputeStringHash( - TNode<Context> context, TNode<String> string_key) { + TNode<String> string_key) { TVARIABLE(IntPtrT, var_result); Label hash_not_computed(this), done(this, &var_result); @@ -1261,25 +1349,23 @@ TNode<IntPtrT> CollectionsBuiltinsAssembler::ComputeStringHash( } void CollectionsBuiltinsAssembler::SameValueZeroString( - SloppyTNode<Context> context, SloppyTNode<String> key_string, - SloppyTNode<Object> candidate_key, Label* if_same, Label* if_not_same) { + TNode<String> key_string, TNode<Object> candidate_key, Label* if_same, + Label* if_not_same) { // If the candidate is not a string, the keys are not equal. GotoIf(TaggedIsSmi(candidate_key), if_not_same); GotoIfNot(IsString(CAST(candidate_key)), if_not_same); - Branch(TaggedEqual(CallBuiltin(Builtins::kStringEqual, context, key_string, - candidate_key), + Branch(TaggedEqual(CallBuiltin(Builtins::kStringEqual, NoContextConstant(), + key_string, candidate_key), TrueConstant()), if_same, if_not_same); } -void CollectionsBuiltinsAssembler::SameValueZeroBigInt(Node* key, - Node* candidate_key, - Label* if_same, - Label* if_not_same) { - CSA_ASSERT(this, IsBigInt(key)); +void CollectionsBuiltinsAssembler::SameValueZeroBigInt( + TNode<BigInt> key, TNode<Object> candidate_key, Label* if_same, + Label* if_not_same) { GotoIf(TaggedIsSmi(candidate_key), if_not_same); - GotoIfNot(IsBigInt(candidate_key), if_not_same); + GotoIfNot(IsBigInt(CAST(candidate_key)), if_not_same); Branch(TaggedEqual(CallRuntime(Runtime::kBigIntEqualToBigInt, NoContextConstant(), key, candidate_key), @@ -1288,8 +1374,8 @@ void CollectionsBuiltinsAssembler::SameValueZeroBigInt(Node* key, } void CollectionsBuiltinsAssembler::SameValueZeroHeapNumber( - SloppyTNode<Float64T> key_float, SloppyTNode<Object> candidate_key, - Label* if_same, Label* if_not_same) { + TNode<Float64T> key_float, TNode<Object> candidate_key, Label* if_same, + Label* if_not_same) { Label if_smi(this), if_keyisnan(this); GotoIf(TaggedIsSmi(candidate_key), &if_smi); @@ -1339,20 +1425,20 @@ TF_BUILTIN(OrderedHashTableHealIndex, CollectionsBuiltinsAssembler) { IntPtrConstant(OrderedHashMap::kClearedTableSentinel)), &return_zero); - VARIABLE(var_i, MachineType::PointerRepresentation(), IntPtrConstant(0)); - VARIABLE(var_index, MachineRepresentation::kTagged, index); + TVARIABLE(IntPtrT, var_i, IntPtrConstant(0)); + TVARIABLE(Smi, var_index, index); Label loop(this, {&var_i, &var_index}); Goto(&loop); BIND(&loop); { - Node* i = var_i.value(); + TNode<IntPtrT> i = var_i.value(); GotoIfNot(IntPtrLessThan(i, number_of_deleted_elements), &return_index); STATIC_ASSERT(OrderedHashMap::RemovedHolesIndex() == OrderedHashSet::RemovedHolesIndex()); TNode<Smi> removed_index = CAST(LoadFixedArrayElement( CAST(table), i, OrderedHashMap::RemovedHolesIndex() * kTaggedSize)); GotoIf(SmiGreaterThanOrEqual(removed_index, index), &return_index); - Decrement(&var_index, 1, SMI_PARAMETERS); + Decrement(&var_index); Increment(&var_i); Goto(&loop); } @@ -1368,7 +1454,7 @@ template <typename TableType> std::pair<TNode<TableType>, TNode<IntPtrT>> CollectionsBuiltinsAssembler::Transition( TNode<TableType> const table, TNode<IntPtrT> const index, - UpdateInTransition const& update_in_transition) { + UpdateInTransition<TableType> const& update_in_transition) { TVARIABLE(IntPtrT, var_index, index); TVARIABLE(TableType, var_table, table); Label if_done(this), if_transition(this, Label::kDeferred); @@ -1413,7 +1499,8 @@ CollectionsBuiltinsAssembler::TransitionAndUpdate( return Transition<TableType>( CAST(LoadObjectField(iterator, IteratorType::kTableOffset)), LoadAndUntagObjectField(iterator, IteratorType::kIndexOffset), - [this, iterator](Node* const table, Node* const index) { + [this, iterator](const TNode<TableType> table, + const TNode<IntPtrT> index) { // Update the {iterator} with the new state. StoreObjectField(iterator, IteratorType::kTableOffset, table); StoreObjectFieldNoWriteBarrier(iterator, IteratorType::kIndexOffset, @@ -1460,13 +1547,14 @@ CollectionsBuiltinsAssembler::NextSkipHoles(TNode<TableType> table, } TF_BUILTIN(MapPrototypeGet, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.get"); - TNode<Object> const table = LoadObjectField(receiver, JSMap::kTableOffset); + TNode<Object> const table = + LoadObjectField<Object>(CAST(receiver), JSMap::kTableOffset); TNode<Smi> index = CAST( CallBuiltin(Builtins::kFindOrderedHashMapEntry, context, table, key)); @@ -1485,13 +1573,14 @@ TF_BUILTIN(MapPrototypeGet, CollectionsBuiltinsAssembler) { } TF_BUILTIN(MapPrototypeHas, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.has"); - TNode<Object> const table = LoadObjectField(receiver, JSMap::kTableOffset); + TNode<Object> const table = + LoadObjectField(CAST(receiver), JSMap::kTableOffset); TNode<Smi> index = CAST( CallBuiltin(Builtins::kFindOrderedHashMapEntry, context, table, key)); @@ -1506,17 +1595,18 @@ TF_BUILTIN(MapPrototypeHas, CollectionsBuiltinsAssembler) { Return(FalseConstant()); } -Node* CollectionsBuiltinsAssembler::NormalizeNumberKey(Node* const key) { - VARIABLE(result, MachineRepresentation::kTagged, key); +const TNode<Object> CollectionsBuiltinsAssembler::NormalizeNumberKey( + const TNode<Object> key) { + TVARIABLE(Object, result, key); Label done(this); GotoIf(TaggedIsSmi(key), &done); - GotoIfNot(IsHeapNumber(key), &done); - TNode<Float64T> const number = LoadHeapNumberValue(key); + GotoIfNot(IsHeapNumber(CAST(key)), &done); + TNode<Float64T> const number = LoadHeapNumberValue(CAST(key)); GotoIfNot(Float64Equal(number, Float64Constant(0.0)), &done); // We know the value is zero, so we take the key to be Smi 0. // Another option would be to normalize to Smi here. - result.Bind(SmiConstant(0)); + result = SmiConstant(0); Goto(&done); BIND(&done); @@ -1524,25 +1614,23 @@ Node* CollectionsBuiltinsAssembler::NormalizeNumberKey(Node* const key) { } TF_BUILTIN(MapPrototypeSet, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* key = Parameter(Descriptor::kKey); - Node* const value = Parameter(Descriptor::kValue); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.set"); key = NormalizeNumberKey(key); TNode<OrderedHashMap> const table = - CAST(LoadObjectField(receiver, JSMap::kTableOffset)); + LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset); - VARIABLE(entry_start_position_or_hash, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position_or_hash, IntPtrConstant(0)); Label entry_found(this), not_found(this); - TryLookupOrderedHashTableIndex<OrderedHashMap>(table, key, context, - &entry_start_position_or_hash, - &entry_found, ¬_found); + TryLookupOrderedHashTableIndex<OrderedHashMap>( + table, key, &entry_start_position_or_hash, &entry_found, ¬_found); BIND(&entry_found); // If we found the entry, we just store the value there. @@ -1561,18 +1649,18 @@ TF_BUILTIN(MapPrototypeSet, CollectionsBuiltinsAssembler) { &add_entry); // Otherwise, go to runtime to compute the hash code. - entry_start_position_or_hash.Bind(SmiUntag(CallGetOrCreateHashRaw(key))); + entry_start_position_or_hash = SmiUntag(CallGetOrCreateHashRaw(CAST(key))); Goto(&add_entry); } BIND(&add_entry); - VARIABLE(number_of_buckets, MachineType::PointerRepresentation()); - VARIABLE(occupancy, MachineType::PointerRepresentation()); + TVARIABLE(IntPtrT, number_of_buckets); + TVARIABLE(IntPtrT, occupancy); TVARIABLE(OrderedHashMap, table_var, table); { // Check we have enough space for the entry. - number_of_buckets.Bind(SmiUntag(CAST(UnsafeLoadFixedArrayElement( - table, OrderedHashMap::NumberOfBucketsIndex())))); + number_of_buckets = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + table, OrderedHashMap::NumberOfBucketsIndex()))); STATIC_ASSERT(OrderedHashMap::kLoadFactor == 2); TNode<WordT> const capacity = WordShl(number_of_buckets.value(), 1); @@ -1580,20 +1668,21 @@ TF_BUILTIN(MapPrototypeSet, CollectionsBuiltinsAssembler) { CAST(LoadObjectField(table, OrderedHashMap::NumberOfElementsOffset()))); TNode<IntPtrT> const number_of_deleted = SmiUntag(CAST(LoadObjectField( table, OrderedHashMap::NumberOfDeletedElementsOffset()))); - occupancy.Bind(IntPtrAdd(number_of_elements, number_of_deleted)); + occupancy = IntPtrAdd(number_of_elements, number_of_deleted); GotoIf(IntPtrLessThan(occupancy.value(), capacity), &store_new_entry); // We do not have enough space, grow the table and reload the relevant // fields. CallRuntime(Runtime::kMapGrow, context, receiver); - table_var = CAST(LoadObjectField(receiver, JSMap::kTableOffset)); - number_of_buckets.Bind(SmiUntag(CAST(UnsafeLoadFixedArrayElement( - table_var.value(), OrderedHashMap::NumberOfBucketsIndex())))); + table_var = + LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset); + number_of_buckets = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + table_var.value(), OrderedHashMap::NumberOfBucketsIndex()))); TNode<IntPtrT> const new_number_of_elements = SmiUntag(CAST(LoadObjectField( table_var.value(), OrderedHashMap::NumberOfElementsOffset()))); TNode<IntPtrT> const new_number_of_deleted = SmiUntag(CAST(LoadObjectField( table_var.value(), OrderedHashMap::NumberOfDeletedElementsOffset()))); - occupancy.Bind(IntPtrAdd(new_number_of_elements, new_number_of_deleted)); + occupancy = IntPtrAdd(new_number_of_elements, new_number_of_deleted); Goto(&store_new_entry); } BIND(&store_new_entry); @@ -1605,15 +1694,16 @@ TF_BUILTIN(MapPrototypeSet, CollectionsBuiltinsAssembler) { } void CollectionsBuiltinsAssembler::StoreOrderedHashMapNewEntry( - TNode<OrderedHashMap> const table, Node* const key, Node* const value, - Node* const hash, Node* const number_of_buckets, Node* const occupancy) { - TNode<WordT> const bucket = + TNode<OrderedHashMap> const table, const TNode<Object> key, + const TNode<Object> value, const TNode<IntPtrT> hash, + const TNode<IntPtrT> number_of_buckets, const TNode<IntPtrT> occupancy) { + TNode<IntPtrT> const bucket = WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1))); TNode<Smi> bucket_entry = CAST(UnsafeLoadFixedArrayElement( table, bucket, OrderedHashMap::HashTableStartIndex() * kTaggedSize)); // Store the entry elements. - TNode<WordT> const entry_start = IntPtrAdd( + TNode<IntPtrT> const entry_start = IntPtrAdd( IntPtrMul(occupancy, IntPtrConstant(OrderedHashMap::kEntrySize)), number_of_buckets); UnsafeStoreFixedArrayElement( @@ -1642,23 +1732,21 @@ void CollectionsBuiltinsAssembler::StoreOrderedHashMapNewEntry( } TF_BUILTIN(MapPrototypeDelete, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.delete"); TNode<OrderedHashMap> const table = - CAST(LoadObjectField(receiver, JSMap::kTableOffset)); + LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset); - VARIABLE(entry_start_position_or_hash, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position_or_hash, IntPtrConstant(0)); Label entry_found(this), not_found(this); - TryLookupOrderedHashTableIndex<OrderedHashMap>(table, key, context, - &entry_start_position_or_hash, - &entry_found, ¬_found); + TryLookupOrderedHashTableIndex<OrderedHashMap>( + table, key, &entry_start_position_or_hash, &entry_found, ¬_found); BIND(¬_found); Return(FalseConstant()); @@ -1703,24 +1791,22 @@ TF_BUILTIN(MapPrototypeDelete, CollectionsBuiltinsAssembler) { } TF_BUILTIN(SetPrototypeAdd, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.add"); key = NormalizeNumberKey(key); TNode<OrderedHashSet> const table = - CAST(LoadObjectField(receiver, JSMap::kTableOffset)); + LoadObjectField<OrderedHashSet>(CAST(receiver), JSMap::kTableOffset); - VARIABLE(entry_start_position_or_hash, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position_or_hash, IntPtrConstant(0)); Label entry_found(this), not_found(this); - TryLookupOrderedHashTableIndex<OrderedHashSet>(table, key, context, - &entry_start_position_or_hash, - &entry_found, ¬_found); + TryLookupOrderedHashTableIndex<OrderedHashSet>( + table, key, &entry_start_position_or_hash, &entry_found, ¬_found); BIND(&entry_found); // The entry was found, there is nothing to do. @@ -1735,18 +1821,18 @@ TF_BUILTIN(SetPrototypeAdd, CollectionsBuiltinsAssembler) { &add_entry); // Otherwise, go to runtime to compute the hash code. - entry_start_position_or_hash.Bind(SmiUntag(CallGetOrCreateHashRaw(key))); + entry_start_position_or_hash = SmiUntag(CallGetOrCreateHashRaw(CAST(key))); Goto(&add_entry); } BIND(&add_entry); - VARIABLE(number_of_buckets, MachineType::PointerRepresentation()); - VARIABLE(occupancy, MachineType::PointerRepresentation()); + TVARIABLE(IntPtrT, number_of_buckets); + TVARIABLE(IntPtrT, occupancy); TVARIABLE(OrderedHashSet, table_var, table); { // Check we have enough space for the entry. - number_of_buckets.Bind(SmiUntag(CAST(UnsafeLoadFixedArrayElement( - table, OrderedHashSet::NumberOfBucketsIndex())))); + number_of_buckets = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + table, OrderedHashSet::NumberOfBucketsIndex()))); STATIC_ASSERT(OrderedHashSet::kLoadFactor == 2); TNode<WordT> const capacity = WordShl(number_of_buckets.value(), 1); @@ -1754,20 +1840,21 @@ TF_BUILTIN(SetPrototypeAdd, CollectionsBuiltinsAssembler) { CAST(LoadObjectField(table, OrderedHashSet::NumberOfElementsOffset()))); TNode<IntPtrT> const number_of_deleted = SmiUntag(CAST(LoadObjectField( table, OrderedHashSet::NumberOfDeletedElementsOffset()))); - occupancy.Bind(IntPtrAdd(number_of_elements, number_of_deleted)); + occupancy = IntPtrAdd(number_of_elements, number_of_deleted); GotoIf(IntPtrLessThan(occupancy.value(), capacity), &store_new_entry); // We do not have enough space, grow the table and reload the relevant // fields. CallRuntime(Runtime::kSetGrow, context, receiver); - table_var = CAST(LoadObjectField(receiver, JSMap::kTableOffset)); - number_of_buckets.Bind(SmiUntag(CAST(UnsafeLoadFixedArrayElement( - table_var.value(), OrderedHashSet::NumberOfBucketsIndex())))); + table_var = + LoadObjectField<OrderedHashSet>(CAST(receiver), JSMap::kTableOffset); + number_of_buckets = SmiUntag(CAST(UnsafeLoadFixedArrayElement( + table_var.value(), OrderedHashSet::NumberOfBucketsIndex()))); TNode<IntPtrT> const new_number_of_elements = SmiUntag(CAST(LoadObjectField( table_var.value(), OrderedHashSet::NumberOfElementsOffset()))); TNode<IntPtrT> const new_number_of_deleted = SmiUntag(CAST(LoadObjectField( table_var.value(), OrderedHashSet::NumberOfDeletedElementsOffset()))); - occupancy.Bind(IntPtrAdd(new_number_of_elements, new_number_of_deleted)); + occupancy = IntPtrAdd(new_number_of_elements, new_number_of_deleted); Goto(&store_new_entry); } BIND(&store_new_entry); @@ -1779,15 +1866,16 @@ TF_BUILTIN(SetPrototypeAdd, CollectionsBuiltinsAssembler) { } void CollectionsBuiltinsAssembler::StoreOrderedHashSetNewEntry( - TNode<OrderedHashSet> const table, Node* const key, Node* const hash, - Node* const number_of_buckets, Node* const occupancy) { - TNode<WordT> const bucket = + TNode<OrderedHashSet> const table, const TNode<Object> key, + const TNode<IntPtrT> hash, const TNode<IntPtrT> number_of_buckets, + const TNode<IntPtrT> occupancy) { + TNode<IntPtrT> const bucket = WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1))); TNode<Smi> bucket_entry = CAST(UnsafeLoadFixedArrayElement( table, bucket, OrderedHashSet::HashTableStartIndex() * kTaggedSize)); // Store the entry elements. - TNode<WordT> const entry_start = IntPtrAdd( + TNode<IntPtrT> const entry_start = IntPtrAdd( IntPtrMul(occupancy, IntPtrConstant(OrderedHashSet::kEntrySize)), number_of_buckets); UnsafeStoreFixedArrayElement( @@ -1812,23 +1900,21 @@ void CollectionsBuiltinsAssembler::StoreOrderedHashSetNewEntry( } TF_BUILTIN(SetPrototypeDelete, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.delete"); TNode<OrderedHashSet> const table = - CAST(LoadObjectField(receiver, JSMap::kTableOffset)); + LoadObjectField<OrderedHashSet>(CAST(receiver), JSMap::kTableOffset); - VARIABLE(entry_start_position_or_hash, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position_or_hash, IntPtrConstant(0)); Label entry_found(this), not_found(this); - TryLookupOrderedHashTableIndex<OrderedHashSet>(table, key, context, - &entry_start_position_or_hash, - &entry_found, ¬_found); + TryLookupOrderedHashTableIndex<OrderedHashSet>( + table, key, &entry_start_position_or_hash, &entry_found, ¬_found); BIND(¬_found); Return(FalseConstant()); @@ -1869,29 +1955,30 @@ TF_BUILTIN(SetPrototypeDelete, CollectionsBuiltinsAssembler) { } TF_BUILTIN(MapPrototypeEntries, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.entries"); Return(AllocateJSCollectionIterator<JSMapIterator>( - context, Context::MAP_KEY_VALUE_ITERATOR_MAP_INDEX, receiver)); + context, Context::MAP_KEY_VALUE_ITERATOR_MAP_INDEX, CAST(receiver))); } TF_BUILTIN(MapPrototypeGetSize, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "get Map.prototype.size"); TNode<OrderedHashMap> const table = - CAST(LoadObjectField(receiver, JSMap::kTableOffset)); + LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset); Return(LoadObjectField(table, OrderedHashMap::NumberOfElementsOffset())); } TF_BUILTIN(MapPrototypeForEach, CollectionsBuiltinsAssembler) { const char* const kMethodName = "Map.prototype.forEach"; - Node* const argc = Parameter(Descriptor::kJSActualArgumentsCount); - Node* const context = Parameter(Descriptor::kContext); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + CodeStubArguments args(this, argc); TNode<Object> const receiver = args.GetReceiver(); TNode<Object> const callback = args.GetOptionalArgumentValue(0); TNode<Object> const this_arg = args.GetOptionalArgumentValue(1); @@ -1914,8 +2001,8 @@ TF_BUILTIN(MapPrototypeForEach, CollectionsBuiltinsAssembler) { // the {receiver} while we're iterating. TNode<IntPtrT> index = var_index.value(); TNode<OrderedHashMap> table = var_table.value(); - std::tie(table, index) = - Transition<OrderedHashMap>(table, index, [](Node*, Node*) {}); + std::tie(table, index) = Transition<OrderedHashMap>( + table, index, [](const TNode<OrderedHashMap>, const TNode<IntPtrT>) {}); // Read the next entry from the {table}, skipping holes. TNode<Object> entry_key; @@ -1951,31 +2038,32 @@ TF_BUILTIN(MapPrototypeForEach, CollectionsBuiltinsAssembler) { } TF_BUILTIN(MapPrototypeKeys, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.keys"); Return(AllocateJSCollectionIterator<JSMapIterator>( - context, Context::MAP_KEY_ITERATOR_MAP_INDEX, receiver)); + context, Context::MAP_KEY_ITERATOR_MAP_INDEX, CAST(receiver))); } TF_BUILTIN(MapPrototypeValues, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.values"); Return(AllocateJSCollectionIterator<JSMapIterator>( - context, Context::MAP_VALUE_ITERATOR_MAP_INDEX, receiver)); + context, Context::MAP_VALUE_ITERATOR_MAP_INDEX, CAST(receiver))); } TF_BUILTIN(MapIteratorPrototypeNext, CollectionsBuiltinsAssembler) { const char* const kMethodName = "Map Iterator.prototype.next"; - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // Ensure that the {receiver} is actually a JSMapIterator. Label if_receiver_valid(this), if_receiver_invalid(this, Label::kDeferred); GotoIf(TaggedIsSmi(receiver), &if_receiver_invalid); - TNode<Uint16T> const receiver_instance_type = LoadInstanceType(receiver); + TNode<Uint16T> const receiver_instance_type = + LoadInstanceType(CAST(receiver)); GotoIf( InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_VALUE_ITERATOR_TYPE), &if_receiver_valid); @@ -1989,8 +2077,8 @@ TF_BUILTIN(MapIteratorPrototypeNext, CollectionsBuiltinsAssembler) { BIND(&if_receiver_valid); // Check if the {receiver} is exhausted. - VARIABLE(var_done, MachineRepresentation::kTagged, TrueConstant()); - VARIABLE(var_value, MachineRepresentation::kTagged, UndefinedConstant()); + TVARIABLE(Oddball, var_done, TrueConstant()); + TVARIABLE(Object, var_value, UndefinedConstant()); Label return_value(this, {&var_done, &var_value}), return_entry(this), return_end(this, Label::kDeferred); @@ -2007,22 +2095,22 @@ TF_BUILTIN(MapIteratorPrototypeNext, CollectionsBuiltinsAssembler) { NextSkipHoles<OrderedHashMap>(table, index, &return_end); StoreObjectFieldNoWriteBarrier(receiver, JSMapIterator::kIndexOffset, SmiTag(index)); - var_value.Bind(entry_key); - var_done.Bind(FalseConstant()); + var_value = entry_key; + var_done = FalseConstant(); // Check how to return the {key} (depending on {receiver} type). GotoIf(InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_ITERATOR_TYPE), &return_value); - var_value.Bind(LoadFixedArrayElement( + var_value = LoadFixedArrayElement( table, entry_start_position, (OrderedHashMap::HashTableStartIndex() + OrderedHashMap::kValueOffset) * - kTaggedSize)); + kTaggedSize); Branch(InstanceTypeEqual(receiver_instance_type, JS_MAP_VALUE_ITERATOR_TYPE), &return_value, &return_entry); BIND(&return_entry); { - Node* result = + TNode<JSObject> result = AllocateJSIteratorResultForEntry(context, entry_key, var_value.value()); Return(result); } @@ -2043,23 +2131,22 @@ TF_BUILTIN(MapIteratorPrototypeNext, CollectionsBuiltinsAssembler) { } TF_BUILTIN(SetPrototypeHas, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.has"); - TNode<Object> const table = LoadObjectField(receiver, JSMap::kTableOffset); + TNode<Object> const table = + LoadObjectField(CAST(receiver), JSMap::kTableOffset); - VARIABLE(entry_start_position, MachineType::PointerRepresentation(), - IntPtrConstant(0)); - VARIABLE(result, MachineRepresentation::kTaggedSigned, IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position, IntPtrConstant(0)); Label if_key_smi(this), if_key_string(this), if_key_heap_number(this), if_key_bigint(this), entry_found(this), not_found(this), done(this); GotoIf(TaggedIsSmi(key), &if_key_smi); - TNode<Map> key_map = LoadMap(key); + TNode<Map> key_map = LoadMap(CAST(key)); TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map); GotoIf(IsStringInstanceType(key_instance_type), &if_key_string); @@ -2067,30 +2154,34 @@ TF_BUILTIN(SetPrototypeHas, CollectionsBuiltinsAssembler) { GotoIf(IsBigIntInstanceType(key_instance_type), &if_key_bigint); FindOrderedHashTableEntryForOtherKey<OrderedHashSet>( - context, table, key, &entry_start_position, &entry_found, ¬_found); + CAST(table), CAST(key), &entry_start_position, &entry_found, ¬_found); BIND(&if_key_smi); { FindOrderedHashTableEntryForSmiKey<OrderedHashSet>( - table, key, &entry_start_position, &entry_found, ¬_found); + CAST(table), CAST(key), &entry_start_position, &entry_found, + ¬_found); } BIND(&if_key_string); { FindOrderedHashTableEntryForStringKey<OrderedHashSet>( - context, table, key, &entry_start_position, &entry_found, ¬_found); + CAST(table), CAST(key), &entry_start_position, &entry_found, + ¬_found); } BIND(&if_key_heap_number); { FindOrderedHashTableEntryForHeapNumberKey<OrderedHashSet>( - context, table, key, &entry_start_position, &entry_found, ¬_found); + CAST(table), CAST(key), &entry_start_position, &entry_found, + ¬_found); } BIND(&if_key_bigint); { FindOrderedHashTableEntryForBigIntKey<OrderedHashSet>( - context, table, key, &entry_start_position, &entry_found, ¬_found); + CAST(table), CAST(key), &entry_start_position, &entry_found, + ¬_found); } BIND(&entry_found); @@ -2101,29 +2192,30 @@ TF_BUILTIN(SetPrototypeHas, CollectionsBuiltinsAssembler) { } TF_BUILTIN(SetPrototypeEntries, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.entries"); Return(AllocateJSCollectionIterator<JSSetIterator>( - context, Context::SET_KEY_VALUE_ITERATOR_MAP_INDEX, receiver)); + context, Context::SET_KEY_VALUE_ITERATOR_MAP_INDEX, CAST(receiver))); } TF_BUILTIN(SetPrototypeGetSize, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "get Set.prototype.size"); TNode<OrderedHashSet> const table = - CAST(LoadObjectField(receiver, JSSet::kTableOffset)); + LoadObjectField<OrderedHashSet>(CAST(receiver), JSSet::kTableOffset); Return(LoadObjectField(table, OrderedHashSet::NumberOfElementsOffset())); } TF_BUILTIN(SetPrototypeForEach, CollectionsBuiltinsAssembler) { const char* const kMethodName = "Set.prototype.forEach"; - Node* const argc = Parameter(Descriptor::kJSActualArgumentsCount); - Node* const context = Parameter(Descriptor::kContext); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + CodeStubArguments args(this, argc); TNode<Object> const receiver = args.GetReceiver(); TNode<Object> const callback = args.GetOptionalArgumentValue(0); TNode<Object> const this_arg = args.GetOptionalArgumentValue(1); @@ -2146,12 +2238,12 @@ TF_BUILTIN(SetPrototypeForEach, CollectionsBuiltinsAssembler) { // the {receiver} while we're iterating. TNode<IntPtrT> index = var_index.value(); TNode<OrderedHashSet> table = var_table.value(); - std::tie(table, index) = - Transition<OrderedHashSet>(table, index, [](Node*, Node*) {}); + std::tie(table, index) = Transition<OrderedHashSet>( + table, index, [](const TNode<OrderedHashSet>, const TNode<IntPtrT>) {}); // Read the next entry from the {table}, skipping holes. - Node* entry_key; - Node* entry_start_position; + TNode<Object> entry_key; + TNode<IntPtrT> entry_start_position; std::tie(entry_key, entry_start_position, index) = NextSkipHoles<OrderedHashSet>(table, index, &done_loop); @@ -2176,23 +2268,24 @@ TF_BUILTIN(SetPrototypeForEach, CollectionsBuiltinsAssembler) { } TF_BUILTIN(SetPrototypeValues, CollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, "Set.prototype.values"); Return(AllocateJSCollectionIterator<JSSetIterator>( - context, Context::SET_VALUE_ITERATOR_MAP_INDEX, receiver)); + context, Context::SET_VALUE_ITERATOR_MAP_INDEX, CAST(receiver))); } TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) { const char* const kMethodName = "Set Iterator.prototype.next"; - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // Ensure that the {receiver} is actually a JSSetIterator. Label if_receiver_valid(this), if_receiver_invalid(this, Label::kDeferred); GotoIf(TaggedIsSmi(receiver), &if_receiver_invalid); - TNode<Uint16T> const receiver_instance_type = LoadInstanceType(receiver); + TNode<Uint16T> const receiver_instance_type = + LoadInstanceType(CAST(receiver)); GotoIf(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE), &if_receiver_valid); Branch( @@ -2204,8 +2297,8 @@ TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) { BIND(&if_receiver_valid); // Check if the {receiver} is exhausted. - VARIABLE(var_done, MachineRepresentation::kTagged, TrueConstant()); - VARIABLE(var_value, MachineRepresentation::kTagged, UndefinedConstant()); + TVARIABLE(Oddball, var_done, TrueConstant()); + TVARIABLE(Object, var_value, UndefinedConstant()); Label return_value(this, {&var_done, &var_value}), return_entry(this), return_end(this, Label::kDeferred); @@ -2216,14 +2309,14 @@ TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) { TransitionAndUpdate<JSSetIterator, OrderedHashSet>(CAST(receiver)); // Read the next entry from the {table}, skipping holes. - Node* entry_key; - Node* entry_start_position; + TNode<Object> entry_key; + TNode<IntPtrT> entry_start_position; std::tie(entry_key, entry_start_position, index) = NextSkipHoles<OrderedHashSet>(table, index, &return_end); StoreObjectFieldNoWriteBarrier(receiver, JSSetIterator::kIndexOffset, SmiTag(index)); - var_value.Bind(entry_key); - var_done.Bind(FalseConstant()); + var_value = entry_key; + var_done = FalseConstant(); // Check how to return the {key} (depending on {receiver} type). Branch(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE), @@ -2231,8 +2324,8 @@ TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) { BIND(&return_entry); { - Node* result = AllocateJSIteratorResultForEntry(context, var_value.value(), - var_value.value()); + TNode<JSObject> result = AllocateJSIteratorResultForEntry( + context, var_value.value(), var_value.value()); Return(result); } @@ -2253,14 +2346,14 @@ TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) { template <typename CollectionType> void CollectionsBuiltinsAssembler::TryLookupOrderedHashTableIndex( - Node* const table, Node* const key, Node* const context, Variable* result, - Label* if_entry_found, Label* if_not_found) { + const TNode<CollectionType> table, const TNode<Object> key, + TVariable<IntPtrT>* result, Label* if_entry_found, Label* if_not_found) { Label if_key_smi(this), if_key_string(this), if_key_heap_number(this), if_key_bigint(this); GotoIf(TaggedIsSmi(key), &if_key_smi); - TNode<Map> key_map = LoadMap(key); + TNode<Map> key_map = LoadMap(CAST(key)); TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map); GotoIf(IsStringInstanceType(key_instance_type), &if_key_string); @@ -2268,44 +2361,42 @@ void CollectionsBuiltinsAssembler::TryLookupOrderedHashTableIndex( GotoIf(IsBigIntInstanceType(key_instance_type), &if_key_bigint); FindOrderedHashTableEntryForOtherKey<CollectionType>( - context, table, key, result, if_entry_found, if_not_found); + table, CAST(key), result, if_entry_found, if_not_found); BIND(&if_key_smi); { FindOrderedHashTableEntryForSmiKey<CollectionType>( - table, key, result, if_entry_found, if_not_found); + table, CAST(key), result, if_entry_found, if_not_found); } BIND(&if_key_string); { FindOrderedHashTableEntryForStringKey<CollectionType>( - context, table, key, result, if_entry_found, if_not_found); + table, CAST(key), result, if_entry_found, if_not_found); } BIND(&if_key_heap_number); { FindOrderedHashTableEntryForHeapNumberKey<CollectionType>( - context, table, key, result, if_entry_found, if_not_found); + table, CAST(key), result, if_entry_found, if_not_found); } BIND(&if_key_bigint); { FindOrderedHashTableEntryForBigIntKey<CollectionType>( - context, table, key, result, if_entry_found, if_not_found); + table, CAST(key), result, if_entry_found, if_not_found); } } TF_BUILTIN(FindOrderedHashMapEntry, CollectionsBuiltinsAssembler) { - Node* const table = Parameter(Descriptor::kTable); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<OrderedHashMap> table = CAST(Parameter(Descriptor::kTable)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); - VARIABLE(entry_start_position, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + TVARIABLE(IntPtrT, entry_start_position, IntPtrConstant(0)); Label entry_found(this), not_found(this); TryLookupOrderedHashTableIndex<OrderedHashMap>( - table, key, context, &entry_start_position, &entry_found, ¬_found); + table, key, &entry_start_position, &entry_found, ¬_found); BIND(&entry_found); Return(SmiTag(entry_start_position.value())); @@ -2324,8 +2415,8 @@ class WeakCollectionsBuiltinsAssembler : public BaseCollectionsAssembler { TNode<Object> key, TNode<Object> value, TNode<IntPtrT> number_of_elements); - TNode<Object> AllocateTable(Variant variant, TNode<Context> context, - TNode<IntPtrT> at_least_space_for) override; + TNode<HeapObject> AllocateTable(Variant variant, + TNode<IntPtrT> at_least_space_for) override; // Generates and sets the identity for a JSRececiver. TNode<Smi> CreateIdentityHash(TNode<Object> receiver); @@ -2390,9 +2481,8 @@ void WeakCollectionsBuiltinsAssembler::AddEntry( SmiFromIntPtr(number_of_elements), SKIP_WRITE_BARRIER); } -TNode<Object> WeakCollectionsBuiltinsAssembler::AllocateTable( - Variant variant, TNode<Context> context, - TNode<IntPtrT> at_least_space_for) { +TNode<HeapObject> WeakCollectionsBuiltinsAssembler::AllocateTable( + Variant variant, TNode<IntPtrT> at_least_space_for) { // See HashTable::New(). CSA_ASSERT(this, IntPtrLessThanOrEqual(IntPtrConstant(0), at_least_space_for)); @@ -2446,8 +2536,7 @@ TNode<IntPtrT> WeakCollectionsBuiltinsAssembler::FindKeyIndex( TVARIABLE(IntPtrT, var_entry, WordAnd(key_hash, entry_mask)); TVARIABLE(IntPtrT, var_count, IntPtrConstant(0)); - Variable* loop_vars[] = {&var_count, &var_entry}; - Label loop(this, arraysize(loop_vars), loop_vars), if_found(this); + Label loop(this, {&var_count, &var_entry}), if_found(this); Goto(&loop); BIND(&loop); TNode<IntPtrT> key_index; @@ -2631,9 +2720,9 @@ TF_BUILTIN(WeakMapLookupHashIndex, WeakCollectionsBuiltinsAssembler) { } TF_BUILTIN(WeakMapGet, WeakCollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label return_undefined(this); @@ -2653,9 +2742,9 @@ TF_BUILTIN(WeakMapGet, WeakCollectionsBuiltinsAssembler) { } TF_BUILTIN(WeakMapPrototypeHas, WeakCollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label return_false(this); @@ -2817,9 +2906,9 @@ TF_BUILTIN(WeakSetPrototypeDelete, CodeStubAssembler) { } TF_BUILTIN(WeakSetPrototypeHas, WeakCollectionsBuiltinsAssembler) { - Node* const receiver = Parameter(Descriptor::kReceiver); - Node* const key = Parameter(Descriptor::kKey); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label return_false(this); diff --git a/deps/v8/src/builtins/builtins-collections-gen.h b/deps/v8/src/builtins/builtins-collections-gen.h index 2bde108e9aeffa..a132557e3cd0a4 100644 --- a/deps/v8/src/builtins/builtins-collections-gen.h +++ b/deps/v8/src/builtins/builtins-collections-gen.h @@ -11,13 +11,13 @@ namespace v8 { namespace internal { void BranchIfIterableWithOriginalKeyOrValueMapIterator( - compiler::CodeAssemblerState* state, compiler::TNode<Object> iterable, - compiler::TNode<Context> context, compiler::CodeAssemblerLabel* if_true, + compiler::CodeAssemblerState* state, TNode<Object> iterable, + TNode<Context> context, compiler::CodeAssemblerLabel* if_true, compiler::CodeAssemblerLabel* if_false); void BranchIfIterableWithOriginalValueSetIterator( - compiler::CodeAssemblerState* state, compiler::TNode<Object> iterable, - compiler::TNode<Context> context, compiler::CodeAssemblerLabel* if_true, + compiler::CodeAssemblerState* state, TNode<Object> iterable, + TNode<Context> context, compiler::CodeAssemblerLabel* if_true, compiler::CodeAssemblerLabel* if_false); } // namespace internal diff --git a/deps/v8/src/builtins/builtins-console-gen.cc b/deps/v8/src/builtins/builtins-console-gen.cc index 1d6a22f61118f6..8a4c8b83da35d0 100644 --- a/deps/v8/src/builtins/builtins-console-gen.cc +++ b/deps/v8/src/builtins/builtins-console-gen.cc @@ -15,15 +15,13 @@ TF_BUILTIN(FastConsoleAssert, CodeStubAssembler) { Label runtime(this); Label out(this); - // TODO(ishell): use constants from Descriptor once the JSFunction linkage - // arguments are reordered. TNode<Int32T> argc = UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); - Node* context = Parameter(Descriptor::kContext); - Node* new_target = Parameter(Descriptor::kJSNewTarget); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget)); GotoIf(Word32Equal(argc, Int32Constant(0)), &runtime); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); BranchIfToBooleanIsTrue(args.AtIndex(0), &out, &runtime); BIND(&out); args.PopAndReturn(UndefinedConstant()); diff --git a/deps/v8/src/builtins/builtins-console.cc b/deps/v8/src/builtins/builtins-console.cc index 28c9261ed41fdc..bc743b6e70a8d2 100644 --- a/deps/v8/src/builtins/builtins-console.cc +++ b/deps/v8/src/builtins/builtins-console.cc @@ -39,8 +39,7 @@ namespace internal { namespace { void ConsoleCall( - Isolate* isolate, - internal::BuiltinArguments& args, // NOLINT(runtime/references) + Isolate* isolate, const internal::BuiltinArguments& args, void (debug::ConsoleDelegate::*func)(const v8::debug::ConsoleCallArguments&, const v8::debug::ConsoleContext&)) { CHECK(!isolate->has_pending_exception()); diff --git a/deps/v8/src/builtins/builtins-constructor-gen.cc b/deps/v8/src/builtins/builtins-constructor-gen.cc index 856718cedfbf0a..bc03e86f791d46 100644 --- a/deps/v8/src/builtins/builtins-constructor-gen.cc +++ b/deps/v8/src/builtins/builtins-constructor-gen.cc @@ -57,12 +57,11 @@ TF_BUILTIN(ConstructWithSpread, CallOrConstructBuiltinsAssembler) { using Node = compiler::Node; TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) { - Node* shared_function_info = Parameter(Descriptor::kSharedFunctionInfo); - Node* feedback_cell = Parameter(Descriptor::kFeedbackCell); - Node* context = Parameter(Descriptor::kContext); - - CSA_ASSERT(this, IsFeedbackCell(feedback_cell)); - CSA_ASSERT(this, IsSharedFunctionInfo(shared_function_info)); + TNode<SharedFunctionInfo> shared_function_info = + CAST(Parameter(Descriptor::kSharedFunctionInfo)); + TNode<FeedbackCell> feedback_cell = + CAST(Parameter(Descriptor::kFeedbackCell)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); IncrementCounter(isolate()->counters()->fast_new_closure_total(), 1); @@ -90,9 +89,8 @@ TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) { // The calculation of |function_map_index| must be in sync with // SharedFunctionInfo::function_map_index(). - Node* const flags = - LoadObjectField(shared_function_info, SharedFunctionInfo::kFlagsOffset, - MachineType::Uint32()); + TNode<Uint32T> flags = LoadObjectField<Uint32T>( + shared_function_info, SharedFunctionInfo::kFlagsOffset); TNode<IntPtrT> const function_map_index = Signed(IntPtrAdd( DecodeWordFromWord32<SharedFunctionInfo::FunctionMapIndexBits>(flags), IntPtrConstant(Context::FIRST_FUNCTION_MAP_INDEX))); @@ -161,7 +159,7 @@ TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) { TailCallRuntime(Runtime::kNewObject, context, target, new_target); } -compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( +TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( SloppyTNode<Context> context, SloppyTNode<JSFunction> target, SloppyTNode<JSReceiver> new_target) { TVARIABLE(JSObject, var_obj); @@ -178,7 +176,7 @@ compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( return var_obj.value(); } -compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( +TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( SloppyTNode<Context> context, SloppyTNode<JSFunction> target, SloppyTNode<JSReceiver> new_target, Label* call_runtime) { // Verify that the new target is a JSFunction. @@ -202,17 +200,17 @@ compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset); GotoIf(TaggedNotEqual(target, new_target_constructor), call_runtime); - VARIABLE(properties, MachineRepresentation::kTagged); + TVARIABLE(HeapObject, properties); Label instantiate_map(this), allocate_properties(this); GotoIf(IsDictionaryMap(initial_map), &allocate_properties); { - properties.Bind(EmptyFixedArrayConstant()); + properties = EmptyFixedArrayConstant(); Goto(&instantiate_map); } BIND(&allocate_properties); { - properties.Bind(AllocateNameDictionary(NameDictionary::kInitialCapacity)); + properties = AllocateNameDictionary(NameDictionary::kInitialCapacity); Goto(&instantiate_map); } @@ -221,11 +219,12 @@ compiler::TNode<JSObject> ConstructorBuiltinsAssembler::EmitFastNewObject( kNone, kWithSlackTracking); } -Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext( - Node* scope_info, Node* slots_uint32, Node* context, ScopeType scope_type) { - TNode<IntPtrT> slots = Signed(ChangeUint32ToWord(slots_uint32)); - TNode<IntPtrT> size = ElementOffsetFromIndex( - slots, PACKED_ELEMENTS, INTPTR_PARAMETERS, Context::kTodoHeaderSize); +TNode<Context> ConstructorBuiltinsAssembler::EmitFastNewFunctionContext( + TNode<ScopeInfo> scope_info, TNode<Uint32T> slots, TNode<Context> context, + ScopeType scope_type) { + TNode<IntPtrT> slots_intptr = Signed(ChangeUint32ToWord(slots)); + TNode<IntPtrT> size = ElementOffsetFromIndex(slots_intptr, PACKED_ELEMENTS, + Context::kTodoHeaderSize); // Create a new closure from the given function info in new space TNode<Context> function_context = @@ -246,7 +245,7 @@ Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext( StoreMapNoWriteBarrier(function_context, context_type); TNode<IntPtrT> min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS); // TODO(ishell): for now, length also includes MIN_CONTEXT_SLOTS. - TNode<IntPtrT> length = IntPtrAdd(slots, min_context_slots); + TNode<IntPtrT> length = IntPtrAdd(slots_intptr, min_context_slots); StoreObjectFieldNoWriteBarrier(function_context, Context::kLengthOffset, SmiTag(length)); StoreObjectFieldNoWriteBarrier(function_context, Context::kScopeInfoOffset, @@ -263,60 +262,60 @@ Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext( TNode<Oddball> undefined = UndefinedConstant(); TNode<IntPtrT> start_offset = IntPtrConstant(Context::kTodoHeaderSize); CodeStubAssembler::VariableList vars(0, zone()); - BuildFastLoop( + BuildFastLoop<IntPtrT>( vars, start_offset, size, - [=](Node* offset) { - StoreObjectFieldNoWriteBarrier( - function_context, UncheckedCast<IntPtrT>(offset), undefined); + [=](TNode<IntPtrT> offset) { + StoreObjectFieldNoWriteBarrier(function_context, offset, undefined); }, - kTaggedSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kTaggedSize, IndexAdvanceMode::kPost); return function_context; } TF_BUILTIN(FastNewFunctionContextEval, ConstructorBuiltinsAssembler) { - Node* scope_info = Parameter(Descriptor::kScopeInfo); - Node* slots = Parameter(Descriptor::kSlots); - Node* context = Parameter(Descriptor::kContext); + TNode<ScopeInfo> scope_info = CAST(Parameter(Descriptor::kScopeInfo)); + TNode<Uint32T> slots = UncheckedCast<Uint32T>(Parameter(Descriptor::kSlots)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(EmitFastNewFunctionContext(scope_info, slots, context, ScopeType::EVAL_SCOPE)); } TF_BUILTIN(FastNewFunctionContextFunction, ConstructorBuiltinsAssembler) { - Node* scope_info = Parameter(Descriptor::kScopeInfo); - Node* slots = Parameter(Descriptor::kSlots); - Node* context = Parameter(Descriptor::kContext); + TNode<ScopeInfo> scope_info = CAST(Parameter(Descriptor::kScopeInfo)); + TNode<Uint32T> slots = UncheckedCast<Uint32T>(Parameter(Descriptor::kSlots)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(EmitFastNewFunctionContext(scope_info, slots, context, ScopeType::FUNCTION_SCOPE)); } -Node* ConstructorBuiltinsAssembler::EmitCreateRegExpLiteral( - Node* feedback_vector, Node* slot, Node* pattern, Node* flags, - Node* context) { +TNode<JSRegExp> ConstructorBuiltinsAssembler::EmitCreateRegExpLiteral( + TNode<HeapObject> maybe_feedback_vector, TNode<UintPtrT> slot, + TNode<Object> pattern, TNode<Smi> flags, TNode<Context> context) { Label call_runtime(this, Label::kDeferred), end(this); - GotoIf(IsUndefined(feedback_vector), &call_runtime); + GotoIf(IsUndefined(maybe_feedback_vector), &call_runtime); - VARIABLE(result, MachineRepresentation::kTagged); + TVARIABLE(JSRegExp, result); + TNode<FeedbackVector> feedback_vector = CAST(maybe_feedback_vector); TNode<Object> literal_site = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS)); + CAST(LoadFeedbackVectorSlot(feedback_vector, slot)); GotoIf(NotHasBoilerplate(literal_site), &call_runtime); { - Node* boilerplate = literal_site; - CSA_ASSERT(this, IsJSRegExp(boilerplate)); + TNode<JSRegExp> boilerplate = CAST(literal_site); int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kTaggedSize; TNode<HeapObject> copy = Allocate(size); for (int offset = 0; offset < size; offset += kTaggedSize) { TNode<Object> value = LoadObjectField(boilerplate, offset); StoreObjectFieldNoWriteBarrier(copy, offset, value); } - result.Bind(copy); + result = CAST(copy); Goto(&end); } BIND(&call_runtime); { - result.Bind(CallRuntime(Runtime::kCreateRegExpLiteral, context, - feedback_vector, SmiTag(slot), pattern, flags)); + result = CAST(CallRuntime(Runtime::kCreateRegExpLiteral, context, + maybe_feedback_vector, SmiTag(Signed(slot)), + pattern, flags)); Goto(&end); } @@ -325,25 +324,26 @@ Node* ConstructorBuiltinsAssembler::EmitCreateRegExpLiteral( } TF_BUILTIN(CreateRegExpLiteral, ConstructorBuiltinsAssembler) { - Node* feedback_vector = Parameter(Descriptor::kFeedbackVector); - TNode<IntPtrT> slot = SmiUntag(Parameter(Descriptor::kSlot)); - Node* pattern = Parameter(Descriptor::kPattern); - Node* flags = Parameter(Descriptor::kFlags); - Node* context = Parameter(Descriptor::kContext); - Node* result = - EmitCreateRegExpLiteral(feedback_vector, slot, pattern, flags, context); + TNode<HeapObject> maybe_feedback_vector = + CAST(Parameter(Descriptor::kFeedbackVector)); + TNode<UintPtrT> slot = Unsigned(SmiUntag(Parameter(Descriptor::kSlot))); + TNode<Object> pattern = CAST(Parameter(Descriptor::kPattern)); + TNode<Smi> flags = CAST(Parameter(Descriptor::kFlags)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<JSRegExp> result = EmitCreateRegExpLiteral(maybe_feedback_vector, slot, + pattern, flags, context); Return(result); } -Node* ConstructorBuiltinsAssembler::EmitCreateShallowArrayLiteral( - Node* feedback_vector, Node* slot, Node* context, Label* call_runtime, +TNode<JSArray> ConstructorBuiltinsAssembler::EmitCreateShallowArrayLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<Context> context, Label* call_runtime, AllocationSiteMode allocation_site_mode) { Label zero_capacity(this), cow_elements(this), fast_elements(this), return_result(this); - VARIABLE(result, MachineRepresentation::kTagged); TNode<Object> maybe_allocation_site = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS)); + CAST(LoadFeedbackVectorSlot(feedback_vector, slot)); GotoIf(NotHasBoilerplate(maybe_allocation_site), call_runtime); TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site); @@ -358,10 +358,12 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowArrayLiteral( } TF_BUILTIN(CreateShallowArrayLiteral, ConstructorBuiltinsAssembler) { - Node* feedback_vector = Parameter(Descriptor::kFeedbackVector); - TNode<IntPtrT> slot = SmiUntag(Parameter(Descriptor::kSlot)); - Node* constant_elements = Parameter(Descriptor::kConstantElements); - Node* context = Parameter(Descriptor::kContext); + TNode<FeedbackVector> feedback_vector = + CAST(Parameter(Descriptor::kFeedbackVector)); + TNode<UintPtrT> slot = Unsigned(SmiUntag(Parameter(Descriptor::kSlot))); + TNode<ArrayBoilerplateDescription> constant_elements = + CAST(Parameter(Descriptor::kConstantElements)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label call_runtime(this, Label::kDeferred); Return(EmitCreateShallowArrayLiteral(feedback_vector, slot, context, &call_runtime, @@ -373,16 +375,18 @@ TF_BUILTIN(CreateShallowArrayLiteral, ConstructorBuiltinsAssembler) { int const flags = AggregateLiteral::kDisableMementos | AggregateLiteral::kIsShallow; Return(CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector, - SmiTag(slot), constant_elements, SmiConstant(flags))); + SmiTag(Signed(slot)), constant_elements, + SmiConstant(flags))); } } -Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( - Node* feedback_vector, Node* slot, Node* context) { +TNode<JSArray> ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<Context> context) { // Array literals always have a valid AllocationSite to properly track // elements transitions. TNode<Object> maybe_allocation_site = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS)); + CAST(LoadFeedbackVectorSlot(feedback_vector, slot)); TVARIABLE(AllocationSite, allocation_site); Label create_empty_array(this), @@ -396,7 +400,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( BIND(&initialize_allocation_site); { allocation_site = - CreateAllocationSiteInFeedbackVector(feedback_vector, SmiTag(slot)); + CreateAllocationSiteInFeedbackVector(feedback_vector, slot); Goto(&create_empty_array); } @@ -418,17 +422,20 @@ Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral( } TF_BUILTIN(CreateEmptyArrayLiteral, ConstructorBuiltinsAssembler) { - Node* feedback_vector = Parameter(Descriptor::kFeedbackVector); - TNode<IntPtrT> slot = SmiUntag(Parameter(Descriptor::kSlot)); - Node* context = Parameter(Descriptor::kContext); - Node* result = EmitCreateEmptyArrayLiteral(feedback_vector, slot, context); + TNode<FeedbackVector> feedback_vector = + CAST(Parameter(Descriptor::kFeedbackVector)); + TNode<UintPtrT> slot = Unsigned(SmiUntag(Parameter(Descriptor::kSlot))); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<JSArray> result = + EmitCreateEmptyArrayLiteral(feedback_vector, slot, context); Return(result); } -Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( - Node* feedback_vector, Node* slot, Label* call_runtime) { +TNode<HeapObject> ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + Label* call_runtime) { TNode<Object> maybe_allocation_site = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS)); + CAST(LoadFeedbackVectorSlot(feedback_vector, slot)); GotoIf(NotHasBoilerplate(maybe_allocation_site), call_runtime); TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site); @@ -436,7 +443,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( TNode<Map> boilerplate_map = LoadMap(boilerplate); CSA_ASSERT(this, IsJSObjectMap(boilerplate_map)); - VARIABLE(var_properties, MachineRepresentation::kTagged); + TVARIABLE(FixedArray, var_properties); { TNode<Uint32T> bit_field_3 = LoadMapBitField3(boilerplate_map); GotoIf(IsSetWord32<Map::IsDeprecatedBit>(bit_field_3), call_runtime); @@ -447,8 +454,8 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( BIND(&if_dictionary); { Comment("Copy dictionary properties"); - var_properties.Bind(CopyNameDictionary( - CAST(LoadSlowProperties(boilerplate)), call_runtime)); + var_properties = CopyNameDictionary(CAST(LoadSlowProperties(boilerplate)), + call_runtime); // Slow objects have no in-object properties. Goto(&done); } @@ -458,13 +465,13 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( TNode<HeapObject> boilerplate_properties = LoadFastProperties(boilerplate); GotoIfNot(IsEmptyFixedArray(boilerplate_properties), call_runtime); - var_properties.Bind(EmptyFixedArrayConstant()); + var_properties = EmptyFixedArrayConstant(); Goto(&done); } BIND(&done); } - VARIABLE(var_elements, MachineRepresentation::kTagged); + TVARIABLE(FixedArrayBase, var_elements); { // Copy the elements backing store, assuming that it's flat. Label if_empty_fixed_array(this), if_copy_elements(this), done(this); @@ -473,7 +480,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( &if_copy_elements); BIND(&if_empty_fixed_array); - var_elements.Bind(boilerplate_elements); + var_elements = boilerplate_elements; Goto(&done); BIND(&if_copy_elements); @@ -483,7 +490,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( flags |= ExtractFixedArrayFlag::kAllFixedArrays; flags |= ExtractFixedArrayFlag::kNewSpaceAllocationOnly; flags |= ExtractFixedArrayFlag::kDontCopyCOW; - var_elements.Bind(CloneFixedArray(boilerplate_elements, flags)); + var_elements = CloneFixedArray(boilerplate_elements, flags); Goto(&done); BIND(&done); } @@ -563,18 +570,18 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( BIND(&continue_with_write_barrier); { Comment("Copy in-object properties slow"); - BuildFastLoop( + BuildFastLoop<IntPtrT>( offset.value(), instance_size, - [=](Node* offset) { + [=](TNode<IntPtrT> offset) { // TODO(ishell): value decompression is not necessary here. TNode<Object> field = LoadObjectField(boilerplate, offset); StoreObjectFieldNoWriteBarrier(copy, offset, field); }, - kTaggedSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kTaggedSize, IndexAdvanceMode::kPost); Comment("Copy mutable HeapNumber values"); - BuildFastLoop( + BuildFastLoop<IntPtrT>( offset.value(), instance_size, - [=](Node* offset) { + [=](TNode<IntPtrT> offset) { TNode<Object> field = LoadObjectField(copy, offset); Label copy_heap_number(this, Label::kDeferred), continue_loop(this); // We only have to clone complex field values. @@ -593,7 +600,7 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( } BIND(&continue_loop); }, - kTaggedSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kTaggedSize, IndexAdvanceMode::kPost); Goto(&done_init); } BIND(&done_init); @@ -603,29 +610,30 @@ Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral( TF_BUILTIN(CreateShallowObjectLiteral, ConstructorBuiltinsAssembler) { Label call_runtime(this); - Node* feedback_vector = Parameter(Descriptor::kFeedbackVector); - TNode<IntPtrT> slot = SmiUntag(Parameter(Descriptor::kSlot)); - Node* copy = + TNode<FeedbackVector> feedback_vector = + CAST(Parameter(Descriptor::kFeedbackVector)); + TNode<UintPtrT> slot = Unsigned(SmiUntag(Parameter(Descriptor::kSlot))); + TNode<HeapObject> copy = EmitCreateShallowObjectLiteral(feedback_vector, slot, &call_runtime); Return(copy); BIND(&call_runtime); - Node* object_boilerplate_description = - Parameter(Descriptor::kObjectBoilerplateDescription); - Node* flags = Parameter(Descriptor::kFlags); - Node* context = Parameter(Descriptor::kContext); + TNode<ObjectBoilerplateDescription> object_boilerplate_description = + CAST(Parameter(Descriptor::kObjectBoilerplateDescription)); + TNode<Smi> flags = CAST(Parameter(Descriptor::kFlags)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TailCallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector, - SmiTag(slot), object_boilerplate_description, flags); + SmiTag(Signed(slot)), object_boilerplate_description, flags); } // Used by the CreateEmptyObjectLiteral bytecode and the Object constructor. -Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral( - Node* context) { +TNode<JSObject> ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral( + TNode<Context> context) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> object_function = CAST(LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX)); - TNode<Map> map = CAST(LoadObjectField( - object_function, JSFunction::kPrototypeOrInitialMapOffset)); + TNode<Map> map = LoadObjectField<Map>( + object_function, JSFunction::kPrototypeOrInitialMapOffset); // Ensure that slack tracking is disabled for the map. STATIC_ASSERT(Map::kNoSlackTracking == 0); CSA_ASSERT( @@ -642,10 +650,10 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) { TNode<IntPtrT> argc = ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget)); - VARIABLE(var_result, MachineRepresentation::kTagged); + TVARIABLE(Object, var_result); Label if_subclass(this, Label::kDeferred), if_notsubclass(this), return_result(this); GotoIf(IsUndefined(new_target), &if_notsubclass); @@ -654,9 +662,8 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) { BIND(&if_subclass); { - TNode<Object> result = + var_result = CallBuiltin(Builtins::kFastNewObject, context, target, new_target); - var_result.Bind(result); Goto(&return_result); } @@ -672,15 +679,13 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) { BIND(&if_newobject); { - Node* result = EmitCreateEmptyObjectLiteral(context); - var_result.Bind(result); + var_result = EmitCreateEmptyObjectLiteral(context); Goto(&return_result); } BIND(&if_toobject); { - TNode<Object> result = CallBuiltin(Builtins::kToObject, context, value); - var_result.Bind(result); + var_result = CallBuiltin(Builtins::kToObject, context, value); Goto(&return_result); } } @@ -691,13 +696,13 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) { // ES #sec-number-constructor TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<IntPtrT> argc = ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); // 1. If no arguments were passed to this function invocation, let n be +0. - VARIABLE(var_n, MachineRepresentation::kTagged, SmiConstant(0)); + TVARIABLE(Number, var_n, SmiConstant(0)); Label if_nloaded(this, &var_n); GotoIf(IntPtrEqual(argc, IntPtrConstant(0)), &if_nloaded); @@ -706,14 +711,14 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) { // b. If Type(prim) is BigInt, let n be the Number value for prim. // c. Otherwise, let n be prim. TNode<Object> value = args.AtIndex(0); - var_n.Bind(ToNumber(context, value, BigIntHandling::kConvertToNumber)); + var_n = ToNumber(context, value, BigIntHandling::kConvertToNumber); Goto(&if_nloaded); BIND(&if_nloaded); { // 3. If NewTarget is undefined, return n. - Node* n_value = var_n.value(); - Node* new_target = Parameter(Descriptor::kJSNewTarget); + TNode<Number> n_value = var_n.value(); + TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget)); Label return_n(this), constructnumber(this, Label::kDeferred); Branch(IsUndefined(new_target), &return_n, &constructnumber); @@ -740,7 +745,7 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) { } TF_BUILTIN(GenericLazyDeoptContinuation, ConstructorBuiltinsAssembler) { - Node* result = Parameter(Descriptor::kResult); + TNode<Object> result = CAST(Parameter(Descriptor::kResult)); Return(result); } diff --git a/deps/v8/src/builtins/builtins-constructor-gen.h b/deps/v8/src/builtins/builtins-constructor-gen.h index 9208506c79eced..761a6c7adbc0a6 100644 --- a/deps/v8/src/builtins/builtins-constructor-gen.h +++ b/deps/v8/src/builtins/builtins-constructor-gen.h @@ -15,21 +15,28 @@ class ConstructorBuiltinsAssembler : public CodeStubAssembler { explicit ConstructorBuiltinsAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} - Node* EmitFastNewFunctionContext(Node* closure, Node* slots, Node* context, - ScopeType scope_type); - - Node* EmitCreateRegExpLiteral(Node* feedback_vector, Node* slot, - Node* pattern, Node* flags, Node* context); - Node* EmitCreateShallowArrayLiteral(Node* feedback_vector, Node* slot, - Node* context, Label* call_runtime, - AllocationSiteMode allocation_site_mode); - - Node* EmitCreateEmptyArrayLiteral(Node* feedback_vector, Node* slot, - Node* context); - - Node* EmitCreateShallowObjectLiteral(Node* feedback_vector, Node* slot, - Label* call_runtime); - Node* EmitCreateEmptyObjectLiteral(Node* context); + TNode<Context> EmitFastNewFunctionContext(TNode<ScopeInfo> scope_info, + TNode<Uint32T> slots, + TNode<Context> context, + ScopeType scope_type); + + TNode<JSRegExp> EmitCreateRegExpLiteral( + TNode<HeapObject> maybe_feedback_vector, TNode<UintPtrT> slot, + TNode<Object> pattern, TNode<Smi> flags, TNode<Context> context); + + TNode<JSArray> EmitCreateShallowArrayLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<Context> context, Label* call_runtime, + AllocationSiteMode allocation_site_mode); + + TNode<JSArray> EmitCreateEmptyArrayLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<Context> context); + + TNode<HeapObject> EmitCreateShallowObjectLiteral( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + Label* call_runtime); + TNode<JSObject> EmitCreateEmptyObjectLiteral(TNode<Context> context); TNode<JSObject> EmitFastNewObject(SloppyTNode<Context> context, SloppyTNode<JSFunction> target, diff --git a/deps/v8/src/builtins/builtins-conversion-gen.cc b/deps/v8/src/builtins/builtins-conversion-gen.cc index 8a0c73b29288af..1666cbf6acc41f 100644 --- a/deps/v8/src/builtins/builtins-conversion-gen.cc +++ b/deps/v8/src/builtins/builtins-conversion-gen.cc @@ -18,16 +18,17 @@ class ConversionBuiltinsAssembler : public CodeStubAssembler { : CodeStubAssembler(state) {} protected: - void Generate_NonPrimitiveToPrimitive(Node* context, Node* input, + void Generate_NonPrimitiveToPrimitive(TNode<Context> context, + TNode<Object> input, ToPrimitiveHint hint); - void Generate_OrdinaryToPrimitive(Node* context, Node* input, + void Generate_OrdinaryToPrimitive(TNode<Context> context, TNode<Object> input, OrdinaryToPrimitiveHint hint); }; // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) void ConversionBuiltinsAssembler::Generate_NonPrimitiveToPrimitive( - Node* context, Node* input, ToPrimitiveHint hint) { + TNode<Context> context, TNode<Object> input, ToPrimitiveHint hint) { // Lookup the @@toPrimitive property on the {input}. TNode<Object> exotic_to_prim = GetProperty(context, input, factory()->to_primitive_symbol()); @@ -42,14 +43,14 @@ void ConversionBuiltinsAssembler::Generate_NonPrimitiveToPrimitive( CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined); TNode<String> hint_string = HeapConstant(factory()->ToPrimitiveHintString(hint)); - Node* result = + TNode<Object> result = CallJS(callable, context, exotic_to_prim, input, hint_string); // Verify that the {result} is actually a primitive. Label if_resultisprimitive(this), if_resultisnotprimitive(this, Label::kDeferred); GotoIf(TaggedIsSmi(result), &if_resultisprimitive); - TNode<Uint16T> result_instance_type = LoadInstanceType(result); + TNode<Uint16T> result_instance_type = LoadInstanceType(CAST(result)); Branch(IsPrimitiveInstanceType(result_instance_type), &if_resultisprimitive, &if_resultisnotprimitive); @@ -78,22 +79,22 @@ void ConversionBuiltinsAssembler::Generate_NonPrimitiveToPrimitive( } TF_BUILTIN(NonPrimitiveToPrimitive_Default, ConversionBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Generate_NonPrimitiveToPrimitive(context, input, ToPrimitiveHint::kDefault); } TF_BUILTIN(NonPrimitiveToPrimitive_Number, ConversionBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Generate_NonPrimitiveToPrimitive(context, input, ToPrimitiveHint::kNumber); } TF_BUILTIN(NonPrimitiveToPrimitive_String, ConversionBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Generate_NonPrimitiveToPrimitive(context, input, ToPrimitiveHint::kString); } @@ -105,22 +106,22 @@ TF_BUILTIN(StringToNumber, CodeStubAssembler) { } TF_BUILTIN(ToName, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); - VARIABLE(var_input, MachineRepresentation::kTagged, input); + TVARIABLE(Object, var_input, input); Label loop(this, &var_input); Goto(&loop); BIND(&loop); { // Load the current {input} value. - Node* input = var_input.value(); + TNode<Object> input = var_input.value(); // Dispatch based on the type of the {input.} Label if_inputisbigint(this), if_inputisname(this), if_inputisnumber(this), if_inputisoddball(this), if_inputisreceiver(this, Label::kDeferred); GotoIf(TaggedIsSmi(input), &if_inputisnumber); - TNode<Uint16T> input_instance_type = LoadInstanceType(input); + TNode<Uint16T> input_instance_type = LoadInstanceType(CAST(input)); STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); GotoIf(IsNameInstanceType(input_instance_type), &if_inputisname); GotoIf(IsJSReceiverInstanceType(input_instance_type), &if_inputisreceiver); @@ -151,7 +152,7 @@ TF_BUILTIN(ToName, CodeStubAssembler) { { // Just return the {input}'s string representation. CSA_ASSERT(this, IsOddballInstanceType(input_instance_type)); - Return(LoadObjectField(input, Oddball::kToStringOffset)); + Return(LoadObjectField(CAST(input), Oddball::kToStringOffset)); } BIND(&if_inputisreceiver); @@ -159,23 +160,23 @@ TF_BUILTIN(ToName, CodeStubAssembler) { // Convert the JSReceiver {input} to a primitive first, // and then run the loop again with the new {input}, // which is then a primitive value. - var_input.Bind(CallBuiltin(Builtins::kNonPrimitiveToPrimitive_String, - context, input)); + var_input = CallBuiltin(Builtins::kNonPrimitiveToPrimitive_String, + context, input); Goto(&loop); } } } TF_BUILTIN(NonNumberToNumber, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<HeapObject> input = CAST(Parameter(Descriptor::kArgument)); Return(NonNumberToNumber(context, input)); } TF_BUILTIN(NonNumberToNumeric, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<HeapObject> input = CAST(Parameter(Descriptor::kArgument)); Return(NonNumberToNumeric(context, input)); } @@ -191,16 +192,19 @@ TF_BUILTIN(ToNumeric, CodeStubAssembler) { // ES6 section 7.1.3 ToNumber ( argument ) TF_BUILTIN(ToNumber, CodeStubAssembler) { + // TODO(solanes, v8:6949): Changing this to a TNode<Context> crashes with the + // empty context. Context might not be needed, but it is propagated all over + // the place and hard to pull out. Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Return(ToNumber(context, input)); } // Like ToNumber, but also converts BigInts. TF_BUILTIN(ToNumberConvertBigInt, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Return(ToNumber(context, input, BigIntHandling::kConvertToNumber)); } @@ -214,8 +218,8 @@ TF_BUILTIN(NumberToString, CodeStubAssembler) { // 7.1.1.1 OrdinaryToPrimitive ( O, hint ) void ConversionBuiltinsAssembler::Generate_OrdinaryToPrimitive( - Node* context, Node* input, OrdinaryToPrimitiveHint hint) { - VARIABLE(var_result, MachineRepresentation::kTagged); + TNode<Context> context, TNode<Object> input, OrdinaryToPrimitiveHint hint) { + TVARIABLE(Object, var_result); Label return_result(this, &var_result); Handle<String> method_names[2]; @@ -246,12 +250,12 @@ void ConversionBuiltinsAssembler::Generate_OrdinaryToPrimitive( // Call the {method} on the {input}. Callable callable = CodeFactory::Call( isolate(), ConvertReceiverMode::kNotNullOrUndefined); - Node* result = CallJS(callable, context, method, input); - var_result.Bind(result); + TNode<Object> result = CallJS(callable, context, method, input); + var_result = result; // Return the {result} if it is a primitive. GotoIf(TaggedIsSmi(result), &return_result); - TNode<Uint16T> result_instance_type = LoadInstanceType(result); + TNode<Uint16T> result_instance_type = LoadInstanceType(CAST(result)); GotoIf(IsPrimitiveInstanceType(result_instance_type), &return_result); } @@ -267,22 +271,22 @@ void ConversionBuiltinsAssembler::Generate_OrdinaryToPrimitive( } TF_BUILTIN(OrdinaryToPrimitive_Number, ConversionBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Generate_OrdinaryToPrimitive(context, input, OrdinaryToPrimitiveHint::kNumber); } TF_BUILTIN(OrdinaryToPrimitive_String, ConversionBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Generate_OrdinaryToPrimitive(context, input, OrdinaryToPrimitiveHint::kString); } // ES6 section 7.1.2 ToBoolean ( argument ) TF_BUILTIN(ToBoolean, CodeStubAssembler) { - Node* value = Parameter(Descriptor::kArgument); + TNode<Object> value = CAST(Parameter(Descriptor::kArgument)); Label return_true(this), return_false(this); BranchIfToBooleanIsTrue(value, &return_true, &return_false); @@ -298,7 +302,7 @@ TF_BUILTIN(ToBoolean, CodeStubAssembler) { // Requires parameter on stack so that it can be used as a continuation from a // LAZY deopt. TF_BUILTIN(ToBooleanLazyDeoptContinuation, CodeStubAssembler) { - Node* value = Parameter(Descriptor::kArgument); + TNode<Object> value = CAST(Parameter(Descriptor::kArgument)); Label return_true(this), return_false(this); BranchIfToBooleanIsTrue(value, &return_true, &return_false); @@ -311,11 +315,10 @@ TF_BUILTIN(ToBooleanLazyDeoptContinuation, CodeStubAssembler) { } TF_BUILTIN(ToLength, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // We might need to loop once for ToNumber conversion. - VARIABLE(var_len, MachineRepresentation::kTagged, - Parameter(Descriptor::kArgument)); + TVARIABLE(Object, var_len, CAST(Parameter(Descriptor::kArgument))); Label loop(this, &var_len); Goto(&loop); BIND(&loop); @@ -325,7 +328,7 @@ TF_BUILTIN(ToLength, CodeStubAssembler) { return_zero(this, Label::kDeferred); // Load the current {len} value. - Node* len = var_len.value(); + TNode<Object> len = var_len.value(); // Check if {len} is a positive Smi. GotoIf(TaggedIsPositiveSmi(len), &return_len); @@ -334,14 +337,16 @@ TF_BUILTIN(ToLength, CodeStubAssembler) { GotoIf(TaggedIsSmi(len), &return_zero); // Check if {len} is a HeapNumber. + TNode<HeapObject> len_heap_object = CAST(len); Label if_lenisheapnumber(this), if_lenisnotheapnumber(this, Label::kDeferred); - Branch(IsHeapNumber(len), &if_lenisheapnumber, &if_lenisnotheapnumber); + Branch(IsHeapNumber(len_heap_object), &if_lenisheapnumber, + &if_lenisnotheapnumber); BIND(&if_lenisheapnumber); { // Load the floating-point value of {len}. - TNode<Float64T> len_value = LoadHeapNumberValue(len); + TNode<Float64T> len_value = LoadHeapNumberValue(len_heap_object); // Check if {len} is not greater than zero. GotoIfNot(Float64GreaterThan(len_value, Float64Constant(0.0)), @@ -361,7 +366,7 @@ TF_BUILTIN(ToLength, CodeStubAssembler) { BIND(&if_lenisnotheapnumber); { // Need to convert {len} to a Number first. - var_len.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, len)); + var_len = CallBuiltin(Builtins::kNonNumberToNumber, context, len); Goto(&loop); } @@ -377,15 +382,15 @@ TF_BUILTIN(ToLength, CodeStubAssembler) { } TF_BUILTIN(ToInteger, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Return(ToInteger(context, input, kNoTruncation)); } TF_BUILTIN(ToInteger_TruncateMinusZero, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kArgument)); Return(ToInteger(context, input, kTruncateMinusZero)); } @@ -396,15 +401,14 @@ TF_BUILTIN(ToObject, CodeStubAssembler) { if_noconstructor(this, Label::kDeferred), if_wrapjs_primitive_wrapper(this); - Node* context = Parameter(Descriptor::kContext); - Node* object = Parameter(Descriptor::kArgument); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> object = CAST(Parameter(Descriptor::kArgument)); - VARIABLE(constructor_function_index_var, - MachineType::PointerRepresentation()); + TVARIABLE(IntPtrT, constructor_function_index_var); GotoIf(TaggedIsSmi(object), &if_smi); - TNode<Map> map = LoadMap(object); + TNode<Map> map = LoadMap(CAST(object)); TNode<Uint16T> instance_type = LoadMapInstanceType(map); GotoIf(IsJSReceiverInstanceType(instance_type), &if_jsreceiver); @@ -413,12 +417,12 @@ TF_BUILTIN(ToObject, CodeStubAssembler) { GotoIf(WordEqual(constructor_function_index, IntPtrConstant(Map::kNoConstructorFunctionIndex)), &if_noconstructor); - constructor_function_index_var.Bind(constructor_function_index); + constructor_function_index_var = constructor_function_index; Goto(&if_wrapjs_primitive_wrapper); BIND(&if_smi); - constructor_function_index_var.Bind( - IntPtrConstant(Context::NUMBER_FUNCTION_INDEX)); + constructor_function_index_var = + IntPtrConstant(Context::NUMBER_FUNCTION_INDEX); Goto(&if_wrapjs_primitive_wrapper); BIND(&if_wrapjs_primitive_wrapper); @@ -449,7 +453,7 @@ TF_BUILTIN(ToObject, CodeStubAssembler) { // ES6 section 12.5.5 typeof operator TF_BUILTIN(Typeof, CodeStubAssembler) { - Node* object = Parameter(Descriptor::kObject); + TNode<Object> object = CAST(Parameter(Descriptor::kObject)); Return(Typeof(object)); } diff --git a/deps/v8/src/builtins/builtins-date-gen.cc b/deps/v8/src/builtins/builtins-date-gen.cc index 97600efaa49098..98c1343d2c8f8e 100644 --- a/deps/v8/src/builtins/builtins-date-gen.cc +++ b/deps/v8/src/builtins/builtins-date-gen.cc @@ -18,23 +18,23 @@ class DateBuiltinsAssembler : public CodeStubAssembler { : CodeStubAssembler(state) {} protected: - void Generate_DatePrototype_GetField(Node* context, Node* receiver, - int field_index); + void Generate_DatePrototype_GetField(TNode<Context> context, + TNode<Object> receiver, int field_index); }; -void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context, - Node* receiver, - int field_index) { +void DateBuiltinsAssembler::Generate_DatePrototype_GetField( + TNode<Context> context, TNode<Object> receiver, int field_index) { Label receiver_not_date(this, Label::kDeferred); GotoIf(TaggedIsSmi(receiver), &receiver_not_date); - TNode<Uint16T> receiver_instance_type = LoadInstanceType(receiver); + TNode<Uint16T> receiver_instance_type = LoadInstanceType(CAST(receiver)); GotoIfNot(InstanceTypeEqual(receiver_instance_type, JS_DATE_TYPE), &receiver_not_date); + TNode<JSDate> date_receiver = CAST(receiver); // Load the specified date field, falling back to the runtime as necessary. if (field_index == JSDate::kDateValue) { - Return(LoadObjectField(receiver, JSDate::kValueOffset)); + Return(LoadObjectField(date_receiver, JSDate::kValueOffset)); } else { if (field_index < JSDate::kFirstUncachedField) { Label stamp_mismatch(this, Label::kDeferred); @@ -42,9 +42,9 @@ void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context, ExternalConstant(ExternalReference::date_cache_stamp(isolate()))); TNode<Object> cache_stamp = - LoadObjectField(receiver, JSDate::kCacheStampOffset); + LoadObjectField(date_receiver, JSDate::kCacheStampOffset); GotoIf(TaggedNotEqual(date_cache_stamp, cache_stamp), &stamp_mismatch); - Return(LoadObjectField(receiver, + Return(LoadObjectField(date_receiver, JSDate::kValueOffset + field_index * kTaggedSize)); BIND(&stamp_mismatch); @@ -53,10 +53,10 @@ void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context, TNode<Smi> field_index_smi = SmiConstant(field_index); TNode<ExternalReference> function = ExternalConstant(ExternalReference::get_date_field_function()); - Node* result = CallCFunction( + TNode<Object> result = CAST(CallCFunction( function, MachineType::AnyTagged(), - std::make_pair(MachineType::AnyTagged(), receiver), - std::make_pair(MachineType::AnyTagged(), field_index_smi)); + std::make_pair(MachineType::AnyTagged(), date_receiver), + std::make_pair(MachineType::AnyTagged(), field_index_smi))); Return(result); } @@ -66,128 +66,128 @@ void DateBuiltinsAssembler::Generate_DatePrototype_GetField(Node* context, } TF_BUILTIN(DatePrototypeGetDate, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kDay); } TF_BUILTIN(DatePrototypeGetDay, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekday); } TF_BUILTIN(DatePrototypeGetFullYear, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kYear); } TF_BUILTIN(DatePrototypeGetHours, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kHour); } TF_BUILTIN(DatePrototypeGetMilliseconds, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecond); } TF_BUILTIN(DatePrototypeGetMinutes, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMinute); } TF_BUILTIN(DatePrototypeGetMonth, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMonth); } TF_BUILTIN(DatePrototypeGetSeconds, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kSecond); } TF_BUILTIN(DatePrototypeGetTime, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue); } TF_BUILTIN(DatePrototypeGetTimezoneOffset, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kTimezoneOffset); } TF_BUILTIN(DatePrototypeGetUTCDate, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kDayUTC); } TF_BUILTIN(DatePrototypeGetUTCDay, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kWeekdayUTC); } TF_BUILTIN(DatePrototypeGetUTCFullYear, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kYearUTC); } TF_BUILTIN(DatePrototypeGetUTCHours, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kHourUTC); } TF_BUILTIN(DatePrototypeGetUTCMilliseconds, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMillisecondUTC); } TF_BUILTIN(DatePrototypeGetUTCMinutes, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMinuteUTC); } TF_BUILTIN(DatePrototypeGetUTCMonth, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kMonthUTC); } TF_BUILTIN(DatePrototypeGetUTCSeconds, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kSecondUTC); } TF_BUILTIN(DatePrototypeValueOf, DateBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Generate_DatePrototype_GetField(context, receiver, JSDate::kDateValue); } TF_BUILTIN(DatePrototypeToPrimitive, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); TNode<Object> hint = CAST(Parameter(Descriptor::kHint)); // Check if the {receiver} is actually a JSReceiver. Label receiver_is_invalid(this, Label::kDeferred); GotoIf(TaggedIsSmi(receiver), &receiver_is_invalid); - GotoIfNot(IsJSReceiver(receiver), &receiver_is_invalid); + GotoIfNot(IsJSReceiver(CAST(receiver)), &receiver_is_invalid); // Dispatch to the appropriate OrdinaryToPrimitive builtin. Label hint_is_number(this), hint_is_string(this), diff --git a/deps/v8/src/builtins/builtins-date.cc b/deps/v8/src/builtins/builtins-date.cc index c3e7601832148f..258b1022da3c60 100644 --- a/deps/v8/src/builtins/builtins-date.cc +++ b/deps/v8/src/builtins/builtins-date.cc @@ -854,16 +854,18 @@ BUILTIN(DatePrototypeToLocaleDateString) { isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleDateString); - CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleDateString"); + const char* method = "Date.prototype.toLocaleDateString"; + CHECK_RECEIVER(JSDate, date, method); RETURN_RESULT_OR_FAILURE( isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, - date, // date - args.atOrUndefined(isolate, 1), // locales - args.atOrUndefined(isolate, 2), // options - JSDateTimeFormat::RequiredOption::kDate, // required - JSDateTimeFormat::DefaultsOption::kDate)); // defaults + date, // date + args.atOrUndefined(isolate, 1), // locales + args.atOrUndefined(isolate, 2), // options + JSDateTimeFormat::RequiredOption::kDate, // required + JSDateTimeFormat::DefaultsOption::kDate, // defaults + method)); // method } // ecma402 #sup-date.prototype.tolocalestring @@ -872,16 +874,18 @@ BUILTIN(DatePrototypeToLocaleString) { isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleString); - CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleString"); + const char* method = "Date.prototype.toLocaleString"; + CHECK_RECEIVER(JSDate, date, method); RETURN_RESULT_OR_FAILURE( isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, - date, // date - args.atOrUndefined(isolate, 1), // locales - args.atOrUndefined(isolate, 2), // options - JSDateTimeFormat::RequiredOption::kAny, // required - JSDateTimeFormat::DefaultsOption::kAll)); // defaults + date, // date + args.atOrUndefined(isolate, 1), // locales + args.atOrUndefined(isolate, 2), // options + JSDateTimeFormat::RequiredOption::kAny, // required + JSDateTimeFormat::DefaultsOption::kAll, // defaults + method)); // method } // ecma402 #sup-date.prototype.tolocaletimestring @@ -890,16 +894,18 @@ BUILTIN(DatePrototypeToLocaleTimeString) { isolate->CountUsage(v8::Isolate::UseCounterFeature::kDateToLocaleTimeString); - CHECK_RECEIVER(JSDate, date, "Date.prototype.toLocaleTimeString"); + const char* method = "Date.prototype.toLocaleTimeString"; + CHECK_RECEIVER(JSDate, date, method); RETURN_RESULT_OR_FAILURE( isolate, JSDateTimeFormat::ToLocaleDateTime( isolate, - date, // date - args.atOrUndefined(isolate, 1), // locales - args.atOrUndefined(isolate, 2), // options - JSDateTimeFormat::RequiredOption::kTime, // required - JSDateTimeFormat::DefaultsOption::kTime)); // defaults + date, // date + args.atOrUndefined(isolate, 1), // locales + args.atOrUndefined(isolate, 2), // options + JSDateTimeFormat::RequiredOption::kTime, // required + JSDateTimeFormat::DefaultsOption::kTime, // defaults + method)); // method } #endif // V8_INTL_SUPPORT diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h index 95f5273f14f7fc..2489538d192826 100644 --- a/deps/v8/src/builtins/builtins-definitions.h +++ b/deps/v8/src/builtins/builtins-definitions.h @@ -102,7 +102,6 @@ namespace internal { ASM(ResumeGeneratorTrampoline, ResumeGenerator) \ \ /* String helpers */ \ - TFC(StringCharAt, StringAt) \ TFC(StringCodePointAt, StringAt) \ TFC(StringFromCodePointAt, StringAtAsString) \ TFC(StringEqual, Compare) \ @@ -219,9 +218,7 @@ namespace internal { TFH(KeyedLoadIC_Slow, LoadWithVector) \ TFH(KeyedStoreIC_Megamorphic, Store) \ TFH(KeyedStoreIC_Slow, StoreWithVector) \ - TFH(LoadGlobalIC_Slow, LoadWithVector) \ TFH(LoadIC_FunctionPrototype, LoadWithVector) \ - TFH(LoadIC_Slow, LoadWithVector) \ TFH(LoadIC_StringLength, LoadWithVector) \ TFH(LoadIC_StringWrapperLength, LoadWithVector) \ TFH(LoadIC_NoFeedback, Load) \ @@ -230,7 +227,6 @@ namespace internal { TFH(StoreInArrayLiteralIC_Slow, StoreWithVector) \ TFH(KeyedLoadIC_SloppyArguments, LoadWithVector) \ TFH(LoadIndexedInterceptorIC, LoadWithVector) \ - TFH(StoreInterceptorIC, StoreWithVector) \ TFH(KeyedStoreIC_SloppyArguments_Standard, StoreWithVector) \ TFH(KeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW, StoreWithVector) \ TFH(KeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB, StoreWithVector) \ @@ -568,6 +564,9 @@ namespace internal { SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ CPP(AsyncFunctionConstructor) \ \ + /* Iterator Protocol */ \ + TFC(GetIteratorWithFeedbackLazyDeoptContinuation, GetIteratorStackParameter) \ + \ /* Global object */ \ CPP(GlobalDecodeURI) \ CPP(GlobalDecodeURIComponent) \ @@ -616,6 +615,10 @@ namespace internal { TFS(IterableToList, kIterable, kIteratorFn) \ TFS(IterableToListWithSymbolLookup, kIterable) \ TFS(IterableToListMayPreserveHoles, kIterable, kIteratorFn) \ + TFS(IterableToFixedArrayForWasm, kIterable, kExpectedLength) \ + \ + /* #sec-createstringlistfromiterable */ \ + TFS(StringListFromIterable, kIterable) \ \ /* Map */ \ TFS(FindOrderedHashMapEntry, kTable, kKey) \ @@ -845,28 +848,13 @@ namespace internal { CPP(RegExpLeftContextGetter) \ /* ES #sec-regexp.prototype.compile */ \ TFJ(RegExpPrototypeCompile, 2, kReceiver, kPattern, kFlags) \ - /* ES #sec-regexp.prototype.exec */ \ - TFJ(RegExpPrototypeExec, 1, kReceiver, kString) \ - /* https://tc39.github.io/proposal-string-matchall/ */ \ - TFJ(RegExpPrototypeMatchAll, 1, kReceiver, kString) \ - /* ES #sec-regexp.prototype-@@search */ \ - TFJ(RegExpPrototypeSearch, 1, kReceiver, kString) \ CPP(RegExpPrototypeToString) \ CPP(RegExpRightContextGetter) \ \ - /* ES #sec-regexp.prototype-@@split */ \ - TFJ(RegExpPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ /* RegExp helpers */ \ TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \ TFS(RegExpExecInternal, kRegExp, kString, kLastIndex, kMatchInfo) \ ASM(RegExpInterpreterTrampoline, CCall) \ - TFS(RegExpPrototypeExecSlow, kReceiver, kString) \ - TFS(RegExpSearchFast, kReceiver, kPattern) \ - TFS(RegExpSplit, kRegExp, kString, kLimit) \ - \ - /* RegExp String Iterator */ \ - /* https://tc39.github.io/proposal-string-matchall/ */ \ - TFJ(RegExpStringIteratorPrototypeNext, 0, kReceiver) \ \ /* Set */ \ TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ @@ -1117,7 +1105,6 @@ namespace internal { TFS(SetProperty, kReceiver, kKey, kValue) \ TFS(SetPropertyInLiteral, kReceiver, kKey, kValue) \ ASM(MemCopyUint8Uint8, CCall) \ - ASM(MemCopyUint16Uint8, CCall) \ ASM(MemMove, CCall) \ \ /* Trace */ \ @@ -1131,7 +1118,14 @@ namespace internal { CPP(FinalizationGroupRegister) \ CPP(FinalizationGroupUnregister) \ CPP(WeakRefConstructor) \ - CPP(WeakRefDeref) + CPP(WeakRefDeref) \ + \ + /* Async modules */ \ + TFJ(AsyncModuleEvaluate, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ + \ + /* CallAsyncModule* are spec anonymyous functions */ \ + CPP(CallAsyncModuleFulfilled) \ + CPP(CallAsyncModuleRejected) #ifdef V8_INTL_SUPPORT #define BUILTIN_LIST_INTL(CPP, TFJ, TFS) \ diff --git a/deps/v8/src/builtins/builtins-function-gen.cc b/deps/v8/src/builtins/builtins-function-gen.cc index ee1f67d43428b6..f0853e9bd979dc 100644 --- a/deps/v8/src/builtins/builtins-function-gen.cc +++ b/deps/v8/src/builtins/builtins-function-gen.cc @@ -15,14 +15,12 @@ namespace internal { TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { Label slow(this); - // TODO(ishell): use constants from Descriptor once the JSFunction linkage - // arguments are reordered. TNode<Int32T> argc = UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); - Node* context = Parameter(Descriptor::kContext); - Node* new_target = Parameter(Descriptor::kJSNewTarget); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget)); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); // Check that receiver has instance type of JS_FUNCTION_TYPE TNode<Object> receiver = args.GetReceiver(); @@ -85,21 +83,20 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { // Choose the right bound function map based on whether the target is // constructable. Comment("Choose the right bound function map"); - VARIABLE(bound_function_map, MachineRepresentation::kTagged); + TVARIABLE(Map, bound_function_map); { Label with_constructor(this); - VariableList vars({&bound_function_map}, zone()); TNode<NativeContext> native_context = LoadNativeContext(context); - Label map_done(this, vars); + Label map_done(this, &bound_function_map); GotoIf(IsConstructorMap(receiver_map), &with_constructor); - bound_function_map.Bind(LoadContextElement( + bound_function_map = CAST(LoadContextElement( native_context, Context::BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX)); Goto(&map_done); BIND(&with_constructor); - bound_function_map.Bind(LoadContextElement( + bound_function_map = CAST(LoadContextElement( native_context, Context::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX)); Goto(&map_done); @@ -115,30 +112,28 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { // Allocate the arguments array. Comment("Allocate the arguments array"); - VARIABLE(argument_array, MachineRepresentation::kTagged); + TVARIABLE(FixedArray, argument_array); { Label empty_arguments(this); Label arguments_done(this, &argument_array); GotoIf(Uint32LessThanOrEqual(argc, Int32Constant(1)), &empty_arguments); TNode<IntPtrT> elements_length = Signed(ChangeUint32ToWord(Unsigned(Int32Sub(argc, Int32Constant(1))))); - TNode<FixedArray> elements = CAST(AllocateFixedArray( - PACKED_ELEMENTS, elements_length, kAllowLargeObjectAllocation)); - VARIABLE(index, MachineType::PointerRepresentation()); - index.Bind(IntPtrConstant(0)); + argument_array = CAST(AllocateFixedArray(PACKED_ELEMENTS, elements_length, + kAllowLargeObjectAllocation)); + TVARIABLE(IntPtrT, index, IntPtrConstant(0)); VariableList foreach_vars({&index}, zone()); args.ForEach( foreach_vars, - [this, elements, &index](Node* arg) { - StoreFixedArrayElement(elements, index.value(), arg); + [&](TNode<Object> arg) { + StoreFixedArrayElement(argument_array.value(), index.value(), arg); Increment(&index); }, IntPtrConstant(1)); - argument_array.Bind(elements); Goto(&arguments_done); BIND(&empty_arguments); - argument_array.Bind(EmptyFixedArrayConstant()); + argument_array = EmptyFixedArrayConstant(); Goto(&arguments_done); BIND(&arguments_done); @@ -146,16 +141,16 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { // Determine bound receiver. Comment("Determine bound receiver"); - VARIABLE(bound_receiver, MachineRepresentation::kTagged); + TVARIABLE(Object, bound_receiver); { Label has_receiver(this); Label receiver_done(this, &bound_receiver); GotoIf(Word32NotEqual(argc, Int32Constant(0)), &has_receiver); - bound_receiver.Bind(UndefinedConstant()); + bound_receiver = UndefinedConstant(); Goto(&receiver_done); BIND(&has_receiver); - bound_receiver.Bind(args.AtIndex(0)); + bound_receiver = args.AtIndex(0); Goto(&receiver_done); BIND(&receiver_done); @@ -196,10 +191,10 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { // ES6 #sec-function.prototype-@@hasinstance TF_BUILTIN(FunctionPrototypeHasInstance, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* f = Parameter(Descriptor::kReceiver); - Node* v = Parameter(Descriptor::kV); - Node* result = OrdinaryHasInstance(context, f, v); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> f = CAST(Parameter(Descriptor::kReceiver)); + TNode<Object> v = CAST(Parameter(Descriptor::kV)); + TNode<Oddball> result = OrdinaryHasInstance(context, f, v); Return(result); } diff --git a/deps/v8/src/builtins/builtins-generator-gen.cc b/deps/v8/src/builtins/builtins-generator-gen.cc index d884c417fc04a0..0a4b3b205b9503 100644 --- a/deps/v8/src/builtins/builtins-generator-gen.cc +++ b/deps/v8/src/builtins/builtins-generator-gen.cc @@ -19,19 +19,25 @@ class GeneratorBuiltinsAssembler : public CodeStubAssembler { : CodeStubAssembler(state) {} protected: + // Currently, AsyncModules in V8 are built on top of JSAsyncFunctionObjects + // with an initial yield. Thus, we need some way to 'resume' the + // underlying JSAsyncFunctionObject owned by an AsyncModule. To support this + // the body of resume is factored out below, and shared by JSGeneratorObject + // prototype methods as well as AsyncModuleEvaluate. The only difference + // between AsyncModuleEvaluate and JSGeneratorObject::PrototypeNext is + // the expected reciever. + void InnerResume(CodeStubArguments* args, Node* receiver, Node* value, + Node* context, JSGeneratorObject::ResumeMode resume_mode, + char const* const method_name); void GeneratorPrototypeResume(CodeStubArguments* args, Node* receiver, Node* value, Node* context, JSGeneratorObject::ResumeMode resume_mode, char const* const method_name); }; -void GeneratorBuiltinsAssembler::GeneratorPrototypeResume( +void GeneratorBuiltinsAssembler::InnerResume( CodeStubArguments* args, Node* receiver, Node* value, Node* context, JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) { - // Check if the {receiver} is actually a JSGeneratorObject. - ThrowIfNotInstanceType(context, receiver, JS_GENERATOR_OBJECT_TYPE, - method_name); - // Check if the {receiver} is running or already closed. TNode<Smi> receiver_continuation = CAST(LoadObjectField(receiver, JSGeneratorObject::kContinuationOffset)); @@ -111,17 +117,46 @@ void GeneratorBuiltinsAssembler::GeneratorPrototypeResume( } } +void GeneratorBuiltinsAssembler::GeneratorPrototypeResume( + CodeStubArguments* args, Node* receiver, Node* value, Node* context, + JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) { + // Check if the {receiver} is actually a JSGeneratorObject. + ThrowIfNotInstanceType(context, receiver, JS_GENERATOR_OBJECT_TYPE, + method_name); + InnerResume(args, receiver, value, context, resume_mode, method_name); +} + +TF_BUILTIN(AsyncModuleEvaluate, GeneratorBuiltinsAssembler) { + const int kValueArg = 0; + + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); + CodeStubArguments args(this, argc); + + TNode<Object> receiver = args.GetReceiver(); + TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); + TNode<Context> context = Cast(Parameter(Descriptor::kContext)); + + // AsyncModules act like JSAsyncFunctions. Thus we check here + // that the {receiver} is a JSAsyncFunction. + char const* const method_name = "[AsyncModule].evaluate"; + ThrowIfNotInstanceType(context, receiver, JS_ASYNC_FUNCTION_OBJECT_TYPE, + method_name); + InnerResume(&args, receiver, value, context, JSGeneratorObject::kNext, + method_name); +} + // ES6 #sec-generator.prototype.next TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) { const int kValueArg = 0; - TNode<IntPtrT> argc = - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); TNode<Object> receiver = args.GetReceiver(); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); GeneratorPrototypeResume(&args, receiver, value, context, JSGeneratorObject::kNext, @@ -132,13 +167,13 @@ TF_BUILTIN(GeneratorPrototypeNext, GeneratorBuiltinsAssembler) { TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) { const int kValueArg = 0; - TNode<IntPtrT> argc = - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); TNode<Object> receiver = args.GetReceiver(); TNode<Object> value = args.GetOptionalArgumentValue(kValueArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); GeneratorPrototypeResume(&args, receiver, value, context, JSGeneratorObject::kReturn, @@ -149,13 +184,13 @@ TF_BUILTIN(GeneratorPrototypeReturn, GeneratorBuiltinsAssembler) { TF_BUILTIN(GeneratorPrototypeThrow, GeneratorBuiltinsAssembler) { const int kExceptionArg = 0; - TNode<IntPtrT> argc = - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); CodeStubArguments args(this, argc); TNode<Object> receiver = args.GetReceiver(); TNode<Object> exception = args.GetOptionalArgumentValue(kExceptionArg); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); GeneratorPrototypeResume(&args, receiver, exception, context, JSGeneratorObject::kThrow, diff --git a/deps/v8/src/builtins/builtins-handler-gen.cc b/deps/v8/src/builtins/builtins-handler-gen.cc index eae8690f1facd0..ef912eabf1fcf6 100644 --- a/deps/v8/src/builtins/builtins-handler-gen.cc +++ b/deps/v8/src/builtins/builtins-handler-gen.cc @@ -48,8 +48,8 @@ TF_BUILTIN(LoadIC_StringLength, CodeStubAssembler) { } TF_BUILTIN(LoadIC_StringWrapperLength, CodeStubAssembler) { - Node* value = Parameter(Descriptor::kReceiver); - Node* string = LoadJSPrimitiveWrapperValue(value); + TNode<JSPrimitiveWrapper> value = CAST(Parameter(Descriptor::kReceiver)); + TNode<String> string = CAST(LoadJSPrimitiveWrapperValue(value)); Return(LoadStringLengthAsSmi(string)); } @@ -388,15 +388,6 @@ TF_BUILTIN(StoreFastElementIC_NoTransitionHandleCOW, HandlerBuiltinsAssembler) { Generate_StoreFastElementIC(STORE_HANDLE_COW); } -TF_BUILTIN(LoadGlobalIC_Slow, CodeStubAssembler) { - Node* name = Parameter(Descriptor::kName); - Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); - - TailCallRuntime(Runtime::kLoadGlobalIC_Slow, context, name, slot, vector); -} - TF_BUILTIN(LoadIC_FunctionPrototype, CodeStubAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); @@ -411,14 +402,6 @@ TF_BUILTIN(LoadIC_FunctionPrototype, CodeStubAssembler) { TailCallRuntime(Runtime::kLoadIC_Miss, context, receiver, name, slot, vector); } -TF_BUILTIN(LoadIC_Slow, CodeStubAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); - Node* context = Parameter(Descriptor::kContext); - - TailCallRuntime(Runtime::kGetProperty, context, receiver, name); -} - TF_BUILTIN(StoreGlobalIC_Slow, CodeStubAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* name = Parameter(Descriptor::kName); @@ -491,17 +474,6 @@ TF_BUILTIN(KeyedStoreIC_SloppyArguments_NoTransitionHandleCOW, Generate_KeyedStoreIC_SloppyArguments(); } -TF_BUILTIN(StoreInterceptorIC, CodeStubAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); - Node* name = Parameter(Descriptor::kName); - Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); - Node* context = Parameter(Descriptor::kContext); - TailCallRuntime(Runtime::kStorePropertyWithInterceptor, context, value, slot, - vector, receiver, name); -} - TF_BUILTIN(LoadIndexedInterceptorIC, CodeStubAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* key = Parameter(Descriptor::kName); diff --git a/deps/v8/src/builtins/builtins-internal-gen.cc b/deps/v8/src/builtins/builtins-internal-gen.cc index 445c8c951732c8..0625b8affcd23a 100644 --- a/deps/v8/src/builtins/builtins-internal-gen.cc +++ b/deps/v8/src/builtins/builtins-internal-gen.cc @@ -18,9 +18,6 @@ namespace v8 { namespace internal { -template <typename T> -using TNode = compiler::TNode<T>; - // ----------------------------------------------------------------------------- // Stack checks. @@ -32,12 +29,14 @@ void Builtins::Generate_StackCheck(MacroAssembler* masm) { // TurboFan support builtins. TF_BUILTIN(CopyFastSmiOrObjectElements, CodeStubAssembler) { - Node* object = Parameter(Descriptor::kObject); + TNode<JSObject> js_object = CAST(Parameter(Descriptor::kObject)); // Load the {object}s elements. - TNode<Object> source = LoadObjectField(object, JSObject::kElementsOffset); - Node* target = CloneFixedArray(source, ExtractFixedArrayFlag::kFixedArrays); - StoreObjectField(object, JSObject::kElementsOffset, target); + TNode<FixedArrayBase> source = + CAST(LoadObjectField(js_object, JSObject::kElementsOffset)); + TNode<FixedArrayBase> target = + CloneFixedArray(source, ExtractFixedArrayFlag::kFixedArrays); + StoreObjectField(js_object, JSObject::kElementsOffset, target); Return(target); } @@ -47,7 +46,7 @@ TF_BUILTIN(GrowFastDoubleElements, CodeStubAssembler) { Node* context = Parameter(Descriptor::kContext); Label runtime(this, Label::kDeferred); - Node* elements = LoadElements(object); + TNode<FixedArrayBase> elements = LoadElements(object); elements = TryGrowElementsCapacity(object, elements, PACKED_DOUBLE_ELEMENTS, key, &runtime); Return(elements); @@ -62,7 +61,7 @@ TF_BUILTIN(GrowFastSmiOrObjectElements, CodeStubAssembler) { Node* context = Parameter(Descriptor::kContext); Label runtime(this, Label::kDeferred); - Node* elements = LoadElements(object); + TNode<FixedArrayBase> elements = LoadElements(object); elements = TryGrowElementsCapacity(object, elements, PACKED_ELEMENTS, key, &runtime); Return(elements); @@ -274,25 +273,24 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler { return TaggedEqual(remembered_set, SmiConstant(EMIT_REMEMBERED_SET)); } - void CallCFunction1WithCallerSavedRegistersMode(MachineType return_type, - MachineType arg0_type, - Node* function, Node* arg0, - Node* mode, Label* next) { + void CallCFunction2WithCallerSavedRegistersMode( + MachineType return_type, MachineType arg0_type, MachineType arg1_type, + Node* function, Node* arg0, Node* arg1, Node* mode, Label* next) { Label dont_save_fp(this), save_fp(this); Branch(ShouldSkipFPRegs(mode), &dont_save_fp, &save_fp); BIND(&dont_save_fp); { - CallCFunctionWithCallerSavedRegisters(function, return_type, - kDontSaveFPRegs, - std::make_pair(arg0_type, arg0)); + CallCFunctionWithCallerSavedRegisters( + function, return_type, kDontSaveFPRegs, + std::make_pair(arg0_type, arg0), std::make_pair(arg1_type, arg1)); Goto(next); } BIND(&save_fp); { - CallCFunctionWithCallerSavedRegisters(function, return_type, - kSaveFPRegs, - std::make_pair(arg0_type, arg0)); + CallCFunctionWithCallerSavedRegisters(function, return_type, kSaveFPRegs, + std::make_pair(arg0_type, arg0), + std::make_pair(arg1_type, arg1)); Goto(next); } } @@ -321,34 +319,82 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler { } } - void InsertToStoreBufferAndGoto(Node* isolate, Node* slot, Node* mode, - Label* next) { - TNode<ExternalReference> store_buffer_top_addr = - ExternalConstant(ExternalReference::store_buffer_top(this->isolate())); - Node* store_buffer_top = - Load(MachineType::Pointer(), store_buffer_top_addr); - StoreNoWriteBarrier(MachineType::PointerRepresentation(), store_buffer_top, - slot); - TNode<WordT> new_store_buffer_top = - IntPtrAdd(store_buffer_top, IntPtrConstant(kSystemPointerSize)); - StoreNoWriteBarrier(MachineType::PointerRepresentation(), - store_buffer_top_addr, new_store_buffer_top); - - TNode<WordT> test = - WordAnd(new_store_buffer_top, - IntPtrConstant(Heap::store_buffer_mask_constant())); - - Label overflow(this); - Branch(IntPtrEqual(test, IntPtrConstant(0)), &overflow, next); - - BIND(&overflow); - { - TNode<ExternalReference> function = - ExternalConstant(ExternalReference::store_buffer_overflow_function()); - CallCFunction1WithCallerSavedRegistersMode(MachineType::Int32(), - MachineType::Pointer(), - function, isolate, mode, next); - } + void InsertIntoRememberedSetAndGotoSlow(Node* isolate, TNode<IntPtrT> object, + TNode<IntPtrT> slot, Node* mode, + Label* next) { + TNode<IntPtrT> page = PageFromAddress(object); + TNode<ExternalReference> function = + ExternalConstant(ExternalReference::insert_remembered_set_function()); + CallCFunction2WithCallerSavedRegistersMode( + MachineType::Int32(), MachineType::Pointer(), MachineType::Pointer(), + function, page, slot, mode, next); + } + + void InsertIntoRememberedSetAndGoto(Node* isolate, TNode<IntPtrT> object, + TNode<IntPtrT> slot, Node* mode, + Label* next) { + Label slow_path(this); + TNode<IntPtrT> page = PageFromAddress(object); + + // Load address of SlotSet + TNode<IntPtrT> slot_set_array = LoadSlotSetArray(page, &slow_path); + TNode<IntPtrT> slot_offset = IntPtrSub(slot, page); + + // Load bucket + TNode<IntPtrT> bucket = LoadBucket(slot_set_array, slot_offset, &slow_path); + + // Update cell + SetBitInCell(bucket, slot_offset); + + Goto(next); + + BIND(&slow_path); + InsertIntoRememberedSetAndGotoSlow(isolate, object, slot, mode, next); + } + + TNode<IntPtrT> LoadSlotSetArray(TNode<IntPtrT> page, Label* slow_path) { + TNode<IntPtrT> slot_set_array = UncheckedCast<IntPtrT>( + Load(MachineType::Pointer(), page, + IntPtrConstant(MemoryChunk::kOldToNewSlotSetOffset))); + GotoIf(WordEqual(slot_set_array, IntPtrConstant(0)), slow_path); + + return slot_set_array; + } + + TNode<IntPtrT> LoadBucket(TNode<IntPtrT> slot_set_array, + TNode<WordT> slot_offset, Label* slow_path) { + // Assume here that SlotSet only contains of buckets + DCHECK_EQ(SlotSet::kSize, SlotSet::kBuckets * sizeof(SlotSet::Bucket)); + TNode<WordT> bucket_index = + WordShr(slot_offset, SlotSet::kBitsPerBucketLog2 + kTaggedSizeLog2); + TNode<IntPtrT> bucket = UncheckedCast<IntPtrT>( + Load(MachineType::Pointer(), slot_set_array, + WordShl(bucket_index, kSystemPointerSizeLog2))); + GotoIf(WordEqual(bucket, IntPtrConstant(0)), slow_path); + return bucket; + } + + void SetBitInCell(TNode<IntPtrT> bucket, TNode<WordT> slot_offset) { + // Load cell value + TNode<WordT> cell_offset = WordAnd( + WordShr(slot_offset, SlotSet::kBitsPerCellLog2 + kTaggedSizeLog2 - + SlotSet::kCellSizeBytesLog2), + IntPtrConstant((SlotSet::kCellsPerBucket - 1) + << SlotSet::kCellSizeBytesLog2)); + TNode<IntPtrT> cell_address = + UncheckedCast<IntPtrT>(IntPtrAdd(bucket, cell_offset)); + TNode<IntPtrT> old_cell_value = + ChangeInt32ToIntPtr(Load<Int32T>(cell_address)); + + // Calculate new cell value + TNode<WordT> bit_index = WordAnd(WordShr(slot_offset, kTaggedSizeLog2), + IntPtrConstant(SlotSet::kBitsPerCell - 1)); + TNode<IntPtrT> new_cell_value = UncheckedCast<IntPtrT>( + WordOr(old_cell_value, WordShl(IntPtrConstant(1), bit_index))); + + // Update cell value + StoreNoWriteBarrier(MachineRepresentation::kWord32, cell_address, + TruncateIntPtrToInt32(new_cell_value)); } }; @@ -399,7 +445,10 @@ TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) { TNode<ExternalReference> isolate_constant = ExternalConstant(ExternalReference::isolate_address(isolate())); Node* fp_mode = Parameter(Descriptor::kFPMode); - InsertToStoreBufferAndGoto(isolate_constant, slot, fp_mode, &exit); + TNode<IntPtrT> object = + BitcastTaggedToWord(Parameter(Descriptor::kObject)); + InsertIntoRememberedSetAndGoto(isolate_constant, object, slot, fp_mode, + &exit); } BIND(&store_buffer_incremental_wb); @@ -407,8 +456,10 @@ TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) { TNode<ExternalReference> isolate_constant = ExternalConstant(ExternalReference::isolate_address(isolate())); Node* fp_mode = Parameter(Descriptor::kFPMode); - InsertToStoreBufferAndGoto(isolate_constant, slot, fp_mode, - &incremental_wb); + TNode<IntPtrT> object = + BitcastTaggedToWord(Parameter(Descriptor::kObject)); + InsertIntoRememberedSetAndGoto(isolate_constant, object, slot, fp_mode, + &incremental_wb); } } @@ -532,8 +583,8 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { TNode<Smi> language_mode = CAST(Parameter(Descriptor::kLanguageMode)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged, key); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); Label if_index(this), if_unique_name(this), if_notunique(this), if_notfound(this), slow(this), if_proxy(this); @@ -554,8 +605,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { BIND(&if_unique_name); { Comment("key is unique name"); - TNode<Name> unique = CAST(var_unique.value()); - CheckForAssociatedProtector(unique, &slow); + CheckForAssociatedProtector(var_unique.value(), &slow); Label dictionary(this), dont_delete(this); GotoIf(IsDictionaryMap(receiver_map), &dictionary); @@ -570,8 +620,8 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(receiver))); - DeleteDictionaryProperty(receiver, properties, unique, context, - &dont_delete, &if_notfound); + DeleteDictionaryProperty(receiver, properties, var_unique.value(), + context, &dont_delete, &if_notfound); } BIND(&dont_delete); @@ -587,7 +637,7 @@ TF_BUILTIN(DeleteProperty, DeletePropertyBaseAssembler) { { // If the string was not found in the string table, then no object can // have a property with that name. - TryInternalizeString(key, &if_index, &var_index, &if_unique_name, + TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name, &var_unique, &if_notfound, &slow); } @@ -719,11 +769,11 @@ TF_BUILTIN(SetDataProperties, SetOrCopyDataPropertiesAssembler) { } TF_BUILTIN(ForInEnumerate, CodeStubAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); - Node* context = Parameter(Descriptor::kContext); + TNode<HeapObject> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label if_empty(this), if_runtime(this, Label::kDeferred); - Node* receiver_map = CheckEnumCache(receiver, &if_empty, &if_runtime); + TNode<Map> receiver_map = CheckEnumCache(receiver, &if_empty, &if_runtime); Return(receiver_map); BIND(&if_empty); @@ -934,12 +984,6 @@ void Builtins::Generate_MemCopyUint8Uint8(MacroAssembler* masm) { } #endif // !defined(V8_TARGET_ARCH_ARM) && !defined(V8_TARGET_ARCH_MIPS) -#ifndef V8_TARGET_ARCH_ARM -void Builtins::Generate_MemCopyUint16Uint8(MacroAssembler* masm) { - masm->Call(BUILTIN_CODE(masm->isolate(), Illegal), RelocInfo::CODE_TARGET); -} -#endif // V8_TARGET_ARCH_ARM - #ifndef V8_TARGET_ARCH_IA32 void Builtins::Generate_MemMove(MacroAssembler* masm) { masm->Call(BUILTIN_CODE(masm->isolate(), Illegal), RelocInfo::CODE_TARGET); diff --git a/deps/v8/src/builtins/builtins-intl-gen.cc b/deps/v8/src/builtins/builtins-intl-gen.cc index 1a9a3b7fd9a822..23305537210fee 100644 --- a/deps/v8/src/builtins/builtins-intl-gen.cc +++ b/deps/v8/src/builtins/builtins-intl-gen.cc @@ -17,9 +17,6 @@ namespace v8 { namespace internal { -template <class T> -using TNode = compiler::TNode<T>; - class IntlBuiltinsAssembler : public CodeStubAssembler { public: explicit IntlBuiltinsAssembler(compiler::CodeAssemblerState* state) @@ -30,6 +27,16 @@ class IntlBuiltinsAssembler : public CodeStubAssembler { const char* method_name); TNode<JSArray> AllocateEmptyJSArray(TNode<Context> context); + + TNode<IntPtrT> PointerToSeqStringData(TNode<String> seq_string) { + CSA_ASSERT(this, + IsSequentialStringInstanceType(LoadInstanceType(seq_string))); + STATIC_ASSERT(SeqOneByteString::kHeaderSize == + SeqTwoByteString::kHeaderSize); + return IntPtrAdd( + BitcastTaggedToWord(seq_string), + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + } }; TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { @@ -61,35 +68,35 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { &call_c); { - Node* const dst_ptr = PointerToSeqStringData(dst); - VARIABLE(var_cursor, MachineType::PointerRepresentation(), - IntPtrConstant(0)); + const TNode<IntPtrT> dst_ptr = PointerToSeqStringData(dst); + TVARIABLE(IntPtrT, var_cursor, IntPtrConstant(0)); - TNode<RawPtrT> const start_address = to_direct.PointerToData(&call_c); + TNode<IntPtrT> const start_address = + ReinterpretCast<IntPtrT>(to_direct.PointerToData(&call_c)); TNode<IntPtrT> const end_address = Signed(IntPtrAdd(start_address, ChangeUint32ToWord(length))); TNode<ExternalReference> const to_lower_table_addr = ExternalConstant(ExternalReference::intl_to_latin1_lower_table()); - VARIABLE(var_did_change, MachineRepresentation::kWord32, Int32Constant(0)); + TVARIABLE(Word32T, var_did_change, Int32Constant(0)); VariableList push_vars({&var_cursor, &var_did_change}, zone()); - BuildFastLoop( + BuildFastLoop<IntPtrT>( push_vars, start_address, end_address, - [=, &var_cursor, &var_did_change](Node* current) { + [&](TNode<IntPtrT> current) { TNode<Uint8T> c = Load<Uint8T>(current); TNode<Uint8T> lower = Load<Uint8T>(to_lower_table_addr, ChangeInt32ToIntPtr(c)); StoreNoWriteBarrier(MachineRepresentation::kWord8, dst_ptr, var_cursor.value(), lower); - var_did_change.Bind( - Word32Or(Word32NotEqual(c, lower), var_did_change.value())); + var_did_change = + Word32Or(Word32NotEqual(c, lower), var_did_change.value()); Increment(&var_cursor); }, - kCharSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kCharSize, IndexAdvanceMode::kPost); // Return the original string if it remained unchanged in order to preserve // e.g. internalization and private symbols (such as the preserved object @@ -110,9 +117,9 @@ TF_BUILTIN(StringToLowerCaseIntl, IntlBuiltinsAssembler) { MachineType type_tagged = MachineType::AnyTagged(); - Node* const result = CallCFunction(function_addr, type_tagged, - std::make_pair(type_tagged, src), - std::make_pair(type_tagged, dst)); + const TNode<String> result = CAST(CallCFunction( + function_addr, type_tagged, std::make_pair(type_tagged, src), + std::make_pair(type_tagged, dst))); Return(result); } @@ -142,7 +149,7 @@ void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context, TNode<Int32T> argc, Runtime::FunctionId format_func_id, const char* method_name) { - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); // Label has_list(this); // 1. Let lf be this value. @@ -151,32 +158,18 @@ void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context, // 3. If lf does not have an [[InitializedListFormat]] internal slot, throw a // TypeError exception. - ThrowIfNotInstanceType(context, receiver, JS_INTL_LIST_FORMAT_TYPE, - method_name); + ThrowIfNotInstanceType(context, receiver, JS_LIST_FORMAT_TYPE, method_name); TNode<JSListFormat> list_format = CAST(receiver); - // 4. If list is not provided or is undefined, then TNode<Object> list = args.GetOptionalArgumentValue(0); - Label has_list(this); - { - GotoIfNot(IsUndefined(list), &has_list); - if (format_func_id == Runtime::kFormatList) { - // a. Return an empty String. - args.PopAndReturn(EmptyStringConstant()); - } else { - DCHECK_EQ(format_func_id, Runtime::kFormatListToParts); - // a. Return an empty Array. - args.PopAndReturn(AllocateEmptyJSArray(context)); - } - } - BIND(&has_list); { - // 5. Let x be ? IterableToList(list). - TNode<Object> x = - CallBuiltin(Builtins::kIterableToListWithSymbolLookup, context, list); + // 4. Let stringList be ? StringListFromIterable(list). + TNode<Object> string_list = + CallBuiltin(Builtins::kStringListFromIterable, context, list); - // 6. Return ? FormatList(lf, x). - args.PopAndReturn(CallRuntime(format_func_id, context, list_format, x)); + // 6. Return ? FormatList(lf, stringList). + args.PopAndReturn( + CallRuntime(format_func_id, context, list_format, string_list)); } } diff --git a/deps/v8/src/builtins/builtins-intl.cc b/deps/v8/src/builtins/builtins-intl.cc index ff8e96f4f512f0..81954a481f0a44 100644 --- a/deps/v8/src/builtins/builtins-intl.cc +++ b/deps/v8/src/builtins/builtins-intl.cc @@ -83,13 +83,8 @@ BUILTIN(NumberFormatPrototypeFormatToParts) { Handle<Object> x; if (args.length() >= 2) { - if (FLAG_harmony_intl_bigint) { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, x, Object::ToNumeric(isolate, args.at(1))); - } else { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, - Object::ToNumber(isolate, args.at(1))); - } + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, + Object::ToNumeric(isolate, args.at(1))); } else { x = isolate->factory()->nan_value(); } @@ -282,8 +277,8 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, // 3. Perform ? Initialize<T>(Format, locales, options). Handle<T> format; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, format, - T::New(isolate, map, locales, options)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, format, T::New(isolate, map, locales, options, method)); // 4. Let this be the this value. Handle<Object> receiver = args.receiver(); @@ -367,7 +362,8 @@ Object DisallowCallConstructor(BuiltinArguments args, Isolate* isolate, * Common code shared by Collator and V8BreakIterator */ template <class T> -Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) { +Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate, + const char* method) { Handle<JSReceiver> new_target; if (args.new_target()->IsUndefined(isolate)) { @@ -386,7 +382,8 @@ Object CallOrConstructConstructor(BuiltinArguments args, Isolate* isolate) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, target, new_target)); - RETURN_RESULT_OR_FAILURE(isolate, T::New(isolate, map, locales, options)); + RETURN_RESULT_OR_FAILURE(isolate, + T::New(isolate, map, locales, options, method)); } } // namespace @@ -466,13 +463,8 @@ BUILTIN(NumberFormatInternalFormatNumber) { // 4. Let x be ? ToNumeric(value). Handle<Object> numeric_obj; - if (FLAG_harmony_intl_bigint) { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj, - Object::ToNumeric(isolate, value)); - } else { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj, - Object::ToNumber(isolate, value)); - } + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, numeric_obj, + Object::ToNumeric(isolate, value)); icu::number::LocalizedNumberFormatter* icu_localized_number_formatter = number_format->icu_number_formatter().raw(); @@ -884,7 +876,7 @@ BUILTIN(CollatorConstructor) { isolate->CountUsage(v8::Isolate::UseCounterFeature::kCollator); - return CallOrConstructConstructor<JSCollator>(args, isolate); + return CallOrConstructConstructor<JSCollator>(args, isolate, "Intl.Collator"); } BUILTIN(CollatorPrototypeResolvedOptions) { @@ -1069,7 +1061,8 @@ BUILTIN(SegmenterPrototypeSegment) { BUILTIN(V8BreakIteratorConstructor) { HandleScope scope(isolate); - return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate); + return CallOrConstructConstructor<JSV8BreakIterator>(args, isolate, + "Intl.v8BreakIterator"); } BUILTIN(V8BreakIteratorPrototypeResolvedOptions) { diff --git a/deps/v8/src/builtins/builtins-iterator-gen.cc b/deps/v8/src/builtins/builtins-iterator-gen.cc index 7bd5acfdcda845..2f8761902b5553 100644 --- a/deps/v8/src/builtins/builtins-iterator-gen.cc +++ b/deps/v8/src/builtins/builtins-iterator-gen.cc @@ -241,6 +241,104 @@ TF_BUILTIN(IterableToList, IteratorBuiltinsAssembler) { Return(IterableToList(context, iterable, iterator_fn)); } +TF_BUILTIN(IterableToFixedArrayForWasm, IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable)); + TNode<Smi> expected_length = CAST(Parameter(Descriptor::kExpectedLength)); + + TNode<Object> iterator_fn = GetIteratorMethod(context, iterable); + + IteratorRecord iterator_record = GetIterator(context, iterable, iterator_fn); + + GrowableFixedArray values(state()); + + Variable* vars[] = {values.var_array(), values.var_length(), + values.var_capacity()}; + Label loop_start(this, 3, vars), compare_length(this), done(this); + Goto(&loop_start); + BIND(&loop_start); + { + TNode<JSReceiver> next = + IteratorStep(context, iterator_record, &compare_length); + TNode<Object> next_value = IteratorValue(context, next); + values.Push(next_value); + Goto(&loop_start); + } + + BIND(&compare_length); + GotoIf(WordEqual(SmiUntag(expected_length), values.var_length()->value()), + &done); + Return(CallRuntime( + Runtime::kThrowTypeError, context, + SmiConstant(MessageTemplate::kWasmTrapMultiReturnLengthMismatch))); + + BIND(&done); + Return(values.var_array()->value()); +} + +TNode<JSArray> IteratorBuiltinsAssembler::StringListFromIterable( + TNode<Context> context, TNode<Object> iterable) { + Label done(this); + GrowableFixedArray list(state()); + // 1. If iterable is undefined, then + // a. Return a new empty List. + GotoIf(IsUndefined(iterable), &done); + + // 2. Let iteratorRecord be ? GetIterator(items). + IteratorRecord iterator_record = GetIterator(context, iterable); + + // 3. Let list be a new empty List. + + Variable* vars[] = {list.var_array(), list.var_length(), list.var_capacity()}; + Label loop_start(this, 3, vars); + Goto(&loop_start); + // 4. Let next be true. + // 5. Repeat, while next is not false + Label if_isnotstringtype(this, Label::kDeferred), + if_exception(this, Label::kDeferred); + BIND(&loop_start); + { + // a. Set next to ? IteratorStep(iteratorRecord). + TNode<JSReceiver> next = IteratorStep(context, iterator_record, &done); + // b. If next is not false, then + // i. Let nextValue be ? IteratorValue(next). + TNode<Object> next_value = IteratorValue(context, next); + // ii. If Type(nextValue) is not String, then + GotoIf(TaggedIsSmi(next_value), &if_isnotstringtype); + TNode<Uint16T> next_value_type = LoadInstanceType(CAST(next_value)); + GotoIfNot(IsStringInstanceType(next_value_type), &if_isnotstringtype); + // iii. Append nextValue to the end of the List list. + list.Push(next_value); + Goto(&loop_start); + // 5.b.ii + BIND(&if_isnotstringtype); + { + // 1. Let error be ThrowCompletion(a newly created TypeError object). + TVARIABLE(Object, var_exception); + TNode<Object> ret = CallRuntime( + Runtime::kThrowTypeError, context, + SmiConstant(MessageTemplate::kIterableYieldedNonString), next_value); + GotoIfException(ret, &if_exception, &var_exception); + Unreachable(); + + // 2. Return ? IteratorClose(iteratorRecord, error). + BIND(&if_exception); + IteratorCloseOnException(context, iterator_record, var_exception.value()); + } + } + + BIND(&done); + // 6. Return list. + return list.ToJSArray(context); +} + +TF_BUILTIN(StringListFromIterable, IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable)); + + Return(StringListFromIterable(context, iterable)); +} + // This builtin always returns a new JSArray and is thus safe to use even in the // presence of code that may call back into user-JS. This builtin will take the // fast path if the iterable is a fast array and the Array prototype and the @@ -354,5 +452,19 @@ TF_BUILTIN(IterableToListWithSymbolLookup, IteratorBuiltinsAssembler) { } } +TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation, + IteratorBuiltinsAssembler) { + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Smi> callSlot = CAST(Parameter(Descriptor::kCallSlot)); + TNode<FeedbackVector> feedback = CAST(Parameter(Descriptor::kFeedback)); + TNode<Object> iteratorMethod = CAST(Parameter(Descriptor::kResult)); + + TNode<Object> result = + CallBuiltin(Builtins::kCallIteratorWithFeedback, context, receiver, + iteratorMethod, callSlot, feedback); + Return(result); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/builtins-iterator-gen.h b/deps/v8/src/builtins/builtins-iterator-gen.h index 2a0a510f738782..7d6e7d5b811c1a 100644 --- a/deps/v8/src/builtins/builtins-iterator-gen.h +++ b/deps/v8/src/builtins/builtins-iterator-gen.h @@ -68,6 +68,11 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler { TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn); + // Currently at https://tc39.github.io/proposal-intl-list-format/ + // #sec-createstringlistfromiterable + TNode<JSArray> StringListFromIterable(TNode<Context> context, + TNode<Object> iterable); + void FastIterableToList(TNode<Context> context, TNode<Object> iterable, TVariable<Object>* var_result, Label* slow); }; diff --git a/deps/v8/src/builtins/builtins-math-gen.cc b/deps/v8/src/builtins/builtins-math-gen.cc index 42d0162f388d33..3bae7c06c35b46 100644 --- a/deps/v8/src/builtins/builtins-math-gen.cc +++ b/deps/v8/src/builtins/builtins-math-gen.cc @@ -143,20 +143,18 @@ void MathBuiltinsAssembler::MathRoundingOperation( } void MathBuiltinsAssembler::MathMaxMin( - Node* context, Node* argc, + TNode<Context> context, TNode<Int32T> argc, TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>, SloppyTNode<Float64T>), double default_val) { - CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc)); - argc = arguments.GetLength(INTPTR_PARAMETERS); + CodeStubArguments arguments(this, argc); - VARIABLE(result, MachineRepresentation::kFloat64); - result.Bind(Float64Constant(default_val)); + TVARIABLE(Float64T, result, Float64Constant(default_val)); CodeStubAssembler::VariableList vars({&result}, zone()); - arguments.ForEach(vars, [=, &result](Node* arg) { - Node* float_value = TruncateTaggedToFloat64(context, arg); - result.Bind((this->*float64op)(result.value(), float_value)); + arguments.ForEach(vars, [&](TNode<Object> arg) { + TNode<Float64T> float_value = TruncateTaggedToFloat64(context, arg); + result = (this->*float64op)(result.value(), float_value); }); arguments.PopAndReturn(ChangeFloat64ToTagged(result.value())); @@ -181,8 +179,8 @@ TF_BUILTIN(MathImul, CodeStubAssembler) { Node* context = Parameter(Descriptor::kContext); Node* x = Parameter(Descriptor::kX); Node* y = Parameter(Descriptor::kY); - Node* x_value = TruncateTaggedToWord32(context, x); - Node* y_value = TruncateTaggedToWord32(context, y); + TNode<Word32T> x_value = TruncateTaggedToWord32(context, x); + TNode<Word32T> y_value = TruncateTaggedToWord32(context, y); TNode<Int32T> value = Signed(Int32Mul(x_value, y_value)); TNode<Number> result = ChangeInt32ToTagged(value); Return(result); @@ -191,8 +189,8 @@ TF_BUILTIN(MathImul, CodeStubAssembler) { CodeStubAssembler::Node* MathBuiltinsAssembler::MathPow(Node* context, Node* base, Node* exponent) { - Node* base_value = TruncateTaggedToFloat64(context, base); - Node* exponent_value = TruncateTaggedToFloat64(context, exponent); + TNode<Float64T> base_value = TruncateTaggedToFloat64(context, base); + TNode<Float64T> exponent_value = TruncateTaggedToFloat64(context, exponent); TNode<Float64T> value = Float64Pow(base_value, exponent_value); return ChangeFloat64ToTagged(value); } @@ -260,19 +258,17 @@ TF_BUILTIN(MathTrunc, MathBuiltinsAssembler) { // ES6 #sec-math.max TF_BUILTIN(MathMax, MathBuiltinsAssembler) { - // TODO(ishell): use constants from Descriptor once the JSFunction linkage - // arguments are reordered. - Node* context = Parameter(Descriptor::kContext); - Node* argc = Parameter(Descriptor::kJSActualArgumentsCount); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); MathMaxMin(context, argc, &CodeStubAssembler::Float64Max, -1.0 * V8_INFINITY); } // ES6 #sec-math.min TF_BUILTIN(MathMin, MathBuiltinsAssembler) { - // TODO(ishell): use constants from Descriptor once the JSFunction linkage - // arguments are reordered. - Node* context = Parameter(Descriptor::kContext); - Node* argc = Parameter(Descriptor::kJSActualArgumentsCount); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); MathMaxMin(context, argc, &CodeStubAssembler::Float64Min, V8_INFINITY); } diff --git a/deps/v8/src/builtins/builtins-math-gen.h b/deps/v8/src/builtins/builtins-math-gen.h index 4bb76d96922681..4de654fa201609 100644 --- a/deps/v8/src/builtins/builtins-math-gen.h +++ b/deps/v8/src/builtins/builtins-math-gen.h @@ -21,7 +21,7 @@ class MathBuiltinsAssembler : public CodeStubAssembler { void MathRoundingOperation( Node* context, Node* x, TNode<Float64T> (CodeStubAssembler::*float64op)(SloppyTNode<Float64T>)); - void MathMaxMin(Node* context, Node* argc, + void MathMaxMin(TNode<Context> context, TNode<Int32T> argc, TNode<Float64T> (CodeStubAssembler::*float64op)( SloppyTNode<Float64T>, SloppyTNode<Float64T>), double default_val); diff --git a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc index 427fd6edb65f71..62aee3b300b371 100644 --- a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc +++ b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc @@ -14,9 +14,6 @@ namespace v8 { namespace internal { -template <typename T> -using TNode = compiler::TNode<T>; - class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler { public: explicit MicrotaskQueueBuiltinsAssembler(compiler::CodeAssemblerState* state) @@ -60,23 +57,20 @@ TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueue( TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskRingBuffer( TNode<RawPtrT> microtask_queue) { - return UncheckedCast<RawPtrT>( - Load(MachineType::Pointer(), microtask_queue, - IntPtrConstant(MicrotaskQueue::kRingBufferOffset))); + return Load<RawPtrT>(microtask_queue, + IntPtrConstant(MicrotaskQueue::kRingBufferOffset)); } TNode<IntPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueueCapacity( TNode<RawPtrT> microtask_queue) { - return UncheckedCast<IntPtrT>( - Load(MachineType::IntPtr(), microtask_queue, - IntPtrConstant(MicrotaskQueue::kCapacityOffset))); + return Load<IntPtrT>(microtask_queue, + IntPtrConstant(MicrotaskQueue::kCapacityOffset)); } TNode<IntPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueueSize( TNode<RawPtrT> microtask_queue) { - return UncheckedCast<IntPtrT>( - Load(MachineType::IntPtr(), microtask_queue, - IntPtrConstant(MicrotaskQueue::kSizeOffset))); + return Load<IntPtrT>(microtask_queue, + IntPtrConstant(MicrotaskQueue::kSizeOffset)); } void MicrotaskQueueBuiltinsAssembler::SetMicrotaskQueueSize( @@ -87,9 +81,8 @@ void MicrotaskQueueBuiltinsAssembler::SetMicrotaskQueueSize( TNode<IntPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueueStart( TNode<RawPtrT> microtask_queue) { - return UncheckedCast<IntPtrT>( - Load(MachineType::IntPtr(), microtask_queue, - IntPtrConstant(MicrotaskQueue::kStartOffset))); + return Load<IntPtrT>(microtask_queue, + IntPtrConstant(MicrotaskQueue::kStartOffset)); } void MicrotaskQueueBuiltinsAssembler::SetMicrotaskQueueStart( @@ -125,7 +118,7 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( TNode<Map> microtask_map = LoadMap(microtask); TNode<Uint16T> microtask_type = LoadMapInstanceType(microtask_map); - VARIABLE(var_exception, MachineRepresentation::kTagged, TheHoleConstant()); + TVARIABLE(HeapObject, var_exception, TheHoleConstant()); Label if_exception(this, Label::kDeferred); Label is_callable(this), is_callback(this), is_promise_fulfill_reaction_job(this), @@ -295,9 +288,9 @@ void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask( void MicrotaskQueueBuiltinsAssembler::IncrementFinishedMicrotaskCount( TNode<RawPtrT> microtask_queue) { - TNode<IntPtrT> count = UncheckedCast<IntPtrT>( - Load(MachineType::IntPtr(), microtask_queue, - IntPtrConstant(MicrotaskQueue::kFinishedMicrotaskCountOffset))); + TNode<IntPtrT> count = Load<IntPtrT>( + microtask_queue, + IntPtrConstant(MicrotaskQueue::kFinishedMicrotaskCountOffset)); TNode<IntPtrT> new_count = IntPtrAdd(count, IntPtrConstant(1)); StoreNoWriteBarrier( MachineType::PointerRepresentation(), microtask_queue, @@ -306,6 +299,8 @@ void MicrotaskQueueBuiltinsAssembler::IncrementFinishedMicrotaskCount( TNode<Context> MicrotaskQueueBuiltinsAssembler::GetCurrentContext() { auto ref = ExternalReference::Create(kContextAddress, isolate()); + // TODO(delphick): Add a checked cast. For now this is not possible as context + // can actually be Smi(0). return TNode<Context>::UncheckedCast(LoadFullTagged(ExternalConstant(ref))); } @@ -317,15 +312,13 @@ void MicrotaskQueueBuiltinsAssembler::SetCurrentContext( TNode<IntPtrT> MicrotaskQueueBuiltinsAssembler::GetEnteredContextCount() { auto ref = ExternalReference::handle_scope_implementer_address(isolate()); - Node* hsi = Load(MachineType::Pointer(), ExternalConstant(ref)); + TNode<RawPtrT> hsi = Load<RawPtrT>(ExternalConstant(ref)); using ContextStack = DetachableVector<Context>; TNode<IntPtrT> size_offset = IntPtrConstant(HandleScopeImplementer::kEnteredContextsOffset + ContextStack::kSizeOffset); - TNode<IntPtrT> size = - UncheckedCast<IntPtrT>(Load(MachineType::IntPtr(), hsi, size_offset)); - return size; + return Load<IntPtrT>(hsi, size_offset); } void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( @@ -333,7 +326,7 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( CSA_ASSERT(this, IsNativeContext(native_context)); auto ref = ExternalReference::handle_scope_implementer_address(isolate()); - Node* hsi = Load(MachineType::Pointer(), ExternalConstant(ref)); + TNode<RawPtrT> hsi = Load<RawPtrT>(ExternalConstant(ref)); using ContextStack = DetachableVector<Context>; TNode<IntPtrT> capacity_offset = @@ -343,10 +336,8 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( IntPtrConstant(HandleScopeImplementer::kEnteredContextsOffset + ContextStack::kSizeOffset); - TNode<IntPtrT> capacity = - UncheckedCast<IntPtrT>(Load(MachineType::IntPtr(), hsi, capacity_offset)); - TNode<IntPtrT> size = - UncheckedCast<IntPtrT>(Load(MachineType::IntPtr(), hsi, size_offset)); + TNode<IntPtrT> capacity = Load<IntPtrT>(hsi, capacity_offset); + TNode<IntPtrT> size = Load<IntPtrT>(hsi, size_offset); Label if_append(this), if_grow(this, Label::kDeferred), done(this); Branch(WordEqual(size, capacity), &if_grow, &if_append); @@ -355,7 +346,7 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( TNode<IntPtrT> data_offset = IntPtrConstant(HandleScopeImplementer::kEnteredContextsOffset + ContextStack::kDataOffset); - Node* data = Load(MachineType::Pointer(), hsi, data_offset); + TNode<RawPtrT> data = Load<RawPtrT>(hsi, data_offset); StoreFullTaggedNoWriteBarrier(data, TimesSystemPointerSize(size), native_context); @@ -367,7 +358,7 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( TNode<IntPtrT> flag_data_offset = IntPtrConstant(HandleScopeImplementer::kIsMicrotaskContextOffset + FlagStack::kDataOffset); - Node* flag_data = Load(MachineType::Pointer(), hsi, flag_data_offset); + TNode<RawPtrT> flag_data = Load<RawPtrT>(hsi, flag_data_offset); StoreNoWriteBarrier(MachineRepresentation::kWord8, flag_data, size, BoolConstant(true)); StoreNoWriteBarrier( @@ -396,7 +387,7 @@ void MicrotaskQueueBuiltinsAssembler::EnterMicrotaskContext( void MicrotaskQueueBuiltinsAssembler::RewindEnteredContext( TNode<IntPtrT> saved_entered_context_count) { auto ref = ExternalReference::handle_scope_implementer_address(isolate()); - Node* hsi = Load(MachineType::Pointer(), ExternalConstant(ref)); + TNode<RawPtrT> hsi = Load<RawPtrT>(ExternalConstant(ref)); using ContextStack = DetachableVector<Context>; TNode<IntPtrT> size_offset = @@ -404,8 +395,7 @@ void MicrotaskQueueBuiltinsAssembler::RewindEnteredContext( ContextStack::kSizeOffset); #ifdef ENABLE_VERIFY_CSA - TNode<IntPtrT> size = - UncheckedCast<IntPtrT>(Load(MachineType::IntPtr(), hsi, size_offset)); + TNode<IntPtrT> size = Load<IntPtrT>(hsi, size_offset); CSA_ASSERT(this, IntPtrLessThan(IntPtrConstant(0), size)); CSA_ASSERT(this, IntPtrLessThanOrEqual(saved_entered_context_count, size)); #endif @@ -446,8 +436,7 @@ void MicrotaskQueueBuiltinsAssembler::RunPromiseHook( } TF_BUILTIN(EnqueueMicrotask, MicrotaskQueueBuiltinsAssembler) { - TNode<Microtask> microtask = - UncheckedCast<Microtask>(Parameter(Descriptor::kMicrotask)); + TNode<Microtask> microtask = CAST(Parameter(Descriptor::kMicrotask)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<NativeContext> native_context = LoadNativeContext(context); TNode<RawPtrT> microtask_queue = GetMicrotaskQueue(native_context); @@ -517,8 +506,7 @@ TF_BUILTIN(RunMicrotasks, MicrotaskQueueBuiltinsAssembler) { TNode<IntPtrT> offset = CalculateRingBufferOffset(capacity, start, IntPtrConstant(0)); - TNode<RawPtrT> microtask_pointer = - UncheckedCast<RawPtrT>(Load(MachineType::Pointer(), ring_buffer, offset)); + TNode<RawPtrT> microtask_pointer = Load<RawPtrT>(ring_buffer, offset); TNode<Microtask> microtask = CAST(BitcastWordToTagged(microtask_pointer)); TNode<IntPtrT> new_size = IntPtrSub(size, IntPtrConstant(1)); diff --git a/deps/v8/src/builtins/builtins-number-gen.cc b/deps/v8/src/builtins/builtins-number-gen.cc index 2aa996eba0dc2f..fc737b793bec26 100644 --- a/deps/v8/src/builtins/builtins-number-gen.cc +++ b/deps/v8/src/builtins/builtins-number-gen.cc @@ -22,57 +22,58 @@ class NumberBuiltinsAssembler : public CodeStubAssembler { protected: template <typename Descriptor> void EmitBitwiseOp(Operation op) { - Node* left = Parameter(Descriptor::kLeft); - Node* right = Parameter(Descriptor::kRight); - Node* context = Parameter(Descriptor::kContext); - - VARIABLE(var_left_word32, MachineRepresentation::kWord32); - VARIABLE(var_right_word32, MachineRepresentation::kWord32); - VARIABLE(var_left_bigint, MachineRepresentation::kTagged, left); - VARIABLE(var_right_bigint, MachineRepresentation::kTagged); + TNode<Object> left = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> right = CAST(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + + TVARIABLE(Word32T, var_left_word32); + TVARIABLE(Word32T, var_right_word32); + TVARIABLE(Object, var_left_maybe_bigint, left); + TVARIABLE(Object, var_right_maybe_bigint); Label if_left_number(this), do_number_op(this); Label if_left_bigint(this), do_bigint_op(this); TaggedToWord32OrBigInt(context, left, &if_left_number, &var_left_word32, - &if_left_bigint, &var_left_bigint); + &if_left_bigint, &var_left_maybe_bigint); BIND(&if_left_number); TaggedToWord32OrBigInt(context, right, &do_number_op, &var_right_word32, - &do_bigint_op, &var_right_bigint); + &do_bigint_op, &var_right_maybe_bigint); BIND(&do_number_op); Return(BitwiseOp(var_left_word32.value(), var_right_word32.value(), op)); // BigInt cases. BIND(&if_left_bigint); - TaggedToNumeric(context, right, &do_bigint_op, &var_right_bigint); + TaggedToNumeric(context, right, &do_bigint_op, &var_right_maybe_bigint); BIND(&do_bigint_op); Return(CallRuntime(Runtime::kBigIntBinaryOp, context, - var_left_bigint.value(), var_right_bigint.value(), - SmiConstant(op))); + var_left_maybe_bigint.value(), + var_right_maybe_bigint.value(), SmiConstant(op))); } template <typename Descriptor> void RelationalComparisonBuiltin(Operation op) { - Node* lhs = Parameter(Descriptor::kLeft); - Node* rhs = Parameter(Descriptor::kRight); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> rhs = CAST(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(RelationalComparison(op, lhs, rhs, context)); } template <typename Descriptor> - void UnaryOp(Variable* var_input, Label* do_smi, Label* do_double, - Variable* var_input_double, Label* do_bigint); + void UnaryOp(TVariable<Object>* var_input, Label* do_smi, Label* do_double, + TVariable<Float64T>* var_input_double, Label* do_bigint); template <typename Descriptor> - void BinaryOp(Label* smis, Variable* var_left, Variable* var_right, - Label* doubles, Variable* var_left_double, - Variable* var_right_double, Label* bigints); + void BinaryOp(Label* smis, TVariable<Object>* var_left, + TVariable<Object>* var_right, Label* doubles, + TVariable<Float64T>* var_left_double, + TVariable<Float64T>* var_right_double, Label* bigints); }; // ES6 #sec-number.isfinite TF_BUILTIN(NumberIsFinite, CodeStubAssembler) { - Node* number = Parameter(Descriptor::kNumber); + TNode<Object> number = CAST(Parameter(Descriptor::kNumber)); Label return_true(this), return_false(this); @@ -80,10 +81,11 @@ TF_BUILTIN(NumberIsFinite, CodeStubAssembler) { GotoIf(TaggedIsSmi(number), &return_true); // Check if {number} is a HeapNumber. - GotoIfNot(IsHeapNumber(number), &return_false); + TNode<HeapObject> number_heap_object = CAST(number); + GotoIfNot(IsHeapNumber(number_heap_object), &return_false); // Check if {number} contains a finite, non-NaN value. - TNode<Float64T> number_value = LoadHeapNumberValue(number); + TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object); BranchIfFloat64IsNaN(Float64Sub(number_value, number_value), &return_false, &return_true); @@ -107,7 +109,7 @@ TF_BUILTIN(NumberIsInteger, CodeStubAssembler) { // ES6 #sec-number.isnan TF_BUILTIN(NumberIsNaN, CodeStubAssembler) { - Node* number = Parameter(Descriptor::kNumber); + TNode<Object> number = CAST(Parameter(Descriptor::kNumber)); Label return_true(this), return_false(this); @@ -115,10 +117,11 @@ TF_BUILTIN(NumberIsNaN, CodeStubAssembler) { GotoIf(TaggedIsSmi(number), &return_false); // Check if {number} is a HeapNumber. - GotoIfNot(IsHeapNumber(number), &return_false); + TNode<HeapObject> number_heap_object = CAST(number); + GotoIfNot(IsHeapNumber(number_heap_object), &return_false); // Check if {number} contains a NaN value. - TNode<Float64T> number_value = LoadHeapNumberValue(number); + TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object); BranchIfFloat64IsNaN(number_value, &return_true, &return_false); BIND(&return_true); @@ -136,17 +139,16 @@ TF_BUILTIN(NumberIsSafeInteger, CodeStubAssembler) { // ES6 #sec-number.parsefloat TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // We might need to loop once for ToString conversion. - VARIABLE(var_input, MachineRepresentation::kTagged, - Parameter(Descriptor::kString)); + TVARIABLE(Object, var_input, CAST(Parameter(Descriptor::kString))); Label loop(this, &var_input); Goto(&loop); BIND(&loop); { // Load the current {input} value. - Node* input = var_input.value(); + TNode<Object> input = var_input.value(); // Check if the {input} is a HeapObject or a Smi. Label if_inputissmi(this), if_inputisnotsmi(this); @@ -161,8 +163,9 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { BIND(&if_inputisnotsmi); { // The {input} is a HeapObject, check if it's already a String. + TNode<HeapObject> input_heap_object = CAST(input); Label if_inputisstring(this), if_inputisnotstring(this); - TNode<Map> input_map = LoadMap(input); + TNode<Map> input_map = LoadMap(input_heap_object); TNode<Uint16T> input_instance_type = LoadMapInstanceType(input_map); Branch(IsStringInstanceType(input_instance_type), &if_inputisstring, &if_inputisnotstring); @@ -172,7 +175,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { // The {input} is already a String, check if {input} contains // a cached array index. Label if_inputcached(this), if_inputnotcached(this); - TNode<Uint32T> input_hash = LoadNameHashField(input); + TNode<Uint32T> input_hash = LoadNameHashField(CAST(input)); Branch(IsClearWord32(input_hash, Name::kDoesNotContainCachedArrayIndexMask), &if_inputcached, &if_inputnotcached); @@ -204,7 +207,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { { // The {input} is already a Number, take care of -0. Label if_inputiszero(this), if_inputisnotzero(this); - TNode<Float64T> input_value = LoadHeapNumberValue(input); + TNode<Float64T> input_value = LoadHeapNumberValue(input_heap_object); Branch(Float64Equal(input_value, Float64Constant(0.0)), &if_inputiszero, &if_inputisnotzero); @@ -219,7 +222,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) { { // Need to convert the {input} to String first. // TODO(bmeurer): This could be more efficient if necessary. - var_input.Bind(CallBuiltin(Builtins::kToString, context, input)); + var_input = CallBuiltin(Builtins::kToString, context, input); Goto(&loop); } } @@ -309,9 +312,9 @@ TF_BUILTIN(ParseInt, CodeStubAssembler) { // ES6 #sec-number.parseint TF_BUILTIN(NumberParseInt, CodeStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - Node* input = Parameter(Descriptor::kString); - Node* radix = Parameter(Descriptor::kRadix); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> input = CAST(Parameter(Descriptor::kString)); + TNode<Object> radix = CAST(Parameter(Descriptor::kRadix)); Return(CallBuiltin(Builtins::kParseInt, context, input, radix)); } @@ -331,27 +334,29 @@ class AddStubAssembler : public CodeStubAssembler { : CodeStubAssembler(state) {} protected: - void ConvertReceiverAndLoop(Variable* var_value, Label* loop, Node* context) { + TNode<Object> ConvertReceiver(TNode<JSReceiver> js_receiver, + TNode<Context> context) { // Call ToPrimitive explicitly without hint (whereas ToNumber // would pass a "number" hint). Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate()); - var_value->Bind(CallStub(callable, context, var_value->value())); - Goto(loop); + return CallStub(callable, context, js_receiver); } - void ConvertNonReceiverAndLoop(Variable* var_value, Label* loop, - Node* context) { - var_value->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, - var_value->value())); + void ConvertNonReceiverAndLoop(TVariable<Object>* var_value, Label* loop, + TNode<Context> context) { + *var_value = + CallBuiltin(Builtins::kNonNumberToNumeric, context, var_value->value()); Goto(loop); } - void ConvertAndLoop(Variable* var_value, Node* instance_type, Label* loop, - Node* context) { + void ConvertAndLoop(TVariable<Object>* var_value, + TNode<Uint16T> instance_type, Label* loop, + TNode<Context> context) { Label is_not_receiver(this, Label::kDeferred); GotoIfNot(IsJSReceiverInstanceType(instance_type), &is_not_receiver); - ConvertReceiverAndLoop(var_value, loop, context); + *var_value = ConvertReceiver(CAST(var_value->value()), context); + Goto(loop); BIND(&is_not_receiver); ConvertNonReceiverAndLoop(var_value, loop, context); @@ -359,30 +364,26 @@ class AddStubAssembler : public CodeStubAssembler { }; TF_BUILTIN(Add, AddStubAssembler) { - Node* context = Parameter(Descriptor::kContext); - VARIABLE(var_left, MachineRepresentation::kTagged, - Parameter(Descriptor::kLeft)); - VARIABLE(var_right, MachineRepresentation::kTagged, - Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TVARIABLE(Object, var_left, CAST(Parameter(Descriptor::kLeft))); + TVARIABLE(Object, var_right, CAST(Parameter(Descriptor::kRight))); // Shared entry for floating point addition. Label do_double_add(this); - VARIABLE(var_left_double, MachineRepresentation::kFloat64); - VARIABLE(var_right_double, MachineRepresentation::kFloat64); + TVARIABLE(Float64T, var_left_double); + TVARIABLE(Float64T, var_right_double); // We might need to loop several times due to ToPrimitive, ToString and/or // ToNumeric conversions. - VARIABLE(var_result, MachineRepresentation::kTagged); - Variable* loop_vars[2] = {&var_left, &var_right}; - Label loop(this, 2, loop_vars), + Label loop(this, {&var_left, &var_right}), string_add_convert_left(this, Label::kDeferred), string_add_convert_right(this, Label::kDeferred), do_bigint_add(this, Label::kDeferred); Goto(&loop); BIND(&loop); { - Node* left = var_left.value(); - Node* right = var_right.value(); + TNode<Object> left = var_left.value(); + TNode<Object> right = var_right.value(); Label if_left_smi(this), if_left_heapobject(this); Branch(TaggedIsSmi(left), &if_left_smi, &if_left_heapobject); @@ -395,27 +396,30 @@ TF_BUILTIN(Add, AddStubAssembler) { BIND(&if_right_smi); { Label if_overflow(this); - TNode<Smi> result = TrySmiAdd(CAST(left), CAST(right), &if_overflow); + TNode<Smi> left_smi = CAST(left); + TNode<Smi> right_smi = CAST(right); + TNode<Smi> result = TrySmiAdd(left_smi, right_smi, &if_overflow); Return(result); BIND(&if_overflow); { - var_left_double.Bind(SmiToFloat64(left)); - var_right_double.Bind(SmiToFloat64(right)); + var_left_double = SmiToFloat64(left_smi); + var_right_double = SmiToFloat64(right_smi); Goto(&do_double_add); } } // if_right_smi BIND(&if_right_heapobject); { - TNode<Map> right_map = LoadMap(right); + TNode<HeapObject> right_heap_object = CAST(right); + TNode<Map> right_map = LoadMap(right_heap_object); Label if_right_not_number(this, Label::kDeferred); GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number); // {right} is a HeapNumber. - var_left_double.Bind(SmiToFloat64(left)); - var_right_double.Bind(LoadHeapNumberValue(right)); + var_left_double = SmiToFloat64(CAST(left)); + var_right_double = LoadHeapNumberValue(right_heap_object); Goto(&do_double_add); BIND(&if_right_not_number); @@ -431,7 +435,8 @@ TF_BUILTIN(Add, AddStubAssembler) { BIND(&if_left_heapobject); { - TNode<Map> left_map = LoadMap(left); + TNode<HeapObject> left_heap_object = CAST(left); + TNode<Map> left_map = LoadMap(left_heap_object); Label if_right_smi(this), if_right_heapobject(this); Branch(TaggedIsSmi(right), &if_right_smi, &if_right_heapobject); @@ -441,8 +446,8 @@ TF_BUILTIN(Add, AddStubAssembler) { GotoIfNot(IsHeapNumberMap(left_map), &if_left_not_number); // {left} is a HeapNumber, {right} is a Smi. - var_left_double.Bind(LoadHeapNumberValue(left)); - var_right_double.Bind(SmiToFloat64(right)); + var_left_double = LoadHeapNumberValue(left_heap_object); + var_right_double = SmiToFloat64(CAST(right)); Goto(&do_double_add); BIND(&if_left_not_number); @@ -458,7 +463,8 @@ TF_BUILTIN(Add, AddStubAssembler) { BIND(&if_right_heapobject); { - TNode<Map> right_map = LoadMap(right); + TNode<HeapObject> right_heap_object = CAST(right); + TNode<Map> right_map = LoadMap(right_heap_object); Label if_left_number(this), if_left_not_number(this, Label::kDeferred); Branch(IsHeapNumberMap(left_map), &if_left_number, &if_left_not_number); @@ -469,8 +475,8 @@ TF_BUILTIN(Add, AddStubAssembler) { GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number); // Both {left} and {right} are HeapNumbers. - var_left_double.Bind(LoadHeapNumberValue(left)); - var_right_double.Bind(LoadHeapNumberValue(right)); + var_left_double = LoadHeapNumberValue(CAST(left)); + var_right_double = LoadHeapNumberValue(right_heap_object); Goto(&do_double_add); BIND(&if_right_not_number); @@ -499,7 +505,8 @@ TF_BUILTIN(Add, AddStubAssembler) { GotoIfNot(IsJSReceiverInstanceType(left_instance_type), &if_left_not_receiver); // {left} is a JSReceiver, convert it first. - ConvertReceiverAndLoop(&var_left, &loop, context); + var_left = ConvertReceiver(CAST(var_left.value()), context); + Goto(&loop); BIND(&if_left_bigint); { @@ -515,7 +522,8 @@ TF_BUILTIN(Add, AddStubAssembler) { &if_right_not_receiver); // {left} is a Primitive, but {right} is a JSReceiver, so convert // {right} with priority. - ConvertReceiverAndLoop(&var_right, &loop, context); + var_right = ConvertReceiver(CAST(var_right.value()), context); + Goto(&loop); BIND(&if_right_not_receiver); // Neither {left} nor {right} are JSReceivers. @@ -553,54 +561,46 @@ TF_BUILTIN(Add, AddStubAssembler) { } template <typename Descriptor> -void NumberBuiltinsAssembler::UnaryOp(Variable* var_input, Label* do_smi, - Label* do_double, - Variable* var_input_double, +void NumberBuiltinsAssembler::UnaryOp(TVariable<Object>* var_input, + Label* do_smi, Label* do_double, + TVariable<Float64T>* var_input_double, Label* do_bigint) { - DCHECK_EQ(var_input->rep(), MachineRepresentation::kTagged); - DCHECK_IMPLIES(var_input_double != nullptr, - var_input_double->rep() == MachineRepresentation::kFloat64); - - Node* context = Parameter(Descriptor::kContext); - var_input->Bind(Parameter(Descriptor::kValue)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + *var_input = CAST(Parameter(Descriptor::kValue)); // We might need to loop for ToNumeric conversion. Label loop(this, {var_input}); Goto(&loop); BIND(&loop); - Node* input = var_input->value(); + TNode<Object> input = var_input->value(); Label not_number(this); GotoIf(TaggedIsSmi(input), do_smi); - GotoIfNot(IsHeapNumber(input), ¬_number); + TNode<HeapObject> input_heap_object = CAST(input); + GotoIfNot(IsHeapNumber(input_heap_object), ¬_number); if (var_input_double != nullptr) { - var_input_double->Bind(LoadHeapNumberValue(input)); + *var_input_double = LoadHeapNumberValue(input_heap_object); } Goto(do_double); BIND(¬_number); - GotoIf(IsBigInt(input), do_bigint); - var_input->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, input)); + GotoIf(IsBigInt(input_heap_object), do_bigint); + *var_input = CallBuiltin(Builtins::kNonNumberToNumeric, context, input); Goto(&loop); } template <typename Descriptor> -void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, - Variable* var_right, Label* doubles, - Variable* var_left_double, - Variable* var_right_double, +void NumberBuiltinsAssembler::BinaryOp(Label* smis, TVariable<Object>* var_left, + TVariable<Object>* var_right, + Label* doubles, + TVariable<Float64T>* var_left_double, + TVariable<Float64T>* var_right_double, Label* bigints) { - DCHECK_EQ(var_left->rep(), MachineRepresentation::kTagged); - DCHECK_EQ(var_right->rep(), MachineRepresentation::kTagged); - DCHECK_IMPLIES(var_left_double != nullptr, - var_left_double->rep() == MachineRepresentation::kFloat64); - DCHECK_IMPLIES(var_right_double != nullptr, - var_right_double->rep() == MachineRepresentation::kFloat64); DCHECK_EQ(var_left_double == nullptr, var_right_double == nullptr); - Node* context = Parameter(Descriptor::kContext); - var_left->Bind(Parameter(Descriptor::kLeft)); - var_right->Bind(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + *var_left = CAST(Parameter(Descriptor::kLeft)); + *var_right = CAST(Parameter(Descriptor::kRight)); // We might need to loop for ToNumeric conversions. Label loop(this, {var_left, var_right}); @@ -613,32 +613,36 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, GotoIf(TaggedIsSmi(var_right->value()), smis); // At this point, var_left is a Smi but var_right is not. - GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number); + TNode<Smi> var_left_smi = CAST(var_left->value()); + TNode<HeapObject> var_right_heap_object = CAST(var_right->value()); + GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number); if (var_left_double != nullptr) { - var_left_double->Bind(SmiToFloat64(var_left->value())); - var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + *var_left_double = SmiToFloat64(var_left_smi); + *var_right_double = LoadHeapNumberValue(var_right_heap_object); } Goto(doubles); BIND(&left_not_smi); { - GotoIfNot(IsHeapNumber(var_left->value()), &left_not_number); + TNode<HeapObject> var_left_heap_object = CAST(var_left->value()); + GotoIfNot(IsHeapNumber(var_left_heap_object), &left_not_number); GotoIfNot(TaggedIsSmi(var_right->value()), &right_not_smi); // At this point, var_left is a HeapNumber and var_right is a Smi. if (var_left_double != nullptr) { - var_left_double->Bind(LoadHeapNumberValue(var_left->value())); - var_right_double->Bind(SmiToFloat64(var_right->value())); + *var_left_double = LoadHeapNumberValue(var_left_heap_object); + *var_right_double = SmiToFloat64(CAST(var_right->value())); } Goto(doubles); } BIND(&right_not_smi); { - GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number); + TNode<HeapObject> var_right_heap_object = CAST(var_right->value()); + GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number); if (var_left_double != nullptr) { - var_left_double->Bind(LoadHeapNumberValue(var_left->value())); - var_right_double->Bind(LoadHeapNumberValue(var_right->value())); + *var_left_double = LoadHeapNumberValue(CAST(var_left->value())); + *var_right_double = LoadHeapNumberValue(var_right_heap_object); } Goto(doubles); } @@ -646,37 +650,38 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left, BIND(&left_not_number); { Label left_bigint(this); - GotoIf(IsBigInt(var_left->value()), &left_bigint); - var_left->Bind( - CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value())); + GotoIf(IsBigInt(CAST(var_left->value())), &left_bigint); + *var_left = + CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value()); Goto(&loop); BIND(&left_bigint); { // Jump to {bigints} if {var_right} is already a Numeric. GotoIf(TaggedIsSmi(var_right->value()), bigints); - GotoIf(IsBigInt(var_right->value()), bigints); - GotoIf(IsHeapNumber(var_right->value()), bigints); - var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, - var_right->value())); + TNode<HeapObject> var_right_heap_object = CAST(var_right->value()); + GotoIf(IsBigInt(var_right_heap_object), bigints); + GotoIf(IsHeapNumber(var_right_heap_object), bigints); + *var_right = CallBuiltin(Builtins::kNonNumberToNumeric, context, + var_right->value()); Goto(&loop); } } BIND(&right_not_number); { - GotoIf(IsBigInt(var_right->value()), bigints); - var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, - var_right->value())); + GotoIf(IsBigInt(CAST(var_right->value())), bigints); + *var_right = + CallBuiltin(Builtins::kNonNumberToNumeric, context, var_right->value()); Goto(&loop); } } TF_BUILTIN(Subtract, NumberBuiltinsAssembler) { - VARIABLE(var_left, MachineRepresentation::kTagged); - VARIABLE(var_right, MachineRepresentation::kTagged); - VARIABLE(var_left_double, MachineRepresentation::kFloat64); - VARIABLE(var_right_double, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_left); + TVARIABLE(Object, var_right); + TVARIABLE(Float64T, var_left_double); + TVARIABLE(Float64T, var_right_double); Label do_smi_sub(this), do_double_sub(this), do_bigint_sub(this); BinaryOp<Descriptor>(&do_smi_sub, &var_left, &var_right, &do_double_sub, @@ -685,14 +690,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) { BIND(&do_smi_sub); { Label if_overflow(this); - TNode<Smi> result = TrySmiSub(CAST(var_left.value()), - CAST(var_right.value()), &if_overflow); + TNode<Smi> var_left_smi = CAST(var_left.value()); + TNode<Smi> var_right_smi = CAST(var_right.value()); + TNode<Smi> result = TrySmiSub(var_left_smi, var_right_smi, &if_overflow); Return(result); BIND(&if_overflow); { - var_left_double.Bind(SmiToFloat64(var_left.value())); - var_right_double.Bind(SmiToFloat64(var_right.value())); + var_left_double = SmiToFloat64(var_left_smi); + var_right_double = SmiToFloat64(var_right_smi); Goto(&do_double_sub); } } @@ -706,15 +712,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) { BIND(&do_bigint_sub); { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), var_right.value(), SmiConstant(Operation::kSubtract))); } } TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - VARIABLE(var_input, MachineRepresentation::kTagged); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TVARIABLE(Object, var_input); Label do_number(this), do_bigint(this); UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint); @@ -733,8 +739,8 @@ TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) { } TF_BUILTIN(Decrement, NumberBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - VARIABLE(var_input, MachineRepresentation::kTagged); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TVARIABLE(Object, var_input); Label do_number(this), do_bigint(this); UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint); @@ -753,8 +759,8 @@ TF_BUILTIN(Decrement, NumberBuiltinsAssembler) { } TF_BUILTIN(Increment, NumberBuiltinsAssembler) { - Node* context = Parameter(Descriptor::kContext); - VARIABLE(var_input, MachineRepresentation::kTagged); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TVARIABLE(Object, var_input); Label do_number(this), do_bigint(this); UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint); @@ -772,8 +778,8 @@ TF_BUILTIN(Increment, NumberBuiltinsAssembler) { } TF_BUILTIN(Negate, NumberBuiltinsAssembler) { - VARIABLE(var_input, MachineRepresentation::kTagged); - VARIABLE(var_input_double, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_input); + TVARIABLE(Float64T, var_input_double); Label do_smi(this), do_double(this), do_bigint(this); UnaryOp<Descriptor>(&var_input, &do_smi, &do_double, &var_input_double, @@ -791,17 +797,17 @@ TF_BUILTIN(Negate, NumberBuiltinsAssembler) { BIND(&do_bigint); { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(CallRuntime(Runtime::kBigIntUnaryOp, context, var_input.value(), SmiConstant(Operation::kNegate))); } } TF_BUILTIN(Multiply, NumberBuiltinsAssembler) { - VARIABLE(var_left, MachineRepresentation::kTagged); - VARIABLE(var_right, MachineRepresentation::kTagged); - VARIABLE(var_left_double, MachineRepresentation::kFloat64); - VARIABLE(var_right_double, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_left); + TVARIABLE(Object, var_right); + TVARIABLE(Float64T, var_left_double); + TVARIABLE(Float64T, var_right_double); Label do_smi_mul(this), do_double_mul(this), do_bigint_mul(this); BinaryOp<Descriptor>(&do_smi_mul, &var_left, &var_right, &do_double_mul, @@ -818,17 +824,17 @@ TF_BUILTIN(Multiply, NumberBuiltinsAssembler) { BIND(&do_bigint_mul); { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), var_right.value(), SmiConstant(Operation::kMultiply))); } } TF_BUILTIN(Divide, NumberBuiltinsAssembler) { - VARIABLE(var_left, MachineRepresentation::kTagged); - VARIABLE(var_right, MachineRepresentation::kTagged); - VARIABLE(var_left_double, MachineRepresentation::kFloat64); - VARIABLE(var_right_double, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_left); + TVARIABLE(Object, var_right); + TVARIABLE(Float64T, var_left_double); + TVARIABLE(Float64T, var_right_double); Label do_smi_div(this), do_double_div(this), do_bigint_div(this); BinaryOp<Descriptor>(&do_smi_div, &var_left, &var_right, &do_double_div, @@ -889,8 +895,8 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) { // division. BIND(&bailout); { - var_left_double.Bind(SmiToFloat64(dividend)); - var_right_double.Bind(SmiToFloat64(divisor)); + var_left_double = SmiToFloat64(dividend); + var_right_double = SmiToFloat64(divisor); Goto(&do_double_div); } } @@ -904,17 +910,17 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) { BIND(&do_bigint_div); { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), var_right.value(), SmiConstant(Operation::kDivide))); } } TF_BUILTIN(Modulus, NumberBuiltinsAssembler) { - VARIABLE(var_left, MachineRepresentation::kTagged); - VARIABLE(var_right, MachineRepresentation::kTagged); - VARIABLE(var_left_double, MachineRepresentation::kFloat64); - VARIABLE(var_right_double, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_left); + TVARIABLE(Object, var_right); + TVARIABLE(Float64T, var_left_double); + TVARIABLE(Float64T, var_right_double); Label do_smi_mod(this), do_double_mod(this), do_bigint_mod(this); BinaryOp<Descriptor>(&do_smi_mod, &var_left, &var_right, &do_double_mod, @@ -930,17 +936,17 @@ TF_BUILTIN(Modulus, NumberBuiltinsAssembler) { BIND(&do_bigint_mod); { - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(), var_right.value(), SmiConstant(Operation::kModulus))); } } TF_BUILTIN(Exponentiate, NumberBuiltinsAssembler) { - VARIABLE(var_left, MachineRepresentation::kTagged); - VARIABLE(var_right, MachineRepresentation::kTagged); + TVARIABLE(Object, var_left); + TVARIABLE(Object, var_right); Label do_number_exp(this), do_bigint_exp(this); - Node* context = Parameter(Descriptor::kContext); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); BinaryOp<Descriptor>(&do_number_exp, &var_left, &var_right, &do_number_exp, nullptr, nullptr, &do_bigint_exp); @@ -997,9 +1003,9 @@ TF_BUILTIN(GreaterThanOrEqual, NumberBuiltinsAssembler) { } TF_BUILTIN(Equal, CodeStubAssembler) { - Node* lhs = Parameter(Descriptor::kLeft); - Node* rhs = Parameter(Descriptor::kRight); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> rhs = CAST(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(Equal(lhs, rhs, context)); } diff --git a/deps/v8/src/builtins/builtins-number.cc b/deps/v8/src/builtins/builtins-number.cc index d2fb0ff74c3a02..49e7ff27b850d2 100644 --- a/deps/v8/src/builtins/builtins-number.cc +++ b/deps/v8/src/builtins/builtins-number.cc @@ -111,6 +111,7 @@ BUILTIN(NumberPrototypeToFixed) { // ES6 section 20.1.3.4 Number.prototype.toLocaleString ( [ r1 [ , r2 ] ] ) BUILTIN(NumberPrototypeToLocaleString) { HandleScope scope(isolate); + const char* method = "Number.prototype.toLocaleString"; isolate->CountUsage(v8::Isolate::UseCounterFeature::kNumberToLocaleString); @@ -123,17 +124,17 @@ BUILTIN(NumberPrototypeToLocaleString) { // 1. Let x be ? thisNumberValue(this value) if (!value->IsNumber()) { THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kNotGeneric, - isolate->factory()->NewStringFromAsciiChecked( - "Number.prototype.toLocaleString"), - isolate->factory()->Number_string())); + isolate, + NewTypeError(MessageTemplate::kNotGeneric, + isolate->factory()->NewStringFromAsciiChecked(method), + isolate->factory()->Number_string())); } #ifdef V8_INTL_SUPPORT RETURN_RESULT_OR_FAILURE( isolate, Intl::NumberToLocaleString(isolate, value, args.atOrUndefined(isolate, 1), - args.atOrUndefined(isolate, 2))); + args.atOrUndefined(isolate, 2), method)); #else // Turn the {value} into a String. return *isolate->factory()->NumberToString(value); diff --git a/deps/v8/src/builtins/builtins-object-gen.cc b/deps/v8/src/builtins/builtins-object-gen.cc index db9d4ed6579244..a35990e2f57801 100644 --- a/deps/v8/src/builtins/builtins-object-gen.cc +++ b/deps/v8/src/builtins/builtins-object-gen.cc @@ -22,29 +22,35 @@ namespace internal { // ----------------------------------------------------------------------------- // ES6 section 19.1 Object Objects -using Node = compiler::Node; -template <class T> -using TNode = CodeStubAssembler::TNode<T>; - class ObjectBuiltinsAssembler : public CodeStubAssembler { public: explicit ObjectBuiltinsAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} protected: - void ReturnToStringFormat(Node* context, Node* string); + void ReturnToStringFormat(TNode<Context> context, TNode<String> string); void AddToDictionaryIf(TNode<BoolT> condition, TNode<NameDictionary> name_dictionary, Handle<Name> name, TNode<Object> value, Label* bailout); - Node* FromPropertyDescriptor(Node* context, Node* desc); - Node* FromPropertyDetails(Node* context, Node* raw_value, Node* details, - Label* if_bailout); - Node* ConstructAccessorDescriptor(Node* context, Node* getter, Node* setter, - Node* enumerable, Node* configurable); - Node* ConstructDataDescriptor(Node* context, Node* value, Node* writable, - Node* enumerable, Node* configurable); - Node* GetAccessorOrUndefined(Node* accessor, Label* if_bailout); + TNode<JSObject> FromPropertyDescriptor(TNode<Context> context, + TNode<FixedArray> desc); + TNode<JSObject> FromPropertyDetails(TNode<Context> context, + TNode<Object> raw_value, + TNode<Word32T> details, + Label* if_bailout); + TNode<JSObject> ConstructAccessorDescriptor(TNode<Context> context, + TNode<Object> getter, + TNode<Object> setter, + TNode<BoolT> enumerable, + TNode<BoolT> configurable); + TNode<JSObject> ConstructDataDescriptor(TNode<Context> context, + TNode<Object> value, + TNode<BoolT> writable, + TNode<BoolT> enumerable, + TNode<BoolT> configurable); + TNode<HeapObject> GetAccessorOrUndefined(TNode<HeapObject> accessor, + Label* if_bailout); }; class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler { @@ -79,8 +85,8 @@ class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler { TNode<IntPtrT> size, TNode<Map> array_map, Label* if_empty); }; -void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, - Node* string) { +void ObjectBuiltinsAssembler::ReturnToStringFormat(TNode<Context> context, + TNode<String> string) { TNode<String> lhs = StringConstant("[object "); TNode<String> rhs = StringConstant("]"); @@ -90,11 +96,9 @@ void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, rhs)); } -Node* ObjectBuiltinsAssembler::ConstructAccessorDescriptor(Node* context, - Node* getter, - Node* setter, - Node* enumerable, - Node* configurable) { +TNode<JSObject> ObjectBuiltinsAssembler::ConstructAccessorDescriptor( + TNode<Context> context, TNode<Object> getter, TNode<Object> setter, + TNode<BoolT> enumerable, TNode<BoolT> configurable) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> map = CAST(LoadContextElement( native_context, Context::ACCESSOR_PROPERTY_DESCRIPTOR_MAP_INDEX)); @@ -114,11 +118,9 @@ Node* ObjectBuiltinsAssembler::ConstructAccessorDescriptor(Node* context, return js_desc; } -Node* ObjectBuiltinsAssembler::ConstructDataDescriptor(Node* context, - Node* value, - Node* writable, - Node* enumerable, - Node* configurable) { +TNode<JSObject> ObjectBuiltinsAssembler::ConstructDataDescriptor( + TNode<Context> context, TNode<Object> value, TNode<BoolT> writable, + TNode<BoolT> enumerable, TNode<BoolT> configurable) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> map = CAST(LoadContextElement( native_context, Context::DATA_PROPERTY_DESCRIPTOR_MAP_INDEX)); @@ -260,10 +262,10 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0)); TVARIABLE(IntPtrT, var_descriptor_number, IntPtrConstant(0)); - Variable* vars[] = {&var_descriptor_number, &var_result_index}; + VariableList vars({&var_descriptor_number, &var_result_index}, zone()); // Let desc be ? O.[[GetOwnProperty]](key). TNode<DescriptorArray> descriptors = LoadMapDescriptors(map); - Label loop(this, 2, vars), after_loop(this), next_descriptor(this); + Label loop(this, vars), after_loop(this), next_descriptor(this); Branch(IntPtrEqual(var_descriptor_number.value(), object_enum_length), &after_loop, &loop); @@ -309,11 +311,10 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( if (collect_type == CollectType::kEntries) { // Let entry be CreateArrayFromList(« key, value »). - Node* array = nullptr; - Node* elements = nullptr; + TNode<JSArray> array; + TNode<FixedArrayBase> elements; std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - PACKED_ELEMENTS, array_map, SmiConstant(2), nullptr, - IntPtrConstant(2)); + PACKED_ELEMENTS, array_map, SmiConstant(2), {}, IntPtrConstant(2)); StoreFixedArrayElement(CAST(elements), 0, next_key, SKIP_WRITE_BARRIER); StoreFixedArrayElement(CAST(elements), 1, value, SKIP_WRITE_BARRIER); value = TNode<JSArray>::UncheckedCast(array); @@ -321,12 +322,12 @@ TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( StoreFixedArrayElement(values_or_entries, var_result_index.value(), value); - Increment(&var_result_index, 1); + Increment(&var_result_index); Goto(&next_descriptor); BIND(&next_descriptor); { - Increment(&var_descriptor_number, 1); + Increment(&var_descriptor_number); Branch(IntPtrEqual(var_result_index.value(), object_enum_length), &after_loop, &loop); } @@ -366,9 +367,9 @@ TF_BUILTIN(ObjectPrototypeToLocaleString, CodeStubAssembler) { } TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) { - Node* object = Parameter(Descriptor::kReceiver); - Node* key = Parameter(Descriptor::kKey); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> object = CAST(Parameter(Descriptor::kReceiver)); + TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label call_runtime(this), return_true(this), return_false(this), to_primitive(this); @@ -379,12 +380,12 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) { Branch(TaggedIsSmi(object), &to_primitive, &if_objectisnotsmi); BIND(&if_objectisnotsmi); - TNode<Map> map = LoadMap(object); + TNode<Map> map = LoadMap(CAST(object)); TNode<Uint16T> instance_type = LoadMapInstanceType(map); { - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); Label if_index(this), if_unique_name(this), if_notunique_name(this); TryToName(key, &if_index, &var_index, &if_unique_name, &var_unique, @@ -407,7 +408,7 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) { BIND(&if_notunique_name); { Label not_in_string_table(this); - TryInternalizeString(key, &if_index, &var_index, &if_unique_name, + TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name, &var_unique, ¬_in_string_table, &call_runtime); BIND(¬_in_string_table); @@ -422,7 +423,7 @@ TF_BUILTIN(ObjectPrototypeHasOwnProperty, ObjectBuiltinsAssembler) { } BIND(&to_primitive); GotoIf(IsNumber(key), &return_false); - Branch(IsName(key), &return_false, &call_runtime); + Branch(IsName(CAST(key)), &return_false, &call_runtime); BIND(&return_true); Return(TrueConstant()); @@ -454,7 +455,7 @@ TF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) { // second argument. // 4. For each element nextSource of sources, in ascending index order, args.ForEach( - [=](Node* next_source) { + [=](TNode<Object> next_source) { CallBuiltin(Builtins::kSetDataProperties, context, to, next_source); }, IntPtrConstant(1)); @@ -467,17 +468,18 @@ TF_BUILTIN(ObjectAssign, ObjectBuiltinsAssembler) { // ES #sec-object.keys TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { - Node* object = Parameter(Descriptor::kObject); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> object = CAST(Parameter(Descriptor::kObject)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - VARIABLE(var_length, MachineRepresentation::kTagged); - VARIABLE(var_elements, MachineRepresentation::kTagged); + TVARIABLE(Smi, var_length); + TVARIABLE(FixedArrayBase, var_elements); Label if_empty(this, Label::kDeferred), if_empty_elements(this), if_fast(this), if_slow(this, Label::kDeferred), if_join(this); // Check if the {object} has a usable enum cache. GotoIf(TaggedIsSmi(object), &if_slow); - TNode<Map> object_map = LoadMap(object); + + TNode<Map> object_map = LoadMap(CAST(object)); TNode<Uint32T> object_bit_field3 = LoadMapBitField3(object_map); TNode<UintPtrT> object_enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(object_bit_field3); @@ -487,7 +489,7 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { // Ensure that the {object} doesn't have any elements. CSA_ASSERT(this, IsJSObjectMap(object_map)); - TNode<FixedArrayBase> object_elements = LoadElements(object); + TNode<FixedArrayBase> object_elements = LoadElements(CAST(object)); GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements); Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements, &if_slow); @@ -500,20 +502,20 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { { // The {object} has a usable enum cache, use that. TNode<DescriptorArray> object_descriptors = LoadMapDescriptors(object_map); - TNode<EnumCache> object_enum_cache = CAST( - LoadObjectField(object_descriptors, DescriptorArray::kEnumCacheOffset)); + TNode<EnumCache> object_enum_cache = LoadObjectField<EnumCache>( + object_descriptors, DescriptorArray::kEnumCacheOffset); TNode<Object> object_enum_keys = LoadObjectField(object_enum_cache, EnumCache::kKeysOffset); // Allocate a JSArray and copy the elements from the {object_enum_keys}. - Node* array = nullptr; - Node* elements = nullptr; + TNode<JSArray> array; + TNode<FixedArrayBase> elements; TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); TNode<Smi> array_length = SmiTag(Signed(object_enum_length)); std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - PACKED_ELEMENTS, array_map, array_length, nullptr, object_enum_length, + PACKED_ELEMENTS, array_map, array_length, {}, object_enum_length, INTPTR_PARAMETERS); CopyFixedArrayElements(PACKED_ELEMENTS, object_enum_keys, elements, object_enum_length, SKIP_WRITE_BARRIER); @@ -523,8 +525,8 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { BIND(&if_empty); { // The {object} doesn't have any enumerable keys. - var_length.Bind(SmiConstant(0)); - var_elements.Bind(EmptyFixedArrayConstant()); + var_length = SmiConstant(0); + var_elements = EmptyFixedArrayConstant(); Goto(&if_join); } @@ -533,8 +535,8 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { // Let the runtime compute the elements. TNode<FixedArray> elements = CAST(CallRuntime(Runtime::kObjectKeys, context, object)); - var_length.Bind(LoadObjectField(elements, FixedArray::kLengthOffset)); - var_elements.Bind(elements); + var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset); + var_elements = elements; Goto(&if_join); } @@ -544,19 +546,19 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - TNode<JSArray> array = AllocateJSArray( - array_map, CAST(var_elements.value()), CAST(var_length.value())); + TNode<JSArray> array = + AllocateJSArray(array_map, var_elements.value(), var_length.value()); Return(array); } } // ES #sec-object.getOwnPropertyNames TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { - Node* object = Parameter(Descriptor::kObject); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> object = CAST(Parameter(Descriptor::kObject)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - VARIABLE(var_length, MachineRepresentation::kTagged); - VARIABLE(var_elements, MachineRepresentation::kTagged); + TVARIABLE(Smi, var_length); + TVARIABLE(FixedArrayBase, var_elements); Label if_empty(this, Label::kDeferred), if_empty_elements(this), if_fast(this), try_fast(this, Label::kDeferred), if_slow(this, Label::kDeferred), if_join(this); @@ -564,10 +566,11 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { // Take the slow path if the {object} IsCustomElementsReceiverInstanceType or // has any elements. GotoIf(TaggedIsSmi(object), &if_slow); - TNode<Map> object_map = LoadMap(object); + + TNode<Map> object_map = LoadMap(CAST(object)); TNode<Uint16T> instance_type = LoadMapInstanceType(object_map); GotoIf(IsCustomElementsReceiverInstanceType(instance_type), &if_slow); - TNode<FixedArrayBase> object_elements = LoadElements(object); + TNode<FixedArrayBase> object_elements = LoadElements(CAST(object)); GotoIf(IsEmptyFixedArray(object_elements), &if_empty_elements); Branch(IsEmptySlowElementDictionary(object_elements), &if_empty_elements, &if_slow); @@ -600,14 +603,14 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { LoadObjectField(object_enum_cache, EnumCache::kKeysOffset); // Allocate a JSArray and copy the elements from the {object_enum_keys}. - Node* array = nullptr; - Node* elements = nullptr; TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); TNode<Smi> array_length = SmiTag(Signed(object_enum_length)); + TNode<JSArray> array; + TNode<FixedArrayBase> elements; std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - PACKED_ELEMENTS, array_map, array_length, nullptr, object_enum_length, + PACKED_ELEMENTS, array_map, array_length, {}, object_enum_length, INTPTR_PARAMETERS); CopyFixedArrayElements(PACKED_ELEMENTS, object_enum_keys, elements, object_enum_length, SKIP_WRITE_BARRIER); @@ -619,16 +622,16 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { // Let the runtime compute the elements and try initializing enum cache. TNode<FixedArray> elements = CAST(CallRuntime( Runtime::kObjectGetOwnPropertyNamesTryFast, context, object)); - var_length.Bind(LoadObjectField(elements, FixedArray::kLengthOffset)); - var_elements.Bind(elements); + var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset); + var_elements = elements; Goto(&if_join); } BIND(&if_empty); { // The {object} doesn't have any enumerable keys. - var_length.Bind(SmiConstant(0)); - var_elements.Bind(EmptyFixedArrayConstant()); + var_length = SmiConstant(0); + var_elements = EmptyFixedArrayConstant(); Goto(&if_join); } @@ -637,8 +640,8 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { // Let the runtime compute the elements. TNode<FixedArray> elements = CAST(CallRuntime(Runtime::kObjectGetOwnPropertyNames, context, object)); - var_length.Bind(LoadObjectField(elements, FixedArray::kLengthOffset)); - var_elements.Bind(elements); + var_length = LoadObjectField<Smi>(elements, FixedArray::kLengthOffset); + var_elements = elements; Goto(&if_join); } @@ -648,8 +651,8 @@ TF_BUILTIN(ObjectGetOwnPropertyNames, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Map> array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - TNode<JSArray> array = AllocateJSArray( - array_map, CAST(var_elements.value()), CAST(var_length.value())); + TNode<JSArray> array = + AllocateJSArray(array_map, var_elements.value(), var_length.value()); Return(array); } } @@ -672,9 +675,9 @@ TF_BUILTIN(ObjectEntries, ObjectEntriesValuesBuiltinsAssembler) { // ES #sec-object.prototype.isprototypeof TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); - Node* value = Parameter(Descriptor::kValue); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label if_receiverisnullorundefined(this, Label::kDeferred), if_valueisnotreceiver(this, Label::kDeferred); @@ -685,31 +688,35 @@ TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { // immediately aborts and returns false anyways. GotoIf(TaggedIsSmi(value), &if_valueisnotreceiver); - // Check if {receiver} is either null or undefined and in that case, - // invoke the ToObject builtin, which raises the appropriate error. - // Otherwise we don't need to invoke ToObject, since {receiver} is - // either already a JSReceiver, in which case ToObject is a no-op, - // or it's a Primitive and ToObject would allocate a fresh JSPrimitiveWrapper - // wrapper, which wouldn't be identical to any existing JSReceiver - // found in the prototype chain of {value}, hence it will return - // false no matter if we search for the Primitive {receiver} or - // a newly allocated JSPrimitiveWrapper wrapper for {receiver}. - GotoIf(IsNull(receiver), &if_receiverisnullorundefined); - GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined); - - // Loop through the prototype chain looking for the {receiver}. - Return(HasInPrototypeChain(context, value, receiver)); - - BIND(&if_receiverisnullorundefined); { - // If {value} is a primitive HeapObject, we need to return - // false instead of throwing an exception per order of the - // steps in the specification, so check that first here. - GotoIfNot(IsJSReceiver(value), &if_valueisnotreceiver); - - // Simulate the ToObject invocation on {receiver}. - ToObject(context, receiver); - Unreachable(); + TNode<HeapObject> value_heap_object = CAST(value); + + // Check if {receiver} is either null or undefined and in that case, + // invoke the ToObject builtin, which raises the appropriate error. + // Otherwise we don't need to invoke ToObject, since {receiver} is + // either already a JSReceiver, in which case ToObject is a no-op, + // or it's a Primitive and ToObject would allocate a fresh + // JSPrimitiveWrapper wrapper, which wouldn't be identical to any existing + // JSReceiver found in the prototype chain of {value}, hence it will return + // false no matter if we search for the Primitive {receiver} or + // a newly allocated JSPrimitiveWrapper wrapper for {receiver}. + GotoIf(IsNull(receiver), &if_receiverisnullorundefined); + GotoIf(IsUndefined(receiver), &if_receiverisnullorundefined); + + // Loop through the prototype chain looking for the {receiver}. + Return(HasInPrototypeChain(context, value_heap_object, receiver)); + + BIND(&if_receiverisnullorundefined); + { + // If {value} is a primitive HeapObject, we need to return + // false instead of throwing an exception per order of the + // steps in the specification, so check that first here. + GotoIfNot(IsJSReceiver(value_heap_object), &if_valueisnotreceiver); + + // Simulate the ToObject invocation on {receiver}. + ToObject(context, receiver); + Unreachable(); + } } BIND(&if_valueisnotreceiver); @@ -731,14 +738,18 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { if_regexp(this), if_string(this), if_symbol(this, Label::kDeferred), if_value(this), if_bigint(this, Label::kDeferred); - Node* receiver = Parameter(Descriptor::kReceiver); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + + TVARIABLE(String, var_default); + TVARIABLE(HeapObject, var_holder); // This is arranged to check the likely cases first. - VARIABLE(var_default, MachineRepresentation::kTagged); - VARIABLE(var_holder, MachineRepresentation::kTagged, receiver); GotoIf(TaggedIsSmi(receiver), &if_number); - TNode<Map> receiver_map = LoadMap(receiver); + + TNode<HeapObject> reciever_heap_object = CAST(receiver); + TNode<Map> receiver_map = LoadMap(reciever_heap_object); + var_holder = reciever_heap_object; TNode<Uint16T> receiver_instance_type = LoadMapInstanceType(receiver_map); GotoIf(IsPrimitiveInstanceType(receiver_instance_type), &if_primitive); const struct { @@ -747,8 +758,8 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { } kJumpTable[] = {{JS_OBJECT_TYPE, &if_object}, {JS_ARRAY_TYPE, &if_array}, {JS_FUNCTION_TYPE, &if_function}, - {JS_REGEXP_TYPE, &if_regexp}, - {JS_ARGUMENTS_TYPE, &if_arguments}, + {JS_REG_EXP_TYPE, &if_regexp}, + {JS_ARGUMENTS_OBJECT_TYPE, &if_arguments}, {JS_DATE_TYPE, &if_date}, {JS_BOUND_FUNCTION_TYPE, &if_function}, {JS_API_OBJECT_TYPE, &if_apiobject}, @@ -769,30 +780,31 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { BIND(&if_apiobject); { // Lookup the @@toStringTag property on the {receiver}. - VARIABLE(var_tag, MachineRepresentation::kTagged, - GetProperty(context, receiver, - isolate()->factory()->to_string_tag_symbol())); + TVARIABLE(Object, var_tag, + GetProperty(context, receiver, + isolate()->factory()->to_string_tag_symbol())); Label if_tagisnotstring(this), if_tagisstring(this); GotoIf(TaggedIsSmi(var_tag.value()), &if_tagisnotstring); - Branch(IsString(var_tag.value()), &if_tagisstring, &if_tagisnotstring); + Branch(IsString(CAST(var_tag.value())), &if_tagisstring, + &if_tagisnotstring); BIND(&if_tagisnotstring); { - var_tag.Bind(CallRuntime(Runtime::kClassOf, context, receiver)); + var_tag = CallRuntime(Runtime::kClassOf, context, receiver); Goto(&if_tagisstring); } BIND(&if_tagisstring); - ReturnToStringFormat(context, var_tag.value()); + ReturnToStringFormat(context, CAST(var_tag.value())); } BIND(&if_arguments); { - var_default.Bind(ArgumentsToStringConstant()); + var_default = ArgumentsToStringConstant(); Goto(&checkstringtag); } BIND(&if_array); { - var_default.Bind(ArrayToStringConstant()); + var_default = ArrayToStringConstant(); Goto(&checkstringtag); } @@ -801,30 +813,30 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> boolean_constructor = CAST( LoadContextElement(native_context, Context::BOOLEAN_FUNCTION_INDEX)); - TNode<Map> boolean_initial_map = CAST(LoadObjectField( - boolean_constructor, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<Object> boolean_prototype = - LoadObjectField(boolean_initial_map, Map::kPrototypeOffset); - var_default.Bind(BooleanToStringConstant()); - var_holder.Bind(boolean_prototype); + TNode<Map> boolean_initial_map = LoadObjectField<Map>( + boolean_constructor, JSFunction::kPrototypeOrInitialMapOffset); + TNode<HeapObject> boolean_prototype = + LoadObjectField<HeapObject>(boolean_initial_map, Map::kPrototypeOffset); + var_default = BooleanToStringConstant(); + var_holder = boolean_prototype; Goto(&checkstringtag); } BIND(&if_date); { - var_default.Bind(DateToStringConstant()); + var_default = DateToStringConstant(); Goto(&checkstringtag); } BIND(&if_error); { - var_default.Bind(ErrorToStringConstant()); + var_default = ErrorToStringConstant(); Goto(&checkstringtag); } BIND(&if_function); { - var_default.Bind(FunctionToStringConstant()); + var_default = FunctionToStringConstant(); Goto(&checkstringtag); } @@ -833,19 +845,19 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> number_constructor = CAST( LoadContextElement(native_context, Context::NUMBER_FUNCTION_INDEX)); - TNode<Map> number_initial_map = CAST(LoadObjectField( - number_constructor, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<Object> number_prototype = - LoadObjectField(number_initial_map, Map::kPrototypeOffset); - var_default.Bind(NumberToStringConstant()); - var_holder.Bind(number_prototype); + TNode<Map> number_initial_map = LoadObjectField<Map>( + number_constructor, JSFunction::kPrototypeOrInitialMapOffset); + TNode<HeapObject> number_prototype = + LoadObjectField<HeapObject>(number_initial_map, Map::kPrototypeOffset); + var_default = NumberToStringConstant(); + var_holder = number_prototype; Goto(&checkstringtag); } BIND(&if_object); { - CSA_ASSERT(this, IsJSReceiver(receiver)); - var_default.Bind(ObjectToStringConstant()); + CSA_ASSERT(this, IsJSReceiver(CAST(receiver))); + var_default = ObjectToStringConstant(); Goto(&checkstringtag); } @@ -885,24 +897,25 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { }); // Lookup the @@toStringTag property on the {receiver}. - VARIABLE(var_tag, MachineRepresentation::kTagged, - GetProperty(context, receiver, - isolate()->factory()->to_string_tag_symbol())); + TVARIABLE(Object, var_tag, + GetProperty(context, receiver, + isolate()->factory()->to_string_tag_symbol())); Label if_tagisnotstring(this), if_tagisstring(this); GotoIf(TaggedIsSmi(var_tag.value()), &if_tagisnotstring); - Branch(IsString(var_tag.value()), &if_tagisstring, &if_tagisnotstring); + Branch(IsString(CAST(var_tag.value())), &if_tagisstring, + &if_tagisnotstring); BIND(&if_tagisnotstring); { - var_tag.Bind(builtin_tag); + var_tag = builtin_tag; Goto(&if_tagisstring); } BIND(&if_tagisstring); - ReturnToStringFormat(context, var_tag.value()); + ReturnToStringFormat(context, CAST(var_tag.value())); } BIND(&if_regexp); { - var_default.Bind(RegexpToStringConstant()); + var_default = RegexpToStringConstant(); Goto(&checkstringtag); } @@ -911,12 +924,12 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> string_constructor = CAST( LoadContextElement(native_context, Context::STRING_FUNCTION_INDEX)); - TNode<Map> string_initial_map = CAST(LoadObjectField( - string_constructor, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<Object> string_prototype = - LoadObjectField(string_initial_map, Map::kPrototypeOffset); - var_default.Bind(StringToStringConstant()); - var_holder.Bind(string_prototype); + TNode<Map> string_initial_map = LoadObjectField<Map>( + string_constructor, JSFunction::kPrototypeOrInitialMapOffset); + TNode<HeapObject> string_prototype = + LoadObjectField<HeapObject>(string_initial_map, Map::kPrototypeOffset); + var_default = StringToStringConstant(); + var_holder = string_prototype; Goto(&checkstringtag); } @@ -925,12 +938,12 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> symbol_constructor = CAST( LoadContextElement(native_context, Context::SYMBOL_FUNCTION_INDEX)); - TNode<Map> symbol_initial_map = CAST(LoadObjectField( - symbol_constructor, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<Object> symbol_prototype = - LoadObjectField(symbol_initial_map, Map::kPrototypeOffset); - var_default.Bind(ObjectToStringConstant()); - var_holder.Bind(symbol_prototype); + TNode<Map> symbol_initial_map = LoadObjectField<Map>( + symbol_constructor, JSFunction::kPrototypeOrInitialMapOffset); + TNode<HeapObject> symbol_prototype = + LoadObjectField<HeapObject>(symbol_initial_map, Map::kPrototypeOffset); + var_default = ObjectToStringConstant(); + var_holder = symbol_prototype; Goto(&checkstringtag); } @@ -939,12 +952,12 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> bigint_constructor = CAST( LoadContextElement(native_context, Context::BIGINT_FUNCTION_INDEX)); - TNode<Map> bigint_initial_map = CAST(LoadObjectField( - bigint_constructor, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<Object> bigint_prototype = - LoadObjectField(bigint_initial_map, Map::kPrototypeOffset); - var_default.Bind(ObjectToStringConstant()); - var_holder.Bind(bigint_prototype); + TNode<Map> bigint_initial_map = LoadObjectField<Map>( + bigint_constructor, JSFunction::kPrototypeOrInitialMapOffset); + TNode<HeapObject> bigint_prototype = + LoadObjectField<HeapObject>(bigint_initial_map, Map::kPrototypeOffset); + var_default = ObjectToStringConstant(); + var_holder = bigint_prototype; Goto(&checkstringtag); } @@ -956,12 +969,13 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { if_value_is_bigint(this, Label::kDeferred), if_value_is_string(this, Label::kDeferred); - Node* receiver_value = LoadJSPrimitiveWrapperValue(receiver); + TNode<Object> receiver_value = + LoadJSPrimitiveWrapperValue(CAST(reciever_heap_object)); // We need to start with the object to see if the value was a subclass // which might have interesting properties. - var_holder.Bind(receiver); + var_holder = reciever_heap_object; GotoIf(TaggedIsSmi(receiver_value), &if_value_is_number); - TNode<Map> receiver_value_map = LoadMap(receiver_value); + TNode<Map> receiver_value_map = LoadMap(CAST(receiver_value)); GotoIf(IsHeapNumberMap(receiver_value_map), &if_value_is_number); GotoIf(IsBooleanMap(receiver_value_map), &if_value_is_boolean); GotoIf(IsSymbolMap(receiver_value_map), &if_value_is_symbol); @@ -974,31 +988,31 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { BIND(&if_value_is_number); { - var_default.Bind(NumberToStringConstant()); + var_default = NumberToStringConstant(); Goto(&checkstringtag); } BIND(&if_value_is_boolean); { - var_default.Bind(BooleanToStringConstant()); + var_default = BooleanToStringConstant(); Goto(&checkstringtag); } BIND(&if_value_is_string); { - var_default.Bind(StringToStringConstant()); + var_default = StringToStringConstant(); Goto(&checkstringtag); } BIND(&if_value_is_bigint); { - var_default.Bind(ObjectToStringConstant()); + var_default = ObjectToStringConstant(); Goto(&checkstringtag); } BIND(&if_value_is_symbol); { - var_default.Bind(ObjectToStringConstant()); + var_default = ObjectToStringConstant(); Goto(&checkstringtag); } } @@ -1013,13 +1027,13 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { Goto(&loop); BIND(&loop); { - Node* holder = var_holder.value(); + TNode<HeapObject> holder = var_holder.value(); GotoIf(IsNull(holder), &return_default); TNode<Map> holder_map = LoadMap(holder); TNode<Uint32T> holder_bit_field3 = LoadMapBitField3(holder_map); GotoIf(IsSetWord32<Map::MayHaveInterestingSymbolsBit>(holder_bit_field3), &return_generic); - var_holder.Bind(LoadMapPrototype(holder_map)); + var_holder = LoadMapPrototype(holder_map); Goto(&loop); } @@ -1029,7 +1043,7 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) { ToStringTagSymbolConstant()); GotoIf(TaggedIsSmi(tag), &return_default); GotoIfNot(IsString(CAST(tag)), &return_default); - ReturnToStringFormat(context, tag); + ReturnToStringFormat(context, CAST(tag)); } BIND(&return_default); @@ -1058,28 +1072,28 @@ TF_BUILTIN(CreateObjectWithoutProperties, ObjectBuiltinsAssembler) { BranchIfJSReceiver(prototype, &prototype_jsreceiver, &call_runtime); } - VARIABLE(map, MachineRepresentation::kTagged); - VARIABLE(properties, MachineRepresentation::kTagged); + TVARIABLE(Map, map); + TVARIABLE(HeapObject, properties); Label instantiate_map(this); BIND(&prototype_null); { Comment("Prototype is null"); - map.Bind(LoadContextElement(native_context, - Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); - properties.Bind(AllocateNameDictionary(NameDictionary::kInitialCapacity)); + map = CAST(LoadContextElement( + native_context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); + properties = AllocateNameDictionary(NameDictionary::kInitialCapacity); Goto(&instantiate_map); } BIND(&prototype_jsreceiver); { Comment("Prototype is JSReceiver"); - properties.Bind(EmptyFixedArrayConstant()); + properties = EmptyFixedArrayConstant(); TNode<HeapObject> object_function = CAST( LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX)); - TNode<Object> object_function_map = LoadObjectField( + TNode<Map> object_function_map = LoadObjectField<Map>( object_function, JSFunction::kPrototypeOrInitialMapOffset); - map.Bind(object_function_map); + map = object_function_map; GotoIf(TaggedEqual(prototype, LoadMapPrototype(map.value())), &instantiate_map); Comment("Try loading the prototype info"); @@ -1087,8 +1101,8 @@ TF_BUILTIN(CreateObjectWithoutProperties, ObjectBuiltinsAssembler) { LoadMapPrototypeInfo(LoadMap(CAST(prototype)), &call_runtime); TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField( prototype_info, PrototypeInfo::kObjectCreateMapOffset); - GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), &call_runtime); - map.Bind(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); + GotoIf(TaggedEqual(maybe_map, UndefinedConstant()), &call_runtime); + map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); Goto(&instantiate_map); } @@ -1153,28 +1167,28 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { // Create a new object with the given prototype. BIND(&no_properties); { - VARIABLE(map, MachineRepresentation::kTagged); - VARIABLE(properties, MachineRepresentation::kTagged); + TVARIABLE(Map, map); + TVARIABLE(HeapObject, properties); Label non_null_proto(this), instantiate_map(this), good(this); Branch(IsNull(prototype), &good, &non_null_proto); BIND(&good); { - map.Bind(LoadContextElement( + map = CAST(LoadContextElement( context, Context::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP)); - properties.Bind(AllocateNameDictionary(NameDictionary::kInitialCapacity)); + properties = AllocateNameDictionary(NameDictionary::kInitialCapacity); Goto(&instantiate_map); } BIND(&non_null_proto); { - properties.Bind(EmptyFixedArrayConstant()); + properties = EmptyFixedArrayConstant(); TNode<HeapObject> object_function = CAST(LoadContextElement(context, Context::OBJECT_FUNCTION_INDEX)); - TNode<Object> object_function_map = LoadObjectField( + TNode<Map> object_function_map = LoadObjectField<Map>( object_function, JSFunction::kPrototypeOrInitialMapOffset); - map.Bind(object_function_map); + map = object_function_map; GotoIf(TaggedEqual(prototype, LoadMapPrototype(map.value())), &instantiate_map); // Try loading the prototype info. @@ -1183,9 +1197,8 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { Comment("Load ObjectCreateMap from PrototypeInfo"); TNode<MaybeObject> maybe_map = LoadMaybeWeakObjectField( prototype_info, PrototypeInfo::kObjectCreateMapOffset); - GotoIf(IsStrongReferenceTo(maybe_map, UndefinedConstant()), - &call_runtime); - map.Bind(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); + GotoIf(TaggedEqual(maybe_map, UndefinedConstant()), &call_runtime); + map = CAST(GetHeapObjectAssumeWeak(maybe_map, &call_runtime)); Goto(&instantiate_map); } @@ -1207,8 +1220,8 @@ TF_BUILTIN(ObjectCreate, ObjectBuiltinsAssembler) { // ES #sec-object.is TF_BUILTIN(ObjectIs, ObjectBuiltinsAssembler) { - Node* const left = Parameter(Descriptor::kLeft); - Node* const right = Parameter(Descriptor::kRight); + TNode<Object> const left = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> const right = CAST(Parameter(Descriptor::kRight)); Label return_true(this), return_false(this); BranchIfSameValue(left, right, &return_true, &return_false); @@ -1221,9 +1234,9 @@ TF_BUILTIN(ObjectIs, ObjectBuiltinsAssembler) { } TF_BUILTIN(CreateIterResultObject, ObjectBuiltinsAssembler) { - Node* const value = Parameter(Descriptor::kValue); - Node* const done = Parameter(Descriptor::kDone); - Node* const context = Parameter(Descriptor::kContext); + TNode<Object> const value = CAST(Parameter(Descriptor::kValue)); + TNode<Oddball> const done = CAST(Parameter(Descriptor::kDone)); + TNode<Context> const context = CAST(Parameter(Descriptor::kContext)); TNode<NativeContext> const native_context = LoadNativeContext(context); TNode<Map> const map = CAST( @@ -1238,53 +1251,53 @@ TF_BUILTIN(CreateIterResultObject, ObjectBuiltinsAssembler) { } TF_BUILTIN(HasProperty, ObjectBuiltinsAssembler) { - Node* key = Parameter(Descriptor::kKey); - Node* object = Parameter(Descriptor::kObject); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> key = CAST(Parameter(Descriptor::kKey)); + TNode<Object> object = CAST(Parameter(Descriptor::kObject)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(HasProperty(context, object, key, kHasProperty)); } TF_BUILTIN(InstanceOf, ObjectBuiltinsAssembler) { - Node* object = Parameter(Descriptor::kLeft); - Node* callable = Parameter(Descriptor::kRight); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> object = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> callable = CAST(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(InstanceOf(object, callable, context)); } // ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) TF_BUILTIN(OrdinaryHasInstance, ObjectBuiltinsAssembler) { - Node* constructor = Parameter(Descriptor::kLeft); - Node* object = Parameter(Descriptor::kRight); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> constructor = CAST(Parameter(Descriptor::kLeft)); + TNode<Object> object = CAST(Parameter(Descriptor::kRight)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(OrdinaryHasInstance(context, constructor, object)); } TF_BUILTIN(GetSuperConstructor, ObjectBuiltinsAssembler) { - Node* object = Parameter(Descriptor::kObject); - Node* context = Parameter(Descriptor::kContext); + TNode<JSFunction> object = CAST(Parameter(Descriptor::kObject)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(GetSuperConstructor(context, object)); } TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { - Node* closure = Parameter(Descriptor::kClosure); - Node* receiver = Parameter(Descriptor::kReceiver); - Node* context = Parameter(Descriptor::kContext); + TNode<JSFunction> closure = CAST(Parameter(Descriptor::kClosure)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // Get the initial map from the function, jumping to the runtime if we don't // have one. Label done(this), runtime(this); GotoIfNot(IsFunctionWithPrototypeSlotMap(LoadMap(closure)), &runtime); - TNode<HeapObject> maybe_map = - CAST(LoadObjectField(closure, JSFunction::kPrototypeOrInitialMapOffset)); + TNode<HeapObject> maybe_map = LoadObjectField<HeapObject>( + closure, JSFunction::kPrototypeOrInitialMapOffset); GotoIf(DoesntHaveInstanceType(maybe_map, MAP_TYPE), &runtime); TNode<Map> map = CAST(maybe_map); - TNode<SharedFunctionInfo> shared = - CAST(LoadObjectField(closure, JSFunction::kSharedFunctionInfoOffset)); + TNode<SharedFunctionInfo> shared = LoadObjectField<SharedFunctionInfo>( + closure, JSFunction::kSharedFunctionInfoOffset); TNode<BytecodeArray> bytecode_array = LoadSharedFunctionInfoBytecodeArray(shared); @@ -1293,7 +1306,7 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { MachineType::Uint16())); TNode<IntPtrT> frame_size = ChangeInt32ToIntPtr(LoadObjectField( bytecode_array, BytecodeArray::kFrameSizeOffset, MachineType::Int32())); - TNode<WordT> size = + TNode<IntPtrT> size = IntPtrAdd(WordSar(frame_size, IntPtrConstant(kTaggedSizeLog2)), formal_parameter_count); TNode<FixedArrayBase> parameters_and_registers = @@ -1337,16 +1350,17 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) { // ES6 section 19.1.2.7 Object.getOwnPropertyDescriptor ( O, P ) TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { - Node* argc = Parameter(Descriptor::kJSActualArgumentsCount); - Node* context = Parameter(Descriptor::kContext); + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); CSA_ASSERT(this, IsUndefined(Parameter(Descriptor::kJSNewTarget))); - CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, argc); TNode<Object> object_input = args.GetOptionalArgumentValue(0); TNode<Object> key = args.GetOptionalArgumentValue(1); // 1. Let obj be ? ToObject(O). - TNode<JSReceiver> object = ToObject_Inline(CAST(context), object_input); + TNode<JSReceiver> object = ToObject_Inline(context, object_input); // 2. Let key be ? ToPropertyKey(P). key = CallBuiltin(Builtins::kToName, context, key); @@ -1359,9 +1373,8 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { TNode<Uint16T> instance_type = LoadMapInstanceType(map); GotoIf(IsSpecialReceiverInstanceType(instance_type), &call_runtime); { - VARIABLE(var_index, MachineType::PointerRepresentation(), - IntPtrConstant(0)); - VARIABLE(var_name, MachineRepresentation::kTagged); + TVARIABLE(IntPtrT, var_index, IntPtrConstant(0)); + TVARIABLE(Name, var_name); TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_name, &call_runtime, &if_notunique_name); @@ -1369,8 +1382,9 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { BIND(&if_notunique_name); { Label not_in_string_table(this); - TryInternalizeString(key, &if_keyisindex, &var_index, &if_iskeyunique, - &var_name, ¬_in_string_table, &call_runtime); + TryInternalizeString(CAST(key), &if_keyisindex, &var_index, + &if_iskeyunique, &var_name, ¬_in_string_table, + &call_runtime); BIND(¬_in_string_table); { @@ -1384,9 +1398,9 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { { Label if_found_value(this), return_empty(this), if_not_found(this); - VARIABLE(var_value, MachineRepresentation::kTagged); - VARIABLE(var_details, MachineRepresentation::kWord32); - VARIABLE(var_raw_value, MachineRepresentation::kTagged); + TVARIABLE(Object, var_value); + TVARIABLE(Word32T, var_details); + TVARIABLE(Object, var_raw_value); TryGetOwnProperty(context, object, object, map, instance_type, var_name.value(), &if_found_value, &var_value, @@ -1394,13 +1408,13 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { &if_not_found, kReturnAccessorPair); BIND(&if_found_value); - // 4. Return FromPropertyDescriptor(desc). - Node* js_desc = FromPropertyDetails(context, var_value.value(), - var_details.value(), &call_runtime); + // 4. Return FromPropertyDetails(desc). + TNode<JSObject> js_desc = FromPropertyDetails( + context, var_value.value(), var_details.value(), &call_runtime); args.PopAndReturn(js_desc); BIND(&return_empty); - var_value.Bind(UndefinedConstant()); + var_value = UndefinedConstant(); args.PopAndReturn(UndefinedConstant()); BIND(&if_not_found); @@ -1421,7 +1435,7 @@ TF_BUILTIN(ObjectGetOwnPropertyDescriptor, ObjectBuiltinsAssembler) { TNode<FixedArray> desc_array = CAST(desc); // 4. Return FromPropertyDescriptor(desc). - Node* js_desc = FromPropertyDescriptor(context, desc_array); + TNode<JSObject> js_desc = FromPropertyDescriptor(context, desc_array); args.PopAndReturn(js_desc); } BIND(&return_undefined); @@ -1440,14 +1454,14 @@ void ObjectBuiltinsAssembler::AddToDictionaryIf( BIND(&done); } -Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context, - Node* desc) { - VARIABLE(js_descriptor, MachineRepresentation::kTagged); +TNode<JSObject> ObjectBuiltinsAssembler::FromPropertyDescriptor( + TNode<Context> context, TNode<FixedArray> desc) { + TVARIABLE(JSObject, js_descriptor); TNode<Int32T> flags = LoadAndUntagToWord32ObjectField( desc, PropertyDescriptorObject::kFlagsOffset); - TNode<Word32T> has_flags = + TNode<Int32T> has_flags = Word32And(flags, Int32Constant(PropertyDescriptorObject::kHasMask)); Label if_accessor_desc(this), if_data_desc(this), if_generic_desc(this), @@ -1465,21 +1479,21 @@ Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context, BIND(&if_accessor_desc); { - js_descriptor.Bind(ConstructAccessorDescriptor( + js_descriptor = ConstructAccessorDescriptor( context, LoadObjectField(desc, PropertyDescriptorObject::kGetOffset), LoadObjectField(desc, PropertyDescriptorObject::kSetOffset), IsSetWord32<PropertyDescriptorObject::IsEnumerableBit>(flags), - IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags))); + IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags)); Goto(&return_desc); } BIND(&if_data_desc); { - js_descriptor.Bind(ConstructDataDescriptor( + js_descriptor = ConstructDataDescriptor( context, LoadObjectField(desc, PropertyDescriptorObject::kValueOffset), IsSetWord32<PropertyDescriptorObject::IsWritableBit>(flags), IsSetWord32<PropertyDescriptorObject::IsEnumerableBit>(flags), - IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags))); + IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags)); Goto(&return_desc); } @@ -1529,7 +1543,7 @@ Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context, IsSetWord32<PropertyDescriptorObject::IsConfigurableBit>(flags)), &bailout); - js_descriptor.Bind(js_desc); + js_descriptor = js_desc; Goto(&return_desc); BIND(&bailout); @@ -1541,36 +1555,36 @@ Node* ObjectBuiltinsAssembler::FromPropertyDescriptor(Node* context, return js_descriptor.value(); } -Node* ObjectBuiltinsAssembler::FromPropertyDetails(Node* context, - Node* raw_value, - Node* details, - Label* if_bailout) { - VARIABLE(js_descriptor, MachineRepresentation::kTagged); +TNode<JSObject> ObjectBuiltinsAssembler::FromPropertyDetails( + TNode<Context> context, TNode<Object> raw_value, TNode<Word32T> details, + Label* if_bailout) { + TVARIABLE(JSObject, js_descriptor); Label if_accessor_desc(this), if_data_desc(this), return_desc(this); BranchIfAccessorPair(raw_value, &if_accessor_desc, &if_data_desc); BIND(&if_accessor_desc); { - TNode<Object> getter = - LoadObjectField(raw_value, AccessorPair::kGetterOffset); - TNode<Object> setter = - LoadObjectField(raw_value, AccessorPair::kSetterOffset); - js_descriptor.Bind(ConstructAccessorDescriptor( + TNode<AccessorPair> accessor_pair_value = CAST(raw_value); + TNode<HeapObject> getter = LoadObjectField<HeapObject>( + accessor_pair_value, AccessorPair::kGetterOffset); + TNode<HeapObject> setter = LoadObjectField<HeapObject>( + accessor_pair_value, AccessorPair::kSetterOffset); + js_descriptor = ConstructAccessorDescriptor( context, GetAccessorOrUndefined(getter, if_bailout), GetAccessorOrUndefined(setter, if_bailout), IsNotSetWord32(details, PropertyDetails::kAttributesDontEnumMask), - IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask))); + IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask)); Goto(&return_desc); } BIND(&if_data_desc); { - js_descriptor.Bind(ConstructDataDescriptor( + js_descriptor = ConstructDataDescriptor( context, raw_value, IsNotSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), IsNotSetWord32(details, PropertyDetails::kAttributesDontEnumMask), - IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask))); + IsNotSetWord32(details, PropertyDetails::kAttributesDontDeleteMask)); Goto(&return_desc); } @@ -1578,20 +1592,20 @@ Node* ObjectBuiltinsAssembler::FromPropertyDetails(Node* context, return js_descriptor.value(); } -Node* ObjectBuiltinsAssembler::GetAccessorOrUndefined(Node* accessor, - Label* if_bailout) { +TNode<HeapObject> ObjectBuiltinsAssembler::GetAccessorOrUndefined( + TNode<HeapObject> accessor, Label* if_bailout) { Label bind_undefined(this, Label::kDeferred), return_result(this); - VARIABLE(result, MachineRepresentation::kTagged); + TVARIABLE(HeapObject, result); GotoIf(IsNull(accessor), &bind_undefined); - result.Bind(accessor); + result = accessor; TNode<Map> map = LoadMap(accessor); // TODO(ishell): probe template instantiations cache. GotoIf(IsFunctionTemplateInfoMap(map), if_bailout); Goto(&return_result); BIND(&bind_undefined); - result.Bind(UndefinedConstant()); + result = UndefinedConstant(); Goto(&return_result); BIND(&return_result); diff --git a/deps/v8/src/builtins/builtins-promise-gen.cc b/deps/v8/src/builtins/builtins-promise-gen.cc index a1da55e0d931e3..b20b288c3d63a3 100644 --- a/deps/v8/src/builtins/builtins-promise-gen.cc +++ b/deps/v8/src/builtins/builtins-promise-gen.cc @@ -21,11 +21,10 @@ namespace v8 { namespace internal { using Node = compiler::Node; -template <class T> -using TNode = CodeStubAssembler::TNode<T>; using IteratorRecord = TorqueStructIteratorRecord; -Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { +TNode<JSPromise> PromiseBuiltinsAssembler::AllocateJSPromise( + TNode<Context> context) { TNode<NativeContext> const native_context = LoadNativeContext(context); TNode<JSFunction> const promise_fun = CAST(LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX)); @@ -39,7 +38,7 @@ Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { RootIndex::kEmptyFixedArray); StoreObjectFieldRoot(promise, JSPromise::kElementsOffset, RootIndex::kEmptyFixedArray); - return promise; + return CAST(promise); } void PromiseBuiltinsAssembler::PromiseInit(Node* promise) { @@ -54,13 +53,14 @@ void PromiseBuiltinsAssembler::PromiseInit(Node* promise) { } } -Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context) { +TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndInitJSPromise( + TNode<Context> context) { return AllocateAndInitJSPromise(context, UndefinedConstant()); } -Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context, - Node* parent) { - Node* const instance = AllocateJSPromise(context); +TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndInitJSPromise( + TNode<Context> context, TNode<Object> parent) { + const TNode<JSPromise> instance = AllocateJSPromise(context); PromiseInit(instance); Label out(this); @@ -72,11 +72,12 @@ Node* PromiseBuiltinsAssembler::AllocateAndInitJSPromise(Node* context, return instance; } -Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise( - Node* context, v8::Promise::PromiseState status, Node* result) { +TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndSetJSPromise( + TNode<Context> context, v8::Promise::PromiseState status, + TNode<Object> result) { DCHECK_NE(Promise::kPending, status); - Node* const instance = AllocateJSPromise(context); + const TNode<JSPromise> instance = AllocateJSPromise(context); StoreObjectFieldNoWriteBarrier(instance, JSPromise::kReactionsOrResultOffset, result); STATIC_ASSERT(JSPromise::kStatusShift == 0); @@ -97,22 +98,23 @@ Node* PromiseBuiltinsAssembler::AllocateAndSetJSPromise( return instance; } -std::pair<Node*, Node*> +std::pair<TNode<JSFunction>, TNode<JSFunction>> PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions( - Node* promise, Node* debug_event, Node* native_context) { - Node* const promise_context = CreatePromiseResolvingFunctionsContext( + TNode<JSPromise> promise, TNode<Object> debug_event, + TNode<NativeContext> native_context) { + const TNode<Context> promise_context = CreatePromiseResolvingFunctionsContext( promise, debug_event, native_context); - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const resolve_info = LoadContextElement( + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> resolve_info = CAST(LoadContextElement( native_context, - Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX); - Node* const resolve = + Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX)); + const TNode<JSFunction> resolve = AllocateFunctionWithMapAndContext(map, resolve_info, promise_context); - TNode<Object> const reject_info = LoadContextElement( + const TNode<SharedFunctionInfo> reject_info = CAST(LoadContextElement( native_context, - Context::PROMISE_CAPABILITY_DEFAULT_REJECT_SHARED_FUN_INDEX); - Node* const reject = + Context::PROMISE_CAPABILITY_DEFAULT_REJECT_SHARED_FUN_INDEX)); + const TNode<JSFunction> reject = AllocateFunctionWithMapAndContext(map, reject_info, promise_context); return std::make_pair(resolve, reject); } @@ -196,7 +198,7 @@ TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { BIND(&if_fast_promise_capability); { - Node* promise = + TNode<JSPromise> promise = AllocateAndInitJSPromise(native_context, UndefinedConstant()); Node* resolve = nullptr; @@ -226,14 +228,15 @@ TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { StoreObjectFieldRoot(capability, PromiseCapability::kRejectOffset, RootIndex::kUndefinedValue); - Node* executor_context = - CreatePromiseGetCapabilitiesExecutorContext(capability, native_context); - TNode<Object> executor_info = LoadContextElement( - native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN); - TNode<Object> function_map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<JSFunction> executor = CAST(AllocateFunctionWithMapAndContext( - function_map, executor_info, executor_context)); + TNode<Context> executor_context = + CAST(CreatePromiseGetCapabilitiesExecutorContext(capability, + native_context)); + TNode<SharedFunctionInfo> executor_info = CAST(LoadContextElement( + native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN)); + TNode<Map> function_map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + TNode<JSFunction> executor = AllocateFunctionWithMapAndContext( + function_map, executor_info, executor_context); TNode<JSReceiver> promise = Construct(native_context, CAST(constructor), executor); @@ -258,14 +261,14 @@ TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { ThrowTypeError(context, MessageTemplate::kPromiseNonCallable); } -Node* PromiseBuiltinsAssembler::CreatePromiseContext(Node* native_context, - int slots) { +TNode<Context> PromiseBuiltinsAssembler::CreatePromiseContext( + TNode<NativeContext> native_context, int slots) { DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS); TNode<HeapObject> const context = AllocateInNewSpace(FixedArray::SizeFor(slots)); InitializeFunctionContext(native_context, context, slots); - return context; + return CAST(context); } Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementContext( @@ -278,8 +281,8 @@ Node* PromiseBuiltinsAssembler::CreatePromiseAllResolveElementContext( TNode<JSArray> values_array = AllocateJSArray( PACKED_ELEMENTS, array_map, IntPtrConstant(0), SmiConstant(0)); - Node* const context = CreatePromiseContext( - native_context, PromiseBuiltins::kPromiseAllResolveElementLength); + TNode<Context> const context = CreatePromiseContext( + CAST(native_context), PromiseBuiltins::kPromiseAllResolveElementLength); StoreContextElementNoWriteBarrier( context, PromiseBuiltins::kPromiseAllResolveElementRemainingSlot, SmiConstant(1)); @@ -301,12 +304,12 @@ PromiseBuiltinsAssembler::CreatePromiseAllResolveElementFunction( index, SmiConstant(PropertyArray::HashField::kMax))); CSA_ASSERT(this, IsNativeContext(native_context)); - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const resolve_info = - LoadContextElement(native_context, slot_index); + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> resolve_info = + CAST(LoadContextElement(native_context, slot_index)); TNode<JSFunction> resolve = - Cast(AllocateFunctionWithMapAndContext(map, resolve_info, context)); + AllocateFunctionWithMapAndContext(map, resolve_info, CAST(context)); STATIC_ASSERT(PropertyArray::kNoHashSentinel == 0); StoreObjectFieldNoWriteBarrier(resolve, JSFunction::kPropertiesOrHashOffset, @@ -315,9 +318,10 @@ PromiseBuiltinsAssembler::CreatePromiseAllResolveElementFunction( return resolve; } -Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( - Node* promise, Node* debug_event, Node* native_context) { - Node* const context = CreatePromiseContext( +TNode<Context> PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( + TNode<JSPromise> promise, TNode<Object> debug_event, + TNode<NativeContext> native_context) { + const TNode<Context> context = CreatePromiseContext( native_context, PromiseBuiltins::kPromiseContextLength); StoreContextElementNoWriteBarrier(context, PromiseBuiltins::kPromiseSlot, promise); @@ -331,7 +335,8 @@ Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext( Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext( Node* promise_capability, Node* native_context) { int kContextLength = PromiseBuiltins::kCapabilitiesContextLength; - Node* context = CreatePromiseContext(native_context, kContextLength); + TNode<Context> context = + CreatePromiseContext(CAST(native_context), kContextLength); StoreContextElementNoWriteBarrier(context, PromiseBuiltins::kCapabilitySlot, promise_capability); return context; @@ -386,14 +391,12 @@ void PromiseBuiltinsAssembler::PromiseSetHandledHint(Node* promise) { // ES #sec-performpromisethen void PromiseBuiltinsAssembler::PerformPromiseThen( - Node* context, Node* promise, Node* on_fulfilled, Node* on_rejected, - Node* result_promise_or_capability) { - CSA_ASSERT(this, TaggedIsNotSmi(promise)); - CSA_ASSERT(this, IsJSPromise(promise)); + TNode<Context> context, TNode<JSPromise> promise, + TNode<HeapObject> on_fulfilled, TNode<HeapObject> on_rejected, + TNode<HeapObject> result_promise_or_capability) { CSA_ASSERT(this, Word32Or(IsCallable(on_fulfilled), IsUndefined(on_fulfilled))); CSA_ASSERT(this, Word32Or(IsCallable(on_rejected), IsUndefined(on_rejected))); - CSA_ASSERT(this, TaggedIsNotSmi(result_promise_or_capability)); CSA_ASSERT( this, Word32Or(Word32Or(IsJSPromise(result_promise_or_capability), @@ -411,9 +414,9 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( // PromiseReaction holding both the onFulfilled and onRejected callbacks. // Once the {promise} is resolved we decide on the concrete handler to // push onto the microtask queue. - TNode<Object> const promise_reactions = + const TNode<Object> promise_reactions = LoadObjectField(promise, JSPromise::kReactionsOrResultOffset); - Node* const reaction = + const TNode<PromiseReaction> reaction = AllocatePromiseReaction(promise_reactions, result_promise_or_capability, on_fulfilled, on_rejected); StoreObjectField(promise, JSPromise::kReactionsOrResultOffset, reaction); @@ -422,10 +425,9 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( BIND(&if_notpending); { - VARIABLE(var_map, MachineRepresentation::kTagged); - VARIABLE(var_handler, MachineRepresentation::kTagged); - VARIABLE(var_handler_context, MachineRepresentation::kTagged, - UndefinedConstant()); + TVARIABLE(Map, var_map); + TVARIABLE(HeapObject, var_handler); + TVARIABLE(Object, var_handler_context, UndefinedConstant()); Label if_fulfilled(this), if_rejected(this, Label::kDeferred), enqueue(this); Branch(IsPromiseStatus(status, v8::Promise::kFulfilled), &if_fulfilled, @@ -433,15 +435,15 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( BIND(&if_fulfilled); { - var_map.Bind(PromiseFulfillReactionJobTaskMapConstant()); - var_handler.Bind(on_fulfilled); + var_map = PromiseFulfillReactionJobTaskMapConstant(); + var_handler = on_fulfilled; Label use_fallback(this, Label::kDeferred), done(this); ExtractHandlerContext(on_fulfilled, &var_handler_context); Branch(IsUndefined(var_handler_context.value()), &use_fallback, &done); BIND(&use_fallback); - var_handler_context.Bind(context); + var_handler_context = context; ExtractHandlerContext(on_rejected, &var_handler_context); Goto(&done); @@ -452,15 +454,15 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( BIND(&if_rejected); { CSA_ASSERT(this, IsPromiseStatus(status, v8::Promise::kRejected)); - var_map.Bind(PromiseRejectReactionJobTaskMapConstant()); - var_handler.Bind(on_rejected); + var_map = PromiseRejectReactionJobTaskMapConstant(); + var_handler = on_rejected; Label use_fallback(this, Label::kDeferred), done(this); ExtractHandlerContext(on_rejected, &var_handler_context); Branch(IsUndefined(var_handler_context.value()), &use_fallback, &done); BIND(&use_fallback); - var_handler_context.Bind(context); + var_handler_context = context; ExtractHandlerContext(on_fulfilled, &var_handler_context); Goto(&done); BIND(&done); @@ -474,8 +476,8 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( { TNode<Object> argument = LoadObjectField(promise, JSPromise::kReactionsOrResultOffset); - Node* microtask = AllocatePromiseReactionJobTask( - var_map.value(), var_handler_context.value(), argument, + TNode<PromiseReactionJobTask> microtask = AllocatePromiseReactionJobTask( + var_map.value(), CAST(var_handler_context.value()), argument, var_handler.value(), result_promise_or_capability); CallBuiltin(Builtins::kEnqueueMicrotask, var_handler_context.value(), microtask); @@ -489,13 +491,15 @@ void PromiseBuiltinsAssembler::PerformPromiseThen( // ES #sec-performpromisethen TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { - Node* const context = Parameter(Descriptor::kContext); - Node* const promise = Parameter(Descriptor::kPromise); - Node* const on_fulfilled = Parameter(Descriptor::kOnFulfilled); - Node* const on_rejected = Parameter(Descriptor::kOnRejected); - Node* const result_promise = Parameter(Descriptor::kResultPromise); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + const TNode<JSPromise> promise = CAST(Parameter(Descriptor::kPromise)); + const TNode<HeapObject> on_fulfilled = + CAST(Parameter(Descriptor::kOnFulfilled)); + const TNode<HeapObject> on_rejected = + CAST(Parameter(Descriptor::kOnRejected)); + const TNode<HeapObject> result_promise = + CAST(Parameter(Descriptor::kResultPromise)); - CSA_ASSERT(this, TaggedIsNotSmi(result_promise)); CSA_ASSERT( this, Word32Or(IsJSPromise(result_promise), IsUndefined(result_promise))); @@ -504,9 +508,9 @@ TF_BUILTIN(PerformPromiseThen, PromiseBuiltinsAssembler) { Return(result_promise); } -Node* PromiseBuiltinsAssembler::AllocatePromiseReaction( - Node* next, Node* promise_or_capability, Node* fulfill_handler, - Node* reject_handler) { +TNode<PromiseReaction> PromiseBuiltinsAssembler::AllocatePromiseReaction( + TNode<Object> next, TNode<HeapObject> promise_or_capability, + TNode<HeapObject> fulfill_handler, TNode<HeapObject> reject_handler) { TNode<HeapObject> const reaction = Allocate(PromiseReaction::kSize); StoreMapNoWriteBarrier(reaction, RootIndex::kPromiseReactionMap); StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kNextOffset, next); @@ -517,12 +521,13 @@ Node* PromiseBuiltinsAssembler::AllocatePromiseReaction( reaction, PromiseReaction::kFulfillHandlerOffset, fulfill_handler); StoreObjectFieldNoWriteBarrier( reaction, PromiseReaction::kRejectHandlerOffset, reject_handler); - return reaction; + return CAST(reaction); } -Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask( - Node* map, Node* context, Node* argument, Node* handler, - Node* promise_or_capability) { +TNode<PromiseReactionJobTask> +PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask( + TNode<Map> map, TNode<Context> context, TNode<Object> argument, + TNode<HeapObject> handler, TNode<HeapObject> promise_or_capability) { TNode<HeapObject> const microtask = Allocate(PromiseReactionJobTask::kSizeOfAllPromiseReactionJobTasks); StoreMapNoWriteBarrier(microtask, map); @@ -535,12 +540,14 @@ Node* PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask( StoreObjectFieldNoWriteBarrier( microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset, promise_or_capability); - return microtask; + return CAST(microtask); } -Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask( - Node* promise_to_resolve, Node* then, Node* thenable, Node* context) { - TNode<HeapObject> const microtask = +TNode<PromiseResolveThenableJobTask> +PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask( + TNode<JSPromise> promise_to_resolve, TNode<JSReceiver> then, + TNode<JSReceiver> thenable, TNode<Context> context) { + const TNode<HeapObject> microtask = Allocate(PromiseResolveThenableJobTask::kSize); StoreMapNoWriteBarrier(microtask, RootIndex::kPromiseResolveThenableJobTaskMap); @@ -553,7 +560,7 @@ Node* PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask( microtask, PromiseResolveThenableJobTask::kThenOffset, then); StoreObjectFieldNoWriteBarrier( microtask, PromiseResolveThenableJobTask::kThenableOffset, thenable); - return microtask; + return CAST(microtask); } // ES #sec-triggerpromisereactions @@ -1003,7 +1010,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { BIND(&if_targetisnotmodified); { - Node* const instance = AllocateAndInitJSPromise(context); + TNode<JSPromise> const instance = AllocateAndInitJSPromise(context); var_result.Bind(instance); Goto(&debug_push); } @@ -1035,7 +1042,7 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { Node *resolve, *reject; std::tie(resolve, reject) = CreatePromiseResolvingFunctions( - var_result.value(), TrueConstant(), native_context); + CAST(var_result.value()), TrueConstant(), native_context); Node* const maybe_exception = CallJS( CodeFactory::Call(isolate, ConvertReceiverMode::kNullOrUndefined), @@ -1080,8 +1087,8 @@ TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { // V8 Extras: v8.createPromise(parent) TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { - Node* const parent = Parameter(Descriptor::kParent); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> parent = CAST(Parameter(Descriptor::kParent)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Return(AllocateAndInitJSPromise(context, parent)); } @@ -1127,14 +1134,15 @@ TF_BUILTIN(PromiseInternalResolve, PromiseBuiltinsAssembler) { // Promise.prototype.then ( onFulfilled, onRejected ) TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) { // 1. Let promise be the this value. - Node* const promise = Parameter(Descriptor::kReceiver); - Node* const on_fulfilled = Parameter(Descriptor::kOnFulfilled); - Node* const on_rejected = Parameter(Descriptor::kOnRejected); - Node* const context = Parameter(Descriptor::kContext); + const TNode<Object> maybe_promise = CAST(Parameter(Descriptor::kReceiver)); + const TNode<Object> on_fulfilled = CAST(Parameter(Descriptor::kOnFulfilled)); + const TNode<Object> on_rejected = CAST(Parameter(Descriptor::kOnRejected)); + const TNode<Context> context = CAST(Parameter(Descriptor::kContext)); // 2. If IsPromise(promise) is false, throw a TypeError exception. - ThrowIfNotInstanceType(context, promise, JS_PROMISE_TYPE, + ThrowIfNotInstanceType(context, maybe_promise, JS_PROMISE_TYPE, "Promise.prototype.then"); + TNode<JSPromise> js_promise = CAST(maybe_promise); // 3. Let C be ? SpeciesConstructor(promise, %Promise%). Label fast_promise_capability(this), slow_constructor(this, Label::kDeferred), @@ -1142,26 +1150,27 @@ TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) { TNode<NativeContext> const native_context = LoadNativeContext(context); TNode<JSFunction> promise_fun = CAST(LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX)); - TNode<Map> const promise_map = LoadMap(promise); + TNode<Map> const promise_map = LoadMap(js_promise); BranchIfPromiseSpeciesLookupChainIntact( native_context, promise_map, &fast_promise_capability, &slow_constructor); BIND(&slow_constructor); TNode<JSReceiver> constructor = - SpeciesConstructor(native_context, promise, promise_fun); + SpeciesConstructor(native_context, js_promise, promise_fun); Branch(TaggedEqual(constructor, promise_fun), &fast_promise_capability, &slow_promise_capability); // 4. Let resultCapability be ? NewPromiseCapability(C). Label perform_promise_then(this); - VARIABLE(var_result_promise, MachineRepresentation::kTagged); - VARIABLE(var_result_promise_or_capability, MachineRepresentation::kTagged); + TVARIABLE(Object, var_result_promise); + TVARIABLE(HeapObject, var_result_promise_or_capability); BIND(&fast_promise_capability); { - Node* const result_promise = AllocateAndInitJSPromise(context, promise); - var_result_promise_or_capability.Bind(result_promise); - var_result_promise.Bind(result_promise); + const TNode<JSPromise> result_promise = + AllocateAndInitJSPromise(context, js_promise); + var_result_promise_or_capability = result_promise; + var_result_promise = result_promise; Goto(&perform_promise_then); } @@ -1170,9 +1179,9 @@ TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) { TNode<Oddball> const debug_event = TrueConstant(); TNode<PromiseCapability> const capability = CAST(CallBuiltin( Builtins::kNewPromiseCapability, context, constructor, debug_event)); - var_result_promise.Bind( - LoadObjectField(capability, PromiseCapability::kPromiseOffset)); - var_result_promise_or_capability.Bind(capability); + var_result_promise = + LoadObjectField(capability, PromiseCapability::kPromiseOffset); + var_result_promise_or_capability = capability; Goto(&perform_promise_then); } @@ -1187,30 +1196,30 @@ TF_BUILTIN(PromisePrototypeThen, PromiseBuiltinsAssembler) { // 3. If IsCallable(onFulfilled) is false, then // a. Set onFulfilled to undefined. - VARIABLE(var_on_fulfilled, MachineRepresentation::kTagged, on_fulfilled); + TVARIABLE(Object, var_on_fulfilled, on_fulfilled); Label if_fulfilled_done(this), if_fulfilled_notcallable(this); GotoIf(TaggedIsSmi(on_fulfilled), &if_fulfilled_notcallable); - Branch(IsCallable(on_fulfilled), &if_fulfilled_done, + Branch(IsCallable(CAST(on_fulfilled)), &if_fulfilled_done, &if_fulfilled_notcallable); BIND(&if_fulfilled_notcallable); - var_on_fulfilled.Bind(UndefinedConstant()); + var_on_fulfilled = UndefinedConstant(); Goto(&if_fulfilled_done); BIND(&if_fulfilled_done); // 4. If IsCallable(onRejected) is false, then // a. Set onRejected to undefined. - VARIABLE(var_on_rejected, MachineRepresentation::kTagged, on_rejected); + TVARIABLE(Object, var_on_rejected, on_rejected); Label if_rejected_done(this), if_rejected_notcallable(this); GotoIf(TaggedIsSmi(on_rejected), &if_rejected_notcallable); - Branch(IsCallable(on_rejected), &if_rejected_done, + Branch(IsCallable(CAST(on_rejected)), &if_rejected_done, &if_rejected_notcallable); BIND(&if_rejected_notcallable); - var_on_rejected.Bind(UndefinedConstant()); + var_on_rejected = UndefinedConstant(); Goto(&if_rejected_done); BIND(&if_rejected_done); - PerformPromiseThen(context, promise, var_on_fulfilled.value(), - var_on_rejected.value(), + PerformPromiseThen(context, js_promise, CAST(var_on_fulfilled.value()), + CAST(var_on_rejected.value()), var_result_promise_or_capability.value()); Return(var_result_promise.value()); } @@ -1522,7 +1531,7 @@ TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) { // create NewPromiseCapability. BIND(&if_nativepromise); { - Node* const result = AllocateAndInitJSPromise(context); + TNode<JSPromise> const result = AllocateAndInitJSPromise(context); CallBuiltin(Builtins::kResolvePromise, context, result, value); Return(result); } @@ -1592,7 +1601,7 @@ TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) { BIND(&if_nativepromise); { - Node* const promise = + TNode<JSPromise> const promise = AllocateAndSetJSPromise(context, v8::Promise::kRejected, reason); CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise, reason); @@ -1621,21 +1630,21 @@ TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) { std::pair<Node*, Node*> PromiseBuiltinsAssembler::CreatePromiseFinallyFunctions( Node* on_finally, Node* constructor, Node* native_context) { - Node* const promise_context = CreatePromiseContext( - native_context, PromiseBuiltins::kPromiseFinallyContextLength); + const TNode<Context> promise_context = CreatePromiseContext( + CAST(native_context), PromiseBuiltins::kPromiseFinallyContextLength); StoreContextElementNoWriteBarrier( promise_context, PromiseBuiltins::kOnFinallySlot, on_finally); StoreContextElementNoWriteBarrier( promise_context, PromiseBuiltins::kConstructorSlot, constructor); - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const then_finally_info = LoadContextElement( - native_context, Context::PROMISE_THEN_FINALLY_SHARED_FUN); - Node* const then_finally = AllocateFunctionWithMapAndContext( + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> then_finally_info = CAST(LoadContextElement( + native_context, Context::PROMISE_THEN_FINALLY_SHARED_FUN)); + TNode<JSFunction> const then_finally = AllocateFunctionWithMapAndContext( map, then_finally_info, promise_context); - TNode<Object> const catch_finally_info = LoadContextElement( - native_context, Context::PROMISE_CATCH_FINALLY_SHARED_FUN); - Node* const catch_finally = AllocateFunctionWithMapAndContext( + const TNode<SharedFunctionInfo> catch_finally_info = CAST(LoadContextElement( + native_context, Context::PROMISE_CATCH_FINALLY_SHARED_FUN)); + TNode<JSFunction> const catch_finally = AllocateFunctionWithMapAndContext( map, catch_finally_info, promise_context); return std::make_pair(then_finally, catch_finally); } @@ -1650,15 +1659,16 @@ TF_BUILTIN(PromiseValueThunkFinally, PromiseBuiltinsAssembler) { Node* PromiseBuiltinsAssembler::CreateValueThunkFunction(Node* value, Node* native_context) { - Node* const value_thunk_context = CreatePromiseContext( - native_context, PromiseBuiltins::kPromiseValueThunkOrReasonContextLength); + const TNode<Context> value_thunk_context = CreatePromiseContext( + CAST(native_context), + PromiseBuiltins::kPromiseValueThunkOrReasonContextLength); StoreContextElementNoWriteBarrier(value_thunk_context, PromiseBuiltins::kValueSlot, value); - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const value_thunk_info = LoadContextElement( - native_context, Context::PROMISE_VALUE_THUNK_FINALLY_SHARED_FUN); - Node* const value_thunk = AllocateFunctionWithMapAndContext( + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> value_thunk_info = CAST(LoadContextElement( + native_context, Context::PROMISE_VALUE_THUNK_FINALLY_SHARED_FUN)); + TNode<JSFunction> const value_thunk = AllocateFunctionWithMapAndContext( map, value_thunk_info, value_thunk_context); return value_thunk; } @@ -1711,15 +1721,16 @@ TF_BUILTIN(PromiseThrowerFinally, PromiseBuiltinsAssembler) { Node* PromiseBuiltinsAssembler::CreateThrowerFunction(Node* reason, Node* native_context) { - Node* const thrower_context = CreatePromiseContext( - native_context, PromiseBuiltins::kPromiseValueThunkOrReasonContextLength); + const TNode<Context> thrower_context = CreatePromiseContext( + CAST(native_context), + PromiseBuiltins::kPromiseValueThunkOrReasonContextLength); StoreContextElementNoWriteBarrier(thrower_context, PromiseBuiltins::kValueSlot, reason); - TNode<Object> const map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const thrower_info = LoadContextElement( - native_context, Context::PROMISE_THROWER_FINALLY_SHARED_FUN); - Node* const thrower = + const TNode<Map> map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> thrower_info = CAST(LoadContextElement( + native_context, Context::PROMISE_THROWER_FINALLY_SHARED_FUN)); + TNode<JSFunction> const thrower = AllocateFunctionWithMapAndContext(map, thrower_info, thrower_context); return thrower; } @@ -1919,7 +1930,7 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { Label do_enqueue(this), if_fulfill(this), if_reject(this, Label::kDeferred), if_runtime(this, Label::kDeferred); TVARIABLE(Object, var_reason); - TVARIABLE(Object, var_then); + TVARIABLE(JSReceiver, var_then); // If promise hook is enabled or the debugger is active, let // the runtime handle this operation, which greatly reduces @@ -1955,7 +1966,8 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { BIND(&if_fast); { // The {resolution} is a native Promise in this case. - var_then = LoadContextElement(native_context, Context::PROMISE_THEN_INDEX); + var_then = + CAST(LoadContextElement(native_context, Context::PROMISE_THEN_INDEX)); Goto(&do_enqueue); } @@ -1987,7 +1999,7 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { GotoIf(TaggedIsSmi(then), &if_fulfill); TNode<Map> const then_map = LoadMap(CAST(then)); GotoIfNot(IsCallableMap(then_map), &if_fulfill); - var_then = then; + var_then = CAST(then); Goto(&do_enqueue); } @@ -1995,8 +2007,9 @@ TF_BUILTIN(ResolvePromise, PromiseBuiltinsAssembler) { { // 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob, // «promise, resolution, thenAction»). - Node* const task = AllocatePromiseResolveThenableJobTask( - promise, var_then.value(), resolution, native_context); + const TNode<PromiseResolveThenableJobTask> task = + AllocatePromiseResolveThenableJobTask(promise, var_then.value(), + CAST(resolution), native_context); TailCallBuiltin(Builtins::kEnqueueMicrotask, native_context, task); } @@ -2150,8 +2163,9 @@ Node* PromiseBuiltinsAssembler::PerformPromiseAll( // Register the PromiseReaction immediately on the {next_value}, not // passing any chained promise since neither async_hooks nor DevTools // are enabled, so there's no use of the resulting promise. - PerformPromiseThen(native_context, next_value, resolve_element_fun, - reject_element_fun, UndefinedConstant()); + PerformPromiseThen(native_context, CAST(next_value), + CAST(resolve_element_fun), CAST(reject_element_fun), + UndefinedConstant()); Goto(&loop); } diff --git a/deps/v8/src/builtins/builtins-promise-gen.h b/deps/v8/src/builtins/builtins-promise-gen.h index 633e3321aa17d3..b2ae8fe8765d8c 100644 --- a/deps/v8/src/builtins/builtins-promise-gen.h +++ b/deps/v8/src/builtins/builtins-promise-gen.h @@ -22,29 +22,34 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler { // // This uses undefined as the parent promise for the promise init // hook. - Node* AllocateAndInitJSPromise(Node* context); + TNode<JSPromise> AllocateAndInitJSPromise(TNode<Context> context); // This uses the given parent as the parent promise for the promise // init hook. - Node* AllocateAndInitJSPromise(Node* context, Node* parent); + TNode<JSPromise> AllocateAndInitJSPromise(TNode<Context> context, + TNode<Object> parent); // This allocates and initializes a promise with the given state and // fields. - Node* AllocateAndSetJSPromise(Node* context, v8::Promise::PromiseState status, - Node* result); + TNode<JSPromise> AllocateAndSetJSPromise(TNode<Context> context, + v8::Promise::PromiseState status, + TNode<Object> result); - Node* AllocatePromiseReaction(Node* next, Node* promise_or_capability, - Node* fulfill_handler, Node* reject_handler); + TNode<PromiseReaction> AllocatePromiseReaction( + TNode<Object> next, TNode<HeapObject> promise_or_capability, + TNode<HeapObject> fulfill_handler, TNode<HeapObject> reject_handler); - Node* AllocatePromiseReactionJobTask(Node* map, Node* context, Node* argument, - Node* handler, - Node* promise_or_capability); - Node* AllocatePromiseResolveThenableJobTask(Node* promise_to_resolve, - Node* then, Node* thenable, - Node* context); + TNode<PromiseReactionJobTask> AllocatePromiseReactionJobTask( + TNode<Map> map, TNode<Context> context, TNode<Object> argument, + TNode<HeapObject> handler, TNode<HeapObject> promise_or_capability); - std::pair<Node*, Node*> CreatePromiseResolvingFunctions(Node* promise, - Node* debug_event, - Node* native_context); + TNode<PromiseResolveThenableJobTask> AllocatePromiseResolveThenableJobTask( + TNode<JSPromise> promise_to_resolve, TNode<JSReceiver> then, + TNode<JSReceiver> thenable, TNode<Context> context); + + std::pair<TNode<JSFunction>, TNode<JSFunction>> + CreatePromiseResolvingFunctions(TNode<JSPromise> promise, + TNode<Object> debug_event, + TNode<NativeContext> native_context); Node* PromiseHasHandler(Node* promise); @@ -62,8 +67,9 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler { Node* native_context, int slot_index); - Node* CreatePromiseResolvingFunctionsContext(Node* promise, Node* debug_event, - Node* native_context); + TNode<Context> CreatePromiseResolvingFunctionsContext( + TNode<JSPromise> promise, TNode<Object> debug_event, + TNode<NativeContext> native_context); Node* CreatePromiseGetCapabilitiesExecutorContext(Node* promise_capability, Node* native_context); @@ -74,11 +80,13 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler { void PromiseSetHasHandler(Node* promise); void PromiseSetHandledHint(Node* promise); - void PerformPromiseThen(Node* context, Node* promise, Node* on_fulfilled, - Node* on_rejected, - Node* result_promise_or_capability); + void PerformPromiseThen(TNode<Context> context, TNode<JSPromise> promise, + TNode<HeapObject> on_fulfilled, + TNode<HeapObject> on_rejected, + TNode<HeapObject> result_promise_or_capability); - Node* CreatePromiseContext(Node* native_context, int slots); + TNode<Context> CreatePromiseContext(TNode<NativeContext> native_context, + int slots); Node* TriggerPromiseReactions(Node* context, Node* promise, Node* result, PromiseReaction::Type type); @@ -161,7 +169,7 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler { v8::Promise::PromiseState expected); void PromiseSetStatus(Node* promise, v8::Promise::PromiseState status); - Node* AllocateJSPromise(Node* context); + TNode<JSPromise> AllocateJSPromise(TNode<Context> context); void ExtractHandlerContext(Node* handler, Variable* var_context); void Generate_PromiseAll( diff --git a/deps/v8/src/builtins/builtins-proxy-gen.cc b/deps/v8/src/builtins/builtins-proxy-gen.cc index bb1137735cdcf3..71d4e8226f595b 100644 --- a/deps/v8/src/builtins/builtins-proxy-gen.cc +++ b/deps/v8/src/builtins/builtins-proxy-gen.cc @@ -14,7 +14,7 @@ namespace v8 { namespace internal { -compiler::TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( +TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( TNode<Context> context, TNode<JSReceiver> target, TNode<JSReceiver> handler) { VARIABLE(map, MachineRepresentation::kTagged); @@ -59,7 +59,8 @@ compiler::TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( } Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments( - Node* context, CodeStubArguments& args, Node* argc, ParameterMode mode) { + Node* context, const CodeStubArguments& args, Node* argc, + ParameterMode mode) { Comment("AllocateJSArrayForCodeStubArguments"); Label if_empty_array(this), allocate_js_array(this); @@ -80,7 +81,7 @@ Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments( GotoIf(SmiGreaterThan(length, SmiConstant(FixedArray::kMaxRegularLength)), &if_large_object); - args.ForEach(list, [=, &offset](Node* arg) { + args.ForEach(list, [&](TNode<Object> arg) { StoreNoWriteBarrier(MachineRepresentation::kTagged, allocated_elements, offset.value(), arg); Increment(&offset, kTaggedSize); @@ -89,7 +90,7 @@ Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments( BIND(&if_large_object); { - args.ForEach(list, [=, &offset](Node* arg) { + args.ForEach(list, [&](TNode<Object> arg) { Store(allocated_elements, offset.value(), arg); Increment(&offset, kTaggedSize); }); @@ -124,20 +125,19 @@ Node* ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext( return context; } -compiler::TNode<JSFunction> -ProxiesCodeStubAssembler::AllocateProxyRevokeFunction(TNode<Context> context, - TNode<JSProxy> proxy) { +TNode<JSFunction> ProxiesCodeStubAssembler::AllocateProxyRevokeFunction( + TNode<Context> context, TNode<JSProxy> proxy) { TNode<NativeContext> const native_context = LoadNativeContext(context); - Node* const proxy_context = - CreateProxyRevokeFunctionContext(proxy, native_context); - TNode<Object> const revoke_map = LoadContextElement( - native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - TNode<Object> const revoke_info = - LoadContextElement(native_context, Context::PROXY_REVOKE_SHARED_FUN); + const TNode<Context> proxy_context = + CAST(CreateProxyRevokeFunctionContext(proxy, native_context)); + const TNode<Map> revoke_map = CAST(LoadContextElement( + native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)); + const TNode<SharedFunctionInfo> revoke_info = CAST( + LoadContextElement(native_context, Context::PROXY_REVOKE_SHARED_FUN)); - return CAST(AllocateFunctionWithMapAndContext(revoke_map, revoke_info, - proxy_context)); + return AllocateFunctionWithMapAndContext(revoke_map, revoke_info, + proxy_context); } TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) { diff --git a/deps/v8/src/builtins/builtins-proxy-gen.h b/deps/v8/src/builtins/builtins-proxy-gen.h index cb51faf57553fd..03b3749bf5d44a 100644 --- a/deps/v8/src/builtins/builtins-proxy-gen.h +++ b/deps/v8/src/builtins/builtins-proxy-gen.h @@ -39,10 +39,9 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler { kProxyContextLength, }; - Node* AllocateJSArrayForCodeStubArguments( - Node* context, - CodeStubArguments& args, // NOLINT(runtime/references) - Node* argc, ParameterMode mode); + Node* AllocateJSArrayForCodeStubArguments(Node* context, + const CodeStubArguments& args, + Node* argc, ParameterMode mode); private: Node* CreateProxyRevokeFunctionContext(Node* proxy, Node* native_context); diff --git a/deps/v8/src/builtins/builtins-reflect-gen.cc b/deps/v8/src/builtins/builtins-reflect-gen.cc index 744a443ecc2dc1..6cffd6ed55ba39 100644 --- a/deps/v8/src/builtins/builtins-reflect-gen.cc +++ b/deps/v8/src/builtins/builtins-reflect-gen.cc @@ -11,12 +11,12 @@ namespace internal { // ES section #sec-reflect.has TF_BUILTIN(ReflectHas, CodeStubAssembler) { - Node* target = Parameter(Descriptor::kTarget); - Node* key = Parameter(Descriptor::kKey); + TNode<Object> target = CAST(Parameter(Descriptor::kTarget)); + TNode<Object> key = CAST(Parameter(Descriptor::kKey)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - ThrowIfNotJSReceiver(context, CAST(target), - MessageTemplate::kCalledOnNonObject, "Reflect.has"); + ThrowIfNotJSReceiver(context, target, MessageTemplate::kCalledOnNonObject, + "Reflect.has"); Return(CallBuiltin(Builtins::kHasProperty, context, target, key)); } diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc index f879d70c676329..b333f2a820c681 100644 --- a/deps/v8/src/builtins/builtins-regexp-gen.cc +++ b/deps/v8/src/builtins/builtins-regexp-gen.cc @@ -23,8 +23,6 @@ namespace v8 { namespace internal { using compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; // Tail calls the regular expression interpreter. // static @@ -80,7 +78,8 @@ TNode<RawPtrT> RegExpBuiltinsAssembler::LoadCodeObjectEntry(TNode<Code> code) { TNode<JSRegExpResult> RegExpBuiltinsAssembler::AllocateRegExpResult( TNode<Context> context, TNode<Smi> length, TNode<Smi> index, - TNode<String> input, TNode<FixedArray>* elements_out) { + TNode<String> input, TNode<RegExpMatchInfo> match_info, + TNode<FixedArray>* elements_out) { CSA_ASSERT(this, SmiLessThanOrEqual( length, SmiConstant(JSArray::kMaxFastArrayLength))); CSA_ASSERT(this, SmiGreaterThan(length, SmiConstant(0))); @@ -90,9 +89,8 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::AllocateRegExpResult( const ElementsKind elements_kind = PACKED_ELEMENTS; TNode<Map> map = CAST(LoadContextElement(LoadNativeContext(context), Context::REGEXP_RESULT_MAP_INDEX)); - Node* no_allocation_site = nullptr; + TNode<AllocationSite> no_allocation_site = {}; TNode<IntPtrT> length_intptr = SmiUntag(length); - TNode<IntPtrT> capacity = length_intptr; // Note: The returned `elements` may be in young large object space, but // `array` is guaranteed to be in new space so we could skip write barriers @@ -100,18 +98,29 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::AllocateRegExpResult( TNode<JSArray> array; TNode<FixedArrayBase> elements; std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - elements_kind, map, length, no_allocation_site, capacity, + elements_kind, map, length, no_allocation_site, length_intptr, INTPTR_PARAMETERS, kAllowLargeObjectAllocation, JSRegExpResult::kSize); // Finish result initialization. TNode<JSRegExpResult> result = CAST(array); + // Load undefined value once here to avoid multiple LoadRoots. + TNode<Oddball> undefined_value = UncheckedCast<Oddball>( + CodeAssembler::LoadRoot(RootIndex::kUndefinedValue)); + StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kIndexOffset, index); // TODO(jgruber,tebbi): Could skip barrier but the MemoryOptimizer complains. StoreObjectField(result, JSRegExpResult::kInputOffset, input); StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kGroupsOffset, - UndefinedConstant()); + undefined_value); + StoreObjectFieldNoWriteBarrier(result, JSRegExpResult::kNamesOffset, + undefined_value); + + // Stash match_info in order to build JSRegExpResultIndices lazily when the + // 'indices' property is accessed. + StoreObjectField(result, JSRegExpResult::kCachedIndicesOrMatchInfoOffset, + match_info); // Finish elements initialization. @@ -213,7 +222,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( TNode<FixedArray> result_elements; TNode<JSRegExpResult> result = AllocateRegExpResult( - context, num_results, start, string, &result_elements); + context, num_results, start, string, match_info, &result_elements); UnsafeStoreFixedArrayElement(result_elements, 0, first); @@ -228,8 +237,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2)); TVARIABLE(IntPtrT, var_to_cursor, IntPtrConstant(1)); - Variable* vars[] = {&var_from_cursor, &var_to_cursor}; - Label loop(this, 2, vars); + Label loop(this, {&var_from_cursor, &var_to_cursor}); Goto(&loop); BIND(&loop); @@ -289,6 +297,9 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( TNode<IntPtrT> names_length = LoadAndUntagFixedArrayBaseLength(names); CSA_ASSERT(this, IntPtrGreaterThan(names_length, IntPtrZero())); + // Stash names in case we need them to build the indices array later. + StoreObjectField(result, JSRegExpResult::kNamesOffset, names); + // Allocate a new object to store the named capture properties. // TODO(jgruber): Could be optimized by adding the object map to the heap // root list. @@ -305,9 +316,7 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( TVARIABLE(IntPtrT, var_i, IntPtrZero()); - Variable* vars[] = {&var_i}; - const int vars_count = sizeof(vars) / sizeof(vars[0]); - Label loop(this, vars_count, vars); + Label loop(this, &var_i); Goto(&loop); BIND(&loop); @@ -355,9 +364,10 @@ TNode<JSRegExpResult> RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( } void RegExpBuiltinsAssembler::GetStringPointers( - Node* const string_data, Node* const offset, Node* const last_index, - Node* const string_length, String::Encoding encoding, - Variable* var_string_start, Variable* var_string_end) { + TNode<RawPtrT> string_data, TNode<IntPtrT> offset, + TNode<IntPtrT> last_index, TNode<IntPtrT> string_length, + String::Encoding encoding, TVariable<RawPtrT>* var_string_start, + TVariable<RawPtrT>* var_string_end) { DCHECK_EQ(var_string_start->rep(), MachineType::PointerRepresentation()); DCHECK_EQ(var_string_end->rep(), MachineType::PointerRepresentation()); @@ -365,13 +375,14 @@ void RegExpBuiltinsAssembler::GetStringPointers( ? UINT8_ELEMENTS : UINT16_ELEMENTS; - TNode<IntPtrT> const from_offset = ElementOffsetFromIndex( - IntPtrAdd(offset, last_index), kind, INTPTR_PARAMETERS); - var_string_start->Bind(IntPtrAdd(string_data, from_offset)); + TNode<IntPtrT> from_offset = + ElementOffsetFromIndex(IntPtrAdd(offset, last_index), kind); + *var_string_start = + ReinterpretCast<RawPtrT>(IntPtrAdd(string_data, from_offset)); - TNode<IntPtrT> const to_offset = ElementOffsetFromIndex( - IntPtrAdd(offset, string_length), kind, INTPTR_PARAMETERS); - var_string_end->Bind(IntPtrAdd(string_data, to_offset)); + TNode<IntPtrT> to_offset = + ElementOffsetFromIndex(IntPtrAdd(offset, string_length), kind); + *var_string_end = ReinterpretCast<RawPtrT>(IntPtrAdd(string_data, to_offset)); } TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( @@ -507,27 +518,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( GotoIf(TaggedIsSmi(var_code.value()), &runtime); TNode<Code> code = CAST(var_code.value()); - // Tier-up in runtime if ticks are non-zero and tier-up hasn't happened yet - // and ensure that a RegExp stack is allocated when using compiled Irregexp. + // Ensure that a RegExp stack is allocated when using compiled Irregexp. + // TODO(jgruber): Guarantee an allocated stack and remove this check. { - Label next(this), check_tier_up(this); - GotoIfNot(TaggedIsSmi(var_bytecode.value()), &check_tier_up); + Label next(this); + GotoIfNot(TaggedIsSmi(var_bytecode.value()), &next); CSA_ASSERT(this, SmiEqual(CAST(var_bytecode.value()), SmiConstant(JSRegExp::kUninitializedValue))); - // Ensure RegExp stack is allocated. TNode<IntPtrT> stack_size = UncheckedCast<IntPtrT>( Load(MachineType::IntPtr(), regexp_stack_memory_size_address)); - GotoIf(IntPtrEqual(stack_size, IntPtrZero()), &runtime); - Goto(&next); - - // Check if tier-up is requested. - BIND(&check_tier_up); - TNode<Smi> ticks = CAST( - UnsafeLoadFixedArrayElement(data, JSRegExp::kIrregexpTierUpTicksIndex)); - GotoIf(SmiToInt32(ticks), &runtime); + Branch(IntPtrEqual(stack_size, IntPtrZero()), &runtime, &next); - Goto(&next); BIND(&next); } @@ -603,13 +605,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( TNode<RawPtrT> code_entry = LoadCodeObjectEntry(code); - TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction( - code_entry, retval_type, std::make_pair(arg0_type, arg0), - std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2), - std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4), - std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6), - std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8), - std::make_pair(arg9_type, arg9))); + // AIX uses function descriptors on CFunction calls. code_entry in this case + // may also point to a Regex interpreter entry trampoline which does not + // have a function descriptor. This method is ineffective on other platforms + // and is equivalent to CallCFunction. + TNode<Int32T> result = + UncheckedCast<Int32T>(CallCFunctionWithoutFunctionDescriptor( + code_entry, retval_type, std::make_pair(arg0_type, arg0), + std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2), + std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4), + std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6), + std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8), + std::make_pair(arg9_type, arg9))); // Check the result. // We expect exactly one result since we force the called regexp to behave @@ -656,18 +663,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( // Fill match and capture offsets in match_info. { - TNode<IntPtrT> limit_offset = ElementOffsetFromIndex( - register_count, INT32_ELEMENTS, SMI_PARAMETERS, 0); + TNode<IntPtrT> limit_offset = + ElementOffsetFromIndex(register_count, INT32_ELEMENTS, 0); TNode<IntPtrT> to_offset = ElementOffsetFromIndex( IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), PACKED_ELEMENTS, - INTPTR_PARAMETERS, RegExpMatchInfo::kHeaderSize - kHeapObjectTag); + RegExpMatchInfo::kHeaderSize - kHeapObjectTag); TVARIABLE(IntPtrT, var_to_offset, to_offset); VariableList vars({&var_to_offset}, zone()); - BuildFastLoop( + BuildFastLoop<IntPtrT>( vars, IntPtrZero(), limit_offset, - [=, &var_to_offset](Node* offset) { + [&](TNode<IntPtrT> offset) { TNode<Int32T> value = UncheckedCast<Int32T>(Load( MachineType::Int32(), static_offsets_vector_address, offset)); TNode<Smi> smi_value = SmiFromInt32(value); @@ -675,7 +682,7 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( var_to_offset.value(), smi_value); Increment(&var_to_offset, kTaggedSize); }, - kInt32Size, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kInt32Size, IndexAdvanceMode::kPost); } var_result = match_info; @@ -733,7 +740,7 @@ RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( TNode<Context> context, TNode<JSReceiver> maybe_regexp, TNode<String> string, Label* if_didnotmatch, const bool is_fastpath) { if (!is_fastpath) { - ThrowIfNotInstanceType(context, maybe_regexp, JS_REGEXP_TYPE, + ThrowIfNotInstanceType(context, maybe_regexp, JS_REG_EXP_TYPE, "RegExp.prototype.exec"); } @@ -894,14 +901,13 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsReceiverInitialRegExpPrototype( return TaggedEqual(receiver, initial_prototype); } -Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( - SloppyTNode<Context> context, SloppyTNode<Object> object, - SloppyTNode<Map> map) { +TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( + TNode<Context> context, TNode<Object> object, TNode<Map> map) { Label out(this); - VARIABLE(var_result, MachineRepresentation::kWord32); + TVARIABLE(BoolT, var_result); #ifdef V8_ENABLE_FORCE_SLOW_PATH - var_result.Bind(Int32Constant(0)); + var_result = Int32FalseConstant(); GotoIfForceSlowPath(&out); #endif @@ -912,13 +918,13 @@ Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( LoadObjectField(regexp_fun, JSFunction::kPrototypeOrInitialMapOffset); TNode<BoolT> const has_initialmap = TaggedEqual(map, initial_map); - var_result.Bind(has_initialmap); + var_result = has_initialmap; GotoIfNot(has_initialmap, &out); // The smi check is required to omit ToLength(lastIndex) calls with possible // user-code execution on the fast path. TNode<Object> last_index = FastLoadLastIndexBeforeSmiCheck(CAST(object)); - var_result.Bind(TaggedIsPositiveSmi(last_index)); + var_result = TaggedIsPositiveSmi(last_index); Goto(&out); BIND(&out); @@ -939,7 +945,7 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec( GotoIfForceSlowPath(&out); #endif - TNode<BoolT> is_regexp = HasInstanceType(object, JS_REGEXP_TYPE); + TNode<BoolT> is_regexp = HasInstanceType(object, JS_REG_EXP_TYPE); var_result = is_regexp; GotoIfNot(is_regexp, &out); @@ -970,8 +976,8 @@ TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpWithOriginalExec( return var_result.value(); } -Node* RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( - SloppyTNode<Context> context, SloppyTNode<Object> object) { +TNode<BoolT> RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( + TNode<Context> context, TNode<Object> object) { CSA_ASSERT(this, TaggedIsNotSmi(object)); return IsFastRegExpNoPrototype(context, object, LoadMap(CAST(object))); } @@ -1046,10 +1052,9 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExp_Permissive( if_isunmodified, if_ismodified); } -void RegExpBuiltinsAssembler::BranchIfFastRegExpResult(Node* const context, - Node* const object, - Label* if_isunmodified, - Label* if_ismodified) { +void RegExpBuiltinsAssembler::BranchIfFastRegExpResult( + const TNode<Context> context, const TNode<Object> object, + Label* if_isunmodified, Label* if_ismodified) { // Could be a Smi. TNode<Map> const map = LoadReceiverMap(object); @@ -1061,15 +1066,6 @@ void RegExpBuiltinsAssembler::BranchIfFastRegExpResult(Node* const context, if_ismodified); } -// Slow path stub for RegExpPrototypeExec to decrease code size. -TF_BUILTIN(RegExpPrototypeExecSlow, RegExpBuiltinsAssembler) { - TNode<JSRegExp> regexp = CAST(Parameter(Descriptor::kReceiver)); - TNode<String> string = CAST(Parameter(Descriptor::kString)); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - Return(RegExpPrototypeExecBody(context, regexp, string, false)); -} - // Fast path stub for ATOM regexps. String matching is done by StringIndexOf, // and {match_info} is updated on success. // The slow path is implemented in RegExp::AtomExec. @@ -1149,33 +1145,6 @@ TF_BUILTIN(RegExpExecInternal, RegExpBuiltinsAssembler) { Return(RegExpExecInternal(context, regexp, string, last_index, match_info)); } -// ES#sec-regexp.prototype.exec -// RegExp.prototype.exec ( string ) -TF_BUILTIN(RegExpPrototypeExec, RegExpBuiltinsAssembler) { - TNode<Object> maybe_receiver = CAST(Parameter(Descriptor::kReceiver)); - TNode<Object> maybe_string = CAST(Parameter(Descriptor::kString)); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - // Ensure {maybe_receiver} is a JSRegExp. - ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, - "RegExp.prototype.exec"); - TNode<JSRegExp> receiver = CAST(maybe_receiver); - - // Convert {maybe_string} to a String. - TNode<String> string = ToString_Inline(context, maybe_string); - - Label if_isfastpath(this), if_isslowpath(this); - Branch(IsFastRegExpNoPrototype(context, receiver), &if_isfastpath, - &if_isslowpath); - - BIND(&if_isfastpath); - Return(RegExpPrototypeExecBody(context, receiver, string, true)); - - BIND(&if_isslowpath); - Return(CallBuiltin(Builtins::kRegExpPrototypeExecSlow, context, receiver, - string)); -} - TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context, TNode<Object> regexp, bool is_fastpath) { @@ -1246,8 +1215,8 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context, { TNode<String> const result = AllocateSeqOneByteString(var_length.value()); - VARIABLE(var_offset, MachineType::PointerRepresentation(), - IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); + TVARIABLE(IntPtrT, var_offset, + IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); #define CASE_FOR_FLAG(FLAG, CHAR) \ do { \ @@ -1256,7 +1225,7 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context, TNode<Int32T> const value = Int32Constant(CHAR); \ StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ var_offset.value(), value); \ - var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \ + var_offset = IntPtrAdd(var_offset.value(), int_one); \ Goto(&next); \ BIND(&next); \ } while (false) @@ -1273,64 +1242,11 @@ TNode<String> RegExpBuiltinsAssembler::FlagsGetter(TNode<Context> context, } } -// ES#sec-isregexp IsRegExp ( argument ) -TNode<BoolT> RegExpBuiltinsAssembler::IsRegExp(TNode<Context> context, - TNode<Object> maybe_receiver) { - Label out(this), if_isregexp(this); - - TVARIABLE(BoolT, var_result, Int32FalseConstant()); - - GotoIf(TaggedIsSmi(maybe_receiver), &out); - GotoIfNot(IsJSReceiver(CAST(maybe_receiver)), &out); - - TNode<JSReceiver> receiver = CAST(maybe_receiver); - - // Check @@match. - { - TNode<Object> value = - GetProperty(context, receiver, isolate()->factory()->match_symbol()); - - Label match_isundefined(this), match_isnotundefined(this); - Branch(IsUndefined(value), &match_isundefined, &match_isnotundefined); - - BIND(&match_isundefined); - Branch(IsJSRegExp(receiver), &if_isregexp, &out); - - BIND(&match_isnotundefined); - Label match_istrueish(this), match_isfalseish(this); - BranchIfToBooleanIsTrue(value, &match_istrueish, &match_isfalseish); - - // The common path. Symbol.match exists, equals the RegExpPrototypeMatch - // function (and is thus trueish), and the receiver is a JSRegExp. - BIND(&match_istrueish); - GotoIf(IsJSRegExp(receiver), &if_isregexp); - CallRuntime(Runtime::kIncrementUseCounter, context, - SmiConstant(v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp)); - Goto(&if_isregexp); - - BIND(&match_isfalseish); - GotoIfNot(IsJSRegExp(receiver), &out); - CallRuntime(Runtime::kIncrementUseCounter, context, - SmiConstant(v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp)); - Goto(&out); - } - - BIND(&if_isregexp); - var_result = Int32TrueConstant(); - Goto(&out); - - BIND(&out); - return var_result.value(); -} - // ES#sec-regexpinitialize // Runtime Semantics: RegExpInitialize ( obj, pattern, flags ) -Node* RegExpBuiltinsAssembler::RegExpInitialize(Node* const context, - Node* const regexp, - Node* const maybe_pattern, - Node* const maybe_flags) { - CSA_ASSERT(this, IsJSRegExp(regexp)); - +TNode<Object> RegExpBuiltinsAssembler::RegExpInitialize( + const TNode<Context> context, const TNode<JSRegExp> regexp, + const TNode<Object> maybe_pattern, const TNode<Object> maybe_flags) { // Normalize pattern. TNode<Object> const pattern = Select<Object>( IsUndefined(maybe_pattern), [=] { return EmptyStringConstant(); }, @@ -1437,7 +1353,7 @@ TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) { // Allocate. - VARIABLE(var_regexp, MachineRepresentation::kTagged); + TVARIABLE(JSRegExp, var_regexp); { Label allocate_jsregexp(this), allocate_generic(this, Label::kDeferred), next(this); @@ -1448,25 +1364,23 @@ TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) { { TNode<Map> const initial_map = CAST(LoadObjectField( regexp_function, JSFunction::kPrototypeOrInitialMapOffset)); - TNode<JSObject> const regexp = AllocateJSObjectFromMap(initial_map); - var_regexp.Bind(regexp); + var_regexp = CAST(AllocateJSObjectFromMap(initial_map)); Goto(&next); } BIND(&allocate_generic); { ConstructorBuiltinsAssembler constructor_assembler(this->state()); - TNode<JSObject> const regexp = constructor_assembler.EmitFastNewObject( - context, regexp_function, CAST(var_new_target.value())); - var_regexp.Bind(regexp); + var_regexp = CAST(constructor_assembler.EmitFastNewObject( + context, regexp_function, CAST(var_new_target.value()))); Goto(&next); } BIND(&next); } - Node* const result = RegExpInitialize(context, var_regexp.value(), - var_pattern.value(), var_flags.value()); + const TNode<Object> result = RegExpInitialize( + context, var_regexp.value(), var_pattern.value(), var_flags.value()); Return(result); } @@ -1478,12 +1392,12 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) { TNode<Object> maybe_flags = CAST(Parameter(Descriptor::kFlags)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, + ThrowIfNotInstanceType(context, maybe_receiver, JS_REG_EXP_TYPE, "RegExp.prototype.compile"); - Node* const receiver = maybe_receiver; + const TNode<JSRegExp> receiver = CAST(maybe_receiver); - VARIABLE(var_flags, MachineRepresentation::kTagged, maybe_flags); - VARIABLE(var_pattern, MachineRepresentation::kTagged, maybe_pattern); + TVARIABLE(Object, var_flags, maybe_flags); + TVARIABLE(Object, var_pattern, maybe_pattern); // Handle a JSRegExp pattern. { @@ -1492,8 +1406,6 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) { GotoIf(TaggedIsSmi(maybe_pattern), &next); GotoIfNot(IsJSRegExp(CAST(maybe_pattern)), &next); - Node* const pattern = maybe_pattern; - // {maybe_flags} must be undefined in this case, otherwise throw. { Label next(this); @@ -1504,19 +1416,20 @@ TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) { BIND(&next); } - TNode<String> const new_flags = FlagsGetter(context, CAST(pattern), true); + const TNode<JSRegExp> pattern = CAST(maybe_pattern); + TNode<String> const new_flags = FlagsGetter(context, pattern, true); TNode<Object> const new_pattern = LoadObjectField(pattern, JSRegExp::kSourceOffset); - var_flags.Bind(new_flags); - var_pattern.Bind(new_pattern); + var_flags = new_flags; + var_pattern = new_pattern; Goto(&next); BIND(&next); } - Node* const result = RegExpInitialize(context, receiver, var_pattern.value(), - var_flags.value()); + const TNode<Object> result = RegExpInitialize( + context, receiver, var_pattern.value(), var_flags.value()); Return(result); } @@ -1586,54 +1499,6 @@ TNode<BoolT> RegExpBuiltinsAssembler::FlagGetter(TNode<Context> context, : SlowFlagGetter(context, regexp, flag); } -// ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) -TNode<Object> RegExpBuiltinsAssembler::RegExpExec(TNode<Context> context, - Node* regexp, Node* string) { - TVARIABLE(Object, var_result); - Label out(this); - - // Take the slow path of fetching the exec property, calling it, and - // verifying its return value. - - // Get the exec property. - TNode<Object> const exec = - GetProperty(context, regexp, isolate()->factory()->exec_string()); - - // Is {exec} callable? - Label if_iscallable(this), if_isnotcallable(this); - - GotoIf(TaggedIsSmi(exec), &if_isnotcallable); - - TNode<Map> const exec_map = LoadMap(CAST(exec)); - Branch(IsCallableMap(exec_map), &if_iscallable, &if_isnotcallable); - - BIND(&if_iscallable); - { - Callable call_callable = CodeFactory::Call(isolate()); - var_result = CAST(CallJS(call_callable, context, exec, regexp, string)); - - GotoIf(IsNull(var_result.value()), &out); - - ThrowIfNotJSReceiver(context, var_result.value(), - MessageTemplate::kInvalidRegExpExecResult, ""); - - Goto(&out); - } - - BIND(&if_isnotcallable); - { - ThrowIfNotInstanceType(context, regexp, JS_REGEXP_TYPE, - "RegExp.prototype.exec"); - - var_result = CallBuiltin(Builtins::kRegExpPrototypeExecSlow, context, - regexp, string); - Goto(&out); - } - - BIND(&out); - return var_result.value(); -} - TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex( SloppyTNode<String> string, SloppyTNode<Number> index, SloppyTNode<BoolT> is_unicode, bool is_fastpath) { @@ -1717,7 +1582,7 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( { var_result = is_fastpath ? RegExpPrototypeExecBody(context, CAST(regexp), string, true) - : RegExpExec(context, regexp, string); + : RegExpExec(context, CAST(regexp), string); Goto(&done); } @@ -1735,9 +1600,9 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( // Loop preparations. Within the loop, collect results from RegExpExec // and store match strings in the array. - Variable* vars[] = {array.var_array(), array.var_length(), - array.var_capacity()}; - Label loop(this, 3, vars), out(this); + Label loop(this, + {array.var_array(), array.var_length(), array.var_capacity()}), + out(this); // Check if the regexp is an ATOM type. If then, keep the literal string to // search for so that we can avoid calling substring in the loop below. @@ -1758,7 +1623,7 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( BIND(&loop); { - VARIABLE(var_match, MachineRepresentation::kTagged); + TVARIABLE(String, var_match); Label if_didmatch(this), if_didnotmatch(this); if (is_fastpath) { @@ -1776,24 +1641,24 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( match_indices, RegExpMatchInfo::kFirstCaptureIndex); TNode<Object> const match_to = UnsafeLoadFixedArrayElement( match_indices, RegExpMatchInfo::kFirstCaptureIndex + 1); - var_match.Bind(CallBuiltin(Builtins::kSubString, context, string, - match_from, match_to)); + var_match = CAST(CallBuiltin(Builtins::kSubString, context, string, + match_from, match_to)); Goto(&if_didmatch); } BIND(&donotsubstring); - var_match.Bind(var_search_string.value()); + var_match = var_search_string.value(); Goto(&if_didmatch); } else { DCHECK(!is_fastpath); - TNode<Object> const result = RegExpExec(context, regexp, string); + TNode<Object> const result = RegExpExec(context, CAST(regexp), string); Label load_match(this); Branch(IsNull(result), &if_didnotmatch, &load_match); BIND(&load_match); - var_match.Bind( - ToString_Inline(context, GetProperty(context, result, SmiZero()))); + var_match = + ToString_Inline(context, GetProperty(context, result, SmiZero())); Goto(&if_didmatch); } @@ -1807,11 +1672,11 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( BIND(&if_didmatch); { - Node* match = var_match.value(); + TNode<String> match = var_match.value(); // Store the match, growing the fixed array if needed. - array.Push(CAST(match)); + array.Push(match); // Advance last index if the match is the empty string. @@ -1855,128 +1720,11 @@ TNode<Object> RegExpBuiltinsAssembler::RegExpPrototypeMatchBody( return var_result.value(); } -void RegExpMatchAllAssembler::Generate(TNode<Context> context, - TNode<Context> native_context, - TNode<Object> receiver, - TNode<Object> maybe_string) { - // 1. Let R be the this value. - // 2. If Type(R) is not Object, throw a TypeError exception. - ThrowIfNotJSReceiver(context, receiver, - MessageTemplate::kIncompatibleMethodReceiver, - "RegExp.prototype.@@matchAll"); - - // 3. Let S be ? ToString(O). - TNode<String> string = ToString_Inline(context, maybe_string); - - TVARIABLE(Object, var_matcher); - TVARIABLE(BoolT, var_global); - TVARIABLE(BoolT, var_unicode); - Label create_iterator(this), if_fast_regexp(this), - if_slow_regexp(this, Label::kDeferred); - - // Strict, because following code uses the flags property. - // TODO(jgruber): Handle slow flag accesses on the fast path and make this - // permissive. - BranchIfFastRegExp_Strict(context, CAST(receiver), &if_fast_regexp, - &if_slow_regexp); - - BIND(&if_fast_regexp); - { - TNode<JSRegExp> fast_regexp = CAST(receiver); - TNode<Object> source = - LoadObjectField(fast_regexp, JSRegExp::kSourceOffset); - - // 4. Let C be ? SpeciesConstructor(R, %RegExp%). - // 5. Let flags be ? ToString(? Get(R, "flags")). - // 6. Let matcher be ? Construct(C, « R, flags »). - TNode<String> flags = FlagsGetter(context, fast_regexp, true); - var_matcher = RegExpCreate(context, native_context, source, flags); - CSA_ASSERT(this, - IsFastRegExpPermissive(context, CAST(var_matcher.value()))); - - // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). - // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). - FastStoreLastIndex(CAST(var_matcher.value()), - FastLoadLastIndex(fast_regexp)); - - // 9. If flags contains "g", let global be true. - // 10. Else, let global be false. - var_global = FastFlagGetter(CAST(var_matcher.value()), JSRegExp::kGlobal); - - // 11. If flags contains "u", let fullUnicode be true. - // 12. Else, let fullUnicode be false. - var_unicode = FastFlagGetter(CAST(var_matcher.value()), JSRegExp::kUnicode); - Goto(&create_iterator); - } - - BIND(&if_slow_regexp); - { - // 4. Let C be ? SpeciesConstructor(R, %RegExp%). - TNode<JSFunction> regexp_fun = CAST( - LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX)); - TNode<JSReceiver> species_constructor = - SpeciesConstructor(native_context, receiver, regexp_fun); - - // 5. Let flags be ? ToString(? Get(R, "flags")). - TNode<Object> flags = - GetProperty(context, receiver, isolate()->factory()->flags_string()); - TNode<String> flags_string = ToString_Inline(context, flags); - - // 6. Let matcher be ? Construct(C, « R, flags »). - var_matcher = - Construct(context, species_constructor, receiver, flags_string); - - // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). - TNode<Number> last_index = - ToLength_Inline(context, SlowLoadLastIndex(context, receiver)); - - // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). - SlowStoreLastIndex(context, var_matcher.value(), last_index); - - // 9. If flags contains "g", let global be true. - // 10. Else, let global be false. - TNode<String> global_char_string = StringConstant("g"); - TNode<Smi> global_ix = - CAST(CallBuiltin(Builtins::kStringIndexOf, context, flags_string, - global_char_string, SmiZero())); - var_global = SmiNotEqual(global_ix, SmiConstant(-1)); - - // 11. If flags contains "u", let fullUnicode be true. - // 12. Else, let fullUnicode be false. - TNode<String> unicode_char_string = StringConstant("u"); - TNode<Smi> unicode_ix = - CAST(CallBuiltin(Builtins::kStringIndexOf, context, flags_string, - unicode_char_string, SmiZero())); - var_unicode = SmiNotEqual(unicode_ix, SmiConstant(-1)); - Goto(&create_iterator); - } - - BIND(&create_iterator); - { - { - // UseCounter for matchAll with non-g RegExp. - // https://crbug.com/v8/9551 - Label next(this); - GotoIf(var_global.value(), &next); - CallRuntime(Runtime::kIncrementUseCounter, context, - SmiConstant(v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp)); - Goto(&next); - BIND(&next); - } - - // 13. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode). - TNode<Object> iterator = - CreateRegExpStringIterator(native_context, var_matcher.value(), string, - var_global.value(), var_unicode.value()); - Return(iterator); - } -} - // ES#sec-createregexpstringiterator // CreateRegExpStringIterator ( R, S, global, fullUnicode ) TNode<Object> RegExpMatchAllAssembler::CreateRegExpStringIterator( - TNode<Context> native_context, TNode<Object> regexp, TNode<String> string, - TNode<BoolT> global, TNode<BoolT> full_unicode) { + TNode<NativeContext> native_context, TNode<Object> regexp, + TNode<String> string, TNode<BoolT> global, TNode<BoolT> full_unicode) { TNode<Map> map = CAST(LoadContextElement( native_context, Context::INITIAL_REGEXP_STRING_ITERATOR_PROTOTYPE_MAP_INDEX)); @@ -2016,164 +1764,11 @@ TNode<Object> RegExpMatchAllAssembler::CreateRegExpStringIterator( return iterator; } -// https://tc39.github.io/proposal-string-matchall/ -// RegExp.prototype [ @@matchAll ] ( string ) -TF_BUILTIN(RegExpPrototypeMatchAll, RegExpMatchAllAssembler) { - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - TNode<NativeContext> native_context = LoadNativeContext(context); - TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); - TNode<Object> maybe_string = CAST(Parameter(Descriptor::kString)); - Generate(context, native_context, receiver, maybe_string); -} - -void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodyFast( - TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string) { - CSA_ASSERT(this, IsFastRegExpPermissive(context, regexp)); - - // Grab the initial value of last index. - TNode<Smi> previous_last_index = FastLoadLastIndex(regexp); - - // Ensure last index is 0. - FastStoreLastIndex(regexp, SmiZero()); - - // Call exec. - Label if_didnotmatch(this); - TNode<RegExpMatchInfo> match_indices = RegExpPrototypeExecBodyWithoutResult( - context, regexp, string, &if_didnotmatch, true); - - // Successful match. - { - // Reset last index. - FastStoreLastIndex(regexp, previous_last_index); - - // Return the index of the match. - TNode<Object> const index = LoadFixedArrayElement( - match_indices, RegExpMatchInfo::kFirstCaptureIndex); - Return(index); - } - - BIND(&if_didnotmatch); - { - // Reset last index and return -1. - FastStoreLastIndex(regexp, previous_last_index); - Return(SmiConstant(-1)); - } -} - -void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow( - TNode<Context> context, Node* const regexp, Node* const string) { - CSA_ASSERT(this, IsJSReceiver(regexp)); - CSA_ASSERT(this, IsString(string)); - - Isolate* const isolate = this->isolate(); - - TNode<Smi> const smi_zero = SmiZero(); - - // Grab the initial value of last index. - TNode<Object> const previous_last_index = - SlowLoadLastIndex(context, CAST(regexp)); - - // Ensure last index is 0. - { - Label next(this), slow(this, Label::kDeferred); - BranchIfSameValue(previous_last_index, smi_zero, &next, &slow); - - BIND(&slow); - SlowStoreLastIndex(context, regexp, smi_zero); - Goto(&next); - BIND(&next); - } - - // Call exec. - TNode<Object> const exec_result = RegExpExec(context, regexp, string); - - // Reset last index if necessary. - { - Label next(this), slow(this, Label::kDeferred); - TNode<Object> const current_last_index = - SlowLoadLastIndex(context, CAST(regexp)); - - BranchIfSameValue(current_last_index, previous_last_index, &next, &slow); - - BIND(&slow); - SlowStoreLastIndex(context, regexp, previous_last_index); - Goto(&next); - BIND(&next); - } - - // Return -1 if no match was found. - { - Label next(this); - GotoIfNot(IsNull(exec_result), &next); - Return(SmiConstant(-1)); - BIND(&next); - } - - // Return the index of the match. - { - Label fast_result(this), slow_result(this, Label::kDeferred); - BranchIfFastRegExpResult(context, exec_result, &fast_result, &slow_result); - - BIND(&fast_result); - { - TNode<Object> const index = - LoadObjectField(CAST(exec_result), JSRegExpResult::kIndexOffset); - Return(index); - } - - BIND(&slow_result); - { - Return(GetProperty(context, exec_result, - isolate->factory()->index_string())); - } - } -} - -// ES#sec-regexp.prototype-@@search -// RegExp.prototype [ @@search ] ( string ) -TF_BUILTIN(RegExpPrototypeSearch, RegExpBuiltinsAssembler) { - TNode<Object> maybe_receiver = CAST(Parameter(Descriptor::kReceiver)); - TNode<Object> maybe_string = CAST(Parameter(Descriptor::kString)); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - // Ensure {maybe_receiver} is a JSReceiver. - ThrowIfNotJSReceiver(context, maybe_receiver, - MessageTemplate::kIncompatibleMethodReceiver, - "RegExp.prototype.@@search"); - TNode<JSReceiver> receiver = CAST(maybe_receiver); - - // Convert {maybe_string} to a String. - TNode<String> const string = ToString_Inline(context, maybe_string); - - Label fast_path(this), slow_path(this); - BranchIfFastRegExp_Permissive(context, receiver, &fast_path, &slow_path); - - BIND(&fast_path); - // TODO(pwong): Could be optimized to remove the overhead of calling the - // builtin (at the cost of a larger builtin). - Return(CallBuiltin(Builtins::kRegExpSearchFast, context, receiver, string)); - - BIND(&slow_path); - RegExpPrototypeSearchBodySlow(context, receiver, string); -} - -// Helper that skips a few initial checks. and assumes... -// 1) receiver is a "fast" RegExp -// 2) pattern is a string -TF_BUILTIN(RegExpSearchFast, RegExpBuiltinsAssembler) { - TNode<JSRegExp> receiver = CAST(Parameter(Descriptor::kReceiver)); - TNode<String> string = CAST(Parameter(Descriptor::kPattern)); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - RegExpPrototypeSearchBodyFast(context, receiver, string); -} - // Generates the fast path for @@split. {regexp} is an unmodified, non-sticky // JSRegExp, {string} is a String, and {limit} is a Smi. -void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, - TNode<JSRegExp> regexp, - TNode<String> string, - TNode<Smi> const limit) { +TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody( + TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string, + TNode<Smi> const limit) { CSA_ASSERT(this, IsFastRegExpPermissive(context, regexp)); CSA_ASSERT(this, Word32BinaryNot(FastFlagGetter(regexp, JSRegExp::kSticky))); @@ -2182,11 +1777,13 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, const ElementsKind kind = PACKED_ELEMENTS; const ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS; - Node* const allocation_site = nullptr; + TNode<AllocationSite> allocation_site = {}; TNode<NativeContext> const native_context = LoadNativeContext(context); TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context); Label return_empty_array(this, Label::kDeferred); + TVARIABLE(JSArray, var_result); + Label done(this); // If limit is zero, return an empty array. { @@ -2220,13 +1817,13 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, { TNode<Smi> length = SmiConstant(1); TNode<IntPtrT> capacity = IntPtrConstant(1); - TNode<JSArray> result = AllocateJSArray(kind, array_map, capacity, - length, allocation_site, mode); + var_result = AllocateJSArray(kind, array_map, capacity, length, + allocation_site, mode); - TNode<FixedArray> fixed_array = CAST(LoadElements(result)); + TNode<FixedArray> fixed_array = CAST(LoadElements(var_result.value())); UnsafeStoreFixedArrayElement(fixed_array, 0, string); - Return(result); + Goto(&done); } } @@ -2240,11 +1837,9 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, TVARIABLE(Smi, var_last_matched_until, SmiZero()); TVARIABLE(Smi, var_next_search_from, SmiZero()); - Variable* vars[] = {array.var_array(), array.var_length(), - array.var_capacity(), &var_last_matched_until, - &var_next_search_from}; - const int vars_count = sizeof(vars) / sizeof(vars[0]); - Label loop(this, vars_count, vars), push_suffix_and_out(this), out(this); + Label loop(this, {array.var_array(), array.var_length(), array.var_capacity(), + &var_last_matched_until, &var_next_search_from}), + push_suffix_and_out(this), out(this); Goto(&loop); BIND(&loop); @@ -2321,19 +1916,17 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, match_indices, RegExpMatchInfo::kNumberOfCapturesIndex)); TNode<IntPtrT> const int_num_registers = SmiUntag(num_registers); - VARIABLE(var_reg, MachineType::PointerRepresentation()); - var_reg.Bind(IntPtrConstant(2)); + TVARIABLE(IntPtrT, var_reg, IntPtrConstant(2)); - Variable* vars[] = {array.var_array(), array.var_length(), - array.var_capacity(), &var_reg}; - const int vars_count = sizeof(vars) / sizeof(vars[0]); - Label nested_loop(this, vars_count, vars), nested_loop_out(this); + Label nested_loop(this, {array.var_array(), array.var_length(), + array.var_capacity(), &var_reg}), + nested_loop_out(this); Branch(IntPtrLessThan(var_reg.value(), int_num_registers), &nested_loop, &nested_loop_out); BIND(&nested_loop); { - Node* const reg = var_reg.value(); + const TNode<IntPtrT> reg = var_reg.value(); TNode<Object> const from = LoadFixedArrayElement( match_indices, reg, RegExpMatchInfo::kFirstCaptureIndex * kTaggedSize, mode); @@ -2342,30 +1935,30 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, (RegExpMatchInfo::kFirstCaptureIndex + 1) * kTaggedSize, mode)); Label select_capture(this), select_undefined(this), store_value(this); - VARIABLE(var_value, MachineRepresentation::kTagged); + TVARIABLE(Object, var_value); Branch(SmiEqual(to, SmiConstant(-1)), &select_undefined, &select_capture); BIND(&select_capture); { - var_value.Bind( - CallBuiltin(Builtins::kSubString, context, string, from, to)); + var_value = + CallBuiltin(Builtins::kSubString, context, string, from, to); Goto(&store_value); } BIND(&select_undefined); { - var_value.Bind(UndefinedConstant()); + var_value = UndefinedConstant(); Goto(&store_value); } BIND(&store_value); { - array.Push(CAST(var_value.value())); + array.Push(var_value.value()); GotoIf(WordEqual(array.length(), int_limit), &out); - TNode<WordT> const new_reg = IntPtrAdd(reg, IntPtrConstant(2)); - var_reg.Bind(new_reg); + const TNode<IntPtrT> new_reg = IntPtrAdd(reg, IntPtrConstant(2)); + var_reg = new_reg; Branch(IntPtrLessThan(new_reg, int_num_registers), &nested_loop, &nested_loop_out); @@ -2382,316 +1975,29 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(TNode<Context> context, BIND(&push_suffix_and_out); { - TNode<Smi> const from = var_last_matched_until.value(); - Node* const to = string_length; + const TNode<Smi> from = var_last_matched_until.value(); + const TNode<Smi> to = string_length; array.Push(CallBuiltin(Builtins::kSubString, context, string, from, to)); Goto(&out); } BIND(&out); { - TNode<JSArray> const result = array.ToJSArray(context); - Return(result); + var_result = array.ToJSArray(context); + Goto(&done); } BIND(&return_empty_array); { TNode<Smi> length = SmiZero(); TNode<IntPtrT> capacity = IntPtrZero(); - TNode<JSArray> result = AllocateJSArray(kind, array_map, capacity, length, - allocation_site, mode); - Return(result); - } -} - -// Helper that skips a few initial checks. -TF_BUILTIN(RegExpSplit, RegExpBuiltinsAssembler) { - TNode<JSRegExp> regexp = CAST(Parameter(Descriptor::kRegExp)); - TNode<String> string = CAST(Parameter(Descriptor::kString)); - TNode<Object> maybe_limit = CAST(Parameter(Descriptor::kLimit)); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - CSA_ASSERT_BRANCH(this, [&](Label* ok, Label* not_ok) { - BranchIfFastRegExp_Strict(context, regexp, ok, not_ok); - }); - - // Verify {maybe_limit}. - - VARIABLE(var_limit, MachineRepresentation::kTagged, maybe_limit); - Label if_limitissmimax(this), runtime(this, Label::kDeferred); - - { - Label next(this); - - GotoIf(IsUndefined(maybe_limit), &if_limitissmimax); - Branch(TaggedIsPositiveSmi(maybe_limit), &next, &runtime); - - // We need to be extra-strict and require the given limit to be either - // undefined or a positive smi. We can't call ToUint32(maybe_limit) since - // that might move us onto the slow path, resulting in ordering spec - // violations (see https://crbug.com/801171). - - BIND(&if_limitissmimax); - { - // TODO(jgruber): In this case, we can probably avoid generation of limit - // checks in Generate_RegExpPrototypeSplitBody. - var_limit.Bind(SmiConstant(Smi::kMaxValue)); - Goto(&next); - } - - BIND(&next); - } - - // Due to specific shortcuts we take on the fast path (specifically, we don't - // allocate a new regexp instance as specced), we need to ensure that the - // given regexp is non-sticky to avoid invalid results. See crbug.com/v8/6706. - - GotoIf(FastFlagGetter(regexp, JSRegExp::kSticky), &runtime); - - // We're good to go on the fast path, which is inlined here. - - RegExpPrototypeSplitBody(context, regexp, string, CAST(var_limit.value())); - - BIND(&runtime); - Return(CallRuntime(Runtime::kRegExpSplit, context, regexp, string, - var_limit.value())); -} - -// ES#sec-regexp.prototype-@@split -// RegExp.prototype [ @@split ] ( string, limit ) -TF_BUILTIN(RegExpPrototypeSplit, RegExpBuiltinsAssembler) { - const int kStringArg = 0; - const int kLimitArg = 1; - - TNode<IntPtrT> argc = - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount)); - CodeStubArguments args(this, argc); - - TNode<Object> maybe_receiver = args.GetReceiver(); - TNode<Object> maybe_string = args.GetOptionalArgumentValue(kStringArg); - TNode<Object> maybe_limit = args.GetOptionalArgumentValue(kLimitArg); - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - - // Ensure {maybe_receiver} is a JSReceiver. - ThrowIfNotJSReceiver(context, maybe_receiver, - MessageTemplate::kIncompatibleMethodReceiver, - "RegExp.prototype.@@split"); - TNode<JSReceiver> receiver = CAST(maybe_receiver); - - // Convert {maybe_string} to a String. - TNode<String> string = ToString_Inline(context, maybe_string); - - // Strict: Reads the flags property. - // TODO(jgruber): Handle slow flag accesses on the fast path and make this - // permissive. - Label stub(this), runtime(this, Label::kDeferred); - BranchIfFastRegExp_Strict(context, receiver, &stub, &runtime); - - BIND(&stub); - args.PopAndReturn(CallBuiltin(Builtins::kRegExpSplit, context, receiver, - string, maybe_limit)); - - BIND(&runtime); - args.PopAndReturn(CallRuntime(Runtime::kRegExpSplit, context, receiver, - string, maybe_limit)); -} - -class RegExpStringIteratorAssembler : public RegExpBuiltinsAssembler { - public: - explicit RegExpStringIteratorAssembler(compiler::CodeAssemblerState* state) - : RegExpBuiltinsAssembler(state) {} - - protected: - TNode<Smi> LoadFlags(TNode<HeapObject> iterator) { - return LoadObjectField<Smi>(iterator, JSRegExpStringIterator::kFlagsOffset); - } - - TNode<BoolT> HasDoneFlag(TNode<Smi> flags) { - return UncheckedCast<BoolT>( - IsSetSmi(flags, 1 << JSRegExpStringIterator::kDoneBit)); - } - - TNode<BoolT> HasGlobalFlag(TNode<Smi> flags) { - return UncheckedCast<BoolT>( - IsSetSmi(flags, 1 << JSRegExpStringIterator::kGlobalBit)); - } - - TNode<BoolT> HasUnicodeFlag(TNode<Smi> flags) { - return UncheckedCast<BoolT>( - IsSetSmi(flags, 1 << JSRegExpStringIterator::kUnicodeBit)); - } - - void SetDoneFlag(TNode<HeapObject> iterator, TNode<Smi> flags) { - TNode<Smi> new_flags = - SmiOr(flags, SmiConstant(1 << JSRegExpStringIterator::kDoneBit)); - StoreObjectFieldNoWriteBarrier( - iterator, JSRegExpStringIterator::kFlagsOffset, new_flags); - } -}; - -// https://tc39.github.io/proposal-string-matchall/ -// %RegExpStringIteratorPrototype%.next ( ) -TF_BUILTIN(RegExpStringIteratorPrototypeNext, RegExpStringIteratorAssembler) { - const char* method_name = "%RegExpStringIterator%.prototype.next"; - TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - TNode<Object> maybe_receiver = CAST(Parameter(Descriptor::kReceiver)); - - Label if_match(this), if_no_match(this, Label::kDeferred), - return_empty_done_result(this, Label::kDeferred); - - // 1. Let O be the this value. - // 2. If Type(O) is not Object, throw a TypeError exception. - // 3. If O does not have all of the internal slots of a RegExp String Iterator - // Object Instance (see 5.3), throw a TypeError exception. - ThrowIfNotInstanceType(context, maybe_receiver, - JS_REGEXP_STRING_ITERATOR_TYPE, method_name); - TNode<HeapObject> receiver = CAST(maybe_receiver); - - // 4. If O.[[Done]] is true, then - // a. Return ! CreateIterResultObject(undefined, true). - TNode<Smi> flags = LoadFlags(receiver); - GotoIf(HasDoneFlag(flags), &return_empty_done_result); - - // 5. Let R be O.[[IteratingRegExp]]. - TNode<JSReceiver> iterating_regexp = CAST(LoadObjectField( - receiver, JSRegExpStringIterator::kIteratingRegExpOffset)); - - // For extra safety, also check the type in release mode. - CSA_CHECK(this, IsJSReceiver(iterating_regexp)); - - // 6. Let S be O.[[IteratedString]]. - TNode<String> iterating_string = CAST( - LoadObjectField(receiver, JSRegExpStringIterator::kIteratedStringOffset)); - - // 7. Let global be O.[[Global]]. - // See if_match. - - // 8. Let fullUnicode be O.[[Unicode]]. - // See if_global. - - // 9. Let match be ? RegExpExec(R, S). - TVARIABLE(Object, var_match); - TVARIABLE(BoolT, var_is_fast_regexp); - { - Label if_fast(this), if_slow(this, Label::kDeferred); - BranchIfFastRegExp_Permissive(context, iterating_regexp, &if_fast, - &if_slow); - - BIND(&if_fast); - { - TNode<RegExpMatchInfo> match_indices = - RegExpPrototypeExecBodyWithoutResult( - context, iterating_regexp, iterating_string, &if_no_match, true); - var_match = ConstructNewResultFromMatchInfo( - context, iterating_regexp, match_indices, iterating_string); - var_is_fast_regexp = Int32TrueConstant(); - Goto(&if_match); - } - - BIND(&if_slow); - { - var_match = RegExpExec(context, iterating_regexp, iterating_string); - var_is_fast_regexp = Int32FalseConstant(); - Branch(IsNull(var_match.value()), &if_no_match, &if_match); - } - } - - // 10. If match is null, then - BIND(&if_no_match); - { - // a. Set O.[[Done]] to true. - SetDoneFlag(receiver, flags); - - // b. Return ! CreateIterResultObject(undefined, true). - Goto(&return_empty_done_result); + var_result = AllocateJSArray(kind, array_map, capacity, length, + allocation_site, mode); + Goto(&done); } - // 11. Else, - BIND(&if_match); - { - Label if_global(this), if_not_global(this, Label::kDeferred), - return_result(this); - - // a. If global is true, - Branch(HasGlobalFlag(flags), &if_global, &if_not_global); - BIND(&if_global); - { - Label if_fast(this), if_slow(this, Label::kDeferred); - // ii. If matchStr is the empty string, - Branch(var_is_fast_regexp.value(), &if_fast, &if_slow); - BIND(&if_fast); - { - // i. Let matchStr be ? ToString(? Get(match, "0")). - CSA_ASSERT_BRANCH(this, [&](Label* ok, Label* not_ok) { - BranchIfFastRegExpResult(context, var_match.value(), ok, not_ok); - }); - CSA_ASSERT(this, - SmiNotEqual(LoadFastJSArrayLength(CAST(var_match.value())), - SmiZero())); - TNode<FixedArray> result_fixed_array = - CAST(LoadElements(CAST(var_match.value()))); - TNode<String> match_str = - CAST(LoadFixedArrayElement(result_fixed_array, 0)); - - // When iterating_regexp is fast, we assume it stays fast even after - // accessing the first match from the RegExp result. - CSA_ASSERT(this, IsFastRegExpPermissive(context, iterating_regexp)); - GotoIfNot(IsEmptyString(match_str), &return_result); - - // 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")). - TNode<Smi> this_index = FastLoadLastIndex(CAST(iterating_regexp)); - - // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). - TNode<Smi> next_index = AdvanceStringIndexFast( - iterating_string, this_index, HasUnicodeFlag(flags)); - - // 3. Perform ? Set(R, "lastIndex", nextIndex, true). - FastStoreLastIndex(CAST(iterating_regexp), next_index); - - // iii. Return ! CreateIterResultObject(match, false). - Goto(&return_result); - } - BIND(&if_slow); - { - // i. Let matchStr be ? ToString(? Get(match, "0")). - TNode<String> match_str = ToString_Inline( - context, GetProperty(context, var_match.value(), SmiZero())); - - GotoIfNot(IsEmptyString(match_str), &return_result); - - // 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")). - TNode<Object> last_index = SlowLoadLastIndex(context, iterating_regexp); - TNode<Number> this_index = ToLength_Inline(context, last_index); - - // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, fullUnicode). - TNode<Number> next_index = AdvanceStringIndex( - iterating_string, this_index, HasUnicodeFlag(flags), false); - - // 3. Perform ? Set(R, "lastIndex", nextIndex, true). - SlowStoreLastIndex(context, iterating_regexp, next_index); - - // iii. Return ! CreateIterResultObject(match, false). - Goto(&return_result); - } - } - // b. Else, - BIND(&if_not_global); - { - // i. Set O.[[Done]] to true. - SetDoneFlag(receiver, flags); - - // ii. Return ! CreateIterResultObject(match, false). - Goto(&return_result); - } - BIND(&return_result); - { - Return(AllocateJSIteratorResult(context, var_match.value(), - FalseConstant())); - } - } - BIND(&return_empty_done_result); - Return( - AllocateJSIteratorResult(context, UndefinedConstant(), TrueConstant())); + BIND(&done); + return var_result.value(); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-regexp-gen.h b/deps/v8/src/builtins/builtins-regexp-gen.h index de841f57b292f0..c6de458ef2a2d9 100644 --- a/deps/v8/src/builtins/builtins-regexp-gen.h +++ b/deps/v8/src/builtins/builtins-regexp-gen.h @@ -25,8 +25,6 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { TNode<Object> RegExpCreate(TNode<Context> context, TNode<Map> initial_map, TNode<Object> regexp_string, TNode<String> flags); - TNode<BoolT> IsRegExp(TNode<Context> context, TNode<Object> maybe_receiver); - TNode<Smi> SmiZero(); TNode<IntPtrT> IntPtrZero(); @@ -37,7 +35,8 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { // and input string. TNode<JSRegExpResult> AllocateRegExpResult( TNode<Context> context, TNode<Smi> length, TNode<Smi> index, - TNode<String> input, TNode<FixedArray>* elements_out = nullptr); + TNode<String> input, TNode<RegExpMatchInfo> match_info, + TNode<FixedArray>* elements_out = nullptr); TNode<Object> FastLoadLastIndexBeforeSmiCheck(TNode<JSRegExp> regexp); TNode<Smi> FastLoadLastIndex(TNode<JSRegExp> regexp) { @@ -56,10 +55,12 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { // Loads {var_string_start} and {var_string_end} with the corresponding // offsets into the given {string_data}. - void GetStringPointers(Node* const string_data, Node* const offset, - Node* const last_index, Node* const string_length, - String::Encoding encoding, Variable* var_string_start, - Variable* var_string_end); + void GetStringPointers(TNode<RawPtrT> string_data, TNode<IntPtrT> offset, + TNode<IntPtrT> last_index, + TNode<IntPtrT> string_length, + String::Encoding encoding, + TVariable<RawPtrT>* var_string_start, + TVariable<RawPtrT>* var_string_end); // Low level logic around the actual call into pattern matching code. TNode<HeapObject> RegExpExecInternal(TNode<Context> context, @@ -136,17 +137,17 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { // Performs fast path checks on the given object itself, but omits prototype // checks. - Node* IsFastRegExpNoPrototype(SloppyTNode<Context> context, - SloppyTNode<Object> object); - Node* IsFastRegExpNoPrototype(SloppyTNode<Context> context, - SloppyTNode<Object> object, - SloppyTNode<Map> map); + TNode<BoolT> IsFastRegExpNoPrototype(TNode<Context> context, + TNode<Object> object); + TNode<BoolT> IsFastRegExpNoPrototype(TNode<Context> context, + TNode<Object> object, TNode<Map> map); // For debugging only. Uses a slow GetProperty call to fetch object.exec. TNode<BoolT> IsFastRegExpWithOriginalExec(TNode<Context> context, TNode<JSRegExp> object); - void BranchIfFastRegExpResult(Node* const context, Node* const object, + void BranchIfFastRegExpResult(const TNode<Context> context, + const TNode<Object> object, Label* if_isunmodified, Label* if_ismodified); TNode<String> FlagsGetter(TNode<Context> context, TNode<Object> regexp, @@ -164,10 +165,10 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { TNode<BoolT> FlagGetter(TNode<Context> context, TNode<Object> regexp, JSRegExp::Flag flag, bool is_fastpath); - Node* RegExpInitialize(Node* const context, Node* const regexp, - Node* const maybe_pattern, Node* const maybe_flags); - - TNode<Object> RegExpExec(TNode<Context> context, Node* regexp, Node* string); + TNode<Object> RegExpInitialize(const TNode<Context> context, + const TNode<JSRegExp> regexp, + const TNode<Object> maybe_pattern, + const TNode<Object> maybe_flags); TNode<Number> AdvanceStringIndex(SloppyTNode<String> string, SloppyTNode<Number> index, @@ -179,20 +180,20 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { return CAST(AdvanceStringIndex(string, index, is_unicode, true)); } + TNode<Smi> AdvanceStringIndexSlow(TNode<String> string, TNode<Number> index, + TNode<BoolT> is_unicode) { + return CAST(AdvanceStringIndex(string, index, is_unicode, false)); + } + TNode<Object> RegExpPrototypeMatchBody(TNode<Context> context, TNode<Object> regexp, TNode<String> const string, const bool is_fastpath); - void RegExpPrototypeSearchBodyFast(TNode<Context> context, - TNode<JSRegExp> regexp, - TNode<String> string); - void RegExpPrototypeSearchBodySlow(TNode<Context> context, Node* const regexp, - Node* const string); - - void RegExpPrototypeSplitBody(TNode<Context> context, TNode<JSRegExp> regexp, - TNode<String> const string, - TNode<Smi> const limit); + TNode<JSArray> RegExpPrototypeSplitBody(TNode<Context> context, + TNode<JSRegExp> regexp, + TNode<String> const string, + TNode<Smi> const limit); }; class RegExpMatchAllAssembler : public RegExpBuiltinsAssembler { @@ -200,13 +201,11 @@ class RegExpMatchAllAssembler : public RegExpBuiltinsAssembler { explicit RegExpMatchAllAssembler(compiler::CodeAssemblerState* state) : RegExpBuiltinsAssembler(state) {} - TNode<Object> CreateRegExpStringIterator(TNode<Context> native_context, + TNode<Object> CreateRegExpStringIterator(TNode<NativeContext> native_context, TNode<Object> regexp, TNode<String> string, TNode<BoolT> global, TNode<BoolT> full_unicode); - void Generate(TNode<Context> context, TNode<Context> native_context, - TNode<Object> receiver, TNode<Object> maybe_string); }; } // namespace internal diff --git a/deps/v8/src/builtins/builtins-sharedarraybuffer-gen.cc b/deps/v8/src/builtins/builtins-sharedarraybuffer-gen.cc index 8ae89187ecbc67..85cb4f10f77ce3 100644 --- a/deps/v8/src/builtins/builtins-sharedarraybuffer-gen.cc +++ b/deps/v8/src/builtins/builtins-sharedarraybuffer-gen.cc @@ -11,8 +11,6 @@ namespace v8 { namespace internal { using compiler::Node; -template <typename T> -using TNode = compiler::TNode<T>; class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler { public: @@ -255,7 +253,7 @@ TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) { GotoIf(Int32GreaterThan(elements_kind, Int32Constant(INT32_ELEMENTS)), &u64); TNode<Number> value_integer = ToInteger_Inline(CAST(context), CAST(value)); - Node* value_word32 = TruncateTaggedToWord32(context, value_integer); + TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer); #if DEBUG DebugSanityCheckAtomicIndex(array, index_word32, context); @@ -338,7 +336,7 @@ TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) { #if DEBUG DebugSanityCheckAtomicIndex(array, index_word32, context); #endif - Node* value_word32 = TruncateTaggedToWord32(context, value_integer); + TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer); int32_t case_values[] = { INT8_ELEMENTS, UINT8_ELEMENTS, INT16_ELEMENTS, @@ -444,8 +442,10 @@ TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) { #if DEBUG DebugSanityCheckAtomicIndex(array, index_word32, context); #endif - Node* old_value_word32 = TruncateTaggedToWord32(context, old_value_integer); - Node* new_value_word32 = TruncateTaggedToWord32(context, new_value_integer); + TNode<Word32T> old_value_word32 = + TruncateTaggedToWord32(context, old_value_integer); + TNode<Word32T> new_value_word32 = + TruncateTaggedToWord32(context, new_value_integer); int32_t case_values[] = { INT8_ELEMENTS, UINT8_ELEMENTS, INT16_ELEMENTS, @@ -571,7 +571,7 @@ void SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon( #if DEBUG DebugSanityCheckAtomicIndex(array, index_word32, context); #endif - Node* value_word32 = TruncateTaggedToWord32(context, value_integer); + TNode<Word32T> value_word32 = TruncateTaggedToWord32(context, value_integer); int32_t case_values[] = { INT8_ELEMENTS, UINT8_ELEMENTS, INT16_ELEMENTS, diff --git a/deps/v8/src/builtins/builtins-string-gen.cc b/deps/v8/src/builtins/builtins-string-gen.cc index fc2745ed0a4ae5..425ffc46d29bc9 100644 --- a/deps/v8/src/builtins/builtins-string-gen.cc +++ b/deps/v8/src/builtins/builtins-string-gen.cc @@ -8,8 +8,10 @@ #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" #include "src/codegen/code-factory.h" +#include "src/execution/protectors.h" #include "src/heap/factory-inl.h" #include "src/heap/heap-inl.h" +#include "src/logging/counters.h" #include "src/objects/objects.h" #include "src/objects/property-cell.h" @@ -17,8 +19,6 @@ namespace v8 { namespace internal { using Node = compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; Node* StringBuiltinsAssembler::DirectStringData(Node* string, Node* string_instance_type) { @@ -120,14 +120,14 @@ Node* StringBuiltinsAssembler::CallSearchStringRaw(Node* const subject_ptr, return result; } -TNode<IntPtrT> StringBuiltinsAssembler::PointerToStringDataAtIndex( - Node* const string_data, Node* const index, String::Encoding encoding) { +TNode<RawPtrT> StringBuiltinsAssembler::PointerToStringDataAtIndex( + TNode<RawPtrT> string_data, TNode<IntPtrT> index, + String::Encoding encoding) { const ElementsKind kind = (encoding == String::ONE_BYTE_ENCODING) ? UINT8_ELEMENTS : UINT16_ELEMENTS; - TNode<IntPtrT> const offset_in_bytes = - ElementOffsetFromIndex(index, kind, INTPTR_PARAMETERS); - return Signed(IntPtrAdd(string_data, offset_in_bytes)); + TNode<IntPtrT> offset_in_bytes = ElementOffsetFromIndex(index, kind); + return RawPtrAdd(string_data, offset_in_bytes); } void StringBuiltinsAssembler::GenerateStringEqual(TNode<String> left, @@ -289,6 +289,262 @@ void StringBuiltinsAssembler::StringEqual_Loop( } } +TNode<String> StringBuiltinsAssembler::StringFromSingleUTF16EncodedCodePoint( + TNode<Int32T> codepoint) { + VARIABLE(var_result, MachineRepresentation::kTagged, EmptyStringConstant()); + + Label if_isword16(this), if_isword32(this), return_result(this); + + Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, + &if_isword32); + + BIND(&if_isword16); + { + var_result.Bind(StringFromSingleCharCode(codepoint)); + Goto(&return_result); + } + + BIND(&if_isword32); + { + TNode<String> value = AllocateSeqTwoByteString(2); + StoreNoWriteBarrier( + MachineRepresentation::kWord32, value, + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), + codepoint); + var_result.Bind(value); + Goto(&return_result); + } + + BIND(&return_result); + return CAST(var_result.value()); +} + +TNode<String> StringBuiltinsAssembler::AllocateConsString(TNode<Uint32T> length, + TNode<String> left, + TNode<String> right) { + // Added string can be a cons string. + Comment("Allocating ConsString"); + TNode<Int32T> left_instance_type = LoadInstanceType(left); + TNode<Int32T> right_instance_type = LoadInstanceType(right); + + // Determine the resulting ConsString map to use depending on whether + // any of {left} or {right} has two byte encoding. + STATIC_ASSERT(kOneByteStringTag != 0); + STATIC_ASSERT(kTwoByteStringTag == 0); + TNode<Int32T> combined_instance_type = + Word32And(left_instance_type, right_instance_type); + TNode<Map> result_map = CAST(Select<Object>( + IsSetWord32(combined_instance_type, kStringEncodingMask), + [=] { return ConsOneByteStringMapConstant(); }, + [=] { return ConsStringMapConstant(); })); + TNode<HeapObject> result = AllocateInNewSpace(ConsString::kSize); + StoreMapNoWriteBarrier(result, result_map); + StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, + MachineRepresentation::kWord32); + StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, + Int32Constant(String::kEmptyHashField), + MachineRepresentation::kWord32); + StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, left); + StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, right); + return CAST(result); +} + +TNode<String> StringBuiltinsAssembler::StringAdd(Node* context, + TNode<String> left, + TNode<String> right) { + TVARIABLE(String, result); + Label check_right(this), runtime(this, Label::kDeferred), cons(this), + done(this, &result), done_native(this, &result); + Counters* counters = isolate()->counters(); + + TNode<Uint32T> left_length = LoadStringLengthAsWord32(left); + GotoIfNot(Word32Equal(left_length, Uint32Constant(0)), &check_right); + result = right; + Goto(&done_native); + + BIND(&check_right); + TNode<Uint32T> right_length = LoadStringLengthAsWord32(right); + GotoIfNot(Word32Equal(right_length, Uint32Constant(0)), &cons); + result = left; + Goto(&done_native); + + BIND(&cons); + { + TNode<Uint32T> new_length = Uint32Add(left_length, right_length); + + // If new length is greater than String::kMaxLength, goto runtime to + // throw. Note: we also need to invalidate the string length protector, so + // can't just throw here directly. + GotoIf(Uint32GreaterThan(new_length, Uint32Constant(String::kMaxLength)), + &runtime); + + TVARIABLE(String, var_left, left); + TVARIABLE(String, var_right, right); + Variable* input_vars[2] = {&var_left, &var_right}; + Label non_cons(this, 2, input_vars); + Label slow(this, Label::kDeferred); + GotoIf(Uint32LessThan(new_length, Uint32Constant(ConsString::kMinLength)), + &non_cons); + + result = + AllocateConsString(new_length, var_left.value(), var_right.value()); + Goto(&done_native); + + BIND(&non_cons); + + Comment("Full string concatenate"); + TNode<Int32T> left_instance_type = LoadInstanceType(var_left.value()); + TNode<Int32T> right_instance_type = LoadInstanceType(var_right.value()); + // Compute intersection and difference of instance types. + + TNode<Int32T> ored_instance_types = + Word32Or(left_instance_type, right_instance_type); + TNode<Word32T> xored_instance_types = + Word32Xor(left_instance_type, right_instance_type); + + // Check if both strings have the same encoding and both are sequential. + GotoIf(IsSetWord32(xored_instance_types, kStringEncodingMask), &runtime); + GotoIf(IsSetWord32(ored_instance_types, kStringRepresentationMask), &slow); + + TNode<IntPtrT> word_left_length = Signed(ChangeUint32ToWord(left_length)); + TNode<IntPtrT> word_right_length = Signed(ChangeUint32ToWord(right_length)); + + Label two_byte(this); + GotoIf(Word32Equal(Word32And(ored_instance_types, + Int32Constant(kStringEncodingMask)), + Int32Constant(kTwoByteStringTag)), + &two_byte); + // One-byte sequential string case + result = AllocateSeqOneByteString(new_length); + CopyStringCharacters(var_left.value(), result.value(), IntPtrConstant(0), + IntPtrConstant(0), word_left_length, + String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING); + CopyStringCharacters(var_right.value(), result.value(), IntPtrConstant(0), + word_left_length, word_right_length, + String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING); + Goto(&done_native); + + BIND(&two_byte); + { + // Two-byte sequential string case + result = AllocateSeqTwoByteString(new_length); + CopyStringCharacters(var_left.value(), result.value(), IntPtrConstant(0), + IntPtrConstant(0), word_left_length, + String::TWO_BYTE_ENCODING, + String::TWO_BYTE_ENCODING); + CopyStringCharacters(var_right.value(), result.value(), IntPtrConstant(0), + word_left_length, word_right_length, + String::TWO_BYTE_ENCODING, + String::TWO_BYTE_ENCODING); + Goto(&done_native); + } + + BIND(&slow); + { + // Try to unwrap indirect strings, restart the above attempt on success. + MaybeDerefIndirectStrings(&var_left, left_instance_type, &var_right, + right_instance_type, &non_cons); + Goto(&runtime); + } + } + BIND(&runtime); + { + result = CAST(CallRuntime(Runtime::kStringAdd, context, left, right)); + Goto(&done); + } + + BIND(&done_native); + { + IncrementCounter(counters->string_add_native(), 1); + Goto(&done); + } + + BIND(&done); + return result.value(); +} + +void StringBuiltinsAssembler::BranchIfCanDerefIndirectString( + TNode<String> string, TNode<Int32T> instance_type, Label* can_deref, + Label* cannot_deref) { + TNode<Int32T> representation = + Word32And(instance_type, Int32Constant(kStringRepresentationMask)); + GotoIf(Word32Equal(representation, Int32Constant(kThinStringTag)), can_deref); + GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)), + cannot_deref); + // Cons string. + TNode<String> rhs = + LoadObjectField<String>(string, ConsString::kSecondOffset); + GotoIf(IsEmptyString(rhs), can_deref); + Goto(cannot_deref); +} + +void StringBuiltinsAssembler::DerefIndirectString(TVariable<String>* var_string, + TNode<Int32T> instance_type) { +#ifdef DEBUG + Label can_deref(this), cannot_deref(this); + BranchIfCanDerefIndirectString(var_string->value(), instance_type, &can_deref, + &cannot_deref); + BIND(&cannot_deref); + DebugBreak(); // Should be able to dereference string. + Goto(&can_deref); + BIND(&can_deref); +#endif // DEBUG + + STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) == + static_cast<int>(ConsString::kFirstOffset)); + *var_string = + LoadObjectField<String>(var_string->value(), ThinString::kActualOffset); +} + +void StringBuiltinsAssembler::MaybeDerefIndirectString( + TVariable<String>* var_string, TNode<Int32T> instance_type, + Label* did_deref, Label* cannot_deref) { + Label deref(this); + BranchIfCanDerefIndirectString(var_string->value(), instance_type, &deref, + cannot_deref); + + BIND(&deref); + { + DerefIndirectString(var_string, instance_type); + Goto(did_deref); + } +} + +void StringBuiltinsAssembler::MaybeDerefIndirectStrings( + TVariable<String>* var_left, TNode<Int32T> left_instance_type, + TVariable<String>* var_right, TNode<Int32T> right_instance_type, + Label* did_something) { + Label did_nothing_left(this), did_something_left(this), + didnt_do_anything(this); + MaybeDerefIndirectString(var_left, left_instance_type, &did_something_left, + &did_nothing_left); + + BIND(&did_something_left); + { + MaybeDerefIndirectString(var_right, right_instance_type, did_something, + did_something); + } + + BIND(&did_nothing_left); + { + MaybeDerefIndirectString(var_right, right_instance_type, did_something, + &didnt_do_anything); + } + + BIND(&didnt_do_anything); + // Fall through if neither string was an indirect string. +} + +TNode<String> StringBuiltinsAssembler::DerefIndirectString( + TNode<String> string, TNode<Int32T> instance_type, Label* cannot_deref) { + Label deref(this); + BranchIfCanDerefIndirectString(string, instance_type, &deref, cannot_deref); + BIND(&deref); + STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) == + static_cast<int>(ConsString::kFirstOffset)); + return LoadObjectField<String>(string, ThinString::kActualOffset); +} + TF_BUILTIN(StringAdd_CheckNone, StringBuiltinsAssembler) { TNode<String> left = CAST(Parameter(Descriptor::kLeft)); TNode<String> right = CAST(Parameter(Descriptor::kRight)); @@ -504,19 +760,6 @@ TF_BUILTIN(StringGreaterThanOrEqual, StringBuiltinsAssembler) { Operation::kGreaterThanOrEqual); } -TF_BUILTIN(StringCharAt, StringBuiltinsAssembler) { - TNode<String> receiver = CAST(Parameter(Descriptor::kReceiver)); - TNode<IntPtrT> position = - UncheckedCast<IntPtrT>(Parameter(Descriptor::kPosition)); - - // Load the character code at the {position} from the {receiver}. - TNode<Int32T> code = StringCharCodeAt(receiver, position); - - // And return the single character string with only that {code} - TNode<String> result = StringFromSingleCharCode(code); - Return(result); -} - TF_BUILTIN(StringCodePointAt, StringBuiltinsAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); Node* position = Parameter(Descriptor::kPosition); @@ -551,14 +794,14 @@ TF_BUILTIN(StringFromCodePointAt, StringBuiltinsAssembler) { // ES6 section 21.1 String Objects // ES6 #sec-string.fromcharcode -TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { +TF_BUILTIN(StringFromCharCode, StringBuiltinsAssembler) { // TODO(ishell): use constants from Descriptor once the JSFunction linkage // arguments are reordered. TNode<Int32T> argc = UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); Node* context = Parameter(Descriptor::kContext); - CodeStubArguments arguments(this, ChangeInt32ToIntPtr(argc)); + CodeStubArguments arguments(this, argc); // Check if we have exactly one argument (plus the implicit receiver), i.e. // if the parent frame is not an arguments adaptor frame. Label if_oneargument(this), if_notoneargument(this); @@ -571,7 +814,7 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { // for one-byte code units, or fall back to creating a single character // string on the fly otherwise. TNode<Object> code = arguments.AtIndex(0); - Node* code32 = TruncateTaggedToWord32(context, code); + TNode<Word32T> code32 = TruncateTaggedToWord32(context, code); TNode<Int32T> code16 = Signed(Word32And(code32, Int32Constant(String::kMaxUtf16CodeUnit))); TNode<String> result = StringFromSingleCharCode(code16); @@ -585,16 +828,14 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { // Assume that the resulting string contains only one-byte characters. TNode<String> one_byte_result = AllocateSeqOneByteString(Unsigned(argc)); - TVARIABLE(IntPtrT, var_max_index); - var_max_index = IntPtrConstant(0); + TVARIABLE(IntPtrT, var_max_index, IntPtrConstant(0)); // Iterate over the incoming arguments, converting them to 8-bit character // codes. Stop if any of the conversions generates a code that doesn't fit // in 8 bits. CodeStubAssembler::VariableList vars({&var_max_index}, zone()); - arguments.ForEach(vars, [this, context, &two_byte, &var_max_index, &code16, - one_byte_result](Node* arg) { - Node* code32 = TruncateTaggedToWord32(context, arg); + arguments.ForEach(vars, [&](TNode<Object> arg) { + TNode<Word32T> code32 = TruncateTaggedToWord32(context, arg); code16 = Word32And(code32, Int32Constant(String::kMaxUtf16CodeUnit)); GotoIf( @@ -604,7 +845,6 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { // The {code16} fits into the SeqOneByteString {one_byte_result}. TNode<IntPtrT> offset = ElementOffsetFromIndex( var_max_index.value(), UINT8_ELEMENTS, - CodeStubAssembler::INTPTR_PARAMETERS, SeqOneByteString::kHeaderSize - kHeapObjectTag); StoreNoWriteBarrier(MachineRepresentation::kWord8, one_byte_result, offset, code16); @@ -629,7 +869,6 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { // Write the character that caused the 8-bit to 16-bit fault. TNode<IntPtrT> max_index_offset = ElementOffsetFromIndex(var_max_index.value(), UINT16_ELEMENTS, - CodeStubAssembler::INTPTR_PARAMETERS, SeqTwoByteString::kHeaderSize - kHeapObjectTag); StoreNoWriteBarrier(MachineRepresentation::kWord16, two_byte_result, max_index_offset, code16); @@ -640,14 +879,13 @@ TF_BUILTIN(StringFromCharCode, CodeStubAssembler) { // using a 16-bit representation. arguments.ForEach( vars, - [this, context, two_byte_result, &var_max_index](Node* arg) { - Node* code32 = TruncateTaggedToWord32(context, arg); + [&](TNode<Object> arg) { + TNode<Word32T> code32 = TruncateTaggedToWord32(context, arg); TNode<Word32T> code16 = Word32And(code32, Int32Constant(String::kMaxUtf16CodeUnit)); TNode<IntPtrT> offset = ElementOffsetFromIndex( var_max_index.value(), UINT16_ELEMENTS, - CodeStubAssembler::INTPTR_PARAMETERS, SeqTwoByteString::kHeaderSize - kHeapObjectTag); StoreNoWriteBarrier(MachineRepresentation::kWord16, two_byte_result, offset, code16); @@ -723,9 +961,9 @@ void StringBuiltinsAssembler::StringIndexOf( BIND(&one_one); { - TNode<IntPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( subject_ptr, subject_offset, String::ONE_BYTE_ENCODING); - TNode<IntPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( search_ptr, search_offset, String::ONE_BYTE_ENCODING); Label direct_memchr_call(this), generic_fast_path(this); @@ -736,8 +974,8 @@ void StringBuiltinsAssembler::StringIndexOf( // search strings. BIND(&direct_memchr_call); { - TNode<IntPtrT> const string_addr = - IntPtrAdd(adjusted_subject_ptr, start_position); + TNode<RawPtrT> const string_addr = + RawPtrAdd(adjusted_subject_ptr, start_position); TNode<IntPtrT> const search_length = IntPtrSub(subject_length, start_position); TNode<IntPtrT> const search_byte = @@ -745,14 +983,14 @@ void StringBuiltinsAssembler::StringIndexOf( TNode<ExternalReference> const memchr = ExternalConstant(ExternalReference::libc_memchr_function()); - TNode<IntPtrT> const result_address = UncheckedCast<IntPtrT>( + TNode<RawPtrT> const result_address = UncheckedCast<RawPtrT>( CallCFunction(memchr, MachineType::Pointer(), std::make_pair(MachineType::Pointer(), string_addr), std::make_pair(MachineType::IntPtr(), search_byte), std::make_pair(MachineType::UintPtr(), search_length))); GotoIf(WordEqual(result_address, int_zero), &return_minus_1); TNode<IntPtrT> const result_index = - IntPtrAdd(IntPtrSub(result_address, string_addr), start_position); + IntPtrAdd(RawPtrSub(result_address, string_addr), start_position); f_return(SmiTag(result_index)); } @@ -767,9 +1005,9 @@ void StringBuiltinsAssembler::StringIndexOf( BIND(&one_two); { - TNode<IntPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( subject_ptr, subject_offset, String::ONE_BYTE_ENCODING); - TNode<IntPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( search_ptr, search_offset, String::TWO_BYTE_ENCODING); Node* const result = CallSearchStringRaw<onebyte_t, twobyte_t>( @@ -780,9 +1018,9 @@ void StringBuiltinsAssembler::StringIndexOf( BIND(&two_one); { - TNode<IntPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( subject_ptr, subject_offset, String::TWO_BYTE_ENCODING); - TNode<IntPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( search_ptr, search_offset, String::ONE_BYTE_ENCODING); Node* const result = CallSearchStringRaw<twobyte_t, onebyte_t>( @@ -793,9 +1031,9 @@ void StringBuiltinsAssembler::StringIndexOf( BIND(&two_two); { - TNode<IntPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_subject_ptr = PointerToStringDataAtIndex( subject_ptr, subject_offset, String::TWO_BYTE_ENCODING); - TNode<IntPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( + TNode<RawPtrT> const adjusted_search_ptr = PointerToStringDataAtIndex( search_ptr, search_offset, String::TWO_BYTE_ENCODING); Node* const result = CallSearchStringRaw<twobyte_t, twobyte_t>( @@ -1300,8 +1538,8 @@ TF_BUILTIN(StringPrototypeMatchAll, StringBuiltinsAssembler) { // maybe_regexp is a fast regexp and receiver is a string. TNode<String> s = CAST(receiver); - RegExpMatchAllAssembler regexp_asm(state()); - regexp_asm.Generate(context, native_context, maybe_regexp, s); + Return( + RegExpPrototypeMatchAllImpl(context, native_context, maybe_regexp, s)); }; auto if_generic_call = [=](Node* fn) { Callable call_callable = CodeFactory::Call(isolate()); @@ -1368,9 +1606,9 @@ TNode<JSArray> StringBuiltinsAssembler::StringToArray( TNode<IntPtrT> string_data_offset = to_direct.offset(); TNode<FixedArray> cache = SingleCharacterStringCacheConstant(); - BuildFastLoop( + BuildFastLoop<IntPtrT>( IntPtrConstant(0), length, - [&](Node* index) { + [&](TNode<IntPtrT> index) { // TODO(jkummerow): Implement a CSA version of DisallowHeapAllocation // and use that to guard ToDirectStringAssembler.PointerToData(). CSA_ASSERT(this, WordEqual(to_direct.PointerToData(&call_runtime), @@ -1387,7 +1625,7 @@ TNode<JSArray> StringBuiltinsAssembler::StringToArray( StoreFixedArrayElement(elements, index, entry); }, - 1, ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + 1, IndexAdvanceMode::kPost); TNode<Map> array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, context); result_array = AllocateJSArray(array_map, elements, length_smi); @@ -1614,7 +1852,7 @@ TF_BUILTIN(StringPrototypeSubstr, StringBuiltinsAssembler) { } } -TF_BUILTIN(StringSubstring, CodeStubAssembler) { +TF_BUILTIN(StringSubstring, StringBuiltinsAssembler) { TNode<String> string = CAST(Parameter(Descriptor::kString)); TNode<IntPtrT> from = UncheckedCast<IntPtrT>(Parameter(Descriptor::kFrom)); TNode<IntPtrT> to = UncheckedCast<IntPtrT>(Parameter(Descriptor::kTo)); @@ -1870,9 +2108,248 @@ void StringBuiltinsAssembler::BranchIfStringPrimitiveWithNoCustomIteration( DCHECK(isolate()->heap()->string_iterator_protector().IsPropertyCell()); Branch( TaggedEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorValid)), + SmiConstant(Protectors::kProtectorValid)), if_true, if_false); } +void StringBuiltinsAssembler::CopyStringCharacters( + Node* from_string, Node* to_string, TNode<IntPtrT> from_index, + TNode<IntPtrT> to_index, TNode<IntPtrT> character_count, + String::Encoding from_encoding, String::Encoding to_encoding) { + // Cannot assert IsString(from_string) and IsString(to_string) here because + // SubString can pass in faked sequential strings when handling external + // subject strings. + bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; + bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; + DCHECK_IMPLIES(to_one_byte, from_one_byte); + Comment("CopyStringCharacters ", + from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", " -> ", + to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); + + ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; + ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; + STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); + int header_size = SeqOneByteString::kHeaderSize - kHeapObjectTag; + TNode<IntPtrT> from_offset = + ElementOffsetFromIndex(from_index, from_kind, header_size); + TNode<IntPtrT> to_offset = + ElementOffsetFromIndex(to_index, to_kind, header_size); + TNode<IntPtrT> byte_count = + ElementOffsetFromIndex(character_count, from_kind); + TNode<IntPtrT> limit_offset = IntPtrAdd(from_offset, byte_count); + + // Prepare the fast loop + MachineType type = + from_one_byte ? MachineType::Uint8() : MachineType::Uint16(); + MachineRepresentation rep = to_one_byte ? MachineRepresentation::kWord8 + : MachineRepresentation::kWord16; + int from_increment = 1 << ElementsKindToShiftSize(from_kind); + int to_increment = 1 << ElementsKindToShiftSize(to_kind); + + TVARIABLE(IntPtrT, current_to_offset, to_offset); + VariableList vars({¤t_to_offset}, zone()); + int to_index_constant = 0, from_index_constant = 0; + bool index_same = (from_encoding == to_encoding) && + (from_index == to_index || + (ToInt32Constant(from_index, &from_index_constant) && + ToInt32Constant(to_index, &to_index_constant) && + from_index_constant == to_index_constant)); + BuildFastLoop<IntPtrT>( + vars, from_offset, limit_offset, + [&](TNode<IntPtrT> offset) { + Node* value = Load(type, from_string, offset); + StoreNoWriteBarrier(rep, to_string, + index_same ? offset : current_to_offset.value(), + value); + if (!index_same) { + Increment(¤t_to_offset, to_increment); + } + }, + from_increment, IndexAdvanceMode::kPost); +} + +// A wrapper around CopyStringCharacters which determines the correct string +// encoding, allocates a corresponding sequential string, and then copies the +// given character range using CopyStringCharacters. +// |from_string| must be a sequential string. +// 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. +TNode<String> StringBuiltinsAssembler::AllocAndCopyStringCharacters( + Node* from, Node* from_instance_type, TNode<IntPtrT> from_index, + TNode<IntPtrT> character_count) { + Label end(this), one_byte_sequential(this), two_byte_sequential(this); + TVARIABLE(String, var_result); + + Branch(IsOneByteStringInstanceType(from_instance_type), &one_byte_sequential, + &two_byte_sequential); + + // The subject string is a sequential one-byte string. + BIND(&one_byte_sequential); + { + TNode<String> result = AllocateSeqOneByteString( + Unsigned(TruncateIntPtrToInt32(character_count))); + CopyStringCharacters(from, result, from_index, IntPtrConstant(0), + character_count, String::ONE_BYTE_ENCODING, + String::ONE_BYTE_ENCODING); + var_result = result; + Goto(&end); + } + + // The subject string is a sequential two-byte string. + BIND(&two_byte_sequential); + { + TNode<String> result = AllocateSeqTwoByteString( + Unsigned(TruncateIntPtrToInt32(character_count))); + CopyStringCharacters(from, result, from_index, IntPtrConstant(0), + character_count, String::TWO_BYTE_ENCODING, + String::TWO_BYTE_ENCODING); + var_result = result; + Goto(&end); + } + + BIND(&end); + return var_result.value(); +} + +TNode<String> StringBuiltinsAssembler::SubString(TNode<String> string, + TNode<IntPtrT> from, + TNode<IntPtrT> to) { + TVARIABLE(String, var_result); + ToDirectStringAssembler to_direct(state(), string); + Label end(this), runtime(this); + + TNode<IntPtrT> const substr_length = IntPtrSub(to, from); + TNode<IntPtrT> const string_length = LoadStringLengthAsWord(string); + + // Begin dispatching based on substring length. + + Label original_string_or_invalid_length(this); + GotoIf(UintPtrGreaterThanOrEqual(substr_length, string_length), + &original_string_or_invalid_length); + + // A real substring (substr_length < string_length). + Label empty(this); + GotoIf(IntPtrEqual(substr_length, IntPtrConstant(0)), &empty); + + Label single_char(this); + GotoIf(IntPtrEqual(substr_length, IntPtrConstant(1)), &single_char); + + // Deal with different string types: update the index if necessary + // and extract the underlying string. + + TNode<String> direct_string = to_direct.TryToDirect(&runtime); + TNode<IntPtrT> offset = IntPtrAdd(from, to_direct.offset()); + TNode<Int32T> const instance_type = to_direct.instance_type(); + + // The subject string can only be external or sequential string of either + // encoding at this point. + Label external_string(this); + { + if (FLAG_string_slices) { + Label next(this); + + // Short slice. Copy instead of slicing. + GotoIf(IntPtrLessThan(substr_length, + IntPtrConstant(SlicedString::kMinLength)), + &next); + + // Allocate new sliced string. + + Counters* counters = isolate()->counters(); + IncrementCounter(counters->sub_string_native(), 1); + + Label one_byte_slice(this), two_byte_slice(this); + Branch(IsOneByteStringInstanceType(to_direct.instance_type()), + &one_byte_slice, &two_byte_slice); + + BIND(&one_byte_slice); + { + var_result = AllocateSlicedOneByteString( + Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string, + SmiTag(offset)); + Goto(&end); + } + + BIND(&two_byte_slice); + { + var_result = AllocateSlicedTwoByteString( + Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string, + SmiTag(offset)); + Goto(&end); + } + + BIND(&next); + } + + // The subject string can only be external or sequential string of either + // encoding at this point. + GotoIf(to_direct.is_external(), &external_string); + + var_result = AllocAndCopyStringCharacters(direct_string, instance_type, + offset, substr_length); + + Counters* counters = isolate()->counters(); + IncrementCounter(counters->sub_string_native(), 1); + + Goto(&end); + } + + // Handle external string. + BIND(&external_string); + { + TNode<RawPtrT> const fake_sequential_string = + to_direct.PointerToString(&runtime); + + var_result = AllocAndCopyStringCharacters( + fake_sequential_string, instance_type, offset, substr_length); + + Counters* counters = isolate()->counters(); + IncrementCounter(counters->sub_string_native(), 1); + + Goto(&end); + } + + BIND(&empty); + { + var_result = EmptyStringConstant(); + Goto(&end); + } + + // Substrings of length 1 are generated through CharCodeAt and FromCharCode. + BIND(&single_char); + { + TNode<Int32T> char_code = StringCharCodeAt(string, from); + var_result = StringFromSingleCharCode(char_code); + Goto(&end); + } + + BIND(&original_string_or_invalid_length); + { + CSA_ASSERT(this, IntPtrEqual(substr_length, string_length)); + + // Equal length - check if {from, to} == {0, str.length}. + GotoIf(UintPtrGreaterThan(from, IntPtrConstant(0)), &runtime); + + // Return the original string (substr_length == string_length). + + Counters* counters = isolate()->counters(); + IncrementCounter(counters->sub_string_native(), 1); + + var_result = string; + Goto(&end); + } + + // Fall back to a runtime call. + BIND(&runtime); + { + var_result = + CAST(CallRuntime(Runtime::kStringSubstring, NoContextConstant(), string, + SmiTag(from), SmiTag(to))); + Goto(&end); + } + + BIND(&end); + return var_result.value(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/builtins-string-gen.h b/deps/v8/src/builtins/builtins-string-gen.h index 64d5a77615d8f6..0dfcf88a8c77da 100644 --- a/deps/v8/src/builtins/builtins-string-gen.h +++ b/deps/v8/src/builtins/builtins-string-gen.h @@ -33,6 +33,25 @@ class StringBuiltinsAssembler : public CodeStubAssembler { SloppyTNode<IntPtrT> index, UnicodeEncoding encoding); + TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint); + + // Return a new string object which holds a substring containing the range + // [from,to[ of string. + TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from, + TNode<IntPtrT> to); + + // Copies |character_count| elements from |from_string| to |to_string| + // starting at the |from_index|'th character. |from_string| and |to_string| + // can either be one-byte strings or two-byte strings, although if + // |from_string| is two-byte, then |to_string| must be two-byte. + // |from_index|, |to_index| and |character_count| must be intptr_ts s.t. 0 <= + // |from_index| <= |from_index| + |character_count| <= from_string.length and + // 0 <= |to_index| <= |to_index| + |character_count| <= to_string.length. + V8_EXPORT_PRIVATE void CopyStringCharacters( + Node* from_string, Node* to_string, TNode<IntPtrT> from_index, + TNode<IntPtrT> to_index, TNode<IntPtrT> character_count, + String::Encoding from_encoding, String::Encoding to_encoding); + protected: void StringEqual_Loop(Node* lhs, Node* lhs_instance_type, MachineType lhs_type, Node* rhs, @@ -51,8 +70,8 @@ class StringBuiltinsAssembler : public CodeStubAssembler { Node* const search_ptr, Node* const search_length, Node* const start_position); - TNode<IntPtrT> PointerToStringDataAtIndex(Node* const string_data, - Node* const index, + TNode<RawPtrT> PointerToStringDataAtIndex(TNode<RawPtrT> string_data, + TNode<IntPtrT> index, String::Encoding encoding); // substr and slice have a common way of handling the {start} argument. @@ -82,6 +101,38 @@ class StringBuiltinsAssembler : public CodeStubAssembler { return SmiLessThan(value, SmiConstant(0)); } + TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left, + TNode<String> right); + + TNode<String> StringAdd(Node* context, TNode<String> left, + TNode<String> right); + + // Check if |string| is an indirect (thin or flat cons) string type that can + // be dereferenced by DerefIndirectString. + void BranchIfCanDerefIndirectString(TNode<String> string, + TNode<Int32T> instance_type, + Label* can_deref, Label* cannot_deref); + // Allocate an appropriate one- or two-byte ConsString with the first and + // second parts specified by |left| and |right|. + // Unpack an indirect (thin or flat cons) string type. + void DerefIndirectString(TVariable<String>* var_string, + TNode<Int32T> instance_type); + // Check if |var_string| has an indirect (thin or flat cons) string type, and + // unpack it if so. + void MaybeDerefIndirectString(TVariable<String>* var_string, + TNode<Int32T> instance_type, Label* did_deref, + Label* cannot_deref); + // Check if |var_left| or |var_right| has an indirect (thin or flat cons) + // string type, and unpack it/them if so. Fall through if nothing was done. + void MaybeDerefIndirectStrings(TVariable<String>* var_left, + TNode<Int32T> left_instance_type, + TVariable<String>* var_right, + TNode<Int32T> right_instance_type, + Label* did_something); + TNode<String> DerefIndirectString(TNode<String> string, + TNode<Int32T> instance_type, + Label* cannot_deref); + // Implements boilerplate logic for {match, split, replace, search} of the // form: // @@ -103,6 +154,12 @@ class StringBuiltinsAssembler : public CodeStubAssembler { Handle<Symbol> symbol, DescriptorIndexNameValue additional_property_to_check, const NodeFunction0& regexp_call, const NodeFunction1& generic_call); + + private: + TNode<String> AllocAndCopyStringCharacters(Node* from, + Node* from_instance_type, + TNode<IntPtrT> from_index, + TNode<IntPtrT> character_count); }; class StringIncludesIndexOfAssembler : public StringBuiltinsAssembler { diff --git a/deps/v8/src/builtins/builtins-string.cc b/deps/v8/src/builtins/builtins-string.cc index 04a96c7e46d020..ba2346d661c7fa 100644 --- a/deps/v8/src/builtins/builtins-string.cc +++ b/deps/v8/src/builtins/builtins-string.cc @@ -136,20 +136,21 @@ BUILTIN(StringPrototypeLocaleCompare) { HandleScope handle_scope(isolate); isolate->CountUsage(v8::Isolate::UseCounterFeature::kStringLocaleCompare); + const char* method = "String.prototype.localeCompare"; #ifdef V8_INTL_SUPPORT - TO_THIS_STRING(str1, "String.prototype.localeCompare"); + TO_THIS_STRING(str1, method); Handle<String> str2; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, str2, Object::ToString(isolate, args.atOrUndefined(isolate, 1))); RETURN_RESULT_OR_FAILURE( - isolate, Intl::StringLocaleCompare(isolate, str1, str2, - args.atOrUndefined(isolate, 2), - args.atOrUndefined(isolate, 3))); + isolate, Intl::StringLocaleCompare( + isolate, str1, str2, args.atOrUndefined(isolate, 2), + args.atOrUndefined(isolate, 3), method)); #else DCHECK_EQ(2, args.length()); - TO_THIS_STRING(str1, "String.prototype.localeCompare"); + TO_THIS_STRING(str1, method); Handle<String> str2; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str2, Object::ToString(isolate, args.at(1))); diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.cc b/deps/v8/src/builtins/builtins-typed-array-gen.cc index 448ff66603f94e..c69034e813b1c8 100644 --- a/deps/v8/src/builtins/builtins-typed-array-gen.cc +++ b/deps/v8/src/builtins/builtins-typed-array-gen.cc @@ -8,6 +8,7 @@ #include "src/builtins/builtins-utils-gen.h" #include "src/builtins/builtins.h" #include "src/builtins/growable-fixed-array-gen.h" +#include "src/execution/protectors.h" #include "src/handles/handles-inl.h" #include "src/heap/factory-inl.h" @@ -15,8 +16,6 @@ namespace v8 { namespace internal { using compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; // ----------------------------------------------------------------------------- // ES6 section 22.2 TypedArray Objects @@ -117,8 +116,8 @@ TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) { // ES6 #sec-get-%typedarray%.prototype.bytelength TF_BUILTIN(TypedArrayPrototypeByteLength, TypedArrayBuiltinsAssembler) { const char* const kMethodName = "get TypedArray.prototype.byteLength"; - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); // Check if the {receiver} is actually a JSTypedArray. ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName); @@ -135,8 +134,8 @@ TF_BUILTIN(TypedArrayPrototypeByteLength, TypedArrayBuiltinsAssembler) { // ES6 #sec-get-%typedarray%.prototype.byteoffset TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) { const char* const kMethodName = "get TypedArray.prototype.byteOffset"; - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); // Check if the {receiver} is actually a JSTypedArray. ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName); @@ -153,8 +152,8 @@ TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) { // ES6 #sec-get-%typedarray%.prototype.length TF_BUILTIN(TypedArrayPrototypeLength, TypedArrayBuiltinsAssembler) { const char* const kMethodName = "get TypedArray.prototype.length"; - Node* context = Parameter(Descriptor::kContext); - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); // Check if the {receiver} is actually a JSTypedArray. ThrowIfNotInstanceType(context, receiver, JS_TYPED_ARRAY_TYPE, kMethodName); @@ -318,8 +317,8 @@ void TypedArrayBuiltinsAssembler::SetTypedArraySource( // Grab pointers and byte lengths we need later on. - TNode<RawPtrT> target_data_ptr = LoadJSTypedArrayBackingStore(target); - TNode<RawPtrT> source_data_ptr = LoadJSTypedArrayBackingStore(source); + TNode<RawPtrT> target_data_ptr = LoadJSTypedArrayDataPtr(target); + TNode<RawPtrT> source_data_ptr = LoadJSTypedArrayDataPtr(source); TNode<Int32T> source_el_kind = LoadElementsKind(source); TNode<Int32T> target_el_kind = LoadElementsKind(target); @@ -538,13 +537,83 @@ TNode<BoolT> TypedArrayBuiltinsAssembler::IsSharedArrayBuffer( return IsSetWord32<JSArrayBuffer::IsSharedBit>(bitfield); } +void TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr( + TNode<JSTypedArray> holder, TNode<ByteArray> base, TNode<UintPtrT> offset) { + offset = UintPtrAdd(UintPtrConstant(ByteArray::kHeaderSize - kHeapObjectTag), + offset); + if (COMPRESS_POINTERS_BOOL) { + TNode<IntPtrT> full_base = Signed(BitcastTaggedToWord(base)); + TNode<Int32T> compressed_base = TruncateIntPtrToInt32(full_base); + // TODO(v8:9706): Add a way to directly use kRootRegister value. + TNode<IntPtrT> isolate_root = + IntPtrSub(full_base, ChangeInt32ToIntPtr(compressed_base)); + // Add JSTypedArray::ExternalPointerCompensationForOnHeapArray() to offset. + DCHECK_EQ( + isolate()->isolate_root(), + JSTypedArray::ExternalPointerCompensationForOnHeapArray(isolate())); + // See JSTypedArray::SetOnHeapDataPtr() for details. + offset = Unsigned(IntPtrAdd(offset, isolate_root)); + } + + StoreObjectField(holder, JSTypedArray::kBasePointerOffset, base); + StoreObjectFieldNoWriteBarrier<UintPtrT>( + holder, JSTypedArray::kExternalPointerOffset, offset); +} + +void TypedArrayBuiltinsAssembler::SetJSTypedArrayOffHeapDataPtr( + TNode<JSTypedArray> holder, TNode<RawPtrT> base, TNode<UintPtrT> offset) { + StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kBasePointerOffset, + SmiConstant(0)); + + base = RawPtrAdd(base, Signed(offset)); + StoreObjectFieldNoWriteBarrier<RawPtrT>( + holder, JSTypedArray::kExternalPointerOffset, base); +} + +void TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromTagged( + TNode<Context> context, TNode<JSTypedArray> typed_array, + TNode<Smi> index_node, TNode<Object> value, ElementsKind elements_kind) { + TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(typed_array); + switch (elements_kind) { + case UINT8_ELEMENTS: + case UINT8_CLAMPED_ELEMENTS: + case INT8_ELEMENTS: + case UINT16_ELEMENTS: + case INT16_ELEMENTS: + StoreElement(data_ptr, elements_kind, index_node, SmiToInt32(CAST(value)), + SMI_PARAMETERS); + break; + case UINT32_ELEMENTS: + case INT32_ELEMENTS: + StoreElement(data_ptr, elements_kind, index_node, + TruncateTaggedToWord32(context, value), SMI_PARAMETERS); + break; + case FLOAT32_ELEMENTS: + StoreElement(data_ptr, elements_kind, index_node, + TruncateFloat64ToFloat32(LoadHeapNumberValue(CAST(value))), + SMI_PARAMETERS); + break; + case FLOAT64_ELEMENTS: + StoreElement(data_ptr, elements_kind, index_node, + LoadHeapNumberValue(CAST(value)), SMI_PARAMETERS); + break; + case BIGUINT64_ELEMENTS: + case BIGINT64_ELEMENTS: + StoreElement(data_ptr, elements_kind, index_node, + UncheckedCast<BigInt>(value), SMI_PARAMETERS); + break; + default: + UNREACHABLE(); + } +} + // ES #sec-get-%typedarray%.prototype.set TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) { const char* method_name = "%TypedArray%.prototype.set"; + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); - CodeStubArguments args( - this, - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount))); + CodeStubArguments args(this, argc); Label if_source_is_typed_array(this), if_source_is_fast_jsarray(this), if_offset_is_out_of_bounds(this, Label::kDeferred), @@ -618,7 +687,7 @@ TF_BUILTIN(TypedArrayPrototypeSet, TypedArrayBuiltinsAssembler) { // ES #sec-get-%typedarray%.prototype-@@tostringtag TF_BUILTIN(TypedArrayPrototypeToStringTag, TypedArrayBuiltinsAssembler) { - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); Label if_receiverisheapobject(this), return_undefined(this); Branch(TaggedIsSmi(receiver), &return_undefined, &if_receiverisheapobject); @@ -645,12 +714,12 @@ TF_BUILTIN(TypedArrayPrototypeToStringTag, TypedArrayBuiltinsAssembler) { #undef TYPED_ARRAY_CASE }; - // We offset the dispatch by FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, so - // that this can be turned into a non-sparse table switch for ideal - // performance. + // We offset the dispatch by FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND, so that + // this can be turned into a non-sparse table switch for ideal performance. BIND(&if_receiverisheapobject); + TNode<HeapObject> receiver_heap_object = CAST(receiver); TNode<Int32T> elements_kind = - Int32Sub(LoadElementsKind(receiver), + Int32Sub(LoadElementsKind(receiver_heap_object), Int32Constant(FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND)); Switch(elements_kind, &return_undefined, elements_kinds, elements_kind_labels, kTypedElementsKindCount); @@ -710,8 +779,7 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) { TNode<IntPtrT> length = ChangeInt32ToIntPtr( UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount))); // 2. Let items be the List of arguments passed to this function. - CodeStubArguments args(this, length, nullptr, INTPTR_PARAMETERS, - CodeStubArguments::ReceiverMode::kHasReceiver); + CodeStubArguments args(this, length); Label if_not_constructor(this, Label::kDeferred), if_detached(this, Label::kDeferred); @@ -737,10 +805,10 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) { DispatchTypedArrayByElementsKind( elements_kind, [&](ElementsKind kind, int size, int typed_array_fun_index) { - BuildFastLoop( + BuildFastLoop<IntPtrT>( IntPtrConstant(0), length, - [&](Node* index) { - TNode<Object> item = args.AtIndex(index, INTPTR_PARAMETERS); + [&](TNode<IntPtrT> index) { + TNode<Object> item = args.AtIndex(index); Node* value = PrepareValueForWriteToTypedArray(item, kind, context); @@ -752,12 +820,11 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) { // GC may move backing store in ToNumber, thus load backing // store everytime in this loop. - TNode<RawPtrT> backing_store = - LoadJSTypedArrayBackingStore(new_typed_array); - StoreElement(backing_store, kind, index, value, - INTPTR_PARAMETERS); + TNode<RawPtrT> data_ptr = + LoadJSTypedArrayDataPtr(new_typed_array); + StoreElement(data_ptr, kind, index, value, INTPTR_PARAMETERS); }, - 1, ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + 1, IndexAdvanceMode::kPost); }); // 8. Return newObj. @@ -773,6 +840,8 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) { // ES6 #sec-%typedarray%.from TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { + TNode<Int32T> argc = + UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label check_iterator(this), from_array_like(this), fast_path(this), @@ -782,9 +851,7 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { if_iterator_fn_not_callable(this, Label::kDeferred), if_detached(this, Label::kDeferred); - CodeStubArguments args( - this, - ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount))); + CodeStubArguments args(this, argc); TNode<Object> source = args.GetOptionalArgumentValue(0); // 5. If thisArg is present, let T be thisArg; else let T be undefined. @@ -866,7 +933,7 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { TNode<PropertyCell> protector_cell = ArrayIteratorProtectorConstant(); GotoIfNot( TaggedEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset), - SmiConstant(Isolate::kProtectorValid)), + SmiConstant(Protectors::kProtectorValid)), &check_iterator); // Source is a TypedArray with unmodified iterator behavior. Use the @@ -950,15 +1017,15 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { TNode<Int32T> elements_kind = LoadElementsKind(target_obj.value()); // 7e/13 : Copy the elements - BuildFastLoop( + BuildFastLoop<Smi>( SmiConstant(0), final_length.value(), - [&](Node* index) { + [&](TNode<Smi> index) { TNode<Object> const k_value = GetProperty(context, final_source.value(), index); TNode<Object> const mapped_value = - CAST(CallJS(CodeFactory::Call(isolate()), context, map_fn, this_arg, - k_value, index)); + CallJS(CodeFactory::Call(isolate()), context, map_fn, this_arg, + k_value, index); DispatchTypedArrayByElementsKind( elements_kind, @@ -974,13 +1041,12 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { // GC may move backing store in map_fn, thus load backing // store in each iteration of this loop. - TNode<RawPtrT> backing_store = - LoadJSTypedArrayBackingStore(target_obj.value()); - StoreElement(backing_store, kind, index, final_value, - SMI_PARAMETERS); + TNode<RawPtrT> data_ptr = + LoadJSTypedArrayDataPtr(target_obj.value()); + StoreElement(data_ptr, kind, index, final_value, SMI_PARAMETERS); }); }, - 1, ParameterMode::SMI_PARAMETERS, IndexAdvanceMode::kPost); + 1, IndexAdvanceMode::kPost); args.PopAndReturn(target_obj.value()); diff --git a/deps/v8/src/builtins/builtins-typed-array-gen.h b/deps/v8/src/builtins/builtins-typed-array-gen.h index d637bc9c6b6c9b..10a2cb608c6139 100644 --- a/deps/v8/src/builtins/builtins-typed-array-gen.h +++ b/deps/v8/src/builtins/builtins-typed-array-gen.h @@ -111,6 +111,18 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler { TNode<Word32T> elements_kind, const TypedArraySwitchCase& case_function); TNode<BoolT> IsSharedArrayBuffer(TNode<JSArrayBuffer> buffer); + + void SetJSTypedArrayOnHeapDataPtr(TNode<JSTypedArray> holder, + TNode<ByteArray> base, + TNode<UintPtrT> offset); + void SetJSTypedArrayOffHeapDataPtr(TNode<JSTypedArray> holder, + TNode<RawPtrT> base, + TNode<UintPtrT> offset); + void StoreJSTypedArrayElementFromTagged(TNode<Context> context, + TNode<JSTypedArray> typed_array, + TNode<Smi> index_node, + TNode<Object> value, + ElementsKind elements_kind); }; } // namespace internal diff --git a/deps/v8/src/builtins/builtins-utils-inl.h b/deps/v8/src/builtins/builtins-utils-inl.h index c9d15f09dd260b..c8c9a2522c97d6 100644 --- a/deps/v8/src/builtins/builtins-utils-inl.h +++ b/deps/v8/src/builtins/builtins-utils-inl.h @@ -12,20 +12,21 @@ namespace v8 { namespace internal { -Handle<Object> BuiltinArguments::atOrUndefined(Isolate* isolate, int index) { +Handle<Object> BuiltinArguments::atOrUndefined(Isolate* isolate, + int index) const { if (index >= length()) { return isolate->factory()->undefined_value(); } return at<Object>(index); } -Handle<Object> BuiltinArguments::receiver() { return at<Object>(0); } +Handle<Object> BuiltinArguments::receiver() const { return at<Object>(0); } -Handle<JSFunction> BuiltinArguments::target() { +Handle<JSFunction> BuiltinArguments::target() const { return Arguments::at<JSFunction>(Arguments::length() - 1 - kTargetOffset); } -Handle<HeapObject> BuiltinArguments::new_target() { +Handle<HeapObject> BuiltinArguments::new_target() const { return Arguments::at<HeapObject>(Arguments::length() - 1 - kNewTargetOffset); } diff --git a/deps/v8/src/builtins/builtins-utils.h b/deps/v8/src/builtins/builtins-utils.h index 822f9df6ecd9be..601dfd58131d7b 100644 --- a/deps/v8/src/builtins/builtins-utils.h +++ b/deps/v8/src/builtins/builtins-utils.h @@ -23,13 +23,13 @@ class BuiltinArguments : public Arguments { DCHECK_LE(1, this->length()); } - Object operator[](int index) { + Object operator[](int index) const { DCHECK_LT(index, length()); return Arguments::operator[](index); } template <class S = Object> - Handle<S> at(int index) { + Handle<S> at(int index) const { DCHECK_LT(index, length()); return Arguments::at<S>(index); } @@ -42,10 +42,10 @@ class BuiltinArguments : public Arguments { static constexpr int kNumExtraArgs = 4; static constexpr int kNumExtraArgsWithReceiver = 5; - inline Handle<Object> atOrUndefined(Isolate* isolate, int index); - inline Handle<Object> receiver(); - inline Handle<JSFunction> target(); - inline Handle<HeapObject> new_target(); + inline Handle<Object> atOrUndefined(Isolate* isolate, int index) const; + inline Handle<Object> receiver() const; + inline Handle<JSFunction> target() const; + inline Handle<HeapObject> new_target() const; // Gets the total number of arguments including the receiver (but // excluding extra arguments). @@ -77,7 +77,7 @@ class BuiltinArguments : public Arguments { RuntimeCallCounterId::kBuiltin_##name); \ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \ "V8.Builtin_" #name); \ - return Builtin_Impl_##name(args, isolate).ptr(); \ + return CONVERT_OBJECT(Builtin_Impl_##name(args, isolate)); \ } \ \ V8_WARN_UNUSED_RESULT Address Builtin_##name( \ @@ -87,7 +87,7 @@ class BuiltinArguments : public Arguments { return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \ } \ BuiltinArguments args(args_length, args_object); \ - return Builtin_Impl_##name(args, isolate).ptr(); \ + return CONVERT_OBJECT(Builtin_Impl_##name(args, isolate)); \ } \ \ V8_WARN_UNUSED_RESULT static Object Builtin_Impl_##name( \ diff --git a/deps/v8/src/builtins/builtins.cc b/deps/v8/src/builtins/builtins.cc index e5829dd1b34977..e0750a732c68a3 100644 --- a/deps/v8/src/builtins/builtins.cc +++ b/deps/v8/src/builtins/builtins.cc @@ -88,14 +88,16 @@ const BuiltinMetadata builtin_metadata[] = {BUILTIN_LIST( } // namespace BailoutId Builtins::GetContinuationBailoutId(Name name) { - DCHECK(Builtins::KindOf(name) == TFJ || Builtins::KindOf(name) == TFC); + DCHECK(Builtins::KindOf(name) == TFJ || Builtins::KindOf(name) == TFC || + Builtins::KindOf(name) == TFS); return BailoutId(BailoutId::kFirstBuiltinContinuationId + name); } Builtins::Name Builtins::GetBuiltinFromBailoutId(BailoutId id) { int builtin_index = id.ToInt() - BailoutId::kFirstBuiltinContinuationId; DCHECK(Builtins::KindOf(builtin_index) == TFJ || - Builtins::KindOf(builtin_index) == TFC); + Builtins::KindOf(builtin_index) == TFC || + Builtins::KindOf(builtin_index) == TFS); return static_cast<Name>(builtin_index); } @@ -204,7 +206,7 @@ void Builtins::PrintBuiltinCode() { CStrVector(FLAG_print_builtin_code_filter))) { CodeTracer::Scope trace_scope(isolate_->GetCodeTracer()); OFStream os(trace_scope.file()); - code->Disassemble(builtin_name, os); + code->Disassemble(builtin_name, os, isolate_); os << "\n"; } } diff --git a/deps/v8/src/builtins/frames.tq b/deps/v8/src/builtins/frames.tq index 7467381690e21d..79f2a0ae010f78 100644 --- a/deps/v8/src/builtins/frames.tq +++ b/deps/v8/src/builtins/frames.tq @@ -24,8 +24,8 @@ Cast<FrameType>(o: Object): FrameType labels CastError { if (TaggedIsNotSmi(o)) goto CastError; assert( - (Convert<uintptr>(BitcastTaggedToWord(o)) >>> kSmiTagSize) < - kFrameTypeCount); + Convert<int32>(BitcastTaggedToWordForTagAndSmiBits(o)) < + Convert<int32>(kFrameTypeCount << kSmiTagSize)); return %RawDownCast<FrameType>(o); } diff --git a/deps/v8/src/builtins/growable-fixed-array-gen.h b/deps/v8/src/builtins/growable-fixed-array-gen.h index 42f2afb281d694..8f72429a97e3fc 100644 --- a/deps/v8/src/builtins/growable-fixed-array-gen.h +++ b/deps/v8/src/builtins/growable-fixed-array-gen.h @@ -10,8 +10,6 @@ namespace v8 { namespace internal { -template <class T> -using TNode = compiler::TNode<T>; // Utility class implementing a growable fixed array through CSA. class GrowableFixedArray : public CodeStubAssembler { diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc index feabac3b66abbe..0885b6e633741d 100644 --- a/deps/v8/src/builtins/ia32/builtins-ia32.cc +++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc @@ -5,7 +5,7 @@ #if V8_TARGET_ARCH_IA32 #include "src/api/api-arguments.h" -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/codegen/code-factory.h" #include "src/debug/debug.h" #include "src/deoptimizer/deoptimizer.h" @@ -785,103 +785,75 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register scratch) { +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry) { // ----------- S t a t e ------------- // -- edx : new target (preserved for callee if needed, and caller) // -- edi : target function (preserved for callee if needed, and caller) - // -- ecx : feedback vector (also used as scratch, value is not preserved) // ----------------------------------- - DCHECK(!AreAliased(edx, edi, scratch)); - - Label optimized_code_slot_is_weak_ref, fallthrough; + DCHECK(!AreAliased(edx, edi, optimized_code_entry)); Register closure = edi; - // Scratch contains feedback_vector. - Register feedback_vector = scratch; - // Load the optimized code from the feedback vector and re-use the register. - Register optimized_code_entry = scratch; - __ mov(optimized_code_entry, - FieldOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); - - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret it as a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); + __ push(edx); + + // Check if the optimized code is marked for deopt. If it is, bailout to a + // given label. + Label found_deoptimized_code; + __ mov(eax, + FieldOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); + __ test(FieldOperand(eax, CodeDataContainer::kKindSpecificFlagsOffset), + Immediate(1 << Code::kMarkedForDeoptimizationBit)); + __ j(not_zero, &found_deoptimized_code); + + // Optimized code is good, get it into the closure and link the closure + // into the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, edx, + eax); + static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch"); + __ LoadCodeObjectEntry(ecx, optimized_code_entry); + __ pop(edx); + __ jmp(ecx); - { - // Optimized code slot is an optimization marker. - - // Fall through if no optimization trigger. - __ cmp(optimized_code_entry, - Immediate(Smi::FromEnum(OptimizationMarker::kNone))); - __ j(equal, &fallthrough); - - // TODO(v8:8394): The logging of first execution will break if - // feedback vectors are not allocated. We need to find a different way of - // logging these events if required. - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); + // Optimized code slot contains deoptimized code, evict it and re-enter + // the closure's code. + __ bind(&found_deoptimized_code); + __ pop(edx); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +} - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ cmp( - optimized_code_entry, - Immediate(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); - __ Assert(equal, AbortReason::kExpectedOptimizationSentinel); - } - __ jmp(&fallthrough); - } - } +static void MaybeOptimizeCode(MacroAssembler* masm, + Register optimization_marker) { + // ----------- S t a t e ------------- + // -- edx : new target (preserved for callee if needed, and caller) + // -- edi : target function (preserved for callee if needed, and caller) + // -- optimization_marker : a Smi containing a non-zero optimization marker. + // ----------------------------------- + DCHECK(!AreAliased(edx, edi, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, &fallthrough); - - __ push(edx); - - // Check if the optimized code is marked for deopt. If it is, bailout to a - // given label. - Label found_deoptimized_code; - __ mov(eax, - FieldOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); - __ test(FieldOperand(eax, CodeDataContainer::kKindSpecificFlagsOffset), - Immediate(1 << Code::kMarkedForDeoptimizationBit)); - __ j(not_zero, &found_deoptimized_code); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, - edx, eax); - static_assert(kJavaScriptCallCodeStartRegister == ecx, "ABI mismatch"); - __ LoadCodeObjectEntry(ecx, optimized_code_entry); - __ pop(edx); - __ jmp(ecx); - - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - __ pop(edx); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ cmp( + optimization_marker, + Immediate(Smi::FromEnum(OptimizationMarker::kInOptimizationQueue))); + __ Assert(equal, AbortReason::kExpectedOptimizationSentinel); + } } - - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); } // Advance the current bytecode offset. This simulates what all bytecode @@ -912,20 +884,21 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, static_cast<int>(interpreter::Bytecode::kDebugBreakExtraWide)); __ cmp(bytecode, Immediate(0x3)); __ j(above, &process_bytecode, Label::kNear); + // The code to load the next bytecode is common to both wide and extra wide. + // We can hoist them up here. inc has to happen before test since it + // modifies the ZF flag. + __ inc(bytecode_offset); __ test(bytecode, Immediate(0x1)); + __ movzx_b(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); __ j(not_equal, &extra_wide, Label::kNear); // Load the next bytecode and update table to the wide scaled table. - __ inc(bytecode_offset); - __ movzx_b(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); __ add(bytecode_size_table, Immediate(kIntSize * interpreter::Bytecodes::kBytecodeCount)); __ jmp(&process_bytecode, Label::kNear); __ bind(&extra_wide); - // Load the next bytecode and update table to the extra wide scaled table. - __ inc(bytecode_offset); - __ movzx_b(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); + // Update table to the extra wide scaled table. __ add(bytecode_size_table, Immediate(2 * kIntSize * interpreter::Bytecodes::kBytecodeCount)); @@ -982,9 +955,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ CmpInstanceType(eax, FEEDBACK_VECTOR_TYPE); __ j(not_equal, &push_stack_frame); - // Read off the optimized code slot in the closure's feedback vector, and if - // there is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, ecx); + // Read off the optimized code slot in the feedback vector. + // Load the optimized code from the feedback vector and re-use the register. + Register optimized_code_entry = ecx; + __ mov(optimized_code_entry, + FieldOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); + + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ cmp(optimized_code_entry, + Immediate(Smi::FromEnum(OptimizationMarker::kNone))); + __ j(not_equal, &optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Load the feedback vector and increment the invocation count. __ mov(feedback_vector, @@ -1035,6 +1020,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ push(Immediate(Smi::FromInt(BytecodeArray::kHeaderSize - kHeapObjectTag))); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size from the BytecodeArray object. Register frame_size = ecx; @@ -1042,22 +1028,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ mov(eax, esp); __ sub(eax, frame_size); __ CompareRealStackLimit(eax); - __ j(above_equal, &ok); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ j(below, &stack_overflow); // If ok, push undefined as the initial value for all register file entries. Label loop_header; Label loop_check; - __ Move(eax, masm->isolate()->factory()->undefined_value()); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ jmp(&loop_check); __ bind(&loop_header); // TODO(rmcilroy): Consider doing more than one push per loop iteration. - __ push(eax); + __ push(kInterpreterAccumulatorRegister); // Continue loop if not done. __ bind(&loop_check); __ sub(frame_size, Immediate(kSystemPointerSize)); @@ -1067,12 +1050,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // If the bytecode array has a valid incoming new target or generator object // register, initialize it with incoming value which was passed in edx. Label no_incoming_new_target_or_generator_register; - __ mov(eax, FieldOperand( + __ mov(ecx, FieldOperand( kInterpreterBytecodeArrayRegister, BytecodeArray::kIncomingNewTargetOrGeneratorRegisterOffset)); - __ test(eax, eax); + __ test(ecx, ecx); __ j(zero, &no_incoming_new_target_or_generator_register); - __ mov(Operand(ebp, eax, times_system_pointer_size, 0), edx); + __ mov(Operand(ebp, ecx, times_system_pointer_size, 0), edx); __ bind(&no_incoming_new_target_or_generator_register); // Load accumulator and bytecode offset into registers. @@ -1117,8 +1100,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LeaveInterpreterFrame(masm, edx, ecx); __ ret(0); + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code as opposed to an optimization marker. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry); + __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); __ int3(); // Should not return. } @@ -2601,14 +2602,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); - __ mov(eax, Operand(eax, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(eax); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } diff --git a/deps/v8/src/builtins/internal-coverage.tq b/deps/v8/src/builtins/internal-coverage.tq index 41ec0c36e42e0e..ebedbdce75b0f6 100644 --- a/deps/v8/src/builtins/internal-coverage.tq +++ b/deps/v8/src/builtins/internal-coverage.tq @@ -28,8 +28,6 @@ namespace internal_coverage { return UnsafeCast<CoverageInfo>(debugInfo.coverage_info); } - @export // Silence unused warning on release builds. SlotCount is only used - // in an assert. TODO(szuend): Remove once macros and asserts work. macro SlotCount(coverageInfo: CoverageInfo): Smi { assert(kFirstSlotIndex == 0); // Otherwise we'd have to consider it below. assert(kFirstSlotIndex == (coverageInfo.length & kSlotIndexCountMask)); diff --git a/deps/v8/src/builtins/iterator.tq b/deps/v8/src/builtins/iterator.tq index 06e8ea539c0dc2..e662e4e75e5afe 100644 --- a/deps/v8/src/builtins/iterator.tq +++ b/deps/v8/src/builtins/iterator.tq @@ -37,22 +37,45 @@ namespace iterator { extern macro IteratorBuiltinsAssembler::IterableToList( implicit context: Context)(JSAny, JSAny): JSArray; + extern macro IteratorBuiltinsAssembler::StringListFromIterable( + implicit context: Context)(JSAny): JSArray; + extern builtin IterableToListMayPreserveHoles(implicit context: Context)(JSAny, JSAny); extern builtin IterableToListWithSymbolLookup(implicit context: Context)(JSAny); transitioning builtin GetIteratorWithFeedback( - context: Context, receiver: JSAny, feedbackSlot: Smi, + context: Context, receiver: JSAny, loadSlot: Smi, callSlot: Smi, feedback: Undefined | FeedbackVector): JSAny { + let iteratorMethod: JSAny; typeswitch (feedback) { case (Undefined): { - return GetProperty(receiver, IteratorSymbolConstant()); + iteratorMethod = GetProperty(receiver, IteratorSymbolConstant()); } case (feedback: FeedbackVector): { - return LoadIC( - context, receiver, IteratorSymbolConstant(), feedbackSlot, - feedback); + iteratorMethod = LoadIC( + context, receiver, IteratorSymbolConstant(), loadSlot, feedback); + } + } + return CallIteratorWithFeedback( + context, receiver, iteratorMethod, callSlot, feedback); + } + + transitioning builtin CallIteratorWithFeedback( + context: Context, receiver: JSAny, iteratorMethod: JSAny, callSlot: Smi, + feedback: Undefined | FeedbackVector): JSAny { + const callSlotUnTagged: uintptr = Unsigned(SmiUntag(callSlot)); + CollectCallFeedback(iteratorMethod, context, feedback, callSlotUnTagged); + const iteratorCallable: Callable = Cast<Callable>(iteratorMethod) + otherwise ThrowCalledNonCallable(iteratorMethod); + const iterator: JSAny = Call(context, iteratorCallable, receiver); + typeswitch (iterator) { + case (JSReceiver): { + return iterator; + } + case (JSPrimitive): { + ThrowSymbolIteratorInvalid(); } } } diff --git a/deps/v8/src/builtins/mips/builtins-mips.cc b/deps/v8/src/builtins/mips/builtins-mips.cc index d3237a1c381c9d..ecfb224fb27d2b 100644 --- a/deps/v8/src/builtins/mips/builtins-mips.cc +++ b/deps/v8/src/builtins/mips/builtins-mips.cc @@ -1085,18 +1085,16 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, t0); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size from the BytecodeArray object. __ lw(t0, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ Subu(t1, sp, Operand(t0)); LoadRealStackLimit(masm, a2); - __ Branch(&ok, hs, t1, Operand(a2)); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ Branch(&stack_overflow, lo, t1, Operand(a2)); // If ok, push undefined as the initial value for all register file entries. Label loop_header; @@ -1169,6 +1167,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); // Unreachable code. __ break_(0xCC); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); + // Unreachable code. + __ break_(0xCC); } static void Generate_InterpreterPushArgs(MacroAssembler* masm, @@ -1525,14 +1528,8 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ lw(a0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ lw(a0, MemOperand(a0, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(a0); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -2131,7 +2128,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- a1 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(a1, &non_callable); __ bind(&non_smi); __ GetObjectType(a1, t1, t2); @@ -2146,12 +2143,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { __ Branch(&non_callable, eq, t1, Operand(zero_reg)); // Check if target is a proxy and call CallProxy external builtin - __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), + RelocInfo::CODE_TARGET, eq, t2, Operand(JS_PROXY_TYPE)); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ bind(&non_function); // Overwrite the original receiver with the (original) target. __ Lsa(kScratchReg, sp, a0, kPointerSizeLog2); __ sw(a1, MemOperand(kScratchReg)); diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc index 7cb66470a34e36..47dbc340020dab 100644 --- a/deps/v8/src/builtins/mips64/builtins-mips64.cc +++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc @@ -1103,18 +1103,16 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, a4); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size (word) from the BytecodeArray object. __ Lw(a4, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ Dsubu(a5, sp, Operand(a4)); LoadRealStackLimit(masm, a2); - __ Branch(&ok, hs, a5, Operand(a2)); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ Branch(&stack_overflow, lo, a5, Operand(a2)); // If ok, push undefined as the initial value for all register file entries. Label loop_header; @@ -1188,6 +1186,11 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); // Unreachable code. __ break_(0xCC); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); + // Unreachable code. + __ break_(0xCC); } static void Generate_InterpreterPushArgs(MacroAssembler* masm, @@ -1542,14 +1545,8 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ Ld(a0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ Ld(a0, MemOperand(a0, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(a0); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -2170,7 +2167,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- a1 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(a1, &non_callable); __ bind(&non_smi); __ GetObjectType(a1, t1, t2); @@ -2184,12 +2181,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { __ And(t1, t1, Operand(Map::IsCallableBit::kMask)); __ Branch(&non_callable, eq, t1, Operand(zero_reg)); - __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), + RelocInfo::CODE_TARGET, eq, t2, Operand(JS_PROXY_TYPE)); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ bind(&non_function); // Overwrite the original receiver with the (original) target. __ Dlsa(kScratchReg, sp, a0, kPointerSizeLog2); __ Sd(a1, MemOperand(kScratchReg)); diff --git a/deps/v8/src/builtins/ppc/builtins-ppc.cc b/deps/v8/src/builtins/ppc/builtins-ppc.cc index 485b793395240a..ab0c7900d59490 100644 --- a/deps/v8/src/builtins/ppc/builtins-ppc.cc +++ b/deps/v8/src/builtins/ppc/builtins-ppc.cc @@ -863,9 +863,11 @@ void Builtins::Generate_RunMicrotasksTrampoline(MacroAssembler* masm) { __ Jump(BUILTIN_CODE(masm->isolate(), RunMicrotasks), RelocInfo::CODE_TARGET); } -static void ReplaceClosureCodeWithOptimizedCode( - MacroAssembler* masm, Register optimized_code, Register closure, - Register scratch1, Register scratch2, Register scratch3) { +static void ReplaceClosureCodeWithOptimizedCode(MacroAssembler* masm, + Register optimized_code, + Register closure, + Register scratch1, + Register scratch2) { // Store code entry in the closure. __ StoreP(optimized_code, FieldMemOperand(closure, JSFunction::kCodeOffset), r0); @@ -902,100 +904,73 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register feedback_vector, - Register scratch1, Register scratch2, - Register scratch3) { +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry, + Register scratch) { // ----------- S t a t e ------------- // -- r6 : new target (preserved for callee if needed, and caller) // -- r4 : target function (preserved for callee if needed, and caller) - // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK(!AreAliased(feedback_vector, r4, r6, scratch1, scratch2, scratch3)); - - Label optimized_code_slot_is_weak_ref, fallthrough; + DCHECK(!AreAliased(r4, r6, optimized_code_entry, scratch)); Register closure = r4; - Register optimized_code_entry = scratch1; - - __ LoadP( - optimized_code_entry, - FieldMemOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); - - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret it as a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); - { - // Optimized code slot is a Smi optimization marker. - - // Fall through if no optimization trigger. - __ CmpSmiLiteral(optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kNone), r0); - __ beq(&fallthrough); - - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); - - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ CmpSmiLiteral( - optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kInOptimizationQueue), r0); - __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); - } - __ b(&fallthrough); - } - } + // Check if the optimized code is marked for deopt. If it is, call the + // runtime to clear it. + Label found_deoptimized_code; + __ LoadP(scratch, FieldMemOperand(optimized_code_entry, + Code::kCodeDataContainerOffset)); + __ LoadWordArith( + scratch, + FieldMemOperand(scratch, CodeDataContainer::kKindSpecificFlagsOffset)); + __ TestBit(scratch, Code::kMarkedForDeoptimizationBit, r0); + __ bne(&found_deoptimized_code, cr0); + + // Optimized code is good, get it into the closure and link the closure + // into the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, + scratch, r8); + static_assert(kJavaScriptCallCodeStartRegister == r5, "ABI mismatch"); + __ LoadCodeObjectEntry(r5, optimized_code_entry); + __ Jump(r5); - { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, optimized_code_entry, &fallthrough); - - // Check if the optimized code is marked for deopt. If it is, call the - // runtime to clear it. - Label found_deoptimized_code; - __ LoadP(scratch2, FieldMemOperand(optimized_code_entry, - Code::kCodeDataContainerOffset)); - __ LoadWordArith( - scratch2, - FieldMemOperand(scratch2, CodeDataContainer::kKindSpecificFlagsOffset)); - __ TestBit(scratch2, Code::kMarkedForDeoptimizationBit, r0); - __ bne(&found_deoptimized_code, cr0); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - // The feedback vector is no longer used, so re-use it as a scratch - // register. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, - scratch2, scratch3, feedback_vector); - static_assert(kJavaScriptCallCodeStartRegister == r5, "ABI mismatch"); - __ LoadCodeObjectEntry(r5, optimized_code_entry); - __ Jump(r5); + // Optimized code slot contains deoptimized code, evict it and re-enter + // the closure's code. + __ bind(&found_deoptimized_code); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +} - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, + Register optimization_marker) { + // ----------- S t a t e ------------- + // -- r6 : new target (preserved for callee if needed, and caller) + // -- r4 : target function (preserved for callee if needed, and caller) + // -- feedback vector (preserved for caller if needed) + // -- optimization_marker : a Smi containing a non-zero optimization marker. + // ----------------------------------- + DCHECK(!AreAliased(feedback_vector, r4, r6, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); + + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ CmpSmiLiteral(optimization_marker, + Smi::FromEnum(OptimizationMarker::kInOptimizationQueue), + r0); + __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); } - - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); } // Advance the current bytecode offset. This simulates what all bytecode @@ -1104,9 +1079,20 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ cmpi(r7, Operand(FEEDBACK_VECTOR_TYPE)); __ bne(&push_stack_frame); - // Read off the optimized code slot in the feedback vector, and if there - // is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r7, r9, r8); + Register optimized_code_entry = r7; + + // Read off the optimized code slot in the feedback vector. + __ LoadP(optimized_code_entry, + FieldMemOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ CmpSmiLiteral(optimized_code_entry, + Smi::FromEnum(OptimizationMarker::kNone), r0); + __ bne(&optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Increment invocation count for the function. __ LoadWord( @@ -1149,29 +1135,27 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, r3); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size (word) from the BytecodeArray object. __ lwz(r5, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ sub(r8, sp, r5); LoadRealStackLimit(masm, r0); __ cmpl(r8, r0); - __ bge(&ok); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ blt(&stack_overflow); // If ok, push undefined as the initial value for all register file entries. // TODO(rmcilroy): Consider doing more than one push per loop iteration. Label loop, no_args; - __ LoadRoot(r8, RootIndex::kUndefinedValue); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ ShiftRightImm(r5, r5, Operand(kPointerSizeLog2), SetRC); __ beq(&no_args, cr0); __ mtctr(r5); __ bind(&loop); - __ push(r8); + __ push(kInterpreterAccumulatorRegister); __ bdnz(&loop); __ bind(&no_args); } @@ -1189,8 +1173,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ StorePX(r6, MemOperand(fp, r8)); __ bind(&no_incoming_new_target_or_generator_register); - // Load accumulator with undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. + // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. Label do_dispatch; @@ -1231,8 +1215,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LeaveInterpreterFrame(masm, r5); __ blr(); + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry, r9); + __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); __ bkpt(0); // Should not return. } @@ -1596,14 +1598,8 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ LoadP(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ LoadP(r3, MemOperand(r3, JavaScriptFrameConstants::kFunctionOffset)); - { FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(r3); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -2260,7 +2256,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- r4 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(r4, &non_callable); __ bind(&non_smi); __ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE); @@ -2277,12 +2273,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // Check if target is a proxy and call CallProxy external builtin __ cmpi(r8, Operand(JS_PROXY_TYPE)); - __ bne(&non_function); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ bind(&non_function); // Overwrite the original receiver the (original) target. __ ShiftLeftImm(r8, r3, Operand(kPointerSizeLog2)); __ StorePX(r4, MemOperand(sp, r8)); diff --git a/deps/v8/src/builtins/regexp-exec.tq b/deps/v8/src/builtins/regexp-exec.tq new file mode 100644 index 00000000000000..b2ca9de10b57ee --- /dev/null +++ b/deps/v8/src/builtins/regexp-exec.tq @@ -0,0 +1,45 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-regexp-gen.h' + +namespace regexp { + + extern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeExecBody( + implicit context: Context)(JSReceiver, String, constexpr bool): JSAny; + + transitioning macro RegExpPrototypeExecBodyFast(implicit context: Context)( + receiver: JSReceiver, string: String): JSAny { + return RegExpPrototypeExecBody(receiver, string, true); + } + + transitioning macro RegExpPrototypeExecBodySlow(implicit context: Context)( + receiver: JSReceiver, string: String): JSAny { + return RegExpPrototypeExecBody(receiver, string, false); + } + + // Slow path stub for RegExpPrototypeExec to decrease code size. + transitioning builtin + RegExpPrototypeExecSlow(implicit context: Context)( + regexp: JSRegExp, string: String): JSAny { + return RegExpPrototypeExecBodySlow(regexp, string); + } + + extern macro RegExpBuiltinsAssembler::IsFastRegExpNoPrototype( + implicit context: Context)(Object): bool; + + // ES#sec-regexp.prototype.exec + // RegExp.prototype.exec ( string ) + transitioning javascript builtin RegExpPrototypeExec( + js-implicit context: Context, receiver: JSAny)(string: JSAny): JSAny { + // Ensure {receiver} is a JSRegExp. + const receiver = Cast<JSRegExp>(receiver) otherwise ThrowTypeError( + kIncompatibleMethodReceiver, 'RegExp.prototype.exec', receiver); + const string = ToString_Inline(context, string); + + return IsFastRegExpNoPrototype(receiver) ? + RegExpPrototypeExecBodyFast(receiver, string) : + RegExpPrototypeExecSlow(receiver, string); + } +} diff --git a/deps/v8/src/builtins/regexp-match-all.tq b/deps/v8/src/builtins/regexp-match-all.tq new file mode 100644 index 00000000000000..1be6e69afce748 --- /dev/null +++ b/deps/v8/src/builtins/regexp-match-all.tq @@ -0,0 +1,258 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-regexp-gen.h' + +namespace regexp { + + extern transitioning macro RegExpBuiltinsAssembler::RegExpCreate( + implicit context: Context)(Context, Object, String): Object; + + extern transitioning macro + RegExpMatchAllAssembler::CreateRegExpStringIterator( + NativeContext, Object, String, bool, bool): JSAny; + + @export + transitioning macro RegExpPrototypeMatchAllImpl(implicit context: Context)( + nativeContext: NativeContext, receiver: JSAny, string: JSAny): JSAny { + // 1. Let R be the this value. + // 2. If Type(R) is not Object, throw a TypeError exception. + ThrowIfNotJSReceiver( + receiver, kIncompatibleMethodReceiver, 'RegExp.prototype.@@matchAll'); + const receiver = UnsafeCast<JSReceiver>(receiver); + + // 3. Let S be ? ToString(O). + const string: String = ToString_Inline(context, string); + + let matcher: Object; + let global: bool; + let unicode: bool; + + // 'FastJSRegExp' uses the strict fast path check because following code + // uses the flags property. + // TODO(jgruber): Handle slow flag accesses on the fast path and make this + // permissive. + typeswitch (receiver) { + case (fastRegExp: FastJSRegExp): { + const source = fastRegExp.source; + + // 4. Let C be ? SpeciesConstructor(R, %RegExp%). + // 5. Let flags be ? ToString(? Get(R, "flags")). + // 6. Let matcher be ? Construct(C, « R, flags »). + const flags: String = FastFlagsGetter(fastRegExp); + matcher = RegExpCreate(nativeContext, source, flags); + const matcherRegExp = UnsafeCast<JSRegExp>(matcher); + assert(IsFastRegExpPermissive(matcherRegExp)); + + // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). + // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). + const fastRegExp = UnsafeCast<FastJSRegExp>(receiver); + FastStoreLastIndex(matcherRegExp, fastRegExp.lastIndex); + + // 9. If flags contains "g", let global be true. + // 10. Else, let global be false. + global = FastFlagGetter(matcherRegExp, kGlobal); + + // 11. If flags contains "u", let fullUnicode be true. + // 12. Else, let fullUnicode be false. + unicode = FastFlagGetter(matcherRegExp, kUnicode); + } + case (Object): { + // 4. Let C be ? SpeciesConstructor(R, %RegExp%). + const regexpFun = + UnsafeCast<JSFunction>(nativeContext[REGEXP_FUNCTION_INDEX]); + const speciesConstructor = + UnsafeCast<Constructor>(SpeciesConstructor(receiver, regexpFun)); + + // 5. Let flags be ? ToString(? Get(R, "flags")). + const flags = GetProperty(receiver, 'flags'); + const flagsString = ToString_Inline(context, flags); + + // 6. Let matcher be ? Construct(C, « R, flags »). + matcher = Construct(speciesConstructor, receiver, flagsString); + + // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). + const lastIndex: Number = + ToLength_Inline(context, SlowLoadLastIndex(receiver)); + + // 8. Perform ? Set(matcher, "lastIndex", lastIndex, true). + SlowStoreLastIndex(UnsafeCast<JSReceiver>(matcher), lastIndex); + + // 9. If flags contains "g", let global be true. + // 10. Else, let global be false. + const globalCharString: String = StringConstant('g'); + const globalIndex: Smi = + StringIndexOf(flagsString, globalCharString, 0); + global = globalIndex != -1; + + // 11. If flags contains "u", let fullUnicode be true. + // 12. Else, let fullUnicode be false. + const unicodeCharString = StringConstant('u'); + const unicodeIndex: Smi = + StringIndexOf(flagsString, unicodeCharString, 0); + unicode = unicodeIndex != -1; + } + } + + // 13. Return ! CreateRegExpStringIterator(matcher, S, global, fullUnicode). + return CreateRegExpStringIterator( + nativeContext, matcher, string, global, unicode); + } + + // https://tc39.github.io/proposal-string-matchall/ + // RegExp.prototype [ @@matchAll ] ( string ) + transitioning javascript builtin RegExpPrototypeMatchAll( + js-implicit context: Context, receiver: JSAny)(string: JSAny): JSAny { + const nativeContext: NativeContext = LoadNativeContext(context); + return RegExpPrototypeMatchAllImpl(nativeContext, receiver, string); + } + + const kJSRegExpStringIteratorDone: + constexpr int31 generates '1 << JSRegExpStringIterator::kDoneBit'; + const kJSRegExpStringIteratorGlobal: constexpr int31 + generates '1 << JSRegExpStringIterator::kGlobalBit'; + const kJSRegExpStringIteratorUnicode: constexpr int31 + generates '1 << JSRegExpStringIterator::kUnicodeBit'; + + extern macro IsSetSmi(Smi, constexpr int31): bool; + + macro HasDoneFlag(flags: Smi): bool { + return IsSetSmi(flags, kJSRegExpStringIteratorDone); + } + + macro HasGlobalFlag(flags: Smi): bool { + return IsSetSmi(flags, kJSRegExpStringIteratorGlobal); + } + + macro HasUnicodeFlag(flags: Smi): bool { + return IsSetSmi(flags, kJSRegExpStringIteratorUnicode); + } + + macro SetDoneFlag(iterator: JSRegExpStringIterator, flags: Smi) { + const newFlags: Smi = flags | kJSRegExpStringIteratorDone; + iterator.flags = newFlags; + } + + extern macro RegExpBuiltinsAssembler::ConstructNewResultFromMatchInfo( + implicit context: Context)(JSReceiver, RegExpMatchInfo, String): + JSRegExpResult; + + // https://tc39.github.io/proposal-string-matchall/ + // %RegExpStringIteratorPrototype%.next ( ) + transitioning javascript builtin RegExpStringIteratorPrototypeNext( + js-implicit context: Context, receiver: JSAny)(): JSAny { + // 1. Let O be the this value. + // 2. If Type(O) is not Object, throw a TypeError exception. + // 3. If O does not have all of the internal slots of a RegExp String + // Iterator Object Instance (see 5.3), throw a TypeError exception. + const methodName: constexpr string = + '%RegExpStringIterator%.prototype.next'; + const receiver = Cast<JSRegExpStringIterator>(receiver) otherwise + ThrowTypeError(kIncompatibleMethodReceiver, methodName, receiver); + + try { + // 4. If O.[[Done]] is true, then + // a. Return ! CreateIterResultObject(undefined, true). + const flags: Smi = receiver.flags; + if (HasDoneFlag(flags)) goto ReturnEmptyDoneResult; + + // 5. Let R be O.[[iteratingRegExp]]. + const iteratingRegExp: JSReceiver = receiver.iterating_reg_exp; + + // 6. Let S be O.[[IteratedString]]. + const iteratingString: String = receiver.iterated_string; + + // 7. Let global be O.[[Global]]. + // 8. Let fullUnicode be O.[[Unicode]]. + // 9. Let match be ? RegExpExec(R, S). + let match: Object; + let isFastRegExp: bool = false; + try { + if (IsFastRegExpPermissive(iteratingRegExp)) { + const matchIndices: RegExpMatchInfo = + RegExpPrototypeExecBodyWithoutResultFast( + UnsafeCast<JSRegExp>(iteratingRegExp), iteratingString) + otherwise IfNoMatch; + match = ConstructNewResultFromMatchInfo( + iteratingRegExp, matchIndices, iteratingString); + isFastRegExp = true; + } else { + match = RegExpExec(iteratingRegExp, iteratingString); + if (match == Null) { + goto IfNoMatch; + } + } + // 11. Else, + // b. Else, handle non-global case first. + if (!HasGlobalFlag(flags)) { + // i. Set O.[[Done]] to true. + SetDoneFlag(receiver, flags); + + // ii. Return ! CreateIterResultObject(match, false). + return AllocateJSIteratorResult(UnsafeCast<JSAny>(match), False); + } + // a. If global is true, + assert(HasGlobalFlag(flags)); + if (isFastRegExp) { + // i. Let matchStr be ? ToString(? Get(match, "0")). + const match = UnsafeCast<FastJSRegExpResult>(match); + const resultFixedArray = UnsafeCast<FixedArray>(match.elements); + const matchStr = UnsafeCast<String>(resultFixedArray.objects[0]); + + // When iterating_regexp is fast, we assume it stays fast even after + // accessing the first match from the RegExp result. + assert(IsFastRegExpPermissive(iteratingRegExp)); + const iteratingRegExp = UnsafeCast<JSRegExp>(iteratingRegExp); + if (matchStr == kEmptyString) { + // 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")). + const thisIndex: Smi = FastLoadLastIndex(iteratingRegExp); + + // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, + // fullUnicode). + const nextIndex: Smi = AdvanceStringIndexFast( + iteratingString, thisIndex, HasUnicodeFlag(flags)); + + // 3. Perform ? Set(R, "lastIndex", nextIndex, true). + FastStoreLastIndex(iteratingRegExp, nextIndex); + } + + // iii. Return ! CreateIterResultObject(match, false). + return AllocateJSIteratorResult(match, False); + } + assert(!isFastRegExp); + // i. Let matchStr be ? ToString(? Get(match, "0")). + const match = UnsafeCast<JSAny>(match); + const matchStr = + ToString_Inline(context, GetProperty(match, SmiConstant(0))); + + if (matchStr == kEmptyString) { + // 1. Let thisIndex be ? ToLength(? Get(R, "lastIndex")). + const lastIndex: JSAny = SlowLoadLastIndex(iteratingRegExp); + const thisIndex: Number = ToLength_Inline(context, lastIndex); + + // 2. Let nextIndex be ! AdvanceStringIndex(S, thisIndex, + // fullUnicode). + const nextIndex: Number = AdvanceStringIndexSlow( + iteratingString, thisIndex, HasUnicodeFlag(flags)); + + // 3. Perform ? Set(R, "lastIndex", nextIndex, true). + SlowStoreLastIndex(iteratingRegExp, nextIndex); + } + // iii. Return ! CreateIterResultObject(match, false). + return AllocateJSIteratorResult(match, False); + } + // 10. If match is null, then + label IfNoMatch { + // a. Set O.[[Done]] to true. + SetDoneFlag(receiver, flags); + + // b. Return ! CreateIterResultObject(undefined, true). + goto ReturnEmptyDoneResult; + } + } + label ReturnEmptyDoneResult { + return AllocateJSIteratorResult(Undefined, True); + } + } +} diff --git a/deps/v8/src/builtins/regexp-replace.tq b/deps/v8/src/builtins/regexp-replace.tq index f13724b476ce5d..1333ce97fb9f59 100644 --- a/deps/v8/src/builtins/regexp-replace.tq +++ b/deps/v8/src/builtins/regexp-replace.tq @@ -6,8 +6,6 @@ namespace regexp { - extern builtin - StringIndexOf(implicit context: Context)(String, String, Smi): Smi; extern builtin SubString(implicit context: Context)(String, Smi, Smi): String; @@ -21,9 +19,6 @@ namespace regexp { StringReplaceNonGlobalRegExpWithFunction(implicit context: Context)( String, JSRegExp, Callable): String; - extern macro - RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Smi, bool): Smi; - transitioning macro RegExpReplaceCallableNoExplicitCaptures(implicit context: Context)( matchesElements: FixedArray, matchesLength: intptr, string: String, diff --git a/deps/v8/src/builtins/regexp-search.tq b/deps/v8/src/builtins/regexp-search.tq new file mode 100644 index 00000000000000..3c4e57d734e09b --- /dev/null +++ b/deps/v8/src/builtins/regexp-search.tq @@ -0,0 +1,105 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-regexp-gen.h' + +namespace regexp { + + transitioning macro + RegExpPrototypeSearchBodyFast(implicit context: Context)( + regexp: JSRegExp, string: String): JSAny { + assert(IsFastRegExpPermissive(regexp)); + + // Grab the initial value of last index. + const previousLastIndex: Smi = FastLoadLastIndex(regexp); + + // Ensure last index is 0. + FastStoreLastIndex(regexp, 0); + + // Call exec. + try { + const matchIndices: RegExpMatchInfo = + RegExpPrototypeExecBodyWithoutResultFast(regexp, string) + otherwise DidNotMatch; + + // Successful match. + // Reset last index. + FastStoreLastIndex(regexp, previousLastIndex); + + // Return the index of the match. + return UnsafeCast<Smi>( + matchIndices.objects[kRegExpMatchInfoFirstCaptureIndex]); + } + label DidNotMatch { + // Reset last index and return -1. + FastStoreLastIndex(regexp, previousLastIndex); + return SmiConstant(-1); + } + } + + extern macro RegExpBuiltinsAssembler::BranchIfFastRegExpResult( + implicit context: Context)(Object): never labels IsUnmodified, + IsModified; + + macro + IsFastRegExpResult(implicit context: Context)(execResult: HeapObject): bool { + BranchIfFastRegExpResult(execResult) otherwise return true, return false; + } + + transitioning macro RegExpPrototypeSearchBodySlow(implicit context: Context)( + regexp: JSReceiver, string: String): JSAny { + // Grab the initial value of last index. + const previousLastIndex = SlowLoadLastIndex(regexp); + const smiZero: Smi = 0; + + // Ensure last index is 0. + if (!SameValue(previousLastIndex, smiZero)) { + SlowStoreLastIndex(regexp, smiZero); + } + + // Call exec. + const execResult = RegExpExec(regexp, string); + + // Reset last index if necessary. + const currentLastIndex = SlowLoadLastIndex(regexp); + if (!SameValue(currentLastIndex, previousLastIndex)) { + SlowStoreLastIndex(regexp, previousLastIndex); + } + + // Return -1 if no match was found. + if (execResult == Null) { + return SmiConstant(-1); + } + + // Return the index of the match. + const fastExecResult = Cast<FastJSRegExpResult>(execResult) + otherwise return GetProperty(execResult, 'index'); + return fastExecResult.index; + } + + // Helper that skips a few initial checks. and assumes... + // 1) receiver is a "fast permissive" RegExp + // 2) pattern is a string + transitioning builtin RegExpSearchFast(implicit context: Context)( + receiver: JSRegExp, string: String): JSAny { + return RegExpPrototypeSearchBodyFast(receiver, string); + } + + // ES#sec-regexp.prototype-@@search + // RegExp.prototype [ @@search ] ( string ) + transitioning javascript builtin RegExpPrototypeSearch( + js-implicit context: Context, receiver: JSAny)(string: JSAny): JSAny { + ThrowIfNotJSReceiver( + receiver, kIncompatibleMethodReceiver, 'RegExp.prototype.@@search'); + const receiver = UnsafeCast<JSReceiver>(receiver); + const string: String = ToString_Inline(context, string); + + if (IsFastRegExpPermissive(receiver)) { + // TODO(pwong): Could be optimized to remove the overhead of calling the + // builtin (at the cost of a larger builtin). + return RegExpSearchFast(UnsafeCast<JSRegExp>(receiver), string); + } + return RegExpPrototypeSearchBodySlow(receiver, string); + } +} diff --git a/deps/v8/src/builtins/regexp-source.tq b/deps/v8/src/builtins/regexp-source.tq index c1ce1c5e9a6935..266c9e7472f2fa 100644 --- a/deps/v8/src/builtins/regexp-source.tq +++ b/deps/v8/src/builtins/regexp-source.tq @@ -6,9 +6,6 @@ namespace regexp { - const kRegExpPrototypeSourceGetter: constexpr int31 - generates 'v8::Isolate::kRegExpPrototypeSourceGetter'; - // ES6 21.2.5.10. // ES #sec-get-regexp.prototype.source transitioning javascript builtin RegExpPrototypeSourceGetter( diff --git a/deps/v8/src/builtins/regexp-split.tq b/deps/v8/src/builtins/regexp-split.tq new file mode 100644 index 00000000000000..8a9a30a7e90f3d --- /dev/null +++ b/deps/v8/src/builtins/regexp-split.tq @@ -0,0 +1,72 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include 'src/builtins/builtins-regexp-gen.h' + +namespace runtime { + extern transitioning runtime + RegExpSplit(implicit context: Context)(JSReceiver, String, Object): JSAny; +} // namespace runtime + +namespace regexp { + + const kMaxValueSmi: constexpr int31 + generates 'Smi::kMaxValue'; + + extern transitioning macro RegExpBuiltinsAssembler::RegExpPrototypeSplitBody( + implicit context: Context)(JSRegExp, String, Smi): JSArray; + + // Helper that skips a few initial checks. + transitioning builtin + RegExpSplit(implicit context: Context)( + regexp: FastJSRegExp, string: String, limit: JSAny): JSAny { + let sanitizedLimit: Smi; + + // We need to be extra-strict and require the given limit to be either + // undefined or a positive smi. We can't call ToUint32(maybe_limit) since + // that might move us onto the slow path, resulting in ordering spec + // violations (see https://crbug.com/801171). + + if (limit == Undefined) { + // TODO(jgruber): In this case, we can probably avoid generation of limit + // checks in Generate_RegExpPrototypeSplitBody. + sanitizedLimit = SmiConstant(kMaxValueSmi); + } else if (!TaggedIsPositiveSmi(limit)) { + return runtime::RegExpSplit(regexp, string, limit); + } else { + sanitizedLimit = UnsafeCast<Smi>(limit); + } + + // Due to specific shortcuts we take on the fast path (specifically, we + // don't allocate a new regexp instance as specced), we need to ensure that + // the given regexp is non-sticky to avoid invalid results. See + // crbug.com/v8/6706. + + if (FastFlagGetter(regexp, kSticky)) { + return runtime::RegExpSplit(regexp, string, sanitizedLimit); + } + + // We're good to go on the fast path, which is inlined here. + return RegExpPrototypeSplitBody(regexp, string, sanitizedLimit); + } + + // ES#sec-regexp.prototype-@@split + // RegExp.prototype [ @@split ] ( string, limit ) + transitioning javascript builtin RegExpPrototypeSplit( + js-implicit context: Context, receiver: JSAny)(...arguments): JSAny { + ThrowIfNotJSReceiver( + receiver, kIncompatibleMethodReceiver, 'RegExp.prototype.@@split'); + const receiver = UnsafeCast<JSReceiver>(receiver); + const string: String = ToString_Inline(context, arguments[0]); + const limit = arguments[1]; + + // Strict: Reads the flags property. + // TODO(jgruber): Handle slow flag accesses on the fast path and make this + // permissive. + const fastRegExp = Cast<FastJSRegExp>(receiver) + otherwise return runtime::RegExpSplit(receiver, string, limit); + return RegExpSplit(fastRegExp, string, limit); + } + +} diff --git a/deps/v8/src/builtins/regexp-test.tq b/deps/v8/src/builtins/regexp-test.tq index 938dfa51f391f5..f2ebb7c2597273 100644 --- a/deps/v8/src/builtins/regexp-test.tq +++ b/deps/v8/src/builtins/regexp-test.tq @@ -20,7 +20,7 @@ namespace regexp { otherwise return False; return True; } - const matchIndices = RegExpExec(context, receiver, str); + const matchIndices = RegExpExec(receiver, str); return SelectBooleanConstant(matchIndices != Null); } diff --git a/deps/v8/src/builtins/regexp.tq b/deps/v8/src/builtins/regexp.tq index 7352d2738fa4a4..e48e7c584deabd 100644 --- a/deps/v8/src/builtins/regexp.tq +++ b/deps/v8/src/builtins/regexp.tq @@ -22,8 +22,34 @@ namespace regexp { BranchIfFastRegExp_Permissive(o) otherwise return true, return false; } - extern macro RegExpBuiltinsAssembler::RegExpExec(Context, Object, Object): - Object; + const kInvalidRegExpExecResult: constexpr MessageTemplate + generates 'MessageTemplate::kInvalidRegExpExecResult'; + + // ES#sec-regexpexec Runtime Semantics: RegExpExec ( R, S ) + @export + transitioning macro RegExpExec(implicit context: Context)( + receiver: JSReceiver, string: String): JSAny { + // Take the slow path of fetching the exec property, calling it, and + // verifying its return value. + + const exec = GetProperty(receiver, 'exec'); + + // Is {exec} callable? + typeswitch (exec) { + case (execCallable: Callable): { + const result = Call(context, execCallable, receiver, string); + if (result != Null) { + ThrowIfNotJSReceiver(result, kInvalidRegExpExecResult, ''); + } + return result; + } + case (Object): { + const regexp = Cast<JSRegExp>(receiver) otherwise ThrowTypeError( + kIncompatibleMethodReceiver, 'RegExp.prototype.exec', receiver); + return RegExpPrototypeExecSlow(regexp, string); + } + } + } extern macro RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResultFast( @@ -161,4 +187,59 @@ namespace regexp { otherwise return SlowFlagsGetter(receiver); return FastFlagsGetter(fastRegexp); } + + extern transitioning macro RegExpBuiltinsAssembler::SlowLoadLastIndex( + implicit context: Context)(JSAny): JSAny; + extern transitioning macro RegExpBuiltinsAssembler::SlowStoreLastIndex( + implicit context: Context)(JSAny, JSAny): void; + + extern macro RegExpBuiltinsAssembler::FastLoadLastIndex(JSRegExp): Smi; + extern macro RegExpBuiltinsAssembler::FastStoreLastIndex(JSRegExp, Smi): void; + + extern builtin + StringIndexOf(implicit context: Context)(String, String, Smi): Smi; + + extern macro + RegExpBuiltinsAssembler::AdvanceStringIndexFast(String, Smi, bool): Smi; + extern macro + RegExpBuiltinsAssembler::AdvanceStringIndexSlow(String, Number, bool): Smi; + + type UseCounterFeature extends int31 + constexpr 'v8::Isolate::UseCounterFeature'; + const kRegExpMatchIsTrueishOnNonJSRegExp: constexpr UseCounterFeature + generates 'v8::Isolate::kRegExpMatchIsTrueishOnNonJSRegExp'; + const kRegExpMatchIsFalseishOnJSRegExp: constexpr UseCounterFeature + generates 'v8::Isolate::kRegExpMatchIsFalseishOnJSRegExp'; + const kRegExpPrototypeSourceGetter: constexpr UseCounterFeature + generates 'v8::Isolate::kRegExpPrototypeSourceGetter'; + + // ES#sec-isregexp IsRegExp ( argument ) + @export + transitioning macro IsRegExp(implicit context: Context)(obj: JSAny): bool { + const receiver = Cast<JSReceiver>(obj) otherwise return false; + + // Check @match. + const value = GetProperty(receiver, MatchSymbolConstant()); + if (value == Undefined) { + return Is<JSRegExp>(receiver); + } + + assert(value != Undefined); + // The common path. Symbol.match exists, equals the RegExpPrototypeMatch + // function (and is thus trueish), and the receiver is a JSRegExp. + if (ToBoolean(value)) { + if (!Is<JSRegExp>(receiver)) { + IncrementUseCounter( + context, SmiConstant(kRegExpMatchIsTrueishOnNonJSRegExp)); + } + return true; + } + + assert(!ToBoolean(value)); + if (Is<JSRegExp>(receiver)) { + IncrementUseCounter( + context, SmiConstant(kRegExpMatchIsFalseishOnJSRegExp)); + } + return false; + } } diff --git a/deps/v8/src/builtins/s390/builtins-s390.cc b/deps/v8/src/builtins/s390/builtins-s390.cc index 7dca12d17e44e4..7fc6b91ba37783 100644 --- a/deps/v8/src/builtins/s390/builtins-s390.cc +++ b/deps/v8/src/builtins/s390/builtins-s390.cc @@ -103,7 +103,7 @@ void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args, // here which will cause scratch to become negative. __ SubP(scratch, sp, scratch); // Check if the arguments will overflow the stack. - __ ShiftLeftP(r0, num_args, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r0, num_args, Operand(kSystemPointerSizeLog2)); __ CmpP(scratch, r0); __ ble(stack_overflow); // Signed comparison. } @@ -147,11 +147,11 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { // sp[2]: number of arguments (smi-tagged) Label loop, no_args; __ beq(&no_args); - __ ShiftLeftP(scratch, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(scratch, r2, Operand(kSystemPointerSizeLog2)); __ SubP(sp, sp, scratch); __ LoadRR(r1, r2); __ bind(&loop); - __ lay(scratch, MemOperand(scratch, -kPointerSize)); + __ lay(scratch, MemOperand(scratch, -kSystemPointerSize)); __ LoadP(r0, MemOperand(scratch, r6)); __ StoreP(r0, MemOperand(scratch, sp)); __ BranchOnCount(r1, &loop); @@ -177,7 +177,7 @@ void Generate_JSBuiltinsConstructStubHelper(MacroAssembler* masm) { __ SmiToPtrArrayOffset(scratch, scratch); __ AddP(sp, sp, scratch); - __ AddP(sp, sp, Operand(kPointerSize)); + __ AddP(sp, sp, Operand(kSystemPointerSize)); __ Ret(); __ bind(&stack_overflow); @@ -213,11 +213,11 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { __ Push(r5); // ----------- S t a t e ------------- - // -- sp[0*kPointerSize]: new target - // -- sp[1*kPointerSize]: padding - // -- r3 and sp[2*kPointerSize]: constructor function - // -- sp[3*kPointerSize]: number of arguments (tagged) - // -- sp[4*kPointerSize]: context + // -- sp[0*kSystemPointerSize]: new target + // -- sp[1*kSystemPointerSize]: padding + // -- r3 and sp[2*kSystemPointerSize]: constructor function + // -- sp[3*kSystemPointerSize]: number of arguments (tagged) + // -- sp[4*kSystemPointerSize]: context // ----------------------------------- __ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); @@ -239,11 +239,11 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r2: receiver - // -- Slot 4 / sp[0*kPointerSize]: new target - // -- Slot 3 / sp[1*kPointerSize]: padding - // -- Slot 2 / sp[2*kPointerSize]: constructor function - // -- Slot 1 / sp[3*kPointerSize]: number of arguments (tagged) - // -- Slot 0 / sp[4*kPointerSize]: context + // -- Slot 4 / sp[0*kSystemPointerSize]: new target + // -- Slot 3 / sp[1*kSystemPointerSize]: padding + // -- Slot 2 / sp[2*kSystemPointerSize]: constructor function + // -- Slot 1 / sp[3*kSystemPointerSize]: number of arguments (tagged) + // -- Slot 0 / sp[4*kSystemPointerSize]: context // ----------------------------------- // Deoptimizer enters here. masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset( @@ -259,12 +259,12 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r5: new target - // -- sp[0*kPointerSize]: implicit receiver - // -- sp[1*kPointerSize]: implicit receiver - // -- sp[2*kPointerSize]: padding - // -- sp[3*kPointerSize]: constructor function - // -- sp[4*kPointerSize]: number of arguments (tagged) - // -- sp[5*kPointerSize]: context + // -- sp[0*kSystemPointerSize]: implicit receiver + // -- sp[1*kSystemPointerSize]: implicit receiver + // -- sp[2*kSystemPointerSize]: padding + // -- sp[3*kSystemPointerSize]: constructor function + // -- sp[4*kSystemPointerSize]: number of arguments (tagged) + // -- sp[5*kSystemPointerSize]: context // ----------------------------------- // Restore constructor function and argument count. @@ -295,21 +295,21 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // -- r5: new target // -- r6: pointer to last argument // -- cr0: condition indicating whether r2 is zero - // -- sp[0*kPointerSize]: implicit receiver - // -- sp[1*kPointerSize]: implicit receiver - // -- sp[2*kPointerSize]: padding - // -- r3 and sp[3*kPointerSize]: constructor function - // -- sp[4*kPointerSize]: number of arguments (tagged) - // -- sp[5*kPointerSize]: context + // -- sp[0*kSystemPointerSize]: implicit receiver + // -- sp[1*kSystemPointerSize]: implicit receiver + // -- sp[2*kSystemPointerSize]: padding + // -- r3 and sp[3*kSystemPointerSize]: constructor function + // -- sp[4*kSystemPointerSize]: number of arguments (tagged) + // -- sp[5*kSystemPointerSize]: context // ----------------------------------- __ ltgr(r2, r2); __ beq(&no_args); - __ ShiftLeftP(r8, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r8, r2, Operand(kSystemPointerSizeLog2)); __ SubP(sp, sp, r8); __ LoadRR(r1, r2); __ bind(&loop); - __ lay(r8, MemOperand(r8, -kPointerSize)); + __ lay(r8, MemOperand(r8, -kSystemPointerSize)); __ LoadP(r0, MemOperand(r8, r6)); __ StoreP(r0, MemOperand(r8, sp)); __ BranchOnCount(r1, &loop); @@ -321,11 +321,11 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0: constructor result - // -- sp[0*kPointerSize]: implicit receiver - // -- sp[1*kPointerSize]: padding - // -- sp[2*kPointerSize]: constructor function - // -- sp[3*kPointerSize]: number of arguments - // -- sp[4*kPointerSize]: context + // -- sp[0*kSystemPointerSize]: implicit receiver + // -- sp[1*kSystemPointerSize]: padding + // -- sp[2*kSystemPointerSize]: constructor function + // -- sp[3*kSystemPointerSize]: number of arguments + // -- sp[4*kSystemPointerSize]: context // ----------------------------------- // Store offset of return address for deoptimizer. @@ -376,7 +376,7 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { __ SmiToPtrArrayOffset(r3, r3); __ AddP(sp, sp, r3); - __ AddP(sp, sp, Operand(kPointerSize)); + __ AddP(sp, sp, Operand(kSystemPointerSize)); __ Ret(); } @@ -465,16 +465,16 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { r3, JSGeneratorObject::kParametersAndRegistersOffset)); { Label loop, done_loop; - __ ShiftLeftP(r5, r5, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r5, r5, Operand(kSystemPointerSizeLog2)); __ SubP(sp, r5); // ip = stack offset // r5 = parameter array offset __ LoadImmP(ip, Operand::Zero()); - __ SubP(r5, Operand(kPointerSize)); + __ SubP(r5, Operand(kSystemPointerSize)); __ blt(&done_loop); - __ lgfi(r1, Operand(-kPointerSize)); + __ lgfi(r1, Operand(-kSystemPointerSize)); __ bind(&loop); @@ -483,7 +483,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { __ StoreP(r0, MemOperand(sp, ip)); // update offsets - __ lay(ip, MemOperand(ip, kPointerSize)); + __ lay(ip, MemOperand(ip, kSystemPointerSize)); __ BranchRelativeOnIdxHighP(r5, r1, &loop); @@ -550,9 +550,9 @@ void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { namespace { constexpr int kPushedStackSpace = - (kNumCalleeSaved + 2) * kPointerSize + - kNumCalleeSavedDoubles * kDoubleSize + 5 * kPointerSize + - EntryFrameConstants::kCallerFPOffset - kPointerSize; + (kNumCalleeSaved + 2) * kSystemPointerSize + + kNumCalleeSavedDoubles * kDoubleSize + 5 * kSystemPointerSize + + EntryFrameConstants::kCallerFPOffset - kSystemPointerSize; // Called with the native C calling convention. The corresponding function // signature is either: @@ -607,9 +607,9 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // Requires us to save the callee-preserved registers r6-r13 // General convention is to also save r14 (return addr) and // sp/r15 as well in a single STM/STMG - __ lay(sp, MemOperand(sp, -10 * kPointerSize)); + __ lay(sp, MemOperand(sp, -10 * kSystemPointerSize)); __ StoreMultipleP(r6, sp, MemOperand(sp, 0)); - pushed_stack_space += (kNumCalleeSaved + 2) * kPointerSize; + pushed_stack_space += (kNumCalleeSaved + 2) * kSystemPointerSize; // Initialize the root register. // C calling convention. The first argument is passed in r2. @@ -625,8 +625,8 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // SMI Marker // kCEntryFPAddress // Frame type - __ lay(sp, MemOperand(sp, -5 * kPointerSize)); - pushed_stack_space += 5 * kPointerSize; + __ lay(sp, MemOperand(sp, -5 * kSystemPointerSize)); + pushed_stack_space += 5 * kSystemPointerSize; // Push a bad frame pointer to fail if it is used. __ LoadImmP(r9, Operand(-1)); @@ -637,16 +637,17 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, __ Move(r6, ExternalReference::Create( IsolateAddressId::kCEntryFPAddress, masm->isolate())); __ LoadP(r6, MemOperand(r6)); - __ StoreMultipleP(r6, r9, MemOperand(sp, kPointerSize)); + __ StoreMultipleP(r6, r9, MemOperand(sp, kSystemPointerSize)); Register scrach = r8; // Set up frame pointer for the frame to be pushed. - // Need to add kPointerSize, because sp has one extra + // Need to add kSystemPointerSize, because sp has one extra // frame already for the frame type being pushed later. - __ lay(fp, MemOperand( - sp, -EntryFrameConstants::kCallerFPOffset + kPointerSize)); - pushed_stack_space += EntryFrameConstants::kCallerFPOffset - kPointerSize; + __ lay(fp, MemOperand(sp, -EntryFrameConstants::kCallerFPOffset + + kSystemPointerSize)); + pushed_stack_space += + EntryFrameConstants::kCallerFPOffset - kSystemPointerSize; // restore r6 __ LoadRR(r6, r1); @@ -736,7 +737,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, // Reload callee-saved preserved regs, return address reg (r14) and sp __ LoadMultipleP(r6, sp, MemOperand(sp, 0)); - __ la(sp, MemOperand(sp, 10 * kPointerSize)); + __ la(sp, MemOperand(sp, 10 * kSystemPointerSize)); // saving floating point registers #if V8_TARGET_ARCH_S390X @@ -790,7 +791,7 @@ static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc, // here which will cause scratch1 to become negative. __ SubP(scratch1, sp, scratch1); // Check if the arguments will overflow the stack. - __ ShiftLeftP(scratch2, argc, Operand(kPointerSizeLog2)); + __ ShiftLeftP(scratch2, argc, Operand(kSystemPointerSizeLog2)); __ CmpP(scratch1, scratch2); __ bgt(&okay); // Signed comparison. @@ -807,7 +808,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, // r4: function // r5: receiver // r6: argc - // [fp + kPushedStackSpace + 20 * kPointerSize]: argv + // [fp + kPushedStackSpace + 20 * kSystemPointerSize]: argv // r0,r2,r7-r9, cp may be clobbered // Enter an internal frame. @@ -831,7 +832,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, // r3: new.target // r4: function // r6: argc - // [fp + kPushedStackSpace + 20 * kPointerSize]: argv + // [fp + kPushedStackSpace + 20 * kSystemPointerSize]: argv // r0,r2,r5,r7-r9, cp may be clobbered // Setup new.target, argc and function. @@ -862,15 +863,15 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, // r9: scratch reg to hold index into argv Label argLoop, argExit; intptr_t zero = 0; - __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r7, r2, Operand(kSystemPointerSizeLog2)); __ SubRR(sp, r7); // Buy the stack frame to fit args __ LoadImmP(r9, Operand(zero)); // Initialize argv index __ bind(&argLoop); __ CmpPH(r7, Operand(zero)); __ beq(&argExit, Label::kNear); - __ lay(r7, MemOperand(r7, -kPointerSize)); + __ lay(r7, MemOperand(r7, -kSystemPointerSize)); __ LoadP(r8, MemOperand(r9, r6)); // read next parameter - __ la(r9, MemOperand(r9, kPointerSize)); // r9++; + __ la(r9, MemOperand(r9, kSystemPointerSize)); // r9++; __ LoadP(r0, MemOperand(r8)); // dereference handle __ StoreP(r0, MemOperand(r7, sp)); // push parameter __ b(&argLoop); @@ -920,9 +921,11 @@ void Builtins::Generate_RunMicrotasksTrampoline(MacroAssembler* masm) { __ Jump(BUILTIN_CODE(masm->isolate(), RunMicrotasks), RelocInfo::CODE_TARGET); } -static void ReplaceClosureCodeWithOptimizedCode( - MacroAssembler* masm, Register optimized_code, Register closure, - Register scratch1, Register scratch2, Register scratch3) { +static void ReplaceClosureCodeWithOptimizedCode(MacroAssembler* masm, + Register optimized_code, + Register closure, + Register scratch1, + Register scratch2) { // Store code entry in the closure. __ StoreP(optimized_code, FieldMemOperand(closure, JSFunction::kCodeOffset), r0); @@ -960,100 +963,72 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register feedback_vector, - Register scratch1, Register scratch2, - Register scratch3) { +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry, + Register scratch) { // ----------- S t a t e ------------- // -- r5 : new target (preserved for callee if needed, and caller) // -- r3 : target function (preserved for callee if needed, and caller) - // -- feedback vector (preserved for caller if needed) // ----------------------------------- - DCHECK(!AreAliased(feedback_vector, r3, r5, scratch1, scratch2, scratch3)); - - Label optimized_code_slot_is_weak_ref, fallthrough; + DCHECK(!AreAliased(r3, r5, optimized_code_entry, scratch)); Register closure = r3; - Register optimized_code_entry = scratch1; - - __ LoadP( - optimized_code_entry, - FieldMemOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); - - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret it as a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); - { - // Optimized code slot is a Smi optimization marker. - - // Fall through if no optimization trigger. - __ CmpSmiLiteral(optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kNone), r0); - __ beq(&fallthrough); - - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); - - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ CmpSmiLiteral( - optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kInOptimizationQueue), r0); - __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); - } - __ b(&fallthrough, Label::kNear); - } - } + // Check if the optimized code is marked for deopt. If it is, call the + // runtime to clear it. + Label found_deoptimized_code; + __ LoadP(scratch, FieldMemOperand(optimized_code_entry, + Code::kCodeDataContainerOffset)); + __ LoadW(scratch, FieldMemOperand( + scratch, CodeDataContainer::kKindSpecificFlagsOffset)); + __ TestBit(scratch, Code::kMarkedForDeoptimizationBit, r0); + __ bne(&found_deoptimized_code); + + // Optimized code is good, get it into the closure and link the closure + // into the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, + scratch, r7); + static_assert(kJavaScriptCallCodeStartRegister == r4, "ABI mismatch"); + __ LoadCodeObjectEntry(r4, optimized_code_entry); + __ Jump(r4); - { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, optimized_code_entry, &fallthrough); - - // Check if the optimized code is marked for deopt. If it is, call the - // runtime to clear it. - Label found_deoptimized_code; - __ LoadP(scratch2, FieldMemOperand(optimized_code_entry, - Code::kCodeDataContainerOffset)); - __ LoadW( - scratch2, - FieldMemOperand(scratch2, CodeDataContainer::kKindSpecificFlagsOffset)); - __ TestBit(scratch2, Code::kMarkedForDeoptimizationBit, r0); - __ bne(&found_deoptimized_code); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - // The feedback vector is no longer used, so re-use it as a scratch - // register. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, - scratch2, scratch3, feedback_vector); - static_assert(kJavaScriptCallCodeStartRegister == r4, "ABI mismatch"); - __ LoadCodeObjectEntry(r4, optimized_code_entry); - __ Jump(r4); + // Optimized code slot contains deoptimized code, evict it and re-enter + // the closure's code. + __ bind(&found_deoptimized_code); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +} - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); +static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, + Register optimization_marker) { + // ----------- S t a t e ------------- + // -- r5 : new target (preserved for callee if needed, and caller) + // -- r3 : target function (preserved for callee if needed, and caller) + // -- feedback vector (preserved for caller if needed) + // -- optimization_marker : a Smi containing a non-zero optimization marker. + // ----------------------------------- + DCHECK(!AreAliased(feedback_vector, r3, r5, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); + + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ CmpSmiLiteral(optimization_marker, + Smi::FromEnum(OptimizationMarker::kInOptimizationQueue), + r0); + __ Assert(eq, AbortReason::kExpectedOptimizationSentinel); } - - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); } // Advance the current bytecode offset. This simulates what all bytecode @@ -1163,9 +1138,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ CmpP(r6, Operand(FEEDBACK_VECTOR_TYPE)); __ bne(&push_stack_frame); - // Read off the optimized code slot in the feedback vector, and if there - // is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, r6, r8, r7); + Register optimized_code_entry = r6; + + // Read off the optimized code slot in the feedback vector. + __ LoadP(optimized_code_entry, + FieldMemOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset)); + + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ CmpSmiLiteral(optimized_code_entry, + Smi::FromEnum(OptimizationMarker::kNone), r0); + __ bne(&optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Increment invocation count for the function. __ LoadW(r1, FieldMemOperand(feedback_vector, @@ -1202,29 +1189,27 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(kInterpreterBytecodeArrayRegister, r4); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size (word) from the BytecodeArray object. __ LoadlW(r4, FieldMemOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ SubP(r8, sp, r4); __ CmpLogicalP(r8, RealStackLimitAsMemOperand(masm)); - __ bge(&ok); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ blt(&stack_overflow); // If ok, push undefined as the initial value for all register file entries. // TODO(rmcilroy): Consider doing more than one push per loop iteration. Label loop, no_args; - __ LoadRoot(r8, RootIndex::kUndefinedValue); - __ ShiftRightP(r4, r4, Operand(kPointerSizeLog2)); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + __ ShiftRightP(r4, r4, Operand(kSystemPointerSizeLog2)); __ LoadAndTestP(r4, r4); __ beq(&no_args); __ LoadRR(r1, r4); __ bind(&loop); - __ push(r8); + __ push(kInterpreterAccumulatorRegister); __ SubP(r1, Operand(1)); __ bne(&loop); __ bind(&no_args); @@ -1238,12 +1223,12 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { BytecodeArray::kIncomingNewTargetOrGeneratorRegisterOffset)); __ CmpP(r8, Operand::Zero()); __ beq(&no_incoming_new_target_or_generator_register); - __ ShiftLeftP(r8, r8, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r8, r8, Operand(kSystemPointerSizeLog2)); __ StoreP(r5, MemOperand(fp, r8)); __ bind(&no_incoming_new_target_or_generator_register); - // Load accumulator with undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. + // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. Label do_dispatch; @@ -1254,7 +1239,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ LoadlB(r5, MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister)); - __ ShiftLeftP(r5, r5, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r5, r5, Operand(kSystemPointerSizeLog2)); __ LoadP(kJavaScriptCallCodeStartRegister, MemOperand(kInterpreterDispatchTableRegister, r5)); __ Call(kJavaScriptCallCodeStartRegister); @@ -1285,8 +1270,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { LeaveInterpreterFrame(masm, r4); __ Ret(); + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry, r8); + __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); __ bkpt(0); // Should not return. } @@ -1296,11 +1299,11 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, Label loop, skip; __ CmpP(count, Operand::Zero()); __ beq(&skip); - __ AddP(index, index, Operand(kPointerSize)); // Bias up for LoadPU + __ AddP(index, index, Operand(kSystemPointerSize)); // Bias up for LoadPU __ LoadRR(r0, count); __ bind(&loop); - __ LoadP(scratch, MemOperand(index, -kPointerSize)); - __ lay(index, MemOperand(index, -kPointerSize)); + __ LoadP(scratch, MemOperand(index, -kSystemPointerSize)); + __ lay(index, MemOperand(index, -kSystemPointerSize)); __ push(scratch); __ SubP(r0, Operand(1)); __ bne(&loop); @@ -1474,7 +1477,7 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { Register scratch = temps.Acquire(); __ LoadlB(scratch, MemOperand(kInterpreterBytecodeArrayRegister, kInterpreterBytecodeOffsetRegister)); - __ ShiftLeftP(scratch, scratch, Operand(kPointerSizeLog2)); + __ ShiftLeftP(scratch, scratch, Operand(kSystemPointerSizeLog2)); __ LoadP(kJavaScriptCallCodeStartRegister, MemOperand(kInterpreterDispatchTableRegister, scratch)); __ Jump(kJavaScriptCallCodeStartRegister); @@ -1540,7 +1543,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { } for (int i = j - 1; i >= 0; --i) { __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerSPOffset + - i * kPointerSize)); + i * kSystemPointerSize)); __ push(r6); } for (int i = 0; i < 3 - j; ++i) { @@ -1589,9 +1592,10 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, // Overwrite the hole inserted by the deoptimizer with the return value from // the LAZY deopt point. __ StoreP( - r2, MemOperand( - sp, config->num_allocatable_general_registers() * kPointerSize + - BuiltinContinuationFrameConstants::kFixedFrameSize)); + r2, + MemOperand(sp, config->num_allocatable_general_registers() * + kSystemPointerSize + + BuiltinContinuationFrameConstants::kFixedFrameSize)); } for (int i = allocatable_register_count - 1; i >= 0; --i) { int code = config->GetAllocatableGeneralCode(i); @@ -1647,14 +1651,8 @@ void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ LoadP(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); - __ LoadP(r2, MemOperand(r2, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ push(r2); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -1707,16 +1705,16 @@ void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) { Register arg_size = r7; Register new_sp = r5; Register scratch = r6; - __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(arg_size, r2, Operand(kSystemPointerSizeLog2)); __ AddP(new_sp, sp, arg_size); __ LoadRoot(scratch, RootIndex::kUndefinedValue); __ LoadRR(r4, scratch); __ LoadP(r3, MemOperand(new_sp, 0)); // receiver - __ CmpP(arg_size, Operand(kPointerSize)); + __ CmpP(arg_size, Operand(kSystemPointerSize)); __ blt(&skip); - __ LoadP(scratch, MemOperand(new_sp, 1 * -kPointerSize)); // thisArg + __ LoadP(scratch, MemOperand(new_sp, 1 * -kSystemPointerSize)); // thisArg __ beq(&skip); - __ LoadP(r4, MemOperand(new_sp, 2 * -kPointerSize)); // argArray + __ LoadP(r4, MemOperand(new_sp, 2 * -kSystemPointerSize)); // argArray __ bind(&skip); __ LoadRR(sp, new_sp); __ StoreP(scratch, MemOperand(sp, 0)); @@ -1765,7 +1763,7 @@ void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { // r2: actual number of arguments // 2. Get the callable to call (passed as receiver) from the stack. - __ ShiftLeftP(r4, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r4, r2, Operand(kSystemPointerSizeLog2)); __ LoadP(r3, MemOperand(sp, r4)); // 3. Shift arguments and return address one slot down on the stack @@ -1780,9 +1778,9 @@ void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { __ AddP(r4, sp, r4); __ bind(&loop); - __ LoadP(scratch, MemOperand(r4, -kPointerSize)); + __ LoadP(scratch, MemOperand(r4, -kSystemPointerSize)); __ StoreP(scratch, MemOperand(r4)); - __ SubP(r4, Operand(kPointerSize)); + __ SubP(r4, Operand(kSystemPointerSize)); __ CmpP(r4, sp); __ bne(&loop); // Adjust the actual number of arguments and remove the top element @@ -1812,19 +1810,20 @@ void Builtins::Generate_ReflectApply(MacroAssembler* masm) { Register arg_size = r7; Register new_sp = r5; Register scratch = r6; - __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(arg_size, r2, Operand(kSystemPointerSizeLog2)); __ AddP(new_sp, sp, arg_size); __ LoadRoot(r3, RootIndex::kUndefinedValue); __ LoadRR(scratch, r3); __ LoadRR(r4, r3); - __ CmpP(arg_size, Operand(kPointerSize)); + __ CmpP(arg_size, Operand(kSystemPointerSize)); __ blt(&skip); - __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target + __ LoadP(r3, MemOperand(new_sp, 1 * -kSystemPointerSize)); // target __ beq(&skip); - __ LoadP(scratch, MemOperand(new_sp, 2 * -kPointerSize)); // thisArgument - __ CmpP(arg_size, Operand(2 * kPointerSize)); + __ LoadP(scratch, + MemOperand(new_sp, 2 * -kSystemPointerSize)); // thisArgument + __ CmpP(arg_size, Operand(2 * kSystemPointerSize)); __ beq(&skip); - __ LoadP(r4, MemOperand(new_sp, 3 * -kPointerSize)); // argumentsList + __ LoadP(r4, MemOperand(new_sp, 3 * -kSystemPointerSize)); // argumentsList __ bind(&skip); __ LoadRR(sp, new_sp); __ StoreP(scratch, MemOperand(sp, 0)); @@ -1862,21 +1861,21 @@ void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { Label skip; Register arg_size = r7; Register new_sp = r6; - __ ShiftLeftP(arg_size, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(arg_size, r2, Operand(kSystemPointerSizeLog2)); __ AddP(new_sp, sp, arg_size); __ LoadRoot(r3, RootIndex::kUndefinedValue); __ LoadRR(r4, r3); __ LoadRR(r5, r3); __ StoreP(r3, MemOperand(new_sp, 0)); // receiver (undefined) - __ CmpP(arg_size, Operand(kPointerSize)); + __ CmpP(arg_size, Operand(kSystemPointerSize)); __ blt(&skip); - __ LoadP(r3, MemOperand(new_sp, 1 * -kPointerSize)); // target + __ LoadP(r3, MemOperand(new_sp, 1 * -kSystemPointerSize)); // target __ LoadRR(r5, r3); // new.target defaults to target __ beq(&skip); - __ LoadP(r4, MemOperand(new_sp, 2 * -kPointerSize)); // argumentsList - __ CmpP(arg_size, Operand(2 * kPointerSize)); + __ LoadP(r4, MemOperand(new_sp, 2 * -kSystemPointerSize)); // argumentsList + __ CmpP(arg_size, Operand(2 * kSystemPointerSize)); __ beq(&skip); - __ LoadP(r5, MemOperand(new_sp, 3 * -kPointerSize)); // new.target + __ LoadP(r5, MemOperand(new_sp, 3 * -kSystemPointerSize)); // new.target __ bind(&skip); __ LoadRR(sp, new_sp); } @@ -1912,15 +1911,15 @@ static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { // Function // ArgC as SMI // Padding <--- New SP - __ lay(sp, MemOperand(sp, -5 * kPointerSize)); + __ lay(sp, MemOperand(sp, -5 * kSystemPointerSize)); // Cleanse the top nibble of 31-bit pointers. __ CleanseP(r14); - __ StoreP(r14, MemOperand(sp, 4 * kPointerSize)); - __ StoreP(fp, MemOperand(sp, 3 * kPointerSize)); - __ StoreP(r6, MemOperand(sp, 2 * kPointerSize)); - __ StoreP(r3, MemOperand(sp, 1 * kPointerSize)); - __ StoreP(r2, MemOperand(sp, 0 * kPointerSize)); + __ StoreP(r14, MemOperand(sp, 4 * kSystemPointerSize)); + __ StoreP(fp, MemOperand(sp, 3 * kSystemPointerSize)); + __ StoreP(r6, MemOperand(sp, 2 * kSystemPointerSize)); + __ StoreP(r3, MemOperand(sp, 1 * kSystemPointerSize)); + __ StoreP(r2, MemOperand(sp, 0 * kSystemPointerSize)); __ Push(Smi::zero()); // Padding. __ la(fp, MemOperand(sp, ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp)); @@ -1933,7 +1932,7 @@ static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { // Get the number of arguments passed (as a smi), tear down the frame and // then tear down the parameters. __ LoadP(r3, MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset)); - int stack_adjustment = kPointerSize; // adjust for receiver + int stack_adjustment = kSystemPointerSize; // adjust for receiver __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment); __ SmiToPtrArrayOffset(r3, r3); __ lay(sp, MemOperand(sp, r3)); @@ -1981,12 +1980,13 @@ void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, Label loop, no_args, skip; __ CmpP(r6, Operand::Zero()); __ beq(&no_args); - __ AddP(r4, r4, - Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize)); + __ AddP( + r4, r4, + Operand(FixedArray::kHeaderSize - kHeapObjectTag - kSystemPointerSize)); __ LoadRR(r1, r6); __ bind(&loop); - __ LoadP(scratch, MemOperand(r4, kPointerSize)); - __ la(r4, MemOperand(r4, kPointerSize)); + __ LoadP(scratch, MemOperand(r4, kSystemPointerSize)); + __ la(r4, MemOperand(r4, kSystemPointerSize)); __ CompareRoot(scratch, RootIndex::kTheHoleValue); __ bne(&skip, Label::kNear); __ LoadRoot(scratch, RootIndex::kUndefinedValue); @@ -2070,11 +2070,11 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, // Forward the arguments from the caller frame. { Label loop; - __ AddP(r6, r6, Operand(kPointerSize)); + __ AddP(r6, r6, Operand(kSystemPointerSize)); __ AddP(r2, r2, r7); __ bind(&loop); { - __ ShiftLeftP(scratch, r7, Operand(kPointerSizeLog2)); + __ ShiftLeftP(scratch, r7, Operand(kSystemPointerSizeLog2)); __ LoadP(scratch, MemOperand(r6, scratch)); __ push(scratch); __ SubP(r7, r7, Operand(1)); @@ -2132,7 +2132,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, __ LoadGlobalProxy(r5); } else { Label convert_to_object, convert_receiver; - __ ShiftLeftP(r5, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r5, r2, Operand(kSystemPointerSizeLog2)); __ LoadP(r5, MemOperand(sp, r5)); __ JumpIfSmi(r5, &convert_to_object); STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); @@ -2169,7 +2169,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, __ LoadP(r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); __ bind(&convert_receiver); } - __ ShiftLeftP(r6, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r6, r2, Operand(kSystemPointerSizeLog2)); __ StoreP(r5, MemOperand(sp, r6)); } __ bind(&done_convert); @@ -2226,7 +2226,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { { Label done; __ LoadRR(scratch, sp); // preserve previous stack pointer - __ ShiftLeftP(r9, r6, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r9, r6, Operand(kSystemPointerSizeLog2)); __ SubP(sp, sp, r9); // Check the stack for overflow. We are not trying to catch interruptions // (i.e. debug break and preemption) here, so check the "real stack @@ -2256,7 +2256,7 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ bind(&loop); __ LoadP(r0, MemOperand(scratch, r7)); __ StoreP(r0, MemOperand(sp, r7)); - __ AddP(r7, r7, Operand(kPointerSize)); + __ AddP(r7, r7, Operand(kSystemPointerSize)); __ BranchOnCount(r1, &loop); __ bind(&skip); } @@ -2268,10 +2268,10 @@ void Generate_PushBoundArguments(MacroAssembler* masm) { __ AddP(r4, r4, r9); __ LoadRR(r1, r6); __ bind(&loop); - __ LoadP(r0, MemOperand(r4, -kPointerSize)); - __ lay(r4, MemOperand(r4, -kPointerSize)); + __ LoadP(r0, MemOperand(r4, -kSystemPointerSize)); + __ lay(r4, MemOperand(r4, -kSystemPointerSize)); __ StoreP(r0, MemOperand(sp, r7)); - __ AddP(r7, r7, Operand(kPointerSize)); + __ AddP(r7, r7, Operand(kSystemPointerSize)); __ BranchOnCount(r1, &loop); __ AddP(r2, r2, r6); } @@ -2291,7 +2291,7 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) { // Patch the receiver to [[BoundThis]]. __ LoadP(r5, FieldMemOperand(r3, JSBoundFunction::kBoundThisOffset)); - __ ShiftLeftP(r1, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r1, r2, Operand(kSystemPointerSizeLog2)); __ StoreP(r5, MemOperand(sp, r1)); // Push the [[BoundArguments]] onto the stack. @@ -2311,7 +2311,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // -- r3 : the target to call (can be any Object). // ----------------------------------- - Label non_callable, non_function, non_smi; + Label non_callable, non_smi; __ JumpIfSmi(r3, &non_callable); __ bind(&non_smi); __ CompareObjectType(r3, r6, r7, JS_FUNCTION_TYPE); @@ -2328,14 +2328,12 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) { // Check if target is a proxy and call CallProxy external builtin __ CmpP(r7, Operand(JS_PROXY_TYPE)); - __ bne(&non_function); - __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET); + __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq); // 2. Call to something else, which might have a [[Call]] internal method (if // not we raise an exception). - __ bind(&non_function); // Overwrite the original receiver the (original) target. - __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r7, r2, Operand(kSystemPointerSizeLog2)); __ StoreP(r3, MemOperand(sp, r7)); // Let the "call_as_function_delegate" take care of the rest. __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r3); @@ -2449,7 +2447,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { __ bind(&non_proxy); { // Overwrite the original receiver with the (original) target. - __ ShiftLeftP(r7, r2, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r7, r2, Operand(kSystemPointerSizeLog2)); __ StoreP(r3, MemOperand(sp, r7)); // Let the "call_as_constructor_delegate" take care of the rest. __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, r3); @@ -2504,8 +2502,8 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { __ SmiToPtrArrayOffset(r2, r2); __ AddP(r2, fp); // adjust for return address and receiver - __ AddP(r2, r2, Operand(2 * kPointerSize)); - __ ShiftLeftP(r6, r4, Operand(kPointerSizeLog2)); + __ AddP(r2, r2, Operand(2 * kSystemPointerSize)); + __ ShiftLeftP(r6, r4, Operand(kSystemPointerSizeLog2)); __ SubP(r6, r2, r6); // Copy the arguments (including the receiver) to the new stack frame. @@ -2520,7 +2518,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { __ LoadP(r0, MemOperand(r2, 0)); __ push(r0); __ CmpP(r2, r6); // Compare before moving to next argument. - __ lay(r2, MemOperand(r2, -kPointerSize)); + __ lay(r2, MemOperand(r2, -kSystemPointerSize)); __ bne(©); __ b(&invoke); @@ -2548,22 +2546,22 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { Label copy; __ bind(©); // Adjust load for return address and receiver. - __ LoadP(r0, MemOperand(r2, 2 * kPointerSize)); + __ LoadP(r0, MemOperand(r2, 2 * kSystemPointerSize)); __ push(r0); __ CmpP(r2, fp); // Compare before moving to next argument. - __ lay(r2, MemOperand(r2, -kPointerSize)); + __ lay(r2, MemOperand(r2, -kSystemPointerSize)); __ bne(©); // Fill the remaining expected arguments with undefined. // r3: function // r4: expected number of argumentus __ LoadRoot(r0, RootIndex::kUndefinedValue); - __ ShiftLeftP(r6, r4, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r6, r4, Operand(kSystemPointerSizeLog2)); __ SubP(r6, fp, r6); // Adjust for frame. __ SubP(r6, r6, Operand(ArgumentsAdaptorFrameConstants::kFixedFrameSizeFromFp + - kPointerSize)); + kSystemPointerSize)); Label fill; __ bind(&fill); @@ -2608,7 +2606,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { // Remove superfluous parameters from the stack. __ SubP(r6, r2, r4); __ lgr(r2, r4); - __ ShiftLeftP(r6, r6, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r6, r6, Operand(kSystemPointerSizeLog2)); __ lay(sp, MemOperand(sp, r6)); __ b(&dont_adapt_arguments); } @@ -2708,8 +2706,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, __ LoadRR(r3, r4); } else { // Compute the argv pointer. - __ ShiftLeftP(r3, r2, Operand(kPointerSizeLog2)); - __ lay(r3, MemOperand(r3, sp, -kPointerSize)); + __ ShiftLeftP(r3, r2, Operand(kSystemPointerSizeLog2)); + __ lay(r3, MemOperand(r3, sp, -kSystemPointerSize)); } // Enter the exit frame that transitions from JavaScript to C++. @@ -2751,7 +2749,8 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, // by one register each. __ LoadRR(r4, r3); __ LoadRR(r3, r2); - __ la(r2, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize)); + __ la(r2, + MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kSystemPointerSize)); isolate_reg = r5; // Clang doesn't preserve r2 (result buffer) // write to r8 (preserved) before entry @@ -2765,7 +2764,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, // If return value is on the stack, pop it to registers. if (needs_return_buffer) { __ LoadRR(r2, r8); - __ LoadP(r3, MemOperand(r2, kPointerSize)); + __ LoadP(r3, MemOperand(r2, kSystemPointerSize)); __ LoadP(r2, MemOperand(r2)); } @@ -2870,7 +2869,7 @@ void Builtins::Generate_DoubleToI(MacroAssembler* masm) { __ Push(result_reg, scratch); // Account for saved regs. - int argument_offset = 2 * kPointerSize; + int argument_offset = 2 * kSystemPointerSize; // Load double input. __ LoadDouble(double_scratch, MemOperand(sp, argument_offset)); @@ -2884,7 +2883,7 @@ void Builtins::Generate_DoubleToI(MacroAssembler* masm) { __ Push(scratch_high, scratch_low); // Account for saved regs. - argument_offset += 2 * kPointerSize; + argument_offset += 2 * kSystemPointerSize; __ LoadlW(scratch_high, MemOperand(sp, argument_offset + Register::kExponentOffset)); @@ -2958,7 +2957,7 @@ void Builtins::Generate_DoubleToI(MacroAssembler* masm) { __ bind(&done); __ Pop(scratch_high, scratch_low); - argument_offset -= 2 * kPointerSize; + argument_offset -= 2 * kSystemPointerSize; __ bind(&fastpath_done); __ StoreP(result_reg, MemOperand(sp, argument_offset)); @@ -3159,33 +3158,33 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { // Set up FunctionCallbackInfo's implicit_args on the stack as follows: // // Target state: - // sp[0 * kPointerSize]: kHolder - // sp[1 * kPointerSize]: kIsolate - // sp[2 * kPointerSize]: undefined (kReturnValueDefaultValue) - // sp[3 * kPointerSize]: undefined (kReturnValue) - // sp[4 * kPointerSize]: kData - // sp[5 * kPointerSize]: undefined (kNewTarget) + // sp[0 * kSystemPointerSize]: kHolder + // sp[1 * kSystemPointerSize]: kIsolate + // sp[2 * kSystemPointerSize]: undefined (kReturnValueDefaultValue) + // sp[3 * kSystemPointerSize]: undefined (kReturnValue) + // sp[4 * kSystemPointerSize]: kData + // sp[5 * kSystemPointerSize]: undefined (kNewTarget) // Reserve space on the stack. - __ lay(sp, MemOperand(sp, -(FCA::kArgsLength * kPointerSize))); + __ lay(sp, MemOperand(sp, -(FCA::kArgsLength * kSystemPointerSize))); // kHolder. - __ StoreP(holder, MemOperand(sp, 0 * kPointerSize)); + __ StoreP(holder, MemOperand(sp, 0 * kSystemPointerSize)); // kIsolate. __ Move(scratch, ExternalReference::isolate_address(masm->isolate())); - __ StoreP(scratch, MemOperand(sp, 1 * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, 1 * kSystemPointerSize)); // kReturnValueDefaultValue and kReturnValue. __ LoadRoot(scratch, RootIndex::kUndefinedValue); - __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize)); - __ StoreP(scratch, MemOperand(sp, 3 * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, 2 * kSystemPointerSize)); + __ StoreP(scratch, MemOperand(sp, 3 * kSystemPointerSize)); // kData. - __ StoreP(call_data, MemOperand(sp, 4 * kPointerSize)); + __ StoreP(call_data, MemOperand(sp, 4 * kSystemPointerSize)); // kNewTarget. - __ StoreP(scratch, MemOperand(sp, 5 * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, 5 * kSystemPointerSize)); // Keep a pointer to kHolder (= implicit_args) in a scratch register. // We use it below to set up the FunctionCallbackInfo object. @@ -3207,33 +3206,34 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { // FunctionCallbackInfo::implicit_args_ (points at kHolder as set up above). // Arguments are after the return address (pushed by EnterExitFrame()). - __ StoreP(scratch, - MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * + kSystemPointerSize)); // FunctionCallbackInfo::values_ (points at the first varargs argument passed // on the stack). - __ AddP(scratch, scratch, Operand((FCA::kArgsLength - 1) * kPointerSize)); - __ ShiftLeftP(r1, argc, Operand(kPointerSizeLog2)); + __ AddP(scratch, scratch, + Operand((FCA::kArgsLength - 1) * kSystemPointerSize)); + __ ShiftLeftP(r1, argc, Operand(kSystemPointerSizeLog2)); __ AddP(scratch, scratch, r1); - __ StoreP(scratch, - MemOperand(sp, (kStackFrameExtraParamSlot + 2) * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, (kStackFrameExtraParamSlot + 2) * + kSystemPointerSize)); // FunctionCallbackInfo::length_. - __ StoreW(argc, - MemOperand(sp, (kStackFrameExtraParamSlot + 3) * kPointerSize)); + __ StoreW(argc, MemOperand(sp, (kStackFrameExtraParamSlot + 3) * + kSystemPointerSize)); // We also store the number of bytes to drop from the stack after returning // from the API function here. __ mov(scratch, - Operand((FCA::kArgsLength + 1 /* receiver */) * kPointerSize)); - __ ShiftLeftP(r1, argc, Operand(kPointerSizeLog2)); + Operand((FCA::kArgsLength + 1 /* receiver */) * kSystemPointerSize)); + __ ShiftLeftP(r1, argc, Operand(kSystemPointerSizeLog2)); __ AddP(scratch, r1); - __ StoreP(scratch, - MemOperand(sp, (kStackFrameExtraParamSlot + 4) * kPointerSize)); + __ StoreP(scratch, MemOperand(sp, (kStackFrameExtraParamSlot + 4) * + kSystemPointerSize)); // v8::InvocationCallback's argument. __ lay(r2, - MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize)); + MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kSystemPointerSize)); ExternalReference thunk_ref = ExternalReference::invoke_function_callback(); @@ -3241,11 +3241,11 @@ void Builtins::Generate_CallApiCallback(MacroAssembler* masm) { // TODO(jgruber): Document what these arguments are. static constexpr int kStackSlotsAboveFCA = 2; MemOperand return_value_operand( - fp, (kStackSlotsAboveFCA + FCA::kReturnValueOffset) * kPointerSize); + fp, (kStackSlotsAboveFCA + FCA::kReturnValueOffset) * kSystemPointerSize); static constexpr int kUseStackSpaceOperand = 0; MemOperand stack_space_operand( - sp, (kStackFrameExtraParamSlot + 4) * kPointerSize); + sp, (kStackFrameExtraParamSlot + 4) * kSystemPointerSize); AllowExternalCallThatCantCauseGC scope(masm); CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, @@ -3293,7 +3293,7 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { // Load address of v8::PropertyAccessorInfo::args_ array and name handle. __ LoadRR(r2, sp); // r2 = Handle<Name> - __ AddP(r3, r2, Operand(1 * kPointerSize)); // r3 = v8::PCI::args_ + __ AddP(r3, r2, Operand(1 * kSystemPointerSize)); // r3 = v8::PCI::args_ // If ABI passes Handles (pointer-sized struct) in a register: // @@ -3321,14 +3321,14 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { if (!ABI_PASSES_HANDLES_IN_REGS) { // pass 1st arg by reference - __ StoreP(r2, MemOperand(sp, arg0Slot * kPointerSize)); - __ AddP(r2, sp, Operand(arg0Slot * kPointerSize)); + __ StoreP(r2, MemOperand(sp, arg0Slot * kSystemPointerSize)); + __ AddP(r2, sp, Operand(arg0Slot * kSystemPointerSize)); } // Create v8::PropertyCallbackInfo object on the stack and initialize // it's args_ field. - __ StoreP(r3, MemOperand(sp, accessorInfoSlot * kPointerSize)); - __ AddP(r3, sp, Operand(accessorInfoSlot * kPointerSize)); + __ StoreP(r3, MemOperand(sp, accessorInfoSlot * kSystemPointerSize)); + __ AddP(r3, sp, Operand(accessorInfoSlot * kSystemPointerSize)); // r3 = v8::PropertyCallbackInfo& ExternalReference thunk_ref = @@ -3340,7 +3340,8 @@ void Builtins::Generate_CallApiGetter(MacroAssembler* masm) { // +3 is to skip prolog, return address and name handle. MemOperand return_value_operand( - fp, (PropertyCallbackArguments::kReturnValueOffset + 3) * kPointerSize); + fp, + (PropertyCallbackArguments::kReturnValueOffset + 3) * kSystemPointerSize); MemOperand* const kUseStackSpaceConstant = nullptr; CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, kStackUnwindSpace, kUseStackSpaceConstant, diff --git a/deps/v8/src/builtins/setup-builtins-internal.cc b/deps/v8/src/builtins/setup-builtins-internal.cc index e93d7008e47b96..e3f39a0906a350 100644 --- a/deps/v8/src/builtins/setup-builtins-internal.cc +++ b/deps/v8/src/builtins/setup-builtins-internal.cc @@ -264,22 +264,17 @@ void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) { namespace { Code GenerateBytecodeHandler(Isolate* isolate, int builtin_index, - const char* name, interpreter::OperandScale operand_scale, interpreter::Bytecode bytecode) { DCHECK(interpreter::Bytecodes::BytecodeHasHandler(bytecode, operand_scale)); Handle<Code> code = interpreter::GenerateBytecodeHandler( - isolate, bytecode, operand_scale, builtin_index, - BuiltinAssemblerOptions(isolate, builtin_index)); + isolate, Builtins::name(builtin_index), bytecode, operand_scale, + builtin_index, BuiltinAssemblerOptions(isolate, builtin_index)); return *code; } } // namespace -#ifdef _MSC_VER -#pragma optimize( "", off ) -#endif - // static void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { Builtins* builtins = isolate->builtins(); @@ -318,9 +313,8 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { CallDescriptors::InterfaceDescriptor, #Name); \ AddBuiltin(builtins, index++, code); -#define BUILD_BCH(Name, OperandScale, Bytecode) \ - code = GenerateBytecodeHandler(isolate, index, Builtins::name(index), \ - OperandScale, Bytecode); \ +#define BUILD_BCH(Name, OperandScale, Bytecode) \ + code = GenerateBytecodeHandler(isolate, index, OperandScale, Bytecode); \ AddBuiltin(builtins, index++, code); #define BUILD_ASM(Name, InterfaceDescriptor) \ @@ -357,10 +351,5 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { builtins->MarkInitialized(); } -#ifdef _MSC_VER -#pragma optimize( "", on ) -#endif - - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/string-endswith.tq b/deps/v8/src/builtins/string-endswith.tq index c3cc7d949b716c..9590b853e793a3 100644 --- a/deps/v8/src/builtins/string-endswith.tq +++ b/deps/v8/src/builtins/string-endswith.tq @@ -41,7 +41,7 @@ namespace string { // 3. Let isRegExp be ? IsRegExp(searchString). // 4. If isRegExp is true, throw a TypeError exception. - if (IsRegExp(searchString)) { + if (regexp::IsRegExp(searchString)) { ThrowTypeError(kFirstArgumentNotRegExp, kBuiltinName); } diff --git a/deps/v8/src/builtins/string-iterator.tq b/deps/v8/src/builtins/string-iterator.tq index d36a44fa97d05e..b0bbb8d4a35dc2 100644 --- a/deps/v8/src/builtins/string-iterator.tq +++ b/deps/v8/src/builtins/string-iterator.tq @@ -11,7 +11,7 @@ namespace string_iterator { properties_or_hash: kEmptyFixedArray, elements: kEmptyFixedArray, string: string, - next_index: nextIndex + index: nextIndex }; } @@ -31,7 +31,7 @@ namespace string_iterator { kIncompatibleMethodReceiver, 'String Iterator.prototype.next', receiver); const string = iterator.string; - const position: intptr = SmiUntag(iterator.next_index); + const position: intptr = SmiUntag(iterator.index); const length: intptr = string.length_intptr; if (position >= length) { return AllocateJSIteratorResult(Undefined, True); @@ -40,7 +40,7 @@ namespace string_iterator { const encoding = UTF16; const ch = string::LoadSurrogatePairAt(string, length, position, encoding); const value: String = string::StringFromSingleUTF16EncodedCodePoint(ch); - iterator.next_index = SmiTag(position + value.length_intptr); + iterator.index = SmiTag(position + value.length_intptr); return AllocateJSIteratorResult(value, False); } } diff --git a/deps/v8/src/builtins/string-slice.tq b/deps/v8/src/builtins/string-slice.tq index 661cc264c50418..b5ddbdb2ccbe74 100644 --- a/deps/v8/src/builtins/string-slice.tq +++ b/deps/v8/src/builtins/string-slice.tq @@ -4,7 +4,8 @@ namespace string_slice { - extern macro SubString(String, intptr, intptr): String; + extern macro StringBuiltinsAssembler::SubString(String, intptr, intptr): + String; // ES6 #sec-string.prototype.slice ( start, end ) // https://tc39.github.io/ecma262/#sec-string.prototype.slice diff --git a/deps/v8/src/builtins/string-startswith.tq b/deps/v8/src/builtins/string-startswith.tq index 7fa7ec6d5ce952..3238f52b86bd20 100644 --- a/deps/v8/src/builtins/string-startswith.tq +++ b/deps/v8/src/builtins/string-startswith.tq @@ -5,9 +5,6 @@ #include 'src/builtins/builtins-regexp-gen.h' namespace string { - extern macro RegExpBuiltinsAssembler::IsRegExp(implicit context: - Context)(Object): bool; - // https://tc39.github.io/ecma262/#sec-string.prototype.startswith transitioning javascript builtin StringPrototypeStartsWith( js-implicit context: Context, receiver: JSAny)(...arguments): Boolean { @@ -23,7 +20,7 @@ namespace string { // 3. Let isRegExp be ? IsRegExp(searchString). // 4. If isRegExp is true, throw a TypeError exception. - if (IsRegExp(searchString)) { + if (regexp::IsRegExp(searchString)) { ThrowTypeError(kFirstArgumentNotRegExp, kBuiltinName); } diff --git a/deps/v8/src/builtins/string-substring.tq b/deps/v8/src/builtins/string-substring.tq index c97b294a34fedd..813dc35ab2817b 100644 --- a/deps/v8/src/builtins/string-substring.tq +++ b/deps/v8/src/builtins/string-substring.tq @@ -4,7 +4,8 @@ namespace string_substring { - extern macro SubString(String, intptr, intptr): String; + extern macro StringBuiltinsAssembler::SubString(String, intptr, intptr): + String; transitioning macro ToSmiBetweenZeroAnd(implicit context: Context)( value: JSAny, limit: Smi): Smi { diff --git a/deps/v8/src/builtins/string.tq b/deps/v8/src/builtins/string.tq index 7f007680e93b73..4f2c342fd554b9 100644 --- a/deps/v8/src/builtins/string.tq +++ b/deps/v8/src/builtins/string.tq @@ -21,7 +21,8 @@ namespace string { extern macro StringBuiltinsAssembler::LoadSurrogatePairAt( String, intptr, intptr, constexpr UnicodeEncoding): int32; - extern macro StringFromSingleUTF16EncodedCodePoint(int32): String; + extern macro StringBuiltinsAssembler::StringFromSingleUTF16EncodedCodePoint( + int32): String; // This function assumes StringPrimitiveWithNoCustomIteration is true. transitioning builtin StringToList(implicit context: Context)(string: String): @@ -187,4 +188,12 @@ namespace string { left: String, right: JSAny): String { return left + ToStringImpl(context, ToPrimitiveDefault(right)); } + + builtin StringCharAt(implicit context: Context)( + receiver: String, position: intptr): String { + // Load the character code at the {position} from the {receiver}. + const code: int32 = StringCharCodeAt(receiver, position); + // And return the single character string with only that {code} + return StringFromSingleCharCode(code); + } } diff --git a/deps/v8/src/builtins/typed-array-createtypedarray.tq b/deps/v8/src/builtins/typed-array-createtypedarray.tq index a476739861684f..a6bd445e34a483 100644 --- a/deps/v8/src/builtins/typed-array-createtypedarray.tq +++ b/deps/v8/src/builtins/typed-array-createtypedarray.tq @@ -27,21 +27,16 @@ namespace typed_array_createtypedarray { isOnHeap: constexpr bool, map: Map, buffer: JSArrayBuffer, byteOffset: uintptr, byteLength: uintptr, length: uintptr): JSTypedArray { let elements: ByteArray; - let externalPointer: RawPtr; - let basePointer: ByteArray | Smi; if constexpr (isOnHeap) { elements = AllocateByteArray(byteLength); - basePointer = elements; - externalPointer = PointerConstant(kExternalPointerForOnHeapArray); } else { - basePointer = Convert<Smi>(0); + elements = kEmptyByteArray; // The max byteOffset is 8 * MaxSmi on the particular platform. 32 bit // platforms are self-limiting, because we can't allocate an array bigger // than our 32-bit arithmetic range anyway. 64 bit platforms could // theoretically have an offset up to 2^35 - 1. - const backingStore: RawPtr = buffer.backing_store; - externalPointer = backingStore + Convert<intptr>(byteOffset); + const backingStore: uintptr = Convert<uintptr>(buffer.backing_store); // Assert no overflow has occurred. Only assert if the mock array buffer // allocator is NOT used. When the mock array buffer is used, impossibly @@ -49,9 +44,7 @@ namespace typed_array_createtypedarray { // and this assertion to fail. assert( IsMockArrayBufferAllocatorFlag() || - Convert<uintptr>(externalPointer) >= Convert<uintptr>(backingStore)); - - elements = kEmptyByteArray; + (backingStore + byteOffset) >= backingStore); } // We can't just build the new object with "new JSTypedArray" here because @@ -64,8 +57,16 @@ namespace typed_array_createtypedarray { typedArray.byte_offset = byteOffset; typedArray.byte_length = byteLength; typedArray.length = length; - typedArray.external_pointer = externalPointer; - typedArray.base_pointer = basePointer; + if constexpr (isOnHeap) { + typed_array::SetJSTypedArrayOnHeapDataPtr( + typedArray, elements, byteOffset); + } else { + typed_array::SetJSTypedArrayOffHeapDataPtr( + typedArray, buffer.backing_store, byteOffset); + assert( + typedArray.data_ptr == + (buffer.backing_store + Convert<intptr>(byteOffset))); + } SetupTypedArrayEmbedderFields(typedArray); return typedArray; } diff --git a/deps/v8/src/builtins/typed-array-slice.tq b/deps/v8/src/builtins/typed-array-slice.tq index dc13865590e051..d17ff4a3756b1c 100644 --- a/deps/v8/src/builtins/typed-array-slice.tq +++ b/deps/v8/src/builtins/typed-array-slice.tq @@ -23,7 +23,7 @@ namespace typed_array_slice { // of src and result array are the same and they are not sharing the // same buffer, use memmove. if (srcKind != destInfo.kind) goto IfSlow; - if (BitcastTaggedToWord(dest.buffer) == BitcastTaggedToWord(src.buffer)) { + if (dest.buffer == src.buffer) { goto IfSlow; } diff --git a/deps/v8/src/builtins/typed-array.tq b/deps/v8/src/builtins/typed-array.tq index 59100736a5dc7b..1c901abf752195 100644 --- a/deps/v8/src/builtins/typed-array.tq +++ b/deps/v8/src/builtins/typed-array.tq @@ -71,12 +71,17 @@ namespace typed_array { ElementsKind): bool; extern macro LoadFixedTypedArrayElementAsTagged( RawPtr, Smi, constexpr ElementsKind): Numeric; - extern macro StoreJSTypedArrayElementFromTagged( + extern macro TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromTagged( Context, JSTypedArray, Smi, JSAny, constexpr ElementsKind); type LoadFn = builtin(Context, JSTypedArray, Smi) => JSAny; type StoreFn = builtin(Context, JSTypedArray, Smi, JSAny) => JSAny; + extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr( + JSTypedArray, ByteArray, uintptr): void; + extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOffHeapDataPtr( + JSTypedArray, RawPtr, uintptr): void; + // AttachedJSTypedArray guards that the array's buffer is not detached. transient type AttachedJSTypedArray extends JSTypedArray; @@ -198,7 +203,7 @@ namespace typed_array { builtin StoreFixedElement<T: type>( context: Context, typedArray: JSTypedArray, index: Smi, value: JSAny): JSAny { - StoreJSTypedArrayElementFromTagged( + typed_array::StoreJSTypedArrayElementFromTagged( context, typedArray, index, value, KindForArrayType<T>()); return Undefined; } diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc index b6b407fb3322ef..9679237ff820f7 100644 --- a/deps/v8/src/builtins/x64/builtins-x64.cc +++ b/deps/v8/src/builtins/x64/builtins-x64.cc @@ -5,8 +5,9 @@ #if V8_TARGET_ARCH_X64 #include "src/api/api-arguments.h" -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/codegen/code-factory.h" +#include "src/codegen/x64/assembler-x64.h" #include "src/deoptimizer/deoptimizer.h" #include "src/execution/frame-constants.h" #include "src/execution/frames.h" @@ -401,13 +402,13 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, __ pushq(r13); __ pushq(r14); __ pushq(r15); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN __ pushq(rdi); // Only callee save in Win64 ABI, argument in AMD64 ABI. __ pushq(rsi); // Only callee save in Win64 ABI, argument in AMD64 ABI. #endif __ pushq(rbx); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // On Win64 XMM6-XMM15 are callee-save. __ AllocateStackSpace(EntryFrameConstants::kXMMRegistersBlockSize); __ movdqu(Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0), xmm6); @@ -507,7 +508,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, } // Restore callee-saved registers (X64 conventions). -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // On Win64 XMM6-XMM15 are callee-save __ movdqu(xmm6, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 0)); __ movdqu(xmm7, Operand(rsp, EntryFrameConstants::kXMMRegisterSize * 1)); @@ -523,7 +524,7 @@ void Generate_JSEntryVariant(MacroAssembler* masm, StackFrame::Type type, #endif __ popq(rbx); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Callee save on in Win64 ABI, arguments/volatile in AMD64 ABI. __ popq(rsi); __ popq(rdi); @@ -611,17 +612,17 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, __ Push(rdi); __ Push(arg_reg_4); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Load the previous frame pointer to access C arguments on stack __ movq(kScratchRegister, Operand(rbp, 0)); // Load the number of arguments and setup pointer to the arguments. __ movq(rax, Operand(kScratchRegister, EntryFrameConstants::kArgcOffset)); __ movq(rbx, Operand(kScratchRegister, EntryFrameConstants::kArgvOffset)); -#else // _WIN64 +#else // V8_TARGET_OS_WIN // Load the number of arguments and setup pointer to the arguments. __ movq(rax, r8); __ movq(rbx, r9); -#endif // _WIN64 +#endif // V8_TARGET_OS_WIN // Current stack contents: // [rsp + 2 * kSystemPointerSize ... ] : Internal frame @@ -851,10 +852,11 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) { // TODO(juliana): if we remove the code below then we don't need all // the parameters. -static void ReplaceClosureCodeWithOptimizedCode( - MacroAssembler* masm, Register optimized_code, Register closure, - Register scratch1, Register scratch2, Register scratch3) { - +static void ReplaceClosureCodeWithOptimizedCode(MacroAssembler* masm, + Register optimized_code, + Register closure, + Register scratch1, + Register scratch2) { // Store the optimized code in the closure. __ StoreTaggedField(FieldOperand(closure, JSFunction::kCodeOffset), optimized_code); @@ -895,104 +897,71 @@ static void TailCallRuntimeIfMarkerEquals(MacroAssembler* masm, __ bind(&no_match); } -static void MaybeTailCallOptimizedCodeSlot(MacroAssembler* masm, - Register feedback_vector, - Register scratch1, Register scratch2, - Register scratch3) { +static void MaybeOptimizeCode(MacroAssembler* masm, Register feedback_vector, + Register optimization_marker) { // ----------- S t a t e ------------- // -- rdx : new target (preserved for callee if needed, and caller) // -- rdi : target function (preserved for callee if needed, and caller) // -- feedback vector (preserved for caller if needed) + // -- optimization_marker : a Smi containing a non-zero optimization marker. // ----------------------------------- - DCHECK(!AreAliased(feedback_vector, rdx, rdi, scratch1, scratch2, scratch3)); - - Label optimized_code_slot_is_weak_ref, fallthrough; - - Register closure = rdi; - Register optimized_code_entry = scratch1; - Register decompr_scratch = COMPRESS_POINTERS_BOOL ? scratch2 : no_reg; - - __ LoadAnyTaggedField( - optimized_code_entry, - FieldOperand(feedback_vector, - FeedbackVector::kOptimizedCodeWeakOrSmiOffset), - decompr_scratch); - - // Check if the code entry is a Smi. If yes, we interpret it as an - // optimisation marker. Otherwise, interpret it as a weak reference to a code - // object. - __ JumpIfNotSmi(optimized_code_entry, &optimized_code_slot_is_weak_ref); - - { - // Optimized code slot is a Smi optimization marker. - - // Fall through if no optimization trigger. - __ SmiCompare(optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kNone)); - __ j(equal, &fallthrough); - - // TODO(v8:8394): The logging of first execution will break if - // feedback vectors are not allocated. We need to find a different way of - // logging these events if required. - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kLogFirstExecution, - Runtime::kFunctionFirstExecution); - TailCallRuntimeIfMarkerEquals(masm, optimized_code_entry, - OptimizationMarker::kCompileOptimized, - Runtime::kCompileOptimized_NotConcurrent); - TailCallRuntimeIfMarkerEquals( - masm, optimized_code_entry, - OptimizationMarker::kCompileOptimizedConcurrent, - Runtime::kCompileOptimized_Concurrent); - { - // Otherwise, the marker is InOptimizationQueue, so fall through hoping - // that an interrupt will eventually update the slot with optimized code. - if (FLAG_debug_code) { - __ SmiCompare(optimized_code_entry, - Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)); - __ Assert(equal, AbortReason::kExpectedOptimizationSentinel); - } - __ jmp(&fallthrough); - } + DCHECK(!AreAliased(feedback_vector, rdx, rdi, optimization_marker)); + + // TODO(v8:8394): The logging of first execution will break if + // feedback vectors are not allocated. We need to find a different way of + // logging these events if required. + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kLogFirstExecution, + Runtime::kFunctionFirstExecution); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimized, + Runtime::kCompileOptimized_NotConcurrent); + TailCallRuntimeIfMarkerEquals(masm, optimization_marker, + OptimizationMarker::kCompileOptimizedConcurrent, + Runtime::kCompileOptimized_Concurrent); + + // Otherwise, the marker is InOptimizationQueue, so fall through hoping + // that an interrupt will eventually update the slot with optimized code. + if (FLAG_debug_code) { + __ SmiCompare(optimization_marker, + Smi::FromEnum(OptimizationMarker::kInOptimizationQueue)); + __ Assert(equal, AbortReason::kExpectedOptimizationSentinel); } +} - { - // Optimized code slot is a weak reference. - __ bind(&optimized_code_slot_is_weak_ref); - - __ LoadWeakValue(optimized_code_entry, &fallthrough); +static void TailCallOptimizedCodeSlot(MacroAssembler* masm, + Register optimized_code_entry, + Register scratch1, Register scratch2) { + // ----------- S t a t e ------------- + // -- rdx : new target (preserved for callee if needed, and caller) + // -- rdi : target function (preserved for callee if needed, and caller) + // ----------------------------------- - // Check if the optimized code is marked for deopt. If it is, call the - // runtime to clear it. - Label found_deoptimized_code; - __ LoadTaggedPointerField( - scratch2, - FieldOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); - __ testl( - FieldOperand(scratch2, CodeDataContainer::kKindSpecificFlagsOffset), - Immediate(1 << Code::kMarkedForDeoptimizationBit)); - __ j(not_zero, &found_deoptimized_code); - - // Optimized code is good, get it into the closure and link the closure into - // the optimized functions list, then tail call the optimized code. - // The feedback vector is no longer used, so re-use it as a scratch - // register. - ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, - scratch2, scratch3, feedback_vector); - static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch"); - __ Move(rcx, optimized_code_entry); - __ JumpCodeObject(rcx); + Register closure = rdi; - // Optimized code slot contains deoptimized code, evict it and re-enter the - // closure's code. - __ bind(&found_deoptimized_code); - GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); - } + // Check if the optimized code is marked for deopt. If it is, call the + // runtime to clear it. + Label found_deoptimized_code; + __ LoadTaggedPointerField( + scratch1, + FieldOperand(optimized_code_entry, Code::kCodeDataContainerOffset)); + __ testl(FieldOperand(scratch1, CodeDataContainer::kKindSpecificFlagsOffset), + Immediate(1 << Code::kMarkedForDeoptimizationBit)); + __ j(not_zero, &found_deoptimized_code); + + // Optimized code is good, get it into the closure and link the closure into + // the optimized functions list, then tail call the optimized code. + ReplaceClosureCodeWithOptimizedCode(masm, optimized_code_entry, closure, + scratch1, scratch2); + static_assert(kJavaScriptCallCodeStartRegister == rcx, "ABI mismatch"); + __ Move(rcx, optimized_code_entry); + __ JumpCodeObject(rcx); - // Fall-through if the optimized code cell is clear and there is no - // optimization marker. - __ bind(&fallthrough); + // Optimized code slot contains deoptimized code, evict it and re-enter the + // closure's code. + __ bind(&found_deoptimized_code); + GenerateTailCallToReturnedCode(masm, Runtime::kEvictOptimizedCodeSlot); } // Advance the current bytecode offset. This simulates what all bytecode @@ -1019,20 +988,21 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, static_cast<int>(interpreter::Bytecode::kDebugBreakExtraWide)); __ cmpb(bytecode, Immediate(0x3)); __ j(above, &process_bytecode, Label::kNear); + // The code to load the next bytecode is common to both wide and extra wide. + // We can hoist them up here. incl has to happen before testb since it + // modifies the ZF flag. + __ incl(bytecode_offset); __ testb(bytecode, Immediate(0x1)); + __ movzxbq(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); __ j(not_equal, &extra_wide, Label::kNear); - // Load the next bytecode and update table to the wide scaled table. - __ incl(bytecode_offset); - __ movzxbq(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); + // Update table to the wide scaled table. __ addq(bytecode_size_table, Immediate(kIntSize * interpreter::Bytecodes::kBytecodeCount)); __ jmp(&process_bytecode, Label::kNear); __ bind(&extra_wide); - // Load the next bytecode and update table to the extra wide scaled table. - __ incl(bytecode_offset); - __ movzxbq(bytecode, Operand(bytecode_array, bytecode_offset, times_1, 0)); + // Update table to the extra wide scaled table. __ addq(bytecode_size_table, Immediate(2 * kIntSize * interpreter::Bytecodes::kBytecodeCount)); @@ -1101,7 +1071,23 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Read off the optimized code slot in the feedback vector, and if there // is optimized code or an optimization marker, call that instead. - MaybeTailCallOptimizedCodeSlot(masm, feedback_vector, rcx, r11, r15); + + Register optimized_code_entry = rcx; + Register decompr_scratch = COMPRESS_POINTERS_BOOL ? r11 : no_reg; + + __ LoadAnyTaggedField( + optimized_code_entry, + FieldOperand(feedback_vector, + FeedbackVector::kOptimizedCodeWeakOrSmiOffset), + decompr_scratch); + + // Check if the optimized code slot is not empty. + Label optimized_code_slot_not_empty; + __ Cmp(optimized_code_entry, Smi::FromEnum(OptimizationMarker::kNone)); + __ j(not_equal, &optimized_code_slot_not_empty); + + Label not_optimized; + __ bind(¬_optimized); // Increment invocation count for the function. __ incl( @@ -1137,28 +1123,26 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Push(rcx); // Allocate the local and temporary register file on the stack. + Label stack_overflow; { // Load frame size from the BytecodeArray object. __ movl(rcx, FieldOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kFrameSizeOffset)); // Do a stack check to ensure we don't go over the limit. - Label ok; __ movq(rax, rsp); __ subq(rax, rcx); __ cmpq(rax, RealStackLimitAsOperand(masm)); - __ j(above_equal, &ok, Label::kNear); - __ CallRuntime(Runtime::kThrowStackOverflow); - __ bind(&ok); + __ j(below, &stack_overflow); // If ok, push undefined as the initial value for all register file entries. Label loop_header; Label loop_check; - __ LoadRoot(rax, RootIndex::kUndefinedValue); + __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); __ j(always, &loop_check, Label::kNear); __ bind(&loop_header); // TODO(rmcilroy): Consider doing more than one push per loop iteration. - __ Push(rax); + __ Push(kInterpreterAccumulatorRegister); // Continue loop if not done. __ bind(&loop_check); __ subq(rcx, Immediate(kSystemPointerSize)); @@ -1169,16 +1153,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // register, initialize it with incoming value which was passed in rdx. Label no_incoming_new_target_or_generator_register; __ movsxlq( - rax, + rcx, FieldOperand(kInterpreterBytecodeArrayRegister, BytecodeArray::kIncomingNewTargetOrGeneratorRegisterOffset)); - __ testl(rax, rax); + __ testl(rcx, rcx); __ j(zero, &no_incoming_new_target_or_generator_register, Label::kNear); - __ movq(Operand(rbp, rax, times_system_pointer_size, 0), rdx); + __ movq(Operand(rbp, rcx, times_system_pointer_size, 0), rdx); __ bind(&no_incoming_new_target_or_generator_register); - // Load accumulator with undefined. - __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue); + // The accumulator is already loaded with undefined. // Load the dispatch table into a register and dispatch to the bytecode // handler at the current bytecode offset. @@ -1201,10 +1184,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { // Get bytecode array and bytecode offset from the stack frame. __ movq(kInterpreterBytecodeArrayRegister, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ movq(kInterpreterBytecodeOffsetRegister, - Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); __ SmiUntag(kInterpreterBytecodeOffsetRegister, - kInterpreterBytecodeOffsetRegister); + Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Either return, or advance to the next bytecode and dispatch. Label do_return; @@ -1223,6 +1204,25 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ bind(&compile_lazy); GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy); __ int3(); // Should not return. + + __ bind(&optimized_code_slot_not_empty); + Label maybe_has_optimized_code; + // Check if optimized code marker is actually a weak reference to the + // optimized code as opposed to an optimization marker. + __ JumpIfNotSmi(optimized_code_entry, &maybe_has_optimized_code); + MaybeOptimizeCode(masm, feedback_vector, optimized_code_entry); + // Fall through if there's no runnable optimized code. + __ jmp(¬_optimized); + + __ bind(&maybe_has_optimized_code); + // Load code entry from the weak reference, if it was cleared, resume + // execution of unoptimized code. + __ LoadWeakValue(optimized_code_entry, ¬_optimized); + TailCallOptimizedCodeSlot(masm, optimized_code_entry, r11, r15); + + __ bind(&stack_overflow); + __ CallRuntime(Runtime::kThrowStackOverflow); + __ int3(); // Should not return. } static void Generate_InterpreterPushArgs(MacroAssembler* masm, @@ -1425,10 +1425,8 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { } // Get the target bytecode offset from the frame. - __ movq(kInterpreterBytecodeOffsetRegister, - Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); __ SmiUntag(kInterpreterBytecodeOffsetRegister, - kInterpreterBytecodeOffsetRegister); + Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Dispatch to the target bytecode. __ movzxbq(r11, Operand(kInterpreterBytecodeArrayRegister, @@ -1443,10 +1441,8 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { // Get bytecode array and bytecode offset from the stack frame. __ movq(kInterpreterBytecodeArrayRegister, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ movq(kInterpreterBytecodeOffsetRegister, - Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); __ SmiUntag(kInterpreterBytecodeOffsetRegister, - kInterpreterBytecodeOffsetRegister); + Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp)); // Load the current bytecode. __ movzxbq(rbx, Operand(kInterpreterBytecodeArrayRegister, @@ -1459,8 +1455,9 @@ void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) { &if_return); // Convert new bytecode offset to a Smi and save in the stackframe. - __ SmiTag(rbx, kInterpreterBytecodeOffsetRegister); - __ movq(Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp), rbx); + __ SmiTag(kInterpreterBytecodeOffsetRegister); + __ movq(Operand(rbp, InterpreterFrameConstants::kBytecodeOffsetFromFp), + kInterpreterBytecodeOffsetRegister); Generate_InterpreterEnterBytecode(masm); @@ -1485,7 +1482,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { // Preserve argument count for later compare. __ movq(rcx, rax); // Push the number of arguments to the callee. - __ SmiTag(rax, rax); + __ SmiTag(rax); __ Push(rax); // Push a copy of the target function and the new target. __ Push(rdi); @@ -1522,7 +1519,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { __ Drop(2); __ Pop(rcx); - __ SmiUntag(rcx, rcx); + __ SmiUntag(rcx); scope.GenerateLeaveFrame(); __ PopReturnAddressTo(rbx); @@ -1536,7 +1533,7 @@ void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) { __ Pop(rdx); __ Pop(rdi); __ Pop(rax); - __ SmiUntag(rax, rax); + __ SmiUntag(rax); } // On failure, tail call back to regular js by re-calling the function // which has be reset to the compile lazy builtin. @@ -1563,7 +1560,7 @@ void Generate_ContinueToBuiltinHelper(MacroAssembler* masm, int code = config->GetAllocatableGeneralCode(i); __ popq(Register::from_code(code)); if (java_script_builtin && code == kJavaScriptCallArgCountRegister.code()) { - __ SmiUntag(Register::from_code(code), Register::from_code(code)); + __ SmiUntag(Register::from_code(code)); } } __ movq( @@ -2274,7 +2271,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, // TODO(bmeurer): Inline the allocation here to avoid building the frame // in the fast case? (fall back to AllocateInNewSpace?) FrameScope scope(masm, StackFrame::INTERNAL); - __ SmiTag(rax, rax); + __ SmiTag(rax); __ Push(rax); __ Push(rdi); __ movq(rax, rcx); @@ -2285,7 +2282,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, __ movq(rcx, rax); __ Pop(rdi); __ Pop(rax); - __ SmiUntag(rax, rax); + __ SmiUntag(rax); } __ LoadTaggedPointerField( rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); @@ -2601,14 +2598,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { } void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { - // Lookup the function in the JavaScript frame. - __ movq(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); - __ movq(rax, Operand(rax, JavaScriptFrameConstants::kFunctionOffset)); - { FrameScope scope(masm, StackFrame::INTERNAL); - // Pass function as argument. - __ Push(rax); __ CallRuntime(Runtime::kCompileForOnStackReplacement); } @@ -2647,7 +2638,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) { // The function index was pushed to the stack by the caller as int32. __ Pop(r11); // Convert to Smi for the runtime call. - __ SmiTag(r11, r11); + __ SmiTag(r11); { HardAbortScope hard_abort(masm); // Avoid calls to Abort. FrameScope scope(masm, StackFrame::WASM_COMPILE_LAZY); @@ -2716,7 +2707,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, // If argv_mode == kArgvInRegister: // r15: pointer to the first argument -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. It requires the // stack to be aligned to 16 bytes. It only allows a single-word to be // returned in register rax. Larger return sizes must be written to an address @@ -2738,7 +2729,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, const Register kCCallArg3 = rcx; const int kArgExtraStackSpace = 0; const int kMaxRegisterResultSize = 2; -#endif // _WIN64 +#endif // V8_TARGET_OS_WIN // Enter the exit frame that transitions from JavaScript to C++. int arg_stack_space = @@ -2809,7 +2800,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size, IsolateAddressId::kPendingExceptionAddress, masm->isolate()); Operand pending_exception_operand = masm->ExternalReferenceAsOperand(pending_exception_address); - __ cmpq(r14, pending_exception_operand); + __ cmp_tagged(r14, pending_exception_operand); __ j(equal, &okay, Label::kNear); __ int3(); __ bind(&okay); diff --git a/deps/v8/src/codegen/OWNERS b/deps/v8/src/codegen/OWNERS index feb2f62f7878ec..64d2d7b97deb01 100644 --- a/deps/v8/src/codegen/OWNERS +++ b/deps/v8/src/codegen/OWNERS @@ -1,6 +1,6 @@ bbudge@chromium.org bmeurer@chromium.org -clemensh@chromium.org +clemensb@chromium.org gdeepti@chromium.org ishell@chromium.org jarin@chromium.org diff --git a/deps/v8/src/codegen/arm/assembler-arm-inl.h b/deps/v8/src/codegen/arm/assembler-arm-inl.h index 3fbd679104ea21..45ec07a382822b 100644 --- a/deps/v8/src/codegen/arm/assembler-arm-inl.h +++ b/deps/v8/src/codegen/arm/assembler-arm-inl.h @@ -118,7 +118,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, DCHECK(IsCodeTarget(rmode_) || rmode_ == FULL_EMBEDDED_OBJECT); Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/arm/assembler-arm.cc b/deps/v8/src/codegen/arm/assembler-arm.cc index 9c46063537d62d..6659960bb809d0 100644 --- a/deps/v8/src/codegen/arm/assembler-arm.cc +++ b/deps/v8/src/codegen/arm/assembler-arm.cc @@ -40,6 +40,7 @@ #include "src/base/bits.h" #include "src/base/cpu.h" +#include "src/base/overflowing-math.h" #include "src/codegen/arm/assembler-arm-inl.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/macro-assembler.h" @@ -452,8 +453,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle<HeapObject> object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); break; case HeapObjectRequest::kStringConstant: { const StringConstantBase* str = request.string(); @@ -4802,15 +4803,17 @@ void Assembler::GrowBuffer() { int rc_delta = (new_start + new_size) - (buffer_start_ + old_size); size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos(); MemMove(new_start, buffer_start_, pc_offset()); - MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(), - reloc_size); + byte* new_reloc_start = reinterpret_cast<byte*>( + reinterpret_cast<Address>(reloc_info_writer.pos()) + rc_delta); + MemMove(new_reloc_start, reloc_info_writer.pos(), reloc_size); // Switch buffers. buffer_ = std::move(new_buffer); buffer_start_ = new_start; - pc_ += pc_delta; - reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, - reloc_info_writer.last_pc() + pc_delta); + pc_ = reinterpret_cast<byte*>(reinterpret_cast<Address>(pc_) + pc_delta); + byte* new_last_pc = reinterpret_cast<byte*>( + reinterpret_cast<Address>(reloc_info_writer.last_pc()) + pc_delta); + reloc_info_writer.Reposition(new_reloc_start, new_last_pc); // None of our relocation types are pc relative pointing outside the code // buffer nor pc absolute pointing inside the code buffer, so there is no need @@ -4831,7 +4834,7 @@ void Assembler::dd(uint32_t data) { // blocked before using dd. DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty()); CheckBuffer(); - *reinterpret_cast<uint32_t*>(pc_) = data; + base::WriteUnalignedValue(reinterpret_cast<Address>(pc_), data); pc_ += sizeof(uint32_t); } @@ -4840,7 +4843,7 @@ void Assembler::dq(uint64_t value) { // blocked before using dq. DCHECK(is_const_pool_blocked() || pending_32_bit_constants_.empty()); CheckBuffer(); - *reinterpret_cast<uint64_t*>(pc_) = value; + base::WriteUnalignedValue(reinterpret_cast<Address>(pc_), value); pc_ += sizeof(uint64_t); } diff --git a/deps/v8/src/codegen/arm/assembler-arm.h b/deps/v8/src/codegen/arm/assembler-arm.h index f669943f34edd6..1d280e5555b8e1 100644 --- a/deps/v8/src/codegen/arm/assembler-arm.h +++ b/deps/v8/src/codegen/arm/assembler-arm.h @@ -41,6 +41,7 @@ #define V8_CODEGEN_ARM_ASSEMBLER_ARM_H_ #include <stdio.h> +#include <memory> #include <vector> #include "src/codegen/arm/constants-arm.h" @@ -305,9 +306,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { explicit Assembler(const AssemblerOptions&, std::unique_ptr<AssemblerBuffer> = {}); - virtual ~Assembler(); + ~Assembler() override; - virtual void AbortedCodeGeneration() { pending_32_bit_constants_.clear(); } + void AbortedCodeGeneration() override { pending_32_bit_constants_.clear(); } // GetCode emits any pending (non-emitted) code and fills the descriptor desc. static constexpr int kNoHandlerTable = 0; diff --git a/deps/v8/src/codegen/arm/macro-assembler-arm.cc b/deps/v8/src/codegen/arm/macro-assembler-arm.cc index 7f6d82518ec1dc..6f1adfead26d14 100644 --- a/deps/v8/src/codegen/arm/macro-assembler-arm.cc +++ b/deps/v8/src/codegen/arm/macro-assembler-arm.cc @@ -573,7 +573,7 @@ void MacroAssembler::Ubfx(Register dst, Register src1, int lsb, int width, Condition cond) { DCHECK_LT(lsb, 32); if (!CpuFeatures::IsSupported(ARMv7) || predictable_code_size()) { - int mask = (1 << (width + lsb)) - 1 - ((1 << lsb) - 1); + int mask = (1u << (width + lsb)) - 1u - ((1u << lsb) - 1u); and_(dst, src1, Operand(mask), LeaveCC, cond); if (lsb != 0) { mov(dst, Operand(dst, LSR, lsb), LeaveCC, cond); @@ -1602,57 +1602,43 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } } -void MacroAssembler::CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_hook; - - ExternalReference debug_hook_active = - ExternalReference::debug_hook_on_function_call_address(isolate()); - Move(r4, debug_hook_active); - ldrsb(r4, MemOperand(r4)); - cmp(r4, Operand(0)); - b(eq, &skip_hook); - - { - // Load receiver to pass it later to DebugOnFunctionCall hook. - if (actual.is_reg()) { - mov(r4, actual.reg()); - } else { - mov(r4, Operand(actual.immediate())); - } - ldr(r4, MemOperand(sp, r4, LSL, kPointerSizeLog2)); - FrameScope frame(this, - has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); - if (expected.is_reg()) { - SmiTag(expected.reg()); - Push(expected.reg()); - } - if (actual.is_reg()) { - SmiTag(actual.reg()); - Push(actual.reg()); - } - if (new_target.is_valid()) { - Push(new_target); - } - Push(fun); - Push(fun); - Push(r4); - CallRuntime(Runtime::kDebugOnFunctionCall); - Pop(fun); - if (new_target.is_valid()) { - Pop(new_target); - } - if (actual.is_reg()) { - Pop(actual.reg()); - SmiUntag(actual.reg()); - } - if (expected.is_reg()) { - Pop(expected.reg()); - SmiUntag(expected.reg()); - } +void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + // Load receiver to pass it later to DebugOnFunctionCall hook. + if (actual.is_reg()) { + ldr(r4, MemOperand(sp, actual.reg(), LSL, kPointerSizeLog2)); + } else { + ldr(r4, MemOperand(sp, actual.immediate() << kPointerSizeLog2)); + } + FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); + if (expected.is_reg()) { + SmiTag(expected.reg()); + Push(expected.reg()); + } + if (actual.is_reg()) { + SmiTag(actual.reg()); + Push(actual.reg()); + } + if (new_target.is_valid()) { + Push(new_target); + } + Push(fun); + Push(fun); + Push(r4); + CallRuntime(Runtime::kDebugOnFunctionCall); + Pop(fun); + if (new_target.is_valid()) { + Pop(new_target); + } + if (actual.is_reg()) { + Pop(actual.reg()); + SmiUntag(actual.reg()); + } + if (expected.is_reg()) { + Pop(expected.reg()); + SmiUntag(expected.reg()); } - bind(&skip_hook); } void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, @@ -1665,7 +1651,16 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK_IMPLIES(new_target.is_valid(), new_target == r3); // On function call, call into the debugger if necessary. - CheckDebugHook(function, new_target, expected, actual); + Label debug_hook, continue_after_hook; + { + ExternalReference debug_hook_active = + ExternalReference::debug_hook_on_function_call_address(isolate()); + Move(r4, debug_hook_active); + ldrsb(r4, MemOperand(r4)); + cmp(r4, Operand(0)); + b(ne, &debug_hook); + } + bind(&continue_after_hook); // Clear the new.target register if not given. if (!new_target.is_valid()) { @@ -1687,11 +1682,17 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(flag == JUMP_FUNCTION); JumpCodeObject(code); } - - // Continue here if InvokePrologue does handle the invocation due to - // mismatched parameter counts. - bind(&done); } + b(&done); + + // Deferred debug hook. + bind(&debug_hook); + CallDebugOnFunctionCall(function, new_target, expected, actual); + b(&continue_after_hook); + + // Continue here if InvokePrologue does handle the invocation due to + // mismatched parameter counts. + bind(&done); } void MacroAssembler::InvokeFunction(Register fun, Register new_target, diff --git a/deps/v8/src/codegen/arm/macro-assembler-arm.h b/deps/v8/src/codegen/arm/macro-assembler-arm.h index bbea40b9a628cc..4807a6d20da3f9 100644 --- a/deps/v8/src/codegen/arm/macro-assembler-arm.h +++ b/deps/v8/src/codegen/arm/macro-assembler-arm.h @@ -633,10 +633,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { const ParameterCount& expected, const ParameterCount& actual, InvokeFlag flag); - // On function call, call into the debugger if necessary. - void CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual); + // On function call, call into the debugger. + void CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual); // Invoke the JavaScript function in the given register. Changes the // current context to the context in the function before invoking. diff --git a/deps/v8/src/codegen/arm64/assembler-arm64-inl.h b/deps/v8/src/codegen/arm64/assembler-arm64-inl.h index baae106c1c6ad8..ce34da7dc2acf6 100644 --- a/deps/v8/src/codegen/arm64/assembler-arm64-inl.h +++ b/deps/v8/src/codegen/arm64/assembler-arm64-inl.h @@ -54,14 +54,12 @@ inline bool CPURegister::IsSP() const { } inline void CPURegList::Combine(const CPURegList& other) { - DCHECK(IsValid()); DCHECK(other.type() == type_); DCHECK(other.RegisterSizeInBits() == size_); list_ |= other.list(); } inline void CPURegList::Remove(const CPURegList& other) { - DCHECK(IsValid()); if (other.type() == type_) { list_ &= ~other.list(); } @@ -84,13 +82,12 @@ inline void CPURegList::Remove(const CPURegister& other1, } inline void CPURegList::Combine(int code) { - DCHECK(IsValid()); DCHECK(CPURegister::Create(code, size_, type_).IsValid()); list_ |= (1ULL << code); + DCHECK(IsValid()); } inline void CPURegList::Remove(int code) { - DCHECK(IsValid()); DCHECK(CPURegister::Create(code, size_, type_).IsValid()); list_ &= ~(1ULL << code); } @@ -311,6 +308,18 @@ Operand Operand::ToExtendedRegister() const { return Operand(reg_, reg_.Is64Bits() ? UXTX : UXTW, shift_amount_); } +Operand Operand::ToW() const { + if (IsShiftedRegister()) { + DCHECK(reg_.Is64Bits()); + return Operand(reg_.W(), shift(), shift_amount()); + } else if (IsExtendedRegister()) { + DCHECK(reg_.Is64Bits()); + return Operand(reg_.W(), extend(), shift_amount()); + } + DCHECK(IsImmediate()); + return *this; +} + Immediate Operand::immediate_for_heap_object_request() const { DCHECK((heap_object_request().kind() == HeapObjectRequest::kHeapNumber && immediate_.rmode() == RelocInfo::FULL_EMBEDDED_OBJECT) || @@ -711,7 +720,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); } - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/arm64/assembler-arm64.cc b/deps/v8/src/codegen/arm64/assembler-arm64.cc index c798d3a8a03ed9..ea2f4696bdbca1 100644 --- a/deps/v8/src/codegen/arm64/assembler-arm64.cc +++ b/deps/v8/src/codegen/arm64/assembler-arm64.cc @@ -63,18 +63,16 @@ void CpuFeatures::PrintFeatures() {} // CPURegList utilities. CPURegister CPURegList::PopLowestIndex() { - DCHECK(IsValid()); if (IsEmpty()) { return NoCPUReg; } - int index = CountTrailingZeros(list_, kRegListSizeInBits); + int index = base::bits::CountTrailingZeros(list_); DCHECK((1LL << index) & list_); Remove(index); return CPURegister::Create(index, size_, type_); } CPURegister CPURegList::PopHighestIndex() { - DCHECK(IsValid()); if (IsEmpty()) { return NoCPUReg; } @@ -369,8 +367,9 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - Handle<HeapObject> object = isolate->factory()->NewHeapNumber( - request.heap_number(), AllocationType::kOld); + Handle<HeapObject> object = + isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); EmbeddedObjectIndex index = AddEmbeddedObject(object); set_embedded_object_index_referenced_from(pc, index); break; @@ -3967,19 +3966,24 @@ void Assembler::LoadStore(const CPURegister& rt, const MemOperand& addr, bool Assembler::IsImmLSUnscaled(int64_t offset) { return is_int9(offset); } bool Assembler::IsImmLSScaled(int64_t offset, unsigned size) { - bool offset_is_size_multiple = (((offset >> size) << size) == offset); + bool offset_is_size_multiple = + (static_cast<int64_t>(static_cast<uint64_t>(offset >> size) << size) == + offset); return offset_is_size_multiple && is_uint12(offset >> size); } bool Assembler::IsImmLSPair(int64_t offset, unsigned size) { - bool offset_is_size_multiple = (((offset >> size) << size) == offset); + bool offset_is_size_multiple = + (static_cast<int64_t>(static_cast<uint64_t>(offset >> size) << size) == + offset); return offset_is_size_multiple && is_int7(offset >> size); } bool Assembler::IsImmLLiteral(int64_t offset) { int inst_size = static_cast<int>(kInstrSizeLog2); bool offset_is_inst_multiple = - (((offset >> inst_size) << inst_size) == offset); + (static_cast<int64_t>(static_cast<uint64_t>(offset >> inst_size) + << inst_size) == offset); DCHECK_GT(offset, 0); offset >>= kLoadLiteralScaleLog2; return offset_is_inst_multiple && is_intn(offset, ImmLLiteral_width); @@ -4178,9 +4182,9 @@ bool Assembler::IsImmLogical(uint64_t value, unsigned width, unsigned* n, // 1110ss 4 UInt(ss) // 11110s 2 UInt(s) // - // So we 'or' (-d << 1) with our computed s to form imms. + // So we 'or' (-d * 2) with our computed s to form imms. *n = out_n; - *imm_s = ((-d << 1) | (s - 1)) & 0x3F; + *imm_s = ((-d * 2) | (s - 1)) & 0x3F; *imm_r = r; return true; diff --git a/deps/v8/src/codegen/arm64/assembler-arm64.h b/deps/v8/src/codegen/arm64/assembler-arm64.h index 04ee6d8b750e05..23e8acb1f95c91 100644 --- a/deps/v8/src/codegen/arm64/assembler-arm64.h +++ b/deps/v8/src/codegen/arm64/assembler-arm64.h @@ -8,6 +8,7 @@ #include <deque> #include <list> #include <map> +#include <memory> #include <vector> #include "src/base/optional.h" @@ -105,6 +106,9 @@ class Operand { // which helps in the encoding of instructions that use the stack pointer. inline Operand ToExtendedRegister() const; + // Returns new Operand adapted for using with W registers. + inline Operand ToW() const; + inline Immediate immediate() const; inline int64_t ImmediateValue() const; inline RelocInfo::Mode ImmediateRMode() const; @@ -189,9 +193,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { explicit Assembler(const AssemblerOptions&, std::unique_ptr<AssemblerBuffer> = {}); - virtual ~Assembler(); + ~Assembler() override; - virtual void AbortedCodeGeneration(); + void AbortedCodeGeneration() override; // System functions --------------------------------------------------------- // Start generating code from the beginning of the buffer, discarding any code @@ -375,7 +379,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // Instruction set functions ------------------------------------------------ // Branch / Jump instructions. - // For branches offsets are scaled, i.e. they in instrcutions not in bytes. + // For branches offsets are scaled, i.e. in instructions not in bytes. // Branch to register. void br(const Register& xn); diff --git a/deps/v8/src/codegen/arm64/constants-arm64.h b/deps/v8/src/codegen/arm64/constants-arm64.h index 914268644a6d54..ccafae5e14f466 100644 --- a/deps/v8/src/codegen/arm64/constants-arm64.h +++ b/deps/v8/src/codegen/arm64/constants-arm64.h @@ -33,6 +33,7 @@ constexpr size_t kMaxPCRelativeCodeRangeInMB = 128; constexpr uint8_t kInstrSize = 4; constexpr uint8_t kInstrSizeLog2 = 2; constexpr uint8_t kLoadLiteralScaleLog2 = 2; +constexpr uint8_t kLoadLiteralScale = 1 << kLoadLiteralScaleLog2; constexpr int kMaxLoadLiteralRange = 1 * MB; const int kNumberOfRegisters = 32; @@ -146,7 +147,8 @@ const unsigned kFloat16ExponentBias = 15; // Actual value of root register is offset from the root array's start // to take advantage of negative displacement values. // TODO(sigurds): Choose best value. -constexpr int kRootRegisterBias = 256; +// TODO(ishell): Choose best value for ptr-compr. +constexpr int kRootRegisterBias = kSystemPointerSize == kTaggedSize ? 256 : 0; using float16 = uint16_t; diff --git a/deps/v8/src/codegen/arm64/instructions-arm64.cc b/deps/v8/src/codegen/arm64/instructions-arm64.cc index 05f3654da99d34..ab022affdd11b2 100644 --- a/deps/v8/src/codegen/arm64/instructions-arm64.cc +++ b/deps/v8/src/codegen/arm64/instructions-arm64.cc @@ -71,6 +71,7 @@ static uint64_t RotateRight(uint64_t value, unsigned int rotate, unsigned int width) { DCHECK_LE(width, 64); rotate &= 63; + if (rotate == 0) return value; return ((value & ((1ULL << rotate) - 1ULL)) << (width - rotate)) | (value >> rotate); } @@ -191,16 +192,16 @@ int64_t Instruction::ImmPCOffset() { } else if (BranchType() != UnknownBranchType) { // All PC-relative branches. // Relative branch offsets are instruction-size-aligned. - offset = ImmBranch() << kInstrSizeLog2; + offset = ImmBranch() * kInstrSize; } else if (IsUnresolvedInternalReference()) { // Internal references are always word-aligned. - offset = ImmUnresolvedInternalReference() << kInstrSizeLog2; + offset = ImmUnresolvedInternalReference() * kInstrSize; } else { // Load literal (offset from PC). DCHECK(IsLdrLiteral()); // The offset is always shifted by 2 bits, even for loads to 64-bits // registers. - offset = ImmLLiteral() << kInstrSizeLog2; + offset = ImmLLiteral() * kInstrSize; } return offset; } diff --git a/deps/v8/src/codegen/arm64/instructions-arm64.h b/deps/v8/src/codegen/arm64/instructions-arm64.h index 1132ba39db2d8d..7fe732e2baae1a 100644 --- a/deps/v8/src/codegen/arm64/instructions-arm64.h +++ b/deps/v8/src/codegen/arm64/instructions-arm64.h @@ -5,6 +5,7 @@ #ifndef V8_CODEGEN_ARM64_INSTRUCTIONS_ARM64_H_ #define V8_CODEGEN_ARM64_INSTRUCTIONS_ARM64_H_ +#include "src/base/memory.h" #include "src/codegen/arm64/constants-arm64.h" #include "src/codegen/arm64/register-arm64.h" #include "src/codegen/arm64/utils-arm64.h" @@ -82,11 +83,13 @@ enum Reg31Mode { Reg31IsStackPointer, Reg31IsZeroRegister }; class Instruction { public: V8_INLINE Instr InstructionBits() const { - return *reinterpret_cast<const Instr*>(this); + // Usually this is aligned, but when de/serializing that's not guaranteed. + return base::ReadUnalignedValue<Instr>(reinterpret_cast<Address>(this)); } V8_INLINE void SetInstructionBits(Instr new_instr) { - *reinterpret_cast<Instr*>(this) = new_instr; + // Usually this is aligned, but when de/serializing that's not guaranteed. + base::WriteUnalignedValue(reinterpret_cast<Address>(this), new_instr); } int Bit(int pos) const { return (InstructionBits() >> pos) & 1; } @@ -96,7 +99,9 @@ class Instruction { } int32_t SignedBits(int msb, int lsb) const { - int32_t bits = *(reinterpret_cast<const int32_t*>(this)); + // Usually this is aligned, but when de/serializing that's not guaranteed. + int32_t bits = + base::ReadUnalignedValue<int32_t>(reinterpret_cast<Address>(this)); return signed_bitextract_32(msb, lsb, bits); } @@ -125,7 +130,8 @@ class Instruction { // formed from ImmPCRelLo and ImmPCRelHi. int ImmPCRel() const { DCHECK(IsPCRelAddressing()); - int offset = ((ImmPCRelHi() << ImmPCRelLo_width) | ImmPCRelLo()); + int offset = (static_cast<uint32_t>(ImmPCRelHi()) << ImmPCRelLo_width) | + ImmPCRelLo(); int width = ImmPCRelLo_width + ImmPCRelHi_width; return signed_bitextract_32(width - 1, 0, offset); } @@ -404,7 +410,7 @@ class Instruction { void SetImmLLiteral(Instruction* source); uintptr_t LiteralAddress() { - int offset = ImmLLiteral() << kLoadLiteralScaleLog2; + int offset = ImmLLiteral() * kLoadLiteralScale; return reinterpret_cast<uintptr_t>(this) + offset; } diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64-inl.h b/deps/v8/src/codegen/arm64/macro-assembler-arm64-inl.h index 62bd9c26bfb36d..261fd1e564a62b 100644 --- a/deps/v8/src/codegen/arm64/macro-assembler-arm64-inl.h +++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64-inl.h @@ -93,6 +93,15 @@ void TurboAssembler::Ccmp(const Register& rn, const Operand& operand, } } +void TurboAssembler::CcmpTagged(const Register& rn, const Operand& operand, + StatusFlags nzcv, Condition cond) { + if (COMPRESS_POINTERS_BOOL) { + Ccmp(rn.W(), operand.ToW(), nzcv, cond); + } else { + Ccmp(rn, operand, nzcv, cond); + } +} + void MacroAssembler::Ccmn(const Register& rn, const Operand& operand, StatusFlags nzcv, Condition cond) { DCHECK(allow_macro_instructions()); @@ -157,6 +166,14 @@ void TurboAssembler::Cmp(const Register& rn, const Operand& operand) { Subs(AppropriateZeroRegFor(rn), rn, operand); } +void TurboAssembler::CmpTagged(const Register& rn, const Operand& operand) { + if (COMPRESS_POINTERS_BOOL) { + Cmp(rn.W(), operand.ToW()); + } else { + Cmp(rn, operand); + } +} + void TurboAssembler::Neg(const Register& rd, const Operand& operand) { DCHECK(allow_macro_instructions()); DCHECK(!rd.IsZero()); @@ -982,7 +999,12 @@ void TurboAssembler::SmiUntag(Register dst, Register src) { AssertSmi(src); } DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); - Asr(dst, src, kSmiShift); + if (COMPRESS_POINTERS_BOOL) { + Asr(dst.W(), src.W(), kSmiShift); + Sxtw(dst, dst); + } else { + Asr(dst, src, kSmiShift); + } } void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) { @@ -1002,11 +1024,11 @@ void TurboAssembler::SmiUntag(Register dst, const MemOperand& src) { } } else { DCHECK(SmiValuesAre31Bits()); -#ifdef V8_COMPRESS_POINTERS - Ldrsw(dst, src); -#else - Ldr(dst, src); -#endif + if (COMPRESS_POINTERS_BOOL) { + Ldr(dst.W(), src); + } else { + Ldr(dst, src); + } SmiUntag(dst); } } @@ -1029,13 +1051,11 @@ void TurboAssembler::JumpIfSmi(Register value, Label* smi_label, } void TurboAssembler::JumpIfEqual(Register x, int32_t y, Label* dest) { - Cmp(x, y); - B(eq, dest); + CompareAndBranch(x, y, eq, dest); } void TurboAssembler::JumpIfLessThan(Register x, int32_t y, Label* dest) { - Cmp(x, y); - B(lt, dest); + CompareAndBranch(x, y, lt, dest); } void MacroAssembler::JumpIfNotSmi(Register value, Label* not_smi_label) { @@ -1083,7 +1103,7 @@ void TurboAssembler::Claim(const Register& count, uint64_t unit_size) { if (unit_size == 0) return; DCHECK(base::bits::IsPowerOfTwo(unit_size)); - const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); + const int shift = base::bits::CountTrailingZeros(unit_size); const Operand size(count, LSL, shift); if (size.IsZero()) { @@ -1136,7 +1156,7 @@ void TurboAssembler::Drop(const Register& count, uint64_t unit_size) { if (unit_size == 0) return; DCHECK(base::bits::IsPowerOfTwo(unit_size)); - const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); + const int shift = base::bits::CountTrailingZeros(unit_size); const Operand size(count, LSL, shift); if (size.IsZero()) { @@ -1175,7 +1195,7 @@ void TurboAssembler::DropSlots(int64_t count) { void TurboAssembler::PushArgument(const Register& arg) { Push(padreg, arg); } -void MacroAssembler::CompareAndBranch(const Register& lhs, const Operand& rhs, +void TurboAssembler::CompareAndBranch(const Register& lhs, const Operand& rhs, Condition cond, Label* label) { if (rhs.IsImmediate() && (rhs.ImmediateValue() == 0) && ((cond == eq) || (cond == ne))) { @@ -1190,6 +1210,16 @@ void MacroAssembler::CompareAndBranch(const Register& lhs, const Operand& rhs, } } +void TurboAssembler::CompareTaggedAndBranch(const Register& lhs, + const Operand& rhs, Condition cond, + Label* label) { + if (COMPRESS_POINTERS_BOOL) { + CompareAndBranch(lhs.W(), rhs.ToW(), cond, label); + } else { + CompareAndBranch(lhs, rhs, cond, label); + } +} + void TurboAssembler::TestAndBranchIfAnySet(const Register& reg, const uint64_t bit_pattern, Label* label) { diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc index 0a721b06474987..892458fe8bb9ed 100644 --- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc +++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc @@ -295,7 +295,9 @@ void TurboAssembler::Mov(const Register& rd, const Operand& operand, } else if (RelocInfo::IsEmbeddedObjectMode(operand.ImmediateRMode())) { Handle<HeapObject> x( reinterpret_cast<Address*>(operand.ImmediateValue())); - IndirectLoadConstant(rd, x); + // TODO(v8:9706): Fix-it! This load will always uncompress the value + // even when we are loading a compressed embedded object. + IndirectLoadConstant(rd.X(), x); return; } } @@ -650,7 +652,14 @@ Operand TurboAssembler::MoveImmediateForShiftedOp(const Register& dst, // The move was successful; nothing to do here. } else { // Pre-shift the immediate to the least-significant bits of the register. - int shift_low = CountTrailingZeros(imm, reg_size); + int shift_low; + if (reg_size == 64) { + shift_low = base::bits::CountTrailingZeros(imm); + } else { + DCHECK_EQ(reg_size, 32); + shift_low = base::bits::CountTrailingZeros(static_cast<uint32_t>(imm)); + } + if (mode == kLimitShiftForSP) { // When applied to the stack pointer, the subsequent arithmetic operation // can use the extend form to shift left by a maximum of four bits. Right @@ -1456,15 +1465,6 @@ void TurboAssembler::LoadRoot(Register destination, RootIndex index) { MemOperand(kRootRegister, RootRegisterOffsetForRootIndex(index))); } -void MacroAssembler::LoadObject(Register result, Handle<Object> object) { - AllowDeferredHandleDereference heap_object_check; - if (object->IsHeapObject()) { - Mov(result, Handle<HeapObject>::cast(object)); - } else { - Mov(result, Operand(Smi::cast(*object))); - } -} - void TurboAssembler::Move(Register dst, Smi src) { Mov(dst, src); } void TurboAssembler::MovePair(Register dst0, Register src0, Register dst1, @@ -1923,21 +1923,25 @@ void TurboAssembler::Call(ExternalReference target) { } void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) { - STATIC_ASSERT(kSystemPointerSize == 8); - STATIC_ASSERT(kSmiTagSize == 1); - STATIC_ASSERT(kSmiTag == 0); - // The builtin_index register contains the builtin index as a Smi. // Untagging is folded into the indexing operand below. -#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) - STATIC_ASSERT(kSmiShiftSize == 0); - Lsl(builtin_index, builtin_index, kSystemPointerSizeLog2 - kSmiShift); -#else - STATIC_ASSERT(kSmiShiftSize == 31); - Asr(builtin_index, builtin_index, kSmiShift - kSystemPointerSizeLog2); -#endif - Add(builtin_index, builtin_index, IsolateData::builtin_entry_table_offset()); - Ldr(builtin_index, MemOperand(kRootRegister, builtin_index)); + if (SmiValuesAre32Bits()) { + Asr(builtin_index, builtin_index, kSmiShift - kSystemPointerSizeLog2); + Add(builtin_index, builtin_index, + IsolateData::builtin_entry_table_offset()); + Ldr(builtin_index, MemOperand(kRootRegister, builtin_index)); + } else { + DCHECK(SmiValuesAre31Bits()); + if (COMPRESS_POINTERS_BOOL) { + Add(builtin_index, kRootRegister, + Operand(builtin_index.W(), SXTW, kSystemPointerSizeLog2 - kSmiShift)); + } else { + Add(builtin_index, kRootRegister, + Operand(builtin_index, LSL, kSystemPointerSizeLog2 - kSmiShift)); + } + Ldr(builtin_index, + MemOperand(builtin_index, IsolateData::builtin_entry_table_offset())); + } } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { @@ -2207,43 +2211,34 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, Bind(®ular_invoke); } -void MacroAssembler::CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_hook; - - Mov(x4, ExternalReference::debug_hook_on_function_call_address(isolate())); - Ldrsb(x4, MemOperand(x4)); - Cbz(x4, &skip_hook); - - { - // Load receiver to pass it later to DebugOnFunctionCall hook. - Operand actual_op = actual.is_immediate() ? Operand(actual.immediate()) - : Operand(actual.reg()); - Mov(x4, actual_op); - Ldr(x4, MemOperand(sp, x4, LSL, kSystemPointerSizeLog2)); - FrameScope frame(this, - has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); +void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + // Load receiver to pass it later to DebugOnFunctionCall hook. + if (actual.is_reg()) { + Ldr(x4, MemOperand(sp, actual.reg(), LSL, kSystemPointerSizeLog2)); + } else { + Ldr(x4, MemOperand(sp, actual.immediate() << kSystemPointerSizeLog2)); + } + FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); - Register expected_reg = padreg; - Register actual_reg = padreg; - if (expected.is_reg()) expected_reg = expected.reg(); - if (actual.is_reg()) actual_reg = actual.reg(); - if (!new_target.is_valid()) new_target = padreg; + Register expected_reg = padreg; + Register actual_reg = padreg; + if (expected.is_reg()) expected_reg = expected.reg(); + if (actual.is_reg()) actual_reg = actual.reg(); + if (!new_target.is_valid()) new_target = padreg; - // Save values on stack. - SmiTag(expected_reg); - SmiTag(actual_reg); - Push(expected_reg, actual_reg, new_target, fun); - Push(fun, x4); - CallRuntime(Runtime::kDebugOnFunctionCall); + // Save values on stack. + SmiTag(expected_reg); + SmiTag(actual_reg); + Push(expected_reg, actual_reg, new_target, fun); + Push(fun, x4); + CallRuntime(Runtime::kDebugOnFunctionCall); - // Restore values from stack. - Pop(fun, new_target, actual_reg, expected_reg); - SmiUntag(actual_reg); - SmiUntag(expected_reg); - } - Bind(&skip_hook); + // Restore values from stack. + Pop(fun, new_target, actual_reg, expected_reg); + SmiUntag(actual_reg); + SmiUntag(expected_reg); } void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, @@ -2256,7 +2251,13 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK_IMPLIES(new_target.is_valid(), new_target.is(x3)); // On function call, call into the debugger if necessary. - CheckDebugHook(function, new_target, expected, actual); + Label debug_hook, continue_after_hook; + { + Mov(x4, ExternalReference::debug_hook_on_function_call_address(isolate())); + Ldrsb(x4, MemOperand(x4)); + Cbnz(x4, &debug_hook); + } + bind(&continue_after_hook); // Clear the new.target register if not given. if (!new_target.is_valid()) { @@ -2284,6 +2285,12 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, JumpCodeObject(code); } } + B(&done); + + // Deferred debug hook. + bind(&debug_hook); + CallDebugOnFunctionCall(function, new_target, expected, actual); + B(&continue_after_hook); // Continue here if InvokePrologue does handle the invocation due to // mismatched parameter counts. @@ -2636,7 +2643,7 @@ void MacroAssembler::CompareRoot(const Register& obj, RootIndex index) { Register temp = temps.AcquireX(); DCHECK(!AreAliased(obj, temp)); LoadRoot(temp, index); - Cmp(obj, temp); + CmpTagged(obj, temp); } void MacroAssembler::JumpIfRoot(const Register& obj, RootIndex index, @@ -2669,20 +2676,20 @@ void MacroAssembler::JumpIfIsInRange(const Register& value, void TurboAssembler::LoadTaggedPointerField(const Register& destination, const MemOperand& field_operand) { -#ifdef V8_COMPRESS_POINTERS - DecompressTaggedPointer(destination, field_operand); -#else - Ldr(destination, field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DecompressTaggedPointer(destination, field_operand); + } else { + Ldr(destination, field_operand); + } } void TurboAssembler::LoadAnyTaggedField(const Register& destination, const MemOperand& field_operand) { -#ifdef V8_COMPRESS_POINTERS - DecompressAnyTagged(destination, field_operand); -#else - Ldr(destination, field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DecompressAnyTagged(destination, field_operand); + } else { + Ldr(destination, field_operand); + } } void TurboAssembler::SmiUntagField(Register dst, const MemOperand& src) { @@ -2691,33 +2698,31 @@ void TurboAssembler::SmiUntagField(Register dst, const MemOperand& src) { void TurboAssembler::StoreTaggedField(const Register& value, const MemOperand& dst_field_operand) { -#ifdef V8_COMPRESS_POINTERS - RecordComment("[ StoreTagged"); - Str(value.W(), dst_field_operand); - RecordComment("]"); -#else - Str(value, dst_field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + Str(value.W(), dst_field_operand); + } else { + Str(value, dst_field_operand); + } } void TurboAssembler::DecompressTaggedSigned(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressTaggedSigned"); - Ldrsw(destination, field_operand); + Ldr(destination.W(), field_operand); RecordComment("]"); } void TurboAssembler::DecompressTaggedSigned(const Register& destination, const Register& source) { RecordComment("[ DecompressTaggedSigned"); - Sxtw(destination, source); + Mov(destination.W(), source.W()); RecordComment("]"); } void TurboAssembler::DecompressTaggedPointer(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressTaggedPointer"); - Ldrsw(destination, field_operand); + Ldr(destination.W(), field_operand); Add(destination, kRootRegister, destination); RecordComment("]"); } @@ -2725,57 +2730,22 @@ void TurboAssembler::DecompressTaggedPointer(const Register& destination, void TurboAssembler::DecompressTaggedPointer(const Register& destination, const Register& source) { RecordComment("[ DecompressTaggedPointer"); - Add(destination, kRootRegister, Operand(source, SXTW)); + Add(destination, kRootRegister, Operand(source, UXTW)); RecordComment("]"); } void TurboAssembler::DecompressAnyTagged(const Register& destination, const MemOperand& field_operand) { RecordComment("[ DecompressAnyTagged"); - Ldrsw(destination, field_operand); - if (kUseBranchlessPtrDecompressionInGeneratedCode) { - UseScratchRegisterScope temps(this); - // Branchlessly compute |masked_root|: - // masked_root = HAS_SMI_TAG(destination) ? 0 : kRootRegister; - STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0)); - Register masked_root = temps.AcquireX(); - // Sign extend tag bit to entire register. - Sbfx(masked_root, destination, 0, kSmiTagSize); - And(masked_root, masked_root, kRootRegister); - // Now this add operation will either leave the value unchanged if it is a - // smi or add the isolate root if it is a heap object. - Add(destination, masked_root, destination); - } else { - Label done; - JumpIfSmi(destination, &done); - Add(destination, kRootRegister, destination); - bind(&done); - } + Ldr(destination.W(), field_operand); + Add(destination, kRootRegister, destination); RecordComment("]"); } void TurboAssembler::DecompressAnyTagged(const Register& destination, const Register& source) { RecordComment("[ DecompressAnyTagged"); - if (kUseBranchlessPtrDecompressionInGeneratedCode) { - UseScratchRegisterScope temps(this); - // Branchlessly compute |masked_root|: - // masked_root = HAS_SMI_TAG(destination) ? 0 : kRootRegister; - STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag == 0)); - Register masked_root = temps.AcquireX(); - // Sign extend tag bit to entire register. - Sbfx(masked_root, source, 0, kSmiTagSize); - And(masked_root, masked_root, kRootRegister); - // Now this add operation will either leave the value unchanged if it is a - // smi or add the isolate root if it is a heap object. - Add(destination, masked_root, Operand(source, SXTW)); - } else { - Label done; - Sxtw(destination, source); - JumpIfSmi(destination, &done); - Add(destination, kRootRegister, destination); - bind(&done); - } + Add(destination, kRootRegister, Operand(source, UXTW)); RecordComment("]"); } diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h index 94091e862489c5..cb3b51eb527f9f 100644 --- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h +++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h @@ -652,6 +652,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { const Operand& operand); inline void Blr(const Register& xn); inline void Cmp(const Register& rn, const Operand& operand); + inline void CmpTagged(const Register& rn, const Operand& operand); inline void Subs(const Register& rd, const Register& rn, const Operand& operand); void Csel(const Register& rd, const Register& rn, const Operand& operand, @@ -843,6 +844,13 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void CheckPageFlag(const Register& object, int mask, Condition cc, Label* condition_met); + // Compare a register with an operand, and branch to label depending on the + // condition. May corrupt the status flags. + inline void CompareAndBranch(const Register& lhs, const Operand& rhs, + Condition cond, Label* label); + inline void CompareTaggedAndBranch(const Register& lhs, const Operand& rhs, + Condition cond, Label* label); + // Test the bits of register defined by bit_pattern, and branch if ANY of // those bits are set. May corrupt the status flags. inline void TestAndBranchIfAnySet(const Register& reg, @@ -1006,6 +1014,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // Conditional macros. inline void Ccmp(const Register& rn, const Operand& operand, StatusFlags nzcv, Condition cond); + inline void CcmpTagged(const Register& rn, const Operand& operand, + StatusFlags nzcv, Condition cond); inline void Clz(const Register& rd, const Register& rn); @@ -1597,8 +1607,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { tbx(vd, vn, vn2, vn3, vn4, vm); } - void LoadObject(Register result, Handle<Object> object); - inline void PushSizeRegList( RegList registers, unsigned reg_size, CPURegister::RegisterType type = CPURegister::kRegister) { @@ -1643,11 +1651,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { // be aligned to 16 bytes. void PeekPair(const CPURegister& dst1, const CPURegister& dst2, int offset); - // Compare a register with an operand, and branch to label depending on the - // condition. May corrupt the status flags. - inline void CompareAndBranch(const Register& lhs, const Operand& rhs, - Condition cond, Label* label); - // Insert one or more instructions into the instruction stream that encode // some caller-defined data. The instructions used will be executable with no // side effects. @@ -1767,10 +1770,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { const ParameterCount& actual, Label* done, InvokeFlag flag, bool* definitely_mismatches); - // On function call, call into the debugger if necessary. - void CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual); + // On function call, call into the debugger. + void CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual); void InvokeFunctionCode(Register function, Register new_target, const ParameterCount& expected, const ParameterCount& actual, InvokeFlag flag); diff --git a/deps/v8/src/codegen/arm64/register-arm64.h b/deps/v8/src/codegen/arm64/register-arm64.h index a782bf9cd8dc7f..bc088a3308772f 100644 --- a/deps/v8/src/codegen/arm64/register-arm64.h +++ b/deps/v8/src/codegen/arm64/register-arm64.h @@ -105,7 +105,7 @@ class CPURegister : public RegisterBase<CPURegister, kRegAfterLast> { enum RegisterType { kRegister, kVRegister, kNoRegister }; static constexpr CPURegister no_reg() { - return CPURegister{0, 0, kNoRegister}; + return CPURegister{kCode_no_reg, 0, kNoRegister}; } template <int code, int size, RegisterType type> @@ -597,18 +597,16 @@ class V8_EXPORT_PRIVATE CPURegList { } CPURegister::RegisterType type() const { - DCHECK(IsValid()); return type_; } RegList list() const { - DCHECK(IsValid()); return list_; } inline void set_list(RegList new_list) { - DCHECK(IsValid()); list_ = new_list; + DCHECK(IsValid()); } // Combine another CPURegList into this one. Registers that already exist in @@ -656,7 +654,6 @@ class V8_EXPORT_PRIVATE CPURegList { static CPURegList GetSafepointSavedRegisters(); bool IsEmpty() const { - DCHECK(IsValid()); return list_ == 0; } @@ -664,7 +661,6 @@ class V8_EXPORT_PRIVATE CPURegList { const CPURegister& other2 = NoCPUReg, const CPURegister& other3 = NoCPUReg, const CPURegister& other4 = NoCPUReg) const { - DCHECK(IsValid()); RegList list = 0; if (!other1.IsNone() && (other1.type() == type_)) list |= other1.bit(); if (!other2.IsNone() && (other2.type() == type_)) list |= other2.bit(); @@ -674,12 +670,10 @@ class V8_EXPORT_PRIVATE CPURegList { } int Count() const { - DCHECK(IsValid()); return CountSetBits(list_, kRegListSizeInBits); } int RegisterSizeInBits() const { - DCHECK(IsValid()); return size_; } @@ -690,7 +684,6 @@ class V8_EXPORT_PRIVATE CPURegList { } int TotalSizeInBytes() const { - DCHECK(IsValid()); return RegisterSizeInBytes() * Count(); } diff --git a/deps/v8/src/codegen/arm64/utils-arm64.cc b/deps/v8/src/codegen/arm64/utils-arm64.cc index 2f972ce5027036..dba2eeb7e1032e 100644 --- a/deps/v8/src/codegen/arm64/utils-arm64.cc +++ b/deps/v8/src/codegen/arm64/utils-arm64.cc @@ -89,15 +89,6 @@ int CountLeadingSignBits(int64_t value, int width) { } } -int CountTrailingZeros(uint64_t value, int width) { - DCHECK((width == 32) || (width == 64)); - if (width == 64) { - return static_cast<int>(base::bits::CountTrailingZeros64(value)); - } - return static_cast<int>(base::bits::CountTrailingZeros32( - static_cast<uint32_t>(value & 0xFFFFFFFFF))); -} - int CountSetBits(uint64_t value, int width) { DCHECK((width == 32) || (width == 64)); if (width == 64) { @@ -109,7 +100,7 @@ int CountSetBits(uint64_t value, int width) { int LowestSetBitPosition(uint64_t value) { DCHECK_NE(value, 0U); - return CountTrailingZeros(value, 64) + 1; + return base::bits::CountTrailingZeros(value) + 1; } int HighestSetBitPosition(uint64_t value) { @@ -118,12 +109,14 @@ int HighestSetBitPosition(uint64_t value) { } uint64_t LargestPowerOf2Divisor(uint64_t value) { - return value & (-(int64_t)value); + // Simulate two's complement (instead of casting to signed and negating) to + // avoid undefined behavior on signed overflow. + return value & ((~value) + 1); } int MaskToBit(uint64_t mask) { DCHECK_EQ(CountSetBits(mask, 64), 1); - return CountTrailingZeros(mask, 64); + return base::bits::CountTrailingZeros(mask); } #undef __ diff --git a/deps/v8/src/codegen/arm64/utils-arm64.h b/deps/v8/src/codegen/arm64/utils-arm64.h index 6bddce6fff2ed8..182d781d55da3d 100644 --- a/deps/v8/src/codegen/arm64/utils-arm64.h +++ b/deps/v8/src/codegen/arm64/utils-arm64.h @@ -33,7 +33,6 @@ int float16classify(float16 value); // Bit counting. int CountLeadingZeros(uint64_t value, int width); int CountLeadingSignBits(int64_t value, int width); -V8_EXPORT_PRIVATE int CountTrailingZeros(uint64_t value, int width); V8_EXPORT_PRIVATE int CountSetBits(uint64_t value, int width); int LowestSetBitPosition(uint64_t value); int HighestSetBitPosition(uint64_t value); @@ -61,7 +60,7 @@ T ReverseBytes(T value, int block_bytes_log2) { static const uint8_t permute_table[3][8] = {{6, 7, 4, 5, 2, 3, 0, 1}, {4, 5, 6, 7, 0, 1, 2, 3}, {0, 1, 2, 3, 4, 5, 6, 7}}; - T result = 0; + typename std::make_unsigned<T>::type result = 0; for (int i = 0; i < 8; i++) { result <<= 8; result |= bytes[permute_table[block_bytes_log2 - 1][i]]; diff --git a/deps/v8/src/codegen/assembler.cc b/deps/v8/src/codegen/assembler.cc index 498afb03206432..4e354d9e54b29d 100644 --- a/deps/v8/src/codegen/assembler.cc +++ b/deps/v8/src/codegen/assembler.cc @@ -92,7 +92,7 @@ class DefaultAssemblerBuffer : public AssemblerBuffer { std::unique_ptr<AssemblerBuffer> Grow(int new_size) override { DCHECK_LT(size(), new_size); - return base::make_unique<DefaultAssemblerBuffer>(new_size); + return std::make_unique<DefaultAssemblerBuffer>(new_size); } private: @@ -121,12 +121,12 @@ class ExternalAssemblerBufferImpl : public AssemblerBuffer { std::unique_ptr<AssemblerBuffer> ExternalAssemblerBuffer(void* start, int size) { - return base::make_unique<ExternalAssemblerBufferImpl>( + return std::make_unique<ExternalAssemblerBufferImpl>( reinterpret_cast<byte*>(start), size); } std::unique_ptr<AssemblerBuffer> NewAssemblerBuffer(int size) { - return base::make_unique<DefaultAssemblerBuffer>(size); + return std::make_unique<DefaultAssemblerBuffer>(size); } // ----------------------------------------------------------------------------- diff --git a/deps/v8/src/codegen/assembler.h b/deps/v8/src/codegen/assembler.h index 98639583d8119f..af70c4a48fb279 100644 --- a/deps/v8/src/codegen/assembler.h +++ b/deps/v8/src/codegen/assembler.h @@ -36,6 +36,7 @@ #define V8_CODEGEN_ASSEMBLER_H_ #include <forward_list> +#include <memory> #include <unordered_map> #include "src/base/memory.h" diff --git a/deps/v8/src/codegen/code-stub-assembler.cc b/deps/v8/src/codegen/code-stub-assembler.cc index 7dad8cb95e00a2..3051ce3662c8ce 100644 --- a/deps/v8/src/codegen/code-stub-assembler.cc +++ b/deps/v8/src/codegen/code-stub-assembler.cc @@ -7,9 +7,11 @@ #include "include/v8-internal.h" #include "src/base/macros.h" #include "src/codegen/code-factory.h" +#include "src/codegen/tnode.h" #include "src/common/globals.h" #include "src/execution/frames-inl.h" #include "src/execution/frames.h" +#include "src/execution/protectors.h" #include "src/heap/heap-inl.h" // For Page/MemoryChunk. TODO(jkummerow): Drop. #include "src/logging/counters.h" #include "src/objects/api-callbacks.h" @@ -17,6 +19,7 @@ #include "src/objects/descriptor-array.h" #include "src/objects/function-kind.h" #include "src/objects/heap-number.h" +#include "src/objects/js-generator.h" #include "src/objects/oddball.h" #include "src/objects/ordered-hash-table-inl.h" #include "src/objects/property-cell.h" @@ -26,10 +29,6 @@ namespace v8 { namespace internal { using compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; -template <class T> -using SloppyTNode = compiler::SloppyTNode<T>; CodeStubAssembler::CodeStubAssembler(compiler::CodeAssemblerState* state) : compiler::CodeAssembler(state), @@ -135,6 +134,148 @@ void CodeStubAssembler::Check(SloppyTNode<Word32T> condition_node, Check(branch, message, file, line, extra_nodes); } +template <> +TNode<Smi> CodeStubAssembler::IntPtrToParameter<Smi>(TNode<IntPtrT> value) { + return SmiTag(value); +} +template <> +TNode<IntPtrT> CodeStubAssembler::IntPtrToParameter<IntPtrT>( + TNode<IntPtrT> value) { + return value; +} + +void CodeStubAssembler::CollectCallableFeedback( + TNode<Object> maybe_target, TNode<Context> context, + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot_id) { + Label extra_checks(this, Label::kDeferred), done(this); + + // Check if we have monomorphic {target} feedback already. + TNode<MaybeObject> feedback = + LoadFeedbackVectorSlot(feedback_vector, slot_id); + Comment("check if monomorphic"); + TNode<BoolT> is_monomorphic = IsWeakReferenceToObject(feedback, maybe_target); + GotoIf(is_monomorphic, &done); + + // Check if it is a megamorphic {target}. + Comment("check if megamorphic"); + TNode<BoolT> is_megamorphic = TaggedEqual( + feedback, HeapConstant(FeedbackVector::MegamorphicSentinel(isolate()))); + Branch(is_megamorphic, &done, &extra_checks); + + BIND(&extra_checks); + { + Label initialize(this), mark_megamorphic(this); + + Comment("check if weak reference"); + TNode<BoolT> is_uninitialized = TaggedEqual( + feedback, + HeapConstant(FeedbackVector::UninitializedSentinel(isolate()))); + GotoIf(is_uninitialized, &initialize); + CSA_ASSERT(this, IsWeakOrCleared(feedback)); + + // If the weak reference is cleared, we have a new chance to become + // monomorphic. + Comment("check if weak reference is cleared"); + Branch(IsCleared(feedback), &initialize, &mark_megamorphic); + + BIND(&initialize); + { + Comment("check if function in same native context"); + GotoIf(TaggedIsSmi(maybe_target), &mark_megamorphic); + TNode<HeapObject> target = CAST(maybe_target); + // Check if the {target} is a JSFunction or JSBoundFunction + // in the current native context. + TVARIABLE(HeapObject, var_current, target); + Label loop(this, &var_current), done_loop(this); + Goto(&loop); + BIND(&loop); + { + Label if_boundfunction(this), if_function(this); + TNode<HeapObject> current = var_current.value(); + TNode<Uint16T> current_instance_type = LoadInstanceType(current); + GotoIf(InstanceTypeEqual(current_instance_type, JS_BOUND_FUNCTION_TYPE), + &if_boundfunction); + Branch(InstanceTypeEqual(current_instance_type, JS_FUNCTION_TYPE), + &if_function, &mark_megamorphic); + + BIND(&if_function); + { + // Check that the JSFunction {current} is in the current native + // context. + TNode<Context> current_context = + CAST(LoadObjectField(current, JSFunction::kContextOffset)); + TNode<NativeContext> current_native_context = + LoadNativeContext(current_context); + Branch( + TaggedEqual(LoadNativeContext(context), current_native_context), + &done_loop, &mark_megamorphic); + } + BIND(&if_boundfunction); + { + // Continue with the [[BoundTargetFunction]] of {target}. + var_current = LoadObjectField<HeapObject>( + current, JSBoundFunction::kBoundTargetFunctionOffset); + Goto(&loop); + } + } + BIND(&done_loop); + StoreWeakReferenceInFeedbackVector(feedback_vector, slot_id, target); + ReportFeedbackUpdate(feedback_vector, slot_id, "Call:Initialize"); + Goto(&done); + } + + BIND(&mark_megamorphic); + { + // MegamorphicSentinel is an immortal immovable object so + // write-barrier is not needed. + Comment("transition to megamorphic"); + DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kmegamorphic_symbol)); + StoreFeedbackVectorSlot( + feedback_vector, slot_id, + HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())), + SKIP_WRITE_BARRIER); + ReportFeedbackUpdate(feedback_vector, slot_id, + "Call:TransitionMegamorphic"); + Goto(&done); + } + } + + BIND(&done); +} + +void CodeStubAssembler::CollectCallFeedback( + TNode<Object> maybe_target, TNode<Context> context, + TNode<HeapObject> maybe_feedback_vector, TNode<UintPtrT> slot_id) { + Label feedback_done(this); + // If feedback_vector is not valid, then nothing to do. + GotoIf(IsUndefined(maybe_feedback_vector), &feedback_done); + + // Increment the call count. + TNode<FeedbackVector> feedback_vector = CAST(maybe_feedback_vector); + IncrementCallCount(feedback_vector, slot_id); + + // Collect the callable {target} feedback. + CollectCallableFeedback(maybe_target, context, feedback_vector, slot_id); + Goto(&feedback_done); + + BIND(&feedback_done); +} + +void CodeStubAssembler::IncrementCallCount( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot_id) { + Comment("increment call count"); + TNode<Smi> call_count = + CAST(LoadFeedbackVectorSlot(feedback_vector, slot_id, kTaggedSize)); + // The lowest {FeedbackNexus::CallCountField::kShift} bits of the call + // count are used as flags. To increment the call count by 1 we hence + // have to increment by 1 << {FeedbackNexus::CallCountField::kShift}. + TNode<Smi> new_count = SmiAdd( + call_count, SmiConstant(1 << FeedbackNexus::CallCountField::kShift)); + // Count is Smi, so we don't need a write barrier. + StoreFeedbackVectorSlot(feedback_vector, slot_id, new_count, + SKIP_WRITE_BARRIER, kTaggedSize); +} + void CodeStubAssembler::FastCheck(TNode<BoolT> condition) { Label ok(this), not_ok(this, Label::kDeferred); Branch(condition, &ok, ¬_ok); @@ -221,7 +362,7 @@ TNode<Object> CodeStubAssembler::NoContextConstant() { } #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ - compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ + TNode<std::remove_pointer<std::remove_reference<decltype( \ std::declval<Heap>().rootAccessorName())>::type>::type> \ CodeStubAssembler::name##Constant() { \ return UncheckedCast<std::remove_pointer<std::remove_reference<decltype( \ @@ -232,7 +373,7 @@ HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR) #undef HEAP_CONSTANT_ACCESSOR #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ - compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ + TNode<std::remove_pointer<std::remove_reference<decltype( \ std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \ CodeStubAssembler::name##Constant() { \ return UncheckedCast<std::remove_pointer<std::remove_reference<decltype( \ @@ -242,14 +383,12 @@ HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR) HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR) #undef HEAP_CONSTANT_ACCESSOR -#define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \ - compiler::TNode<BoolT> CodeStubAssembler::Is##name( \ - SloppyTNode<Object> value) { \ - return TaggedEqual(value, name##Constant()); \ - } \ - compiler::TNode<BoolT> CodeStubAssembler::IsNot##name( \ - SloppyTNode<Object> value) { \ - return TaggedNotEqual(value, name##Constant()); \ +#define HEAP_CONSTANT_TEST(rootIndexName, rootAccessorName, name) \ + TNode<BoolT> CodeStubAssembler::Is##name(SloppyTNode<Object> value) { \ + return TaggedEqual(value, name##Constant()); \ + } \ + TNode<BoolT> CodeStubAssembler::IsNot##name(SloppyTNode<Object> value) { \ + return TaggedNotEqual(value, name##Constant()); \ } HEAP_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_TEST) #undef HEAP_CONSTANT_TEST @@ -264,6 +403,21 @@ TNode<BInt> CodeStubAssembler::BIntConstant(int value) { #endif } +template <> +TNode<Smi> CodeStubAssembler::IntPtrOrSmiConstant<Smi>(int value) { + return SmiConstant(value); +} + +template <> +TNode<IntPtrT> CodeStubAssembler::IntPtrOrSmiConstant<IntPtrT>(int value) { + return IntPtrConstant(value); +} + +template <> +TNode<RawPtrT> CodeStubAssembler::IntPtrOrSmiConstant<RawPtrT>(int value) { + return ReinterpretCast<RawPtrT>(IntPtrConstant(value)); +} + Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) { if (mode == SMI_PARAMETERS) { return SmiConstant(value); @@ -273,41 +427,29 @@ Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) { } } -TNode<BoolT> CodeStubAssembler::IntPtrOrSmiEqual(Node* left, Node* right, - ParameterMode mode) { - if (mode == SMI_PARAMETERS) { - return SmiEqual(CAST(left), CAST(right)); - } else { - DCHECK_EQ(INTPTR_PARAMETERS, mode); - return IntPtrEqual(UncheckedCast<IntPtrT>(left), - UncheckedCast<IntPtrT>(right)); +bool CodeStubAssembler::IsIntPtrOrSmiConstantZero(TNode<Smi> test) { + Smi smi_test; + if (ToSmiConstant(test, &smi_test) && smi_test.value() == 0) { + return true; } + return false; } -TNode<BoolT> CodeStubAssembler::IntPtrOrSmiNotEqual(Node* left, Node* right, - ParameterMode mode) { - if (mode == SMI_PARAMETERS) { - return SmiNotEqual(CAST(left), CAST(right)); - } else { - DCHECK_EQ(INTPTR_PARAMETERS, mode); - return WordNotEqual(UncheckedCast<IntPtrT>(left), - UncheckedCast<IntPtrT>(right)); +bool CodeStubAssembler::IsIntPtrOrSmiConstantZero(TNode<IntPtrT> test) { + int32_t constant_test; + if (ToInt32Constant(test, &constant_test) && constant_test == 0) { + return true; } + return false; } bool CodeStubAssembler::IsIntPtrOrSmiConstantZero(Node* test, ParameterMode mode) { - int32_t constant_test; - Smi smi_test; if (mode == INTPTR_PARAMETERS) { - if (ToInt32Constant(test, &constant_test) && constant_test == 0) { - return true; - } + return IsIntPtrOrSmiConstantZero(UncheckedCast<IntPtrT>(test)); } else { DCHECK_EQ(mode, SMI_PARAMETERS); - if (ToSmiConstant(test, &smi_test) && smi_test.value() == 0) { - return true; - } + return IsIntPtrOrSmiConstantZero(UncheckedCast<Smi>(test)); } return false; } @@ -352,6 +494,10 @@ Node* CodeStubAssembler::MatchesParameterMode(Node* value, ParameterMode mode) { } TNode<BoolT> CodeStubAssembler::WordIsPowerOfTwo(SloppyTNode<IntPtrT> value) { + intptr_t constant; + if (ToIntPtrConstant(value, &constant)) { + return BoolConstant(base::bits::IsPowerOfTwo(constant)); + } // value && !(value & (value - 1)) return IntPtrEqual( Select<IntPtrT>( @@ -578,21 +724,44 @@ TNode<Float64T> CodeStubAssembler::Float64Trunc(SloppyTNode<Float64T> x) { TNode<BoolT> CodeStubAssembler::IsValidSmi(TNode<Smi> smi) { if (SmiValuesAre32Bits() && kSystemPointerSize == kInt64Size) { // Check that the Smi value is zero in the lower bits. - TNode<IntPtrT> value = BitcastTaggedSignedToWord(smi); + TNode<IntPtrT> value = BitcastTaggedToWordForTagAndSmiBits(smi); return Word32Equal(Int32Constant(0), TruncateIntPtrToInt32(value)); } return Int32TrueConstant(); } -Node* CodeStubAssembler::SmiShiftBitsConstant() { - return IntPtrConstant(kSmiShiftSize + kSmiTagSize); +TNode<BoolT> CodeStubAssembler::IsValidSmiIndex(TNode<Smi> smi) { + if (COMPRESS_POINTERS_BOOL) { + return WordEqual( + BitcastTaggedToWordForTagAndSmiBits(smi), + BitcastTaggedToWordForTagAndSmiBits(NormalizeSmiIndex(smi))); + } + return Int32TrueConstant(); +} + +TNode<Smi> CodeStubAssembler::NormalizeSmiIndex(TNode<Smi> smi_index) { + if (COMPRESS_POINTERS_BOOL) { + TNode<Int32T> raw = + TruncateWordToInt32(BitcastTaggedToWordForTagAndSmiBits(smi_index)); + smi_index = BitcastWordToTaggedSigned(ChangeInt32ToIntPtr(raw)); + } + return smi_index; } TNode<Smi> CodeStubAssembler::SmiFromInt32(SloppyTNode<Int32T> value) { - TNode<IntPtrT> value_intptr = ChangeInt32ToIntPtr(value); - TNode<Smi> smi = - BitcastWordToTaggedSigned(WordShl(value_intptr, SmiShiftBitsConstant())); - return smi; + if (COMPRESS_POINTERS_BOOL) { + static_assert(!COMPRESS_POINTERS_BOOL || (kSmiShiftSize + kSmiTagSize == 1), + "Use shifting instead of add"); + return BitcastWordToTaggedSigned( + ChangeUint32ToWord(Int32Add(value, value))); + } + return SmiTag(ChangeInt32ToIntPtr(value)); +} + +TNode<Smi> CodeStubAssembler::SmiFromUint32(TNode<Uint32T> value) { + CSA_ASSERT(this, IntPtrLessThan(ChangeUint32ToWord(value), + IntPtrConstant(Smi::kMaxValue))); + return SmiFromInt32(Signed(value)); } TNode<BoolT> CodeStubAssembler::IsValidPositiveSmi(TNode<IntPtrT> value) { @@ -612,6 +781,9 @@ TNode<Smi> CodeStubAssembler::SmiTag(SloppyTNode<IntPtrT> value) { if (ToInt32Constant(value, &constant_value) && Smi::IsValid(constant_value)) { return SmiConstant(constant_value); } + if (COMPRESS_POINTERS_BOOL) { + return SmiFromInt32(TruncateIntPtrToInt32(value)); + } TNode<Smi> smi = BitcastWordToTaggedSigned(WordShl(value, SmiShiftBitsConstant())); return smi; @@ -622,11 +794,19 @@ TNode<IntPtrT> CodeStubAssembler::SmiUntag(SloppyTNode<Smi> value) { if (ToIntPtrConstant(value, &constant_value)) { return IntPtrConstant(constant_value >> (kSmiShiftSize + kSmiTagSize)); } - return Signed( - WordSar(BitcastTaggedSignedToWord(value), SmiShiftBitsConstant())); + if (COMPRESS_POINTERS_BOOL) { + return ChangeInt32ToIntPtr(SmiToInt32(value)); + } + return Signed(WordSar(BitcastTaggedToWordForTagAndSmiBits(value), + SmiShiftBitsConstant())); } TNode<Int32T> CodeStubAssembler::SmiToInt32(SloppyTNode<Smi> value) { + if (COMPRESS_POINTERS_BOOL) { + return Signed(Word32Sar( + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(value)), + SmiShiftBitsConstant32())); + } TNode<IntPtrT> result = SmiUntag(value); return TruncateIntPtrToInt32(result); } @@ -673,13 +853,13 @@ TNode<Smi> CodeStubAssembler::TrySmiAdd(TNode<Smi> lhs, TNode<Smi> rhs, Label* if_overflow) { if (SmiValuesAre32Bits()) { return BitcastWordToTaggedSigned( - TryIntPtrAdd(BitcastTaggedSignedToWord(lhs), - BitcastTaggedSignedToWord(rhs), if_overflow)); + TryIntPtrAdd(BitcastTaggedToWordForTagAndSmiBits(lhs), + BitcastTaggedToWordForTagAndSmiBits(rhs), if_overflow)); } else { DCHECK(SmiValuesAre31Bits()); TNode<PairT<Int32T, BoolT>> pair = Int32AddWithOverflow( - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(lhs)), - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(rhs))); + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(lhs)), + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(rhs))); TNode<BoolT> overflow = Projection<1>(pair); GotoIf(overflow, if_overflow); TNode<Int32T> result = Projection<0>(pair); @@ -690,8 +870,9 @@ TNode<Smi> CodeStubAssembler::TrySmiAdd(TNode<Smi> lhs, TNode<Smi> rhs, TNode<Smi> CodeStubAssembler::TrySmiSub(TNode<Smi> lhs, TNode<Smi> rhs, Label* if_overflow) { if (SmiValuesAre32Bits()) { - TNode<PairT<IntPtrT, BoolT>> pair = IntPtrSubWithOverflow( - BitcastTaggedSignedToWord(lhs), BitcastTaggedSignedToWord(rhs)); + TNode<PairT<IntPtrT, BoolT>> pair = + IntPtrSubWithOverflow(BitcastTaggedToWordForTagAndSmiBits(lhs), + BitcastTaggedToWordForTagAndSmiBits(rhs)); TNode<BoolT> overflow = Projection<1>(pair); GotoIf(overflow, if_overflow); TNode<IntPtrT> result = Projection<0>(pair); @@ -699,8 +880,8 @@ TNode<Smi> CodeStubAssembler::TrySmiSub(TNode<Smi> lhs, TNode<Smi> rhs, } else { DCHECK(SmiValuesAre31Bits()); TNode<PairT<Int32T, BoolT>> pair = Int32SubWithOverflow( - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(lhs)), - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(rhs))); + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(lhs)), + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(rhs))); TNode<BoolT> overflow = Projection<1>(pair); GotoIf(overflow, if_overflow); TNode<Int32T> result = Projection<0>(pair); @@ -878,7 +1059,7 @@ TNode<Number> CodeStubAssembler::SmiMul(TNode<Smi> a, TNode<Smi> b) { } BIND(&answer_zero); { - TNode<Word32T> or_result = Word32Or(lhs32, rhs32); + TNode<Int32T> or_result = Word32Or(lhs32, rhs32); Label if_should_be_negative_zero(this), if_should_be_zero(this); Branch(Int32LessThan(or_result, zero), &if_should_be_negative_zero, &if_should_be_zero); @@ -982,41 +1163,27 @@ TNode<Int32T> CodeStubAssembler::TruncateIntPtrToInt32( return ReinterpretCast<Int32T>(value); } -TNode<BoolT> CodeStubAssembler::TaggedIsSmi(SloppyTNode<Object> a) { - STATIC_ASSERT(kSmiTagMask < kMaxUInt32); - return Word32Equal(Word32And(TruncateIntPtrToInt32(BitcastTaggedToWord(a)), - Int32Constant(kSmiTagMask)), - Int32Constant(0)); -} - TNode<BoolT> CodeStubAssembler::TaggedIsSmi(TNode<MaybeObject> a) { STATIC_ASSERT(kSmiTagMask < kMaxUInt32); return Word32Equal( - Word32And(TruncateIntPtrToInt32(BitcastMaybeObjectToWord(a)), + Word32And(TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), Int32Constant(kSmiTagMask)), Int32Constant(0)); } -TNode<BoolT> CodeStubAssembler::TaggedIsNotSmi(SloppyTNode<Object> a) { - // Although BitcastTaggedSignedToWord is generally unsafe on HeapObjects, we - // can nonetheless use it to inspect the Smi tag. The assumption here is that - // the GC will not exchange Smis for HeapObjects or vice-versa. - TNode<IntPtrT> a_bitcast = BitcastTaggedSignedToWord(UncheckedCast<Smi>(a)); - STATIC_ASSERT(kSmiTagMask < kMaxUInt32); - return Word32NotEqual( - Word32And(TruncateIntPtrToInt32(a_bitcast), Int32Constant(kSmiTagMask)), - Int32Constant(0)); +TNode<BoolT> CodeStubAssembler::TaggedIsNotSmi(TNode<MaybeObject> a) { + return Word32BinaryNot(TaggedIsSmi(a)); } TNode<BoolT> CodeStubAssembler::TaggedIsPositiveSmi(SloppyTNode<Object> a) { #if defined(V8_HOST_ARCH_32_BIT) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) return Word32Equal( Word32And( - TruncateIntPtrToInt32(BitcastTaggedToWord(a)), - Uint32Constant(kSmiTagMask | static_cast<int32_t>(kSmiSignMask))), + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), + Uint32Constant(static_cast<uint32_t>(kSmiTagMask | kSmiSignMask))), Int32Constant(0)); #else - return WordEqual(WordAnd(BitcastTaggedToWord(a), + return WordEqual(WordAnd(BitcastTaggedToWordForTagAndSmiBits(a), IntPtrConstant(kSmiTagMask | kSmiSignMask)), IntPtrConstant(0)); #endif @@ -1052,55 +1219,6 @@ TNode<Float64T> CodeStubAssembler::LoadDoubleWithHoleCheck( INTPTR_PARAMETERS, if_hole); } -void CodeStubAssembler::BranchIfPrototypesHaveNoElements( - Node* receiver_map, Label* definitely_no_elements, - Label* possibly_elements) { - CSA_SLOW_ASSERT(this, IsMap(receiver_map)); - VARIABLE(var_map, MachineRepresentation::kTagged, receiver_map); - Label loop_body(this, &var_map); - TNode<FixedArray> empty_fixed_array = EmptyFixedArrayConstant(); - TNode<NumberDictionary> empty_slow_element_dictionary = - EmptySlowElementDictionaryConstant(); - Goto(&loop_body); - - BIND(&loop_body); - { - Node* map = var_map.value(); - TNode<HeapObject> prototype = LoadMapPrototype(map); - GotoIf(IsNull(prototype), definitely_no_elements); - TNode<Map> prototype_map = LoadMap(prototype); - TNode<Uint16T> prototype_instance_type = LoadMapInstanceType(prototype_map); - - // Pessimistically assume elements if a Proxy, Special API Object, - // or JSPrimitiveWrapper wrapper is found on the prototype chain. After this - // instance type check, it's not necessary to check for interceptors or - // access checks. - Label if_custom(this, Label::kDeferred), if_notcustom(this); - Branch(IsCustomElementsReceiverInstanceType(prototype_instance_type), - &if_custom, &if_notcustom); - - BIND(&if_custom); - { - // For string JSPrimitiveWrapper wrappers we still support the checks as - // long as they wrap the empty string. - GotoIfNot( - InstanceTypeEqual(prototype_instance_type, JS_PRIMITIVE_WRAPPER_TYPE), - possibly_elements); - Node* prototype_value = LoadJSPrimitiveWrapperValue(prototype); - Branch(IsEmptyString(prototype_value), &if_notcustom, possibly_elements); - } - - BIND(&if_notcustom); - { - TNode<FixedArrayBase> prototype_elements = LoadElements(CAST(prototype)); - var_map.Bind(prototype_map); - GotoIf(TaggedEqual(prototype_elements, empty_fixed_array), &loop_body); - Branch(TaggedEqual(prototype_elements, empty_slow_element_dictionary), - &loop_body, possibly_elements); - } - } -} - void CodeStubAssembler::BranchIfJSReceiver(SloppyTNode<Object> object, Label* if_true, Label* if_false) { GotoIf(TaggedIsSmi(object), if_false); @@ -1118,19 +1236,6 @@ void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) { #endif } -void CodeStubAssembler::GotoIfDebugExecutionModeChecksSideEffects( - Label* if_true) { - STATIC_ASSERT(sizeof(DebugInfo::ExecutionMode) >= sizeof(int32_t)); - - TNode<ExternalReference> execution_mode_address = ExternalConstant( - ExternalReference::debug_execution_mode_address(isolate())); - TNode<Int32T> execution_mode = - UncheckedCast<Int32T>(Load(MachineType::Int32(), execution_mode_address)); - - GotoIf(Word32Equal(execution_mode, Int32Constant(DebugInfo::kSideEffects)), - if_true); -} - TNode<HeapObject> CodeStubAssembler::AllocateRaw(TNode<IntPtrT> size_in_bytes, AllocationFlags flags, TNode<RawPtrT> top_address, @@ -1557,7 +1662,7 @@ void CodeStubAssembler::GotoIfMapHasSlowProperties(TNode<Map> map, } TNode<HeapObject> CodeStubAssembler::LoadFastProperties( - SloppyTNode<JSObject> object) { + SloppyTNode<JSReceiver> object) { CSA_SLOW_ASSERT(this, Word32BinaryNot(IsDictionaryMap(LoadMap(object)))); TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object); return Select<HeapObject>( @@ -1566,7 +1671,7 @@ TNode<HeapObject> CodeStubAssembler::LoadFastProperties( } TNode<HeapObject> CodeStubAssembler::LoadSlowProperties( - SloppyTNode<JSObject> object) { + SloppyTNode<JSReceiver> object) { CSA_SLOW_ASSERT(this, IsDictionaryMap(LoadMap(object))); TNode<Object> properties = LoadJSReceiverPropertiesOrHash(object); return Select<HeapObject>( @@ -1862,18 +1967,8 @@ TNode<Uint32T> CodeStubAssembler::LoadStringLengthAsWord32( return LoadObjectField<Uint32T>(string, String::kLengthOffset); } -Node* CodeStubAssembler::PointerToSeqStringData(Node* seq_string) { - CSA_ASSERT(this, IsString(seq_string)); - CSA_ASSERT(this, - IsSequentialStringInstanceType(LoadInstanceType(seq_string))); - STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); - return IntPtrAdd( - BitcastTaggedToWord(seq_string), - IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); -} - -Node* CodeStubAssembler::LoadJSPrimitiveWrapperValue(Node* object) { - CSA_ASSERT(this, IsJSPrimitiveWrapper(object)); +TNode<Object> CodeStubAssembler::LoadJSPrimitiveWrapperValue( + TNode<JSPrimitiveWrapper> object) { return LoadObjectField(object, JSPrimitiveWrapper::kValueOffset); } @@ -1887,15 +1982,9 @@ void CodeStubAssembler::DispatchMaybeObject(TNode<MaybeObject> maybe_object, GotoIf(IsCleared(maybe_object), if_cleared); - GotoIf(Word32Equal(Word32And(TruncateIntPtrToInt32( - BitcastMaybeObjectToWord(maybe_object)), - Int32Constant(kHeapObjectTagMask)), - Int32Constant(kHeapObjectTag)), - &inner_if_strong); + GotoIf(IsStrong(maybe_object), &inner_if_strong); - *extracted = - BitcastWordToTagged(WordAnd(BitcastMaybeObjectToWord(maybe_object), - IntPtrConstant(~kWeakHeapObjectMask))); + *extracted = GetHeapObjectAssumeWeak(maybe_object); Goto(if_weak); BIND(&inner_if_smi); @@ -1908,10 +1997,10 @@ void CodeStubAssembler::DispatchMaybeObject(TNode<MaybeObject> maybe_object, } TNode<BoolT> CodeStubAssembler::IsStrong(TNode<MaybeObject> value) { - return Word32Equal( - Word32And(TruncateIntPtrToInt32(BitcastMaybeObjectToWord(value)), - Int32Constant(kHeapObjectTagMask)), - Int32Constant(kHeapObjectTag)); + return Word32Equal(Word32And(TruncateIntPtrToInt32( + BitcastTaggedToWordForTagAndSmiBits(value)), + Int32Constant(kHeapObjectTagMask)), + Int32Constant(kHeapObjectTag)); } TNode<HeapObject> CodeStubAssembler::GetHeapObjectIfStrong( @@ -1921,10 +2010,10 @@ TNode<HeapObject> CodeStubAssembler::GetHeapObjectIfStrong( } TNode<BoolT> CodeStubAssembler::IsWeakOrCleared(TNode<MaybeObject> value) { - return Word32Equal( - Word32And(TruncateIntPtrToInt32(BitcastMaybeObjectToWord(value)), - Int32Constant(kHeapObjectTagMask)), - Int32Constant(kWeakHeapObjectTag)); + return Word32Equal(Word32And(TruncateIntPtrToInt32( + BitcastTaggedToWordForTagAndSmiBits(value)), + Int32Constant(kHeapObjectTagMask)), + Int32Constant(kWeakHeapObjectTag)); } TNode<BoolT> CodeStubAssembler::IsCleared(TNode<MaybeObject> value) { @@ -1932,11 +2021,6 @@ TNode<BoolT> CodeStubAssembler::IsCleared(TNode<MaybeObject> value) { Int32Constant(kClearedWeakHeapObjectLower32)); } -TNode<BoolT> CodeStubAssembler::IsNotCleared(TNode<MaybeObject> value) { - return Word32NotEqual(TruncateIntPtrToInt32(BitcastMaybeObjectToWord(value)), - Int32Constant(kClearedWeakHeapObjectLower32)); -} - TNode<HeapObject> CodeStubAssembler::GetHeapObjectAssumeWeak( TNode<MaybeObject> value) { CSA_ASSERT(this, IsWeakOrCleared(value)); @@ -1951,43 +2035,41 @@ TNode<HeapObject> CodeStubAssembler::GetHeapObjectAssumeWeak( return GetHeapObjectAssumeWeak(value); } -TNode<BoolT> CodeStubAssembler::IsWeakReferenceTo(TNode<MaybeObject> object, - TNode<Object> value) { -#if defined(V8_HOST_ARCH_32_BIT) || defined(V8_COMPRESS_POINTERS) - STATIC_ASSERT(kTaggedSize == kInt32Size); - return Word32Equal( - Word32And(TruncateWordToInt32(BitcastMaybeObjectToWord(object)), - Uint32Constant( - static_cast<uint32_t>(~kWeakHeapObjectMask & kMaxUInt32))), - TruncateWordToInt32(BitcastTaggedToWord(value))); -#else - return WordEqual(WordAnd(BitcastMaybeObjectToWord(object), - IntPtrConstant(~kWeakHeapObjectMask)), - BitcastTaggedToWord(value)); - -#endif -} - -TNode<BoolT> CodeStubAssembler::IsStrongReferenceTo(TNode<MaybeObject> object, - TNode<Object> value) { - return TaggedEqual(BitcastWordToTagged(BitcastMaybeObjectToWord(object)), - value); -} - -TNode<BoolT> CodeStubAssembler::IsNotWeakReferenceTo(TNode<MaybeObject> object, - TNode<Object> value) { -#if defined(V8_HOST_ARCH_32_BIT) || defined(V8_COMPRESS_POINTERS) - return Word32NotEqual( - Word32And(TruncateWordToInt32(BitcastMaybeObjectToWord(object)), - Uint32Constant( - static_cast<uint32_t>(~kWeakHeapObjectMask & kMaxUInt32))), - TruncateWordToInt32(BitcastTaggedToWord(value))); -#else - return WordNotEqual(WordAnd(BitcastMaybeObjectToWord(object), - IntPtrConstant(~kWeakHeapObjectMask)), - BitcastTaggedToWord(value)); - -#endif +// This version generates +// (maybe_object & ~mask) == value +// It works for non-Smi |maybe_object| and for both Smi and HeapObject values +// but requires a big constant for ~mask. +TNode<BoolT> CodeStubAssembler::IsWeakReferenceToObject( + TNode<MaybeObject> maybe_object, TNode<Object> value) { + CSA_ASSERT(this, TaggedIsNotSmi(maybe_object)); + if (COMPRESS_POINTERS_BOOL) { + return Word32Equal( + Word32And(TruncateWordToInt32(BitcastMaybeObjectToWord(maybe_object)), + Uint32Constant(~static_cast<uint32_t>(kWeakHeapObjectMask))), + TruncateWordToInt32(BitcastTaggedToWord(value))); + } else { + return WordEqual(WordAnd(BitcastMaybeObjectToWord(maybe_object), + IntPtrConstant(~kWeakHeapObjectMask)), + BitcastTaggedToWord(value)); + } +} + +// This version generates +// maybe_object == (heap_object | mask) +// It works for any |maybe_object| values and generates a better code because it +// uses a small constant for mask. +TNode<BoolT> CodeStubAssembler::IsWeakReferenceTo( + TNode<MaybeObject> maybe_object, TNode<HeapObject> heap_object) { + if (COMPRESS_POINTERS_BOOL) { + return Word32Equal( + TruncateWordToInt32(BitcastMaybeObjectToWord(maybe_object)), + Word32Or(TruncateWordToInt32(BitcastTaggedToWord(heap_object)), + Int32Constant(kWeakHeapObjectMask))); + } else { + return WordEqual(BitcastMaybeObjectToWord(maybe_object), + WordOr(BitcastTaggedToWord(heap_object), + IntPtrConstant(kWeakHeapObjectMask))); + } } TNode<MaybeObject> CodeStubAssembler::MakeWeak(TNode<HeapObject> value) { @@ -2123,16 +2205,27 @@ TNode<IntPtrT> CodeStubAssembler::LoadPropertyArrayLength( return Signed(DecodeWord<PropertyArray::LengthField>(value)); } -TNode<RawPtrT> CodeStubAssembler::LoadJSTypedArrayBackingStore( +TNode<RawPtrT> CodeStubAssembler::LoadJSTypedArrayDataPtr( TNode<JSTypedArray> typed_array) { - // Backing store = external_pointer + base_pointer. - Node* external_pointer = - LoadObjectField(typed_array, JSTypedArray::kExternalPointerOffset, - MachineType::Pointer()); - TNode<Object> base_pointer = - LoadObjectField(typed_array, JSTypedArray::kBasePointerOffset); - return UncheckedCast<RawPtrT>( - IntPtrAdd(external_pointer, BitcastTaggedToWord(base_pointer))); + // Data pointer = external_pointer + static_cast<Tagged_t>(base_pointer). + TNode<RawPtrT> external_pointer = LoadObjectField<RawPtrT>( + typed_array, JSTypedArray::kExternalPointerOffset); + + TNode<IntPtrT> base_pointer; + if (COMPRESS_POINTERS_BOOL) { + TNode<Int32T> compressed_base = + LoadObjectField<Int32T>(typed_array, JSTypedArray::kBasePointerOffset); + // Zero-extend TaggedT to WordT according to current compression scheme + // so that the addition with |external_pointer| (which already contains + // compensated offset value) below will decompress the tagged value. + // See JSTypedArray::ExternalPointerCompensationForOnHeapArray() for + // details. + base_pointer = Signed(ChangeUint32ToWord(compressed_base)); + } else { + base_pointer = + LoadObjectField<IntPtrT>(typed_array, JSTypedArray::kBasePointerOffset); + } + return RawPtrAdd(external_pointer, base_pointer); } TNode<BigInt> CodeStubAssembler::LoadFixedBigInt64ArrayElementAsTagged( @@ -2267,8 +2360,7 @@ TNode<BigInt> CodeStubAssembler::BigIntFromInt64(TNode<IntPtrT> value) { return var_result.value(); } -compiler::TNode<BigInt> -CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged( +TNode<BigInt> CodeStubAssembler::LoadFixedBigUint64ArrayElementAsTagged( SloppyTNode<RawPtrT> data_pointer, SloppyTNode<IntPtrT> offset) { Label if_zero(this), done(this); if (Is64()) { @@ -2416,59 +2508,30 @@ TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged( return var_result.value(); } -void CodeStubAssembler::StoreJSTypedArrayElementFromTagged( - TNode<Context> context, TNode<JSTypedArray> typed_array, - TNode<Smi> index_node, TNode<Object> value, ElementsKind elements_kind) { - TNode<RawPtrT> data_pointer = LoadJSTypedArrayBackingStore(typed_array); - switch (elements_kind) { - case UINT8_ELEMENTS: - case UINT8_CLAMPED_ELEMENTS: - case INT8_ELEMENTS: - case UINT16_ELEMENTS: - case INT16_ELEMENTS: - StoreElement(data_pointer, elements_kind, index_node, - SmiToInt32(CAST(value)), SMI_PARAMETERS); - break; - case UINT32_ELEMENTS: - case INT32_ELEMENTS: - StoreElement(data_pointer, elements_kind, index_node, - TruncateTaggedToWord32(context, value), SMI_PARAMETERS); - break; - case FLOAT32_ELEMENTS: - StoreElement(data_pointer, elements_kind, index_node, - TruncateFloat64ToFloat32(LoadHeapNumberValue(CAST(value))), - SMI_PARAMETERS); - break; - case FLOAT64_ELEMENTS: - StoreElement(data_pointer, elements_kind, index_node, - LoadHeapNumberValue(CAST(value)), SMI_PARAMETERS); - break; - case BIGUINT64_ELEMENTS: - case BIGINT64_ELEMENTS: - StoreElement(data_pointer, elements_kind, index_node, - UncheckedCast<BigInt>(value), SMI_PARAMETERS); - break; - default: - UNREACHABLE(); - } -} - +template <typename TIndex> TNode<MaybeObject> CodeStubAssembler::LoadFeedbackVectorSlot( - Node* object, Node* slot_index_node, int additional_offset, - ParameterMode parameter_mode) { - CSA_SLOW_ASSERT(this, IsFeedbackVector(object)); - CSA_SLOW_ASSERT(this, MatchesParameterMode(slot_index_node, parameter_mode)); + TNode<FeedbackVector> feedback_vector, TNode<TIndex> slot, + int additional_offset) { int32_t header_size = FeedbackVector::kFeedbackSlotsOffset + additional_offset - kHeapObjectTag; - TNode<IntPtrT> offset = ElementOffsetFromIndex( - slot_index_node, HOLEY_ELEMENTS, parameter_mode, header_size); + TNode<IntPtrT> offset = + ElementOffsetFromIndex(slot, HOLEY_ELEMENTS, header_size); CSA_SLOW_ASSERT( - this, IsOffsetInBounds(offset, LoadFeedbackVectorLength(CAST(object)), + this, IsOffsetInBounds(offset, LoadFeedbackVectorLength(feedback_vector), FeedbackVector::kHeaderSize)); - return UncheckedCast<MaybeObject>( - Load(MachineType::AnyTagged(), object, offset)); + return Load<MaybeObject>(feedback_vector, offset); } +template TNode<MaybeObject> CodeStubAssembler::LoadFeedbackVectorSlot( + TNode<FeedbackVector> feedback_vector, TNode<Smi> slot, + int additional_offset); +template TNode<MaybeObject> CodeStubAssembler::LoadFeedbackVectorSlot( + TNode<FeedbackVector> feedback_vector, TNode<IntPtrT> slot, + int additional_offset); +template TNode<MaybeObject> CodeStubAssembler::LoadFeedbackVectorSlot( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + int additional_offset); + template <typename Array> TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32ArrayElement( TNode<Array> object, int array_header_size, Node* index_node, @@ -2617,6 +2680,13 @@ TNode<Float64T> CodeStubAssembler::LoadDoubleWithHoleCheck( return UncheckedCast<Float64T>(Load(machine_type, base, offset)); } +TNode<BoolT> CodeStubAssembler::LoadContextHasExtensionField( + SloppyTNode<Context> context) { + TNode<IntPtrT> value = + LoadAndUntagObjectField(context, Context::kLengthOffset); + return IsSetWord<Context::HasExtensionField>(value); +} + TNode<Object> CodeStubAssembler::LoadContextElement( SloppyTNode<Context> context, int slot_index) { int offset = Context::SlotOffset(slot_index); @@ -2626,15 +2696,15 @@ TNode<Object> CodeStubAssembler::LoadContextElement( TNode<Object> CodeStubAssembler::LoadContextElement( SloppyTNode<Context> context, SloppyTNode<IntPtrT> slot_index) { - TNode<IntPtrT> offset = ElementOffsetFromIndex( - slot_index, PACKED_ELEMENTS, INTPTR_PARAMETERS, Context::SlotOffset(0)); + TNode<IntPtrT> offset = ElementOffsetFromIndex(slot_index, PACKED_ELEMENTS, + Context::SlotOffset(0)); return UncheckedCast<Object>(Load(MachineType::AnyTagged(), context, offset)); } TNode<Object> CodeStubAssembler::LoadContextElement(TNode<Context> context, TNode<Smi> slot_index) { - TNode<IntPtrT> offset = ElementOffsetFromIndex( - slot_index, PACKED_ELEMENTS, SMI_PARAMETERS, Context::SlotOffset(0)); + TNode<IntPtrT> offset = ElementOffsetFromIndex(slot_index, PACKED_ELEMENTS, + Context::SlotOffset(0)); return UncheckedCast<Object>(Load(MachineType::AnyTagged(), context, offset)); } @@ -2949,33 +3019,30 @@ void CodeStubAssembler::StoreFixedDoubleArrayElement( StoreNoWriteBarrier(rep, object, offset, value_silenced); } -void CodeStubAssembler::StoreFeedbackVectorSlot(Node* object, - Node* slot_index_node, - Node* value, - WriteBarrierMode barrier_mode, - int additional_offset, - ParameterMode parameter_mode) { - CSA_SLOW_ASSERT(this, IsFeedbackVector(object)); - CSA_SLOW_ASSERT(this, MatchesParameterMode(slot_index_node, parameter_mode)); +void CodeStubAssembler::StoreFeedbackVectorSlot( + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<AnyTaggedT> value, WriteBarrierMode barrier_mode, + int additional_offset) { DCHECK(IsAligned(additional_offset, kTaggedSize)); DCHECK(barrier_mode == SKIP_WRITE_BARRIER || barrier_mode == UNSAFE_SKIP_WRITE_BARRIER || barrier_mode == UPDATE_WRITE_BARRIER); int header_size = FeedbackVector::kFeedbackSlotsOffset + additional_offset - kHeapObjectTag; - TNode<IntPtrT> offset = ElementOffsetFromIndex( - slot_index_node, HOLEY_ELEMENTS, parameter_mode, header_size); - // Check that slot_index_node <= object.length. + TNode<IntPtrT> offset = + ElementOffsetFromIndex(Signed(slot), HOLEY_ELEMENTS, header_size); + // Check that slot <= feedback_vector.length. CSA_ASSERT(this, - IsOffsetInBounds(offset, LoadFeedbackVectorLength(CAST(object)), + IsOffsetInBounds(offset, LoadFeedbackVectorLength(feedback_vector), FeedbackVector::kHeaderSize)); if (barrier_mode == SKIP_WRITE_BARRIER) { - StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, value); + StoreNoWriteBarrier(MachineRepresentation::kTagged, feedback_vector, offset, + value); } else if (barrier_mode == UNSAFE_SKIP_WRITE_BARRIER) { - UnsafeStoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, - value); + UnsafeStoreNoWriteBarrier(MachineRepresentation::kTagged, feedback_vector, + offset, value); } else { - Store(object, offset, value); + Store(feedback_vector, offset, value); } } @@ -3045,33 +3112,29 @@ TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Label success(this); TVARIABLE(Smi, var_tagged_length); ParameterMode mode = OptimalParameterMode(); - VARIABLE(var_length, OptimalParameterRepresentation(), - TaggedToParameter(LoadFastJSArrayLength(array), mode)); - VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); + TVARIABLE(BInt, var_length, SmiToBInt(LoadFastJSArrayLength(array))); + TVARIABLE(FixedArrayBase, var_elements, LoadElements(array)); // Resize the capacity of the fixed array if it doesn't fit. TNode<IntPtrT> first = arg_index->value(); - Node* growth = IntPtrToParameter( - IntPtrSub(UncheckedCast<IntPtrT>(args->GetLength(INTPTR_PARAMETERS)), - first), - mode); + TNode<BInt> growth = IntPtrToBInt(IntPtrSub(args->GetLength(), first)); PossiblyGrowElementsCapacity(mode, kind, array, var_length.value(), &var_elements, growth, &pre_bailout); // Push each argument onto the end of the array now that there is enough // capacity. CodeStubAssembler::VariableList push_vars({&var_length}, zone()); - Node* elements = var_elements.value(); + TNode<FixedArrayBase> elements = var_elements.value(); args->ForEach( push_vars, - [this, kind, mode, elements, &var_length, &pre_bailout](Node* arg) { + [&](TNode<Object> arg) { TryStoreArrayElement(kind, mode, &pre_bailout, elements, var_length.value(), arg); - Increment(&var_length, 1, mode); + Increment(&var_length); }, - first, nullptr); + first); { - TNode<Smi> length = ParameterToTagged(var_length.value(), mode); + TNode<Smi> length = BIntToSmi(var_length.value()); var_tagged_length = length; StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); Goto(&success); @@ -3111,8 +3174,7 @@ void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, CSA_SLOW_ASSERT(this, IsJSArray(array)); Comment("BuildAppendJSArray: ", ElementsKindToString(kind)); ParameterMode mode = OptimalParameterMode(); - VARIABLE(var_length, OptimalParameterRepresentation(), - TaggedToParameter(LoadFastJSArrayLength(array), mode)); + TVARIABLE(BInt, var_length, SmiToBInt(LoadFastJSArrayLength(array))); VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array)); // Resize the capacity of the fixed array if it doesn't fit. @@ -3124,9 +3186,9 @@ void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array, // capacity. TryStoreArrayElement(kind, mode, bailout, var_elements.value(), var_length.value(), value); - Increment(&var_length, 1, mode); + Increment(&var_length); - TNode<Smi> length = ParameterToTagged(var_length.value(), mode); + TNode<Smi> length = BIntToSmi(var_length.value()); StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); } @@ -3138,7 +3200,7 @@ Node* CodeStubAssembler::AllocateCellWithValue(Node* value, return result; } -Node* CodeStubAssembler::LoadCellValue(Node* cell) { +TNode<Object> CodeStubAssembler::LoadCellValue(Node* cell) { CSA_SLOW_ASSERT(this, HasInstanceType(cell, CELL_TYPE)); return LoadObjectField(cell, Cell::kValueOffset); } @@ -3278,7 +3340,8 @@ TNode<ByteArray> CodeStubAssembler::AllocateByteArray(TNode<UintPtrT> length, TNode<IntPtrT> raw_size = GetArrayAllocationSize(Signed(length), UINT8_ELEMENTS, INTPTR_PARAMETERS, ByteArray::kHeaderSize + kObjectAlignmentMask); - TNode<WordT> size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); + TNode<IntPtrT> size = + WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), &if_sizeissmall, &if_notsizeissmall); @@ -3352,7 +3415,8 @@ TNode<String> CodeStubAssembler::AllocateSeqOneByteString( TNode<IntPtrT> raw_size = GetArrayAllocationSize( Signed(ChangeUint32ToWord(length)), UINT8_ELEMENTS, INTPTR_PARAMETERS, SeqOneByteString::kHeaderSize + kObjectAlignmentMask); - TNode<WordT> size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); + TNode<IntPtrT> size = + WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), &if_sizeissmall, &if_notsizeissmall); @@ -3423,7 +3487,8 @@ TNode<String> CodeStubAssembler::AllocateSeqTwoByteString( TNode<IntPtrT> raw_size = GetArrayAllocationSize( Signed(ChangeUint32ToWord(length)), UINT16_ELEMENTS, INTPTR_PARAMETERS, SeqOneByteString::kHeaderSize + kObjectAlignmentMask); - TNode<WordT> size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); + TNode<IntPtrT> size = + WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), &if_sizeissmall, &if_notsizeissmall); @@ -3496,35 +3561,6 @@ TNode<String> CodeStubAssembler::AllocateSlicedTwoByteString( offset); } -TNode<String> CodeStubAssembler::AllocateConsString(TNode<Uint32T> length, - TNode<String> left, - TNode<String> right) { - // Added string can be a cons string. - Comment("Allocating ConsString"); - TNode<Int32T> left_instance_type = LoadInstanceType(left); - TNode<Int32T> right_instance_type = LoadInstanceType(right); - - // Determine the resulting ConsString map to use depending on whether - // any of {left} or {right} has two byte encoding. - STATIC_ASSERT(kOneByteStringTag != 0); - STATIC_ASSERT(kTwoByteStringTag == 0); - TNode<Int32T> combined_instance_type = - Word32And(left_instance_type, right_instance_type); - TNode<Map> result_map = CAST(Select<Object>( - IsSetWord32(combined_instance_type, kStringEncodingMask), - [=] { return ConsOneByteStringMapConstant(); }, - [=] { return ConsStringMapConstant(); })); - TNode<HeapObject> result = AllocateInNewSpace(ConsString::kSize); - StoreMapNoWriteBarrier(result, result_map); - StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, - MachineRepresentation::kWord32); - StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, - Int32Constant(String::kEmptyHashField), - MachineRepresentation::kWord32); - StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, left); - StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, right); - return CAST(result); -} TNode<NameDictionary> CodeStubAssembler::AllocateNameDictionary( int at_least_space_for) { @@ -3762,106 +3798,26 @@ template V8_EXPORT_PRIVATE TNode<SmallOrderedHashSet> CodeStubAssembler::AllocateSmallOrderedHashTable<SmallOrderedHashSet>( TNode<IntPtrT> capacity); -template <typename CollectionType> -void CodeStubAssembler::FindOrderedHashTableEntry( - Node* table, Node* hash, - const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, - Variable* entry_start_position, Label* entry_found, Label* not_found) { - // Get the index of the bucket. - TNode<IntPtrT> const number_of_buckets = - SmiUntag(CAST(UnsafeLoadFixedArrayElement( - CAST(table), CollectionType::NumberOfBucketsIndex()))); - TNode<WordT> const bucket = - WordAnd(hash, IntPtrSub(number_of_buckets, IntPtrConstant(1))); - TNode<IntPtrT> const first_entry = SmiUntag(CAST(UnsafeLoadFixedArrayElement( - CAST(table), bucket, - CollectionType::HashTableStartIndex() * kTaggedSize))); - - // Walk the bucket chain. - TNode<IntPtrT> entry_start; - Label if_key_found(this); - { - TVARIABLE(IntPtrT, var_entry, first_entry); - Label loop(this, {&var_entry, entry_start_position}), - continue_next_entry(this); - Goto(&loop); - BIND(&loop); - - // If the entry index is the not-found sentinel, we are done. - GotoIf(IntPtrEqual(var_entry.value(), - IntPtrConstant(CollectionType::kNotFound)), - not_found); - - // Make sure the entry index is within range. - CSA_ASSERT( - this, - UintPtrLessThan( - var_entry.value(), - SmiUntag(SmiAdd( - CAST(UnsafeLoadFixedArrayElement( - CAST(table), CollectionType::NumberOfElementsIndex())), - CAST(UnsafeLoadFixedArrayElement( - CAST(table), - CollectionType::NumberOfDeletedElementsIndex())))))); - - // Compute the index of the entry relative to kHashTableStartIndex. - entry_start = - IntPtrAdd(IntPtrMul(var_entry.value(), - IntPtrConstant(CollectionType::kEntrySize)), - number_of_buckets); - - // Load the key from the entry. - TNode<Object> const candidate_key = UnsafeLoadFixedArrayElement( - CAST(table), entry_start, - CollectionType::HashTableStartIndex() * kTaggedSize); - - key_compare(candidate_key, &if_key_found, &continue_next_entry); - - BIND(&continue_next_entry); - // Load the index of the next entry in the bucket chain. - var_entry = SmiUntag(CAST(UnsafeLoadFixedArrayElement( - CAST(table), entry_start, - (CollectionType::HashTableStartIndex() + CollectionType::kChainOffset) * - kTaggedSize))); - - Goto(&loop); - } - - BIND(&if_key_found); - entry_start_position->Bind(entry_start); - Goto(entry_found); -} - -template void CodeStubAssembler::FindOrderedHashTableEntry<OrderedHashMap>( - Node* table, Node* hash, - const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, - Variable* entry_start_position, Label* entry_found, Label* not_found); -template void CodeStubAssembler::FindOrderedHashTableEntry<OrderedHashSet>( - Node* table, Node* hash, - const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, - Variable* entry_start_position, Label* entry_found, Label* not_found); - Node* CodeStubAssembler::AllocateStruct(Node* map, AllocationFlags flags) { Comment("AllocateStruct"); CSA_ASSERT(this, IsMap(map)); TNode<IntPtrT> size = TimesTaggedSize(LoadMapInstanceSizeInWords(map)); TNode<HeapObject> object = Allocate(size, flags); StoreMapNoWriteBarrier(object, map); - InitializeStructBody(object, map, size, Struct::kHeaderSize); + InitializeStructBody(object, size, Struct::kHeaderSize); return object; } -void CodeStubAssembler::InitializeStructBody(Node* object, Node* map, - Node* size, int start_offset) { - CSA_SLOW_ASSERT(this, IsMap(map)); +void CodeStubAssembler::InitializeStructBody(TNode<HeapObject> object, + TNode<IntPtrT> size, + int start_offset) { Comment("InitializeStructBody"); TNode<Oddball> filler = UndefinedConstant(); // Calculate the untagged field addresses. - object = BitcastTaggedToWord(object); - TNode<WordT> start_address = - IntPtrAdd(object, IntPtrConstant(start_offset - kHeapObjectTag)); - TNode<WordT> end_address = - IntPtrSub(IntPtrAdd(object, size), IntPtrConstant(kHeapObjectTag)); + TNode<IntPtrT> start_address = + IntPtrAdd(BitcastTaggedToWord(object), + IntPtrConstant(start_offset - kHeapObjectTag)); + TNode<IntPtrT> end_address = IntPtrAdd(start_address, size); StoreFieldsNoWriteBarrier(start_address, end_address, filler); } @@ -3883,8 +3839,9 @@ TNode<JSObject> CodeStubAssembler::AllocateJSObjectFromMap( } void CodeStubAssembler::InitializeJSObjectFromMap( - Node* object, Node* map, Node* instance_size, Node* properties, - Node* elements, SlackTrackingMode slack_tracking_mode) { + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size, Node* properties, Node* elements, + SlackTrackingMode slack_tracking_mode) { CSA_SLOW_ASSERT(this, IsMap(map)); // This helper assumes that the object is in new-space, as guarded by the // check in AllocatedJSObjectFromMap. @@ -3915,7 +3872,8 @@ void CodeStubAssembler::InitializeJSObjectFromMap( } void CodeStubAssembler::InitializeJSObjectBodyNoSlackTracking( - Node* object, Node* map, Node* instance_size, int start_offset) { + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size, int start_offset) { STATIC_ASSERT(Map::kNoSlackTracking == 0); CSA_ASSERT( this, IsClearWord32<Map::ConstructionCounterBits>(LoadMapBitField3(map))); @@ -3924,8 +3882,8 @@ void CodeStubAssembler::InitializeJSObjectBodyNoSlackTracking( } void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking( - Node* object, Node* map, Node* instance_size) { - CSA_SLOW_ASSERT(this, IsMap(map)); + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size) { Comment("InitializeJSObjectBodyNoSlackTracking"); // Perform in-object slack tracking if requested. @@ -3953,9 +3911,9 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking( // The object still has in-object slack therefore the |unsed_or_unused| // field contain the "used" value. - TNode<UintPtrT> used_size = TimesTaggedSize(ChangeUint32ToWord( + TNode<IntPtrT> used_size = Signed(TimesTaggedSize(ChangeUint32ToWord( LoadObjectField(map, Map::kUsedOrUnusedInstanceSizeInWordsOffset, - MachineType::Uint8()))); + MachineType::Uint8())))); Comment("iInitialize filler fields"); InitializeFieldsWithRoot(object, used_size, instance_size, @@ -3984,19 +3942,19 @@ void CodeStubAssembler::InitializeJSObjectBodyWithSlackTracking( BIND(&end); } -void CodeStubAssembler::StoreFieldsNoWriteBarrier(Node* start_address, - Node* end_address, - Node* value) { +void CodeStubAssembler::StoreFieldsNoWriteBarrier(TNode<IntPtrT> start_address, + TNode<IntPtrT> end_address, + TNode<Object> value) { Comment("StoreFieldsNoWriteBarrier"); CSA_ASSERT(this, WordIsAligned(start_address, kTaggedSize)); CSA_ASSERT(this, WordIsAligned(end_address, kTaggedSize)); - BuildFastLoop( + BuildFastLoop<IntPtrT>( start_address, end_address, - [this, value](Node* current) { + [=](TNode<IntPtrT> current) { UnsafeStoreNoWriteBarrier(MachineRepresentation::kTagged, current, value); }, - kTaggedSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + kTaggedSize, IndexAdvanceMode::kPost); } TNode<BoolT> CodeStubAssembler::IsValidFastJSArrayCapacity( @@ -4008,12 +3966,12 @@ TNode<BoolT> CodeStubAssembler::IsValidFastJSArrayCapacity( TNode<JSArray> CodeStubAssembler::AllocateJSArray( TNode<Map> array_map, TNode<FixedArrayBase> elements, TNode<Smi> length, - Node* allocation_site, int array_header_size) { + TNode<AllocationSite> allocation_site, int array_header_size) { Comment("begin allocation of JSArray passing in elements"); CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); int base_size = array_header_size; - if (allocation_site != nullptr) { + if (!allocation_site.is_null()) { base_size += AllocationMemento::kSize; } @@ -4027,8 +3985,9 @@ TNode<JSArray> CodeStubAssembler::AllocateJSArray( std::pair<TNode<JSArray>, TNode<FixedArrayBase>> CodeStubAssembler::AllocateUninitializedJSArrayWithElements( ElementsKind kind, TNode<Map> array_map, TNode<Smi> length, - Node* allocation_site, Node* capacity, ParameterMode capacity_mode, - AllocationFlags allocation_flags, int array_header_size) { + TNode<AllocationSite> allocation_site, Node* capacity, + ParameterMode capacity_mode, AllocationFlags allocation_flags, + int array_header_size) { Comment("begin allocation of JSArray with elements"); CHECK_EQ(allocation_flags & ~kAllowLargeObjectAllocation, 0); CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); @@ -4065,7 +4024,9 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements( BIND(&nonempty); { int base_size = array_header_size; - if (allocation_site != nullptr) base_size += AllocationMemento::kSize; + if (!allocation_site.is_null()) { + base_size += AllocationMemento::kSize; + } const int elements_offset = base_size; @@ -4138,8 +4099,8 @@ CodeStubAssembler::AllocateUninitializedJSArrayWithElements( } TNode<JSArray> CodeStubAssembler::AllocateUninitializedJSArray( - TNode<Map> array_map, TNode<Smi> length, Node* allocation_site, - TNode<IntPtrT> size_in_bytes) { + TNode<Map> array_map, TNode<Smi> length, + TNode<AllocationSite> allocation_site, TNode<IntPtrT> size_in_bytes) { CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); // Allocate space for the JSArray and the elements FixedArray in one go. @@ -4150,7 +4111,7 @@ TNode<JSArray> CodeStubAssembler::AllocateUninitializedJSArray( StoreObjectFieldRoot(array, JSArray::kPropertiesOrHashOffset, RootIndex::kEmptyFixedArray); - if (allocation_site != nullptr) { + if (!allocation_site.is_null()) { InitializeAllocationMemento(array, IntPtrConstant(JSArray::kSize), allocation_site); } @@ -4160,7 +4121,7 @@ TNode<JSArray> CodeStubAssembler::AllocateUninitializedJSArray( TNode<JSArray> CodeStubAssembler::AllocateJSArray( ElementsKind kind, TNode<Map> array_map, Node* capacity, TNode<Smi> length, - Node* allocation_site, ParameterMode capacity_mode, + TNode<AllocationSite> allocation_site, ParameterMode capacity_mode, AllocationFlags allocation_flags) { CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity, capacity_mode)); @@ -4189,10 +4150,9 @@ TNode<JSArray> CodeStubAssembler::AllocateJSArray( return array; } -Node* CodeStubAssembler::ExtractFastJSArray(Node* context, Node* array, - Node* begin, Node* count, - ParameterMode mode, Node* capacity, - Node* allocation_site) { +Node* CodeStubAssembler::ExtractFastJSArray( + TNode<Context> context, TNode<JSArray> array, Node* begin, Node* count, + ParameterMode mode, Node* capacity, TNode<AllocationSite> allocation_site) { TNode<Map> original_array_map = LoadMap(array); TNode<Int32T> elements_kind = LoadMapElementsKind(original_array_map); @@ -4209,18 +4169,16 @@ Node* CodeStubAssembler::ExtractFastJSArray(Node* context, Node* array, return result; } -Node* CodeStubAssembler::CloneFastJSArray(Node* context, Node* array, - ParameterMode mode, - Node* allocation_site, - HoleConversionMode convert_holes) { +TNode<JSArray> CodeStubAssembler::CloneFastJSArray( + TNode<Context> context, TNode<JSArray> array, ParameterMode mode, + TNode<AllocationSite> allocation_site, HoleConversionMode convert_holes) { // TODO(dhai): we should be able to assert IsFastJSArray(array) here, but this // function is also used to copy boilerplates even when the no-elements // protector is invalid. This function should be renamed to reflect its uses. - CSA_ASSERT(this, IsJSArray(array)); TNode<Number> length = LoadJSArrayLength(array); - Node* new_elements = nullptr; - VARIABLE(var_new_elements, MachineRepresentation::kTagged); + TNode<FixedArrayBase> new_elements; + TVARIABLE(FixedArrayBase, var_new_elements); TVARIABLE(Int32T, var_elements_kind, LoadMapElementsKind(LoadMap(array))); Label allocate_jsarray(this), holey_extract(this), @@ -4240,7 +4198,7 @@ Node* CodeStubAssembler::CloneFastJSArray(Node* context, Node* array, TaggedToParameter(CAST(length), mode), nullptr, ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW, mode, nullptr, var_elements_kind.value()); - var_new_elements.Bind(new_elements); + var_new_elements = new_elements; Goto(&allocate_jsarray); if (need_conversion) { @@ -4257,7 +4215,7 @@ Node* CodeStubAssembler::CloneFastJSArray(Node* context, Node* array, LoadElements(array), IntPtrOrSmiConstant(0, mode), TaggedToParameter(CAST(length), mode), nullptr, ExtractFixedArrayFlag::kAllFixedArrays, mode, &var_holes_converted); - var_new_elements.Bind(new_elements); + var_new_elements = new_elements; // If the array type didn't change, use the original elements kind. GotoIfNot(var_holes_converted.value(), &allocate_jsarray); // Otherwise use PACKED_ELEMENTS for the target's elements kind. @@ -4283,8 +4241,8 @@ Node* CodeStubAssembler::CloneFastJSArray(Node* context, Node* array, TNode<Map> array_map = LoadJSArrayElementsMap(var_elements_kind.value(), native_context); - TNode<JSArray> result = AllocateJSArray( - array_map, CAST(var_new_elements.value()), CAST(length), allocation_site); + TNode<JSArray> result = AllocateJSArray(array_map, var_new_elements.value(), + CAST(length), allocation_site); return result; } @@ -4555,14 +4513,14 @@ TNode<FixedArrayBase> CodeStubAssembler::ExtractFixedDoubleArrayFillingHoles( const int first_element_offset = FixedArray::kHeaderSize - kHeapObjectTag; TNode<IntPtrT> first_from_element_offset = ElementOffsetFromIndex(first, kind, mode, 0); - TNode<WordT> limit_offset = IntPtrAdd(first_from_element_offset, - IntPtrConstant(first_element_offset)); + TNode<IntPtrT> limit_offset = IntPtrAdd(first_from_element_offset, + IntPtrConstant(first_element_offset)); TVARIABLE(IntPtrT, var_from_offset, ElementOffsetFromIndex(IntPtrOrSmiAdd(first, count, mode), kind, mode, first_element_offset)); Label decrement(this, {&var_from_offset}), done(this); - TNode<WordT> to_array_adjusted = + TNode<IntPtrT> to_array_adjusted = IntPtrSub(BitcastTaggedToWord(to_elements), first_from_element_offset); Branch(WordEqual(var_from_offset.value(), limit_offset), &done, &decrement); @@ -4908,12 +4866,10 @@ void CodeStubAssembler::MoveElements(ElementsKind kind, TNode<IntPtrT> elements_intptr = BitcastTaggedToWord(elements); TNode<IntPtrT> target_data_ptr = IntPtrAdd(elements_intptr, - ElementOffsetFromIndex(dst_index, kind, INTPTR_PARAMETERS, - fa_base_data_offset)); + ElementOffsetFromIndex(dst_index, kind, fa_base_data_offset)); TNode<IntPtrT> source_data_ptr = IntPtrAdd(elements_intptr, - ElementOffsetFromIndex(src_index, kind, INTPTR_PARAMETERS, - fa_base_data_offset)); + ElementOffsetFromIndex(src_index, kind, fa_base_data_offset)); TNode<ExternalReference> memmove = ExternalConstant(ExternalReference::libc_memmove_function()); CallCFunction(memmove, MachineType::Pointer(), @@ -4997,10 +4953,10 @@ void CodeStubAssembler::CopyElements(ElementsKind kind, IntPtrMul(length, IntPtrConstant(ElementsKindToByteSize(kind))); static const int32_t fa_base_data_offset = FixedArrayBase::kHeaderSize - kHeapObjectTag; - TNode<IntPtrT> src_offset_start = ElementOffsetFromIndex( - src_index, kind, INTPTR_PARAMETERS, fa_base_data_offset); - TNode<IntPtrT> dst_offset_start = ElementOffsetFromIndex( - dst_index, kind, INTPTR_PARAMETERS, fa_base_data_offset); + TNode<IntPtrT> src_offset_start = + ElementOffsetFromIndex(src_index, kind, fa_base_data_offset); + TNode<IntPtrT> dst_offset_start = + ElementOffsetFromIndex(dst_index, kind, fa_base_data_offset); TNode<IntPtrT> src_elements_intptr = BitcastTaggedToWord(src_elements); TNode<IntPtrT> source_data_ptr = IntPtrAdd(src_elements_intptr, src_offset_start); @@ -5283,65 +5239,6 @@ void CodeStubAssembler::CopyPropertyArrayValues(Node* from_array, Comment("] CopyPropertyArrayValues"); } -void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string, - TNode<IntPtrT> from_index, - TNode<IntPtrT> to_index, - TNode<IntPtrT> character_count, - String::Encoding from_encoding, - String::Encoding to_encoding) { - // Cannot assert IsString(from_string) and IsString(to_string) here because - // CSA::SubString can pass in faked sequential strings when handling external - // subject strings. - bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING; - bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING; - DCHECK_IMPLIES(to_one_byte, from_one_byte); - Comment("CopyStringCharacters ", - from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", " -> ", - to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING"); - - ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; - ElementsKind to_kind = to_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; - STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); - int header_size = SeqOneByteString::kHeaderSize - kHeapObjectTag; - TNode<IntPtrT> from_offset = ElementOffsetFromIndex( - from_index, from_kind, INTPTR_PARAMETERS, header_size); - TNode<IntPtrT> to_offset = - ElementOffsetFromIndex(to_index, to_kind, INTPTR_PARAMETERS, header_size); - TNode<IntPtrT> byte_count = - ElementOffsetFromIndex(character_count, from_kind, INTPTR_PARAMETERS); - TNode<WordT> limit_offset = IntPtrAdd(from_offset, byte_count); - - // Prepare the fast loop - MachineType type = - from_one_byte ? MachineType::Uint8() : MachineType::Uint16(); - MachineRepresentation rep = to_one_byte ? MachineRepresentation::kWord8 - : MachineRepresentation::kWord16; - int from_increment = 1 << ElementsKindToShiftSize(from_kind); - int to_increment = 1 << ElementsKindToShiftSize(to_kind); - - VARIABLE(current_to_offset, MachineType::PointerRepresentation(), to_offset); - VariableList vars({¤t_to_offset}, zone()); - int to_index_constant = 0, from_index_constant = 0; - bool index_same = (from_encoding == to_encoding) && - (from_index == to_index || - (ToInt32Constant(from_index, &from_index_constant) && - ToInt32Constant(to_index, &to_index_constant) && - from_index_constant == to_index_constant)); - BuildFastLoop( - vars, from_offset, limit_offset, - [this, from_string, to_string, ¤t_to_offset, to_increment, type, - rep, index_same](Node* offset) { - Node* value = Load(type, from_string, offset); - StoreNoWriteBarrier(rep, to_string, - index_same ? offset : current_to_offset.value(), - value); - if (!index_same) { - Increment(¤t_to_offset, to_increment); - } - }, - from_increment, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); -} - Node* CodeStubAssembler::LoadElementAndPrepareForStore(Node* array, Node* offset, ElementsKind from_kind, @@ -5381,9 +5278,9 @@ Node* CodeStubAssembler::CalculateNewElementsCapacity(Node* old_capacity, return IntPtrOrSmiAdd(new_capacity, padding, mode); } -Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, - ElementsKind kind, Node* key, - Label* bailout) { +TNode<FixedArrayBase> CodeStubAssembler::TryGrowElementsCapacity( + Node* object, Node* elements, ElementsKind kind, Node* key, + Label* bailout) { CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(elements, kind)); CSA_SLOW_ASSERT(this, TaggedIsSmi(key)); @@ -5395,11 +5292,9 @@ Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, TaggedToParameter(capacity, mode), mode, bailout); } -Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, - ElementsKind kind, Node* key, - Node* capacity, - ParameterMode mode, - Label* bailout) { +TNode<FixedArrayBase> CodeStubAssembler::TryGrowElementsCapacity( + Node* object, Node* elements, ElementsKind kind, Node* key, Node* capacity, + ParameterMode mode, Label* bailout) { Comment("TryGrowElementsCapacity"); CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); CSA_SLOW_ASSERT(this, IsFixedArrayWithKindOrEmpty(elements, kind)); @@ -5418,7 +5313,7 @@ Node* CodeStubAssembler::TryGrowElementsCapacity(Node* object, Node* elements, new_capacity, mode, bailout); } -Node* CodeStubAssembler::GrowElementsCapacity( +TNode<FixedArrayBase> CodeStubAssembler::GrowElementsCapacity( Node* object, Node* elements, ElementsKind from_kind, ElementsKind to_kind, Node* capacity, Node* new_capacity, ParameterMode mode, Label* bailout) { Comment("[ GrowElementsCapacity"); @@ -5471,45 +5366,22 @@ void CodeStubAssembler::InitializeAllocationMemento(Node* base, Comment("]"); } -Node* CodeStubAssembler::TryTaggedToFloat64(Node* value, - Label* if_valueisnotnumber) { - Label out(this); - VARIABLE(var_result, MachineRepresentation::kFloat64); - - // Check if the {value} is a Smi or a HeapObject. - Label if_valueissmi(this), if_valueisnotsmi(this); - Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi); - - BIND(&if_valueissmi); - { - // Convert the Smi {value}. - var_result.Bind(SmiToFloat64(value)); - Goto(&out); - } - - BIND(&if_valueisnotsmi); - { - // Check if {value} is a HeapNumber. - Label if_valueisheapnumber(this); - Branch(IsHeapNumber(value), &if_valueisheapnumber, if_valueisnotnumber); - - BIND(&if_valueisheapnumber); - { - // Load the floating point value. - var_result.Bind(LoadHeapNumberValue(value)); - Goto(&out); - } - } - BIND(&out); - return var_result.value(); +TNode<Float64T> CodeStubAssembler::TryTaggedToFloat64( + TNode<Object> value, Label* if_valueisnotnumber) { + return Select<Float64T>( + TaggedIsSmi(value), [&]() { return SmiToFloat64(CAST(value)); }, + [&]() { + GotoIfNot(IsHeapNumber(CAST(value)), if_valueisnotnumber); + return LoadHeapNumberValue(CAST(value)); + }); } -Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { +TNode<Float64T> CodeStubAssembler::TruncateTaggedToFloat64( + SloppyTNode<Context> context, SloppyTNode<Object> value) { // We might need to loop once due to ToNumber conversion. - VARIABLE(var_value, MachineRepresentation::kTagged); - VARIABLE(var_result, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_value, value); + TVARIABLE(Float64T, var_result); Label loop(this, &var_value), done_loop(this, &var_result); - var_value.Bind(value); Goto(&loop); BIND(&loop); { @@ -5520,14 +5392,13 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { // Convert {value} to Float64 if it is a number and convert it to a number // otherwise. - Node* const result = TryTaggedToFloat64(value, &if_valueisnotnumber); - var_result.Bind(result); + var_result = TryTaggedToFloat64(value, &if_valueisnotnumber); Goto(&done_loop); BIND(&if_valueisnotnumber); { // Convert the {value} to a Number first. - var_value.Bind(CallBuiltin(Builtins::kNonNumberToNumber, context, value)); + var_value = CallBuiltin(Builtins::kNonNumberToNumber, context, value); Goto(&loop); } } @@ -5535,8 +5406,9 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) { return var_result.value(); } -Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { - VARIABLE(var_result, MachineRepresentation::kWord32); +TNode<Word32T> CodeStubAssembler::TruncateTaggedToWord32( + SloppyTNode<Context> context, SloppyTNode<Object> value) { + TVARIABLE(Word32T, var_result); Label done(this); TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumber>(context, value, &done, &var_result); @@ -5546,38 +5418,33 @@ Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) { // Truncate {value} to word32 and jump to {if_number} if it is a Number, // or find that it is a BigInt and jump to {if_bigint}. -void CodeStubAssembler::TaggedToWord32OrBigInt(Node* context, Node* value, - Label* if_number, - Variable* var_word32, - Label* if_bigint, - Variable* var_bigint) { +void CodeStubAssembler::TaggedToWord32OrBigInt( + TNode<Context> context, TNode<Object> value, Label* if_number, + TVariable<Word32T>* var_word32, Label* if_bigint, + TVariable<Object>* var_maybe_bigint) { TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>( - context, value, if_number, var_word32, if_bigint, var_bigint); + context, value, if_number, var_word32, if_bigint, var_maybe_bigint); } // Truncate {value} to word32 and jump to {if_number} if it is a Number, // or find that it is a BigInt and jump to {if_bigint}. In either case, // store the type feedback in {var_feedback}. void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback( - Node* context, Node* value, Label* if_number, Variable* var_word32, - Label* if_bigint, Variable* var_bigint, Variable* var_feedback) { + TNode<Context> context, TNode<Object> value, Label* if_number, + TVariable<Word32T>* var_word32, Label* if_bigint, + TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) { TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>( - context, value, if_number, var_word32, if_bigint, var_bigint, + context, value, if_number, var_word32, if_bigint, var_maybe_bigint, var_feedback); } template <Object::Conversion conversion> void CodeStubAssembler::TaggedToWord32OrBigIntImpl( - Node* context, Node* value, Label* if_number, Variable* var_word32, - Label* if_bigint, Variable* var_bigint, Variable* var_feedback) { - DCHECK(var_word32->rep() == MachineRepresentation::kWord32); - DCHECK(var_bigint == nullptr || - var_bigint->rep() == MachineRepresentation::kTagged); - DCHECK(var_feedback == nullptr || - var_feedback->rep() == MachineRepresentation::kTaggedSigned); - + TNode<Context> context, TNode<Object> value, Label* if_number, + TVariable<Word32T>* var_word32, Label* if_bigint, + TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) { // We might need to loop after conversion. - VARIABLE(var_value, MachineRepresentation::kTagged, value); + TVARIABLE(Object, var_value, value); OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNone); Variable* loop_vars[] = {&var_value, var_feedback}; int num_vars = @@ -5592,12 +5459,13 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl( GotoIf(TaggedIsNotSmi(value), ¬_smi); // {value} is a Smi. - var_word32->Bind(SmiToInt32(value)); + *var_word32 = SmiToInt32(CAST(value)); CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall); Goto(if_number); BIND(¬_smi); - TNode<Map> map = LoadMap(value); + TNode<HeapObject> value_heap_object = CAST(value); + TNode<Map> map = LoadMap(value_heap_object); GotoIf(IsHeapNumberMap(map), &is_heap_number); TNode<Uint16T> instance_type = LoadMapInstanceType(map); if (conversion == Object::Conversion::kToNumeric) { @@ -5610,7 +5478,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl( // We do not require an Or with earlier feedback here because once we // convert the value to a Numeric, we cannot reach this path. We can // only reach this path on the first pass when the feedback is kNone. - CSA_ASSERT(this, SmiEqual(CAST(var_feedback->value()), + CSA_ASSERT(this, SmiEqual(var_feedback->value(), SmiConstant(BinaryOperationFeedback::kNone))); } GotoIf(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &is_oddball); @@ -5618,25 +5486,25 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl( auto builtin = conversion == Object::Conversion::kToNumeric ? Builtins::kNonNumberToNumeric : Builtins::kNonNumberToNumber; - var_value.Bind(CallBuiltin(builtin, context, value)); + var_value = CallBuiltin(builtin, context, value); OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny); Goto(&loop); BIND(&is_oddball); - var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); + var_value = LoadObjectField(value_heap_object, Oddball::kToNumberOffset); OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumberOrOddball); Goto(&loop); } BIND(&is_heap_number); - var_word32->Bind(TruncateHeapNumberValueToWord32(CAST(value))); + *var_word32 = TruncateHeapNumberValueToWord32(CAST(value)); CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber); Goto(if_number); if (conversion == Object::Conversion::kToNumeric) { BIND(&is_bigint); - var_bigint->Bind(value); + *var_maybe_bigint = value; CombineFeedback(var_feedback, BinaryOperationFeedback::kBigInt); Goto(if_bigint); } @@ -5650,14 +5518,14 @@ TNode<Int32T> CodeStubAssembler::TruncateHeapNumberValueToWord32( } void CodeStubAssembler::TryHeapNumberToSmi(TNode<HeapNumber> number, - TVariable<Smi>& var_result_smi, + TVariable<Smi>* var_result_smi, Label* if_smi) { TNode<Float64T> value = LoadHeapNumberValue(number); TryFloat64ToSmi(value, var_result_smi, if_smi); } void CodeStubAssembler::TryFloat64ToSmi(TNode<Float64T> value, - TVariable<Smi>& var_result_smi, + TVariable<Smi>* var_result_smi, Label* if_smi) { TNode<Int32T> value32 = RoundFloat64ToInt32(value); TNode<Float64T> value64 = ChangeInt32ToFloat64(value32); @@ -5674,13 +5542,13 @@ void CodeStubAssembler::TryFloat64ToSmi(TNode<Float64T> value, BIND(&if_int32); { if (SmiValuesAre32Bits()) { - var_result_smi = SmiTag(ChangeInt32ToIntPtr(value32)); + *var_result_smi = SmiTag(ChangeInt32ToIntPtr(value32)); } else { DCHECK(SmiValuesAre31Bits()); TNode<PairT<Int32T, BoolT>> pair = Int32AddWithOverflow(value32, value32); TNode<BoolT> overflow = Projection<1>(pair); GotoIf(overflow, &if_heap_number); - var_result_smi = + *var_result_smi = BitcastWordToTaggedSigned(ChangeInt32ToIntPtr(Projection<0>(pair))); } Goto(if_smi); @@ -5693,7 +5561,7 @@ TNode<Number> CodeStubAssembler::ChangeFloat64ToTagged( Label if_smi(this), done(this); TVARIABLE(Smi, var_smi_result); TVARIABLE(Number, var_result); - TryFloat64ToSmi(value, var_smi_result, &if_smi); + TryFloat64ToSmi(value, &var_smi_result, &if_smi); var_result = AllocateHeapNumberWithValue(value); Goto(&done); @@ -6144,42 +6012,42 @@ TNode<BoolT> CodeStubAssembler::IsUndetectableMap(SloppyTNode<Map> map) { } TNode<BoolT> CodeStubAssembler::IsNoElementsProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = NoElementsProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsArrayIteratorProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = ArrayIteratorProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsPromiseResolveProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); - TNode<Cell> cell = PromiseResolveProtectorConstant(); - TNode<Object> cell_value = LoadObjectField(cell, Cell::kValueOffset); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); + TNode<PropertyCell> cell = PromiseResolveProtectorConstant(); + TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsPromiseThenProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = PromiseThenProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsArraySpeciesProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = ArraySpeciesProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsTypedArraySpeciesProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = TypedArraySpeciesProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); @@ -6190,12 +6058,12 @@ TNode<BoolT> CodeStubAssembler::IsRegExpSpeciesProtectorCellInvalid( TNode<PropertyCell> cell = CAST(LoadContextElement( native_context, Context::REGEXP_SPECIES_PROTECTOR_INDEX)); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); return TaggedEqual(cell_value, invalid); } TNode<BoolT> CodeStubAssembler::IsPromiseSpeciesProtectorCellInvalid() { - TNode<Smi> invalid = SmiConstant(Isolate::kProtectorInvalid); + TNode<Smi> invalid = SmiConstant(Protectors::kProtectorInvalid); TNode<PropertyCell> cell = PromiseSpeciesProtectorConstant(); TNode<Object> cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); return TaggedEqual(cell_value, invalid); @@ -6394,6 +6262,10 @@ TNode<BoolT> CodeStubAssembler::IsJSGlobalProxy( return IsJSGlobalProxyMap(LoadMap(object)); } +TNode<BoolT> CodeStubAssembler::IsJSGeneratorMap(TNode<Map> map) { + return InstanceTypeEqual(LoadMapInstanceType(map), JS_GENERATOR_OBJECT_TYPE); +} + TNode<BoolT> CodeStubAssembler::IsJSObjectInstanceType( SloppyTNode<Int32T> instance_type) { STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); @@ -6428,6 +6300,11 @@ TNode<BoolT> CodeStubAssembler::IsJSStringIterator( return HasInstanceType(object, JS_STRING_ITERATOR_TYPE); } +TNode<BoolT> CodeStubAssembler::IsJSRegExpStringIterator( + SloppyTNode<HeapObject> object) { + return HasInstanceType(object, JS_REG_EXP_STRING_ITERATOR_TYPE); +} + TNode<BoolT> CodeStubAssembler::IsMap(SloppyTNode<HeapObject> map) { return IsMetaMap(LoadMap(map)); } @@ -6656,7 +6533,7 @@ TNode<BoolT> CodeStubAssembler::IsBigInt(SloppyTNode<HeapObject> object) { TNode<BoolT> CodeStubAssembler::IsPrimitiveInstanceType( SloppyTNode<Int32T> instance_type) { return Int32LessThanOrEqual(instance_type, - Int32Constant(LAST_PRIMITIVE_TYPE)); + Int32Constant(LAST_PRIMITIVE_HEAP_OBJECT_TYPE)); } TNode<BoolT> CodeStubAssembler::IsPrivateSymbol( @@ -6716,8 +6593,7 @@ TNode<BoolT> CodeStubAssembler::IsNumberDictionary( return HasInstanceType(object, NUMBER_DICTIONARY_TYPE); } -TNode<BoolT> CodeStubAssembler::IsJSGeneratorObject( - SloppyTNode<HeapObject> object) { +TNode<BoolT> CodeStubAssembler::IsJSGeneratorObject(TNode<HeapObject> object) { return HasInstanceType(object, JS_GENERATOR_OBJECT_TYPE); } @@ -6762,7 +6638,7 @@ TNode<BoolT> CodeStubAssembler::IsJSDataView(TNode<HeapObject> object) { } TNode<BoolT> CodeStubAssembler::IsJSRegExp(SloppyTNode<HeapObject> object) { - return HasInstanceType(object, JS_REGEXP_TYPE); + return HasInstanceType(object, JS_REG_EXP_TYPE); } TNode<BoolT> CodeStubAssembler::IsNumber(SloppyTNode<Object> object) { @@ -7011,201 +6887,17 @@ TNode<String> CodeStubAssembler::StringFromSingleCharCode(TNode<Int32T> code) { return CAST(var_result.value()); } -// A wrapper around CopyStringCharacters which determines the correct string -// encoding, allocates a corresponding sequential string, and then copies the -// given character range using CopyStringCharacters. -// |from_string| must be a sequential string. -// 0 <= |from_index| <= |from_index| + |character_count| < from_string.length. -TNode<String> CodeStubAssembler::AllocAndCopyStringCharacters( - Node* from, Node* from_instance_type, TNode<IntPtrT> from_index, - TNode<IntPtrT> character_count) { - Label end(this), one_byte_sequential(this), two_byte_sequential(this); - TVARIABLE(String, var_result); - - Branch(IsOneByteStringInstanceType(from_instance_type), &one_byte_sequential, - &two_byte_sequential); - - // The subject string is a sequential one-byte string. - BIND(&one_byte_sequential); - { - TNode<String> result = AllocateSeqOneByteString( - Unsigned(TruncateIntPtrToInt32(character_count))); - CopyStringCharacters(from, result, from_index, IntPtrConstant(0), - character_count, String::ONE_BYTE_ENCODING, - String::ONE_BYTE_ENCODING); - var_result = result; - Goto(&end); - } - - // The subject string is a sequential two-byte string. - BIND(&two_byte_sequential); - { - TNode<String> result = AllocateSeqTwoByteString( - Unsigned(TruncateIntPtrToInt32(character_count))); - CopyStringCharacters(from, result, from_index, IntPtrConstant(0), - character_count, String::TWO_BYTE_ENCODING, - String::TWO_BYTE_ENCODING); - var_result = result; - Goto(&end); - } - - BIND(&end); - return var_result.value(); -} - -TNode<String> CodeStubAssembler::SubString(TNode<String> string, - TNode<IntPtrT> from, - TNode<IntPtrT> to) { - TVARIABLE(String, var_result); - ToDirectStringAssembler to_direct(state(), string); - Label end(this), runtime(this); - - TNode<IntPtrT> const substr_length = IntPtrSub(to, from); - TNode<IntPtrT> const string_length = LoadStringLengthAsWord(string); - - // Begin dispatching based on substring length. - - Label original_string_or_invalid_length(this); - GotoIf(UintPtrGreaterThanOrEqual(substr_length, string_length), - &original_string_or_invalid_length); - - // A real substring (substr_length < string_length). - Label empty(this); - GotoIf(IntPtrEqual(substr_length, IntPtrConstant(0)), &empty); - - Label single_char(this); - GotoIf(IntPtrEqual(substr_length, IntPtrConstant(1)), &single_char); - - // Deal with different string types: update the index if necessary - // and extract the underlying string. - - TNode<String> direct_string = to_direct.TryToDirect(&runtime); - TNode<IntPtrT> offset = IntPtrAdd(from, to_direct.offset()); - TNode<Int32T> const instance_type = to_direct.instance_type(); - - // The subject string can only be external or sequential string of either - // encoding at this point. - Label external_string(this); - { - if (FLAG_string_slices) { - Label next(this); - - // Short slice. Copy instead of slicing. - GotoIf(IntPtrLessThan(substr_length, - IntPtrConstant(SlicedString::kMinLength)), - &next); - - // Allocate new sliced string. - - Counters* counters = isolate()->counters(); - IncrementCounter(counters->sub_string_native(), 1); - - Label one_byte_slice(this), two_byte_slice(this); - Branch(IsOneByteStringInstanceType(to_direct.instance_type()), - &one_byte_slice, &two_byte_slice); - - BIND(&one_byte_slice); - { - var_result = AllocateSlicedOneByteString( - Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string, - SmiTag(offset)); - Goto(&end); - } - - BIND(&two_byte_slice); - { - var_result = AllocateSlicedTwoByteString( - Unsigned(TruncateIntPtrToInt32(substr_length)), direct_string, - SmiTag(offset)); - Goto(&end); - } - - BIND(&next); - } - - // The subject string can only be external or sequential string of either - // encoding at this point. - GotoIf(to_direct.is_external(), &external_string); - - var_result = AllocAndCopyStringCharacters(direct_string, instance_type, - offset, substr_length); - - Counters* counters = isolate()->counters(); - IncrementCounter(counters->sub_string_native(), 1); - - Goto(&end); - } - - // Handle external string. - BIND(&external_string); - { - TNode<RawPtrT> const fake_sequential_string = - to_direct.PointerToString(&runtime); - - var_result = AllocAndCopyStringCharacters( - fake_sequential_string, instance_type, offset, substr_length); - - Counters* counters = isolate()->counters(); - IncrementCounter(counters->sub_string_native(), 1); - - Goto(&end); - } - - BIND(&empty); - { - var_result = EmptyStringConstant(); - Goto(&end); - } - - // Substrings of length 1 are generated through CharCodeAt and FromCharCode. - BIND(&single_char); - { - TNode<Int32T> char_code = StringCharCodeAt(string, from); - var_result = StringFromSingleCharCode(char_code); - Goto(&end); - } - - BIND(&original_string_or_invalid_length); - { - CSA_ASSERT(this, IntPtrEqual(substr_length, string_length)); - - // Equal length - check if {from, to} == {0, str.length}. - GotoIf(UintPtrGreaterThan(from, IntPtrConstant(0)), &runtime); - - // Return the original string (substr_length == string_length). - - Counters* counters = isolate()->counters(); - IncrementCounter(counters->sub_string_native(), 1); - - var_result = string; - Goto(&end); - } - - // Fall back to a runtime call. - BIND(&runtime); - { - var_result = - CAST(CallRuntime(Runtime::kStringSubstring, NoContextConstant(), string, - SmiTag(from), SmiTag(to))); - Goto(&end); - } - - BIND(&end); - return var_result.value(); -} - -ToDirectStringAssembler::ToDirectStringAssembler( - compiler::CodeAssemblerState* state, TNode<String> string, Flags flags) - : CodeStubAssembler(state), - var_string_(string, this), - var_instance_type_(LoadInstanceType(string), this), - var_offset_(IntPtrConstant(0), this), - var_is_external_(Int32Constant(0), this), - flags_(flags) {} +ToDirectStringAssembler::ToDirectStringAssembler( + compiler::CodeAssemblerState* state, TNode<String> string, Flags flags) + : CodeStubAssembler(state), + var_string_(string, this), + var_instance_type_(LoadInstanceType(string), this), + var_offset_(IntPtrConstant(0), this), + var_is_external_(Int32Constant(0), this), + flags_(flags) {} TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) { - VariableList vars({&var_string_, &var_offset_, &var_instance_type_}, zone()); - Label dispatch(this, vars); + Label dispatch(this, {&var_string_, &var_offset_, &var_instance_type_}); Label if_iscons(this); Label if_isexternal(this); Label if_issliced(this); @@ -7333,232 +7025,6 @@ TNode<RawPtrT> ToDirectStringAssembler::TryToSequential( return var_result.value(); } -void CodeStubAssembler::BranchIfCanDerefIndirectString( - TNode<String> string, TNode<Int32T> instance_type, Label* can_deref, - Label* cannot_deref) { - TNode<Int32T> representation = - Word32And(instance_type, Int32Constant(kStringRepresentationMask)); - GotoIf(Word32Equal(representation, Int32Constant(kThinStringTag)), can_deref); - GotoIf(Word32NotEqual(representation, Int32Constant(kConsStringTag)), - cannot_deref); - // Cons string. - TNode<String> rhs = - LoadObjectField<String>(string, ConsString::kSecondOffset); - GotoIf(IsEmptyString(rhs), can_deref); - Goto(cannot_deref); -} - -TNode<String> CodeStubAssembler::DerefIndirectString( - TNode<String> string, TNode<Int32T> instance_type, Label* cannot_deref) { - Label deref(this); - BranchIfCanDerefIndirectString(string, instance_type, &deref, cannot_deref); - BIND(&deref); - STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) == - static_cast<int>(ConsString::kFirstOffset)); - return LoadObjectField<String>(string, ThinString::kActualOffset); -} - -void CodeStubAssembler::DerefIndirectString(TVariable<String>* var_string, - TNode<Int32T> instance_type) { -#ifdef DEBUG - Label can_deref(this), cannot_deref(this); - BranchIfCanDerefIndirectString(var_string->value(), instance_type, &can_deref, - &cannot_deref); - BIND(&cannot_deref); - DebugBreak(); // Should be able to dereference string. - Goto(&can_deref); - BIND(&can_deref); -#endif // DEBUG - - STATIC_ASSERT(static_cast<int>(ThinString::kActualOffset) == - static_cast<int>(ConsString::kFirstOffset)); - *var_string = - LoadObjectField<String>(var_string->value(), ThinString::kActualOffset); -} - -void CodeStubAssembler::MaybeDerefIndirectString(TVariable<String>* var_string, - TNode<Int32T> instance_type, - Label* did_deref, - Label* cannot_deref) { - Label deref(this); - BranchIfCanDerefIndirectString(var_string->value(), instance_type, &deref, - cannot_deref); - - BIND(&deref); - { - DerefIndirectString(var_string, instance_type); - Goto(did_deref); - } -} - -void CodeStubAssembler::MaybeDerefIndirectStrings( - TVariable<String>* var_left, TNode<Int32T> left_instance_type, - TVariable<String>* var_right, TNode<Int32T> right_instance_type, - Label* did_something) { - Label did_nothing_left(this), did_something_left(this), - didnt_do_anything(this); - MaybeDerefIndirectString(var_left, left_instance_type, &did_something_left, - &did_nothing_left); - - BIND(&did_something_left); - { - MaybeDerefIndirectString(var_right, right_instance_type, did_something, - did_something); - } - - BIND(&did_nothing_left); - { - MaybeDerefIndirectString(var_right, right_instance_type, did_something, - &didnt_do_anything); - } - - BIND(&didnt_do_anything); - // Fall through if neither string was an indirect string. -} - -TNode<String> CodeStubAssembler::StringAdd(Node* context, TNode<String> left, - TNode<String> right) { - TVARIABLE(String, result); - Label check_right(this), runtime(this, Label::kDeferred), cons(this), - done(this, &result), done_native(this, &result); - Counters* counters = isolate()->counters(); - - TNode<Uint32T> left_length = LoadStringLengthAsWord32(left); - GotoIfNot(Word32Equal(left_length, Uint32Constant(0)), &check_right); - result = right; - Goto(&done_native); - - BIND(&check_right); - TNode<Uint32T> right_length = LoadStringLengthAsWord32(right); - GotoIfNot(Word32Equal(right_length, Uint32Constant(0)), &cons); - result = left; - Goto(&done_native); - - BIND(&cons); - { - TNode<Uint32T> new_length = Uint32Add(left_length, right_length); - - // If new length is greater than String::kMaxLength, goto runtime to - // throw. Note: we also need to invalidate the string length protector, so - // can't just throw here directly. - GotoIf(Uint32GreaterThan(new_length, Uint32Constant(String::kMaxLength)), - &runtime); - - TVARIABLE(String, var_left, left); - TVARIABLE(String, var_right, right); - Variable* input_vars[2] = {&var_left, &var_right}; - Label non_cons(this, 2, input_vars); - Label slow(this, Label::kDeferred); - GotoIf(Uint32LessThan(new_length, Uint32Constant(ConsString::kMinLength)), - &non_cons); - - result = - AllocateConsString(new_length, var_left.value(), var_right.value()); - Goto(&done_native); - - BIND(&non_cons); - - Comment("Full string concatenate"); - TNode<Int32T> left_instance_type = LoadInstanceType(var_left.value()); - TNode<Int32T> right_instance_type = LoadInstanceType(var_right.value()); - // Compute intersection and difference of instance types. - - TNode<Int32T> ored_instance_types = - Word32Or(left_instance_type, right_instance_type); - TNode<Word32T> xored_instance_types = - Word32Xor(left_instance_type, right_instance_type); - - // Check if both strings have the same encoding and both are sequential. - GotoIf(IsSetWord32(xored_instance_types, kStringEncodingMask), &runtime); - GotoIf(IsSetWord32(ored_instance_types, kStringRepresentationMask), &slow); - - TNode<IntPtrT> word_left_length = Signed(ChangeUint32ToWord(left_length)); - TNode<IntPtrT> word_right_length = Signed(ChangeUint32ToWord(right_length)); - - Label two_byte(this); - GotoIf(Word32Equal(Word32And(ored_instance_types, - Int32Constant(kStringEncodingMask)), - Int32Constant(kTwoByteStringTag)), - &two_byte); - // One-byte sequential string case - result = AllocateSeqOneByteString(new_length); - CopyStringCharacters(var_left.value(), result.value(), IntPtrConstant(0), - IntPtrConstant(0), word_left_length, - String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING); - CopyStringCharacters(var_right.value(), result.value(), IntPtrConstant(0), - word_left_length, word_right_length, - String::ONE_BYTE_ENCODING, String::ONE_BYTE_ENCODING); - Goto(&done_native); - - BIND(&two_byte); - { - // Two-byte sequential string case - result = AllocateSeqTwoByteString(new_length); - CopyStringCharacters(var_left.value(), result.value(), IntPtrConstant(0), - IntPtrConstant(0), word_left_length, - String::TWO_BYTE_ENCODING, - String::TWO_BYTE_ENCODING); - CopyStringCharacters(var_right.value(), result.value(), IntPtrConstant(0), - word_left_length, word_right_length, - String::TWO_BYTE_ENCODING, - String::TWO_BYTE_ENCODING); - Goto(&done_native); - } - - BIND(&slow); - { - // Try to unwrap indirect strings, restart the above attempt on success. - MaybeDerefIndirectStrings(&var_left, left_instance_type, &var_right, - right_instance_type, &non_cons); - Goto(&runtime); - } - } - BIND(&runtime); - { - result = CAST(CallRuntime(Runtime::kStringAdd, context, left, right)); - Goto(&done); - } - - BIND(&done_native); - { - IncrementCounter(counters->string_add_native(), 1); - Goto(&done); - } - - BIND(&done); - return result.value(); -} - -TNode<String> CodeStubAssembler::StringFromSingleUTF16EncodedCodePoint( - TNode<Int32T> codepoint) { - VARIABLE(var_result, MachineRepresentation::kTagged, EmptyStringConstant()); - - Label if_isword16(this), if_isword32(this), return_result(this); - - Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16, - &if_isword32); - - BIND(&if_isword16); - { - var_result.Bind(StringFromSingleCharCode(codepoint)); - Goto(&return_result); - } - - BIND(&if_isword32); - { - TNode<String> value = AllocateSeqTwoByteString(2); - StoreNoWriteBarrier( - MachineRepresentation::kWord32, value, - IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag), - codepoint); - var_result.Bind(value); - Goto(&return_result); - } - - BIND(&return_result); - return CAST(var_result.value()); -} - TNode<Number> CodeStubAssembler::StringToNumber(TNode<String> input) { Label runtime(this, Label::kDeferred); Label end(this); @@ -7585,22 +7051,22 @@ TNode<Number> CodeStubAssembler::StringToNumber(TNode<String> input) { return var_result.value(); } -TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) { +TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input, + Label* bailout) { TVARIABLE(String, result); TVARIABLE(Smi, smi_input); - Label runtime(this, Label::kDeferred), if_smi(this), if_heap_number(this), - done(this, &result); + Label if_smi(this), if_heap_number(this), done(this, &result); // Load the number string cache. TNode<FixedArray> number_string_cache = NumberStringCacheConstant(); // Make the hash mask from the length of the number string cache. It // contains two elements (number and string) for each cache entry. - // TODO(ishell): cleanup mask handling. - TNode<IntPtrT> mask = - BitcastTaggedSignedToWord(LoadFixedArrayBaseLength(number_string_cache)); - TNode<IntPtrT> one = IntPtrConstant(1); - mask = IntPtrSub(mask, one); + TNode<IntPtrT> number_string_cache_length = + LoadAndUntagFixedArrayBaseLength(number_string_cache); + TNode<Int32T> one = Int32Constant(1); + TNode<Word32T> mask = Int32Sub( + Word32Shr(TruncateWordToInt32(number_string_cache_length), one), one); GotoIfNot(TaggedIsSmi(input), &if_heap_number); smi_input = CAST(input); @@ -7611,36 +7077,35 @@ TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) { Comment("NumberToString - HeapNumber"); TNode<HeapNumber> heap_number_input = CAST(input); // Try normalizing the HeapNumber. - TryHeapNumberToSmi(heap_number_input, smi_input, &if_smi); + TryHeapNumberToSmi(heap_number_input, &smi_input, &if_smi); // Make a hash from the two 32-bit values of the double. TNode<Int32T> low = LoadObjectField<Int32T>(heap_number_input, HeapNumber::kValueOffset); TNode<Int32T> high = LoadObjectField<Int32T>( heap_number_input, HeapNumber::kValueOffset + kIntSize); - TNode<Word32T> hash = Word32Xor(low, high); - TNode<IntPtrT> word_hash = WordShl(ChangeInt32ToIntPtr(hash), one); - TNode<WordT> index = - WordAnd(word_hash, WordSar(mask, SmiShiftBitsConstant())); + TNode<Word32T> hash = Word32And(Word32Xor(low, high), mask); + TNode<IntPtrT> entry_index = + Signed(ChangeUint32ToWord(Int32Add(hash, hash))); // Cache entry's key must be a heap number TNode<Object> number_key = - UnsafeLoadFixedArrayElement(number_string_cache, index); - GotoIf(TaggedIsSmi(number_key), &runtime); + UnsafeLoadFixedArrayElement(number_string_cache, entry_index); + GotoIf(TaggedIsSmi(number_key), bailout); TNode<HeapObject> number_key_heap_object = CAST(number_key); - GotoIfNot(IsHeapNumber(number_key_heap_object), &runtime); + GotoIfNot(IsHeapNumber(number_key_heap_object), bailout); // Cache entry's key must match the heap number value we're looking for. TNode<Int32T> low_compare = LoadObjectField<Int32T>( number_key_heap_object, HeapNumber::kValueOffset); TNode<Int32T> high_compare = LoadObjectField<Int32T>( number_key_heap_object, HeapNumber::kValueOffset + kIntSize); - GotoIfNot(Word32Equal(low, low_compare), &runtime); - GotoIfNot(Word32Equal(high, high_compare), &runtime); + GotoIfNot(Word32Equal(low, low_compare), bailout); + GotoIfNot(Word32Equal(high, high_compare), bailout); // Heap number match, return value from cache entry. - result = CAST( - UnsafeLoadFixedArrayElement(number_string_cache, index, kTaggedSize)); + result = CAST(UnsafeLoadFixedArrayElement(number_string_cache, entry_index, + kTaggedSize)); Goto(&done); } @@ -7648,17 +7113,28 @@ TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) { { Comment("NumberToString - Smi"); // Load the smi key, make sure it matches the smi we're looking for. - TNode<Object> smi_index = BitcastWordToTagged(WordAnd( - WordShl(BitcastTaggedSignedToWord(smi_input.value()), one), mask)); + TNode<Word32T> hash = Word32And(SmiToInt32(smi_input.value()), mask); + TNode<IntPtrT> entry_index = + Signed(ChangeUint32ToWord(Int32Add(hash, hash))); TNode<Object> smi_key = UnsafeLoadFixedArrayElement( - number_string_cache, smi_index, 0, SMI_PARAMETERS); - GotoIf(TaggedNotEqual(smi_key, smi_input.value()), &runtime); + number_string_cache, entry_index, 0, INTPTR_PARAMETERS); + GotoIf(TaggedNotEqual(smi_key, smi_input.value()), bailout); // Smi match, return value from cache entry. - result = CAST(UnsafeLoadFixedArrayElement(number_string_cache, smi_index, - kTaggedSize, SMI_PARAMETERS)); + result = CAST(UnsafeLoadFixedArrayElement(number_string_cache, entry_index, + kTaggedSize, INTPTR_PARAMETERS)); Goto(&done); } + BIND(&done); + return result.value(); +} + +TNode<String> CodeStubAssembler::NumberToString(TNode<Number> input) { + TVARIABLE(String, result); + Label runtime(this, Label::kDeferred), done(this, &result); + + result = NumberToString(input, &runtime); + Goto(&done); BIND(&runtime); { @@ -8290,102 +7766,129 @@ void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { } } -void CodeStubAssembler::Increment(Variable* variable, int value, - ParameterMode mode) { - DCHECK_IMPLIES(mode == INTPTR_PARAMETERS, - variable->rep() == MachineType::PointerRepresentation()); - DCHECK_IMPLIES(mode == SMI_PARAMETERS, CanBeTaggedSigned(variable->rep())); - variable->Bind(IntPtrOrSmiAdd(variable->value(), - IntPtrOrSmiConstant(value, mode), mode)); +template <typename TIndex> +void CodeStubAssembler::Increment(TVariable<TIndex>* variable, int value) { + *variable = + IntPtrOrSmiAdd(variable->value(), IntPtrOrSmiConstant<TIndex>(value)); } +// Instantiate Increment for Smi and IntPtrT. +// TODO(v8:9708): Consider renaming to [Smi|IntPtrT|RawPtrT]Increment. +template void CodeStubAssembler::Increment<Smi>(TVariable<Smi>* variable, + int value); +template void CodeStubAssembler::Increment<IntPtrT>( + TVariable<IntPtrT>* variable, int value); +template void CodeStubAssembler::Increment<RawPtrT>( + TVariable<RawPtrT>* variable, int value); + void CodeStubAssembler::Use(Label* label) { GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); } -void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, - Variable* var_index, Label* if_keyisunique, - Variable* var_unique, Label* if_bailout, +void CodeStubAssembler::TryToName(SloppyTNode<Object> key, Label* if_keyisindex, + TVariable<IntPtrT>* var_index, + Label* if_keyisunique, + TVariable<Name>* var_unique, + Label* if_bailout, Label* if_notinternalized) { - DCHECK_EQ(MachineType::PointerRepresentation(), var_index->rep()); - DCHECK_EQ(MachineRepresentation::kTagged, var_unique->rep()); Comment("TryToName"); - Label if_hascachedindex(this), if_keyisnotindex(this), if_thinstring(this), - if_keyisother(this, Label::kDeferred); + Label if_keyisnotindex(this); // Handle Smi and HeapNumber keys. - var_index->Bind(TryToIntptr(key, &if_keyisnotindex)); + *var_index = TryToIntptr(key, &if_keyisnotindex); Goto(if_keyisindex); BIND(&if_keyisnotindex); - TNode<Map> key_map = LoadMap(key); - var_unique->Bind(key); - // Symbols are unique. - GotoIf(IsSymbolMap(key_map), if_keyisunique); - TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map); - // Miss if |key| is not a String. - STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); - GotoIfNot(IsStringInstanceType(key_instance_type), &if_keyisother); - - // |key| is a String. Check if it has a cached array index. - TNode<Uint32T> hash = LoadNameHashField(key); - GotoIf(IsClearWord32(hash, Name::kDoesNotContainCachedArrayIndexMask), - &if_hascachedindex); - // No cached array index. If the string knows that it contains an index, - // then it must be an uncacheable index. Handle this case in the runtime. - GotoIf(IsClearWord32(hash, Name::kIsNotArrayIndexMask), if_bailout); - // Check if we have a ThinString. - GotoIf(InstanceTypeEqual(key_instance_type, THIN_STRING_TYPE), - &if_thinstring); - GotoIf(InstanceTypeEqual(key_instance_type, THIN_ONE_BYTE_STRING_TYPE), - &if_thinstring); - // Finally, check if |key| is internalized. - STATIC_ASSERT(kNotInternalizedTag != 0); - GotoIf(IsSetWord32(key_instance_type, kIsNotInternalizedMask), - if_notinternalized != nullptr ? if_notinternalized : if_bailout); - Goto(if_keyisunique); + { + Label if_symbol(this), if_string(this), + if_keyisother(this, Label::kDeferred); + TNode<HeapObject> key_heap_object = CAST(key); + TNode<Map> key_map = LoadMap(key_heap_object); - BIND(&if_thinstring); - var_unique->Bind( - LoadObjectField<String>(CAST(key), ThinString::kActualOffset)); - Goto(if_keyisunique); + GotoIf(IsSymbolMap(key_map), &if_symbol); - BIND(&if_hascachedindex); - var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); - Goto(if_keyisindex); + // Miss if |key| is not a String. + STATIC_ASSERT(FIRST_NAME_TYPE == FIRST_TYPE); + TNode<Uint16T> key_instance_type = LoadMapInstanceType(key_map); + Branch(IsStringInstanceType(key_instance_type), &if_string, &if_keyisother); - BIND(&if_keyisother); - GotoIfNot(InstanceTypeEqual(key_instance_type, ODDBALL_TYPE), if_bailout); - var_unique->Bind(LoadObjectField(key, Oddball::kToStringOffset)); - Goto(if_keyisunique); + // Symbols are unique. + BIND(&if_symbol); + { + *var_unique = CAST(key); + Goto(if_keyisunique); + } + + BIND(&if_string); + { + Label if_hascachedindex(this), if_thinstring(this); + + // |key| is a String. Check if it has a cached array index. + TNode<String> key_string = CAST(key); + TNode<Uint32T> hash = LoadNameHashField(key_string); + GotoIf(IsClearWord32(hash, Name::kDoesNotContainCachedArrayIndexMask), + &if_hascachedindex); + // No cached array index. If the string knows that it contains an index, + // then it must be an uncacheable index. Handle this case in the runtime. + GotoIf(IsClearWord32(hash, Name::kIsNotArrayIndexMask), if_bailout); + // Check if we have a ThinString. + GotoIf(InstanceTypeEqual(key_instance_type, THIN_STRING_TYPE), + &if_thinstring); + GotoIf(InstanceTypeEqual(key_instance_type, THIN_ONE_BYTE_STRING_TYPE), + &if_thinstring); + // Finally, check if |key| is internalized. + STATIC_ASSERT(kNotInternalizedTag != 0); + GotoIf(IsSetWord32(key_instance_type, kIsNotInternalizedMask), + if_notinternalized != nullptr ? if_notinternalized : if_bailout); + + *var_unique = key_string; + Goto(if_keyisunique); + + BIND(&if_thinstring); + *var_unique = + LoadObjectField<String>(key_string, ThinString::kActualOffset); + Goto(if_keyisunique); + + BIND(&if_hascachedindex); + *var_index = + Signed(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash)); + Goto(if_keyisindex); + } + + BIND(&if_keyisother); + { + GotoIfNot(InstanceTypeEqual(key_instance_type, ODDBALL_TYPE), if_bailout); + *var_unique = + LoadObjectField<String>(key_heap_object, Oddball::kToStringOffset); + Goto(if_keyisunique); + } + } } void CodeStubAssembler::TryInternalizeString( - Node* string, Label* if_index, Variable* var_index, Label* if_internalized, - Variable* var_internalized, Label* if_not_internalized, Label* if_bailout) { - DCHECK(var_index->rep() == MachineType::PointerRepresentation()); - DCHECK_EQ(var_internalized->rep(), MachineRepresentation::kTagged); - CSA_SLOW_ASSERT(this, IsString(string)); + SloppyTNode<String> string, Label* if_index, TVariable<IntPtrT>* var_index, + Label* if_internalized, TVariable<Name>* var_internalized, + Label* if_not_internalized, Label* if_bailout) { TNode<ExternalReference> function = ExternalConstant(ExternalReference::try_internalize_string_function()); TNode<ExternalReference> const isolate_ptr = ExternalConstant(ExternalReference::isolate_address(isolate())); - Node* result = - CallCFunction(function, MachineType::AnyTagged(), - std::make_pair(MachineType::Pointer(), isolate_ptr), - std::make_pair(MachineType::AnyTagged(), string)); + TNode<Object> result = + CAST(CallCFunction(function, MachineType::AnyTagged(), + std::make_pair(MachineType::Pointer(), isolate_ptr), + std::make_pair(MachineType::AnyTagged(), string))); Label internalized(this); GotoIf(TaggedIsNotSmi(result), &internalized); - TNode<IntPtrT> word_result = SmiUntag(result); + TNode<IntPtrT> word_result = SmiUntag(CAST(result)); GotoIf(IntPtrEqual(word_result, IntPtrConstant(ResultSentinel::kNotFound)), if_not_internalized); GotoIf(IntPtrEqual(word_result, IntPtrConstant(ResultSentinel::kUnsupported)), if_bailout); - var_index->Bind(word_result); + *var_index = word_result; Goto(if_index); BIND(&internalized); - var_internalized->Bind(result); + *var_internalized = CAST(result); Goto(if_internalized); } @@ -8712,31 +8215,6 @@ TNode<Object> CodeStubAssembler::BasicLoadNumberDictionaryElement( return LoadValueByKeyIndex<NumberDictionary>(dictionary, index); } -void CodeStubAssembler::BasicStoreNumberDictionaryElement( - TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index, - TNode<Object> value, Label* not_data, Label* if_hole, Label* read_only) { - TVARIABLE(IntPtrT, var_entry); - Label if_found(this); - NumberDictionaryLookup(dictionary, intptr_index, &if_found, &var_entry, - if_hole); - BIND(&if_found); - - // Check that the value is a data property. - TNode<IntPtrT> index = EntryToIndex<NumberDictionary>(var_entry.value()); - TNode<Uint32T> details = - LoadDetailsByKeyIndex<NumberDictionary>(dictionary, index); - TNode<Uint32T> kind = DecodeWord32<PropertyDetails::KindField>(details); - // TODO(jkummerow): Support accessors without missing? - GotoIfNot(Word32Equal(kind, Int32Constant(kData)), not_data); - - // Check that the property is writeable. - GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), - read_only); - - // Finally, store the value. - StoreValueByKeyIndex<NumberDictionary>(dictionary, index, value); -} - template <class Dictionary> void CodeStubAssembler::FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key, @@ -8858,16 +8336,16 @@ void CodeStubAssembler::LookupLinear(TNode<Name> unique_name, first_inclusive, IntPtrMul(ChangeInt32ToIntPtr(number_of_valid_entries), factor)); - BuildFastLoop( + BuildFastLoop<IntPtrT>( last_exclusive, first_inclusive, - [=](SloppyTNode<IntPtrT> name_index) { + [=](TNode<IntPtrT> name_index) { TNode<MaybeObject> element = LoadArrayElement(array, Array::kHeaderSize, name_index); TNode<Name> candidate_name = CAST(element); *var_name_index = name_index; GotoIf(TaggedEqual(candidate_name, unique_name), if_found); }, - -Array::kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPre); + -Array::kEntrySize, IndexAdvanceMode::kPre); Goto(if_not_found); } @@ -9029,7 +8507,7 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( TNode<Uint16T> type = LoadMapInstanceType(map); TNode<Uint32T> bit_field3 = EnsureOnlyHasSimpleProperties(map, type, bailout); - TNode<DescriptorArray> descriptors = LoadMapDescriptors(map); + TVARIABLE(DescriptorArray, var_descriptors, LoadMapDescriptors(map)); TNode<Uint32T> nof_descriptors = DecodeWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3); @@ -9044,25 +8522,23 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( // Note: var_end_key_index is exclusive for the loop TVARIABLE(IntPtrT, var_end_key_index, ToKeyIndex<DescriptorArray>(nof_descriptors)); - VariableList list( - {&var_stable, &var_has_symbol, &var_is_symbol_processing_loop, - &var_start_key_index, &var_end_key_index}, - zone()); + VariableList list({&var_descriptors, &var_stable, &var_has_symbol, + &var_is_symbol_processing_loop, &var_start_key_index, + &var_end_key_index}, + zone()); Label descriptor_array_loop( - this, {&var_stable, &var_has_symbol, &var_is_symbol_processing_loop, - &var_start_key_index, &var_end_key_index}); + this, {&var_descriptors, &var_stable, &var_has_symbol, + &var_is_symbol_processing_loop, &var_start_key_index, + &var_end_key_index}); Goto(&descriptor_array_loop); BIND(&descriptor_array_loop); - BuildFastLoop( + BuildFastLoop<IntPtrT>( list, var_start_key_index.value(), var_end_key_index.value(), - [=, &var_stable, &var_has_symbol, &var_is_symbol_processing_loop, - &var_start_key_index, &var_end_key_index](Node* index) { - TNode<IntPtrT> descriptor_key_index = - TNode<IntPtrT>::UncheckedCast(index); + [&](TNode<IntPtrT> descriptor_key_index) { TNode<Name> next_key = - LoadKeyByKeyIndex(descriptors, descriptor_key_index); + LoadKeyByKeyIndex(var_descriptors.value(), descriptor_key_index); TVARIABLE(Object, var_value, SmiConstant(0)); Label callback(this), next_iteration(this); @@ -9117,7 +8593,7 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( // Directly decode from the descriptor array if |object| did not // change shape. var_map = map; - var_meta_storage = descriptors; + var_meta_storage = var_descriptors.value(); var_entry = Signed(descriptor_key_index); Goto(&if_found_fast); } @@ -9183,19 +8659,21 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( BIND(&callback); body(next_key, var_value.value()); - // Check if |object| is still stable, i.e. we can proceed using - // property details from preloaded |descriptors|. - var_stable = Select<BoolT>( - var_stable.value(), - [=] { return TaggedEqual(LoadMap(object), map); }, - [=] { return Int32FalseConstant(); }); + // Check if |object| is still stable, i.e. the descriptors in the + // preloaded |descriptors| are still the same modulo in-place + // representation changes. + GotoIfNot(var_stable.value(), &next_iteration); + var_stable = TaggedEqual(LoadMap(object), map); + // Reload the descriptors just in case the actual array changed, and + // any of the field representations changed in-place. + var_descriptors = LoadMapDescriptors(map); Goto(&next_iteration); } } BIND(&next_iteration); }, - DescriptorArray::kEntrySize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + DescriptorArray::kEntrySize, IndexAdvanceMode::kPost); if (mode == kEnumerationOrder) { Label done(this); @@ -9205,14 +8683,73 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( var_is_symbol_processing_loop = Int32TrueConstant(); // Add DescriptorArray::kEntrySize to make the var_end_key_index exclusive // as BuildFastLoop() expects. - Increment(&var_end_key_index, DescriptorArray::kEntrySize, - INTPTR_PARAMETERS); + Increment(&var_end_key_index, DescriptorArray::kEntrySize); Goto(&descriptor_array_loop); BIND(&done); } } +TNode<Object> CodeStubAssembler::GetConstructor(TNode<Map> map) { + TVARIABLE(HeapObject, var_maybe_constructor); + var_maybe_constructor = map; + Label loop(this, &var_maybe_constructor), done(this); + GotoIfNot(IsMap(var_maybe_constructor.value()), &done); + Goto(&loop); + + BIND(&loop); + { + var_maybe_constructor = CAST(LoadObjectField( + var_maybe_constructor.value(), Map::kConstructorOrBackPointerOffset)); + GotoIf(IsMap(var_maybe_constructor.value()), &loop); + Goto(&done); + } + + BIND(&done); + return var_maybe_constructor.value(); +} + +TNode<NativeContext> CodeStubAssembler::GetCreationContext( + TNode<JSReceiver> receiver, Label* if_bailout) { + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Object> constructor = GetConstructor(receiver_map); + + TVARIABLE(JSFunction, var_function); + + Label done(this), if_jsfunction(this), if_jsgenerator(this); + GotoIf(TaggedIsSmi(constructor), if_bailout); + + TNode<Map> function_map = LoadMap(CAST(constructor)); + GotoIf(IsJSFunctionMap(function_map), &if_jsfunction); + GotoIf(IsJSGeneratorMap(function_map), &if_jsgenerator); + // Remote objects don't have a creation context. + GotoIf(IsFunctionTemplateInfoMap(function_map), if_bailout); + + CSA_ASSERT(this, IsJSFunctionMap(receiver_map)); + var_function = CAST(receiver); + Goto(&done); + + BIND(&if_jsfunction); + { + var_function = CAST(constructor); + Goto(&done); + } + + BIND(&if_jsgenerator); + { + var_function = LoadJSGeneratorObjectFunction(CAST(receiver)); + Goto(&done); + } + + BIND(&done); + TNode<Context> context = LoadJSFunctionContext(var_function.value()); + + GotoIfNot(IsContext(context), if_bailout); + + TNode<NativeContext> native_context = LoadNativeContext(context); + return native_context; +} + void CodeStubAssembler::DescriptorLookup( SloppyTNode<Name> unique_name, SloppyTNode<DescriptorArray> descriptors, SloppyTNode<Uint32T> bitfield3, Label* if_found, @@ -9302,7 +8839,7 @@ void CodeStubAssembler::TryLookupPropertyInSimpleObject( } void CodeStubAssembler::TryLookupProperty( - SloppyTNode<JSObject> object, SloppyTNode<Map> map, + SloppyTNode<JSReceiver> object, SloppyTNode<Map> map, SloppyTNode<Int32T> instance_type, SloppyTNode<Name> unique_name, Label* if_found_fast, Label* if_found_dict, Label* if_found_global, TVariable<HeapObject>* var_meta_storage, TVariable<IntPtrT>* var_name_index, @@ -9310,7 +8847,7 @@ void CodeStubAssembler::TryLookupProperty( Label if_objectisspecial(this); GotoIf(IsSpecialReceiverInstanceType(instance_type), &if_objectisspecial); - TryLookupPropertyInSimpleObject(object, map, unique_name, if_found_fast, + TryLookupPropertyInSimpleObject(CAST(object), map, unique_name, if_found_fast, if_found_dict, var_meta_storage, var_name_index, if_not_found); @@ -9547,25 +9084,44 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor( // AccessorPair case. { if (mode == kCallJSGetter) { + Label if_callable(this), if_function_template_info(this); Node* accessor_pair = value; TNode<HeapObject> getter = CAST(LoadObjectField(accessor_pair, AccessorPair::kGetterOffset)); TNode<Map> getter_map = LoadMap(getter); - TNode<Uint16T> instance_type = LoadMapInstanceType(getter_map); - // FunctionTemplateInfo getters are not supported yet. - GotoIf(InstanceTypeEqual(instance_type, FUNCTION_TEMPLATE_INFO_TYPE), - if_bailout); + + GotoIf(IsCallableMap(getter_map), &if_callable); + GotoIf(IsFunctionTemplateInfoMap(getter_map), &if_function_template_info); // Return undefined if the {getter} is not callable. var_value.Bind(UndefinedConstant()); - GotoIfNot(IsCallableMap(getter_map), &done); + Goto(&done); - // Call the accessor. - Callable callable = CodeFactory::Call(isolate()); - Node* result = CallJS(callable, context, getter, receiver); - var_value.Bind(result); + BIND(&if_callable); + { + // Call the accessor. + Callable callable = CodeFactory::Call(isolate()); + Node* result = CallJS(callable, context, getter, receiver); + var_value.Bind(result); + Goto(&done); + } + + BIND(&if_function_template_info); + { + TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>( + getter, FunctionTemplateInfo::kCachedPropertyNameOffset); + GotoIfNot(IsTheHole(cached_property_name), if_bailout); + + TNode<NativeContext> creation_context = + GetCreationContext(CAST(receiver), if_bailout); + var_value.Bind(CallBuiltin( + Builtins::kCallFunctionTemplate_CheckAccessAndCompatibleReceiver, + creation_context, getter, IntPtrConstant(0), receiver)); + Goto(&done); + } + } else { + Goto(&done); } - Goto(&done); } // AccessorInfo case. @@ -9617,10 +9173,11 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor( GotoIfNot(IsLengthString( LoadObjectField(accessor_info, AccessorInfo::kNameOffset)), if_bailout); - Node* receiver_value = LoadJSPrimitiveWrapperValue(receiver); + TNode<Object> receiver_value = + LoadJSPrimitiveWrapperValue(CAST(receiver)); GotoIfNot(TaggedIsNotSmi(receiver_value), if_bailout); - GotoIfNot(IsString(receiver_value), if_bailout); - var_value.Bind(LoadStringLengthAsSmi(receiver_value)); + GotoIfNot(IsString(CAST(receiver_value)), if_bailout); + var_value.Bind(LoadStringLengthAsSmi(CAST(receiver_value))); Goto(&done); } } @@ -9808,18 +9365,14 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map, } BIND(&if_isfaststringwrapper); { - CSA_ASSERT(this, HasInstanceType(object, JS_PRIMITIVE_WRAPPER_TYPE)); - Node* string = LoadJSPrimitiveWrapperValue(object); - CSA_ASSERT(this, IsString(string)); + TNode<String> string = CAST(LoadJSPrimitiveWrapperValue(CAST(object))); TNode<IntPtrT> length = LoadStringLengthAsWord(string); GotoIf(UintPtrLessThan(intptr_index, length), if_found); Goto(&if_isobjectorsmi); } BIND(&if_isslowstringwrapper); { - CSA_ASSERT(this, HasInstanceType(object, JS_PRIMITIVE_WRAPPER_TYPE)); - Node* string = LoadJSPrimitiveWrapperValue(object); - CSA_ASSERT(this, IsString(string)); + TNode<String> string = CAST(LoadJSPrimitiveWrapperValue(CAST(object))); TNode<IntPtrT> length = LoadStringLengthAsWord(string); GotoIf(UintPtrLessThan(intptr_index, length), if_found); Goto(&if_isdictionary); @@ -9892,8 +9445,8 @@ void CodeStubAssembler::TryPrototypeChainLookup( GotoIf(InstanceTypeEqual(instance_type, JS_PROXY_TYPE), if_proxy); } - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); Label if_keyisindex(this), if_iskeyunique(this); TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique, @@ -9905,9 +9458,7 @@ void CodeStubAssembler::TryPrototypeChainLookup( TVARIABLE(Map, var_holder_map, map); TVARIABLE(Int32T, var_holder_instance_type, instance_type); - VariableList merged_variables( - {&var_holder, &var_holder_map, &var_holder_instance_type}, zone()); - Label loop(this, merged_variables); + Label loop(this, {&var_holder, &var_holder_map, &var_holder_instance_type}); Goto(&loop); BIND(&loop); { @@ -9950,9 +9501,7 @@ void CodeStubAssembler::TryPrototypeChainLookup( TVARIABLE(Map, var_holder_map, map); TVARIABLE(Int32T, var_holder_instance_type, instance_type); - VariableList merged_variables( - {&var_holder, &var_holder_map, &var_holder_instance_type}, zone()); - Label loop(this, merged_variables); + Label loop(this, {&var_holder, &var_holder_map, &var_holder_instance_type}); Goto(&loop); BIND(&loop); { @@ -9978,22 +9527,22 @@ void CodeStubAssembler::TryPrototypeChainLookup( } } -Node* CodeStubAssembler::HasInPrototypeChain(Node* context, Node* object, - SloppyTNode<Object> prototype) { - CSA_ASSERT(this, TaggedIsNotSmi(object)); - VARIABLE(var_result, MachineRepresentation::kTagged); +TNode<Oddball> CodeStubAssembler::HasInPrototypeChain(TNode<Context> context, + TNode<HeapObject> object, + TNode<Object> prototype) { + TVARIABLE(Oddball, var_result); Label return_false(this), return_true(this), return_runtime(this, Label::kDeferred), return_result(this); // Loop through the prototype chain looking for the {prototype}. - VARIABLE(var_object_map, MachineRepresentation::kTagged, LoadMap(object)); + TVARIABLE(Map, var_object_map, LoadMap(object)); Label loop(this, &var_object_map); Goto(&loop); BIND(&loop); { // Check if we can determine the prototype directly from the {object_map}. Label if_objectisdirect(this), if_objectisspecial(this, Label::kDeferred); - Node* object_map = var_object_map.value(); + TNode<Map> object_map = var_object_map.value(); TNode<Uint16T> object_instance_type = LoadMapInstanceType(object_map); Branch(IsSpecialReceiverInstanceType(object_instance_type), &if_objectisspecial, &if_objectisdirect); @@ -10018,22 +9567,22 @@ Node* CodeStubAssembler::HasInPrototypeChain(Node* context, Node* object, // Continue with the prototype. CSA_ASSERT(this, TaggedIsNotSmi(object_prototype)); - var_object_map.Bind(LoadMap(object_prototype)); + var_object_map = LoadMap(object_prototype); Goto(&loop); } BIND(&return_true); - var_result.Bind(TrueConstant()); + var_result = TrueConstant(); Goto(&return_result); BIND(&return_false); - var_result.Bind(FalseConstant()); + var_result = FalseConstant(); Goto(&return_result); BIND(&return_runtime); { // Fallback to the runtime implementation. - var_result.Bind( + var_result = CAST( CallRuntime(Runtime::kHasInPrototypeChain, context, object, prototype)); } Goto(&return_result); @@ -10042,63 +9591,67 @@ Node* CodeStubAssembler::HasInPrototypeChain(Node* context, Node* object, return var_result.value(); } -Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, - Node* object) { - VARIABLE(var_result, MachineRepresentation::kTagged); +TNode<Oddball> CodeStubAssembler::OrdinaryHasInstance( + TNode<Context> context, TNode<Object> callable_maybe_smi, + TNode<Object> object_maybe_smi) { + TVARIABLE(Oddball, var_result); Label return_runtime(this, Label::kDeferred), return_result(this); GotoIfForceSlowPath(&return_runtime); // Goto runtime if {object} is a Smi. - GotoIf(TaggedIsSmi(object), &return_runtime); + GotoIf(TaggedIsSmi(object_maybe_smi), &return_runtime); // Goto runtime if {callable} is a Smi. - GotoIf(TaggedIsSmi(callable), &return_runtime); + GotoIf(TaggedIsSmi(callable_maybe_smi), &return_runtime); - // Load map of {callable}. - TNode<Map> callable_map = LoadMap(callable); - - // Goto runtime if {callable} is not a JSFunction. - TNode<Uint16T> callable_instance_type = LoadMapInstanceType(callable_map); - GotoIfNot(InstanceTypeEqual(callable_instance_type, JS_FUNCTION_TYPE), - &return_runtime); - - GotoIfPrototypeRequiresRuntimeLookup(CAST(callable), callable_map, - &return_runtime); - - // Get the "prototype" (or initial map) of the {callable}. - TNode<HeapObject> callable_prototype = LoadObjectField<HeapObject>( - CAST(callable), JSFunction::kPrototypeOrInitialMapOffset); { - Label no_initial_map(this), walk_prototype_chain(this); - TVARIABLE(HeapObject, var_callable_prototype, callable_prototype); + // Load map of {callable}. + TNode<HeapObject> object = CAST(object_maybe_smi); + TNode<HeapObject> callable = CAST(callable_maybe_smi); + TNode<Map> callable_map = LoadMap(callable); - // Resolve the "prototype" if the {callable} has an initial map. - GotoIfNot(IsMap(callable_prototype), &no_initial_map); - var_callable_prototype = - LoadObjectField<HeapObject>(callable_prototype, Map::kPrototypeOffset); - Goto(&walk_prototype_chain); + // Goto runtime if {callable} is not a JSFunction. + TNode<Uint16T> callable_instance_type = LoadMapInstanceType(callable_map); + GotoIfNot(InstanceTypeEqual(callable_instance_type, JS_FUNCTION_TYPE), + &return_runtime); - BIND(&no_initial_map); - // {callable_prototype} is the hole if the "prototype" property hasn't been - // requested so far. - Branch(TaggedEqual(callable_prototype, TheHoleConstant()), &return_runtime, - &walk_prototype_chain); + GotoIfPrototypeRequiresRuntimeLookup(CAST(callable), callable_map, + &return_runtime); - BIND(&walk_prototype_chain); - callable_prototype = var_callable_prototype.value(); - } + // Get the "prototype" (or initial map) of the {callable}. + TNode<HeapObject> callable_prototype = LoadObjectField<HeapObject>( + callable, JSFunction::kPrototypeOrInitialMapOffset); + { + Label no_initial_map(this), walk_prototype_chain(this); + TVARIABLE(HeapObject, var_callable_prototype, callable_prototype); + + // Resolve the "prototype" if the {callable} has an initial map. + GotoIfNot(IsMap(callable_prototype), &no_initial_map); + var_callable_prototype = LoadObjectField<HeapObject>( + callable_prototype, Map::kPrototypeOffset); + Goto(&walk_prototype_chain); + + BIND(&no_initial_map); + // {callable_prototype} is the hole if the "prototype" property hasn't + // been requested so far. + Branch(TaggedEqual(callable_prototype, TheHoleConstant()), + &return_runtime, &walk_prototype_chain); + + BIND(&walk_prototype_chain); + callable_prototype = var_callable_prototype.value(); + } - // Loop through the prototype chain looking for the {callable} prototype. - CSA_ASSERT(this, IsJSReceiver(callable_prototype)); - var_result.Bind(HasInPrototypeChain(context, object, callable_prototype)); - Goto(&return_result); + // Loop through the prototype chain looking for the {callable} prototype. + var_result = HasInPrototypeChain(context, object, callable_prototype); + Goto(&return_result); + } BIND(&return_runtime); { // Fallback to the runtime implementation. - var_result.Bind( - CallRuntime(Runtime::kOrdinaryHasInstance, context, callable, object)); + var_result = CAST(CallRuntime(Runtime::kOrdinaryHasInstance, context, + callable_maybe_smi, object_maybe_smi)); } Goto(&return_result); @@ -10111,34 +9664,72 @@ TNode<IntPtrT> CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, ParameterMode mode, int base_size) { CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, mode)); + if (mode == SMI_PARAMETERS) { + return ElementOffsetFromIndex(ReinterpretCast<Smi>(index_node), kind, + base_size); + } else { + DCHECK(mode == INTPTR_PARAMETERS); + return ElementOffsetFromIndex(ReinterpretCast<IntPtrT>(index_node), kind, + base_size); + } +} + +template <typename TIndex> +TNode<IntPtrT> CodeStubAssembler::ElementOffsetFromIndex( + TNode<TIndex> index_node, ElementsKind kind, int base_size) { + // TODO(v8:9708): Remove IntPtrT variant in favor of UintPtrT. + static_assert(std::is_same<TIndex, Smi>::value || + std::is_same<TIndex, IntPtrT>::value || + std::is_same<TIndex, UintPtrT>::value, + "Only Smi, UintPtrT or IntPtrT index nodes are allowed"); int element_size_shift = ElementsKindToShiftSize(kind); int element_size = 1 << element_size_shift; int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; intptr_t index = 0; + TNode<IntPtrT> intptr_index_node; bool constant_index = false; - if (mode == SMI_PARAMETERS) { + if (std::is_same<TIndex, Smi>::value) { + TNode<Smi> smi_index_node = ReinterpretCast<Smi>(index_node); element_size_shift -= kSmiShiftBits; Smi smi_index; - constant_index = ToSmiConstant(index_node, &smi_index); - if (constant_index) index = smi_index.value(); - index_node = BitcastTaggedSignedToWord(index_node); + constant_index = ToSmiConstant(smi_index_node, &smi_index); + if (constant_index) { + index = smi_index.value(); + } else { + if (COMPRESS_POINTERS_BOOL) { + smi_index_node = NormalizeSmiIndex(smi_index_node); + } + } + intptr_index_node = BitcastTaggedToWordForTagAndSmiBits(smi_index_node); } else { - DCHECK(mode == INTPTR_PARAMETERS); - constant_index = ToIntPtrConstant(index_node, &index); + intptr_index_node = ReinterpretCast<IntPtrT>(index_node); + constant_index = ToIntPtrConstant(intptr_index_node, &index); } if (constant_index) { return IntPtrConstant(base_size + element_size * index); } - TNode<WordT> shifted_index = + TNode<IntPtrT> shifted_index = (element_size_shift == 0) - ? UncheckedCast<WordT>(index_node) + ? intptr_index_node : ((element_size_shift > 0) - ? WordShl(index_node, IntPtrConstant(element_size_shift)) - : WordSar(index_node, IntPtrConstant(-element_size_shift))); + ? WordShl(intptr_index_node, + IntPtrConstant(element_size_shift)) + : WordSar(intptr_index_node, + IntPtrConstant(-element_size_shift))); return IntPtrAdd(IntPtrConstant(base_size), Signed(shifted_index)); } +// Instantiate ElementOffsetFromIndex for Smi and IntPtrT. +template V8_EXPORT_PRIVATE TNode<IntPtrT> +CodeStubAssembler::ElementOffsetFromIndex<Smi>(TNode<Smi> index_node, + ElementsKind kind, + int base_size); +template V8_EXPORT_PRIVATE TNode<IntPtrT> +CodeStubAssembler::ElementOffsetFromIndex<IntPtrT>(TNode<IntPtrT> index_node, + ElementsKind kind, + int base_size); + TNode<BoolT> CodeStubAssembler::IsOffsetInBounds(SloppyTNode<IntPtrT> offset, SloppyTNode<IntPtrT> length, int header_size, @@ -10146,8 +9737,7 @@ TNode<BoolT> CodeStubAssembler::IsOffsetInBounds(SloppyTNode<IntPtrT> offset, // Make sure we point to the last field. int element_size = 1 << ElementsKindToShiftSize(kind); int correction = header_size - kHeapObjectTag - element_size; - TNode<IntPtrT> last_offset = - ElementOffsetFromIndex(length, kind, INTPTR_PARAMETERS, correction); + TNode<IntPtrT> last_offset = ElementOffsetFromIndex(length, kind, correction); return IntPtrLessThanOrEqual(offset, last_offset); } @@ -10203,8 +9793,9 @@ TNode<FeedbackVector> CodeStubAssembler::LoadFeedbackVectorForStub() { return CAST(LoadFeedbackVector(function)); } -void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* maybe_vector, - Node* slot_id) { +void CodeStubAssembler::UpdateFeedback(TNode<Smi> feedback, + TNode<HeapObject> maybe_vector, + TNode<UintPtrT> slot_id) { Label end(this); // If feedback_vector is not valid, then nothing to do. GotoIf(IsUndefined(maybe_vector), &end); @@ -10216,7 +9807,7 @@ void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* maybe_vector, TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(feedback_vector, slot_id); TNode<Smi> previous_feedback = CAST(feedback_element); - TNode<Smi> combined_feedback = SmiOr(previous_feedback, CAST(feedback)); + TNode<Smi> combined_feedback = SmiOr(previous_feedback, feedback); GotoIf(SmiEqual(previous_feedback, combined_feedback), &end); { @@ -10230,7 +9821,7 @@ void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* maybe_vector, } void CodeStubAssembler::ReportFeedbackUpdate( - SloppyTNode<FeedbackVector> feedback_vector, SloppyTNode<IntPtrT> slot_id, + TNode<FeedbackVector> feedback_vector, SloppyTNode<UintPtrT> slot_id, const char* reason) { // Reset profiler ticks. StoreObjectFieldNoWriteBarrier( @@ -10241,7 +9832,7 @@ void CodeStubAssembler::ReportFeedbackUpdate( // Trace the update. CallRuntime(Runtime::kInterpreterTraceUpdateFeedback, NoContextConstant(), LoadFromParentFrame(JavaScriptFrameConstants::kFunctionOffset), - SmiTag(slot_id), StringConstant(reason)); + SmiTag(Signed(slot_id)), StringConstant(reason)); #endif // V8_TRACE_FEEDBACK_UPDATES } @@ -10285,14 +9876,16 @@ TNode<Map> CodeStubAssembler::LoadReceiverMap(SloppyTNode<Object> receiver) { [=] { return LoadMap(UncheckedCast<HeapObject>(receiver)); }); } -TNode<IntPtrT> CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { +TNode<IntPtrT> CodeStubAssembler::TryToIntptr(SloppyTNode<Object> key, + Label* miss) { TVARIABLE(IntPtrT, var_intptr_key); Label done(this, &var_intptr_key), key_is_smi(this); GotoIf(TaggedIsSmi(key), &key_is_smi); + // Try to convert a heap number to a Smi. - GotoIfNot(IsHeapNumber(key), miss); + GotoIfNot(IsHeapNumber(CAST(key)), miss); { - TNode<Float64T> value = LoadHeapNumberValue(key); + TNode<Float64T> value = LoadHeapNumberValue(CAST(key)); TNode<Int32T> int_value = RoundFloat64ToInt32(value); GotoIfNot(Float64Equal(value, ChangeInt32ToFloat64(int_value)), miss); var_intptr_key = ChangeInt32ToIntPtr(int_value); @@ -10301,7 +9894,7 @@ TNode<IntPtrT> CodeStubAssembler::TryToIntptr(Node* key, Label* miss) { BIND(&key_is_smi); { - var_intptr_key = SmiUntag(key); + var_intptr_key = SmiUntag(CAST(key)); Goto(&done); } @@ -10354,7 +9947,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments( } Label if_mapped(this), if_unmapped(this), end(this, &var_result); TNode<IntPtrT> intptr_two = IntPtrConstant(2); - TNode<WordT> adjusted_length = IntPtrSub(elements_length, intptr_two); + TNode<IntPtrT> adjusted_length = IntPtrSub(elements_length, intptr_two); GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped); @@ -10510,33 +10103,35 @@ void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, } } -Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) { +TNode<Uint8T> CodeStubAssembler::Int32ToUint8Clamped( + TNode<Int32T> int32_value) { Label done(this); TNode<Int32T> int32_zero = Int32Constant(0); TNode<Int32T> int32_255 = Int32Constant(255); - VARIABLE(var_value, MachineRepresentation::kWord32, int32_value); + TVARIABLE(Word32T, var_value, int32_value); GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done); - var_value.Bind(int32_zero); + var_value = int32_zero; GotoIf(Int32LessThan(int32_value, int32_zero), &done); - var_value.Bind(int32_255); + var_value = int32_255; Goto(&done); BIND(&done); - return var_value.value(); + return UncheckedCast<Uint8T>(var_value.value()); } -Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) { +TNode<Uint8T> CodeStubAssembler::Float64ToUint8Clamped( + TNode<Float64T> float64_value) { Label done(this); - VARIABLE(var_value, MachineRepresentation::kWord32, Int32Constant(0)); + TVARIABLE(Word32T, var_value, Int32Constant(0)); GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done); - var_value.Bind(Int32Constant(255)); + var_value = Int32Constant(255); GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done); { TNode<Float64T> rounded_value = Float64RoundToEven(float64_value); - var_value.Bind(TruncateFloat64ToWord32(rounded_value)); + var_value = TruncateFloat64ToWord32(rounded_value); Goto(&done); } BIND(&done); - return var_value.value(); + return UncheckedCast<Uint8T>(var_value.value()); } Node* CodeStubAssembler::PrepareValueForWriteToTypedArray( @@ -10716,8 +10311,8 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, GotoIfNot(UintPtrLessThan(intptr_key, length), &update_value_and_bailout); } - TNode<RawPtrT> backing_store = LoadJSTypedArrayBackingStore(CAST(object)); - StoreElement(backing_store, elements_kind, intptr_key, converted_value, + TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(object)); + StoreElement(data_ptr, elements_kind, intptr_key, converted_value, parameter_mode); Goto(&done); @@ -10807,7 +10402,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, if (IsSmiElementsKind(elements_kind)) { GotoIfNot(TaggedIsSmi(value), bailout); } else if (IsDoubleElementsKind(elements_kind)) { - value = TryTaggedToFloat64(value, bailout); + value = TryTaggedToFloat64(CAST(value), bailout); } if (IsGrowStoreMode(store_mode) && @@ -11047,7 +10642,7 @@ TNode<IntPtrT> CodeStubAssembler::PageFromAddress(TNode<IntPtrT> address) { } TNode<AllocationSite> CodeStubAssembler::CreateAllocationSiteInFeedbackVector( - SloppyTNode<FeedbackVector> feedback_vector, TNode<Smi> slot) { + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot) { TNode<IntPtrT> size = IntPtrConstant(AllocationSite::kSizeWithWeakNext); TNode<HeapObject> site = Allocate(size, CodeStubAssembler::kPretenured); StoreMapNoWriteBarrier(site, RootIndex::kAllocationSiteWithWeakNextMap); @@ -11090,19 +10685,16 @@ TNode<AllocationSite> CodeStubAssembler::CreateAllocationSiteInFeedbackVector( StoreObjectField(site, AllocationSite::kWeakNextOffset, next_site); StoreFullTaggedNoWriteBarrier(site_list, site); - StoreFeedbackVectorSlot(feedback_vector, slot, site, UPDATE_WRITE_BARRIER, 0, - SMI_PARAMETERS); + StoreFeedbackVectorSlot(feedback_vector, slot, site); return CAST(site); } TNode<MaybeObject> CodeStubAssembler::StoreWeakReferenceInFeedbackVector( - SloppyTNode<FeedbackVector> feedback_vector, Node* slot, - SloppyTNode<HeapObject> value, int additional_offset, - ParameterMode parameter_mode) { + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<HeapObject> value, int additional_offset) { TNode<MaybeObject> weak_value = MakeWeak(value); StoreFeedbackVectorSlot(feedback_vector, slot, weak_value, - UPDATE_WRITE_BARRIER, additional_offset, - parameter_mode); + UPDATE_WRITE_BARRIER, additional_offset); return weak_value; } @@ -11135,14 +10727,14 @@ TNode<Int32T> CodeStubAssembler::LoadElementsKind( return elements_kind; } -Node* CodeStubAssembler::BuildFastLoop( - const CodeStubAssembler::VariableList& vars, Node* start_index, - Node* end_index, const FastLoopBody& body, int increment, - ParameterMode parameter_mode, IndexAdvanceMode advance_mode) { - CSA_SLOW_ASSERT(this, MatchesParameterMode(start_index, parameter_mode)); - CSA_SLOW_ASSERT(this, MatchesParameterMode(end_index, parameter_mode)); - MachineRepresentation index_rep = ParameterRepresentation(parameter_mode); - VARIABLE(var, index_rep, start_index); +template <typename TIndex> +TNode<TIndex> CodeStubAssembler::BuildFastLoop(const VariableList& vars, + TNode<TIndex> start_index, + TNode<TIndex> end_index, + const FastLoopBody<TIndex>& body, + int increment, + IndexAdvanceMode advance_mode) { + TVARIABLE(TIndex, var, start_index); VariableList vars_copy(vars.begin(), vars.end(), zone()); vars_copy.push_back(&var); Label loop(this, vars_copy); @@ -11154,8 +10746,7 @@ Node* CodeStubAssembler::BuildFastLoop( // to force the loop header check at the end of the loop and branch forward to // it from the pre-header). The extra branch is slower in the case that the // loop actually iterates. - TNode<BoolT> first_check = - IntPtrOrSmiEqual(var.value(), end_index, parameter_mode); + TNode<BoolT> first_check = IntPtrOrSmiEqual(var.value(), end_index); int32_t first_check_val; if (ToInt32Constant(first_check, &first_check_val)) { if (first_check_val) return var.value(); @@ -11167,19 +10758,28 @@ Node* CodeStubAssembler::BuildFastLoop( BIND(&loop); { if (advance_mode == IndexAdvanceMode::kPre) { - Increment(&var, increment, parameter_mode); + Increment(&var, increment); } body(var.value()); if (advance_mode == IndexAdvanceMode::kPost) { - Increment(&var, increment, parameter_mode); + Increment(&var, increment); } - Branch(IntPtrOrSmiNotEqual(var.value(), end_index, parameter_mode), &loop, - &after_loop); + Branch(IntPtrOrSmiNotEqual(var.value(), end_index), &loop, &after_loop); } BIND(&after_loop); return var.value(); } +// Instantiate BuildFastLoop for Smi and IntPtrT. +template TNode<Smi> CodeStubAssembler::BuildFastLoop<Smi>( + const VariableList& vars, TNode<Smi> start_index, TNode<Smi> end_index, + const FastLoopBody<Smi>& body, int increment, + IndexAdvanceMode advance_mode); +template TNode<IntPtrT> CodeStubAssembler::BuildFastLoop<IntPtrT>( + const VariableList& vars, TNode<IntPtrT> start_index, + TNode<IntPtrT> end_index, const FastLoopBody<IntPtrT>& body, int increment, + IndexAdvanceMode advance_mode); + void CodeStubAssembler::BuildFastFixedArrayForEach( const CodeStubAssembler::VariableList& vars, Node* fixed_array, ElementsKind kind, Node* first_element_inclusive, @@ -11201,17 +10801,15 @@ void CodeStubAssembler::BuildFastFixedArrayForEach( if (direction == ForEachDirection::kForward) { for (int i = first_val; i < last_val; ++i) { TNode<IntPtrT> index = IntPtrConstant(i); - TNode<IntPtrT> offset = - ElementOffsetFromIndex(index, kind, INTPTR_PARAMETERS, - FixedArray::kHeaderSize - kHeapObjectTag); + TNode<IntPtrT> offset = ElementOffsetFromIndex( + index, kind, FixedArray::kHeaderSize - kHeapObjectTag); body(fixed_array, offset); } } else { for (int i = last_val - 1; i >= first_val; --i) { TNode<IntPtrT> index = IntPtrConstant(i); - TNode<IntPtrT> offset = - ElementOffsetFromIndex(index, kind, INTPTR_PARAMETERS, - FixedArray::kHeaderSize - kHeapObjectTag); + TNode<IntPtrT> offset = ElementOffsetFromIndex( + index, kind, FixedArray::kHeaderSize - kHeapObjectTag); body(fixed_array, offset); } } @@ -11228,11 +10826,10 @@ void CodeStubAssembler::BuildFastFixedArrayForEach( if (direction == ForEachDirection::kReverse) std::swap(start, limit); int increment = IsDoubleElementsKind(kind) ? kDoubleSize : kTaggedSize; - BuildFastLoop( + BuildFastLoop<IntPtrT>( vars, start, limit, - [fixed_array, &body](Node* offset) { body(fixed_array, offset); }, + [&](TNode<IntPtrT> offset) { body(fixed_array, offset); }, direction == ForEachDirection::kReverse ? -increment : increment, - INTPTR_PARAMETERS, direction == ForEachDirection::kReverse ? IndexAdvanceMode::kPre : IndexAdvanceMode::kPost); } @@ -11243,22 +10840,21 @@ void CodeStubAssembler::GotoIfFixedArraySizeDoesntFitInNewSpace( doesnt_fit); } -void CodeStubAssembler::InitializeFieldsWithRoot(Node* object, - Node* start_offset, - Node* end_offset, +void CodeStubAssembler::InitializeFieldsWithRoot(TNode<HeapObject> object, + TNode<IntPtrT> start_offset, + TNode<IntPtrT> end_offset, RootIndex root_index) { CSA_SLOW_ASSERT(this, TaggedIsNotSmi(object)); start_offset = IntPtrAdd(start_offset, IntPtrConstant(-kHeapObjectTag)); end_offset = IntPtrAdd(end_offset, IntPtrConstant(-kHeapObjectTag)); TNode<Object> root_value = LoadRoot(root_index); - BuildFastLoop( + BuildFastLoop<IntPtrT>( end_offset, start_offset, - [this, object, root_value](Node* current) { + [=](TNode<IntPtrT> current) { StoreNoWriteBarrier(MachineRepresentation::kTagged, object, current, root_value); }, - -kTaggedSize, INTPTR_PARAMETERS, - CodeStubAssembler::IndexAdvanceMode::kPre); + -kTaggedSize, CodeStubAssembler::IndexAdvanceMode::kPre); } void CodeStubAssembler::BranchIfNumberRelationalComparison( @@ -11384,11 +10980,9 @@ Operation Reverse(Operation op) { } } // anonymous namespace -Node* CodeStubAssembler::RelationalComparison(Operation op, - SloppyTNode<Object> left, - SloppyTNode<Object> right, - SloppyTNode<Context> context, - Variable* var_type_feedback) { +TNode<Oddball> CodeStubAssembler::RelationalComparison( + Operation op, TNode<Object> left, TNode<Object> right, + TNode<Context> context, TVariable<Smi>* var_type_feedback) { Label return_true(this), return_false(this), do_float_comparison(this), end(this); TVARIABLE(Oddball, var_result); // Actually only "true" or "false". @@ -11403,7 +10997,7 @@ Node* CodeStubAssembler::RelationalComparison(Operation op, if (var_type_feedback != nullptr) { // Initialize the type feedback to None. The current feedback is combined // with the previous feedback. - var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kNone)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kNone); loop_variable_list.push_back(var_type_feedback); } Label loop(this, loop_variable_list); @@ -11914,17 +11508,17 @@ void CodeStubAssembler::GenerateEqual_Same(SloppyTNode<Object> value, } // ES6 section 7.2.12 Abstract Equality Comparison -Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, - SloppyTNode<Object> right, - SloppyTNode<Context> context, - Variable* var_type_feedback) { +TNode<Oddball> CodeStubAssembler::Equal(SloppyTNode<Object> left, + SloppyTNode<Object> right, + SloppyTNode<Context> context, + TVariable<Smi>* var_type_feedback) { // This is a slightly optimized version of Object::Equals. Whenever you // change something functionality wise in here, remember to update the // Object::Equals method as well. Label if_equal(this), if_notequal(this), do_float_comparison(this), do_right_stringtonumber(this, Label::kDeferred), end(this); - VARIABLE(result, MachineRepresentation::kTagged); + TVARIABLE(Oddball, result); TVARIABLE(Float64T, var_left_float); TVARIABLE(Float64T, var_right_float); @@ -11984,7 +11578,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, GotoIf(IsHeapNumberMap(right_map), &if_right_heapnumber); // {left} is Smi and {right} is not HeapNumber or Smi. if (var_type_feedback != nullptr) { - var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } GotoIf(IsBooleanMap(right_map), &if_right_boolean); TNode<Uint16T> right_type = LoadMapInstanceType(right_map); @@ -12009,8 +11603,8 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, BIND(&if_right_bigint); { - result.Bind(CallRuntime(Runtime::kBigIntEqualToNumber, - NoContextConstant(), right, left)); + result = CAST(CallRuntime(Runtime::kBigIntEqualToNumber, + NoContextConstant(), right, left)); Goto(&end); } @@ -12046,7 +11640,8 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, BIND(&if_left_string); { GotoIfNot(IsStringInstanceType(right_type), &use_symmetry); - result.Bind(CallBuiltin(Builtins::kStringEqual, context, left, right)); + result = + CAST(CallBuiltin(Builtins::kStringEqual, context, left, right)); CombineFeedback(var_type_feedback, SmiOr(CollectFeedbackForString(left_type), CollectFeedbackForString(right_type))); @@ -12067,8 +11662,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, { Label if_right_boolean(this); if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } GotoIf(IsStringInstanceType(right_type), &do_right_stringtonumber); GotoIf(IsBooleanMap(right_map), &if_right_boolean); @@ -12098,38 +11692,35 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, BIND(&if_right_heapnumber); { if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } - result.Bind(CallRuntime(Runtime::kBigIntEqualToNumber, - NoContextConstant(), left, right)); + result = CAST(CallRuntime(Runtime::kBigIntEqualToNumber, + NoContextConstant(), left, right)); Goto(&end); } BIND(&if_right_bigint); { CombineFeedback(var_type_feedback, CompareOperationFeedback::kBigInt); - result.Bind(CallRuntime(Runtime::kBigIntEqualToBigInt, - NoContextConstant(), left, right)); + result = CAST(CallRuntime(Runtime::kBigIntEqualToBigInt, + NoContextConstant(), left, right)); Goto(&end); } BIND(&if_right_string); { if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } - result.Bind(CallRuntime(Runtime::kBigIntEqualToString, - NoContextConstant(), left, right)); + result = CAST(CallRuntime(Runtime::kBigIntEqualToString, + NoContextConstant(), left, right)); Goto(&end); } BIND(&if_right_boolean); { if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } var_right = LoadObjectField(CAST(right), Oddball::kToNumberOffset); Goto(&loop); @@ -12154,8 +11745,8 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, if (var_type_feedback != nullptr) { // If {right} is undetectable, it must be either also // Null or Undefined, or a Receiver (aka document.all). - var_type_feedback->Bind(SmiConstant( - CompareOperationFeedback::kReceiverOrNullOrUndefined)); + *var_type_feedback = SmiConstant( + CompareOperationFeedback::kReceiverOrNullOrUndefined); } Goto(&if_equal); } @@ -12164,12 +11755,11 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, { if (var_type_feedback != nullptr) { // Track whether {right} is Null, Undefined or Receiver. - var_type_feedback->Bind(SmiConstant( - CompareOperationFeedback::kReceiverOrNullOrUndefined)); + *var_type_feedback = SmiConstant( + CompareOperationFeedback::kReceiverOrNullOrUndefined); GotoIf(IsJSReceiverInstanceType(right_type), &if_notequal); GotoIfNot(IsBooleanMap(right_map), &if_notequal); - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } Goto(&if_notequal); } @@ -12178,8 +11768,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, BIND(&if_left_boolean); { if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } // If {right} is a Boolean too, it must be a different Boolean. @@ -12200,7 +11789,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, if (var_type_feedback != nullptr) { Label if_right_symbol(this); GotoIf(IsSymbolInstanceType(right_type), &if_right_symbol); - var_type_feedback->Bind(SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); Goto(&if_notequal); BIND(&if_right_symbol); @@ -12218,8 +11807,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, // {left} is a Primitive and {right} is a JSReceiver, so swapping // the order is not observable. if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } Goto(&use_symmetry); } @@ -12254,8 +11842,8 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, // When we get here, {right} must be either Null or Undefined. CSA_ASSERT(this, IsNullOrUndefined(right)); if (var_type_feedback != nullptr) { - var_type_feedback->Bind(SmiConstant( - CompareOperationFeedback::kReceiverOrNullOrUndefined)); + *var_type_feedback = SmiConstant( + CompareOperationFeedback::kReceiverOrNullOrUndefined); } Branch(IsUndetectableMap(left_map), &if_equal, &if_notequal); } @@ -12265,8 +11853,7 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, // {right} is a Primitive, and neither Null or Undefined; // convert {left} to Primitive too. if (var_type_feedback != nullptr) { - var_type_feedback->Bind( - SmiConstant(CompareOperationFeedback::kAny)); + *var_type_feedback = SmiConstant(CompareOperationFeedback::kAny); } Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate()); var_left = CallStub(callable, context, left); @@ -12298,13 +11885,13 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, BIND(&if_equal); { - result.Bind(TrueConstant()); + result = TrueConstant(); Goto(&end); } BIND(&if_notequal); { - result.Bind(FalseConstant()); + result = FalseConstant(); Goto(&end); } @@ -12312,9 +11899,9 @@ Node* CodeStubAssembler::Equal(SloppyTNode<Object> left, return result.value(); } -TNode<Oddball> CodeStubAssembler::StrictEqual(SloppyTNode<Object> lhs, - SloppyTNode<Object> rhs, - Variable* var_type_feedback) { +TNode<Oddball> CodeStubAssembler::StrictEqual( + SloppyTNode<Object> lhs, SloppyTNode<Object> rhs, + TVariable<Smi>* var_type_feedback) { // Pseudo-code for the algorithm below: // // if (lhs == rhs) { @@ -12482,7 +12069,7 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(SloppyTNode<Object> lhs, CollectFeedbackForString(lhs_instance_type); TNode<Smi> rhs_feedback = CollectFeedbackForString(rhs_instance_type); - var_type_feedback->Bind(SmiOr(lhs_feedback, rhs_feedback)); + *var_type_feedback = SmiOr(lhs_feedback, rhs_feedback); } result = CAST(CallBuiltin(Builtins::kStringEqual, NoContextConstant(), lhs, rhs)); @@ -12556,7 +12143,7 @@ TNode<Oddball> CodeStubAssembler::StrictEqual(SloppyTNode<Object> lhs, BIND(&if_lhsisoddball); { - STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE); + STATIC_ASSERT(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == ODDBALL_TYPE); GotoIf(IsBooleanMap(rhs_map), &if_not_equivalent_types); GotoIf(Int32LessThan(rhs_instance_type, Int32Constant(ODDBALL_TYPE)), @@ -12855,8 +12442,8 @@ TNode<Oddball> CodeStubAssembler::HasProperty(SloppyTNode<Context> context, return result.value(); } -Node* CodeStubAssembler::Typeof(Node* value) { - VARIABLE(result_var, MachineRepresentation::kTagged); +TNode<String> CodeStubAssembler::Typeof(SloppyTNode<Object> value) { + TVARIABLE(String, result_var); Label return_number(this, Label::kDeferred), if_oddball(this), return_function(this), return_undefined(this), return_object(this), @@ -12864,7 +12451,8 @@ Node* CodeStubAssembler::Typeof(Node* value) { GotoIf(TaggedIsSmi(value), &return_number); - TNode<Map> map = LoadMap(value); + TNode<HeapObject> value_heap_object = CAST(value); + TNode<Map> map = LoadMap(value_heap_object); GotoIf(IsHeapNumberMap(map), &return_number); @@ -12890,49 +12478,50 @@ Node* CodeStubAssembler::Typeof(Node* value) { GotoIf(IsBigIntInstanceType(instance_type), &return_bigint); CSA_ASSERT(this, InstanceTypeEqual(instance_type, SYMBOL_TYPE)); - result_var.Bind(HeapConstant(isolate()->factory()->symbol_string())); + result_var = HeapConstant(isolate()->factory()->symbol_string()); Goto(&return_result); BIND(&return_number); { - result_var.Bind(HeapConstant(isolate()->factory()->number_string())); + result_var = HeapConstant(isolate()->factory()->number_string()); Goto(&return_result); } BIND(&if_oddball); { - TNode<Object> type = LoadObjectField(value, Oddball::kTypeOfOffset); - result_var.Bind(type); + TNode<String> type = + CAST(LoadObjectField(value_heap_object, Oddball::kTypeOfOffset)); + result_var = type; Goto(&return_result); } BIND(&return_function); { - result_var.Bind(HeapConstant(isolate()->factory()->function_string())); + result_var = HeapConstant(isolate()->factory()->function_string()); Goto(&return_result); } BIND(&return_undefined); { - result_var.Bind(HeapConstant(isolate()->factory()->undefined_string())); + result_var = HeapConstant(isolate()->factory()->undefined_string()); Goto(&return_result); } BIND(&return_object); { - result_var.Bind(HeapConstant(isolate()->factory()->object_string())); + result_var = HeapConstant(isolate()->factory()->object_string()); Goto(&return_result); } BIND(&return_string); { - result_var.Bind(HeapConstant(isolate()->factory()->string_string())); + result_var = HeapConstant(isolate()->factory()->string_string()); Goto(&return_result); } BIND(&return_bigint); { - result_var.Bind(HeapConstant(isolate()->factory()->bigint_string())); + result_var = HeapConstant(isolate()->factory()->bigint_string()); Goto(&return_result); } @@ -12941,7 +12530,7 @@ Node* CodeStubAssembler::Typeof(Node* value) { } TNode<Object> CodeStubAssembler::GetSuperConstructor( - SloppyTNode<Context> context, SloppyTNode<JSFunction> active_function) { + TNode<Context> context, TNode<JSFunction> active_function) { Label is_not_constructor(this, Label::kDeferred), out(this); TVARIABLE(Object, result); @@ -13004,9 +12593,10 @@ TNode<JSReceiver> CodeStubAssembler::SpeciesConstructor( return var_result.value(); } -Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, - Node* context) { - VARIABLE(var_result, MachineRepresentation::kTagged); +TNode<Oddball> CodeStubAssembler::InstanceOf(TNode<Object> object, + TNode<Object> callable, + TNode<Context> context) { + TVARIABLE(Oddball, var_result); Label if_notcallable(this, Label::kDeferred), if_notreceiver(this, Label::kDeferred), if_otherhandler(this), if_nohandler(this, Label::kDeferred), return_true(this), @@ -13014,7 +12604,7 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, // Ensure that the {callable} is actually a JSReceiver. GotoIf(TaggedIsSmi(callable), &if_notreceiver); - GotoIfNot(IsJSReceiver(callable), &if_notreceiver); + GotoIfNot(IsJSReceiver(CAST(callable)), &if_notreceiver); // Load the @@hasInstance property from {callable}. TNode<Object> inst_of_handler = @@ -13032,8 +12622,8 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, // Call to Function.prototype[@@hasInstance] directly. Callable builtin(BUILTIN_CODE(isolate(), FunctionPrototypeHasInstance), CallTrampolineDescriptor{}); - Node* result = CallJS(builtin, context, inst_of_handler, callable, object); - var_result.Bind(result); + var_result = + CAST(CallJS(builtin, context, inst_of_handler, callable, object)); Goto(&return_result); } @@ -13055,12 +12645,11 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, BIND(&if_nohandler); { // Ensure that the {callable} is actually Callable. - GotoIfNot(IsCallable(callable), &if_notcallable); + GotoIfNot(IsCallable(CAST(callable)), &if_notcallable); // Use the OrdinaryHasInstance algorithm. - TNode<Object> result = - CallBuiltin(Builtins::kOrdinaryHasInstance, context, callable, object); - var_result.Bind(result); + var_result = CAST( + CallBuiltin(Builtins::kOrdinaryHasInstance, context, callable, object)); Goto(&return_result); } @@ -13071,11 +12660,11 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable, { ThrowTypeError(context, MessageTemplate::kNonObjectInInstanceOfCheck); } BIND(&return_true); - var_result.Bind(TrueConstant()); + var_result = TrueConstant(); Goto(&return_result); BIND(&return_false); - var_result.Bind(FalseConstant()); + var_result = FalseConstant(); Goto(&return_result); BIND(&return_result); @@ -13294,9 +12883,8 @@ TNode<JSObject> CodeStubAssembler::AllocateJSIteratorResult( return CAST(result); } -Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context, - Node* key, - Node* value) { +TNode<JSObject> CodeStubAssembler::AllocateJSIteratorResultForEntry( + TNode<Context> context, TNode<Object> key, SloppyTNode<Object> value) { TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Smi> length = SmiConstant(2); int const elements_size = FixedArray::SizeFor(2); @@ -13326,7 +12914,7 @@ Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context, StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, array); StoreObjectFieldRoot(result, JSIteratorResult::kDoneOffset, RootIndex::kFalseValue); - return result; + return CAST(result); } TNode<JSReceiver> CodeStubAssembler::ArraySpeciesCreate(TNode<Context> context, @@ -13393,21 +12981,19 @@ TNode<UintPtrT> CodeStubAssembler::LoadJSTypedArrayLength( return LoadObjectField<UintPtrT>(typed_array, JSTypedArray::kLengthOffset); } -CodeStubArguments::CodeStubArguments( - CodeStubAssembler* assembler, Node* argc, Node* fp, - CodeStubAssembler::ParameterMode param_mode, ReceiverMode receiver_mode) +CodeStubArguments::CodeStubArguments(CodeStubAssembler* assembler, + TNode<IntPtrT> argc, TNode<RawPtrT> fp, + ReceiverMode receiver_mode) : assembler_(assembler), - argc_mode_(param_mode), receiver_mode_(receiver_mode), argc_(argc), base_(), fp_(fp != nullptr ? fp : assembler_->LoadFramePointer()) { TNode<IntPtrT> offset = assembler_->ElementOffsetFromIndex( - argc_, SYSTEM_POINTER_ELEMENTS, param_mode, + argc_, SYSTEM_POINTER_ELEMENTS, (StandardFrameConstants::kFixedSlotCountAboveFp - 1) * kSystemPointerSize); - base_ = - assembler_->UncheckedCast<RawPtrT>(assembler_->IntPtrAdd(fp_, offset)); + base_ = assembler_->RawPtrAdd(fp_, offset); } TNode<Object> CodeStubArguments::GetReceiver() const { @@ -13422,24 +13008,18 @@ void CodeStubArguments::SetReceiver(TNode<Object> object) const { base_, assembler_->IntPtrConstant(kSystemPointerSize), object); } -TNode<WordT> CodeStubArguments::AtIndexPtr( - Node* index, CodeStubAssembler::ParameterMode mode) const { - using Node = compiler::Node; - Node* negated_index = assembler_->IntPtrOrSmiSub( - assembler_->IntPtrOrSmiConstant(0, mode), index, mode); +TNode<RawPtrT> CodeStubArguments::AtIndexPtr(TNode<IntPtrT> index) const { + TNode<IntPtrT> negated_index = + assembler_->IntPtrOrSmiSub(assembler_->IntPtrConstant(0), index); TNode<IntPtrT> offset = assembler_->ElementOffsetFromIndex( - negated_index, SYSTEM_POINTER_ELEMENTS, mode, 0); - return assembler_->IntPtrAdd(assembler_->UncheckedCast<IntPtrT>(base_), - offset); + negated_index, SYSTEM_POINTER_ELEMENTS, 0); + return assembler_->RawPtrAdd(base_, offset); } -TNode<Object> CodeStubArguments::AtIndex( - Node* index, CodeStubAssembler::ParameterMode mode) const { - DCHECK_EQ(argc_mode_, mode); - CSA_ASSERT(assembler_, - assembler_->UintPtrOrSmiLessThan(index, GetLength(mode), mode)); +TNode<Object> CodeStubArguments::AtIndex(TNode<IntPtrT> index) const { + CSA_ASSERT(assembler_, assembler_->UintPtrOrSmiLessThan(index, GetLength())); return assembler_->UncheckedCast<Object>( - assembler_->LoadFullTagged(AtIndexPtr(index, mode))); + assembler_->LoadFullTagged(AtIndexPtr(index))); } TNode<Object> CodeStubArguments::AtIndex(int index) const { @@ -13452,9 +13032,8 @@ TNode<Object> CodeStubArguments::GetOptionalArgumentValue( CodeStubAssembler::Label argument_missing(assembler_), argument_done(assembler_, &result); - assembler_->GotoIf(assembler_->UintPtrOrSmiGreaterThanOrEqual( - assembler_->IntPtrOrSmiConstant(index, argc_mode_), - argc_, argc_mode_), + assembler_->GotoIf(assembler_->UintPtrGreaterThanOrEqual( + assembler_->IntPtrConstant(index), argc_), &argument_missing); result = AtIndex(index); assembler_->Goto(&argument_done); @@ -13473,10 +13052,8 @@ TNode<Object> CodeStubArguments::GetOptionalArgumentValue( CodeStubAssembler::Label argument_missing(assembler_), argument_done(assembler_, &result); - assembler_->GotoIf( - assembler_->UintPtrOrSmiGreaterThanOrEqual( - assembler_->IntPtrToParameter(index, argc_mode_), argc_, argc_mode_), - &argument_missing); + assembler_->GotoIf(assembler_->UintPtrGreaterThanOrEqual(index, argc_), + &argument_missing); result = AtIndex(index); assembler_->Goto(&argument_done); @@ -13490,43 +13067,38 @@ TNode<Object> CodeStubArguments::GetOptionalArgumentValue( void CodeStubArguments::ForEach( const CodeStubAssembler::VariableList& vars, - const CodeStubArguments::ForEachBodyFunction& body, Node* first, Node* last, - CodeStubAssembler::ParameterMode mode) { + const CodeStubArguments::ForEachBodyFunction& body, TNode<IntPtrT> first, + TNode<IntPtrT> last) const { assembler_->Comment("CodeStubArguments::ForEach"); if (first == nullptr) { - first = assembler_->IntPtrOrSmiConstant(0, mode); + first = assembler_->IntPtrConstant(0); } if (last == nullptr) { - DCHECK_EQ(mode, argc_mode_); last = argc_; } - TNode<IntPtrT> start = assembler_->IntPtrSub( - assembler_->UncheckedCast<IntPtrT>(base_), - assembler_->ElementOffsetFromIndex(first, SYSTEM_POINTER_ELEMENTS, mode)); - TNode<IntPtrT> end = assembler_->IntPtrSub( - assembler_->UncheckedCast<IntPtrT>(base_), - assembler_->ElementOffsetFromIndex(last, SYSTEM_POINTER_ELEMENTS, mode)); - assembler_->BuildFastLoop( + TNode<RawPtrT> start = assembler_->RawPtrSub( + base_, + assembler_->ElementOffsetFromIndex(first, SYSTEM_POINTER_ELEMENTS)); + TNode<RawPtrT> end = assembler_->RawPtrSub( + base_, assembler_->ElementOffsetFromIndex(last, SYSTEM_POINTER_ELEMENTS)); + assembler_->BuildFastLoop<RawPtrT>( vars, start, end, - [this, &body](Node* current) { - Node* arg = assembler_->Load(MachineType::AnyTagged(), current); + [&](TNode<RawPtrT> current) { + TNode<Object> arg = assembler_->Load<Object>(current); body(arg); }, - -kSystemPointerSize, CodeStubAssembler::INTPTR_PARAMETERS, - CodeStubAssembler::IndexAdvanceMode::kPost); + -kSystemPointerSize, CodeStubAssembler::IndexAdvanceMode::kPost); } void CodeStubArguments::PopAndReturn(Node* value) { - Node* pop_count; + TNode<IntPtrT> pop_count; if (receiver_mode_ == ReceiverMode::kHasReceiver) { - pop_count = assembler_->IntPtrOrSmiAdd( - argc_, assembler_->IntPtrOrSmiConstant(1, argc_mode_), argc_mode_); + pop_count = assembler_->IntPtrAdd(argc_, assembler_->IntPtrConstant(1)); } else { pop_count = argc_; } - assembler_->PopAndReturn(assembler_->ParameterToIntPtr(pop_count, argc_mode_), - value); + assembler_->PopAndReturn(pop_count, value); } TNode<BoolT> CodeStubAssembler::IsFastElementsKind( @@ -13642,21 +13214,15 @@ Node* CodeStubAssembler:: } TNode<Code> CodeStubAssembler::LoadBuiltin(TNode<Smi> builtin_id) { - CSA_ASSERT(this, SmiGreaterThanOrEqual(builtin_id, SmiConstant(0))); - CSA_ASSERT(this, - SmiLessThan(builtin_id, SmiConstant(Builtins::builtin_count))); + CSA_ASSERT(this, SmiBelow(builtin_id, SmiConstant(Builtins::builtin_count))); - int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; - int index_shift = kSystemPointerSizeLog2 - kSmiShiftBits; - TNode<WordT> table_index = - index_shift >= 0 - ? WordShl(BitcastTaggedSignedToWord(builtin_id), index_shift) - : WordSar(BitcastTaggedSignedToWord(builtin_id), -index_shift); - - return CAST( - Load(MachineType::TaggedPointer(), + TNode<IntPtrT> offset = + ElementOffsetFromIndex(SmiToBInt(builtin_id), SYSTEM_POINTER_ELEMENTS); + + return CAST(BitcastWordToTagged( + Load(MachineType::Pointer(), ExternalConstant(ExternalReference::builtins_address(isolate())), - table_index)); + offset))); } TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( @@ -13765,11 +13331,9 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( return sfi_code.value(); } -Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map, - Node* shared_info, - Node* context) { - CSA_SLOW_ASSERT(this, IsMap(map)); - +TNode<JSFunction> CodeStubAssembler::AllocateFunctionWithMapAndContext( + TNode<Map> map, TNode<SharedFunctionInfo> shared_info, + TNode<Context> context) { TNode<Code> const code = GetSharedFunctionInfoCode(shared_info); // TODO(ishell): All the callers of this function pass map loaded from @@ -13790,7 +13354,7 @@ Node* CodeStubAssembler::AllocateFunctionWithMapAndContext(Node* map, shared_info); StoreObjectFieldNoWriteBarrier(fun, JSFunction::kContextOffset, context); StoreObjectFieldNoWriteBarrier(fun, JSFunction::kCodeOffset, code); - return fun; + return CAST(fun); } void CodeStubAssembler::CheckPrototypeEnumCache(Node* receiver, @@ -13839,8 +13403,9 @@ void CodeStubAssembler::CheckPrototypeEnumCache(Node* receiver, } } -Node* CodeStubAssembler::CheckEnumCache(Node* receiver, Label* if_empty, - Label* if_runtime) { +TNode<Map> CodeStubAssembler::CheckEnumCache(TNode<HeapObject> receiver, + Label* if_empty, + Label* if_runtime) { Label if_fast(this), if_cache(this), if_no_cache(this, Label::kDeferred); TNode<Map> receiver_map = LoadMap(receiver); @@ -13855,7 +13420,7 @@ Node* CodeStubAssembler::CheckEnumCache(Node* receiver, Label* if_empty, { // Avoid runtime-call for empty dictionary receivers. GotoIfNot(IsDictionaryMap(receiver_map), if_runtime); - TNode<NameDictionary> properties = CAST(LoadSlowProperties(receiver)); + TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(receiver))); TNode<Smi> length = GetNumberOfElements(properties); GotoIfNot(TaggedEqual(length, SmiConstant(0)), if_runtime); // Check that there are no elements on the {receiver} and its prototype @@ -13881,8 +13446,7 @@ TNode<Object> CodeStubAssembler::GetArgumentValue(TorqueStructArguments args, TorqueStructArguments CodeStubAssembler::GetFrameArguments( TNode<RawPtrT> frame, TNode<IntPtrT> argc) { - return CodeStubArguments(this, argc, frame, INTPTR_PARAMETERS) - .GetTorqueArguments(); + return CodeStubArguments(this, argc, frame).GetTorqueArguments(); } void CodeStubAssembler::Print(const char* s) { @@ -13976,9 +13540,8 @@ TNode<JSArray> CodeStubAssembler::ArrayCreate(TNode<Context> context, // TODO(delphick): Consider using // AllocateUninitializedJSArrayWithElements to avoid initializing an // array and then writing over it. - array = - AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, length, SmiConstant(0), - nullptr, ParameterMode::SMI_PARAMETERS); + array = AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, length, + SmiConstant(0), {}, ParameterMode::SMI_PARAMETERS); Goto(&done); BIND(&done); diff --git a/deps/v8/src/codegen/code-stub-assembler.h b/deps/v8/src/codegen/code-stub-assembler.h index 9884d04e66e1da..eee3e7a376a9d3 100644 --- a/deps/v8/src/codegen/code-stub-assembler.h +++ b/deps/v8/src/codegen/code-stub-assembler.h @@ -97,6 +97,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; V(iterator_symbol, iterator_symbol, IteratorSymbol) \ V(length_string, length_string, LengthString) \ V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap) \ + V(match_symbol, match_symbol, MatchSymbol) \ V(megamorphic_symbol, megamorphic_symbol, MegamorphicSymbol) \ V(MetaMap, meta_map, MetaMap) \ V(MinusZeroValue, minus_zero_value, MinusZero) \ @@ -114,7 +115,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; V(object_to_string, object_to_string, ObjectToString) \ V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap) \ V(OnePointerFillerMap, one_pointer_filler_map, OnePointerFillerMap) \ - V(premonomorphic_symbol, premonomorphic_symbol, PremonomorphicSymbol) \ V(PreparseDataMap, preparse_data_map, PreparseDataMap) \ V(PromiseCapabilityMap, promise_capability_map, PromiseCapabilityMap) \ V(PromiseFulfillReactionJobTaskMap, promise_fulfill_reaction_job_task_map, \ @@ -157,11 +157,11 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(V) #ifdef DEBUG -#define CSA_CHECK(csa, x) \ - (csa)->Check( \ - [&]() -> compiler::Node* { \ - return implicit_cast<compiler::SloppyTNode<Word32T>>(x); \ - }, \ +#define CSA_CHECK(csa, x) \ + (csa)->Check( \ + [&]() -> compiler::Node* { \ + return implicit_cast<SloppyTNode<Word32T>>(x); \ + }, \ #x, __FILE__, __LINE__) #else #define CSA_CHECK(csa, x) (csa)->FastCheck(x) @@ -255,10 +255,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler public TorqueGeneratedExportedMacrosAssembler { public: using Node = compiler::Node; - template <class T> - using TNode = compiler::TNode<T>; - template <class T> - using SloppyTNode = compiler::SloppyTNode<T>; template <typename T> using LazyNode = std::function<TNode<T>()>; @@ -303,11 +299,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler return ParameterRepresentation(OptimalParameterMode()); } + TNode<IntPtrT> ParameterToIntPtr(TNode<Smi> value) { return SmiUntag(value); } + TNode<IntPtrT> ParameterToIntPtr(TNode<IntPtrT> value) { return value; } + // TODO(v8:9708): remove once all uses are ported. TNode<IntPtrT> ParameterToIntPtr(Node* value, ParameterMode mode) { if (mode == SMI_PARAMETERS) value = SmiUntag(value); return UncheckedCast<IntPtrT>(value); } + template <typename TIndex> + TNode<TIndex> IntPtrToParameter(TNode<IntPtrT> value); + Node* IntPtrToParameter(SloppyTNode<IntPtrT> value, ParameterMode mode) { if (mode == SMI_PARAMETERS) return SmiTag(value); return value; @@ -364,6 +366,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler #error Unknown architecture. #endif + // Pointer compression specific. Returns true if the upper 32 bits of a Smi + // contain the sign of a lower 32 bits (i.e. not corrupted) so that the Smi + // can be directly used as an index in element offset computation. + TNode<BoolT> IsValidSmiIndex(TNode<Smi> smi); + + // Pointer compression specific. Ensures that the upper 32 bits of a Smi + // contain the sign of a lower 32 bits so that the Smi can be directly used + // as an index in element offset computation. + TNode<Smi> NormalizeSmiIndex(TNode<Smi> smi_index); + TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) { GotoIf(TaggedIsNotSmi(value), fail); return UncheckedCast<Smi>(value); @@ -443,18 +455,52 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Node* MatchesParameterMode(Node* value, ParameterMode mode); -#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ - Node* OpName(Node* a, Node* b, ParameterMode mode) { \ - if (mode == SMI_PARAMETERS) { \ - return SmiOpName(CAST(a), CAST(b)); \ - } else { \ - DCHECK_EQ(INTPTR_PARAMETERS, mode); \ - return IntPtrOpName(a, b); \ - } \ - } +#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ + /* TODO(v8:9708): remove once all uses are ported. */ \ + Node* OpName(Node* a, Node* b, ParameterMode mode) { \ + if (mode == SMI_PARAMETERS) { \ + return SmiOpName(CAST(a), CAST(b)); \ + } else { \ + DCHECK_EQ(INTPTR_PARAMETERS, mode); \ + return IntPtrOpName(UncheckedCast<IntPtrT>(a), \ + UncheckedCast<IntPtrT>(b)); \ + } \ + } \ + TNode<Smi> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \ + TNode<IntPtrT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \ + return IntPtrOpName(a, b); \ + } \ + TNode<RawPtrT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) { \ + return ReinterpretCast<RawPtrT>(IntPtrOpName( \ + ReinterpretCast<IntPtrT>(a), ReinterpretCast<IntPtrT>(b))); \ + } + // TODO(v8:9708): Define BInt operations once all uses are ported. PARAMETER_BINOP(IntPtrOrSmiMin, IntPtrMin, SmiMin) PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd) PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub) +#undef PARAMETER_BINOP + +#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \ + /* TODO(v8:9708): remove once all uses are ported. */ \ + TNode<BoolT> OpName(Node* a, Node* b, ParameterMode mode) { \ + if (mode == SMI_PARAMETERS) { \ + return SmiOpName(CAST(a), CAST(b)); \ + } else { \ + DCHECK_EQ(INTPTR_PARAMETERS, mode); \ + return IntPtrOpName(UncheckedCast<IntPtrT>(a), \ + UncheckedCast<IntPtrT>(b)); \ + } \ + } \ + TNode<BoolT> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \ + TNode<BoolT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \ + return IntPtrOpName(a, b); \ + } \ + TNode<BoolT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) { \ + return IntPtrOpName(a, b); \ + } + // TODO(v8:9708): Define BInt operations once all uses are ported. + PARAMETER_BINOP(IntPtrOrSmiEqual, WordEqual, SmiEqual) + PARAMETER_BINOP(IntPtrOrSmiNotEqual, WordNotEqual, SmiNotEqual) PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan) PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual, SmiLessThanOrEqual) @@ -473,31 +519,30 @@ class V8_EXPORT_PRIVATE CodeStubAssembler intptr_t ConstexprWordNot(intptr_t a) { return ~a; } uintptr_t ConstexprWordNot(uintptr_t a) { return ~a; } - TNode<BoolT> TaggedEqual(TNode<UnionT<Object, MaybeObject>> a, - TNode<UnionT<Object, MaybeObject>> b) { - // In pointer-compressed architectures, the instruction selector will narrow - // this comparison to a 32-bit one. + TNode<BoolT> TaggedEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) { +#ifdef V8_COMPRESS_POINTERS + return Word32Equal(ChangeTaggedToCompressed(a), + ChangeTaggedToCompressed(b)); +#else return WordEqual(ReinterpretCast<WordT>(a), ReinterpretCast<WordT>(b)); +#endif } - TNode<BoolT> TaggedNotEqual(TNode<UnionT<Object, MaybeObject>> a, - TNode<UnionT<Object, MaybeObject>> b) { - // In pointer-compressed architectures, the instruction selector will narrow - // this comparison to a 32-bit one. - return WordNotEqual(ReinterpretCast<WordT>(a), ReinterpretCast<WordT>(b)); + TNode<BoolT> TaggedNotEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) { + return Word32BinaryNot(TaggedEqual(a, b)); } TNode<Object> NoContextConstant(); #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ - compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ + TNode<std::remove_pointer<std::remove_reference<decltype( \ std::declval<ReadOnlyRoots>().rootAccessorName())>::type>::type> \ name##Constant(); HEAP_IMMUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR) #undef HEAP_CONSTANT_ACCESSOR #define HEAP_CONSTANT_ACCESSOR(rootIndexName, rootAccessorName, name) \ - compiler::TNode<std::remove_pointer<std::remove_reference<decltype( \ + TNode<std::remove_pointer<std::remove_reference<decltype( \ std::declval<Heap>().rootAccessorName())>::type>::type> \ name##Constant(); HEAP_MUTABLE_IMMOVABLE_OBJECT_LIST(HEAP_CONSTANT_ACCESSOR) @@ -511,11 +556,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BInt> BIntConstant(int value); + template <typename TIndex> + TNode<TIndex> IntPtrOrSmiConstant(int value); + // TODO(v8:9708): remove once all uses are ported. Node* IntPtrOrSmiConstant(int value, ParameterMode mode); - TNode<BoolT> IntPtrOrSmiEqual(Node* left, Node* right, ParameterMode mode); - TNode<BoolT> IntPtrOrSmiNotEqual(Node* left, Node* right, ParameterMode mode); + bool IsIntPtrOrSmiConstantZero(TNode<Smi> test); + bool IsIntPtrOrSmiConstantZero(TNode<IntPtrT> test); + // TODO(v8:9708): remove once all uses are ported. bool IsIntPtrOrSmiConstantZero(Node* test, ParameterMode mode); + bool TryGetIntPtrOrSmiConstantValue(Node* maybe_constant, int* value, ParameterMode mode); @@ -557,25 +607,27 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Float64T> SmiToFloat64(SloppyTNode<Smi> value); TNode<Smi> SmiFromIntPtr(SloppyTNode<IntPtrT> value) { return SmiTag(value); } TNode<Smi> SmiFromInt32(SloppyTNode<Int32T> value); + TNode<Smi> SmiFromUint32(TNode<Uint32T> value); TNode<IntPtrT> SmiToIntPtr(SloppyTNode<Smi> value) { return SmiUntag(value); } TNode<Int32T> SmiToInt32(SloppyTNode<Smi> value); // Smi operations. -#define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName) \ - TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ - if (SmiValuesAre32Bits()) { \ - return BitcastWordToTaggedSigned(IntPtrOpName( \ - BitcastTaggedSignedToWord(a), BitcastTaggedSignedToWord(b))); \ - } else { \ - DCHECK(SmiValuesAre31Bits()); \ - if (kSystemPointerSize == kInt64Size) { \ - CSA_ASSERT(this, IsValidSmi(a)); \ - CSA_ASSERT(this, IsValidSmi(b)); \ - } \ - return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr( \ - Int32OpName(TruncateIntPtrToInt32(BitcastTaggedSignedToWord(a)), \ - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(b))))); \ - } \ +#define SMI_ARITHMETIC_BINOP(SmiOpName, IntPtrOpName, Int32OpName) \ + TNode<Smi> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ + if (SmiValuesAre32Bits()) { \ + return BitcastWordToTaggedSigned( \ + IntPtrOpName(BitcastTaggedToWordForTagAndSmiBits(a), \ + BitcastTaggedToWordForTagAndSmiBits(b))); \ + } else { \ + DCHECK(SmiValuesAre31Bits()); \ + if (kSystemPointerSize == kInt64Size) { \ + CSA_ASSERT(this, IsValidSmi(a)); \ + CSA_ASSERT(this, IsValidSmi(b)); \ + } \ + return BitcastWordToTaggedSigned(ChangeInt32ToIntPtr(Int32OpName( \ + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), \ + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(b))))); \ + } \ } SMI_ARITHMETIC_BINOP(SmiAdd, IntPtrAdd, Int32Add) SMI_ARITHMETIC_BINOP(SmiSub, IntPtrSub, Int32Sub) @@ -595,38 +647,40 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Smi> SmiShl(TNode<Smi> a, int shift) { return BitcastWordToTaggedSigned( - WordShl(BitcastTaggedSignedToWord(a), shift)); + WordShl(BitcastTaggedToWordForTagAndSmiBits(a), shift)); } TNode<Smi> SmiShr(TNode<Smi> a, int shift) { if (kTaggedSize == kInt64Size) { return BitcastWordToTaggedSigned( - WordAnd(WordShr(BitcastTaggedSignedToWord(a), shift), - BitcastTaggedSignedToWord(SmiConstant(-1)))); + WordAnd(WordShr(BitcastTaggedToWordForTagAndSmiBits(a), shift), + BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1)))); } else { // For pointer compressed Smis, we want to make sure that we truncate to // int32 before shifting, to avoid the values of the top 32-bits from // leaking into the sign bit of the smi. return BitcastWordToTaggedSigned(WordAnd( ChangeInt32ToIntPtr(Word32Shr( - TruncateWordToInt32(BitcastTaggedSignedToWord(a)), shift)), - BitcastTaggedSignedToWord(SmiConstant(-1)))); + TruncateWordToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), + shift)), + BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1)))); } } TNode<Smi> SmiSar(TNode<Smi> a, int shift) { if (kTaggedSize == kInt64Size) { return BitcastWordToTaggedSigned( - WordAnd(WordSar(BitcastTaggedSignedToWord(a), shift), - BitcastTaggedSignedToWord(SmiConstant(-1)))); + WordAnd(WordSar(BitcastTaggedToWordForTagAndSmiBits(a), shift), + BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1)))); } else { // For pointer compressed Smis, we want to make sure that we truncate to // int32 before shifting, to avoid the values of the top 32-bits from // changing the sign bit of the smi. return BitcastWordToTaggedSigned(WordAnd( ChangeInt32ToIntPtr(Word32Sar( - TruncateWordToInt32(BitcastTaggedSignedToWord(a)), shift)), - BitcastTaggedSignedToWord(SmiConstant(-1)))); + TruncateWordToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), + shift)), + BitcastTaggedToWordForTagAndSmiBits(SmiConstant(-1)))); } } @@ -648,21 +702,22 @@ class V8_EXPORT_PRIVATE CodeStubAssembler } } -#define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName) \ - TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ - if (kTaggedSize == kInt64Size) { \ - return IntPtrOpName(BitcastTaggedSignedToWord(a), \ - BitcastTaggedSignedToWord(b)); \ - } else { \ - DCHECK_EQ(kTaggedSize, kInt32Size); \ - DCHECK(SmiValuesAre31Bits()); \ - if (kSystemPointerSize == kInt64Size) { \ - CSA_ASSERT(this, IsValidSmi(a)); \ - CSA_ASSERT(this, IsValidSmi(b)); \ - } \ - return Int32OpName(TruncateIntPtrToInt32(BitcastTaggedSignedToWord(a)), \ - TruncateIntPtrToInt32(BitcastTaggedSignedToWord(b))); \ - } \ +#define SMI_COMPARISON_OP(SmiOpName, IntPtrOpName, Int32OpName) \ + TNode<BoolT> SmiOpName(TNode<Smi> a, TNode<Smi> b) { \ + if (kTaggedSize == kInt64Size) { \ + return IntPtrOpName(BitcastTaggedToWordForTagAndSmiBits(a), \ + BitcastTaggedToWordForTagAndSmiBits(b)); \ + } else { \ + DCHECK_EQ(kTaggedSize, kInt32Size); \ + DCHECK(SmiValuesAre31Bits()); \ + if (kSystemPointerSize == kInt64Size) { \ + CSA_ASSERT(this, IsValidSmi(a)); \ + CSA_ASSERT(this, IsValidSmi(b)); \ + } \ + return Int32OpName( \ + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(a)), \ + TruncateIntPtrToInt32(BitcastTaggedToWordForTagAndSmiBits(b))); \ + } \ } SMI_COMPARISON_OP(SmiEqual, WordEqual, Word32Equal) SMI_COMPARISON_OP(SmiNotEqual, WordNotEqual, Word32NotEqual) @@ -856,9 +911,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Int32T> TruncateIntPtrToInt32(SloppyTNode<IntPtrT> value); // Check a value for smi-ness - TNode<BoolT> TaggedIsSmi(SloppyTNode<Object> a); TNode<BoolT> TaggedIsSmi(TNode<MaybeObject> a); - TNode<BoolT> TaggedIsNotSmi(SloppyTNode<Object> a); + TNode<BoolT> TaggedIsSmi(SloppyTNode<Object> a) { + return TaggedIsSmi(UncheckedCast<MaybeObject>(a)); + } + TNode<BoolT> TaggedIsNotSmi(TNode<MaybeObject> a); + TNode<BoolT> TaggedIsNotSmi(SloppyTNode<Object> a) { + return TaggedIsNotSmi(UncheckedCast<MaybeObject>(a)); + } // Check that the value is a non-negative smi. TNode<BoolT> TaggedIsPositiveSmi(SloppyTNode<Object> a); // Check that a word has a word-aligned address. @@ -918,9 +978,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Works only with V8_ENABLE_FORCE_SLOW_PATH compile time flag. Nop otherwise. void GotoIfForceSlowPath(Label* if_true); - // Branches to {if_true} when Debug::ExecutionMode is DebugInfo::kSideEffect. - void GotoIfDebugExecutionModeChecksSideEffects(Label* if_true); - // Load value from current parent frame by given offset in bytes. Node* LoadFromParentFrame(int offset, MachineType type = MachineType::AnyTagged()); @@ -1060,9 +1117,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Word32T> IsStringWrapperElementsKind(TNode<Map> map); void GotoIfMapHasSlowProperties(TNode<Map> map, Label* if_slow); - // Load the properties backing store of a JSObject. - TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSObject> object); - TNode<HeapObject> LoadFastProperties(SloppyTNode<JSObject> object); + // Load the properties backing store of a JSReceiver. + TNode<HeapObject> LoadSlowProperties(SloppyTNode<JSReceiver> object); + TNode<HeapObject> LoadFastProperties(SloppyTNode<JSReceiver> object); // Load the elements backing store of a JSObject. TNode<FixedArrayBase> LoadElements(SloppyTNode<JSObject> object) { return LoadJSObjectElements(object); @@ -1148,10 +1205,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<IntPtrT> LoadStringLengthAsWord(SloppyTNode<String> string); // Load length field of a String object as uint32_t value. TNode<Uint32T> LoadStringLengthAsWord32(SloppyTNode<String> string); - // Loads a pointer to the sequential String char array. - Node* PointerToSeqStringData(Node* seq_string); // Load value field of a JSPrimitiveWrapper object. - Node* LoadJSPrimitiveWrapperValue(Node* object); + TNode<Object> LoadJSPrimitiveWrapperValue(TNode<JSPrimitiveWrapper> object); // Figures out whether the value of maybe_object is: // - a SMI (jump to "if_smi", "extracted" will be the SMI value) @@ -1175,7 +1230,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BoolT> IsWeakOrCleared(TNode<MaybeObject> value); TNode<BoolT> IsCleared(TNode<MaybeObject> value); - TNode<BoolT> IsNotCleared(TNode<MaybeObject> value); + TNode<BoolT> IsNotCleared(TNode<MaybeObject> value) { + return Word32BinaryNot(IsCleared(value)); + } // Removes the weak bit + asserts it was set. TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value); @@ -1183,12 +1240,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<HeapObject> GetHeapObjectAssumeWeak(TNode<MaybeObject> value, Label* if_cleared); - TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> object, - TNode<Object> value); - TNode<BoolT> IsNotWeakReferenceTo(TNode<MaybeObject> object, - TNode<Object> value); - TNode<BoolT> IsStrongReferenceTo(TNode<MaybeObject> object, - TNode<Object> value); + // Checks if |maybe_object| is a weak reference to given |heap_object|. + // Works for both any tagged |maybe_object| values. + TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> maybe_object, + TNode<HeapObject> heap_object); + // Returns true if the |object| is a HeapObject and |maybe_object| is a weak + // reference to |object|. + // The |maybe_object| must not be a Smi. + TNode<BoolT> IsWeakReferenceToObject(TNode<MaybeObject> maybe_object, + TNode<Object> object); TNode<MaybeObject> MakeWeak(TNode<HeapObject> value); @@ -1341,9 +1401,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Int32T> elements_kind, Label* if_accessor, Label* if_hole); // Load a feedback slot from a FeedbackVector. + template <typename TIndex> TNode<MaybeObject> LoadFeedbackVectorSlot( - Node* object, Node* index, int additional_offset = 0, - ParameterMode parameter_mode = INTPTR_PARAMETERS); + TNode<FeedbackVector> feedback_vector, TNode<TIndex> slot, + int additional_offset = 0); TNode<IntPtrT> LoadFeedbackVectorLength(TNode<FeedbackVector>); TNode<Float64T> LoadDoubleWithHoleCheck(TNode<FixedDoubleArray> array, @@ -1383,13 +1444,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BigInt> BigIntFromInt32Pair(TNode<IntPtrT> low, TNode<IntPtrT> high); TNode<BigInt> BigIntFromUint32Pair(TNode<UintPtrT> low, TNode<UintPtrT> high); - void StoreJSTypedArrayElementFromTagged(TNode<Context> context, - TNode<JSTypedArray> typed_array, - TNode<Smi> index_node, - TNode<Object> value, - ElementsKind elements_kind); - // Context manipulation + TNode<BoolT> LoadContextHasExtensionField(SloppyTNode<Context> context); TNode<Object> LoadContextElement(SloppyTNode<Context> context, int slot_index); TNode<Object> LoadContextElement(SloppyTNode<Context> context, @@ -1608,10 +1664,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler } void StoreFeedbackVectorSlot( - Node* object, Node* index, Node* value, + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<AnyTaggedT> value, WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER, - int additional_offset = 0, - ParameterMode parameter_mode = INTPTR_PARAMETERS); + int additional_offset = 0); void EnsureArrayLengthWritable(TNode<Map> map, Label* bailout); @@ -1633,8 +1689,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler void BuildAppendJSArray(ElementsKind kind, Node* array, Node* value, Label* bailout); - void StoreFieldsNoWriteBarrier(Node* start_address, Node* end_address, - Node* value); + void StoreFieldsNoWriteBarrier(TNode<IntPtrT> start_address, + TNode<IntPtrT> end_address, + TNode<Object> value); Node* AllocateCellWithValue(Node* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); @@ -1642,7 +1699,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler return AllocateCellWithValue(SmiConstant(value), SKIP_WRITE_BARRIER); } - Node* LoadCellValue(Node* cell); + TNode<Object> LoadCellValue(Node* cell); void StoreCellValue(Node* cell, Node* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); @@ -1698,11 +1755,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<String> parent, TNode<Smi> offset); - // Allocate an appropriate one- or two-byte ConsString with the first and - // second parts specified by |left| and |right|. - TNode<String> AllocateConsString(TNode<Uint32T> length, TNode<String> left, - TNode<String> right); - TNode<NameDictionary> AllocateNameDictionary(int at_least_space_for); TNode<NameDictionary> AllocateNameDictionary( TNode<IntPtrT> at_least_space_for, AllocationFlags = kNone); @@ -1714,26 +1766,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler template <typename CollectionType> Node* AllocateOrderedHashTable(); - // Builds code that finds OrderedHashTable entry for a key with hash code - // {hash} with using the comparison code generated by {key_compare}. The code - // jumps to {entry_found} if the key is found, or to {not_found} if the key - // was not found. In the {entry_found} branch, the variable - // entry_start_position will be bound to the index of the entry (relative to - // OrderedHashTable::kHashTableStartIndex). - // - // The {CollectionType} template parameter stands for the particular instance - // of OrderedHashTable, it should be OrderedHashMap or OrderedHashSet. - template <typename CollectionType> - void FindOrderedHashTableEntry( - Node* table, Node* hash, - const std::function<void(TNode<Object>, Label*, Label*)>& key_compare, - Variable* entry_start_position, Label* entry_found, Label* not_found); - template <typename CollectionType> TNode<CollectionType> AllocateSmallOrderedHashTable(TNode<IntPtrT> capacity); Node* AllocateStruct(Node* map, AllocationFlags flags = kNone); - void InitializeStructBody(Node* object, Node* map, Node* size, + void InitializeStructBody(TNode<HeapObject> object, TNode<IntPtrT> size, int start_offset = Struct::kHeaderSize); TNode<JSObject> AllocateJSObjectFromMap( @@ -1742,14 +1779,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler SlackTrackingMode slack_tracking_mode = kNoSlackTracking); void InitializeJSObjectFromMap( - Node* object, Node* map, Node* instance_size, Node* properties = nullptr, + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size, Node* properties = nullptr, Node* elements = nullptr, SlackTrackingMode slack_tracking_mode = kNoSlackTracking); - void InitializeJSObjectBodyWithSlackTracking(Node* object, Node* map, - Node* instance_size); + void InitializeJSObjectBodyWithSlackTracking( + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size); void InitializeJSObjectBodyNoSlackTracking( - Node* object, Node* map, Node* instance_size, + SloppyTNode<HeapObject> object, SloppyTNode<Map> map, + SloppyTNode<IntPtrT> instance_size, int start_offset = JSObject::kHeaderSize); TNode<BoolT> IsValidFastJSArrayCapacity(Node* capacity, @@ -1762,7 +1802,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler std::pair<TNode<JSArray>, TNode<FixedArrayBase>> AllocateUninitializedJSArrayWithElements( ElementsKind kind, TNode<Map> array_map, TNode<Smi> length, - Node* allocation_site, Node* capacity, + TNode<AllocationSite> allocation_site, Node* capacity, ParameterMode capacity_mode = INTPTR_PARAMETERS, AllocationFlags allocation_flags = kNone, int array_header_size = JSArray::kSize); @@ -1771,20 +1811,20 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // The ParameterMode argument is only used for the capacity parameter. TNode<JSArray> AllocateJSArray( ElementsKind kind, TNode<Map> array_map, Node* capacity, - TNode<Smi> length, Node* allocation_site = nullptr, + TNode<Smi> length, TNode<AllocationSite> allocation_site = {}, ParameterMode capacity_mode = INTPTR_PARAMETERS, AllocationFlags allocation_flags = kNone); TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map, TNode<Smi> capacity, TNode<Smi> length) { - return AllocateJSArray(kind, array_map, capacity, length, nullptr, + return AllocateJSArray(kind, array_map, capacity, length, {}, SMI_PARAMETERS); } TNode<JSArray> AllocateJSArray(ElementsKind kind, TNode<Map> array_map, TNode<IntPtrT> capacity, TNode<Smi> length, AllocationFlags allocation_flags = kNone) { - return AllocateJSArray(kind, array_map, capacity, length, nullptr, + return AllocateJSArray(kind, array_map, capacity, length, {}, INTPTR_PARAMETERS, allocation_flags); } @@ -1792,7 +1832,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<JSArray> AllocateJSArray(TNode<Map> array_map, TNode<FixedArrayBase> elements, TNode<Smi> length, - Node* allocation_site = nullptr, + TNode<AllocationSite> allocation_site = {}, int array_header_size = JSArray::kSize); enum class HoleConversionMode { kDontConvert, kConvertToUndefined }; @@ -1806,15 +1846,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // If |convert_holes| is set kDontConvert, holes are also copied to the // resulting array, who will have the same elements kind as |array|. The // function generates significantly less code in this case. - Node* CloneFastJSArray( - Node* context, Node* array, ParameterMode mode = INTPTR_PARAMETERS, - Node* allocation_site = nullptr, + TNode<JSArray> CloneFastJSArray( + TNode<Context> context, TNode<JSArray> array, + ParameterMode mode = INTPTR_PARAMETERS, + TNode<AllocationSite> allocation_site = {}, HoleConversionMode convert_holes = HoleConversionMode::kDontConvert); - Node* ExtractFastJSArray(Node* context, Node* array, Node* begin, Node* count, + Node* ExtractFastJSArray(TNode<Context> context, TNode<JSArray> array, + Node* begin, Node* count, ParameterMode mode = INTPTR_PARAMETERS, Node* capacity = nullptr, - Node* allocation_site = nullptr); + TNode<AllocationSite> allocation_site = {}); TNode<FixedArrayBase> AllocateFixedArray( ElementsKind kind, Node* capacity, ParameterMode mode = INTPTR_PARAMETERS, @@ -1828,6 +1870,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler fixed_array_map); } + TNode<NativeContext> GetCreationContext(TNode<JSReceiver> receiver, + Label* if_bailout); + TNode<Object> GetConstructor(TNode<Map> map); + TNode<Map> GetStructMap(InstanceType instance_type); TNode<FixedArray> AllocateUninitializedFixedArray(intptr_t capacity) { @@ -1879,10 +1925,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Object> object, IterationKind mode); + // TODO(v8:9722): Return type should be JSIteratorResult TNode<JSObject> AllocateJSIteratorResult(SloppyTNode<Context> context, SloppyTNode<Object> value, SloppyTNode<Oddball> done); - Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value); + + // TODO(v8:9722): Return type should be JSIteratorResult + TNode<JSObject> AllocateJSIteratorResultForEntry(TNode<Context> context, + TNode<Object> key, + SloppyTNode<Object> value); TNode<JSReceiver> ArraySpeciesCreate(TNode<Context> context, TNode<Object> originalArray, @@ -1904,6 +1955,25 @@ class V8_EXPORT_PRIVATE CodeStubAssembler enum class DestroySource { kNo, kYes }; + // Collect the callable |maybe_target| feedback for either a CALL_IC or + // an INSTANCEOF_IC in the |feedback_vector| at |slot_id|. + void CollectCallableFeedback(TNode<Object> maybe_target, + TNode<Context> context, + TNode<FeedbackVector> feedback_vector, + TNode<UintPtrT> slot_id); + + // Collect CALL_IC feedback for |maybe_target| function in the + // |feedback_vector| at |slot_id|, and the call counts in + // the |feedback_vector| at |slot_id+1|. + void CollectCallFeedback(TNode<Object> maybe_target, TNode<Context> context, + TNode<HeapObject> maybe_feedback_vector, + TNode<UintPtrT> slot_id); + + // Increment the call count for a CALL_IC or construct call. + // The call count is located at feedback_vector[slot_id + 1]. + void IncrementCallCount(TNode<FeedbackVector> feedback_vector, + TNode<UintPtrT> slot_id); + // Specify DestroySource::kYes if {from_array} is being supplanted by // {to_array}. This offers a slight performance benefit by simply copying the // array word by word. The source may be destroyed at the end of this macro. @@ -2152,27 +2222,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // kAllFixedArrays, the generated code is more compact and efficient if the // caller can specify whether only FixedArrays or FixedDoubleArrays will be // passed as the |source| parameter. - Node* CloneFixedArray(Node* source, - ExtractFixedArrayFlags flags = - ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW) { + TNode<FixedArrayBase> CloneFixedArray( + TNode<FixedArrayBase> source, + ExtractFixedArrayFlags flags = + ExtractFixedArrayFlag::kAllFixedArraysDontCopyCOW) { ParameterMode mode = OptimalParameterMode(); return ExtractFixedArray(source, IntPtrOrSmiConstant(0, mode), nullptr, nullptr, flags, mode); } - // Copies |character_count| elements from |from_string| to |to_string| - // starting at the |from_index|'th character. |from_string| and |to_string| - // can either be one-byte strings or two-byte strings, although if - // |from_string| is two-byte, then |to_string| must be two-byte. - // |from_index|, |to_index| and |character_count| must be intptr_ts s.t. 0 <= - // |from_index| <= |from_index| + |character_count| <= from_string.length and - // 0 <= |to_index| <= |to_index| + |character_count| <= to_string.length. - void CopyStringCharacters(Node* from_string, Node* to_string, - TNode<IntPtrT> from_index, TNode<IntPtrT> to_index, - TNode<IntPtrT> character_count, - String::Encoding from_encoding, - String::Encoding to_encoding); - // Loads an element from |array| of |from_kind| elements by given |offset| // (NOTE: not index!), does a hole check if |if_hole| is provided and // converts the value so that it becomes ready for storing to array of @@ -2194,21 +2252,26 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Tries to grow the |elements| array of given |object| to store the |key| // or bails out if the growing gap is too big. Returns new elements. - Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind, - Node* key, Label* bailout); + TNode<FixedArrayBase> TryGrowElementsCapacity(Node* object, Node* elements, + ElementsKind kind, Node* key, + Label* bailout); // Tries to grow the |capacity|-length |elements| array of given |object| // to store the |key| or bails out if the growing gap is too big. Returns // new elements. - Node* TryGrowElementsCapacity(Node* object, Node* elements, ElementsKind kind, - Node* key, Node* capacity, ParameterMode mode, - Label* bailout); + TNode<FixedArrayBase> TryGrowElementsCapacity(Node* object, Node* elements, + ElementsKind kind, Node* key, + Node* capacity, + ParameterMode mode, + Label* bailout); // Grows elements capacity of given object. Returns new elements. - Node* GrowElementsCapacity(Node* object, Node* elements, - ElementsKind from_kind, ElementsKind to_kind, - Node* capacity, Node* new_capacity, - ParameterMode mode, Label* bailout); + TNode<FixedArrayBase> GrowElementsCapacity(Node* object, Node* elements, + ElementsKind from_kind, + ElementsKind to_kind, + Node* capacity, Node* new_capacity, + ParameterMode mode, + Label* bailout); // Given a need to grow by |growth|, allocate an appropriate new capacity // if necessary, and return a new elements FixedArray object. Label |bailout| @@ -2223,25 +2286,30 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Node* base_allocation_size, Node* allocation_site); - Node* TryTaggedToFloat64(Node* value, Label* if_valueisnotnumber); - Node* TruncateTaggedToFloat64(Node* context, Node* value); - Node* TruncateTaggedToWord32(Node* context, Node* value); - void TaggedToWord32OrBigInt(Node* context, Node* value, Label* if_number, - Variable* var_word32, Label* if_bigint, - Variable* var_bigint); - void TaggedToWord32OrBigIntWithFeedback( - Node* context, Node* value, Label* if_number, Variable* var_word32, - Label* if_bigint, Variable* var_bigint, Variable* var_feedback); + TNode<Float64T> TryTaggedToFloat64(TNode<Object> value, + Label* if_valueisnotnumber); + TNode<Float64T> TruncateTaggedToFloat64(SloppyTNode<Context> context, + SloppyTNode<Object> value); + TNode<Word32T> TruncateTaggedToWord32(SloppyTNode<Context> context, + SloppyTNode<Object> value); + void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value, + Label* if_number, TVariable<Word32T>* var_word32, + Label* if_bigint, + TVariable<Object>* var_maybe_bigint); + void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context, + TNode<Object> value, Label* if_number, + TVariable<Word32T>* var_word32, + Label* if_bigint, + TVariable<Object>* var_maybe_bigint, + TVariable<Smi>* var_feedback); // Truncate the floating point value of a HeapNumber to an Int32. TNode<Int32T> TruncateHeapNumberValueToWord32(TNode<HeapNumber> object); // Conversions. - void TryHeapNumberToSmi(TNode<HeapNumber> number, - TVariable<Smi>& output, // NOLINT(runtime/references) + void TryHeapNumberToSmi(TNode<HeapNumber> number, TVariable<Smi>* output, Label* if_smi); - void TryFloat64ToSmi(TNode<Float64T> number, - TVariable<Smi>& output, // NOLINT(runtime/references) + void TryFloat64ToSmi(TNode<Float64T> number, TVariable<Smi>* output, Label* if_smi); TNode<Number> ChangeFloat64ToTagged(SloppyTNode<Float64T> value); TNode<Number> ChangeInt32ToTagged(SloppyTNode<Int32T> value); @@ -2377,7 +2445,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BoolT> IsAllocationSiteInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsJSFunctionMap(SloppyTNode<Map> map); TNode<BoolT> IsJSFunction(SloppyTNode<HeapObject> object); - TNode<BoolT> IsJSGeneratorObject(SloppyTNode<HeapObject> object); + TNode<BoolT> IsJSGeneratorObject(TNode<HeapObject> object); TNode<BoolT> IsJSGlobalProxyInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsJSGlobalProxyMap(SloppyTNode<Map> map); TNode<BoolT> IsJSGlobalProxy(SloppyTNode<HeapObject> object); @@ -2388,6 +2456,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BoolT> IsJSPromise(SloppyTNode<HeapObject> object); TNode<BoolT> IsJSProxy(SloppyTNode<HeapObject> object); TNode<BoolT> IsJSStringIterator(SloppyTNode<HeapObject> object); + TNode<BoolT> IsJSRegExpStringIterator(SloppyTNode<HeapObject> object); TNode<BoolT> IsJSReceiverInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsJSReceiverMap(SloppyTNode<Map> map); TNode<BoolT> IsJSReceiver(SloppyTNode<HeapObject> object); @@ -2395,6 +2464,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<BoolT> IsJSTypedArrayInstanceType(SloppyTNode<Int32T> instance_type); TNode<BoolT> IsJSTypedArrayMap(SloppyTNode<Map> map); TNode<BoolT> IsJSTypedArray(SloppyTNode<HeapObject> object); + TNode<BoolT> IsJSGeneratorMap(TNode<Map> map); TNode<BoolT> IsJSPrimitiveWrapperInstanceType( SloppyTNode<Int32T> instance_type); TNode<BoolT> IsJSPrimitiveWrapperMap(SloppyTNode<Map> map); @@ -2537,47 +2607,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Return the single character string with only {code}. TNode<String> StringFromSingleCharCode(TNode<Int32T> code); - // Return a new string object which holds a substring containing the range - // [from,to[ of string. - TNode<String> SubString(TNode<String> string, TNode<IntPtrT> from, - TNode<IntPtrT> to); - - // Return a new string object produced by concatenating |first| with |second|. - TNode<String> StringAdd(Node* context, TNode<String> first, - TNode<String> second); - - // Check if |string| is an indirect (thin or flat cons) string type that can - // be dereferenced by DerefIndirectString. - void BranchIfCanDerefIndirectString(TNode<String> string, - TNode<Int32T> instance_type, - Label* can_deref, Label* cannot_deref); - // Unpack an indirect (thin or flat cons) string type. - void DerefIndirectString(TVariable<String>* var_string, - TNode<Int32T> instance_type); - // Check if |var_string| has an indirect (thin or flat cons) string type, - // and unpack it if so. - void MaybeDerefIndirectString(TVariable<String>* var_string, - TNode<Int32T> instance_type, Label* did_deref, - Label* cannot_deref); - // Check if |var_left| or |var_right| has an indirect (thin or flat cons) - // string type, and unpack it/them if so. Fall through if nothing was done. - void MaybeDerefIndirectStrings(TVariable<String>* var_left, - TNode<Int32T> left_instance_type, - TVariable<String>* var_right, - TNode<Int32T> right_instance_type, - Label* did_something); - TNode<String> DerefIndirectString(TNode<String> string, - TNode<Int32T> instance_type, - Label* cannot_deref); - - TNode<String> StringFromSingleUTF16EncodedCodePoint(TNode<Int32T> codepoint); - // Type conversion helpers. enum class BigIntHandling { kConvertToNumber, kThrow }; // Convert a String to a Number. TNode<Number> StringToNumber(TNode<String> input); // Convert a Number to a String. TNode<String> NumberToString(TNode<Number> input); + TNode<String> NumberToString(TNode<Number> input, Label* bailout); + // Convert a Non-Number object to a Number. TNode<Number> NonNumberToNumber( SloppyTNode<Context> context, SloppyTNode<HeapObject> input, @@ -2715,6 +2752,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler return Word32Equal(Word32And(word32, const_mask), const_mask); } + // Returns true if the bit field |BitField| in |word32| is equal to a given. + // constant |value|. Avoids a shift compared to using DecodeWord32. + template <typename BitField> + TNode<BoolT> IsEqualInWord32(TNode<Word32T> word32, + typename BitField::FieldType value) { + TNode<Word32T> masked_word32 = + Word32And(word32, Int32Constant(BitField::kMask)); + return Word32Equal(masked_word32, Int32Constant(BitField::encode(value))); + } + // Returns true if any of the |T|'s bits in given |word| are set. template <typename T> TNode<BoolT> IsSetWord(SloppyTNode<WordT> word) { @@ -2730,9 +2777,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Smi-encoding of the mask is performed implicitly! TNode<BoolT> IsSetSmi(SloppyTNode<Smi> smi, int untagged_mask) { intptr_t mask_word = bit_cast<intptr_t>(Smi::FromInt(untagged_mask)); - return WordNotEqual( - WordAnd(BitcastTaggedSignedToWord(smi), IntPtrConstant(mask_word)), - IntPtrConstant(0)); + return WordNotEqual(WordAnd(BitcastTaggedToWordForTagAndSmiBits(smi), + IntPtrConstant(mask_word)), + IntPtrConstant(0)); } // Returns true if all of the |T|'s bits in given |word32| are clear. @@ -2762,11 +2809,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler void IncrementCounter(StatsCounter* counter, int delta); void DecrementCounter(StatsCounter* counter, int delta); - void Increment(Variable* variable, int value = 1, - ParameterMode mode = INTPTR_PARAMETERS); - void Decrement(Variable* variable, int value = 1, - ParameterMode mode = INTPTR_PARAMETERS) { - Increment(variable, -value, mode); + template <typename TIndex> + void Increment(TVariable<TIndex>* variable, int value = 1); + + template <typename TIndex> + void Decrement(TVariable<TIndex>* variable, int value = 1) { + Increment(variable, -value); } // Generates "if (false) goto label" code. Useful for marking a label as @@ -2780,8 +2828,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Note: If |key| does not yet have a hash, |if_notinternalized| will be taken // even if |key| is an array index. |if_keyisunique| will never // be taken for array indices. - void TryToName(Node* key, Label* if_keyisindex, Variable* var_index, - Label* if_keyisunique, Variable* var_unique, Label* if_bailout, + void TryToName(SloppyTNode<Object> key, Label* if_keyisindex, + TVariable<IntPtrT>* var_index, Label* if_keyisunique, + TVariable<Name>* var_unique, Label* if_bailout, Label* if_notinternalized = nullptr); // Performs a hash computation and string table lookup for the given string, @@ -2793,8 +2842,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // - |if_not_internalized| if the string is not in the string table (but // does not add it). // - |if_bailout| for unsupported cases (e.g. uncachable array index). - void TryInternalizeString(Node* string, Label* if_index, Variable* var_index, - Label* if_internalized, Variable* var_internalized, + void TryInternalizeString(SloppyTNode<String> string, Label* if_index, + TVariable<IntPtrT>* var_index, + Label* if_internalized, + TVariable<Name>* var_internalized, Label* if_not_internalized, Label* if_bailout); // Calculates array index for given dictionary entry and entry field. @@ -2938,10 +2989,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Object> BasicLoadNumberDictionaryElement( TNode<NumberDictionary> dictionary, TNode<IntPtrT> intptr_index, Label* not_data, Label* if_hole); - void BasicStoreNumberDictionaryElement(TNode<NumberDictionary> dictionary, - TNode<IntPtrT> intptr_index, - TNode<Object> value, Label* not_data, - Label* if_hole, Label* read_only); template <class Dictionary> void FindInsertionEntry(TNode<Dictionary> dictionary, TNode<Name> key, @@ -3053,7 +3100,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // // Note: this code does not check if the global dictionary points to deleted // entry! This has to be done by the caller. - void TryLookupProperty(SloppyTNode<JSObject> object, SloppyTNode<Map> map, + void TryLookupProperty(SloppyTNode<JSReceiver> object, SloppyTNode<Map> map, SloppyTNode<Int32T> instance_type, SloppyTNode<Name> unique_name, Label* if_found_fast, Label* if_found_dict, Label* if_found_global, @@ -3113,10 +3160,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Returns true if {object} has {prototype} somewhere in it's prototype // chain, otherwise false is returned. Might cause arbitrary side effects // due to [[GetPrototypeOf]] invocations. - Node* HasInPrototypeChain(Node* context, Node* object, - SloppyTNode<Object> prototype); + TNode<Oddball> HasInPrototypeChain(TNode<Context> context, + TNode<HeapObject> object, + TNode<Object> prototype); // ES6 section 7.3.19 OrdinaryHasInstance (C, O) - Node* OrdinaryHasInstance(Node* context, Node* callable, Node* object); + TNode<Oddball> OrdinaryHasInstance(TNode<Context> context, + TNode<Object> callable, + TNode<Object> object); // Load type feedback vector from the stub caller's frame. TNode<FeedbackVector> LoadFeedbackVectorForStub(); @@ -3137,12 +3187,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler SloppyTNode<JSFunction> closure); // Update the type feedback vector. - void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id); + void UpdateFeedback(TNode<Smi> feedback, + TNode<HeapObject> maybe_feedback_vector, + TNode<UintPtrT> slot_id); // Report that there was a feedback update, performing any tasks that should // be done after a feedback update. - void ReportFeedbackUpdate(SloppyTNode<FeedbackVector> feedback_vector, - SloppyTNode<IntPtrT> slot_id, const char* reason); + void ReportFeedbackUpdate(TNode<FeedbackVector> feedback_vector, + SloppyTNode<UintPtrT> slot_id, const char* reason); // Combine the new feedback with the existing_feedback. Do nothing if // existing_feedback is nullptr. @@ -3185,8 +3237,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler TNode<Context> LoadScriptContext(TNode<Context> context, TNode<IntPtrT> context_index); - Node* Int32ToUint8Clamped(Node* int32_value); - Node* Float64ToUint8Clamped(Node* float64_value); + TNode<Uint8T> Int32ToUint8Clamped(TNode<Int32T> int32_value); + TNode<Uint8T> Float64ToUint8Clamped(TNode<Float64T> float64_value); Node* PrepareValueForWriteToTypedArray(TNode<Object> input, ElementsKind elements_kind, @@ -3229,13 +3281,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Store a weak in-place reference into the FeedbackVector. TNode<MaybeObject> StoreWeakReferenceInFeedbackVector( - SloppyTNode<FeedbackVector> feedback_vector, Node* slot, - SloppyTNode<HeapObject> value, int additional_offset = 0, - ParameterMode parameter_mode = INTPTR_PARAMETERS); + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot, + TNode<HeapObject> value, int additional_offset = 0); // Create a new AllocationSite and install it into a feedback vector. TNode<AllocationSite> CreateAllocationSiteInFeedbackVector( - SloppyTNode<FeedbackVector> feedback_vector, TNode<Smi> slot); + TNode<FeedbackVector> feedback_vector, TNode<UintPtrT> slot); // TODO(ishell, cbruni): Change to HasBoilerplate. TNode<BoolT> NotHasBoilerplate(TNode<Object> maybe_literal_site); @@ -3245,19 +3296,22 @@ class V8_EXPORT_PRIVATE CodeStubAssembler enum class IndexAdvanceMode { kPre, kPost }; - using FastLoopBody = std::function<void(Node* index)>; + template <typename TIndex> + using FastLoopBody = std::function<void(TNode<TIndex> index)>; - Node* BuildFastLoop(const VariableList& var_list, Node* start_index, - Node* end_index, const FastLoopBody& body, int increment, - ParameterMode parameter_mode, - IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre); + template <typename TIndex> + TNode<TIndex> BuildFastLoop( + const VariableList& var_list, TNode<TIndex> start_index, + TNode<TIndex> end_index, const FastLoopBody<TIndex>& body, int increment, + IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre); - Node* BuildFastLoop(Node* start_index, Node* end_index, - const FastLoopBody& body, int increment, - ParameterMode parameter_mode, - IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) { + template <typename TIndex> + TNode<TIndex> BuildFastLoop( + TNode<TIndex> start_index, TNode<TIndex> end_index, + const FastLoopBody<TIndex>& body, int increment, + IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) { return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body, - increment, parameter_mode, advance_mode); + increment, advance_mode); } enum class ForEachDirection { kForward, kReverse }; @@ -3304,13 +3358,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Label* doesnt_fit, int base_size, ParameterMode mode); - void InitializeFieldsWithRoot(Node* object, Node* start_offset, - Node* end_offset, RootIndex root); + void InitializeFieldsWithRoot(TNode<HeapObject> object, + TNode<IntPtrT> start_offset, + TNode<IntPtrT> end_offset, RootIndex root); - Node* RelationalComparison(Operation op, SloppyTNode<Object> left, - SloppyTNode<Object> right, - SloppyTNode<Context> context, - Variable* var_type_feedback = nullptr); + TNode<Oddball> RelationalComparison( + Operation op, TNode<Object> left, TNode<Object> right, + TNode<Context> context, TVariable<Smi>* var_type_feedback = nullptr); void BranchIfNumberRelationalComparison(Operation op, SloppyTNode<Number> left, @@ -3360,12 +3414,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler void GotoIfNumberGreaterThanOrEqual(Node* left, Node* right, Label* if_false); - Node* Equal(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs, - SloppyTNode<Context> context, - Variable* var_type_feedback = nullptr); + TNode<Oddball> Equal(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs, + SloppyTNode<Context> context, + TVariable<Smi>* var_type_feedback = nullptr); TNode<Oddball> StrictEqual(SloppyTNode<Object> lhs, SloppyTNode<Object> rhs, - Variable* var_type_feedback = nullptr); + TVariable<Smi>* var_type_feedback = nullptr); // ECMA#sec-samevalue // Similar to StrictEqual except that NaNs are treated as equal and minus zero @@ -3395,16 +3449,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler HasPropertyLookupMode::kHasProperty); } - Node* Typeof(Node* value); + TNode<String> Typeof(SloppyTNode<Object> value); - TNode<Object> GetSuperConstructor(SloppyTNode<Context> context, - SloppyTNode<JSFunction> active_function); + TNode<Object> GetSuperConstructor(TNode<Context> context, + TNode<JSFunction> active_function); TNode<JSReceiver> SpeciesConstructor( SloppyTNode<Context> context, SloppyTNode<Object> object, SloppyTNode<JSReceiver> default_constructor); - Node* InstanceOf(Node* object, Node* callable, Node* context); + TNode<Oddball> InstanceOf(TNode<Object> object, TNode<Object> callable, + TNode<Context> context); // Debug helpers Node* IsDebugActive(); @@ -3431,8 +3486,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // JSTypedArray helpers TNode<UintPtrT> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array); - TNode<RawPtrT> LoadJSTypedArrayBackingStore(TNode<JSTypedArray> typed_array); + TNode<RawPtrT> LoadJSTypedArrayDataPtr(TNode<JSTypedArray> typed_array); + template <typename TIndex> + TNode<IntPtrT> ElementOffsetFromIndex(TNode<TIndex> index, ElementsKind kind, + int base_size = 0); + // TODO(v8:9708): remove once all uses are ported. TNode<IntPtrT> ElementOffsetFromIndex(Node* index, ElementsKind kind, ParameterMode mode, int base_size = 0); @@ -3451,8 +3510,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler SloppyTNode<SharedFunctionInfo> shared_info, Label* if_compile_lazy = nullptr); - Node* AllocateFunctionWithMapAndContext(Node* map, Node* shared_info, - Node* context); + TNode<JSFunction> AllocateFunctionWithMapAndContext( + TNode<Map> map, TNode<SharedFunctionInfo> shared_info, + TNode<Context> context); // Promise helpers Node* IsPromiseHookEnabled(); @@ -3463,7 +3523,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // for..in helpers void CheckPrototypeEnumCache(Node* receiver, Node* receiver_map, Label* if_fast, Label* if_slow); - Node* CheckEnumCache(Node* receiver, Label* if_empty, Label* if_runtime); + TNode<Map> CheckEnumCache(TNode<HeapObject> receiver, Label* if_empty, + Label* if_runtime); TNode<Object> GetArgumentValue(TorqueStructArguments args, TNode<IntPtrT> index); @@ -3620,11 +3681,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Node* receiver, Label* if_bailout, GetOwnPropertyMode mode = kCallJSGetter); - TNode<IntPtrT> TryToIntptr(Node* key, Label* miss); - - void BranchIfPrototypesHaveNoElements(Node* receiver_map, - Label* definitely_no_elements, - Label* possibly_elements); + TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* miss); void InitializeFunctionContext(Node* native_context, Node* context, int slots); @@ -3655,13 +3712,18 @@ class V8_EXPORT_PRIVATE CodeStubAssembler // Allocate and return a JSArray of given total size in bytes with header // fields initialized. - TNode<JSArray> AllocateUninitializedJSArray(TNode<Map> array_map, - TNode<Smi> length, - Node* allocation_site, - TNode<IntPtrT> size_in_bytes); + TNode<JSArray> AllocateUninitializedJSArray( + TNode<Map> array_map, TNode<Smi> length, + TNode<AllocationSite> allocation_site, TNode<IntPtrT> size_in_bytes); TNode<BoolT> IsValidSmi(TNode<Smi> smi); - Node* SmiShiftBitsConstant(); + + TNode<IntPtrT> SmiShiftBitsConstant() { + return IntPtrConstant(kSmiShiftSize + kSmiTagSize); + } + TNode<Int32T> SmiShiftBitsConstant32() { + return Int32Constant(kSmiShiftSize + kSmiTagSize); + } // Emits keyed sloppy arguments load if the |value| is nullptr or store // otherwise. Returns either the loaded value or |value|. @@ -3689,10 +3751,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler void GenerateEqual_Same(SloppyTNode<Object> value, Label* if_equal, Label* if_notequal, Variable* var_type_feedback = nullptr); - TNode<String> AllocAndCopyStringCharacters(Node* from, - Node* from_instance_type, - TNode<IntPtrT> from_index, - TNode<IntPtrT> character_count); static const int kElementLoopUnrollThreshold = 8; @@ -3705,11 +3763,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler Variable* var_numeric, Variable* var_feedback); template <Object::Conversion conversion> - void TaggedToWord32OrBigIntImpl(Node* context, Node* value, Label* if_number, - Variable* var_word32, + void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value, + Label* if_number, + TVariable<Word32T>* var_word32, Label* if_bigint = nullptr, - Variable* var_bigint = nullptr, - Variable* var_feedback = nullptr); + TVariable<Object>* var_maybe_bigint = nullptr, + TVariable<Smi>* var_feedback = nullptr); private: // Low-level accessors for Descriptor arrays. @@ -3727,36 +3786,48 @@ class V8_EXPORT_PRIVATE CodeStubAssembler } }; +// template <typename TIndex> class V8_EXPORT_PRIVATE CodeStubArguments { public: using Node = compiler::Node; - template <class T> - using TNode = compiler::TNode<T>; - template <class T> - using SloppyTNode = compiler::SloppyTNode<T>; enum ReceiverMode { kHasReceiver, kNoReceiver }; - // |argc| is an intptr value which specifies the number of arguments passed - // to the builtin excluding the receiver. The arguments will include a - // receiver iff |receiver_mode| is kHasReceiver. - CodeStubArguments(CodeStubAssembler* assembler, Node* argc, + // |argc| specifies the number of arguments passed to the builtin excluding + // the receiver. The arguments will include a receiver iff |receiver_mode| + // is kHasReceiver. + CodeStubArguments(CodeStubAssembler* assembler, TNode<IntPtrT> argc, ReceiverMode receiver_mode = ReceiverMode::kHasReceiver) - : CodeStubArguments(assembler, argc, nullptr, - CodeStubAssembler::INTPTR_PARAMETERS, receiver_mode) { - } + : CodeStubArguments(assembler, argc, TNode<RawPtrT>(), receiver_mode) {} + + CodeStubArguments(CodeStubAssembler* assembler, TNode<Int32T> argc, + ReceiverMode receiver_mode = ReceiverMode::kHasReceiver) + : CodeStubArguments(assembler, assembler->ChangeInt32ToIntPtr(argc), + TNode<RawPtrT>(), receiver_mode) {} - // |argc| is either a smi or intptr depending on |param_mode|. The arguments - // include a receiver iff |receiver_mode| is kHasReceiver. - CodeStubArguments(CodeStubAssembler* assembler, Node* argc, Node* fp, - CodeStubAssembler::ParameterMode param_mode, + // TODO(v8:9708): Consider removing this variant + CodeStubArguments(CodeStubAssembler* assembler, TNode<Smi> argc, + ReceiverMode receiver_mode = ReceiverMode::kHasReceiver) + : CodeStubArguments(assembler, assembler->ParameterToIntPtr(argc), + TNode<RawPtrT>(), receiver_mode) {} + + // |argc| specifies the number of arguments passed to the builtin excluding + // the receiver. The arguments will include a receiver iff |receiver_mode| + // is kHasReceiver. + CodeStubArguments(CodeStubAssembler* assembler, TNode<IntPtrT> argc, + TNode<RawPtrT> fp, ReceiverMode receiver_mode = ReceiverMode::kHasReceiver); + CodeStubArguments(CodeStubAssembler* assembler, TNode<Smi> argc, + TNode<RawPtrT> fp, + ReceiverMode receiver_mode = ReceiverMode::kHasReceiver) + : CodeStubArguments(assembler, assembler->ParameterToIntPtr(argc), fp, + receiver_mode) {} + // Used by Torque to construct arguments based on a Torque-defined // struct of values. CodeStubArguments(CodeStubAssembler* assembler, TorqueStructArguments torque_arguments) : assembler_(assembler), - argc_mode_(CodeStubAssembler::INTPTR_PARAMETERS), receiver_mode_(ReceiverMode::kHasReceiver), argc_(torque_arguments.length), base_(torque_arguments.base), @@ -3769,14 +3840,17 @@ class V8_EXPORT_PRIVATE CodeStubArguments { void SetReceiver(TNode<Object> object) const; // Computes address of the index'th argument. - TNode<WordT> AtIndexPtr(Node* index, - CodeStubAssembler::ParameterMode mode = - CodeStubAssembler::INTPTR_PARAMETERS) const; + TNode<RawPtrT> AtIndexPtr(TNode<IntPtrT> index) const; + TNode<RawPtrT> AtIndexPtr(TNode<Smi> index) const { + return AtIndexPtr(assembler_->ParameterToIntPtr(index)); + } // |index| is zero-based and does not include the receiver - TNode<Object> AtIndex(Node* index, - CodeStubAssembler::ParameterMode mode = - CodeStubAssembler::INTPTR_PARAMETERS) const; + TNode<Object> AtIndex(TNode<IntPtrT> index) const; + // TODO(v8:9708): Consider removing this variant + TNode<Object> AtIndex(TNode<Smi> index) const { + return AtIndex(assembler_->ParameterToIntPtr(index)); + } TNode<Object> AtIndex(int index) const; @@ -3786,15 +3860,10 @@ class V8_EXPORT_PRIVATE CodeStubArguments { TNode<Object> GetOptionalArgumentValue(int index, TNode<Object> default_value); - Node* GetLength(CodeStubAssembler::ParameterMode mode) const { - DCHECK_EQ(mode, argc_mode_); - return argc_; - } + TNode<IntPtrT> GetLength() const { return argc_; } TorqueStructArguments GetTorqueArguments() const { - DCHECK_EQ(argc_mode_, CodeStubAssembler::INTPTR_PARAMETERS); - return TorqueStructArguments{assembler_->UncheckedCast<RawPtrT>(fp_), base_, - assembler_->UncheckedCast<IntPtrT>(argc_)}; + return TorqueStructArguments{fp_, base_, argc_}; } TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index) { @@ -3802,28 +3871,32 @@ class V8_EXPORT_PRIVATE CodeStubArguments { } TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index, TNode<Object> default_value); - TNode<IntPtrT> GetLength() const { - DCHECK_EQ(argc_mode_, CodeStubAssembler::INTPTR_PARAMETERS); - return assembler_->UncheckedCast<IntPtrT>(argc_); - } - using ForEachBodyFunction = std::function<void(Node* arg)>; + using ForEachBodyFunction = std::function<void(TNode<Object> arg)>; // Iteration doesn't include the receiver. |first| and |last| are zero-based. - void ForEach(const ForEachBodyFunction& body, Node* first = nullptr, - Node* last = nullptr, - CodeStubAssembler::ParameterMode mode = - CodeStubAssembler::INTPTR_PARAMETERS) { + template <typename TIndex> + void ForEach(const ForEachBodyFunction& body, TNode<TIndex> first = {}, + TNode<TIndex> last = {}) const { CodeStubAssembler::VariableList list(0, assembler_->zone()); ForEach(list, body, first, last); } // Iteration doesn't include the receiver. |first| and |last| are zero-based. void ForEach(const CodeStubAssembler::VariableList& vars, - const ForEachBodyFunction& body, Node* first = nullptr, - Node* last = nullptr, - CodeStubAssembler::ParameterMode mode = - CodeStubAssembler::INTPTR_PARAMETERS); + const ForEachBodyFunction& body, TNode<IntPtrT> first = {}, + TNode<IntPtrT> last = {}) const; + + void ForEach(const CodeStubAssembler::VariableList& vars, + const ForEachBodyFunction& body, TNode<Smi> first, + TNode<Smi> last = {}) const { + TNode<IntPtrT> first_intptr = assembler_->ParameterToIntPtr(first); + TNode<IntPtrT> last_intptr; + if (last != nullptr) { + last_intptr = assembler_->ParameterToIntPtr(last); + } + return ForEach(vars, body, first_intptr, last_intptr); + } void PopAndReturn(Node* value); @@ -3831,11 +3904,10 @@ class V8_EXPORT_PRIVATE CodeStubArguments { Node* GetArguments(); CodeStubAssembler* assembler_; - CodeStubAssembler::ParameterMode argc_mode_; ReceiverMode receiver_mode_; - Node* argc_; + TNode<IntPtrT> argc_; TNode<RawPtrT> base_; - Node* fp_; + TNode<RawPtrT> fp_; }; class ToDirectStringAssembler : public CodeStubAssembler { diff --git a/deps/v8/src/codegen/compilation-cache.cc b/deps/v8/src/codegen/compilation-cache.cc index 6e9613005e71a5..ef3d83a06eb88a 100644 --- a/deps/v8/src/codegen/compilation-cache.cc +++ b/deps/v8/src/codegen/compilation-cache.cc @@ -28,7 +28,7 @@ CompilationCache::CompilationCache(Isolate* isolate) eval_global_(isolate), eval_contextual_(isolate), reg_exp_(isolate, kRegExpGenerations), - enabled_(true) { + enabled_script_and_eval_(true) { CompilationSubCache* subcaches[kSubCacheCount] = { &script_, &eval_global_, &eval_contextual_, ®_exp_}; for (int i = 0; i < kSubCacheCount; ++i) { @@ -254,7 +254,7 @@ void CompilationCacheRegExp::Put(Handle<String> source, JSRegExp::Flags flags, } void CompilationCache::Remove(Handle<SharedFunctionInfo> function_info) { - if (!IsEnabled()) return; + if (!IsEnabledScriptAndEval()) return; eval_global_.Remove(function_info); eval_contextual_.Remove(function_info); @@ -265,7 +265,7 @@ MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript( Handle<String> source, MaybeHandle<Object> name, int line_offset, int column_offset, ScriptOriginOptions resource_options, Handle<Context> native_context, LanguageMode language_mode) { - if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>(); + if (!IsEnabledScriptAndEval()) return MaybeHandle<SharedFunctionInfo>(); return script_.Lookup(source, name, line_offset, column_offset, resource_options, native_context, language_mode); @@ -277,7 +277,7 @@ InfoCellPair CompilationCache::LookupEval(Handle<String> source, LanguageMode language_mode, int position) { InfoCellPair result; - if (!IsEnabled()) return result; + if (!IsEnabledScriptAndEval()) return result; const char* cache_type; @@ -303,8 +303,6 @@ InfoCellPair CompilationCache::LookupEval(Handle<String> source, MaybeHandle<FixedArray> CompilationCache::LookupRegExp(Handle<String> source, JSRegExp::Flags flags) { - if (!IsEnabled()) return MaybeHandle<FixedArray>(); - return reg_exp_.Lookup(source, flags); } @@ -312,7 +310,7 @@ void CompilationCache::PutScript(Handle<String> source, Handle<Context> native_context, LanguageMode language_mode, Handle<SharedFunctionInfo> function_info) { - if (!IsEnabled()) return; + if (!IsEnabledScriptAndEval()) return; LOG(isolate(), CompilationCacheEvent("put", "script", *function_info)); script_.Put(source, native_context, language_mode, function_info); @@ -324,7 +322,7 @@ void CompilationCache::PutEval(Handle<String> source, Handle<SharedFunctionInfo> function_info, Handle<FeedbackCell> feedback_cell, int position) { - if (!IsEnabled()) return; + if (!IsEnabledScriptAndEval()) return; const char* cache_type; HandleScope scope(isolate()); @@ -344,8 +342,6 @@ void CompilationCache::PutEval(Handle<String> source, void CompilationCache::PutRegExp(Handle<String> source, JSRegExp::Flags flags, Handle<FixedArray> data) { - if (!IsEnabled()) return; - reg_exp_.Put(source, flags, data); } @@ -367,10 +363,12 @@ void CompilationCache::MarkCompactPrologue() { } } -void CompilationCache::Enable() { enabled_ = true; } +void CompilationCache::EnableScriptAndEval() { + enabled_script_and_eval_ = true; +} -void CompilationCache::Disable() { - enabled_ = false; +void CompilationCache::DisableScriptAndEval() { + enabled_script_and_eval_ = false; Clear(); } diff --git a/deps/v8/src/codegen/compilation-cache.h b/deps/v8/src/codegen/compilation-cache.h index 35595b19858510..04bea44a82b36e 100644 --- a/deps/v8/src/codegen/compilation-cache.h +++ b/deps/v8/src/codegen/compilation-cache.h @@ -202,9 +202,14 @@ class V8_EXPORT_PRIVATE CompilationCache { void MarkCompactPrologue(); // Enable/disable compilation cache. Used by debugger to disable compilation - // cache during debugging to make sure new scripts are always compiled. - void Enable(); - void Disable(); + // cache during debugging so that eval and new scripts are always compiled. + // TODO(bmeurer, chromium:992277): The RegExp cache cannot be enabled and/or + // disabled, since it doesn't affect debugging. However ideally the other + // caches should also be always on, even in the presence of the debugger, + // but at this point there are too many unclear invariants, and so I decided + // to just fix the pressing performance problem for RegExp individually first. + void EnableScriptAndEval(); + void DisableScriptAndEval(); private: explicit CompilationCache(Isolate* isolate); @@ -215,7 +220,9 @@ class V8_EXPORT_PRIVATE CompilationCache { // The number of sub caches covering the different types to cache. static const int kSubCacheCount = 4; - bool IsEnabled() const { return FLAG_compilation_cache && enabled_; } + bool IsEnabledScriptAndEval() const { + return FLAG_compilation_cache && enabled_script_and_eval_; + } Isolate* isolate() const { return isolate_; } @@ -227,8 +234,8 @@ class V8_EXPORT_PRIVATE CompilationCache { CompilationCacheRegExp reg_exp_; CompilationSubCache* subcaches_[kSubCacheCount]; - // Current enable state of the compilation cache. - bool enabled_; + // Current enable state of the compilation cache for scripts and eval. + bool enabled_script_and_eval_; friend class Isolate; diff --git a/deps/v8/src/codegen/compiler.cc b/deps/v8/src/codegen/compiler.cc index fbd181f5c8eeb1..d73be13a30a7d6 100644 --- a/deps/v8/src/codegen/compiler.cc +++ b/deps/v8/src/codegen/compiler.cc @@ -666,21 +666,25 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Code> GetCodeFromOptimizedCodeCache( function->GetIsolate(), RuntimeCallCounterId::kCompileGetFromOptimizedCodeMap); Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate()); + Isolate* isolate = function->GetIsolate(); DisallowHeapAllocation no_gc; - if (osr_offset.IsNone()) { - if (function->has_feedback_vector()) { - FeedbackVector feedback_vector = function->feedback_vector(); - feedback_vector.EvictOptimizedCodeMarkedForDeoptimization( - function->shared(), "GetCodeFromOptimizedCodeCache"); - Code code = feedback_vector.optimized_code(); - - if (!code.is_null()) { - // Caching of optimized code enabled and optimized code found. - DCHECK(!code.marked_for_deoptimization()); - DCHECK(function->shared().is_compiled()); - return Handle<Code>(code, feedback_vector.GetIsolate()); - } - } + Code code; + if (osr_offset.IsNone() && function->has_feedback_vector()) { + FeedbackVector feedback_vector = function->feedback_vector(); + feedback_vector.EvictOptimizedCodeMarkedForDeoptimization( + function->shared(), "GetCodeFromOptimizedCodeCache"); + code = feedback_vector.optimized_code(); + } else if (!osr_offset.IsNone()) { + code = function->context() + .native_context() + .GetOSROptimizedCodeCache() + .GetOptimizedCode(shared, osr_offset, isolate); + } + if (!code.is_null()) { + // Caching of optimized code enabled and optimized code found. + DCHECK(!code.marked_for_deoptimization()); + DCHECK(function->shared().is_compiled()); + return Handle<Code>(code, isolate); } return MaybeHandle<Code>(); } @@ -711,12 +715,15 @@ void InsertCodeIntoOptimizedCodeCache( // Cache optimized context-specific code. Handle<JSFunction> function = compilation_info->closure(); Handle<SharedFunctionInfo> shared(function->shared(), function->GetIsolate()); - Handle<Context> native_context(function->context().native_context(), - function->GetIsolate()); + Handle<NativeContext> native_context(function->context().native_context(), + function->GetIsolate()); if (compilation_info->osr_offset().IsNone()) { Handle<FeedbackVector> vector = handle(function->feedback_vector(), function->GetIsolate()); FeedbackVector::SetOptimizedCode(vector, code); + } else { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + compilation_info->osr_offset()); } } @@ -1904,6 +1911,12 @@ struct ScriptCompileTimerScope { case CacheBehaviour::kConsumeCodeCache: return isolate_->counters()->compile_script_with_consume_cache(); + // Note that this only counts the finalization part of streaming, the + // actual streaming compile is counted by BackgroundCompileTask into + // "compile_script_on_background". + case CacheBehaviour::kNoCacheBecauseStreamingSource: + return isolate_->counters()->compile_script_streaming_finalization(); + case CacheBehaviour::kNoCacheBecauseInlineScript: return isolate_->counters() ->compile_script_no_cache_because_inline_script(); @@ -1923,9 +1936,6 @@ struct ScriptCompileTimerScope { // TODO(leszeks): Consider counting separately once modules are more // common. case CacheBehaviour::kNoCacheBecauseModule: - // TODO(leszeks): Count separately or remove entirely once we have - // background compilation. - case CacheBehaviour::kNoCacheBecauseStreamingSource: case CacheBehaviour::kNoCacheBecauseV8Extension: case CacheBehaviour::kNoCacheBecauseExtensionModule: case CacheBehaviour::kNoCacheBecausePacScript: diff --git a/deps/v8/src/codegen/constant-pool.cc b/deps/v8/src/codegen/constant-pool.cc index 6816c5b7ad580b..42b2fa6e9a0233 100644 --- a/deps/v8/src/codegen/constant-pool.cc +++ b/deps/v8/src/codegen/constant-pool.cc @@ -49,22 +49,22 @@ ConstantPoolEntry::Access ConstantPoolBuilder::NextAccess( } ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry( - ConstantPoolEntry& entry, ConstantPoolEntry::Type type) { + ConstantPoolEntry* entry, ConstantPoolEntry::Type type) { DCHECK(!emitted_label_.is_bound()); PerTypeEntryInfo& info = info_[type]; const int entry_size = ConstantPoolEntry::size(type); bool merged = false; - if (entry.sharing_ok()) { + if (entry->sharing_ok()) { // Try to merge entries std::vector<ConstantPoolEntry>::iterator it = info.shared_entries.begin(); int end = static_cast<int>(info.shared_entries.size()); for (int i = 0; i < end; i++, it++) { if ((entry_size == kSystemPointerSize) - ? entry.value() == it->value() - : entry.value64() == it->value64()) { + ? entry->value() == it->value() + : entry->value64() == it->value64()) { // Merge with found entry. - entry.set_merged_index(i); + entry->set_merged_index(i); merged = true; break; } @@ -72,16 +72,16 @@ ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry( } // By definition, merged entries have regular access. - DCHECK(!merged || entry.merged_index() < info.regular_count); + DCHECK(!merged || entry->merged_index() < info.regular_count); ConstantPoolEntry::Access access = (merged ? ConstantPoolEntry::REGULAR : NextAccess(type)); // Enforce an upper bound on search time by limiting the search to // unique sharable entries which fit in the regular section. - if (entry.sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) { - info.shared_entries.push_back(entry); + if (entry->sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) { + info.shared_entries.push_back(*entry); } else { - info.entries.push_back(entry); + info.entries.push_back(*entry); } // We're done if we found a match or have already triggered the diff --git a/deps/v8/src/codegen/constant-pool.h b/deps/v8/src/codegen/constant-pool.h index d07452336b4e40..d2ab5641aea07f 100644 --- a/deps/v8/src/codegen/constant-pool.h +++ b/deps/v8/src/codegen/constant-pool.h @@ -102,13 +102,13 @@ class ConstantPoolBuilder { ConstantPoolEntry::Access AddEntry(int position, intptr_t value, bool sharing_ok) { ConstantPoolEntry entry(position, value, sharing_ok); - return AddEntry(entry, ConstantPoolEntry::INTPTR); + return AddEntry(&entry, ConstantPoolEntry::INTPTR); } // Add double constant to the embedded constant pool ConstantPoolEntry::Access AddEntry(int position, Double value) { ConstantPoolEntry entry(position, value); - return AddEntry(entry, ConstantPoolEntry::DOUBLE); + return AddEntry(&entry, ConstantPoolEntry::DOUBLE); } // Add double constant to the embedded constant pool @@ -138,9 +138,8 @@ class ConstantPoolBuilder { inline Label* EmittedPosition() { return &emitted_label_; } private: - ConstantPoolEntry::Access AddEntry( - ConstantPoolEntry& entry, // NOLINT(runtime/references) - ConstantPoolEntry::Type type); + ConstantPoolEntry::Access AddEntry(ConstantPoolEntry* entry, + ConstantPoolEntry::Type type); void EmitSharedEntries(Assembler* assm, ConstantPoolEntry::Type type); void EmitGroup(Assembler* assm, ConstantPoolEntry::Access access, ConstantPoolEntry::Type type); diff --git a/deps/v8/src/codegen/cpu-features.h b/deps/v8/src/codegen/cpu-features.h index dae9992c57f6c1..6b3d3934d0c111 100644 --- a/deps/v8/src/codegen/cpu-features.h +++ b/deps/v8/src/codegen/cpu-features.h @@ -13,7 +13,7 @@ namespace internal { // CPU feature flags. enum CpuFeature { - // x86 +#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 SSE4_2, SSE4_1, SSSE3, @@ -26,39 +26,46 @@ enum CpuFeature { LZCNT, POPCNT, ATOM, - // ARM + +#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 // - Standard configurations. The baseline is ARMv6+VFPv2. ARMv7, // ARMv7-A + VFPv3-D32 + NEON ARMv7_SUDIV, // ARMv7-A + VFPv4-D32 + NEON + SUDIV ARMv8, // ARMv8-A (+ all of the above) - // MIPS, MIPS64 + + // ARM feature aliases (based on the standard configurations above). + VFPv3 = ARMv7, + NEON = ARMv7, + VFP32DREGS = ARMv7, + SUDIV = ARMv7_SUDIV, + +#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 FPU, FP64FPU, MIPSr1, MIPSr2, MIPSr6, MIPS_SIMD, // MSA instructions - // PPC + +#elif V8_TARGET_ARCH_PPC + FPU, FPR_GPR_MOV, LWSYNC, ISELECT, VSX, MODULO, - // S390 + +#elif V8_TARGET_ARCH_S390X + FPU, DISTINCT_OPS, GENERAL_INSTR_EXT, FLOATING_POINT_EXT, VECTOR_FACILITY, VECTOR_ENHANCE_FACILITY_1, MISC_INSTR_EXT2, +#endif - NUMBER_OF_CPU_FEATURES, - - // ARM feature aliases (based on the standard configurations above). - VFPv3 = ARMv7, - NEON = ARMv7, - VFP32DREGS = ARMv7, - SUDIV = ARMv7_SUDIV + NUMBER_OF_CPU_FEATURES }; // CpuFeatures keeps track of which features are supported by the target CPU. diff --git a/deps/v8/src/codegen/external-reference.cc b/deps/v8/src/codegen/external-reference.cc index 44503e532d1ed0..e1f873cb38d330 100644 --- a/deps/v8/src/codegen/external-reference.cc +++ b/deps/v8/src/codegen/external-reference.cc @@ -217,10 +217,8 @@ struct IsValidExternalReferenceType<Result (Class::*)(Args...)> { FUNCTION_REFERENCE(incremental_marking_record_write_function, IncrementalMarking::RecordWriteFromCode) -ExternalReference ExternalReference::store_buffer_overflow_function() { - return ExternalReference( - Redirect(Heap::store_buffer_overflow_function_address())); -} +FUNCTION_REFERENCE(insert_remembered_set_function, + Heap::InsertIntoRememberedSetFromCode) FUNCTION_REFERENCE(delete_handle_scope_extensions, HandleScope::DeleteExtensions) @@ -342,10 +340,6 @@ ExternalReference ExternalReference::address_of_real_jslimit(Isolate* isolate) { return ExternalReference(address); } -ExternalReference ExternalReference::store_buffer_top(Isolate* isolate) { - return ExternalReference(isolate->heap()->store_buffer_top_address()); -} - ExternalReference ExternalReference::heap_is_marking_flag_address( Isolate* isolate) { return ExternalReference(isolate->heap()->IsMarkingFlagAddress()); @@ -529,19 +523,19 @@ ExternalReference ExternalReference::address_of_regexp_stack_memory_top_address( FUNCTION_REFERENCE_WITH_TYPE(ieee754_acos_function, base::ieee754::acos, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_acosh_function, base::ieee754::acosh, - BUILTIN_FP_FP_CALL) + BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_asin_function, base::ieee754::asin, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_asinh_function, base::ieee754::asinh, - BUILTIN_FP_FP_CALL) + BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan_function, base::ieee754::atan, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_atanh_function, base::ieee754::atanh, - BUILTIN_FP_FP_CALL) + BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_atan2_function, base::ieee754::atan2, BUILTIN_FP_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_cbrt_function, base::ieee754::cbrt, - BUILTIN_FP_FP_CALL) + BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_cos_function, base::ieee754::cos, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_cosh_function, base::ieee754::cosh, @@ -549,7 +543,7 @@ FUNCTION_REFERENCE_WITH_TYPE(ieee754_cosh_function, base::ieee754::cosh, FUNCTION_REFERENCE_WITH_TYPE(ieee754_exp_function, base::ieee754::exp, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_expm1_function, base::ieee754::expm1, - BUILTIN_FP_FP_CALL) + BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_log_function, base::ieee754::log, BUILTIN_FP_CALL) FUNCTION_REFERENCE_WITH_TYPE(ieee754_log1p_function, base::ieee754::log1p, diff --git a/deps/v8/src/codegen/external-reference.h b/deps/v8/src/codegen/external-reference.h index 45c26bdfb091d5..7cc0241fc4a5f8 100644 --- a/deps/v8/src/codegen/external-reference.h +++ b/deps/v8/src/codegen/external-reference.h @@ -38,7 +38,6 @@ class StatsCounter; V(allocation_sites_list_address, "Heap::allocation_sites_list_address()") \ V(address_of_jslimit, "StackGuard::address_of_jslimit()") \ V(address_of_real_jslimit, "StackGuard::address_of_real_jslimit()") \ - V(store_buffer_top, "store_buffer_top") \ V(heap_is_marking_flag_address, "heap_is_marking_flag_address") \ V(new_space_allocation_top_address, "Heap::NewSpaceAllocationTopAddress()") \ V(new_space_allocation_limit_address, \ @@ -143,6 +142,7 @@ class StatsCounter; V(ieee754_tanh_function, "base::ieee754::tanh") \ V(incremental_marking_record_write_function, \ "IncrementalMarking::RecordWrite") \ + V(insert_remembered_set_function, "Heap::InsertIntoRememberedSetFromCode") \ V(invalidate_prototype_chains_function, \ "JSObject::InvalidatePrototypeChains()") \ V(invoke_accessor_getter_callback, "InvokeAccessorGetterCallback") \ @@ -170,7 +170,6 @@ class StatsCounter; V(search_string_raw_two_one, "search_string_raw_two_one") \ V(search_string_raw_two_two, "search_string_raw_two_two") \ V(smi_lexicographic_compare_function, "smi_lexicographic_compare_function") \ - V(store_buffer_overflow_function, "StoreBuffer::StoreBufferOverflow") \ V(try_internalize_string_function, "try_internalize_string_function") \ V(wasm_call_trap_callback_for_testing, \ "wasm::call_trap_callback_for_testing") \ diff --git a/deps/v8/src/codegen/ia32/assembler-ia32-inl.h b/deps/v8/src/codegen/ia32/assembler-ia32-inl.h index e274b41fa33b77..174a4838683df8 100644 --- a/deps/v8/src/codegen/ia32/assembler-ia32-inl.h +++ b/deps/v8/src/codegen/ia32/assembler-ia32-inl.h @@ -39,6 +39,7 @@ #include "src/codegen/ia32/assembler-ia32.h" +#include "src/base/memory.h" #include "src/codegen/assembler.h" #include "src/debug/debug.h" #include "src/objects/objects-inl.h" @@ -58,12 +59,12 @@ void RelocInfo::apply(intptr_t delta) { RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY))); if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_) || IsOffHeapTarget(rmode_)) { - int32_t* p = reinterpret_cast<int32_t*>(pc_); - *p -= delta; // Relocate entry. + base::WriteUnalignedValue(pc_, + base::ReadUnalignedValue<int32_t>(pc_) - delta); } else if (IsInternalReference(rmode_)) { - // absolute code pointer inside code object moves with the code object. - int32_t* p = reinterpret_cast<int32_t*>(pc_); - *p += delta; // Relocate entry. + // Absolute code pointer inside code object moves with the code object. + base::WriteUnalignedValue(pc_, + base::ReadUnalignedValue<int32_t>(pc_) + delta); } } @@ -103,7 +104,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, if (icache_flush_mode != SKIP_ICACHE_FLUSH) { FlushInstructionCache(pc_, sizeof(Address)); } - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/ia32/assembler-ia32.cc b/deps/v8/src/codegen/ia32/assembler-ia32.cc index aefcab7299c7c8..405e4b7c553fe1 100644 --- a/deps/v8/src/codegen/ia32/assembler-ia32.cc +++ b/deps/v8/src/codegen/ia32/assembler-ia32.cc @@ -272,8 +272,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle<HeapObject> object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); break; case HeapObjectRequest::kStringConstant: { const StringConstantBase* str = request.string(); @@ -2163,70 +2163,6 @@ void Assembler::divsd(XMMRegister dst, Operand src) { emit_sse_operand(dst, src); } -void Assembler::xorpd(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x66); - EMIT(0x0F); - EMIT(0x57); - emit_sse_operand(dst, src); -} - -void Assembler::andps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x54); - emit_sse_operand(dst, src); -} - -void Assembler::andnps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x55); - emit_sse_operand(dst, src); -} - -void Assembler::orps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x56); - emit_sse_operand(dst, src); -} - -void Assembler::xorps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x57); - emit_sse_operand(dst, src); -} - -void Assembler::addps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x58); - emit_sse_operand(dst, src); -} - -void Assembler::subps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x5C); - emit_sse_operand(dst, src); -} - -void Assembler::mulps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x59); - emit_sse_operand(dst, src); -} - -void Assembler::divps(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x0F); - EMIT(0x5E); - emit_sse_operand(dst, src); -} - void Assembler::rcpps(XMMRegister dst, Operand src) { EnsureSpace ensure_space(this); EMIT(0x0F); @@ -2234,29 +2170,31 @@ void Assembler::rcpps(XMMRegister dst, Operand src) { emit_sse_operand(dst, src); } -void Assembler::rsqrtps(XMMRegister dst, Operand src) { +void Assembler::sqrtps(XMMRegister dst, Operand src) { EnsureSpace ensure_space(this); EMIT(0x0F); - EMIT(0x52); + EMIT(0x51); emit_sse_operand(dst, src); } -void Assembler::minps(XMMRegister dst, Operand src) { +void Assembler::rsqrtps(XMMRegister dst, Operand src) { EnsureSpace ensure_space(this); EMIT(0x0F); - EMIT(0x5D); + EMIT(0x52); emit_sse_operand(dst, src); } -void Assembler::maxps(XMMRegister dst, Operand src) { +void Assembler::cmpps(XMMRegister dst, Operand src, uint8_t cmp) { EnsureSpace ensure_space(this); EMIT(0x0F); - EMIT(0x5F); + EMIT(0xC2); emit_sse_operand(dst, src); + EMIT(cmp); } -void Assembler::cmpps(XMMRegister dst, Operand src, uint8_t cmp) { +void Assembler::cmppd(XMMRegister dst, Operand src, uint8_t cmp) { EnsureSpace ensure_space(this); + EMIT(0x66); EMIT(0x0F); EMIT(0xC2); emit_sse_operand(dst, src); @@ -2280,22 +2218,6 @@ void Assembler::haddps(XMMRegister dst, Operand src) { emit_sse_operand(dst, src); } -void Assembler::andpd(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x66); - EMIT(0x0F); - EMIT(0x54); - emit_sse_operand(dst, src); -} - -void Assembler::orpd(XMMRegister dst, Operand src) { - EnsureSpace ensure_space(this); - EMIT(0x66); - EMIT(0x0F); - EMIT(0x56); - emit_sse_operand(dst, src); -} - void Assembler::ucomisd(XMMRegister dst, Operand src) { EnsureSpace ensure_space(this); EMIT(0x66); @@ -2398,6 +2320,16 @@ void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) { EMIT(imm8); } +void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) { + DCHECK(is_uint8(imm8)); + EnsureSpace ensure_space(this); + EMIT(0x66); + EMIT(0x0F); + EMIT(0xC6); + emit_sse_operand(dst, src); + EMIT(imm8); +} + void Assembler::movdqa(Operand dst, XMMRegister src) { EnsureSpace ensure_space(this); EMIT(0x66); @@ -2776,6 +2708,23 @@ void Assembler::minss(XMMRegister dst, Operand src) { emit_sse_operand(dst, src); } +// Packed single-precision floating-point SSE instructions. +void Assembler::ps(byte opcode, XMMRegister dst, Operand src) { + EnsureSpace ensure_space(this); + EMIT(0x0F); + EMIT(opcode); + emit_sse_operand(dst, src); +} + +// Packed double-precision floating-point SSE instructions. +void Assembler::pd(byte opcode, XMMRegister dst, Operand src) { + EnsureSpace ensure_space(this); + EMIT(0x66); + EMIT(0x0F); + EMIT(opcode); + emit_sse_operand(dst, src); +} + // AVX instructions void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { @@ -2811,12 +2760,25 @@ void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) { vinstr(op, dst, src1, src2, k66, k0F, kWIG); } +void Assembler::vshufpd(XMMRegister dst, XMMRegister src1, Operand src2, + byte imm8) { + DCHECK(is_uint8(imm8)); + vpd(0xC6, dst, src1, src2); + EMIT(imm8); +} + void Assembler::vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp) { vps(0xC2, dst, src1, src2); EMIT(cmp); } +void Assembler::vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, + uint8_t cmp) { + vpd(0xC2, dst, src1, src2); + EMIT(cmp); +} + void Assembler::vshufps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8) { DCHECK(is_uint8(imm8)); @@ -2848,6 +2810,12 @@ void Assembler::vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8) { EMIT(imm8); } +void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, uint8_t imm8) { + XMMRegister iop = XMMRegister::from_code(2); + vinstr(0x73, iop, dst, Operand(src), k66, k0F, kWIG); + EMIT(imm8); +} + void Assembler::vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8) { XMMRegister iop = XMMRegister::from_code(4); vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG); @@ -3158,11 +3126,10 @@ void Assembler::emit_operand(int code, Operand adr) { DCHECK_GT(length, 0); // Emit updated ModRM byte containing the given register. - pc_[0] = (adr.buf_[0] & ~0x38) | (code << 3); + EMIT((adr.buf_[0] & ~0x38) | (code << 3)); // Emit the rest of the encoded operand. - for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; - pc_ += length; + for (unsigned i = 1; i < length; i++) EMIT(adr.buf_[i]); // Emit relocation information if necessary. if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) { diff --git a/deps/v8/src/codegen/ia32/assembler-ia32.h b/deps/v8/src/codegen/ia32/assembler-ia32.h index 52256212763e44..8161ff83223688 100644 --- a/deps/v8/src/codegen/ia32/assembler-ia32.h +++ b/deps/v8/src/codegen/ia32/assembler-ia32.h @@ -38,6 +38,7 @@ #define V8_CODEGEN_IA32_ASSEMBLER_IA32_H_ #include <deque> +#include <memory> #include "src/codegen/assembler.h" #include "src/codegen/ia32/constants-ia32.h" @@ -292,7 +293,7 @@ class V8_EXPORT_PRIVATE Operand { // Only valid if len_ > 4. RelocInfo::Mode rmode_ = RelocInfo::NONE; - // TODO(clemensh): Get rid of this friendship, or make Operand immutable. + // TODO(clemensb): Get rid of this friendship, or make Operand immutable. friend class Assembler; }; ASSERT_TRIVIALLY_COPYABLE(Operand); @@ -371,7 +372,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // own buffer. Otherwise it takes ownership of the provided buffer. explicit Assembler(const AssemblerOptions&, std::unique_ptr<AssemblerBuffer> = {}); - virtual ~Assembler() {} // GetCode emits any pending (non-emitted) code and fills the descriptor desc. static constexpr int kNoHandlerTable = 0; @@ -512,6 +512,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void movzx_w(Register dst, Operand src); void movq(XMMRegister dst, Operand src); + // Conditional moves void cmov(Condition cc, Register dst, Register src) { cmov(cc, dst, Operand(src)); @@ -849,56 +850,54 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void movups(XMMRegister dst, Operand src); void movups(Operand dst, XMMRegister src); void shufps(XMMRegister dst, XMMRegister src, byte imm8); + void shufpd(XMMRegister dst, XMMRegister src, byte imm8); void maxss(XMMRegister dst, XMMRegister src) { maxss(dst, Operand(src)); } void maxss(XMMRegister dst, Operand src); void minss(XMMRegister dst, XMMRegister src) { minss(dst, Operand(src)); } void minss(XMMRegister dst, Operand src); - void andps(XMMRegister dst, Operand src); - void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); } - void andnps(XMMRegister dst, Operand src); - void andnps(XMMRegister dst, XMMRegister src) { andnps(dst, Operand(src)); } - void xorps(XMMRegister dst, Operand src); - void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); } - void orps(XMMRegister dst, Operand src); - void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); } - - void addps(XMMRegister dst, Operand src); - void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); } - void subps(XMMRegister dst, Operand src); - void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); } - void mulps(XMMRegister dst, Operand src); - void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); } - void divps(XMMRegister dst, Operand src); - void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); } void rcpps(XMMRegister dst, Operand src); void rcpps(XMMRegister dst, XMMRegister src) { rcpps(dst, Operand(src)); } + void sqrtps(XMMRegister dst, Operand src); + void sqrtps(XMMRegister dst, XMMRegister src) { sqrtps(dst, Operand(src)); } void rsqrtps(XMMRegister dst, Operand src); void rsqrtps(XMMRegister dst, XMMRegister src) { rsqrtps(dst, Operand(src)); } void haddps(XMMRegister dst, Operand src); void haddps(XMMRegister dst, XMMRegister src) { haddps(dst, Operand(src)); } - - void minps(XMMRegister dst, Operand src); - void minps(XMMRegister dst, XMMRegister src) { minps(dst, Operand(src)); } - void maxps(XMMRegister dst, Operand src); - void maxps(XMMRegister dst, XMMRegister src) { maxps(dst, Operand(src)); } + void sqrtpd(XMMRegister dst, Operand src) { + sse2_instr(dst, src, 0x66, 0x0F, 0x51); + } + void sqrtpd(XMMRegister dst, XMMRegister src) { sqrtpd(dst, Operand(src)); } void cmpps(XMMRegister dst, Operand src, uint8_t cmp); void cmpps(XMMRegister dst, XMMRegister src, uint8_t cmp) { cmpps(dst, Operand(src), cmp); } -#define SSE_CMP_P(instr, imm8) \ - void instr##ps(XMMRegister dst, XMMRegister src) { \ - cmpps(dst, Operand(src), imm8); \ - } \ - void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); } + void cmppd(XMMRegister dst, Operand src, uint8_t cmp); + void cmppd(XMMRegister dst, XMMRegister src, uint8_t cmp) { + cmppd(dst, Operand(src), cmp); + } + +// Packed floating-point comparison operations. +#define PACKED_CMP_LIST(V) \ + V(cmpeq, 0x0) \ + V(cmplt, 0x1) \ + V(cmple, 0x2) \ + V(cmpunord, 0x3) \ + V(cmpneq, 0x4) - SSE_CMP_P(cmpeq, 0x0) - SSE_CMP_P(cmplt, 0x1) - SSE_CMP_P(cmple, 0x2) - SSE_CMP_P(cmpneq, 0x4) +#define SSE_CMP_P(instr, imm8) \ + void instr##ps(XMMRegister dst, XMMRegister src) { \ + cmpps(dst, Operand(src), imm8); \ + } \ + void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); } \ + void instr##pd(XMMRegister dst, XMMRegister src) { \ + cmppd(dst, Operand(src), imm8); \ + } \ + void instr##pd(XMMRegister dst, Operand src) { cmppd(dst, src, imm8); } + PACKED_CMP_LIST(SSE_CMP_P) #undef SSE_CMP_P // SSE2 instructions @@ -941,22 +940,20 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void mulsd(XMMRegister dst, Operand src); void divsd(XMMRegister dst, XMMRegister src) { divsd(dst, Operand(src)); } void divsd(XMMRegister dst, Operand src); - void xorpd(XMMRegister dst, XMMRegister src) { xorpd(dst, Operand(src)); } - void xorpd(XMMRegister dst, Operand src); void sqrtsd(XMMRegister dst, XMMRegister src) { sqrtsd(dst, Operand(src)); } void sqrtsd(XMMRegister dst, Operand src); - void andpd(XMMRegister dst, XMMRegister src) { andpd(dst, Operand(src)); } - void andpd(XMMRegister dst, Operand src); - void orpd(XMMRegister dst, XMMRegister src) { orpd(dst, Operand(src)); } - void orpd(XMMRegister dst, Operand src); - void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); } void ucomisd(XMMRegister dst, Operand src); void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode); void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); + void movapd(XMMRegister dst, XMMRegister src) { movapd(dst, Operand(src)); } + void movapd(XMMRegister dst, Operand src) { + sse2_instr(dst, src, 0x66, 0x0F, 0x28); + } + void movmskpd(Register dst, XMMRegister src); void movmskps(Register dst, XMMRegister src); @@ -1298,6 +1295,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void vrcpps(XMMRegister dst, Operand src) { vinstr(0x53, dst, xmm0, src, kNone, k0F, kWIG); } + void vsqrtps(XMMRegister dst, XMMRegister src) { vsqrtps(dst, Operand(src)); } + void vsqrtps(XMMRegister dst, Operand src) { + vinstr(0x51, dst, xmm0, src, kNone, k0F, kWIG); + } void vrsqrtps(XMMRegister dst, XMMRegister src) { vrsqrtps(dst, Operand(src)); } @@ -1310,14 +1311,24 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void vhaddps(XMMRegister dst, XMMRegister src1, Operand src2) { vinstr(0x7C, dst, src1, src2, kF2, k0F, kWIG); } + void vsqrtpd(XMMRegister dst, XMMRegister src) { vsqrtpd(dst, Operand(src)); } + void vsqrtpd(XMMRegister dst, Operand src) { + vinstr(0x51, dst, xmm0, src, k66, k0F, kWIG); + } void vmovaps(XMMRegister dst, XMMRegister src) { vmovaps(dst, Operand(src)); } void vmovaps(XMMRegister dst, Operand src) { vps(0x28, dst, xmm0, src); } + void vmovapd(XMMRegister dst, XMMRegister src) { vmovapd(dst, Operand(src)); } + void vmovapd(XMMRegister dst, Operand src) { vpd(0x28, dst, xmm0, src); } void vmovups(XMMRegister dst, XMMRegister src) { vmovups(dst, Operand(src)); } void vmovups(XMMRegister dst, Operand src) { vps(0x10, dst, xmm0, src); } void vshufps(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) { vshufps(dst, src1, Operand(src2), imm8); } void vshufps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8); + void vshufpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) { + vshufpd(dst, src1, Operand(src2), imm8); + } + void vshufpd(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8); void vpsllw(XMMRegister dst, XMMRegister src, uint8_t imm8); void vpslld(XMMRegister dst, XMMRegister src, uint8_t imm8); @@ -1325,6 +1336,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8); void vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8); void vpsrad(XMMRegister dst, XMMRegister src, uint8_t imm8); + void vpsrlq(XMMRegister dst, XMMRegister src, uint8_t imm8); void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) { vpshufhw(dst, Operand(src), shuffle); @@ -1489,6 +1501,11 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { } void rorx(Register dst, Operand src, byte imm8); + // Implementation of packed single-precision floating-point SSE instructions. + void ps(byte op, XMMRegister dst, Operand src); + // Implementation of packed double-precision floating-point SSE instructions. + void pd(byte op, XMMRegister dst, Operand src); + #define PACKED_OP_LIST(V) \ V(and, 0x54) \ V(andn, 0x55) \ @@ -1501,6 +1518,19 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { V(div, 0x5e) \ V(max, 0x5f) +#define SSE_PACKED_OP_DECLARE(name, opcode) \ + void name##ps(XMMRegister dst, XMMRegister src) { \ + ps(opcode, dst, Operand(src)); \ + } \ + void name##ps(XMMRegister dst, Operand src) { ps(opcode, dst, src); } \ + void name##pd(XMMRegister dst, XMMRegister src) { \ + pd(opcode, dst, Operand(src)); \ + } \ + void name##pd(XMMRegister dst, Operand src) { pd(opcode, dst, src); } + + PACKED_OP_LIST(SSE_PACKED_OP_DECLARE) +#undef SSE_PACKED_OP_DECLARE + #define AVX_PACKED_OP_DECLARE(name, opcode) \ void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ vps(opcode, dst, src1, Operand(src2)); \ @@ -1516,24 +1546,32 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { } PACKED_OP_LIST(AVX_PACKED_OP_DECLARE) +#undef AVX_PACKED_OP_DECLARE +#undef PACKED_OP_LIST + void vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2); void vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2); void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp); -#define AVX_CMP_P(instr, imm8) \ - void instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ - vcmpps(dst, src1, Operand(src2), imm8); \ - } \ - void instr##ps(XMMRegister dst, XMMRegister src1, Operand src2) { \ - vcmpps(dst, src1, src2, imm8); \ - } - - AVX_CMP_P(vcmpeq, 0x0) - AVX_CMP_P(vcmplt, 0x1) - AVX_CMP_P(vcmple, 0x2) - AVX_CMP_P(vcmpneq, 0x4) - + void vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t cmp); + +#define AVX_CMP_P(instr, imm8) \ + void v##instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ + vcmpps(dst, src1, Operand(src2), imm8); \ + } \ + void v##instr##ps(XMMRegister dst, XMMRegister src1, Operand src2) { \ + vcmpps(dst, src1, src2, imm8); \ + } \ + void v##instr##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \ + vcmppd(dst, src1, Operand(src2), imm8); \ + } \ + void v##instr##pd(XMMRegister dst, XMMRegister src1, Operand src2) { \ + vcmppd(dst, src1, src2, imm8); \ + } + + PACKED_CMP_LIST(AVX_CMP_P) #undef AVX_CMP_P +#undef PACKED_CMP_LIST // Other SSE and AVX instructions #define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \ diff --git a/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc b/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc index 070f3159776a76..dd11bc496eda80 100644 --- a/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc +++ b/deps/v8/src/codegen/ia32/macro-assembler-ia32.cc @@ -1168,57 +1168,44 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } } -void MacroAssembler::CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_hook; - - ExternalReference debug_hook_active = - ExternalReference::debug_hook_on_function_call_address(isolate()); - push(eax); - cmpb(ExternalReferenceAsOperand(debug_hook_active, eax), Immediate(0)); - pop(eax); - j(equal, &skip_hook); - - { - FrameScope frame(this, - has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); - if (expected.is_reg()) { - SmiTag(expected.reg()); - Push(expected.reg()); - } - if (actual.is_reg()) { - SmiTag(actual.reg()); - Push(actual.reg()); - SmiUntag(actual.reg()); - } - if (new_target.is_valid()) { - Push(new_target); - } - Push(fun); - Push(fun); - Operand receiver_op = - actual.is_reg() - ? Operand(ebp, actual.reg(), times_system_pointer_size, - kSystemPointerSize * 2) - : Operand(ebp, actual.immediate() * times_system_pointer_size + - kSystemPointerSize * 2); - Push(receiver_op); - CallRuntime(Runtime::kDebugOnFunctionCall); - Pop(fun); - if (new_target.is_valid()) { - Pop(new_target); - } - if (actual.is_reg()) { - Pop(actual.reg()); - SmiUntag(actual.reg()); - } - if (expected.is_reg()) { - Pop(expected.reg()); - SmiUntag(expected.reg()); - } +void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); + if (expected.is_reg()) { + SmiTag(expected.reg()); + Push(expected.reg()); + } + if (actual.is_reg()) { + SmiTag(actual.reg()); + Push(actual.reg()); + SmiUntag(actual.reg()); + } + if (new_target.is_valid()) { + Push(new_target); + } + Push(fun); + Push(fun); + Operand receiver_op = + actual.is_reg() + ? Operand(ebp, actual.reg(), times_system_pointer_size, + kSystemPointerSize * 2) + : Operand(ebp, actual.immediate() * times_system_pointer_size + + kSystemPointerSize * 2); + Push(receiver_op); + CallRuntime(Runtime::kDebugOnFunctionCall); + Pop(fun); + if (new_target.is_valid()) { + Pop(new_target); + } + if (actual.is_reg()) { + Pop(actual.reg()); + SmiUntag(actual.reg()); + } + if (expected.is_reg()) { + Pop(expected.reg()); + SmiUntag(expected.reg()); } - bind(&skip_hook); } void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, @@ -1233,7 +1220,16 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK_IMPLIES(actual.is_reg(), actual.reg() == eax); // On function call, call into the debugger if necessary. - CheckDebugHook(function, new_target, expected, actual); + Label debug_hook, continue_after_hook; + { + ExternalReference debug_hook_active = + ExternalReference::debug_hook_on_function_call_address(isolate()); + push(eax); + cmpb(ExternalReferenceAsOperand(debug_hook_active, eax), Immediate(0)); + pop(eax); + j(not_equal, &debug_hook, Label::kNear); + } + bind(&continue_after_hook); // Clear the new.target register if not given. if (!new_target.is_valid()) { @@ -1256,8 +1252,15 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(flag == JUMP_FUNCTION); JumpCodeObject(ecx); } - bind(&done); } + jmp(&done, Label::kNear); + + // Deferred debug hook. + bind(&debug_hook); + CallDebugOnFunctionCall(function, new_target, expected, actual); + jmp(&continue_after_hook, Label::kNear); + + bind(&done); } void MacroAssembler::InvokeFunction(Register fun, Register new_target, @@ -1479,6 +1482,15 @@ void TurboAssembler::Psrlw(XMMRegister dst, uint8_t shift) { } } +void TurboAssembler::Psrlq(XMMRegister dst, uint8_t shift) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpsrlq(dst, dst, shift); + } else { + psrlq(dst, shift); + } +} + void TurboAssembler::Psignb(XMMRegister dst, Operand src) { if (CpuFeatures::IsSupported(AVX)) { CpuFeatureScope scope(this, AVX); diff --git a/deps/v8/src/codegen/ia32/macro-assembler-ia32.h b/deps/v8/src/codegen/ia32/macro-assembler-ia32.h index c65871cfad34a2..9e7774c55d5da6 100644 --- a/deps/v8/src/codegen/ia32/macro-assembler-ia32.h +++ b/deps/v8/src/codegen/ia32/macro-assembler-ia32.h @@ -237,6 +237,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void Pshufd(XMMRegister dst, Operand src, uint8_t shuffle); void Psraw(XMMRegister dst, uint8_t shift); void Psrlw(XMMRegister dst, uint8_t shift); + void Psrlq(XMMRegister dst, uint8_t shift); // SSE/SSE2 instructions with AVX version. #define AVX_OP2_WITH_TYPE(macro_name, name, dst_type, src_type) \ @@ -258,6 +259,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { AVX_OP2_WITH_TYPE(Movd, movd, Register, XMMRegister) AVX_OP2_WITH_TYPE(Movd, movd, Operand, XMMRegister) AVX_OP2_WITH_TYPE(Cvtdq2ps, cvtdq2ps, XMMRegister, Operand) + AVX_OP2_WITH_TYPE(Sqrtpd, sqrtpd, XMMRegister, const Operand&) + AVX_OP2_WITH_TYPE(Movapd, movapd, XMMRegister, XMMRegister) + AVX_OP2_WITH_TYPE(Movapd, movapd, XMMRegister, const Operand&) #undef AVX_OP2_WITH_TYPE @@ -278,6 +282,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { AVX_OP3_XO(Packsswb, packsswb) AVX_OP3_XO(Packuswb, packuswb) + AVX_OP3_XO(Paddusb, paddusb) AVX_OP3_XO(Pcmpeqb, pcmpeqb) AVX_OP3_XO(Pcmpeqw, pcmpeqw) AVX_OP3_XO(Pcmpeqd, pcmpeqd) @@ -294,10 +299,41 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { AVX_OP3_XO(Xorpd, xorpd) AVX_OP3_XO(Sqrtss, sqrtss) AVX_OP3_XO(Sqrtsd, sqrtsd) + AVX_OP3_XO(Orpd, orpd) + AVX_OP3_XO(Andnpd, andnpd) #undef AVX_OP3_XO #undef AVX_OP3_WITH_TYPE +// Only use this macro when dst and src1 is the same in SSE case. +#define AVX_PACKED_OP3_WITH_TYPE(macro_name, name, dst_type, src_type) \ + void macro_name(dst_type dst, dst_type src1, src_type src2) { \ + if (CpuFeatures::IsSupported(AVX)) { \ + CpuFeatureScope scope(this, AVX); \ + v##name(dst, src1, src2); \ + } else { \ + DCHECK_EQ(dst, src1); \ + name(dst, src2); \ + } \ + } +#define AVX_PACKED_OP3(macro_name, name) \ + AVX_PACKED_OP3_WITH_TYPE(macro_name, name, XMMRegister, XMMRegister) \ + AVX_PACKED_OP3_WITH_TYPE(macro_name, name, XMMRegister, Operand) + + AVX_PACKED_OP3(Addpd, addpd) + AVX_PACKED_OP3(Subpd, subpd) + AVX_PACKED_OP3(Mulpd, mulpd) + AVX_PACKED_OP3(Divpd, divpd) + AVX_PACKED_OP3(Cmpeqpd, cmpeqpd) + AVX_PACKED_OP3(Cmpneqpd, cmpneqpd) + AVX_PACKED_OP3(Cmpltpd, cmpltpd) + AVX_PACKED_OP3(Cmplepd, cmplepd) + AVX_PACKED_OP3(Minpd, minpd) + AVX_PACKED_OP3(Maxpd, maxpd) + AVX_PACKED_OP3(Cmpunordpd, cmpunordpd) +#undef AVX_PACKED_OP3 +#undef AVX_PACKED_OP3_WITH_TYPE + // Non-SSE2 instructions. #define AVX_OP2_WITH_TYPE_SCOPE(macro_name, name, dst_type, src_type, \ sse_scope) \ @@ -529,11 +565,11 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { const ParameterCount& expected, const ParameterCount& actual, InvokeFlag flag); - // On function call, call into the debugger if necessary. + // On function call, call into the debugger. // This may clobber ecx. - void CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual); + void CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual); // Invoke the JavaScript function in the given register. Changes the // current context to the context in the function before invoking. diff --git a/deps/v8/src/codegen/interface-descriptors.cc b/deps/v8/src/codegen/interface-descriptors.cc index f537ebc899428c..1525f814cd97d6 100644 --- a/deps/v8/src/codegen/interface-descriptors.cc +++ b/deps/v8/src/codegen/interface-descriptors.cc @@ -278,6 +278,11 @@ void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific( data->InitializePlatformSpecific(0, nullptr); } +void GetIteratorStackParameterDescriptor::InitializePlatformSpecific( + CallInterfaceDescriptorData* data) { + data->InitializePlatformSpecific(0, nullptr); +} + void LoadWithVectorDescriptor::InitializePlatformSpecific( CallInterfaceDescriptorData* data) { Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(), diff --git a/deps/v8/src/codegen/interface-descriptors.h b/deps/v8/src/codegen/interface-descriptors.h index 544d62fd9f01d7..e305d666a3e70e 100644 --- a/deps/v8/src/codegen/interface-descriptors.h +++ b/deps/v8/src/codegen/interface-descriptors.h @@ -9,12 +9,17 @@ #include "src/codegen/machine-type.h" #include "src/codegen/register-arch.h" +#include "src/codegen/tnode.h" #include "src/common/globals.h" #include "src/execution/isolate.h" namespace v8 { namespace internal { +#define TORQUE_BUILTIN_LIST_TFC(V) \ + BUILTIN_LIST_FROM_TORQUE(IGNORE_BUILTIN, IGNORE_BUILTIN, V, IGNORE_BUILTIN, \ + IGNORE_BUILTIN, IGNORE_BUILTIN) + #define INTERFACE_DESCRIPTOR_LIST(V) \ V(Abort) \ V(Allocate) \ @@ -52,6 +57,7 @@ namespace internal { V(FastNewFunctionContext) \ V(FastNewObject) \ V(FrameDropperTrampoline) \ + V(GetIteratorStackParameter) \ V(GetProperty) \ V(GrowArrayElements) \ V(InterpreterCEntry1) \ @@ -89,7 +95,8 @@ namespace internal { V(WasmTableGet) \ V(WasmTableSet) \ V(WasmThrow) \ - BUILTIN_LIST_TFS(V) + BUILTIN_LIST_TFS(V) \ + TORQUE_BUILTIN_LIST_TFC(V) class V8_EXPORT_PRIVATE CallInterfaceDescriptorData { public: @@ -486,6 +493,46 @@ class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor { DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor) }; +// This class is subclassed by Torque-generated call interface descriptors. +template <int parameter_count> +class TorqueInterfaceDescriptor : public CallInterfaceDescriptor { + public: + static constexpr int kDescriptorFlags = CallInterfaceDescriptorData::kNoFlags; + static constexpr int kParameterCount = parameter_count; + enum ParameterIndices { kContext = kParameterCount }; + template <int i> + static ParameterIndices ParameterIndex() { + STATIC_ASSERT(0 <= i && i < kParameterCount); + return static_cast<ParameterIndices>(i); + } + static constexpr int kReturnCount = 1; + + using CallInterfaceDescriptor::CallInterfaceDescriptor; + + protected: + static const int kRegisterParams = + kParameterCount > kMaxTFSBuiltinRegisterParams + ? kMaxTFSBuiltinRegisterParams + : kParameterCount; + static const int kStackParams = kParameterCount - kRegisterParams; + virtual MachineType ReturnType() = 0; + virtual std::array<MachineType, kParameterCount> ParameterTypes() = 0; + void InitializePlatformSpecific(CallInterfaceDescriptorData* data) override { + DefaultInitializePlatformSpecific(data, kRegisterParams); + } + void InitializePlatformIndependent( + CallInterfaceDescriptorData* data) override { + std::vector<MachineType> machine_types = {ReturnType()}; + auto parameter_types = ParameterTypes(); + machine_types.insert(machine_types.end(), parameter_types.begin(), + parameter_types.end()); + DCHECK_EQ(kReturnCount + kParameterCount, machine_types.size()); + data->InitializePlatformIndependent(Flags(kDescriptorFlags), kReturnCount, + kParameterCount, machine_types.data(), + static_cast<int>(machine_types.size())); + } +}; + // Dummy descriptor used to mark builtins that don't yet have their proper // descriptor associated. using DummyDescriptor = VoidDescriptor; @@ -706,7 +753,7 @@ class FastNewFunctionContextDescriptor : public CallInterfaceDescriptor { public: DEFINE_PARAMETERS(kScopeInfo, kSlots) DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kScopeInfo - MachineType::Int32()) // kSlots + MachineType::Uint32()) // kSlots DECLARE_DESCRIPTOR(FastNewFunctionContextDescriptor, CallInterfaceDescriptor) static const Register ScopeInfoRegister(); @@ -771,6 +818,16 @@ class AsyncFunctionStackParameterDescriptor final CallInterfaceDescriptor) }; +class GetIteratorStackParameterDescriptor final + : public CallInterfaceDescriptor { + public: + DEFINE_PARAMETERS(kReceiver, kCallSlot, kFeedback, kResult) + DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), MachineType::AnyTagged(), + MachineType::AnyTagged(), MachineType::AnyTagged()) + DECLARE_DESCRIPTOR(GetIteratorStackParameterDescriptor, + CallInterfaceDescriptor) +}; + class GetPropertyDescriptor final : public CallInterfaceDescriptor { public: DEFINE_PARAMETERS(kObject, kKey) @@ -1298,6 +1355,11 @@ class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor { BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR) #undef DEFINE_TFS_BUILTIN_DESCRIPTOR +// This file contains interface descriptor class definitions for builtins +// defined in Torque. It is included here because the class definitions need to +// precede the definition of name##Descriptor::key() below. +#include "torque-generated/interface-descriptors-tq.inc" + #undef DECLARE_DEFAULT_DESCRIPTOR #undef DECLARE_DESCRIPTOR_WITH_BASE #undef DECLARE_DESCRIPTOR diff --git a/deps/v8/src/codegen/machine-type.h b/deps/v8/src/codegen/machine-type.h index 15e3df65c5adc9..a0bef4e07d65a4 100644 --- a/deps/v8/src/codegen/machine-type.h +++ b/deps/v8/src/codegen/machine-type.h @@ -9,6 +9,7 @@ #include "src/base/bits.h" #include "src/common/globals.h" +#include "src/flags/flags.h" namespace v8 { namespace internal { @@ -114,6 +115,10 @@ class MachineType { constexpr bool IsCompressedPointer() const { return representation() == MachineRepresentation::kCompressedPointer; } + constexpr static MachineRepresentation TaggedRepresentation() { + return (kTaggedSize == 4) ? MachineRepresentation::kWord32 + : MachineRepresentation::kWord64; + } constexpr static MachineRepresentation PointerRepresentation() { return (kSystemPointerSize == 4) ? MachineRepresentation::kWord32 : MachineRepresentation::kWord64; @@ -239,71 +244,79 @@ class MachineType { // pointer flag is enabled. Otherwise, they returned the corresponding tagged // one. constexpr static MachineRepresentation RepCompressedTagged() { -#ifdef V8_COMPRESS_POINTERS - return MachineRepresentation::kCompressed; -#else - return MachineRepresentation::kTagged; -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineRepresentation::kCompressed; + } else { + return MachineRepresentation::kTagged; + } } constexpr static MachineRepresentation RepCompressedTaggedSigned() { -#ifdef V8_COMPRESS_POINTERS - return MachineRepresentation::kCompressedSigned; -#else - return MachineRepresentation::kTaggedSigned; -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineRepresentation::kCompressedSigned; + } else { + return MachineRepresentation::kTaggedSigned; + } } constexpr static MachineRepresentation RepCompressedTaggedPointer() { -#ifdef V8_COMPRESS_POINTERS - return MachineRepresentation::kCompressedPointer; -#else - return MachineRepresentation::kTaggedPointer; -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineRepresentation::kCompressedPointer; + } else { + return MachineRepresentation::kTaggedPointer; + } + } + + constexpr static MachineType TypeRawTagged() { + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineType::Int32(); + } else { + return MachineType::Pointer(); + } } constexpr static MachineType TypeCompressedTagged() { -#ifdef V8_COMPRESS_POINTERS - return MachineType::AnyCompressed(); -#else - return MachineType::AnyTagged(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineType::AnyCompressed(); + } else { + return MachineType::AnyTagged(); + } } constexpr static MachineType TypeCompressedTaggedSigned() { -#ifdef V8_COMPRESS_POINTERS - return MachineType::CompressedSigned(); -#else - return MachineType::TaggedSigned(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineType::CompressedSigned(); + } else { + return MachineType::TaggedSigned(); + } } constexpr static MachineType TypeCompressedTaggedPointer() { -#ifdef V8_COMPRESS_POINTERS - return MachineType::CompressedPointer(); -#else - return MachineType::TaggedPointer(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return MachineType::CompressedPointer(); + } else { + return MachineType::TaggedPointer(); + } } constexpr bool IsCompressedTagged() const { -#ifdef V8_COMPRESS_POINTERS - return IsCompressed(); -#else - return IsTagged(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return IsCompressed(); + } else { + return IsTagged(); + } } constexpr bool IsCompressedTaggedSigned() const { -#ifdef V8_COMPRESS_POINTERS - return IsCompressedSigned(); -#else - return IsTaggedSigned(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return IsCompressedSigned(); + } else { + return IsTaggedSigned(); + } } constexpr bool IsCompressedTaggedPointer() const { -#ifdef V8_COMPRESS_POINTERS - return IsCompressedPointer(); -#else - return IsTaggedPointer(); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return IsCompressedPointer(); + } else { + return IsTaggedPointer(); + } } static MachineType TypeForRepresentation(const MachineRepresentation& rep, @@ -405,11 +418,11 @@ inline bool IsAnyCompressed(MachineRepresentation rep) { } inline bool IsAnyCompressedTagged(MachineRepresentation rep) { -#ifdef V8_COMPRESS_POINTERS - return IsAnyCompressed(rep); -#else - return IsAnyTagged(rep); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + return IsAnyCompressed(rep); + } else { + return IsAnyTagged(rep); + } } // Gets the log2 of the element size in bytes of the machine type. @@ -431,7 +444,6 @@ V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) { case MachineRepresentation::kTaggedSigned: case MachineRepresentation::kTaggedPointer: case MachineRepresentation::kTagged: - return kSystemPointerSizeLog2; case MachineRepresentation::kCompressedSigned: case MachineRepresentation::kCompressedPointer: case MachineRepresentation::kCompressed: diff --git a/deps/v8/src/codegen/mips/assembler-mips-inl.h b/deps/v8/src/codegen/mips/assembler-mips-inl.h index d8181ad8f5b958..53e6f93411b700 100644 --- a/deps/v8/src/codegen/mips/assembler-mips-inl.h +++ b/deps/v8/src/codegen/mips/assembler-mips-inl.h @@ -133,7 +133,7 @@ void Assembler::set_target_internal_reference_encoded_at(Address pc, if (Assembler::IsJicOrJialc(instr2)) { // Encoded internal references are lui/jic load of 32-bit absolute address. uint32_t lui_offset_u, jic_offset_u; - Assembler::UnpackTargetAddressUnsigned(imm, lui_offset_u, jic_offset_u); + Assembler::UnpackTargetAddressUnsigned(imm, &lui_offset_u, &jic_offset_u); Assembler::instr_at_put(pc + 0 * kInstrSize, instr1 | lui_offset_u); Assembler::instr_at_put(pc + 1 * kInstrSize, instr2 | jic_offset_u); @@ -183,7 +183,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_)); Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/mips/assembler-mips.cc b/deps/v8/src/codegen/mips/assembler-mips.cc index 423da2fb65f778..768b16b86c4433 100644 --- a/deps/v8/src/codegen/mips/assembler-mips.cc +++ b/deps/v8/src/codegen/mips/assembler-mips.cc @@ -231,8 +231,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle<HeapObject> object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); break; case HeapObjectRequest::kStringConstant: const StringConstantBase* str = request.string(); @@ -742,27 +742,27 @@ uint32_t Assembler::CreateTargetAddress(Instr instr_lui, Instr instr_jic) { // before that addition, difference between upper part of the target address and // upper part of the sign-extended offset (0xFFFF or 0x0000), will be inserted // in jic register with lui instruction. -void Assembler::UnpackTargetAddress(uint32_t address, int16_t& lui_offset, - int16_t& jic_offset) { - lui_offset = (address & kHiMask) >> kLuiShift; - jic_offset = address & kLoMask; +void Assembler::UnpackTargetAddress(uint32_t address, int16_t* lui_offset, + int16_t* jic_offset) { + *lui_offset = (address & kHiMask) >> kLuiShift; + *jic_offset = address & kLoMask; - if (jic_offset < 0) { - lui_offset -= kImm16Mask; + if (*jic_offset < 0) { + *lui_offset -= kImm16Mask; } } void Assembler::UnpackTargetAddressUnsigned(uint32_t address, - uint32_t& lui_offset, - uint32_t& jic_offset) { + uint32_t* lui_offset, + uint32_t* jic_offset) { int16_t lui_offset16 = (address & kHiMask) >> kLuiShift; int16_t jic_offset16 = address & kLoMask; if (jic_offset16 < 0) { lui_offset16 -= kImm16Mask; } - lui_offset = static_cast<uint32_t>(lui_offset16) & kImm16Mask; - jic_offset = static_cast<uint32_t>(jic_offset16) & kImm16Mask; + *lui_offset = static_cast<uint32_t>(lui_offset16) & kImm16Mask; + *jic_offset = static_cast<uint32_t>(jic_offset16) & kImm16Mask; } void Assembler::PatchLuiOriImmediate(int pc, int32_t imm, Instr instr_lui, @@ -977,7 +977,7 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos, if (IsJicOrJialc(instr2)) { uint32_t lui_offset_u, jic_offset_u; - UnpackTargetAddressUnsigned(imm, lui_offset_u, jic_offset_u); + UnpackTargetAddressUnsigned(imm, &lui_offset_u, &jic_offset_u); instr_at_put(pos + 0 * kInstrSize, instr1 | lui_offset_u); instr_at_put(pos + 1 * kInstrSize, instr2 | jic_offset_u); } else { @@ -1928,7 +1928,7 @@ void Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) { // ------------Memory-instructions------------- -void Assembler::AdjustBaseAndOffset(MemOperand& src, +void Assembler::AdjustBaseAndOffset(MemOperand* src, OffsetAccessType access_type, int second_access_add_to_offset) { // This method is used to adjust the base register and offset pair @@ -1941,26 +1941,26 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, // pointer register). // We preserve the "alignment" of 'offset' by adjusting it by a multiple of 8. - bool doubleword_aligned = (src.offset() & (kDoubleSize - 1)) == 0; + bool doubleword_aligned = (src->offset() & (kDoubleSize - 1)) == 0; bool two_accesses = static_cast<bool>(access_type) || !doubleword_aligned; DCHECK_LE(second_access_add_to_offset, 7); // Must be <= 7. // is_int16 must be passed a signed value, hence the static cast below. - if (is_int16(src.offset()) && + if (is_int16(src->offset()) && (!two_accesses || is_int16(static_cast<int32_t>( - src.offset() + second_access_add_to_offset)))) { + src->offset() + second_access_add_to_offset)))) { // Nothing to do: 'offset' (and, if needed, 'offset + 4', or other specified // value) fits into int16_t. return; } UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); - DCHECK(src.rm() != scratch); // Must not overwrite the register 'base' - // while loading 'offset'. + DCHECK(src->rm() != scratch); // Must not overwrite the register 'base' + // while loading 'offset'. #ifdef DEBUG // Remember the "(mis)alignment" of 'offset', it will be checked at the end. - uint32_t misalignment = src.offset() & (kDoubleSize - 1); + uint32_t misalignment = src->offset() & (kDoubleSize - 1); #endif // Do not load the whole 32-bit 'offset' if it can be represented as @@ -1972,13 +1972,13 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, 0x7FF8; // Max int16_t that's a multiple of 8. constexpr int32_t kMaxOffsetForSimpleAdjustment = 2 * kMinOffsetForSimpleAdjustment; - if (0 <= src.offset() && src.offset() <= kMaxOffsetForSimpleAdjustment) { - addiu(at, src.rm(), kMinOffsetForSimpleAdjustment); - src.offset_ -= kMinOffsetForSimpleAdjustment; - } else if (-kMaxOffsetForSimpleAdjustment <= src.offset() && - src.offset() < 0) { - addiu(at, src.rm(), -kMinOffsetForSimpleAdjustment); - src.offset_ += kMinOffsetForSimpleAdjustment; + if (0 <= src->offset() && src->offset() <= kMaxOffsetForSimpleAdjustment) { + addiu(at, src->rm(), kMinOffsetForSimpleAdjustment); + src->offset_ -= kMinOffsetForSimpleAdjustment; + } else if (-kMaxOffsetForSimpleAdjustment <= src->offset() && + src->offset() < 0) { + addiu(at, src->rm(), -kMinOffsetForSimpleAdjustment); + src->offset_ += kMinOffsetForSimpleAdjustment; } else if (IsMipsArchVariant(kMips32r6)) { // On r6 take advantage of the aui instruction, e.g.: // aui at, base, offset_high @@ -1989,12 +1989,12 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, // addiu at, at, 8 // lw reg_lo, (offset_low-8)(at) // lw reg_hi, (offset_low-4)(at) - int16_t offset_high = static_cast<uint16_t>(src.offset() >> 16); - int16_t offset_low = static_cast<uint16_t>(src.offset()); + int16_t offset_high = static_cast<uint16_t>(src->offset() >> 16); + int16_t offset_low = static_cast<uint16_t>(src->offset()); offset_high += (offset_low < 0) ? 1 : 0; // Account for offset sign extension in load/store. - aui(scratch, src.rm(), static_cast<uint16_t>(offset_high)); + aui(scratch, src->rm(), static_cast<uint16_t>(offset_high)); if (two_accesses && !is_int16(static_cast<int32_t>( offset_low + second_access_add_to_offset))) { // Avoid overflow in the 16-bit offset of the load/store instruction when @@ -2002,7 +2002,7 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, addiu(scratch, scratch, kDoubleSize); offset_low -= kDoubleSize; } - src.offset_ = offset_low; + src->offset_ = offset_low; } else { // Do not load the whole 32-bit 'offset' if it can be represented as // a sum of three 16-bit signed offsets. This can save an instruction. @@ -2013,62 +2013,62 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, 2 * kMinOffsetForSimpleAdjustment; constexpr int32_t kMaxOffsetForMediumAdjustment = 3 * kMinOffsetForSimpleAdjustment; - if (0 <= src.offset() && src.offset() <= kMaxOffsetForMediumAdjustment) { - addiu(scratch, src.rm(), kMinOffsetForMediumAdjustment / 2); + if (0 <= src->offset() && src->offset() <= kMaxOffsetForMediumAdjustment) { + addiu(scratch, src->rm(), kMinOffsetForMediumAdjustment / 2); addiu(scratch, scratch, kMinOffsetForMediumAdjustment / 2); - src.offset_ -= kMinOffsetForMediumAdjustment; - } else if (-kMaxOffsetForMediumAdjustment <= src.offset() && - src.offset() < 0) { - addiu(scratch, src.rm(), -kMinOffsetForMediumAdjustment / 2); + src->offset_ -= kMinOffsetForMediumAdjustment; + } else if (-kMaxOffsetForMediumAdjustment <= src->offset() && + src->offset() < 0) { + addiu(scratch, src->rm(), -kMinOffsetForMediumAdjustment / 2); addiu(scratch, scratch, -kMinOffsetForMediumAdjustment / 2); - src.offset_ += kMinOffsetForMediumAdjustment; + src->offset_ += kMinOffsetForMediumAdjustment; } else { // Now that all shorter options have been exhausted, load the full 32-bit // offset. - int32_t loaded_offset = RoundDown(src.offset(), kDoubleSize); + int32_t loaded_offset = RoundDown(src->offset(), kDoubleSize); lui(scratch, (loaded_offset >> kLuiShift) & kImm16Mask); ori(scratch, scratch, loaded_offset & kImm16Mask); // Load 32-bit offset. - addu(scratch, scratch, src.rm()); - src.offset_ -= loaded_offset; + addu(scratch, scratch, src->rm()); + src->offset_ -= loaded_offset; } } - src.rm_ = scratch; + src->rm_ = scratch; - DCHECK(is_int16(src.offset())); + DCHECK(is_int16(src->offset())); if (two_accesses) { DCHECK(is_int16( - static_cast<int32_t>(src.offset() + second_access_add_to_offset))); + static_cast<int32_t>(src->offset() + second_access_add_to_offset))); } - DCHECK(misalignment == (src.offset() & (kDoubleSize - 1))); + DCHECK(misalignment == (src->offset() & (kDoubleSize - 1))); } void Assembler::lb(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(LB, source.rm(), rd, source.offset()); } void Assembler::lbu(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(LBU, source.rm(), rd, source.offset()); } void Assembler::lh(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(LH, source.rm(), rd, source.offset()); } void Assembler::lhu(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(LHU, source.rm(), rd, source.offset()); } void Assembler::lw(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(LW, source.rm(), rd, source.offset()); } @@ -2088,19 +2088,19 @@ void Assembler::lwr(Register rd, const MemOperand& rs) { void Assembler::sb(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(SB, source.rm(), rd, source.offset()); } void Assembler::sh(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(SH, source.rm(), rd, source.offset()); } void Assembler::sw(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); GenInstrImmediate(SW, source.rm(), rd, source.offset()); } @@ -2385,13 +2385,13 @@ void Assembler::seb(Register rd, Register rt) { // Load, store, move. void Assembler::lwc1(FPURegister fd, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); GenInstrImmediate(LWC1, tmp.rm(), fd, tmp.offset()); } void Assembler::swc1(FPURegister fd, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); GenInstrImmediate(SWC1, tmp.rm(), fd, tmp.offset()); } @@ -2969,7 +2969,7 @@ MSA_BRANCH_LIST(MSA_BRANCH) #define MSA_LD_ST(name, opcode) \ void Assembler::name(MSARegister wd, const MemOperand& rs) { \ MemOperand source = rs; \ - AdjustBaseAndOffset(source); \ + AdjustBaseAndOffset(&source); \ if (is_int10(source.offset())) { \ GenInstrMsaMI10(opcode, source.offset(), source.rm(), wd); \ } else { \ @@ -3473,7 +3473,8 @@ int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, Address pc, if (IsJicOrJialc(instr2)) { uint32_t lui_offset_u, jic_offset_u; - Assembler::UnpackTargetAddressUnsigned(imm, lui_offset_u, jic_offset_u); + Assembler::UnpackTargetAddressUnsigned(imm, + &lui_offset_u, &jic_offset_u); instr_at_put(pc + 0 * kInstrSize, instr1 | lui_offset_u); instr_at_put(pc + 1 * kInstrSize, instr2 | jic_offset_u); } else { @@ -3717,7 +3718,7 @@ void Assembler::set_target_value_at(Address pc, uint32_t target, if (IsJicOrJialc(instr2)) { // Must use 2 instructions to insure patchable code => use lui and jic uint32_t lui_offset, jic_offset; - Assembler::UnpackTargetAddressUnsigned(target, lui_offset, jic_offset); + Assembler::UnpackTargetAddressUnsigned(target, &lui_offset, &jic_offset); instr1 &= ~kImm16Mask; instr2 &= ~kImm16Mask; diff --git a/deps/v8/src/codegen/mips/assembler-mips.h b/deps/v8/src/codegen/mips/assembler-mips.h index 0359be2c94aef8..d8cb8ec3f2a9e8 100644 --- a/deps/v8/src/codegen/mips/assembler-mips.h +++ b/deps/v8/src/codegen/mips/assembler-mips.h @@ -36,6 +36,7 @@ #define V8_CODEGEN_MIPS_ASSEMBLER_MIPS_H_ #include <stdio.h> +#include <memory> #include <set> @@ -1478,13 +1479,11 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { static bool IsAddImmediate(Instr instr); static Instr SetAddImmediateOffset(Instr instr, int16_t offset); static uint32_t CreateTargetAddress(Instr instr_lui, Instr instr_jic); - static void UnpackTargetAddress( - uint32_t address, int16_t& lui_offset, // NOLINT(runtime/references) - int16_t& jic_offset); // NOLINT(runtime/references) - static void UnpackTargetAddressUnsigned( - uint32_t address, - uint32_t& lui_offset, // NOLINT(runtime/references) - uint32_t& jic_offset); // NOLINT(runtime/references) + static void UnpackTargetAddress(uint32_t address, int16_t* lui_offset, + int16_t* jic_offset); + static void UnpackTargetAddressUnsigned(uint32_t address, + uint32_t* lui_offset, + uint32_t* jic_offset); static bool IsAndImmediate(Instr instr); static bool IsEmittedConstant(Instr instr); @@ -1515,7 +1514,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // Helper function for memory load/store using base register and offset. void AdjustBaseAndOffset( - MemOperand& src, // NOLINT(runtime/references) + MemOperand* src, OffsetAccessType access_type = OffsetAccessType::SINGLE_ACCESS, int second_access_add_to_offset = 4); diff --git a/deps/v8/src/codegen/mips/macro-assembler-mips.cc b/deps/v8/src/codegen/mips/macro-assembler-mips.cc index 2e4698a9e71c78..760d33d7c9179b 100644 --- a/deps/v8/src/codegen/mips/macro-assembler-mips.cc +++ b/deps/v8/src/codegen/mips/macro-assembler-mips.cc @@ -1063,7 +1063,7 @@ void TurboAssembler::Ulw(Register rd, const MemOperand& rs) { DCHECK(kMipsLwrOffset <= 3 && kMipsLwlOffset <= 3); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 3 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 3); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 3); if (rd != source.rm()) { lwr(rd, MemOperand(source.rm(), source.offset() + kMipsLwrOffset)); lwl(rd, MemOperand(source.rm(), source.offset() + kMipsLwlOffset)); @@ -1089,7 +1089,7 @@ void TurboAssembler::Usw(Register rd, const MemOperand& rs) { DCHECK(kMipsSwrOffset <= 3 && kMipsSwlOffset <= 3); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 3 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 3); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 3); swr(rd, MemOperand(source.rm(), source.offset() + kMipsSwrOffset)); swl(rd, MemOperand(source.rm(), source.offset() + kMipsSwlOffset)); } @@ -1105,7 +1105,7 @@ void TurboAssembler::Ulh(Register rd, const MemOperand& rs) { IsMipsArchVariant(kLoongson)); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); if (source.rm() == scratch) { @@ -1140,7 +1140,7 @@ void TurboAssembler::Ulhu(Register rd, const MemOperand& rs) { IsMipsArchVariant(kLoongson)); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); if (source.rm() == scratch) { @@ -1177,7 +1177,7 @@ void TurboAssembler::Ush(Register rd, const MemOperand& rs, Register scratch) { IsMipsArchVariant(kLoongson)); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); if (scratch != rd) { mov(scratch, rd); @@ -1256,7 +1256,7 @@ void TurboAssembler::Ldc1(FPURegister fd, const MemOperand& src) { BlockTrampolinePoolScope block_trampoline_pool(this); DCHECK(Register::kMantissaOffset <= 4 && Register::kExponentOffset <= 4); MemOperand tmp = src; - AdjustBaseAndOffset(tmp, OffsetAccessType::TWO_ACCESSES); + AdjustBaseAndOffset(&tmp, OffsetAccessType::TWO_ACCESSES); lwc1(fd, MemOperand(tmp.rm(), tmp.offset() + Register::kMantissaOffset)); if (IsFp32Mode()) { // fp32 mode. FPURegister nextfpreg = FPURegister::from_code(fd.code() + 1); @@ -1284,7 +1284,7 @@ void TurboAssembler::Sdc1(FPURegister fd, const MemOperand& src) { BlockTrampolinePoolScope block_trampoline_pool(this); DCHECK(Register::kMantissaOffset <= 4 && Register::kExponentOffset <= 4); MemOperand tmp = src; - AdjustBaseAndOffset(tmp, OffsetAccessType::TWO_ACCESSES); + AdjustBaseAndOffset(&tmp, OffsetAccessType::TWO_ACCESSES); swc1(fd, MemOperand(tmp.rm(), tmp.offset() + Register::kMantissaOffset)); if (IsFp32Mode()) { // fp32 mode. FPURegister nextfpreg = FPURegister::from_code(fd.code() + 1); @@ -1305,13 +1305,13 @@ void TurboAssembler::Sdc1(FPURegister fd, const MemOperand& src) { void TurboAssembler::Lw(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lw(rd, source); } void TurboAssembler::Sw(Register rd, const MemOperand& rs) { MemOperand dest = rs; - AdjustBaseAndOffset(dest); + AdjustBaseAndOffset(&dest); sw(rd, dest); } @@ -2926,18 +2926,18 @@ Register TurboAssembler::GetRtAsRegisterHelper(const Operand& rt, return r2; } -bool TurboAssembler::CalculateOffset(Label* L, int32_t& offset, +bool TurboAssembler::CalculateOffset(Label* L, int32_t* offset, OffsetSize bits) { if (!is_near(L, bits)) return false; - offset = GetOffset(offset, L, bits); + *offset = GetOffset(*offset, L, bits); return true; } -bool TurboAssembler::CalculateOffset(Label* L, int32_t& offset, OffsetSize bits, - Register& scratch, const Operand& rt) { +bool TurboAssembler::CalculateOffset(Label* L, int32_t* offset, OffsetSize bits, + Register* scratch, const Operand& rt) { if (!is_near(L, bits)) return false; - scratch = GetRtAsRegisterHelper(rt, scratch); - offset = GetOffset(offset, L, bits); + *scratch = GetRtAsRegisterHelper(rt, *scratch); + *offset = GetOffset(*offset, L, bits); return true; } @@ -2955,23 +2955,23 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, BlockTrampolinePoolScope block_trampoline_pool(this); switch (cond) { case cc_always: - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); break; case eq: if (rt.is_reg() && rs.code() == rt.rm().code()) { // Pre R6 beq is used here to make the code patchable. Otherwise bc // should be used which has no condition field so is not patchable. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; beq(rs, scratch, offset); nop(); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; beqzc(rs, offset); } else { // We don't want any other register but scratch clobbered. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; beqc(rs, scratch, offset); } @@ -2980,16 +2980,16 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { // Pre R6 bne is used here to make the code patchable. Otherwise we // should not generate any instruction. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bne(rs, scratch, offset); nop(); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; bnezc(rs, offset); } else { // We don't want any other register but scratch clobbered. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bnec(rs, scratch, offset); } @@ -3001,14 +3001,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bltzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgtzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltc(scratch, rs, offset); @@ -3017,17 +3017,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case greater_equal: // rs >= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; blezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgec(rs, scratch, offset); @@ -3038,14 +3038,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgtzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bltzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltc(rs, scratch, offset); @@ -3054,17 +3054,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case less_equal: // rs <= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; blezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgec(scratch, rs, offset); @@ -3077,14 +3077,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; bnezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; bnezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltuc(scratch, rs, offset); @@ -3093,17 +3093,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case Ugreater_equal: // rs >= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; beqzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgeuc(rs, scratch, offset); @@ -3114,13 +3114,13 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; bnezc(scratch, offset); } else if (IsZero(rt)) { break; // No code needs to be emitted. } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltuc(rs, scratch, offset); @@ -3129,17 +3129,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case Uless_equal: // rs <= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26, &scratch, rt)) return false; bc(offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; beqzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgeuc(scratch, rs, offset); @@ -3418,7 +3418,7 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, DCHECK((cond == cc_always && is_int26(offset)) || is_int16(offset)); switch (cond) { case cc_always: - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); break; case eq: @@ -3440,11 +3440,11 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, if (rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bltzalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgtzalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3456,14 +3456,14 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, case greater_equal: // rs >= rt if (rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; blezalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgezalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3477,11 +3477,11 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, if (rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgtzalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bltzalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3493,14 +3493,14 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, case less_equal: // rs <= r2 if (rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgezalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; blezalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3751,8 +3751,8 @@ void TurboAssembler::Jump(Register target, const Operand& offset, if (IsMipsArchVariant(kMips32r6) && bd == PROTECT && !is_int16(offset.immediate())) { uint32_t aui_offset, jic_offset; - Assembler::UnpackTargetAddressUnsigned(offset.immediate(), aui_offset, - jic_offset); + Assembler::UnpackTargetAddressUnsigned(offset.immediate(), &aui_offset, + &jic_offset); RecordRelocInfo(RelocInfo::EXTERNAL_REFERENCE, offset.immediate()); aui(target, target, aui_offset); if (cond == cc_always) { @@ -3790,7 +3790,7 @@ void TurboAssembler::Jump(intptr_t target, RelocInfo::Mode rmode, // This is not an issue, t9 is expected to be clobbered anyway. if (IsMipsArchVariant(kMips32r6) && bd == PROTECT) { uint32_t lui_offset, jic_offset; - UnpackTargetAddressUnsigned(target, lui_offset, jic_offset); + UnpackTargetAddressUnsigned(target, &lui_offset, &jic_offset); if (MustUseReg(rmode)) { RecordRelocInfo(rmode, target); } @@ -3853,10 +3853,8 @@ void TurboAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode, } void TurboAssembler::Jump(const ExternalReference& reference) { - UseScratchRegisterScope temps(this); - Register scratch = temps.Acquire(); - li(scratch, reference); - Jump(scratch); + li(t9, reference); + Jump(t9); } void MacroAssembler::JumpIfIsInRange(Register value, unsigned lower_limit, @@ -3940,7 +3938,7 @@ void TurboAssembler::Call(Address target, RelocInfo::Mode rmode, Condition cond, int32_t target_int = static_cast<int32_t>(target); if (IsMipsArchVariant(kMips32r6) && bd == PROTECT && cond == cc_always) { uint32_t lui_offset, jialc_offset; - UnpackTargetAddressUnsigned(target_int, lui_offset, jialc_offset); + UnpackTargetAddressUnsigned(target_int, &lui_offset, &jialc_offset); if (MustUseReg(rmode)) { RecordRelocInfo(rmode, target_int); } @@ -3990,7 +3988,6 @@ void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode, } } DCHECK(RelocInfo::IsCodeTarget(rmode)); - AllowDeferredHandleDereference embedding_raw_address; Call(code.address(), rmode, cond, rs, rt, bd); } diff --git a/deps/v8/src/codegen/mips/macro-assembler-mips.h b/deps/v8/src/codegen/mips/macro-assembler-mips.h index d9c372f8687155..e82c88f0b5e4c6 100644 --- a/deps/v8/src/codegen/mips/macro-assembler-mips.h +++ b/deps/v8/src/codegen/mips/macro-assembler-mips.h @@ -849,12 +849,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void BranchShortMSA(MSABranchDF df, Label* target, MSABranchCondition cond, MSARegister wt, BranchDelaySlot bd = PROTECT); - bool CalculateOffset(Label* L, int32_t& offset, // NOLINT(runtime/references) - OffsetSize bits); - bool CalculateOffset(Label* L, int32_t& offset, // NOLINT(runtime/references) - OffsetSize bits, - Register& scratch, // NOLINT(runtime/references) - const Operand& rt); + // TODO(mips) Reorder parameters so out parameters come last. + bool CalculateOffset(Label* L, int32_t* offset, OffsetSize bits); + bool CalculateOffset(Label* L, int32_t* offset, OffsetSize bits, + Register* scratch, const Operand& rt); void BranchShortHelperR6(int32_t offset, Label* L); void BranchShortHelper(int16_t offset, Label* L, BranchDelaySlot bdslot); diff --git a/deps/v8/src/codegen/mips64/assembler-mips64-inl.h b/deps/v8/src/codegen/mips64/assembler-mips64-inl.h index 7b9946d16eb061..cacdbd8f8bbb32 100644 --- a/deps/v8/src/codegen/mips64/assembler-mips64-inl.h +++ b/deps/v8/src/codegen/mips64/assembler-mips64-inl.h @@ -159,7 +159,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, DCHECK(IsCodeTarget(rmode_) || IsFullEmbeddedObject(rmode_)); Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/mips64/assembler-mips64.cc b/deps/v8/src/codegen/mips64/assembler-mips64.cc index 801faf6306d861..37a05585c4b873 100644 --- a/deps/v8/src/codegen/mips64/assembler-mips64.cc +++ b/deps/v8/src/codegen/mips64/assembler-mips64.cc @@ -207,8 +207,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle<HeapObject> object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); break; case HeapObjectRequest::kStringConstant: const StringConstantBase* str = request.string(); @@ -1996,7 +1996,7 @@ void Assembler::dlsa(Register rd, Register rt, Register rs, uint8_t sa) { // ------------Memory-instructions------------- -void Assembler::AdjustBaseAndOffset(MemOperand& src, +void Assembler::AdjustBaseAndOffset(MemOperand* src, OffsetAccessType access_type, int second_access_add_to_offset) { // This method is used to adjust the base register and offset pair @@ -2009,25 +2009,25 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, // pointer register). // We preserve the "alignment" of 'offset' by adjusting it by a multiple of 8. - bool doubleword_aligned = (src.offset() & (kDoubleSize - 1)) == 0; + bool doubleword_aligned = (src->offset() & (kDoubleSize - 1)) == 0; bool two_accesses = static_cast<bool>(access_type) || !doubleword_aligned; DCHECK_LE(second_access_add_to_offset, 7); // Must be <= 7. // is_int16 must be passed a signed value, hence the static cast below. - if (is_int16(src.offset()) && + if (is_int16(src->offset()) && (!two_accesses || is_int16(static_cast<int32_t>( - src.offset() + second_access_add_to_offset)))) { + src->offset() + second_access_add_to_offset)))) { // Nothing to do: 'offset' (and, if needed, 'offset + 4', or other specified // value) fits into int16_t. return; } - DCHECK(src.rm() != + DCHECK(src->rm() != at); // Must not overwrite the register 'base' while loading 'offset'. #ifdef DEBUG // Remember the "(mis)alignment" of 'offset', it will be checked at the end. - uint32_t misalignment = src.offset() & (kDoubleSize - 1); + uint32_t misalignment = src->offset() & (kDoubleSize - 1); #endif // Do not load the whole 32-bit 'offset' if it can be represented as @@ -2042,13 +2042,13 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); - if (0 <= src.offset() && src.offset() <= kMaxOffsetForSimpleAdjustment) { - daddiu(scratch, src.rm(), kMinOffsetForSimpleAdjustment); - src.offset_ -= kMinOffsetForSimpleAdjustment; - } else if (-kMaxOffsetForSimpleAdjustment <= src.offset() && - src.offset() < 0) { - daddiu(scratch, src.rm(), -kMinOffsetForSimpleAdjustment); - src.offset_ += kMinOffsetForSimpleAdjustment; + if (0 <= src->offset() && src->offset() <= kMaxOffsetForSimpleAdjustment) { + daddiu(scratch, src->rm(), kMinOffsetForSimpleAdjustment); + src->offset_ -= kMinOffsetForSimpleAdjustment; + } else if (-kMaxOffsetForSimpleAdjustment <= src->offset() && + src->offset() < 0) { + daddiu(scratch, src->rm(), -kMinOffsetForSimpleAdjustment); + src->offset_ += kMinOffsetForSimpleAdjustment; } else if (kArchVariant == kMips64r6) { // On r6 take advantage of the daui instruction, e.g.: // daui at, base, offset_high @@ -2060,9 +2060,9 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, // daddiu at, at, 8 // lw reg_lo, (offset_low-8)(at) // lw reg_hi, (offset_low-4)(at) - int16_t offset_low = static_cast<uint16_t>(src.offset()); + int16_t offset_low = static_cast<uint16_t>(src->offset()); int32_t offset_low32 = offset_low; - int16_t offset_high = static_cast<uint16_t>(src.offset() >> 16); + int16_t offset_high = static_cast<uint16_t>(src->offset() >> 16); bool increment_hi16 = offset_low < 0; bool overflow_hi16 = false; @@ -2070,7 +2070,7 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, offset_high++; overflow_hi16 = (offset_high == -32768); } - daui(scratch, src.rm(), static_cast<uint16_t>(offset_high)); + daui(scratch, src->rm(), static_cast<uint16_t>(offset_high)); if (overflow_hi16) { dahi(scratch, 1); @@ -2084,7 +2084,7 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, offset_low32 -= kDoubleSize; } - src.offset_ = offset_low32; + src->offset_ = offset_low32; } else { // Do not load the whole 32-bit 'offset' if it can be represented as // a sum of three 16-bit signed offsets. This can save an instruction. @@ -2095,33 +2095,33 @@ void Assembler::AdjustBaseAndOffset(MemOperand& src, 2 * kMinOffsetForSimpleAdjustment; constexpr int32_t kMaxOffsetForMediumAdjustment = 3 * kMinOffsetForSimpleAdjustment; - if (0 <= src.offset() && src.offset() <= kMaxOffsetForMediumAdjustment) { - daddiu(scratch, src.rm(), kMinOffsetForMediumAdjustment / 2); + if (0 <= src->offset() && src->offset() <= kMaxOffsetForMediumAdjustment) { + daddiu(scratch, src->rm(), kMinOffsetForMediumAdjustment / 2); daddiu(scratch, scratch, kMinOffsetForMediumAdjustment / 2); - src.offset_ -= kMinOffsetForMediumAdjustment; - } else if (-kMaxOffsetForMediumAdjustment <= src.offset() && - src.offset() < 0) { - daddiu(scratch, src.rm(), -kMinOffsetForMediumAdjustment / 2); + src->offset_ -= kMinOffsetForMediumAdjustment; + } else if (-kMaxOffsetForMediumAdjustment <= src->offset() && + src->offset() < 0) { + daddiu(scratch, src->rm(), -kMinOffsetForMediumAdjustment / 2); daddiu(scratch, scratch, -kMinOffsetForMediumAdjustment / 2); - src.offset_ += kMinOffsetForMediumAdjustment; + src->offset_ += kMinOffsetForMediumAdjustment; } else { // Now that all shorter options have been exhausted, load the full 32-bit // offset. - int32_t loaded_offset = RoundDown(src.offset(), kDoubleSize); + int32_t loaded_offset = RoundDown(src->offset(), kDoubleSize); lui(scratch, (loaded_offset >> kLuiShift) & kImm16Mask); ori(scratch, scratch, loaded_offset & kImm16Mask); // Load 32-bit offset. - daddu(scratch, scratch, src.rm()); - src.offset_ -= loaded_offset; + daddu(scratch, scratch, src->rm()); + src->offset_ -= loaded_offset; } } - src.rm_ = scratch; + src->rm_ = scratch; - DCHECK(is_int16(src.offset())); + DCHECK(is_int16(src->offset())); if (two_accesses) { DCHECK(is_int16( - static_cast<int32_t>(src.offset() + second_access_add_to_offset))); + static_cast<int32_t>(src->offset() + second_access_add_to_offset))); } - DCHECK(misalignment == (src.offset() & (kDoubleSize - 1))); + DCHECK(misalignment == (src->offset() & (kDoubleSize - 1))); } void Assembler::lb(Register rd, const MemOperand& rs) { @@ -3169,7 +3169,7 @@ MSA_BRANCH_LIST(MSA_BRANCH) #define MSA_LD_ST(name, opcode) \ void Assembler::name(MSARegister wd, const MemOperand& rs) { \ MemOperand source = rs; \ - AdjustBaseAndOffset(source); \ + AdjustBaseAndOffset(&source); \ if (is_int10(source.offset())) { \ GenInstrMsaMI10(opcode, source.offset(), source.rm(), wd); \ } else { \ diff --git a/deps/v8/src/codegen/mips64/assembler-mips64.h b/deps/v8/src/codegen/mips64/assembler-mips64.h index 9695aa652486ff..48733eebea524d 100644 --- a/deps/v8/src/codegen/mips64/assembler-mips64.h +++ b/deps/v8/src/codegen/mips64/assembler-mips64.h @@ -36,7 +36,7 @@ #define V8_CODEGEN_MIPS64_ASSEMBLER_MIPS64_H_ #include <stdio.h> - +#include <memory> #include <set> #include "src/codegen/assembler.h" @@ -1560,7 +1560,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { // Helper function for memory load/store using base register and offset. void AdjustBaseAndOffset( - MemOperand& src, // NOLINT(runtime/references) + MemOperand* src, OffsetAccessType access_type = OffsetAccessType::SINGLE_ACCESS, int second_access_add_to_offset = 4); diff --git a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc index b3537860643784..2ea770d224070e 100644 --- a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc +++ b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc @@ -1166,7 +1166,7 @@ void TurboAssembler::Ulw(Register rd, const MemOperand& rs) { DCHECK(kMipsLwrOffset <= 3 && kMipsLwlOffset <= 3); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 3 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 3); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 3); if (rd != source.rm()) { lwr(rd, MemOperand(source.rm(), source.offset() + kMipsLwrOffset)); lwl(rd, MemOperand(source.rm(), source.offset() + kMipsLwlOffset)); @@ -1201,7 +1201,7 @@ void TurboAssembler::Usw(Register rd, const MemOperand& rs) { DCHECK(kMipsSwrOffset <= 3 && kMipsSwlOffset <= 3); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 3 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 3); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 3); swr(rd, MemOperand(source.rm(), source.offset() + kMipsSwrOffset)); swl(rd, MemOperand(source.rm(), source.offset() + kMipsSwlOffset)); } @@ -1216,7 +1216,7 @@ void TurboAssembler::Ulh(Register rd, const MemOperand& rs) { DCHECK_EQ(kArchVariant, kMips64r2); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); if (source.rm() == scratch) { @@ -1250,7 +1250,7 @@ void TurboAssembler::Ulhu(Register rd, const MemOperand& rs) { DCHECK_EQ(kArchVariant, kMips64r2); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); if (source.rm() == scratch) { @@ -1286,7 +1286,7 @@ void TurboAssembler::Ush(Register rd, const MemOperand& rs, Register scratch) { DCHECK_EQ(kArchVariant, kMips64r2); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 1 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 1); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 1); if (scratch != rd) { mov(scratch, rd); @@ -1314,7 +1314,7 @@ void TurboAssembler::Uld(Register rd, const MemOperand& rs) { DCHECK(kMipsLdrOffset <= 7 && kMipsLdlOffset <= 7); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 7 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 7); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 7); if (rd != source.rm()) { ldr(rd, MemOperand(source.rm(), source.offset() + kMipsLdrOffset)); ldl(rd, MemOperand(source.rm(), source.offset() + kMipsLdlOffset)); @@ -1349,7 +1349,7 @@ void TurboAssembler::Usd(Register rd, const MemOperand& rs) { DCHECK(kMipsSdrOffset <= 7 && kMipsSdlOffset <= 7); MemOperand source = rs; // Adjust offset for two accesses and check if offset + 7 fits into int16_t. - AdjustBaseAndOffset(source, OffsetAccessType::TWO_ACCESSES, 7); + AdjustBaseAndOffset(&source, OffsetAccessType::TWO_ACCESSES, 7); sdr(rd, MemOperand(source.rm(), source.offset() + kMipsSdrOffset)); sdl(rd, MemOperand(source.rm(), source.offset() + kMipsSdlOffset)); } @@ -1411,91 +1411,91 @@ void TurboAssembler::Usdc1(FPURegister fd, const MemOperand& rs, void TurboAssembler::Lb(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lb(rd, source); } void TurboAssembler::Lbu(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lbu(rd, source); } void TurboAssembler::Sb(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); sb(rd, source); } void TurboAssembler::Lh(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lh(rd, source); } void TurboAssembler::Lhu(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lhu(rd, source); } void TurboAssembler::Sh(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); sh(rd, source); } void TurboAssembler::Lw(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lw(rd, source); } void TurboAssembler::Lwu(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); lwu(rd, source); } void TurboAssembler::Sw(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); sw(rd, source); } void TurboAssembler::Ld(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); ld(rd, source); } void TurboAssembler::Sd(Register rd, const MemOperand& rs) { MemOperand source = rs; - AdjustBaseAndOffset(source); + AdjustBaseAndOffset(&source); sd(rd, source); } void TurboAssembler::Lwc1(FPURegister fd, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); lwc1(fd, tmp); } void TurboAssembler::Swc1(FPURegister fs, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); swc1(fs, tmp); } void TurboAssembler::Ldc1(FPURegister fd, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); ldc1(fd, tmp); } void TurboAssembler::Sdc1(FPURegister fs, const MemOperand& src) { MemOperand tmp = src; - AdjustBaseAndOffset(tmp); + AdjustBaseAndOffset(&tmp); sdc1(fs, tmp); } @@ -3362,18 +3362,18 @@ Register TurboAssembler::GetRtAsRegisterHelper(const Operand& rt, return r2; } -bool TurboAssembler::CalculateOffset(Label* L, int32_t& offset, +bool TurboAssembler::CalculateOffset(Label* L, int32_t* offset, OffsetSize bits) { if (!is_near(L, bits)) return false; - offset = GetOffset(offset, L, bits); + *offset = GetOffset(*offset, L, bits); return true; } -bool TurboAssembler::CalculateOffset(Label* L, int32_t& offset, OffsetSize bits, - Register& scratch, const Operand& rt) { +bool TurboAssembler::CalculateOffset(Label* L, int32_t* offset, OffsetSize bits, + Register* scratch, const Operand& rt) { if (!is_near(L, bits)) return false; - scratch = GetRtAsRegisterHelper(rt, scratch); - offset = GetOffset(offset, L, bits); + *scratch = GetRtAsRegisterHelper(rt, *scratch); + *offset = GetOffset(*offset, L, bits); return true; } @@ -3392,23 +3392,23 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, BlockTrampolinePoolScope block_trampoline_pool(this); switch (cond) { case cc_always: - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); break; case eq: if (rt.is_reg() && rs.code() == rt.rm().code()) { // Pre R6 beq is used here to make the code patchable. Otherwise bc // should be used which has no condition field so is not patchable. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; beq(rs, scratch, offset); nop(); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; beqzc(rs, offset); } else { // We don't want any other register but scratch clobbered. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; beqc(rs, scratch, offset); } @@ -3417,16 +3417,16 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { // Pre R6 bne is used here to make the code patchable. Otherwise we // should not generate any instruction. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bne(rs, scratch, offset); nop(); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; bnezc(rs, offset); } else { // We don't want any other register but scratch clobbered. - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bnec(rs, scratch, offset); } @@ -3438,14 +3438,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bltzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgtzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltc(scratch, rs, offset); @@ -3454,17 +3454,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case greater_equal: // rs >= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; blezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgec(rs, scratch, offset); @@ -3475,14 +3475,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgtzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bltzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltc(rs, scratch, offset); @@ -3491,17 +3491,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case less_equal: // rs <= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; blezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgec(scratch, rs, offset); @@ -3514,14 +3514,14 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; bnezc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; bnezc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltuc(scratch, rs, offset); @@ -3530,17 +3530,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case Ugreater_equal: // rs >= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; beqzc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgeuc(rs, scratch, offset); @@ -3551,13 +3551,13 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, if (rt.is_reg() && rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21, &scratch, rt)) return false; bnezc(scratch, offset); } else if (IsZero(rt)) { break; // No code needs to be emitted. } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bltuc(rs, scratch, offset); @@ -3566,17 +3566,17 @@ bool TurboAssembler::BranchShortHelperR6(int32_t offset, Label* L, case Uless_equal: // rs <= rt if (rt.is_reg() && rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; bc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26, &scratch, rt)) return false; bc(offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset21)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false; beqzc(rs, offset); } else { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; DCHECK(rs != scratch); bgeuc(scratch, rs, offset); @@ -3858,7 +3858,7 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, DCHECK((cond == cc_always && is_int26(offset)) || is_int16(offset)); switch (cond) { case cc_always: - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); break; case eq: @@ -3880,11 +3880,11 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, if (rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bltzalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgtzalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3896,14 +3896,14 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, case greater_equal: // rs >= rt if (rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; blezalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bgezalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3917,11 +3917,11 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, if (rs.code() == rt.rm().code()) { break; // No code needs to be emitted. } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgtzalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; bltzalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -3933,14 +3933,14 @@ bool TurboAssembler::BranchAndLinkShortHelperR6(int32_t offset, Label* L, case less_equal: // rs <= r2 if (rs.code() == rt.rm().code()) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset26)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset26)) return false; balc(offset); } else if (rs == zero_reg) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16, scratch, rt)) + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16, &scratch, rt)) return false; bgezalc(scratch, offset); } else if (IsZero(rt)) { - if (!CalculateOffset(L, offset, OffsetSize::kOffset16)) return false; + if (!CalculateOffset(L, &offset, OffsetSize::kOffset16)) return false; blezalc(rs, offset); } else { if (!is_near(L, bits)) return false; @@ -4202,10 +4202,8 @@ void TurboAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode, } void TurboAssembler::Jump(const ExternalReference& reference) { - UseScratchRegisterScope temps(this); - Register scratch = temps.Acquire(); - li(scratch, reference); - Jump(scratch); + li(t9, reference); + Jump(t9); } // Note: To call gcc-compiled C code on mips, you must call through t9. @@ -4284,7 +4282,6 @@ void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode, void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) { STATIC_ASSERT(kSystemPointerSize == 8); - STATIC_ASSERT(kSmiShiftSize == 31); STATIC_ASSERT(kSmiTagSize == 1); STATIC_ASSERT(kSmiTag == 0); diff --git a/deps/v8/src/codegen/mips64/macro-assembler-mips64.h b/deps/v8/src/codegen/mips64/macro-assembler-mips64.h index c2b701a5affcaa..886d64e494b3b0 100644 --- a/deps/v8/src/codegen/mips64/macro-assembler-mips64.h +++ b/deps/v8/src/codegen/mips64/macro-assembler-mips64.h @@ -850,12 +850,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void CallCFunctionHelper(Register function, int num_reg_arguments, int num_double_arguments); - bool CalculateOffset(Label* L, int32_t& offset, // NOLINT(runtime/references) - OffsetSize bits); - bool CalculateOffset(Label* L, int32_t& offset, // NOLINT(runtime/references) - OffsetSize bits, - Register& scratch, // NOLINT(runtime/references) - const Operand& rt); + // TODO(mips) Reorder parameters so out parameters come last. + bool CalculateOffset(Label* L, int32_t* offset, OffsetSize bits); + bool CalculateOffset(Label* L, int32_t* offset, OffsetSize bits, + Register* scratch, const Operand& rt); void BranchShortHelperR6(int32_t offset, Label* L); void BranchShortHelper(int16_t offset, Label* L, BranchDelaySlot bdslot); diff --git a/deps/v8/src/codegen/optimized-compilation-info.cc b/deps/v8/src/codegen/optimized-compilation-info.cc index 7dc94f39cd6a3a..de89371adbf365 100644 --- a/deps/v8/src/codegen/optimized-compilation-info.cc +++ b/deps/v8/src/codegen/optimized-compilation-info.cc @@ -111,15 +111,9 @@ OptimizedCompilationInfo::~OptimizedCompilationInfo() { } void OptimizedCompilationInfo::set_deferred_handles( - std::shared_ptr<DeferredHandles> deferred_handles) { + std::unique_ptr<DeferredHandles> deferred_handles) { DCHECK_NULL(deferred_handles_); - deferred_handles_.swap(deferred_handles); -} - -void OptimizedCompilationInfo::set_deferred_handles( - DeferredHandles* deferred_handles) { - DCHECK_NULL(deferred_handles_); - deferred_handles_.reset(deferred_handles); + deferred_handles_ = std::move(deferred_handles); } void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) { @@ -132,6 +126,7 @@ void OptimizedCompilationInfo::ReopenHandlesInNewHandleScope(Isolate* isolate) { if (!closure_.is_null()) { closure_ = Handle<JSFunction>(*closure_, isolate); } + DCHECK(code_.is_null()); } void OptimizedCompilationInfo::AbortOptimization(BailoutReason reason) { diff --git a/deps/v8/src/codegen/optimized-compilation-info.h b/deps/v8/src/codegen/optimized-compilation-info.h index 624517283e3e2c..2f3afafc68da5e 100644 --- a/deps/v8/src/codegen/optimized-compilation-info.h +++ b/deps/v8/src/codegen/optimized-compilation-info.h @@ -231,11 +231,7 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { osr_frame_ = osr_frame; } - void set_deferred_handles(std::shared_ptr<DeferredHandles> deferred_handles); - void set_deferred_handles(DeferredHandles* deferred_handles); - std::shared_ptr<DeferredHandles> deferred_handles() { - return deferred_handles_; - } + void set_deferred_handles(std::unique_ptr<DeferredHandles> deferred_handles); void ReopenHandlesInNewHandleScope(Isolate* isolate); @@ -330,7 +326,7 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { // OptimizedCompilationInfo allocates. Zone* zone_; - std::shared_ptr<DeferredHandles> deferred_handles_; + std::unique_ptr<DeferredHandles> deferred_handles_; BailoutReason bailout_reason_ = BailoutReason::kNoReason; diff --git a/deps/v8/src/codegen/pending-optimization-table.cc b/deps/v8/src/codegen/pending-optimization-table.cc index b7be9c77757eee..84e36fc8438d08 100644 --- a/deps/v8/src/codegen/pending-optimization-table.cc +++ b/deps/v8/src/codegen/pending-optimization-table.cc @@ -83,7 +83,7 @@ void PendingOptimizationTable::MarkedForOptimization( function->ShortPrint(); PrintF( " should be prepared for optimization with " - "%%PrepareFunctionForOptimize before " + "%%PrepareFunctionForOptimization before " "%%OptimizeFunctionOnNextCall / %%OptimizeOSR "); UNREACHABLE(); } diff --git a/deps/v8/src/codegen/ppc/assembler-ppc-inl.h b/deps/v8/src/codegen/ppc/assembler-ppc-inl.h index 166b9d4423115f..c55a5a9c0bfa0c 100644 --- a/deps/v8/src/codegen/ppc/assembler-ppc-inl.h +++ b/deps/v8/src/codegen/ppc/assembler-ppc-inl.h @@ -144,7 +144,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, DCHECK(IsCodeTarget(rmode_) || rmode_ == FULL_EMBEDDED_OBJECT); Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/ppc/assembler-ppc.cc b/deps/v8/src/codegen/ppc/assembler-ppc.cc index 2a638af0705055..03dbb2edaa0dc3 100644 --- a/deps/v8/src/codegen/ppc/assembler-ppc.cc +++ b/deps/v8/src/codegen/ppc/assembler-ppc.cc @@ -200,8 +200,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Handle<HeapObject> object; switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); break; } case HeapObjectRequest::kStringConstant: { @@ -1121,20 +1121,6 @@ void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o, } #endif -// Function descriptor for AIX. -// Code address skips the function descriptor "header". -// TOC and static chain are ignored and set to 0. -void Assembler::function_descriptor() { - if (ABI_USES_FUNCTION_DESCRIPTORS) { - Label instructions; - DCHECK_EQ(pc_offset(), 0); - emit_label_addr(&instructions); - dp(0); - dp(0); - bind(&instructions); - } -} - int Assembler::instructions_required_for_mov(Register dst, const Operand& src) const { bool canOptimize = diff --git a/deps/v8/src/codegen/ppc/assembler-ppc.h b/deps/v8/src/codegen/ppc/assembler-ppc.h index dee264a75c06bb..c056de9f2feaeb 100644 --- a/deps/v8/src/codegen/ppc/assembler-ppc.h +++ b/deps/v8/src/codegen/ppc/assembler-ppc.h @@ -41,6 +41,7 @@ #define V8_CODEGEN_PPC_ASSEMBLER_PPC_H_ #include <stdio.h> +#include <memory> #include <vector> #include "src/codegen/assembler.h" @@ -839,8 +840,6 @@ class Assembler : public AssemblerBase { void mtfprwa(DoubleRegister dst, Register src); #endif - void function_descriptor(); - // Exception-generating instructions and debugging support void stop(Condition cond = al, int32_t code = kDefaultStopCode, CRegister cr = cr7); diff --git a/deps/v8/src/codegen/ppc/constants-ppc.h b/deps/v8/src/codegen/ppc/constants-ppc.h index f6ebc6a7ba53c5..2e499fd2c41357 100644 --- a/deps/v8/src/codegen/ppc/constants-ppc.h +++ b/deps/v8/src/codegen/ppc/constants-ppc.h @@ -60,6 +60,12 @@ namespace internal { // TODO(sigurds): Change this value once we use relative jumps. constexpr size_t kMaxPCRelativeCodeRangeInMB = 0; +// Used to encode a boolean value when emitting 32 bit +// opcodes which will indicate the presence of function descriptors +constexpr int kHasFunctionDescriptorBitShift = 9; +constexpr int kHasFunctionDescriptorBitMask = 1 + << kHasFunctionDescriptorBitShift; + // Number of registers const int kNumRegisters = 32; diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc index 41162063331b2e..08fb85dd2ced21 100644 --- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc +++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc @@ -209,6 +209,12 @@ void TurboAssembler::Jump(const ExternalReference& reference) { UseScratchRegisterScope temps(this); Register scratch = temps.Acquire(); Move(scratch, reference); + if (ABI_USES_FUNCTION_DESCRIPTORS) { + // AIX uses a function descriptor. When calling C code be + // aware of this descriptor and pick up values from it. + LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(scratch, kPointerSize)); + LoadP(scratch, MemOperand(scratch, 0)); + } Jump(scratch); } @@ -1287,12 +1293,11 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, { // Load receiver to pass it later to DebugOnFunctionCall hook. if (actual.is_reg()) { - mr(r7, actual.reg()); + ShiftLeftImm(r7, actual.reg(), Operand(kPointerSizeLog2)); + LoadPX(r7, MemOperand(sp, r7)); } else { - mov(r7, Operand(actual.immediate())); + LoadP(r7, MemOperand(sp, actual.immediate() << kPointerSizeLog2), r0); } - ShiftLeftImm(r7, r7, Operand(kPointerSizeLog2)); - LoadPX(r7, MemOperand(sp, r7)); FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); if (expected.is_reg()) { @@ -1931,28 +1936,35 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1, void TurboAssembler::CallCFunction(ExternalReference function, int num_reg_arguments, - int num_double_arguments) { + int num_double_arguments, + bool has_function_descriptor) { Move(ip, function); - CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments); + CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments, + has_function_descriptor); } void TurboAssembler::CallCFunction(Register function, int num_reg_arguments, - int num_double_arguments) { - CallCFunctionHelper(function, num_reg_arguments, num_double_arguments); + int num_double_arguments, + bool has_function_descriptor) { + CallCFunctionHelper(function, num_reg_arguments, num_double_arguments, + has_function_descriptor); } void TurboAssembler::CallCFunction(ExternalReference function, - int num_arguments) { - CallCFunction(function, num_arguments, 0); + int num_arguments, + bool has_function_descriptor) { + CallCFunction(function, num_arguments, 0, has_function_descriptor); } -void TurboAssembler::CallCFunction(Register function, int num_arguments) { - CallCFunction(function, num_arguments, 0); +void TurboAssembler::CallCFunction(Register function, int num_arguments, + bool has_function_descriptor) { + CallCFunction(function, num_arguments, 0, has_function_descriptor); } void TurboAssembler::CallCFunctionHelper(Register function, int num_reg_arguments, - int num_double_arguments) { + int num_double_arguments, + bool has_function_descriptor) { DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters); DCHECK(has_frame()); @@ -1977,7 +1989,7 @@ void TurboAssembler::CallCFunctionHelper(Register function, // allow preemption, so the return address in the link register // stays correct. Register dest = function; - if (ABI_USES_FUNCTION_DESCRIPTORS) { + if (ABI_USES_FUNCTION_DESCRIPTORS && has_function_descriptor) { // AIX/PPC64BE Linux uses a function descriptor. When calling C code be // aware of this descriptor and pick up values from it LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(function, kPointerSize)); @@ -2409,51 +2421,51 @@ void MacroAssembler::Xor(Register ra, Register rs, const Operand& rb, void MacroAssembler::CmpSmiLiteral(Register src1, Smi smi, Register scratch, CRegister cr) { -#if V8_TARGET_ARCH_PPC64 +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + Cmpi(src1, Operand(smi), scratch, cr); +#else LoadSmiLiteral(scratch, smi); cmp(src1, scratch, cr); -#else - Cmpi(src1, Operand(smi), scratch, cr); #endif } void MacroAssembler::CmplSmiLiteral(Register src1, Smi smi, Register scratch, CRegister cr) { -#if V8_TARGET_ARCH_PPC64 +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + Cmpli(src1, Operand(smi), scratch, cr); +#else LoadSmiLiteral(scratch, smi); cmpl(src1, scratch, cr); -#else - Cmpli(src1, Operand(smi), scratch, cr); #endif } void MacroAssembler::AddSmiLiteral(Register dst, Register src, Smi smi, Register scratch) { -#if V8_TARGET_ARCH_PPC64 +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + Add(dst, src, static_cast<intptr_t>(smi.ptr()), scratch); +#else LoadSmiLiteral(scratch, smi); add(dst, src, scratch); -#else - Add(dst, src, reinterpret_cast<intptr_t>(smi), scratch); #endif } void MacroAssembler::SubSmiLiteral(Register dst, Register src, Smi smi, Register scratch) { -#if V8_TARGET_ARCH_PPC64 +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + Add(dst, src, -(static_cast<intptr_t>(smi.ptr())), scratch); +#else LoadSmiLiteral(scratch, smi); sub(dst, src, scratch); -#else - Add(dst, src, -(reinterpret_cast<intptr_t>(smi)), scratch); #endif } void MacroAssembler::AndSmiLiteral(Register dst, Register src, Smi smi, Register scratch, RCBit rc) { -#if V8_TARGET_ARCH_PPC64 +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + And(dst, src, Operand(smi), rc); +#else LoadSmiLiteral(scratch, smi); and_(dst, src, scratch, rc); -#else - And(dst, src, Operand(smi), rc); #endif } @@ -2941,14 +2953,18 @@ void TurboAssembler::JumpIfLessThan(Register x, int32_t y, Label* dest) { void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) { STATIC_ASSERT(kSystemPointerSize == 8); - STATIC_ASSERT(kSmiShiftSize == 31); STATIC_ASSERT(kSmiTagSize == 1); STATIC_ASSERT(kSmiTag == 0); // The builtin_index register contains the builtin index as a Smi. // Untagging is folded into the indexing operand below. +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + ShiftLeftImm(builtin_index, builtin_index, + Operand(kSystemPointerSizeLog2 - kSmiShift)); +#else ShiftRightArithImm(builtin_index, builtin_index, kSmiShift - kSystemPointerSizeLog2); +#endif addi(builtin_index, builtin_index, Operand(IsolateData::builtin_entry_table_offset())); LoadPX(builtin_index, MemOperand(kRootRegister, builtin_index)); diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h index fd4cb6014bb322..1c88558fc4a0a3 100644 --- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h +++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h @@ -350,12 +350,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // garbage collection, since that might move the code and invalidate the // return address (unless this is somehow accounted for by the called // function). - void CallCFunction(ExternalReference function, int num_arguments); - void CallCFunction(Register function, int num_arguments); + void CallCFunction(ExternalReference function, int num_arguments, + bool has_function_descriptor = kHasFunctionDescriptor); + void CallCFunction(Register function, int num_arguments, + bool has_function_descriptor = kHasFunctionDescriptor); void CallCFunction(ExternalReference function, int num_reg_arguments, - int num_double_arguments); + int num_double_arguments, + bool has_function_descriptor = kHasFunctionDescriptor); void CallCFunction(Register function, int num_reg_arguments, - int num_double_arguments); + int num_double_arguments, + bool has_function_descriptor = kHasFunctionDescriptor); // Call a runtime routine. This expects {centry} to contain a fitting CEntry // builtin for the target runtime function and uses an indirect call. @@ -642,7 +646,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { int CalculateStackPassedWords(int num_reg_arguments, int num_double_arguments); void CallCFunctionHelper(Register function, int num_reg_arguments, - int num_double_arguments); + int num_double_arguments, + bool has_function_descriptor); void CallRecordWriteStub(Register object, Register address, RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode, Handle<Code> code_target, @@ -876,12 +881,12 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { } void SmiToPtrArrayOffset(Register dst, Register src) { -#if V8_TARGET_ARCH_PPC64 - STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2); - ShiftRightArithImm(dst, src, kSmiShift - kPointerSizeLog2); -#else +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2); ShiftLeftImm(dst, src, Operand(kPointerSizeLog2 - kSmiShift)); +#else + STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2); + ShiftRightArithImm(dst, src, kSmiShift - kPointerSizeLog2); #endif } @@ -895,7 +900,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { void AssertNotSmi(Register object); void AssertSmi(Register object); -#if V8_TARGET_ARCH_PPC64 +#if !defined(V8_COMPRESS_POINTERS) && !defined(V8_31BIT_SMIS_ON_64BIT_ARCH) // Ensure it is permissible to read/write int value directly from // upper half of the smi. STATIC_ASSERT(kSmiTag == 0); diff --git a/deps/v8/src/codegen/reglist.h b/deps/v8/src/codegen/reglist.h index 609e6b88458e13..4f1d35267d0ba2 100644 --- a/deps/v8/src/codegen/reglist.h +++ b/deps/v8/src/codegen/reglist.h @@ -25,20 +25,18 @@ constexpr int NumRegs(RegList list) { return base::bits::CountPopulation(list); } +namespace detail { // Combine two RegLists by building the union of the contained registers. -// Implemented as a Functor to pass it to base::fold even on gcc < 5 (see -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892). -// TODO(clemensh): Remove this once we require gcc >= 5.0. -struct CombineRegListsFunctor { - constexpr RegList operator()(RegList list1, RegList list2) const { - return list1 | list2; - } -}; +// TODO(clemensb): Replace by constexpr lambda once we have C++17. +constexpr RegList CombineRegListsHelper(RegList list1, RegList list2) { + return list1 | list2; +} +} // namespace detail // Combine several RegLists by building the union of the contained registers. template <typename... RegLists> constexpr RegList CombineRegLists(RegLists... lists) { - return base::fold(CombineRegListsFunctor{}, 0, lists...); + return base::fold(detail::CombineRegListsHelper, 0, lists...); } } // namespace internal diff --git a/deps/v8/src/codegen/reloc-info.cc b/deps/v8/src/codegen/reloc-info.cc index a889a8b9c7bfea..039a6746b1b391 100644 --- a/deps/v8/src/codegen/reloc-info.cc +++ b/deps/v8/src/codegen/reloc-info.cc @@ -366,7 +366,7 @@ void RelocInfo::set_target_address(Address target, Assembler::set_target_address_at(pc_, constant_pool_, target, icache_flush_mode); if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && - IsCodeTargetMode(rmode_)) { + IsCodeTargetMode(rmode_) && !FLAG_disable_write_barriers) { Code target_code = Code::GetCodeFromTargetAddress(target); MarkingBarrierForCode(host(), this, target_code); } diff --git a/deps/v8/src/codegen/s390/assembler-s390-inl.h b/deps/v8/src/codegen/s390/assembler-s390-inl.h index 5e7b193c8ace4a..f911bdabf6f301 100644 --- a/deps/v8/src/codegen/s390/assembler-s390-inl.h +++ b/deps/v8/src/codegen/s390/assembler-s390-inl.h @@ -150,7 +150,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, DCHECK(IsCodeTarget(rmode_) || rmode_ == FULL_EMBEDDED_OBJECT); Assembler::set_target_address_at(pc_, constant_pool_, target.ptr(), icache_flush_mode); - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/s390/assembler-s390.cc b/deps/v8/src/codegen/s390/assembler-s390.cc index 873c0a2ad060c8..9de95ed5084bd0 100644 --- a/deps/v8/src/codegen/s390/assembler-s390.cc +++ b/deps/v8/src/codegen/s390/assembler-s390.cc @@ -329,8 +329,8 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - object = isolate->factory()->NewHeapNumber(request.heap_number(), - AllocationType::kOld); + object = isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); set_target_address_at(pc, kNullAddress, object.address(), SKIP_ICACHE_FLUSH); break; diff --git a/deps/v8/src/codegen/s390/assembler-s390.h b/deps/v8/src/codegen/s390/assembler-s390.h index 0653e79b67cf20..f1a418d1afa01e 100644 --- a/deps/v8/src/codegen/s390/assembler-s390.h +++ b/deps/v8/src/codegen/s390/assembler-s390.h @@ -40,6 +40,7 @@ #ifndef V8_CODEGEN_S390_ASSEMBLER_S390_H_ #define V8_CODEGEN_S390_ASSEMBLER_S390_H_ #include <stdio.h> +#include <memory> #if V8_HOST_ARCH_S390 // elf.h include is required for auxv check for STFLE facility used // for hardware detection, which is sensible only on s390 hosts. diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.cc b/deps/v8/src/codegen/s390/macro-assembler-s390.cc index 355d536379a1b6..4cab44d9e1b612 100644 --- a/deps/v8/src/codegen/s390/macro-assembler-s390.cc +++ b/deps/v8/src/codegen/s390/macro-assembler-s390.cc @@ -51,7 +51,7 @@ int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode, } RegList list = kJSCallerSaved & ~exclusions; - bytes += NumRegs(list) * kPointerSize; + bytes += NumRegs(list) * kSystemPointerSize; if (fp_mode == kSaveFPRegs) { bytes += NumRegs(kCallerSavedDoubles) * kDoubleSize; @@ -76,7 +76,7 @@ int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1, RegList list = kJSCallerSaved & ~exclusions; MultiPush(list); - bytes += NumRegs(list) * kPointerSize; + bytes += NumRegs(list) * kSystemPointerSize; if (fp_mode == kSaveFPRegs) { MultiPushDoubles(kCallerSavedDoubles); @@ -107,7 +107,7 @@ int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1, RegList list = kJSCallerSaved & ~exclusions; MultiPop(list); - bytes += NumRegs(list) * kPointerSize; + bytes += NumRegs(list) * kSystemPointerSize; return bytes; } @@ -116,8 +116,8 @@ void TurboAssembler::LoadFromConstantsTable(Register destination, int constant_index) { DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kBuiltinsConstantsTable)); - const uint32_t offset = - FixedArray::kHeaderSize + constant_index * kPointerSize - kHeapObjectTag; + const uint32_t offset = FixedArray::kHeaderSize + + constant_index * kSystemPointerSize - kHeapObjectTag; CHECK(is_uint19(offset)); DCHECK_NE(destination, r0); @@ -258,7 +258,7 @@ void TurboAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode, void TurboAssembler::Drop(int count) { if (count > 0) { - int total = count * kPointerSize; + int total = count * kSystemPointerSize; if (is_uint12(total)) { la(sp, MemOperand(sp, total)); } else if (is_int20(total)) { @@ -270,7 +270,7 @@ void TurboAssembler::Drop(int count) { } void TurboAssembler::Drop(Register count, Register scratch) { - ShiftLeftP(scratch, count, Operand(kPointerSizeLog2)); + ShiftLeftP(scratch, count, Operand(kSystemPointerSizeLog2)); AddP(sp, sp, scratch); } @@ -367,12 +367,12 @@ void TurboAssembler::BranchRelativeOnIdxHighP(Register dst, Register inc, void TurboAssembler::MultiPush(RegList regs, Register location) { int16_t num_to_push = base::bits::CountPopulation(regs); - int16_t stack_offset = num_to_push * kPointerSize; + int16_t stack_offset = num_to_push * kSystemPointerSize; SubP(location, location, Operand(stack_offset)); for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) { if ((regs & (1 << i)) != 0) { - stack_offset -= kPointerSize; + stack_offset -= kSystemPointerSize; StoreP(ToRegister(i), MemOperand(location, stack_offset)); } } @@ -384,7 +384,7 @@ void TurboAssembler::MultiPop(RegList regs, Register location) { for (int16_t i = 0; i < Register::kNumRegisters; i++) { if ((regs & (1 << i)) != 0) { LoadP(ToRegister(i), MemOperand(location, stack_offset)); - stack_offset += kPointerSize; + stack_offset += kSystemPointerSize; } } AddP(location, location, Operand(stack_offset)); @@ -439,13 +439,13 @@ void MacroAssembler::RecordWriteField(Register object, int offset, } // Although the object register is tagged, the offset is relative to the start - // of the object, so so offset must be a multiple of kPointerSize. - DCHECK(IsAligned(offset, kPointerSize)); + // of the object, so so offset must be a multiple of kSystemPointerSize. + DCHECK(IsAligned(offset, kSystemPointerSize)); lay(dst, MemOperand(object, offset - kHeapObjectTag)); if (emit_debug_code()) { Label ok; - AndP(r0, dst, Operand(kPointerSize - 1)); + AndP(r0, dst, Operand(kSystemPointerSize - 1)); beq(&ok, Label::kNear); stop(); bind(&ok); @@ -632,7 +632,7 @@ void TurboAssembler::PushCommonFrame(Register marker_reg) { Push(r14, fp); fp_delta = 0; } - la(fp, MemOperand(sp, fp_delta * kPointerSize)); + la(fp, MemOperand(sp, fp_delta * kSystemPointerSize)); } void TurboAssembler::PopCommonFrame(Register marker_reg) { @@ -653,7 +653,7 @@ void TurboAssembler::PushStandardFrame(Register function_reg) { Push(r14, fp, cp); fp_delta = 1; } - la(fp, MemOperand(sp, fp_delta * kPointerSize)); + la(fp, MemOperand(sp, fp_delta * kSystemPointerSize)); } void TurboAssembler::RestoreFrameStateForTailCall() { @@ -1082,9 +1082,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space, DCHECK(frame_type == StackFrame::EXIT || frame_type == StackFrame::BUILTIN_EXIT); // Set up the frame structure on the stack. - DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); - DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); - DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); + DCHECK_EQ(2 * kSystemPointerSize, ExitFrameConstants::kCallerSPDisplacement); + DCHECK_EQ(1 * kSystemPointerSize, ExitFrameConstants::kCallerPCOffset); + DCHECK_EQ(0 * kSystemPointerSize, ExitFrameConstants::kCallerFPOffset); DCHECK_GT(stack_space, 0); // This is an opportunity to build a frame to wrap @@ -1117,7 +1117,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space, // since the sp slot and code slot were pushed after the fp. } - lay(sp, MemOperand(sp, -stack_space * kPointerSize)); + lay(sp, MemOperand(sp, -stack_space * kSystemPointerSize)); // Allocate and align the frame preparing for calling the runtime // function. @@ -1127,11 +1127,11 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space, ClearRightImm(sp, sp, Operand(3)); // equivalent to &= -8 } - lay(sp, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize)); + lay(sp, MemOperand(sp, -kNumRequiredStackFrameSlots * kSystemPointerSize)); StoreP(MemOperand(sp), Operand::Zero(), r0); // Set the exit frame sp value to point just before the return address // location. - lay(r1, MemOperand(sp, kStackFrameSPSlot * kPointerSize)); + lay(r1, MemOperand(sp, kStackFrameSPSlot * kSystemPointerSize)); StoreP(r1, MemOperand(fp, ExitFrameConstants::kSPOffset)); } @@ -1184,7 +1184,8 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, if (argument_count.is_valid()) { if (!argument_count_is_length) { - ShiftLeftP(argument_count, argument_count, Operand(kPointerSizeLog2)); + ShiftLeftP(argument_count, argument_count, + Operand(kSystemPointerSizeLog2)); } la(sp, MemOperand(sp, argument_count)); } @@ -1211,22 +1212,24 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, #endif // Calculate the end of destination area where we will put the arguments - // after we drop current frame. We AddP kPointerSize to count the receiver - // argument which is not included into formal parameters count. + // after we drop current frame. We AddP kSystemPointerSize to count the + // receiver argument which is not included into formal parameters count. Register dst_reg = scratch0; - ShiftLeftP(dst_reg, caller_args_count_reg, Operand(kPointerSizeLog2)); + ShiftLeftP(dst_reg, caller_args_count_reg, Operand(kSystemPointerSizeLog2)); AddP(dst_reg, fp, dst_reg); AddP(dst_reg, dst_reg, - Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize)); + Operand(StandardFrameConstants::kCallerSPOffset + kSystemPointerSize)); Register src_reg = caller_args_count_reg; - // Calculate the end of source area. +kPointerSize is for the receiver. + // Calculate the end of source area. +kSystemPointerSize is for the receiver. if (callee_args_count.is_reg()) { - ShiftLeftP(src_reg, callee_args_count.reg(), Operand(kPointerSizeLog2)); + ShiftLeftP(src_reg, callee_args_count.reg(), + Operand(kSystemPointerSizeLog2)); AddP(src_reg, sp, src_reg); - AddP(src_reg, src_reg, Operand(kPointerSize)); + AddP(src_reg, src_reg, Operand(kSystemPointerSize)); } else { - mov(src_reg, Operand((callee_args_count.immediate() + 1) * kPointerSize)); + mov(src_reg, + Operand((callee_args_count.immediate() + 1) * kSystemPointerSize)); AddP(src_reg, src_reg, sp); } @@ -1253,10 +1256,10 @@ void TurboAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, } LoadRR(r1, tmp_reg); bind(&loop); - LoadP(tmp_reg, MemOperand(src_reg, -kPointerSize)); - StoreP(tmp_reg, MemOperand(dst_reg, -kPointerSize)); - lay(src_reg, MemOperand(src_reg, -kPointerSize)); - lay(dst_reg, MemOperand(dst_reg, -kPointerSize)); + LoadP(tmp_reg, MemOperand(src_reg, -kSystemPointerSize)); + StoreP(tmp_reg, MemOperand(dst_reg, -kSystemPointerSize)); + lay(src_reg, MemOperand(src_reg, -kSystemPointerSize)); + lay(dst_reg, MemOperand(dst_reg, -kSystemPointerSize)); BranchOnCount(r1, &loop); // Leave current frame. @@ -1342,12 +1345,12 @@ void MacroAssembler::CheckDebugHook(Register fun, Register new_target, { // Load receiver to pass it later to DebugOnFunctionCall hook. if (actual.is_reg()) { - LoadRR(r6, actual.reg()); + ShiftLeftP(r6, actual.reg(), Operand(kSystemPointerSizeLog2)); + LoadP(r6, MemOperand(sp, r6)); } else { - mov(r6, Operand(actual.immediate())); + LoadP(r6, MemOperand(sp, actual.immediate() << kSystemPointerSizeLog2), + ip); } - ShiftLeftP(r6, r6, Operand(kPointerSizeLog2)); - LoadP(r6, MemOperand(sp, r6)); FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); if (expected.is_reg()) { @@ -1470,8 +1473,8 @@ void MacroAssembler::MaybeDropFrames() { void MacroAssembler::PushStackHandler() { // Adjust this code if not the case. - STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kPointerSize); - STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); + STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kSystemPointerSize); + STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kSystemPointerSize); // Link the current handler as the next handler. Move(r7, @@ -1486,13 +1489,13 @@ void MacroAssembler::PushStackHandler() { // Copy the old handler into the next handler slot. MoveChar(MemOperand(sp, StackHandlerConstants::kNextOffset), MemOperand(r7), - Operand(kPointerSize)); + Operand(kSystemPointerSize)); // Set this new handler as the current one. StoreP(sp, MemOperand(r7)); } void MacroAssembler::PopStackHandler() { - STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kPointerSize); + STATIC_ASSERT(StackHandlerConstants::kSize == 2 * kSystemPointerSize); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); // Pop the Next Handler into r3 and store it into Handler Address reference. @@ -1839,18 +1842,19 @@ void TurboAssembler::PrepareCallCFunction(int num_reg_arguments, int stack_passed_arguments = CalculateStackPassedWords(num_reg_arguments, num_double_arguments); int stack_space = kNumRequiredStackFrameSlots; - if (frame_alignment > kPointerSize) { + if (frame_alignment > kSystemPointerSize) { // Make stack end at alignment and make room for stack arguments // -- preserving original value of sp. LoadRR(scratch, sp); - lay(sp, MemOperand(sp, -(stack_passed_arguments + 1) * kPointerSize)); + lay(sp, MemOperand(sp, -(stack_passed_arguments + 1) * kSystemPointerSize)); DCHECK(base::bits::IsPowerOfTwo(frame_alignment)); ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment))); - StoreP(scratch, MemOperand(sp, (stack_passed_arguments)*kPointerSize)); + StoreP(scratch, + MemOperand(sp, (stack_passed_arguments)*kSystemPointerSize)); } else { stack_space += stack_passed_arguments; } - lay(sp, MemOperand(sp, (-stack_space) * kPointerSize)); + lay(sp, MemOperand(sp, (-stack_space) * kSystemPointerSize)); } void TurboAssembler::PrepareCallCFunction(int num_reg_arguments, @@ -1940,11 +1944,11 @@ void TurboAssembler::CallCFunctionHelper(Register function, int stack_passed_arguments = CalculateStackPassedWords(num_reg_arguments, num_double_arguments); int stack_space = kNumRequiredStackFrameSlots + stack_passed_arguments; - if (ActivationFrameAlignment() > kPointerSize) { + if (ActivationFrameAlignment() > kSystemPointerSize) { // Load the original stack pointer (pre-alignment) from the stack - LoadP(sp, MemOperand(sp, stack_space * kPointerSize)); + LoadP(sp, MemOperand(sp, stack_space * kSystemPointerSize)); } else { - la(sp, MemOperand(sp, stack_space * kPointerSize)); + la(sp, MemOperand(sp, stack_space * kSystemPointerSize)); } } @@ -1962,20 +1966,20 @@ void TurboAssembler::CheckPageFlag( uint32_t shifted_mask = mask; // Determine the byte offset to be tested if (mask <= 0x80) { - byte_offset = kPointerSize - 1; + byte_offset = kSystemPointerSize - 1; } else if (mask < 0x8000) { - byte_offset = kPointerSize - 2; + byte_offset = kSystemPointerSize - 2; shifted_mask = mask >> 8; } else if (mask < 0x800000) { - byte_offset = kPointerSize - 3; + byte_offset = kSystemPointerSize - 3; shifted_mask = mask >> 16; } else { - byte_offset = kPointerSize - 4; + byte_offset = kSystemPointerSize - 4; shifted_mask = mask >> 24; } #if V8_TARGET_LITTLE_ENDIAN // Reverse the byte_offset if emulating on little endian platform - byte_offset = kPointerSize - byte_offset - 1; + byte_offset = kSystemPointerSize - byte_offset - 1; #endif tm(MemOperand(scratch, MemoryChunk::kFlagsOffset + byte_offset), Operand(shifted_mask)); @@ -3415,12 +3419,12 @@ void TurboAssembler::LoadIntLiteral(Register dst, int value) { void TurboAssembler::LoadSmiLiteral(Register dst, Smi smi) { intptr_t value = static_cast<intptr_t>(smi.ptr()); -#if V8_TARGET_ARCH_S390X +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + llilf(dst, Operand(value)); +#else DCHECK_EQ(value & 0xFFFFFFFF, 0); // The smi value is loaded in upper 32-bits. Lower 32-bit are zeros. llihf(dst, Operand(value >> 32)); -#else - llilf(dst, Operand(value)); #endif } @@ -3456,16 +3460,16 @@ void TurboAssembler::LoadFloat32Literal(DoubleRegister result, float value, } void TurboAssembler::CmpSmiLiteral(Register src1, Smi smi, Register scratch) { -#if V8_TARGET_ARCH_S390X +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + // CFI takes 32-bit immediate. + cfi(src1, Operand(smi)); +#else if (CpuFeatures::IsSupported(DISTINCT_OPS)) { cih(src1, Operand(static_cast<intptr_t>(smi.ptr()) >> 32)); } else { LoadSmiLiteral(scratch, smi); cgr(src1, scratch); } -#else - // CFI takes 32-bit immediate. - cfi(src1, Operand(smi)); #endif } @@ -4154,7 +4158,7 @@ void TurboAssembler::ShiftRightArith(Register dst, Register src, Register val) { // Clear right most # of bits void TurboAssembler::ClearRightImm(Register dst, Register src, const Operand& val) { - int numBitsToClear = val.immediate() % (kPointerSize * 8); + int numBitsToClear = val.immediate() % (kSystemPointerSize * 8); // Try to use RISBG if possible if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) { @@ -4342,14 +4346,19 @@ void TurboAssembler::JumpIfLessThan(Register x, int32_t y, Label* dest) { void TurboAssembler::LoadEntryFromBuiltinIndex(Register builtin_index) { STATIC_ASSERT(kSystemPointerSize == 8); - STATIC_ASSERT(kSmiShiftSize == 31); STATIC_ASSERT(kSmiTagSize == 1); STATIC_ASSERT(kSmiTag == 0); // The builtin_index register contains the builtin index as a Smi. // Untagging is folded into the indexing operand below. +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + STATIC_ASSERT(kSmiShiftSize == 0); + ShiftLeftP(builtin_index, builtin_index, + Operand(kSystemPointerSizeLog2 - kSmiShift)); +#else ShiftRightArithP(builtin_index, builtin_index, Operand(kSmiShift - kSystemPointerSizeLog2)); +#endif AddP(builtin_index, builtin_index, Operand(IsolateData::builtin_entry_table_offset())); LoadP(builtin_index, MemOperand(kRootRegister, builtin_index)); @@ -4427,7 +4436,7 @@ void TurboAssembler::StoreReturnAddressAndCall(Register target) { Label return_label; larl(r14, &return_label); // Generate the return addr of call later. - StoreP(r14, MemOperand(sp, kStackFrameRASlot * kPointerSize)); + StoreP(r14, MemOperand(sp, kStackFrameRASlot * kSystemPointerSize)); // zLinux ABI requires caller's frame to have sufficient space for callee // preserved regsiter save area. diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.h b/deps/v8/src/codegen/s390/macro-assembler-s390.h index 856e4b592ecef0..06c26cb305f984 100644 --- a/deps/v8/src/codegen/s390/macro-assembler-s390.h +++ b/deps/v8/src/codegen/s390/macro-assembler-s390.h @@ -515,26 +515,26 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { } void push(DoubleRegister src) { - lay(sp, MemOperand(sp, -kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize)); StoreDouble(src, MemOperand(sp)); } void push(Register src) { - lay(sp, MemOperand(sp, -kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize)); StoreP(src, MemOperand(sp)); } void pop(DoubleRegister dst) { LoadDouble(dst, MemOperand(sp)); - la(sp, MemOperand(sp, kPointerSize)); + la(sp, MemOperand(sp, kSystemPointerSize)); } void pop(Register dst) { LoadP(dst, MemOperand(sp)); - la(sp, MemOperand(sp, kPointerSize)); + la(sp, MemOperand(sp, kSystemPointerSize)); } - void pop() { la(sp, MemOperand(sp, kPointerSize)); } + void pop() { la(sp, MemOperand(sp, kSystemPointerSize)); } void Push(Register src) { push(src); } @@ -544,25 +544,25 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // Push two registers. Pushes leftmost register first (to highest address). void Push(Register src1, Register src2) { - lay(sp, MemOperand(sp, -kPointerSize * 2)); - StoreP(src1, MemOperand(sp, kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize * 2)); + StoreP(src1, MemOperand(sp, kSystemPointerSize)); StoreP(src2, MemOperand(sp, 0)); } // Push three registers. Pushes leftmost register first (to highest address). void Push(Register src1, Register src2, Register src3) { - lay(sp, MemOperand(sp, -kPointerSize * 3)); - StoreP(src1, MemOperand(sp, kPointerSize * 2)); - StoreP(src2, MemOperand(sp, kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize * 3)); + StoreP(src1, MemOperand(sp, kSystemPointerSize * 2)); + StoreP(src2, MemOperand(sp, kSystemPointerSize)); StoreP(src3, MemOperand(sp, 0)); } // Push four registers. Pushes leftmost register first (to highest address). void Push(Register src1, Register src2, Register src3, Register src4) { - lay(sp, MemOperand(sp, -kPointerSize * 4)); - StoreP(src1, MemOperand(sp, kPointerSize * 3)); - StoreP(src2, MemOperand(sp, kPointerSize * 2)); - StoreP(src3, MemOperand(sp, kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize * 4)); + StoreP(src1, MemOperand(sp, kSystemPointerSize * 3)); + StoreP(src2, MemOperand(sp, kSystemPointerSize * 2)); + StoreP(src3, MemOperand(sp, kSystemPointerSize)); StoreP(src4, MemOperand(sp, 0)); } @@ -580,11 +580,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { DCHECK(src3 != src5); DCHECK(src4 != src5); - lay(sp, MemOperand(sp, -kPointerSize * 5)); - StoreP(src1, MemOperand(sp, kPointerSize * 4)); - StoreP(src2, MemOperand(sp, kPointerSize * 3)); - StoreP(src3, MemOperand(sp, kPointerSize * 2)); - StoreP(src4, MemOperand(sp, kPointerSize)); + lay(sp, MemOperand(sp, -kSystemPointerSize * 5)); + StoreP(src1, MemOperand(sp, kSystemPointerSize * 4)); + StoreP(src2, MemOperand(sp, kSystemPointerSize * 3)); + StoreP(src3, MemOperand(sp, kSystemPointerSize * 2)); + StoreP(src4, MemOperand(sp, kSystemPointerSize)); StoreP(src5, MemOperand(sp, 0)); } @@ -593,36 +593,36 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // Pop two registers. Pops rightmost register first (from lower address). void Pop(Register src1, Register src2) { LoadP(src2, MemOperand(sp, 0)); - LoadP(src1, MemOperand(sp, kPointerSize)); - la(sp, MemOperand(sp, 2 * kPointerSize)); + LoadP(src1, MemOperand(sp, kSystemPointerSize)); + la(sp, MemOperand(sp, 2 * kSystemPointerSize)); } // Pop three registers. Pops rightmost register first (from lower address). void Pop(Register src1, Register src2, Register src3) { LoadP(src3, MemOperand(sp, 0)); - LoadP(src2, MemOperand(sp, kPointerSize)); - LoadP(src1, MemOperand(sp, 2 * kPointerSize)); - la(sp, MemOperand(sp, 3 * kPointerSize)); + LoadP(src2, MemOperand(sp, kSystemPointerSize)); + LoadP(src1, MemOperand(sp, 2 * kSystemPointerSize)); + la(sp, MemOperand(sp, 3 * kSystemPointerSize)); } // Pop four registers. Pops rightmost register first (from lower address). void Pop(Register src1, Register src2, Register src3, Register src4) { LoadP(src4, MemOperand(sp, 0)); - LoadP(src3, MemOperand(sp, kPointerSize)); - LoadP(src2, MemOperand(sp, 2 * kPointerSize)); - LoadP(src1, MemOperand(sp, 3 * kPointerSize)); - la(sp, MemOperand(sp, 4 * kPointerSize)); + LoadP(src3, MemOperand(sp, kSystemPointerSize)); + LoadP(src2, MemOperand(sp, 2 * kSystemPointerSize)); + LoadP(src1, MemOperand(sp, 3 * kSystemPointerSize)); + la(sp, MemOperand(sp, 4 * kSystemPointerSize)); } // Pop five registers. Pops rightmost register first (from lower address). void Pop(Register src1, Register src2, Register src3, Register src4, Register src5) { LoadP(src5, MemOperand(sp, 0)); - LoadP(src4, MemOperand(sp, kPointerSize)); - LoadP(src3, MemOperand(sp, 2 * kPointerSize)); - LoadP(src2, MemOperand(sp, 3 * kPointerSize)); - LoadP(src1, MemOperand(sp, 4 * kPointerSize)); - la(sp, MemOperand(sp, 5 * kPointerSize)); + LoadP(src4, MemOperand(sp, kSystemPointerSize)); + LoadP(src3, MemOperand(sp, 2 * kSystemPointerSize)); + LoadP(src2, MemOperand(sp, 3 * kSystemPointerSize)); + LoadP(src1, MemOperand(sp, 4 * kSystemPointerSize)); + la(sp, MemOperand(sp, 5 * kSystemPointerSize)); } // Push a fixed frame, consisting of lr, fp, constant pool. @@ -1182,12 +1182,12 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { } void SmiToPtrArrayOffset(Register dst, Register src) { -#if V8_TARGET_ARCH_S390X - STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2); - ShiftRightArithP(dst, src, Operand(kSmiShift - kPointerSizeLog2)); +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kSystemPointerSizeLog2); + ShiftLeftP(dst, src, Operand(kSystemPointerSizeLog2 - kSmiShift)); #else - STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2); - ShiftLeftP(dst, src, Operand(kPointerSizeLog2 - kSmiShift)); + STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kSystemPointerSizeLog2); + ShiftRightArithP(dst, src, Operand(kSmiShift - kSystemPointerSizeLog2)); #endif } @@ -1201,14 +1201,14 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { void AssertNotSmi(Register object); void AssertSmi(Register object); -#if V8_TARGET_ARCH_S390X +#if !defined(V8_COMPRESS_POINTERS) && !defined(V8_31BIT_SMIS_ON_64BIT_ARCH) // Ensure it is permissible to read/write int value directly from // upper half of the smi. STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); #endif #if V8_TARGET_LITTLE_ENDIAN -#define SmiWordOffset(offset) (offset + kPointerSize / 2) +#define SmiWordOffset(offset) (offset + kSystemPointerSize / 2) #else #define SmiWordOffset(offset) offset #endif diff --git a/deps/v8/src/codegen/source-position-table.cc b/deps/v8/src/codegen/source-position-table.cc index 870241eac69b92..ba8e5981f06fb2 100644 --- a/deps/v8/src/codegen/source-position-table.cc +++ b/deps/v8/src/codegen/source-position-table.cc @@ -31,24 +31,23 @@ using MoreBit = BitField8<bool, 7, 1>; using ValueBits = BitField8<unsigned, 0, 7>; // Helper: Add the offsets from 'other' to 'value'. Also set is_statement. -void AddAndSetEntry(PositionTableEntry& value, // NOLINT(runtime/references) +void AddAndSetEntry(PositionTableEntry* value, const PositionTableEntry& other) { - value.code_offset += other.code_offset; - value.source_position += other.source_position; - value.is_statement = other.is_statement; + value->code_offset += other.code_offset; + value->source_position += other.source_position; + value->is_statement = other.is_statement; } // Helper: Subtract the offsets from 'other' from 'value'. -void SubtractFromEntry(PositionTableEntry& value, // NOLINT(runtime/references) +void SubtractFromEntry(PositionTableEntry* value, const PositionTableEntry& other) { - value.code_offset -= other.code_offset; - value.source_position -= other.source_position; + value->code_offset -= other.code_offset; + value->source_position -= other.source_position; } // Helper: Encode an integer. template <typename T> -void EncodeInt(std::vector<byte>& bytes, // NOLINT(runtime/references) - T value) { +void EncodeInt(std::vector<byte>* bytes, T value) { using unsigned_type = typename std::make_unsigned<T>::type; // Zig-zag encoding. static const int kShift = sizeof(T) * kBitsPerByte - 1; @@ -60,14 +59,13 @@ void EncodeInt(std::vector<byte>& bytes, // NOLINT(runtime/references) more = encoded > ValueBits::kMax; byte current = MoreBit::encode(more) | ValueBits::encode(encoded & ValueBits::kMask); - bytes.push_back(current); + bytes->push_back(current); encoded >>= ValueBits::kSize; } while (more); } // Encode a PositionTableEntry. -void EncodeEntry(std::vector<byte>& bytes, // NOLINT(runtime/references) - const PositionTableEntry& entry) { +void EncodeEntry(std::vector<byte>* bytes, const PositionTableEntry& entry) { // We only accept ascending code offsets. DCHECK_GE(entry.code_offset, 0); // Since code_offset is not negative, we use sign to encode is_statement. @@ -115,17 +113,16 @@ Vector<const byte> VectorFromByteArray(ByteArray byte_array) { } #ifdef ENABLE_SLOW_DCHECKS -void CheckTableEquals( - std::vector<PositionTableEntry>& raw_entries, // NOLINT(runtime/references) - SourcePositionTableIterator& encoded) { // NOLINT(runtime/references) +void CheckTableEquals(const std::vector<PositionTableEntry>& raw_entries, + SourcePositionTableIterator* encoded) { // Brute force testing: Record all positions and decode // the entire table to verify they are identical. auto raw = raw_entries.begin(); - for (; !encoded.done(); encoded.Advance(), raw++) { + for (; !encoded->done(); encoded->Advance(), raw++) { DCHECK(raw != raw_entries.end()); - DCHECK_EQ(encoded.code_offset(), raw->code_offset); - DCHECK_EQ(encoded.source_position().raw(), raw->source_position); - DCHECK_EQ(encoded.is_statement(), raw->is_statement); + DCHECK_EQ(encoded->code_offset(), raw->code_offset); + DCHECK_EQ(encoded->source_position().raw(), raw->source_position); + DCHECK_EQ(encoded->is_statement(), raw->is_statement); } DCHECK(raw == raw_entries.end()); } @@ -148,8 +145,8 @@ void SourcePositionTableBuilder::AddPosition(size_t code_offset, void SourcePositionTableBuilder::AddEntry(const PositionTableEntry& entry) { PositionTableEntry tmp(entry); - SubtractFromEntry(tmp, previous_); - EncodeEntry(bytes_, tmp); + SubtractFromEntry(&tmp, previous_); + EncodeEntry(&bytes_, tmp); previous_ = entry; #ifdef ENABLE_SLOW_DCHECKS raw_entries_.push_back(entry); @@ -169,7 +166,7 @@ Handle<ByteArray> SourcePositionTableBuilder::ToSourcePositionTable( // Brute force testing: Record all positions and decode // the entire table to verify they are identical. SourcePositionTableIterator it(*table, SourcePositionTableIterator::kAll); - CheckTableEquals(raw_entries_, it); + CheckTableEquals(raw_entries_, &it); // No additional source positions after creating the table. mode_ = OMIT_SOURCE_POSITIONS; #endif @@ -187,7 +184,7 @@ OwnedVector<byte> SourcePositionTableBuilder::ToSourcePositionTableVector() { // the entire table to verify they are identical. SourcePositionTableIterator it(table.as_vector(), SourcePositionTableIterator::kAll); - CheckTableEquals(raw_entries_, it); + CheckTableEquals(raw_entries_, &it); // No additional source positions after creating the table. mode_ = OMIT_SOURCE_POSITIONS; #endif @@ -232,7 +229,7 @@ void SourcePositionTableIterator::Advance() { } else { PositionTableEntry tmp; DecodeEntry(bytes, &index_, &tmp); - AddAndSetEntry(current_, tmp); + AddAndSetEntry(¤t_, tmp); SourcePosition p = source_position(); filter_satisfied = (filter_ == kAll) || (filter_ == kJavaScriptOnly && p.IsJavaScript()) || diff --git a/deps/v8/src/codegen/tnode.h b/deps/v8/src/codegen/tnode.h new file mode 100644 index 00000000000000..1f6c627929b11e --- /dev/null +++ b/deps/v8/src/codegen/tnode.h @@ -0,0 +1,374 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_CODEGEN_TNODE_H_ +#define V8_CODEGEN_TNODE_H_ + +#include "src/codegen/machine-type.h" + +namespace v8 { +namespace internal { + +class HeapNumber; +class BigInt; +class Object; + +namespace compiler { + +class Node; + +} + +struct UntaggedT {}; + +struct IntegralT : UntaggedT {}; + +struct WordT : IntegralT { + static const MachineRepresentation kMachineRepresentation = + (kSystemPointerSize == 4) ? MachineRepresentation::kWord32 + : MachineRepresentation::kWord64; +}; + +struct RawPtrT : WordT { + static constexpr MachineType kMachineType = MachineType::Pointer(); +}; + +template <class To> +struct RawPtr : RawPtrT {}; + +struct Word32T : IntegralT { + static const MachineRepresentation kMachineRepresentation = + MachineRepresentation::kWord32; +}; +struct Int32T : Word32T { + static constexpr MachineType kMachineType = MachineType::Int32(); +}; +struct Uint32T : Word32T { + static constexpr MachineType kMachineType = MachineType::Uint32(); +}; +struct Int16T : Int32T { + static constexpr MachineType kMachineType = MachineType::Int16(); +}; +struct Uint16T : Uint32T, Int32T { + static constexpr MachineType kMachineType = MachineType::Uint16(); +}; +struct Int8T : Int16T { + static constexpr MachineType kMachineType = MachineType::Int8(); +}; +struct Uint8T : Uint16T, Int16T { + static constexpr MachineType kMachineType = MachineType::Uint8(); +}; + +struct Word64T : IntegralT { + static const MachineRepresentation kMachineRepresentation = + MachineRepresentation::kWord64; +}; +struct Int64T : Word64T { + static constexpr MachineType kMachineType = MachineType::Int64(); +}; +struct Uint64T : Word64T { + static constexpr MachineType kMachineType = MachineType::Uint64(); +}; + +struct IntPtrT : WordT { + static constexpr MachineType kMachineType = MachineType::IntPtr(); +}; +struct UintPtrT : WordT { + static constexpr MachineType kMachineType = MachineType::UintPtr(); +}; + +struct Float32T : UntaggedT { + static const MachineRepresentation kMachineRepresentation = + MachineRepresentation::kFloat32; + static constexpr MachineType kMachineType = MachineType::Float32(); +}; + +struct Float64T : UntaggedT { + static const MachineRepresentation kMachineRepresentation = + MachineRepresentation::kFloat64; + static constexpr MachineType kMachineType = MachineType::Float64(); +}; + +#ifdef V8_COMPRESS_POINTERS +using TaggedT = Int32T; +#else +using TaggedT = IntPtrT; +#endif + +// Result of a comparison operation. +struct BoolT : Word32T {}; + +// Value type of a Turbofan node with two results. +template <class T1, class T2> +struct PairT {}; + +inline constexpr MachineType CommonMachineType(MachineType type1, + MachineType type2) { + return (type1 == type2) ? type1 + : ((type1.IsTagged() && type2.IsTagged()) + ? MachineType::AnyTagged() + : MachineType::None()); +} + +template <class Type, class Enable = void> +struct MachineTypeOf { + static constexpr MachineType value = Type::kMachineType; +}; + +template <class Type, class Enable> +constexpr MachineType MachineTypeOf<Type, Enable>::value; + +template <> +struct MachineTypeOf<Object> { + static constexpr MachineType value = MachineType::AnyTagged(); +}; +template <> +struct MachineTypeOf<MaybeObject> { + static constexpr MachineType value = MachineType::AnyTagged(); +}; +template <> +struct MachineTypeOf<Smi> { + static constexpr MachineType value = MachineType::TaggedSigned(); +}; +template <class HeapObjectSubtype> +struct MachineTypeOf<HeapObjectSubtype, + typename std::enable_if<std::is_base_of< + HeapObject, HeapObjectSubtype>::value>::type> { + static constexpr MachineType value = MachineType::TaggedPointer(); +}; + +template <class HeapObjectSubtype> +constexpr MachineType MachineTypeOf< + HeapObjectSubtype, typename std::enable_if<std::is_base_of< + HeapObject, HeapObjectSubtype>::value>::type>::value; + +template <class Type, class Enable = void> +struct MachineRepresentationOf { + static const MachineRepresentation value = Type::kMachineRepresentation; +}; +template <class T> +struct MachineRepresentationOf< + T, typename std::enable_if<std::is_base_of<Object, T>::value>::type> { + static const MachineRepresentation value = + MachineTypeOf<T>::value.representation(); +}; +template <class T> +struct MachineRepresentationOf< + T, typename std::enable_if<std::is_base_of<MaybeObject, T>::value>::type> { + static const MachineRepresentation value = + MachineTypeOf<T>::value.representation(); +}; +template <> +struct MachineRepresentationOf<ExternalReference> { + static const MachineRepresentation value = RawPtrT::kMachineRepresentation; +}; + +template <class T> +struct is_valid_type_tag { + static const bool value = std::is_base_of<Object, T>::value || + std::is_base_of<UntaggedT, T>::value || + std::is_base_of<MaybeObject, T>::value || + std::is_same<ExternalReference, T>::value; + static const bool is_tagged = std::is_base_of<Object, T>::value || + std::is_base_of<MaybeObject, T>::value; +}; + +template <class T1, class T2> +struct is_valid_type_tag<PairT<T1, T2>> { + static const bool value = + is_valid_type_tag<T1>::value && is_valid_type_tag<T2>::value; + static const bool is_tagged = false; +}; + +template <class T1, class T2> +struct UnionT; + +template <class T1, class T2> +struct is_valid_type_tag<UnionT<T1, T2>> { + static const bool is_tagged = + is_valid_type_tag<T1>::is_tagged && is_valid_type_tag<T2>::is_tagged; + static const bool value = is_tagged; +}; + +template <class T1, class T2> +struct UnionT { + static constexpr MachineType kMachineType = + CommonMachineType(MachineTypeOf<T1>::value, MachineTypeOf<T2>::value); + static const MachineRepresentation kMachineRepresentation = + kMachineType.representation(); + static_assert(kMachineRepresentation != MachineRepresentation::kNone, + "no common representation"); + static_assert(is_valid_type_tag<T1>::is_tagged && + is_valid_type_tag<T2>::is_tagged, + "union types are only possible for tagged values"); +}; + +using AnyTaggedT = UnionT<Object, MaybeObject>; +using Number = UnionT<Smi, HeapNumber>; +using Numeric = UnionT<Number, BigInt>; + +// A pointer to a builtin function, used by Torque's function pointers. +using BuiltinPtr = Smi; + +class int31_t { + public: + int31_t() : value_(0) {} + int31_t(int value) : value_(value) { // NOLINT(runtime/explicit) + DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0); + } + int31_t& operator=(int value) { + DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0); + value_ = value; + return *this; + } + int32_t value() const { return value_; } + operator int32_t() const { return value_; } + + private: + int32_t value_; +}; + +template <class T, class U> +struct is_subtype { + static const bool value = std::is_base_of<U, T>::value; +}; +template <class T1, class T2, class U> +struct is_subtype<UnionT<T1, T2>, U> { + static const bool value = + is_subtype<T1, U>::value && is_subtype<T2, U>::value; +}; +template <class T, class U1, class U2> +struct is_subtype<T, UnionT<U1, U2>> { + static const bool value = + is_subtype<T, U1>::value || is_subtype<T, U2>::value; +}; +template <class T1, class T2, class U1, class U2> +struct is_subtype<UnionT<T1, T2>, UnionT<U1, U2>> { + static const bool value = + (is_subtype<T1, U1>::value || is_subtype<T1, U2>::value) && + (is_subtype<T2, U1>::value || is_subtype<T2, U2>::value); +}; + +template <class T, class U> +struct types_have_common_values { + static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value; +}; +template <class U> +struct types_have_common_values<BoolT, U> { + static const bool value = types_have_common_values<Word32T, U>::value; +}; +template <class U> +struct types_have_common_values<Uint32T, U> { + static const bool value = types_have_common_values<Word32T, U>::value; +}; +template <class U> +struct types_have_common_values<Int32T, U> { + static const bool value = types_have_common_values<Word32T, U>::value; +}; +template <class U> +struct types_have_common_values<Uint64T, U> { + static const bool value = types_have_common_values<Word64T, U>::value; +}; +template <class U> +struct types_have_common_values<Int64T, U> { + static const bool value = types_have_common_values<Word64T, U>::value; +}; +template <class U> +struct types_have_common_values<IntPtrT, U> { + static const bool value = types_have_common_values<WordT, U>::value; +}; +template <class U> +struct types_have_common_values<UintPtrT, U> { + static const bool value = types_have_common_values<WordT, U>::value; +}; +template <class T1, class T2, class U> +struct types_have_common_values<UnionT<T1, T2>, U> { + static const bool value = types_have_common_values<T1, U>::value || + types_have_common_values<T2, U>::value; +}; + +template <class T, class U1, class U2> +struct types_have_common_values<T, UnionT<U1, U2>> { + static const bool value = types_have_common_values<T, U1>::value || + types_have_common_values<T, U2>::value; +}; +template <class T1, class T2, class U1, class U2> +struct types_have_common_values<UnionT<T1, T2>, UnionT<U1, U2>> { + static const bool value = types_have_common_values<T1, U1>::value || + types_have_common_values<T1, U2>::value || + types_have_common_values<T2, U1>::value || + types_have_common_values<T2, U2>::value; +}; + +template <class T> +struct types_have_common_values<T, MaybeObject> { + static const bool value = types_have_common_values<T, Object>::value; +}; + +template <class T> +struct types_have_common_values<MaybeObject, T> { + static const bool value = types_have_common_values<Object, T>::value; +}; + +// TNode<T> is an SSA value with the static type tag T, which is one of the +// following: +// - a subclass of internal::Object represents a tagged type +// - a subclass of internal::UntaggedT represents an untagged type +// - ExternalReference +// - PairT<T1, T2> for an operation returning two values, with types T1 +// and T2 +// - UnionT<T1, T2> represents either a value of type T1 or of type T2. +template <class T> +class TNode { + public: + template <class U, + typename std::enable_if<is_subtype<U, T>::value, int>::type = 0> + TNode(const TNode<U>& other) : node_(other) { + LazyTemplateChecks(); + } + TNode() : TNode(nullptr) {} + + TNode operator=(TNode other) { + DCHECK_NOT_NULL(other.node_); + node_ = other.node_; + return *this; + } + + bool is_null() { return node_ == nullptr; } + + operator compiler::Node*() const { return node_; } + + static TNode UncheckedCast(compiler::Node* node) { return TNode(node); } + + protected: + explicit TNode(compiler::Node* node) : node_(node) { LazyTemplateChecks(); } + + private: + // These checks shouldn't be checked before TNode is actually used. + void LazyTemplateChecks() { + static_assert(is_valid_type_tag<T>::value, "invalid type tag"); + } + + compiler::Node* node_; +}; + +// SloppyTNode<T> is a variant of TNode<T> and allows implicit casts from +// Node*. It is intended for function arguments as long as some call sites +// still use untyped Node* arguments. +// TODO(tebbi): Delete this class once transition is finished. +template <class T> +class SloppyTNode : public TNode<T> { + public: + SloppyTNode(compiler::Node* node) // NOLINT(runtime/explicit) + : TNode<T>(node) {} + template <class U, typename std::enable_if<is_subtype<U, T>::value, + int>::type = 0> + SloppyTNode(const TNode<U>& other) // NOLINT(runtime/explicit) + : TNode<T>(other) {} +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_CODEGEN_TNODE_H_ diff --git a/deps/v8/src/codegen/turbo-assembler.h b/deps/v8/src/codegen/turbo-assembler.h index 3a3e65a41e753d..6e11ad5c3fbf69 100644 --- a/deps/v8/src/codegen/turbo-assembler.h +++ b/deps/v8/src/codegen/turbo-assembler.h @@ -5,6 +5,8 @@ #ifndef V8_CODEGEN_TURBO_ASSEMBLER_H_ #define V8_CODEGEN_TURBO_ASSEMBLER_H_ +#include <memory> + #include "src/base/template-utils.h" #include "src/builtins/builtins.h" #include "src/codegen/assembler-arch.h" @@ -100,7 +102,7 @@ class V8_EXPORT_PRIVATE TurboAssemblerBase : public Assembler { static bool IsAddressableThroughRootRegister( Isolate* isolate, const ExternalReference& reference); -#if V8_OS_WIN +#ifdef V8_TARGET_OS_WIN // Minimum page size. We must touch memory once per page when expanding the // stack, to avoid access violations. static constexpr int kStackPageSize = 4 * KB; diff --git a/deps/v8/src/codegen/x64/assembler-x64-inl.h b/deps/v8/src/codegen/x64/assembler-x64-inl.h index f5d0c0ffcf528c..d8457d9d3e38a0 100644 --- a/deps/v8/src/codegen/x64/assembler-x64-inl.h +++ b/deps/v8/src/codegen/x64/assembler-x64-inl.h @@ -218,6 +218,7 @@ Address Assembler::target_address_at(Address pc, Address constant_pool) { void Assembler::set_target_address_at(Address pc, Address constant_pool, Address target, ICacheFlushMode icache_flush_mode) { + DCHECK(is_int32(target - pc - 4)); WriteUnalignedValue(pc, static_cast<int32_t>(target - pc - 4)); if (icache_flush_mode != SKIP_ICACHE_FLUSH) { FlushInstructionCache(pc, sizeof(int32_t)); @@ -363,7 +364,8 @@ void RelocInfo::set_target_object(Heap* heap, HeapObject target, if (icache_flush_mode != SKIP_ICACHE_FLUSH) { FlushInstructionCache(pc_, sizeof(Address)); } - if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null()) { + if (write_barrier_mode == UPDATE_WRITE_BARRIER && !host().is_null() && + !FLAG_disable_write_barriers) { WriteBarrierForCode(host(), this, target); } } diff --git a/deps/v8/src/codegen/x64/assembler-x64.cc b/deps/v8/src/codegen/x64/assembler-x64.cc index 1783da700ba53d..16791a6453926d 100644 --- a/deps/v8/src/codegen/x64/assembler-x64.cc +++ b/deps/v8/src/codegen/x64/assembler-x64.cc @@ -327,8 +327,9 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { Address pc = reinterpret_cast<Address>(buffer_start_) + request.offset(); switch (request.kind()) { case HeapObjectRequest::kHeapNumber: { - Handle<HeapNumber> object = isolate->factory()->NewHeapNumber( - request.heap_number(), AllocationType::kOld); + Handle<HeapNumber> object = + isolate->factory()->NewHeapNumber<AllocationType::kOld>( + request.heap_number()); WriteUnalignedValue(pc, object); break; } @@ -1777,6 +1778,13 @@ void Assembler::emit_mov(Register dst, Immediate64 value, int size) { } } +void Assembler::movq_imm64(Register dst, int64_t value) { + EnsureSpace ensure_space(this); + emit_rex(dst, kInt64Size); + emit(0xB8 | dst.low_bits()); + emitq(static_cast<uint64_t>(value)); +} + void Assembler::movq_heap_number(Register dst, double value) { EnsureSpace ensure_space(this); emit_rex(dst, kInt64Size); @@ -1963,6 +1971,13 @@ void Assembler::emit_repmovs(int size) { emit(0xA5); } +void Assembler::repstosq() { + EnsureSpace ensure_space(this); + emit(0xF3); + emit_rex_64(); + emit(0xAB); +} + void Assembler::mull(Register src) { EnsureSpace ensure_space(this); emit_optional_rex_32(src); @@ -4099,6 +4114,42 @@ void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1, emit_sse_operand(dst, src2); } +void Assembler::vfmaps(byte op, XMMRegister dst, XMMRegister src1, + XMMRegister src2) { + DCHECK(IsEnabled(FMA3)); + EnsureSpace ensure_space(this); + emit_vex_prefix(dst, src1, src2, kL128, k66, k0F38, kW0); + emit(op); + emit_sse_operand(dst, src2); +} + +void Assembler::vfmaps(byte op, XMMRegister dst, XMMRegister src1, + Operand src2) { + DCHECK(IsEnabled(FMA3)); + EnsureSpace ensure_space(this); + emit_vex_prefix(dst, src1, src2, kL128, k66, k0F38, kW0); + emit(op); + emit_sse_operand(dst, src2); +} + +void Assembler::vfmapd(byte op, XMMRegister dst, XMMRegister src1, + XMMRegister src2) { + DCHECK(IsEnabled(FMA3)); + EnsureSpace ensure_space(this); + emit_vex_prefix(dst, src1, src2, kL128, k66, k0F38, kW1); + emit(op); + emit_sse_operand(dst, src2); +} + +void Assembler::vfmapd(byte op, XMMRegister dst, XMMRegister src1, + Operand src2) { + DCHECK(IsEnabled(FMA3)); + EnsureSpace ensure_space(this); + emit_vex_prefix(dst, src1, src2, kL128, k66, k0F38, kW1); + emit(op); + emit_sse_operand(dst, src2); +} + void Assembler::vmovd(XMMRegister dst, Register src) { DCHECK(IsEnabled(AVX)); EnsureSpace ensure_space(this); diff --git a/deps/v8/src/codegen/x64/assembler-x64.h b/deps/v8/src/codegen/x64/assembler-x64.h index 7c69b4c4736dff..74cfd0ab850500 100644 --- a/deps/v8/src/codegen/x64/assembler-x64.h +++ b/deps/v8/src/codegen/x64/assembler-x64.h @@ -39,6 +39,7 @@ #include <deque> #include <map> +#include <memory> #include <vector> #include "src/codegen/assembler.h" @@ -155,7 +156,9 @@ enum ScaleFactor : int8_t { times_4 = 2, times_8 = 3, times_int_size = times_4, - times_system_pointer_size = (kSystemPointerSize == 8) ? times_8 : times_4, + + times_half_system_pointer_size = times_4, + times_system_pointer_size = times_8, times_tagged_size = (kTaggedSize == 8) ? times_8 : times_4, }; @@ -513,12 +516,16 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void movq_string(Register dst, const StringConstantBase* str); - // Loads a 64-bit immediate into a register. + // Loads a 64-bit immediate into a register, potentially using the constant + // pool. void movq(Register dst, int64_t value) { movq(dst, Immediate64(value)); } void movq(Register dst, uint64_t value) { movq(dst, Immediate64(static_cast<int64_t>(value))); } + // Loads a 64-bit immediate into a register without using the constant pool. + void movq_imm64(Register dst, int64_t value); + void movsxbl(Register dst, Register src); void movsxbl(Register dst, Operand src); void movsxbq(Register dst, Register src); @@ -531,12 +538,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void movsxlq(Register dst, Operand src); // Repeated moves. - void repmovsb(); void repmovsw(); void repmovsl() { emit_repmovs(kInt32Size); } void repmovsq() { emit_repmovs(kInt64Size); } + // Repeated store of quadwords (fill RCX quadwords at [RDI] with RAX). + void repstosq(); + // Instruction to load from an immediate 64-bit pointer into RAX. void load_rax(Address value, RelocInfo::Mode rmode); void load_rax(ExternalReference ext); @@ -1295,6 +1304,36 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); void vfmass(byte op, XMMRegister dst, XMMRegister src1, Operand src2); + void vfmadd231ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + vfmaps(0xb8, dst, src1, src2); + } + void vfmadd231ps(XMMRegister dst, XMMRegister src1, Operand src2) { + vfmaps(0xb8, dst, src1, src2); + } + void vfnmadd231ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + vfmaps(0xbc, dst, src1, src2); + } + void vfnmadd231ps(XMMRegister dst, XMMRegister src1, Operand src2) { + vfmaps(0xbc, dst, src1, src2); + } + void vfmaps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); + void vfmaps(byte op, XMMRegister dst, XMMRegister src1, Operand src2); + + void vfmadd231pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + vfmapd(0xb8, dst, src1, src2); + } + void vfmadd231pd(XMMRegister dst, XMMRegister src1, Operand src2) { + vfmapd(0xb8, dst, src1, src2); + } + void vfnmadd231pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { + vfmapd(0xbc, dst, src1, src2); + } + void vfnmadd231pd(XMMRegister dst, XMMRegister src1, Operand src2) { + vfmapd(0xbc, dst, src1, src2); + } + void vfmapd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2); + void vfmapd(byte op, XMMRegister dst, XMMRegister src1, Operand src2); + void vmovd(XMMRegister dst, Register src); void vmovd(XMMRegister dst, Operand src); void vmovd(Register dst, XMMRegister src); @@ -1330,7 +1369,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { impl(opcode, dst, src1, src2); \ } - AVX_SP_3(vsqrt, 0x51) + // vsqrtpd is defined by sqrtpd in SSE2_INSTRUCTION_LIST + AVX_S_3(vsqrt, 0x51) + AVX_3(vsqrtps, 0x51, vps) AVX_S_3(vadd, 0x58) AVX_S_3(vsub, 0x5c) AVX_S_3(vmul, 0x59) diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.cc b/deps/v8/src/codegen/x64/macro-assembler-x64.cc index 4deeb1bc02df08..d02b95b38e1736 100644 --- a/deps/v8/src/codegen/x64/macro-assembler-x64.cc +++ b/deps/v8/src/codegen/x64/macro-assembler-x64.cc @@ -218,45 +218,45 @@ void TurboAssembler::CompareRoot(Operand with, RootIndex index) { void TurboAssembler::LoadTaggedPointerField(Register destination, Operand field_operand) { -#ifdef V8_COMPRESS_POINTERS - DecompressTaggedPointer(destination, field_operand); -#else - mov_tagged(destination, field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DecompressTaggedPointer(destination, field_operand); + } else { + mov_tagged(destination, field_operand); + } } void TurboAssembler::LoadAnyTaggedField(Register destination, Operand field_operand, Register scratch) { -#ifdef V8_COMPRESS_POINTERS - DecompressAnyTagged(destination, field_operand, scratch); -#else - mov_tagged(destination, field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DecompressAnyTagged(destination, field_operand, scratch); + } else { + mov_tagged(destination, field_operand); + } } void TurboAssembler::PushTaggedPointerField(Operand field_operand, Register scratch) { -#ifdef V8_COMPRESS_POINTERS - DCHECK(!field_operand.AddressUsesRegister(scratch)); - DecompressTaggedPointer(scratch, field_operand); - Push(scratch); -#else - Push(field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DCHECK(!field_operand.AddressUsesRegister(scratch)); + DecompressTaggedPointer(scratch, field_operand); + Push(scratch); + } else { + Push(field_operand); + } } void TurboAssembler::PushTaggedAnyField(Operand field_operand, Register scratch1, Register scratch2) { -#ifdef V8_COMPRESS_POINTERS - DCHECK(!AreAliased(scratch1, scratch2)); - DCHECK(!field_operand.AddressUsesRegister(scratch1)); - DCHECK(!field_operand.AddressUsesRegister(scratch2)); - DecompressAnyTagged(scratch1, field_operand, scratch2); - Push(scratch1); -#else - Push(field_operand); -#endif + if (COMPRESS_POINTERS_BOOL) { + DCHECK(!AreAliased(scratch1, scratch2)); + DCHECK(!field_operand.AddressUsesRegister(scratch1)); + DCHECK(!field_operand.AddressUsesRegister(scratch2)); + DecompressAnyTagged(scratch1, field_operand, scratch2); + Push(scratch1); + } else { + Push(field_operand); + } } void TurboAssembler::SmiUntagField(Register dst, Operand src) { @@ -265,44 +265,40 @@ void TurboAssembler::SmiUntagField(Register dst, Operand src) { void TurboAssembler::StoreTaggedField(Operand dst_field_operand, Immediate value) { -#ifdef V8_COMPRESS_POINTERS - RecordComment("[ StoreTagged"); - movl(dst_field_operand, value); - RecordComment("]"); -#else - movq(dst_field_operand, value); -#endif + if (COMPRESS_POINTERS_BOOL) { + movl(dst_field_operand, value); + } else { + movq(dst_field_operand, value); + } } void TurboAssembler::StoreTaggedField(Operand dst_field_operand, Register value) { -#ifdef V8_COMPRESS_POINTERS - RecordComment("[ StoreTagged"); - movl(dst_field_operand, value); - RecordComment("]"); -#else - movq(dst_field_operand, value); -#endif + if (COMPRESS_POINTERS_BOOL) { + movl(dst_field_operand, value); + } else { + movq(dst_field_operand, value); + } } void TurboAssembler::DecompressTaggedSigned(Register destination, Operand field_operand) { RecordComment("[ DecompressTaggedSigned"); - movsxlq(destination, field_operand); + movl(destination, field_operand); RecordComment("]"); } void TurboAssembler::DecompressTaggedSigned(Register destination, Register source) { RecordComment("[ DecompressTaggedSigned"); - movsxlq(destination, source); + movl(destination, source); RecordComment("]"); } void TurboAssembler::DecompressTaggedPointer(Register destination, Operand field_operand) { RecordComment("[ DecompressTaggedPointer"); - movsxlq(destination, field_operand); + movl(destination, field_operand); addq(destination, kRootRegister); RecordComment("]"); } @@ -310,30 +306,14 @@ void TurboAssembler::DecompressTaggedPointer(Register destination, void TurboAssembler::DecompressTaggedPointer(Register destination, Register source) { RecordComment("[ DecompressTaggedPointer"); - movsxlq(destination, source); + movl(destination, source); addq(destination, kRootRegister); RecordComment("]"); } void TurboAssembler::DecompressRegisterAnyTagged(Register destination, Register scratch) { - if (kUseBranchlessPtrDecompressionInGeneratedCode) { - // Branchlessly compute |masked_root|: - // masked_root = HAS_SMI_TAG(destination) ? 0 : kRootRegister; - STATIC_ASSERT((kSmiTagSize == 1) && (kSmiTag < 32)); - Register masked_root = scratch; - xorq(masked_root, masked_root); - Condition smi = CheckSmi(destination); - cmovq(NegateCondition(smi), masked_root, kRootRegister); - // Now this add operation will either leave the value unchanged if it is - // a smi or add the isolate root if it is a heap object. - addq(destination, masked_root); - } else { - Label done; - JumpIfSmi(destination, &done); - addq(destination, kRootRegister); - bind(&done); - } + addq(destination, kRootRegister); } void TurboAssembler::DecompressAnyTagged(Register destination, @@ -341,7 +321,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination, Register scratch) { DCHECK(!AreAliased(destination, scratch)); RecordComment("[ DecompressAnyTagged"); - movsxlq(destination, field_operand); + movl(destination, field_operand); DecompressRegisterAnyTagged(destination, scratch); RecordComment("]"); } @@ -350,7 +330,7 @@ void TurboAssembler::DecompressAnyTagged(Register destination, Register source, Register scratch) { DCHECK(!AreAliased(destination, scratch)); RecordComment("[ DecompressAnyTagged"); - movsxlq(destination, source); + movl(destination, source); DecompressRegisterAnyTagged(destination, scratch); RecordComment("]"); } @@ -1109,7 +1089,11 @@ Register TurboAssembler::GetSmiConstant(Smi source) { xorl(kScratchRegister, kScratchRegister); return kScratchRegister; } - Move(kScratchRegister, source); + if (SmiValuesAre32Bits()) { + Move(kScratchRegister, source); + } else { + movl(kScratchRegister, Immediate(source)); + } return kScratchRegister; } @@ -1133,20 +1117,47 @@ void TurboAssembler::Move(Register dst, ExternalReference ext) { movq(dst, Immediate64(ext.address(), RelocInfo::EXTERNAL_REFERENCE)); } -void MacroAssembler::SmiTag(Register dst, Register src) { +void MacroAssembler::SmiTag(Register reg) { STATIC_ASSERT(kSmiTag == 0); - if (dst != src) { + DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); + if (COMPRESS_POINTERS_BOOL) { + shll(reg, Immediate(kSmiShift)); + } else { + shlq(reg, Immediate(kSmiShift)); + } +} + +void MacroAssembler::SmiTag(Register dst, Register src) { + DCHECK(dst != src); + if (COMPRESS_POINTERS_BOOL) { + movl(dst, src); + } else { movq(dst, src); } + SmiTag(dst); +} + +void TurboAssembler::SmiUntag(Register reg) { + STATIC_ASSERT(kSmiTag == 0); DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); - shlq(dst, Immediate(kSmiShift)); + // TODO(v8:7703): Is there a way to avoid this sign extension when pointer + // compression is enabled? + if (COMPRESS_POINTERS_BOOL) { + movsxlq(reg, reg); + } + sarq(reg, Immediate(kSmiShift)); } void TurboAssembler::SmiUntag(Register dst, Register src) { - STATIC_ASSERT(kSmiTag == 0); - if (dst != src) { + DCHECK(dst != src); + if (COMPRESS_POINTERS_BOOL) { + movsxlq(dst, src); + } else { movq(dst, src); } + // TODO(v8:7703): Call SmiUntag(reg) if we can find a way to avoid the extra + // mov when pointer compression is enabled. + STATIC_ASSERT(kSmiTag == 0); DCHECK(SmiValuesAre32Bits() || SmiValuesAre31Bits()); sarq(dst, Immediate(kSmiShift)); } @@ -1158,12 +1169,13 @@ void TurboAssembler::SmiUntag(Register dst, Operand src) { movsxlq(dst, dst); } else { DCHECK(SmiValuesAre31Bits()); -#ifdef V8_COMPRESS_POINTERS - movsxlq(dst, src); -#else - movq(dst, src); -#endif - sarq(dst, Immediate(kSmiShift)); + if (COMPRESS_POINTERS_BOOL) { + movsxlq(dst, src); + sarq(dst, Immediate(kSmiShift)); + } else { + movq(dst, src); + sarq(dst, Immediate(kSmiShift)); + } } } @@ -1283,12 +1295,9 @@ SmiIndex MacroAssembler::SmiToIndex(Register dst, Register src, int shift) { return SmiIndex(dst, times_1); } else { DCHECK(SmiValuesAre31Bits()); - if (dst != src) { - mov_tagged(dst, src); - } // We have to sign extend the index register to 64-bit as the SMI might // be negative. - movsxlq(dst, dst); + movsxlq(dst, src); if (shift < kSmiShift) { sarq(dst, Immediate(kSmiShift - shift)); } else if (shift != kSmiShift) { @@ -1423,7 +1432,6 @@ void MacroAssembler::Negpd(XMMRegister dst) { } void MacroAssembler::Cmp(Register dst, Handle<Object> source) { - AllowDeferredHandleDereference smi_check; if (source->IsSmi()) { Cmp(dst, Smi::cast(*source)); } else { @@ -1433,7 +1441,6 @@ void MacroAssembler::Cmp(Register dst, Handle<Object> source) { } void MacroAssembler::Cmp(Operand dst, Handle<Object> source) { - AllowDeferredHandleDereference smi_check; if (source->IsSmi()) { Cmp(dst, Smi::cast(*source)); } else { @@ -1463,6 +1470,8 @@ void TurboAssembler::Move(Register result, Handle<HeapObject> object, RelocInfo::Mode rmode) { if (FLAG_embedded_builtins) { if (root_array_available_ && options().isolate_independent_code) { + // TODO(v8:9706): Fix-it! This load will always uncompress the value + // even when we are loading a compressed embedded object. IndirectLoadConstant(result, object); return; } @@ -1605,26 +1614,20 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { } Operand TurboAssembler::EntryFromBuiltinIndexAsOperand(Register builtin_index) { -#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) - STATIC_ASSERT(kSmiShiftSize == 0); - STATIC_ASSERT(kSmiTagSize == 1); - STATIC_ASSERT(kSmiTag == 0); - - // The builtin_index register contains the builtin index as a Smi. - // Untagging is folded into the indexing operand below (we use times_4 instead - // of times_8 since smis are already shifted by one). - return Operand(kRootRegister, builtin_index, times_4, - IsolateData::builtin_entry_table_offset()); -#else // defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) - STATIC_ASSERT(kSmiShiftSize == 31); - STATIC_ASSERT(kSmiTagSize == 1); - STATIC_ASSERT(kSmiTag == 0); + if (SmiValuesAre32Bits()) { + // The builtin_index register contains the builtin index as a Smi. + SmiUntag(builtin_index); + return Operand(kRootRegister, builtin_index, times_system_pointer_size, + IsolateData::builtin_entry_table_offset()); + } else { + DCHECK(SmiValuesAre31Bits()); - // The builtin_index register contains the builtin index as a Smi. - SmiUntag(builtin_index, builtin_index); - return Operand(kRootRegister, builtin_index, times_8, - IsolateData::builtin_entry_table_offset()); -#endif // defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) + // The builtin_index register contains the builtin index as a Smi. + // Untagging is folded into the indexing operand below (we use + // times_half_system_pointer_size since smis are already shifted by one). + return Operand(kRootRegister, builtin_index, times_half_system_pointer_size, + IsolateData::builtin_entry_table_offset()); + } } void TurboAssembler::CallBuiltinByIndex(Register builtin_index) { @@ -1739,7 +1742,11 @@ void TurboAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { Movd(dst, src); return; } - if (CpuFeatures::IsSupported(SSE4_1)) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpextrd(dst, src, imm8); + return; + } else if (CpuFeatures::IsSupported(SSE4_1)) { CpuFeatureScope sse_scope(this, SSE4_1); pextrd(dst, src, imm8); return; @@ -1749,8 +1756,38 @@ void TurboAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { shrq(dst, Immediate(32)); } +void TurboAssembler::Pextrw(Register dst, XMMRegister src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpextrw(dst, src, imm8); + return; + } else { + DCHECK(CpuFeatures::IsSupported(SSE4_1)); + CpuFeatureScope sse_scope(this, SSE4_1); + pextrw(dst, src, imm8); + return; + } +} + +void TurboAssembler::Pextrb(Register dst, XMMRegister src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpextrb(dst, src, imm8); + return; + } else { + DCHECK(CpuFeatures::IsSupported(SSE4_1)); + CpuFeatureScope sse_scope(this, SSE4_1); + pextrb(dst, src, imm8); + return; + } +} + void TurboAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { - if (CpuFeatures::IsSupported(SSE4_1)) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrd(dst, dst, src, imm8); + return; + } else if (CpuFeatures::IsSupported(SSE4_1)) { CpuFeatureScope sse_scope(this, SSE4_1); pinsrd(dst, src, imm8); return; @@ -1765,7 +1802,11 @@ void TurboAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { } void TurboAssembler::Pinsrd(XMMRegister dst, Operand src, int8_t imm8) { - if (CpuFeatures::IsSupported(SSE4_1)) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrd(dst, dst, src, imm8); + return; + } else if (CpuFeatures::IsSupported(SSE4_1)) { CpuFeatureScope sse_scope(this, SSE4_1); pinsrd(dst, src, imm8); return; @@ -1779,6 +1820,56 @@ void TurboAssembler::Pinsrd(XMMRegister dst, Operand src, int8_t imm8) { } } +void TurboAssembler::Pinsrw(XMMRegister dst, Register src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrw(dst, dst, src, imm8); + return; + } else { + DCHECK(CpuFeatures::IsSupported(SSE4_1)); + CpuFeatureScope sse_scope(this, SSE4_1); + pinsrw(dst, src, imm8); + return; + } +} + +void TurboAssembler::Pinsrw(XMMRegister dst, Operand src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrw(dst, dst, src, imm8); + return; + } else { + CpuFeatureScope sse_scope(this, SSE4_1); + pinsrw(dst, src, imm8); + return; + } +} + +void TurboAssembler::Pinsrb(XMMRegister dst, Register src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrb(dst, dst, src, imm8); + return; + } else { + DCHECK(CpuFeatures::IsSupported(SSE4_1)); + CpuFeatureScope sse_scope(this, SSE4_1); + pinsrb(dst, src, imm8); + return; + } +} + +void TurboAssembler::Pinsrb(XMMRegister dst, Operand src, int8_t imm8) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpinsrb(dst, dst, src, imm8); + return; + } else { + CpuFeatureScope sse_scope(this, SSE4_1); + pinsrb(dst, src, imm8); + return; + } +} + void TurboAssembler::Psllq(XMMRegister dst, byte imm8) { if (CpuFeatures::IsSupported(AVX)) { CpuFeatureScope scope(this, AVX); @@ -1819,6 +1910,16 @@ void TurboAssembler::Psrld(XMMRegister dst, byte imm8) { } } +void TurboAssembler::Pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vpshufd(dst, src, shuffle); + } else { + DCHECK(!IsEnabled(AVX)); + pshufd(dst, src, shuffle); + } +} + void TurboAssembler::Lzcntl(Register dst, Register src) { if (CpuFeatures::IsSupported(LZCNT)) { CpuFeatureScope scope(this, LZCNT); @@ -2278,7 +2379,16 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK_IMPLIES(new_target.is_valid(), new_target == rdx); // On function call, call into the debugger if necessary. - CheckDebugHook(function, new_target, expected, actual); + Label debug_hook, continue_after_hook; + { + ExternalReference debug_hook_active = + ExternalReference::debug_hook_on_function_call_address(isolate()); + Operand debug_hook_active_operand = + ExternalReferenceAsOperand(debug_hook_active); + cmpb(debug_hook_active_operand, Immediate(0)); + j(not_equal, &debug_hook, Label::kNear); + } + bind(&continue_after_hook); // Clear the new.target register if not given. if (!new_target.is_valid()) { @@ -2302,8 +2412,15 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(flag == JUMP_FUNCTION); JumpCodeObject(rcx); } - bind(&done); } + jmp(&done, Label::kNear); + + // Deferred debug hook. + bind(&debug_hook); + CallDebugOnFunctionCall(function, new_target, expected, actual); + jmp(&continue_after_hook, Label::kNear); + + bind(&done); } void MacroAssembler::InvokePrologue(const ParameterCount& expected, @@ -2368,50 +2485,38 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } } -void MacroAssembler::CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual) { - Label skip_hook; - ExternalReference debug_hook_active = - ExternalReference::debug_hook_on_function_call_address(isolate()); - Operand debug_hook_active_operand = - ExternalReferenceAsOperand(debug_hook_active); - cmpb(debug_hook_active_operand, Immediate(0)); - j(equal, &skip_hook); - - { - FrameScope frame(this, - has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); - if (expected.is_reg()) { - SmiTag(expected.reg(), expected.reg()); - Push(expected.reg()); - } - if (actual.is_reg()) { - SmiTag(actual.reg(), actual.reg()); - Push(actual.reg()); - SmiUntag(actual.reg(), actual.reg()); - } - if (new_target.is_valid()) { - Push(new_target); - } - Push(fun); - Push(fun); - Push(StackArgumentsAccessor(rbp, actual).GetReceiverOperand()); - CallRuntime(Runtime::kDebugOnFunctionCall); - Pop(fun); - if (new_target.is_valid()) { - Pop(new_target); - } - if (actual.is_reg()) { - Pop(actual.reg()); - SmiUntag(actual.reg(), actual.reg()); - } - if (expected.is_reg()) { - Pop(expected.reg()); - SmiUntag(expected.reg(), expected.reg()); - } +void MacroAssembler::CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual) { + FrameScope frame(this, has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); + if (expected.is_reg()) { + SmiTag(expected.reg()); + Push(expected.reg()); + } + if (actual.is_reg()) { + SmiTag(actual.reg()); + Push(actual.reg()); + SmiUntag(actual.reg()); + } + if (new_target.is_valid()) { + Push(new_target); + } + Push(fun); + Push(fun); + Push(StackArgumentsAccessor(rbp, actual).GetReceiverOperand()); + CallRuntime(Runtime::kDebugOnFunctionCall); + Pop(fun); + if (new_target.is_valid()) { + Pop(new_target); + } + if (actual.is_reg()) { + Pop(actual.reg()); + SmiUntag(actual.reg()); + } + if (expected.is_reg()) { + Pop(expected.reg()); + SmiUntag(expected.reg()); } - bind(&skip_hook); } void TurboAssembler::StubPrologue(StackFrame::Type type) { @@ -2443,7 +2548,7 @@ void TurboAssembler::LeaveFrame(StackFrame::Type type) { popq(rbp); } -#ifdef V8_OS_WIN +#ifdef V8_TARGET_OS_WIN void TurboAssembler::AllocateStackSpace(Register bytes_scratch) { // In windows, we cannot increment the stack size by more than one page // (minimum page size is 4KB) without accessing at least one byte on the @@ -2511,7 +2616,7 @@ void MacroAssembler::EnterExitFramePrologue(bool save_rax, void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles) { -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN const int kShadowSpace = 4; arg_stack_space += kShadowSpace; #endif @@ -2615,7 +2720,7 @@ void MacroAssembler::LeaveExitFrameEpilogue() { movq(c_entry_fp_operand, Immediate(0)); } -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN static const int kRegisterPassedArguments = 4; #else static const int kRegisterPassedArguments = 6; @@ -2634,7 +2739,7 @@ int TurboAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers // and the caller does not reserve stack slots for them. DCHECK_GE(num_arguments, 0); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN const int kMinimumStackSlots = kRegisterPassedArguments; if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; return num_arguments; diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.h b/deps/v8/src/codegen/x64/macro-assembler-x64.h index 8e7766c7e1946c..f38da45788c162 100644 --- a/deps/v8/src/codegen/x64/macro-assembler-x64.h +++ b/deps/v8/src/codegen/x64/macro-assembler-x64.h @@ -152,8 +152,26 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { AVX_OP(Roundsd, roundsd) AVX_OP(Sqrtss, sqrtss) AVX_OP(Sqrtsd, sqrtsd) + AVX_OP(Sqrtpd, sqrtpd) AVX_OP(Ucomiss, ucomiss) AVX_OP(Ucomisd, ucomisd) + AVX_OP(Pshufb, pshufb) + AVX_OP(Paddusb, paddusb) + AVX_OP(Psignd, psignd) + AVX_OP(Pand, pand) + AVX_OP(Por, por) + AVX_OP(Pxor, pxor) + AVX_OP(Psubd, psubd) + AVX_OP(Pslld, pslld) + AVX_OP(Psrad, psrad) + AVX_OP(Psrld, psrld) + AVX_OP(Paddd, paddd) + AVX_OP(Pmulld, pmulld) + AVX_OP(Pminsd, pminsd) + AVX_OP(Pminud, pminud) + AVX_OP(Pmaxsd, pmaxsd) + AVX_OP(Pmaxud, pmaxud) + AVX_OP(Pcmpgtd, pcmpgtd) #undef AVX_OP @@ -314,6 +332,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { RelocInfo::Mode rmode = RelocInfo::FULL_EMBEDDED_OBJECT); // Convert smi to word-size sign-extended value. + void SmiUntag(Register reg); + // Requires dst != src void SmiUntag(Register dst, Register src); void SmiUntag(Register dst, Operand src); @@ -365,14 +385,22 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // Non-SSE2 instructions. void Pextrd(Register dst, XMMRegister src, int8_t imm8); + void Pextrw(Register dst, XMMRegister src, int8_t imm8); + void Pextrb(Register dst, XMMRegister src, int8_t imm8); void Pinsrd(XMMRegister dst, Register src, int8_t imm8); void Pinsrd(XMMRegister dst, Operand src, int8_t imm8); + void Pinsrw(XMMRegister dst, Register src, int8_t imm8); + void Pinsrw(XMMRegister dst, Operand src, int8_t imm8); + void Pinsrb(XMMRegister dst, Register src, int8_t imm8); + void Pinsrb(XMMRegister dst, Operand src, int8_t imm8); void Psllq(XMMRegister dst, byte imm8); void Psrlq(XMMRegister dst, byte imm8); void Pslld(XMMRegister dst, byte imm8); void Psrld(XMMRegister dst, byte imm8); + void Pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle); + void CompareRoot(Register with, RootIndex index); void CompareRoot(Operand with, RootIndex index); @@ -414,7 +442,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // stack check, do it before calling this function because this function may // write into the newly allocated space. It may also overwrite the given // register's value, in the version that takes a register. -#ifdef V8_OS_WIN +#ifdef V8_TARGET_OS_WIN void AllocateStackSpace(Register bytes_scratch); void AllocateStackSpace(int bytes); #else @@ -647,10 +675,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { const ParameterCount& expected, const ParameterCount& actual, InvokeFlag flag); - // On function call, call into the debugger if necessary. - void CheckDebugHook(Register fun, Register new_target, - const ParameterCount& expected, - const ParameterCount& actual); + // On function call, call into the debugger. + void CallDebugOnFunctionCall(Register fun, Register new_target, + const ParameterCount& expected, + const ParameterCount& actual); // Invoke the JavaScript function in the given register. Changes the // current context to the context in the function before invoking. @@ -665,6 +693,8 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler { // Conversions between tagged smi values and non-tagged integer values. // Tag an word-size value. The result must be known to be a valid smi value. + void SmiTag(Register reg); + // Requires dst != src void SmiTag(Register dst, Register src); // Simple comparison of smis. Both sides must be known smis to use these, @@ -917,7 +947,7 @@ inline Operand NativeContextOperand() { // Provides access to exit frame stack space (not GCed). inline Operand StackSpaceOperand(int index) { -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN const int kShaddowSpace = 4; return Operand(rsp, (index + kShaddowSpace) * kSystemPointerSize); #else diff --git a/deps/v8/src/codegen/x64/register-x64.h b/deps/v8/src/codegen/x64/register-x64.h index 199571f088defd..181da9d9f3a20d 100644 --- a/deps/v8/src/codegen/x64/register-x64.h +++ b/deps/v8/src/codegen/x64/register-x64.h @@ -88,7 +88,7 @@ constexpr int kNumJSCallerSaved = 5; // Number of registers for which space is reserved in safepoints. constexpr int kNumSafepointRegisters = 16; -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Windows calling convention constexpr Register arg_reg_1 = rcx; constexpr Register arg_reg_2 = rdx; @@ -100,7 +100,7 @@ constexpr Register arg_reg_1 = rdi; constexpr Register arg_reg_2 = rsi; constexpr Register arg_reg_3 = rdx; constexpr Register arg_reg_4 = rcx; -#endif // _WIN64 +#endif // V8_TARGET_OS_WIN #define DOUBLE_REGISTERS(V) \ V(xmm0) \ diff --git a/deps/v8/src/codegen/x64/sse-instr.h b/deps/v8/src/codegen/x64/sse-instr.h index 8ba54e85b42ec1..8af06ae92c8d63 100644 --- a/deps/v8/src/codegen/x64/sse-instr.h +++ b/deps/v8/src/codegen/x64/sse-instr.h @@ -6,6 +6,7 @@ #define V8_CODEGEN_X64_SSE_INSTR_H_ #define SSE2_INSTRUCTION_LIST(V) \ + V(sqrtpd, 66, 0F, 51) \ V(andnpd, 66, 0F, 55) \ V(addpd, 66, 0F, 58) \ V(mulpd, 66, 0F, 59) \ diff --git a/deps/v8/src/common/assert-scope.cc b/deps/v8/src/common/assert-scope.cc index f1fe717cc0983c..5138ce7122129d 100644 --- a/deps/v8/src/common/assert-scope.cc +++ b/deps/v8/src/common/assert-scope.cc @@ -126,8 +126,6 @@ template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>; template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>; template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>; template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>; -template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>; -template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>; template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>; template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>; diff --git a/deps/v8/src/common/assert-scope.h b/deps/v8/src/common/assert-scope.h index 73729400ac6c95..27f411214452f7 100644 --- a/deps/v8/src/common/assert-scope.h +++ b/deps/v8/src/common/assert-scope.h @@ -28,7 +28,6 @@ enum PerThreadAssertType { HEAP_ALLOCATION_ASSERT, HANDLE_ALLOCATION_ASSERT, HANDLE_DEREFERENCE_ASSERT, - DEFERRED_HANDLE_DEREFERENCE_ASSERT, CODE_DEPENDENCY_CHANGE_ASSERT, LAST_PER_THREAD_ASSERT_TYPE }; @@ -145,19 +144,11 @@ using DisallowHandleDereference = using AllowHandleDereference = PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, true>; -// Scope to document where we do not expect deferred handles to be dereferenced. -using DisallowDeferredHandleDereference = - PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>; - -// Scope to introduce an exception to DisallowDeferredHandleDereference. -using AllowDeferredHandleDereference = - PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>; - -// Scope to document where we do not expect deferred handles to be dereferenced. +// Scope to document where we do not expect code dependencies to change. using DisallowCodeDependencyChange = PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, false>; -// Scope to introduce an exception to DisallowDeferredHandleDereference. +// Scope to introduce an exception to DisallowCodeDependencyChange. using AllowCodeDependencyChange = PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, true>; @@ -243,10 +234,6 @@ extern template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>; extern template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>; extern template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>; extern template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>; -extern template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, - false>; -extern template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, - true>; extern template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>; extern template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>; diff --git a/deps/v8/src/common/globals.h b/deps/v8/src/common/globals.h index a0584b95c40475..9d5771f6946380 100644 --- a/deps/v8/src/common/globals.h +++ b/deps/v8/src/common/globals.h @@ -166,13 +166,14 @@ constexpr int kElidedFrameSlots = 0; #endif constexpr int kDoubleSizeLog2 = 3; +constexpr size_t kMaxWasmCodeMB = 1024; +constexpr size_t kMaxWasmCodeMemory = kMaxWasmCodeMB * MB; #if V8_TARGET_ARCH_ARM64 // ARM64 only supports direct calls within a 128 MB range. -constexpr size_t kMaxWasmCodeMB = 128; +constexpr size_t kMaxWasmCodeSpaceSize = 128 * MB; #else -constexpr size_t kMaxWasmCodeMB = 1024; +constexpr size_t kMaxWasmCodeSpaceSize = kMaxWasmCodeMemory; #endif -constexpr size_t kMaxWasmCodeMemory = kMaxWasmCodeMB * MB; #if V8_HOST_ARCH_64_BIT constexpr int kSystemPointerSizeLog2 = 3; @@ -230,7 +231,7 @@ constexpr int kTaggedSizeLog2 = 2; // These types define raw and atomic storage types for tagged values stored // on V8 heap. -using Tagged_t = int32_t; +using Tagged_t = uint32_t; using AtomicTagged_t = base::Atomic32; #else @@ -245,11 +246,6 @@ using AtomicTagged_t = base::AtomicWord; #endif // V8_COMPRESS_POINTERS -// Defines whether the branchless or branchful implementation of pointer -// decompression should be used. -constexpr bool kUseBranchlessPtrDecompressionInRuntime = false; -constexpr bool kUseBranchlessPtrDecompressionInGeneratedCode = false; - STATIC_ASSERT(kTaggedSize == (1 << kTaggedSizeLog2)); STATIC_ASSERT((kTaggedSize == 8) == TAGGED_SIZE_8_BYTES); @@ -404,6 +400,7 @@ enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; // Enums used by CEntry. enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; enum ArgvMode { kArgvOnStack, kArgvInRegister }; +enum FunctionDescriptorMode { kNoFunctionDescriptor, kHasFunctionDescriptor }; // This constant is used as an undefined value when passing source positions. constexpr int kNoSourcePosition = -1; @@ -795,8 +792,6 @@ enum InlineCacheState { NO_FEEDBACK, // Has never been executed. UNINITIALIZED, - // Has been executed but monomorphic state has been delayed. - PREMONOMORPHIC, // Has been executed and only one receiver type has been seen. MONOMORPHIC, // Check failed due to prototype (or map deprecation). @@ -816,8 +811,6 @@ inline const char* InlineCacheState2String(InlineCacheState state) { return "NOFEEDBACK"; case UNINITIALIZED: return "UNINITIALIZED"; - case PREMONOMORPHIC: - return "PREMONOMORPHIC"; case MONOMORPHIC: return "MONOMORPHIC"; case RECOMPUTE_HANDLER: @@ -1216,6 +1209,10 @@ enum VariableLocation : uint8_t { // immediately initialized upon creation (kCreatedInitialized). enum InitializationFlag : uint8_t { kNeedsInitialization, kCreatedInitialized }; +// Static variables can only be used with the class in the closest +// class scope as receivers. +enum class IsStaticFlag : uint8_t { kNotStatic, kStatic }; + enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned }; enum class InterpreterPushArgsMode : unsigned { diff --git a/deps/v8/src/common/message-template.h b/deps/v8/src/common/message-template.h index e3307a525c81fa..41af7b8f18a733 100644 --- a/deps/v8/src/common/message-template.h +++ b/deps/v8/src/common/message-template.h @@ -10,7 +10,6 @@ namespace v8 { namespace internal { -// TODO(913887): fix the use of 'neuter' in these error messages. #define MESSAGE_TEMPLATES(T) \ /* Error */ \ T(None, "") \ @@ -34,7 +33,6 @@ namespace internal { "Derived ArrayBuffer constructor created a buffer which was too small") \ T(ArrayBufferSpeciesThis, \ "ArrayBuffer subclass returned this from species constructor") \ - T(ArrayItemNotType, "array %[%] is not type %") \ T(AwaitNotInAsyncFunction, "await is only valid in async function") \ T(AtomicsWaitNotAllowed, "Atomics.wait cannot be called in this context") \ T(BadSortComparisonFunction, \ @@ -78,7 +76,7 @@ namespace internal { T(DebuggerType, "Debugger: Parameters have wrong types.") \ T(DeclarationMissingInitializer, "Missing initializer in % declaration") \ T(DefineDisallowed, "Cannot define property %, object is not extensible") \ - T(DetachedOperation, "Cannot perform % on a neutered ArrayBuffer") \ + T(DetachedOperation, "Cannot perform % on a detached ArrayBuffer") \ T(DuplicateTemplateProperty, "Object template has duplicate property '%'") \ T(ExtendsValueNotConstructor, \ "Class extends value % is not a constructor or null") \ @@ -101,6 +99,7 @@ namespace internal { T(InvalidRegExpExecResult, \ "RegExp exec method returned something other than an Object or null") \ T(InvalidUnit, "Invalid unit argument for %() '%'") \ + T(IterableYieldedNonString, "Iterable yielded % which is not a string") \ T(IteratorResultNotAnObject, "Iterator result % is not an object") \ T(IteratorSymbolNonCallable, "Found non-callable @@iterator") \ T(IteratorValueNotAnObject, "Iterator value % is not an entry object") \ @@ -540,6 +539,7 @@ namespace internal { T(WasmTrapFloatUnrepresentable, "float unrepresentable in integer range") \ T(WasmTrapFuncInvalid, "invalid index into function table") \ T(WasmTrapFuncSigMismatch, "function signature mismatch") \ + T(WasmTrapMultiReturnLengthMismatch, "multi-return length mismatch") \ T(WasmTrapTypeError, "wasm function signature contains illegal type") \ T(WasmTrapDataSegmentDropped, "data segment has been dropped") \ T(WasmTrapElemSegmentDropped, "element segment has been dropped") \ @@ -554,7 +554,7 @@ namespace internal { T(DataCloneError, "% could not be cloned.") \ T(DataCloneErrorOutOfMemory, "Data cannot be cloned, out of memory.") \ T(DataCloneErrorDetachedArrayBuffer, \ - "An ArrayBuffer is neutered and could not be cloned.") \ + "An ArrayBuffer is detached and could not be cloned.") \ T(DataCloneErrorSharedArrayBufferTransferred, \ "A SharedArrayBuffer could not be cloned. SharedArrayBuffer must not be " \ "transferred.") \ diff --git a/deps/v8/src/common/ptr-compr-inl.h b/deps/v8/src/common/ptr-compr-inl.h index a8fd7f245cb90c..17239d15c2783a 100644 --- a/deps/v8/src/common/ptr-compr-inl.h +++ b/deps/v8/src/common/ptr-compr-inl.h @@ -29,8 +29,7 @@ V8_INLINE Address GetIsolateRoot<Address>(Address on_heap_addr) { // signed constant instead of 64-bit constant (the problem is that 2Gb looks // like a negative 32-bit value). It's correct because we will never use // leftmost address of V8 heap as |on_heap_addr|. - return RoundDown<kPtrComprIsolateRootAlignment>(on_heap_addr + - kPtrComprIsolateRootBias - 1); + return RoundDown<kPtrComprIsolateRootAlignment>(on_heap_addr); } template <> @@ -54,37 +53,20 @@ V8_INLINE Address DecompressTaggedSigned(Tagged_t raw_value) { template <typename TOnHeapAddress> V8_INLINE Address DecompressTaggedPointer(TOnHeapAddress on_heap_addr, Tagged_t raw_value) { - // Current compression scheme requires |raw_value| to be sign-extended - // from int32_t to intptr_t. - intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value)); - Address root = GetIsolateRoot(on_heap_addr); - return root + static_cast<Address>(value); + return GetIsolateRoot(on_heap_addr) + static_cast<Address>(raw_value); } // Decompresses any tagged value, preserving both weak- and smi- tags. template <typename TOnHeapAddress> V8_INLINE Address DecompressTaggedAny(TOnHeapAddress on_heap_addr, Tagged_t raw_value) { - if (kUseBranchlessPtrDecompressionInRuntime) { - // Current compression scheme requires |raw_value| to be sign-extended - // from int32_t to intptr_t. - intptr_t value = static_cast<intptr_t>(static_cast<int32_t>(raw_value)); - // |root_mask| is 0 if the |value| was a smi or -1 otherwise. - Address root_mask = static_cast<Address>(-(value & kSmiTagMask)); - Address root_or_zero = root_mask & GetIsolateRoot(on_heap_addr); - return root_or_zero + static_cast<Address>(value); - } else { - return HAS_SMI_TAG(raw_value) - ? DecompressTaggedSigned(raw_value) - : DecompressTaggedPointer(on_heap_addr, raw_value); - } + return DecompressTaggedPointer(on_heap_addr, raw_value); } #ifdef V8_COMPRESS_POINTERS STATIC_ASSERT(kPtrComprHeapReservationSize == Internals::kPtrComprHeapReservationSize); -STATIC_ASSERT(kPtrComprIsolateRootBias == Internals::kPtrComprIsolateRootBias); STATIC_ASSERT(kPtrComprIsolateRootAlignment == Internals::kPtrComprIsolateRootAlignment); diff --git a/deps/v8/src/common/ptr-compr.h b/deps/v8/src/common/ptr-compr.h index 5b4a74e7e316fb..105d5f1a4f65b0 100644 --- a/deps/v8/src/common/ptr-compr.h +++ b/deps/v8/src/common/ptr-compr.h @@ -14,7 +14,6 @@ namespace internal { // See v8:7703 for details about how pointer compression works. constexpr size_t kPtrComprHeapReservationSize = size_t{4} * GB; -constexpr size_t kPtrComprIsolateRootBias = kPtrComprHeapReservationSize / 2; constexpr size_t kPtrComprIsolateRootAlignment = size_t{4} * GB; } // namespace internal diff --git a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc index e1d47d30a61285..42d64b66145bf9 100644 --- a/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc +++ b/deps/v8/src/compiler-dispatcher/compiler-dispatcher.cc @@ -6,7 +6,6 @@ #include "src/ast/ast.h" #include "src/base/platform/time.h" -#include "src/base/template-utils.h" #include "src/codegen/compiler.h" #include "src/flags/flags.h" #include "src/handles/global-handles.h" @@ -66,7 +65,7 @@ base::Optional<CompilerDispatcher::JobId> CompilerDispatcher::Enqueue( if (!IsEnabled()) return base::nullopt; - std::unique_ptr<Job> job = base::make_unique<Job>(new BackgroundCompileTask( + std::unique_ptr<Job> job = std::make_unique<Job>(new BackgroundCompileTask( allocator_, outer_parse_info, function_name, function_literal, worker_thread_runtime_call_stats_, background_compile_timer_, static_cast<int>(max_stack_size_))); diff --git a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc index fbaeaa73f87398..3d2342e9a22bf0 100644 --- a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc +++ b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc @@ -5,7 +5,6 @@ #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/base/atomicops.h" -#include "src/base/template-utils.h" #include "src/codegen/compiler.h" #include "src/codegen/optimized-compilation-info.h" #include "src/execution/isolate.h" @@ -244,14 +243,14 @@ void OptimizingCompileDispatcher::QueueForOptimization( blocked_jobs_++; } else { V8::GetCurrentPlatform()->CallOnWorkerThread( - base::make_unique<CompileTask>(isolate_, this)); + std::make_unique<CompileTask>(isolate_, this)); } } void OptimizingCompileDispatcher::Unblock() { while (blocked_jobs_ > 0) { V8::GetCurrentPlatform()->CallOnWorkerThread( - base::make_unique<CompileTask>(isolate_, this)); + std::make_unique<CompileTask>(isolate_, this)); blocked_jobs_--; } } diff --git a/deps/v8/src/compiler/OWNERS b/deps/v8/src/compiler/OWNERS index 50e2af71290003..204c0ba115e3c9 100644 --- a/deps/v8/src/compiler/OWNERS +++ b/deps/v8/src/compiler/OWNERS @@ -8,11 +8,12 @@ tebbi@chromium.org neis@chromium.org mvstanton@chromium.org mslekova@chromium.org +jgruber@chromium.org per-file wasm-*=ahaas@chromium.org per-file wasm-*=bbudge@chromium.org per-file wasm-*=binji@chromium.org -per-file wasm-*=clemensh@chromium.org +per-file wasm-*=clemensb@chromium.org per-file wasm-*=gdeepti@chromium.org per-file int64-lowering.*=ahaas@chromium.org diff --git a/deps/v8/src/compiler/access-builder.cc b/deps/v8/src/compiler/access-builder.cc index 7a72be80284c05..e6c5568af03a41 100644 --- a/deps/v8/src/compiler/access-builder.cc +++ b/deps/v8/src/compiler/access-builder.cc @@ -23,10 +23,9 @@ namespace internal { namespace compiler { // static -FieldAccess AccessBuilder::ForExternalTaggedValue() { - FieldAccess access = {kUntaggedBase, 0, - MaybeHandle<Name>(), MaybeHandle<Map>(), - Type::Any(), MachineType::AnyTagged(), +FieldAccess AccessBuilder::ForExternalIntPtr() { + FieldAccess access = {kUntaggedBase, 0, MaybeHandle<Name>(), + MaybeHandle<Map>(), Type::Any(), MachineType::IntPtr(), kNoWriteBarrier}; return access; } @@ -109,7 +108,6 @@ FieldAccess AccessBuilder::ForJSObjectElements() { return access; } - // static FieldAccess AccessBuilder::ForJSObjectInObjectProperty(const MapRef& map, int index) { @@ -185,7 +183,6 @@ FieldAccess AccessBuilder::ForJSFunctionContext() { return access; } - // static FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() { FieldAccess access = { @@ -296,7 +293,6 @@ FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() { return access; } - // static FieldAccess AccessBuilder::ForJSGeneratorObjectParametersAndRegisters() { FieldAccess access = { @@ -478,7 +474,6 @@ FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) { return access; } - // static FieldAccess AccessBuilder::ForJSIteratorResultDone() { FieldAccess access = { @@ -489,7 +484,6 @@ FieldAccess AccessBuilder::ForJSIteratorResultDone() { return access; } - // static FieldAccess AccessBuilder::ForJSIteratorResultValue() { FieldAccess access = { @@ -540,7 +534,6 @@ FieldAccess AccessBuilder::ForJSRegExpSource() { return access; } - // static FieldAccess AccessBuilder::ForFixedArrayLength() { FieldAccess access = {kTaggedBase, @@ -600,7 +593,6 @@ FieldAccess AccessBuilder::ForMapBitField3() { return access; } - // static FieldAccess AccessBuilder::ForMapDescriptors() { FieldAccess access = { @@ -611,7 +603,6 @@ FieldAccess AccessBuilder::ForMapDescriptors() { return access; } - // static FieldAccess AccessBuilder::ForMapInstanceType() { FieldAccess access = { @@ -621,7 +612,6 @@ FieldAccess AccessBuilder::ForMapInstanceType() { return access; } - // static FieldAccess AccessBuilder::ForMapPrototype() { FieldAccess access = { @@ -810,7 +800,7 @@ FieldAccess AccessBuilder::ForJSStringIteratorString() { // static FieldAccess AccessBuilder::ForJSStringIteratorIndex() { FieldAccess access = {kTaggedBase, - JSStringIterator::kNextIndexOffset, + JSStringIterator::kIndexOffset, Handle<Name>(), MaybeHandle<Map>(), TypeCache::Get()->kStringLengthType, @@ -829,7 +819,6 @@ FieldAccess AccessBuilder::ForArgumentsLength() { return access; } - // static FieldAccess AccessBuilder::ForArgumentsCallee() { FieldAccess access = { @@ -840,7 +829,6 @@ FieldAccess AccessBuilder::ForArgumentsCallee() { return access; } - // static FieldAccess AccessBuilder::ForFixedArraySlot( size_t index, WriteBarrierKind write_barrier_kind) { @@ -852,7 +840,6 @@ FieldAccess AccessBuilder::ForFixedArraySlot( return access; } - // static FieldAccess AccessBuilder::ForCellValue() { FieldAccess access = {kTaggedBase, Cell::kValueOffset, @@ -937,7 +924,7 @@ ElementAccess AccessBuilder::ForStackArgument() { ElementAccess access = { kUntaggedBase, CommonFrameConstants::kFixedFrameSizeAboveFp - kSystemPointerSize, - Type::NonInternal(), MachineType::AnyTagged(), + Type::NonInternal(), MachineType::Pointer(), WriteBarrierKind::kNoWriteBarrier}; return access; } diff --git a/deps/v8/src/compiler/access-builder.h b/deps/v8/src/compiler/access-builder.h index 231e75f819587b..4aa69e3726e0fc 100644 --- a/deps/v8/src/compiler/access-builder.h +++ b/deps/v8/src/compiler/access-builder.h @@ -24,11 +24,8 @@ class V8_EXPORT_PRIVATE AccessBuilder final // =========================================================================== // Access to external values (based on external references). - // Provides access to a tagged field identified by an external reference. - static FieldAccess ForExternalTaggedValue(); - - // Provides access to an uint8 field identified by an external reference. - static FieldAccess ForExternalUint8Value(); + // Provides access to an IntPtr field identified by an external reference. + static FieldAccess ForExternalIntPtr(); // =========================================================================== // Access to heap object fields and elements (based on tagged pointer). diff --git a/deps/v8/src/compiler/access-info.cc b/deps/v8/src/compiler/access-info.cc index 269ef903751ee7..dcdd1de831a4f7 100644 --- a/deps/v8/src/compiler/access-info.cc +++ b/deps/v8/src/compiler/access-info.cc @@ -31,9 +31,9 @@ bool CanInlinePropertyAccess(Handle<Map> map) { // We can inline property access to prototypes of all primitives, except // the special Oddball ones that have no wrapper counterparts (i.e. Null, // Undefined and TheHole). - STATIC_ASSERT(ODDBALL_TYPE == LAST_PRIMITIVE_TYPE); + STATIC_ASSERT(ODDBALL_TYPE == LAST_PRIMITIVE_HEAP_OBJECT_TYPE); if (map->IsBooleanMap()) return true; - if (map->instance_type() < LAST_PRIMITIVE_TYPE) return true; + if (map->instance_type() < LAST_PRIMITIVE_HEAP_OBJECT_TYPE) return true; return map->IsJSObjectMap() && !map->is_dictionary_map() && !map->has_named_interceptor() && // TODO(verwaest): Whitelist contexts to which we have access. @@ -323,8 +323,8 @@ bool AccessInfoFactory::ComputeElementAccessInfos( PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo( Handle<Map> receiver_map, Handle<Map> map, MaybeHandle<JSObject> holder, - int descriptor, AccessMode access_mode) const { - DCHECK_NE(descriptor, DescriptorArray::kNotFound); + InternalIndex descriptor, AccessMode access_mode) const { + DCHECK(descriptor.is_found()); Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); PropertyDetails const details = descriptors->GetDetails(descriptor); int index = descriptors->GetFieldIndex(descriptor); @@ -351,6 +351,11 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo( descriptor)); } else if (details_representation.IsDouble()) { field_type = type_cache_->kFloat64; + if (!FLAG_unbox_double_fields) { + unrecorded_dependencies.push_back( + dependencies()->FieldRepresentationDependencyOffTheRecord( + map_ref, descriptor)); + } } else if (details_representation.IsHeapObject()) { // Extract the field type from the property details (make sure its // representation is TaggedPointer to reflect the heap object case). @@ -408,9 +413,9 @@ PropertyAccessInfo AccessInfoFactory::ComputeDataFieldAccessInfo( PropertyAccessInfo AccessInfoFactory::ComputeAccessorDescriptorAccessInfo( Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map, - MaybeHandle<JSObject> holder, int descriptor, + MaybeHandle<JSObject> holder, InternalIndex descriptor, AccessMode access_mode) const { - DCHECK_NE(descriptor, DescriptorArray::kNotFound); + DCHECK(descriptor.is_found()); Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); SLOW_DCHECK(descriptor == descriptors->Search(*name, *map)); if (map->instance_type() == JS_MODULE_NAMESPACE_TYPE) { @@ -497,8 +502,8 @@ PropertyAccessInfo AccessInfoFactory::ComputePropertyAccessInfo( while (true) { // Lookup the named property on the {map}. Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); - int const number = descriptors->Search(*name, *map); - if (number != DescriptorArray::kNotFound) { + InternalIndex const number = descriptors->Search(*name, *map); + if (number.is_found()) { PropertyDetails const details = descriptors->GetDetails(number); if (access_mode == AccessMode::kStore || access_mode == AccessMode::kStoreInLiteral) { @@ -762,7 +767,7 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition( } Handle<Map> transition_map(transition, isolate()); - int const number = transition_map->LastAdded(); + InternalIndex const number = transition_map->LastAdded(); PropertyDetails const details = transition_map->instance_descriptors().GetDetails(number); // Don't bother optimizing stores to read-only properties. @@ -789,6 +794,12 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition( transition_map_ref, number)); } else if (details_representation.IsDouble()) { field_type = type_cache_->kFloat64; + if (!FLAG_unbox_double_fields) { + transition_map_ref.SerializeOwnDescriptor(number); + unrecorded_dependencies.push_back( + dependencies()->FieldRepresentationDependencyOffTheRecord( + transition_map_ref, number)); + } } else if (details_representation.IsHeapObject()) { // Extract the field type from the property details (make sure its // representation is TaggedPointer to reflect the heap object case). diff --git a/deps/v8/src/compiler/access-info.h b/deps/v8/src/compiler/access-info.h index e2f6e6d453da7f..59101e2cc90621 100644 --- a/deps/v8/src/compiler/access-info.h +++ b/deps/v8/src/compiler/access-info.h @@ -204,11 +204,11 @@ class AccessInfoFactory final { PropertyAccessInfo ComputeDataFieldAccessInfo(Handle<Map> receiver_map, Handle<Map> map, MaybeHandle<JSObject> holder, - int descriptor, + InternalIndex descriptor, AccessMode access_mode) const; PropertyAccessInfo ComputeAccessorDescriptorAccessInfo( Handle<Map> receiver_map, Handle<Name> name, Handle<Map> map, - MaybeHandle<JSObject> holder, int descriptor, + MaybeHandle<JSObject> holder, InternalIndex descriptor, AccessMode access_mode) const; void MergePropertyAccessInfos(ZoneVector<PropertyAccessInfo> infos, diff --git a/deps/v8/src/compiler/backend/arm/code-generator-arm.cc b/deps/v8/src/compiler/backend/arm/code-generator-arm.cc index 65a569d755b1fd..3fe5361083895a 100644 --- a/deps/v8/src/compiler/backend/arm/code-generator-arm.cc +++ b/deps/v8/src/compiler/backend/arm/code-generator-arm.cc @@ -44,7 +44,7 @@ class ArmOperandConverter final : public InstructionOperandConverter { UNREACHABLE(); } - Operand InputImmediate(size_t index) { + Operand InputImmediate(size_t index) const { return ToImmediate(instr_->InputAt(index)); } @@ -111,7 +111,7 @@ class ArmOperandConverter final : public InstructionOperandConverter { return InputOffset(&first_index); } - Operand ToImmediate(InstructionOperand* operand) { + Operand ToImmediate(InstructionOperand* operand) const { Constant constant = ToConstant(operand); switch (constant.type()) { case Constant::kInt32: @@ -153,9 +153,6 @@ class ArmOperandConverter final : public InstructionOperandConverter { NeonMemOperand NeonInputOperand(size_t first_index) { const size_t index = first_index; switch (AddressingModeField::decode(instr_->opcode())) { - case kMode_Offset_RR: - return NeonMemOperand(InputRegister(index + 0), - InputRegister(index + 1)); case kMode_Operand2_R: return NeonMemOperand(InputRegister(index + 0)); default: @@ -309,9 +306,9 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { UNREACHABLE(); } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, InstructionCode opcode, - ArmOperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, + InstructionCode opcode, + ArmOperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); if (access_mode == kMemoryAccessPoisoned) { @@ -320,10 +317,10 @@ void EmitWordLoadPoisoningIfNeeded( } } -void ComputePoisonedAddressForLoad( - CodeGenerator* codegen, InstructionCode opcode, - ArmOperandConverter& i, // NOLINT(runtime/references) - Register address) { +void ComputePoisonedAddressForLoad(CodeGenerator* codegen, + InstructionCode opcode, + ArmOperandConverter const& i, + Register address) { DCHECK_EQ(kMemoryAccessPoisoned, static_cast<MemoryAccessMode>(MiscField::decode(opcode))); switch (AddressingModeField::decode(opcode)) { @@ -1798,6 +1795,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ vneg(i.OutputSimd128Register(), i.InputSimd128Register(0)); break; } + case kArmF32x4Sqrt: { + QwNeonRegister dst = i.OutputSimd128Register(); + QwNeonRegister src1 = i.InputSimd128Register(0); + DCHECK_EQ(dst, q0); + DCHECK_EQ(src1, q0); +#define S_FROM_Q(reg, lane) SwVfpRegister::from_code(reg.code() * 4 + lane) + __ vsqrt(S_FROM_Q(dst, 0), S_FROM_Q(src1, 0)); + __ vsqrt(S_FROM_Q(dst, 1), S_FROM_Q(src1, 1)); + __ vsqrt(S_FROM_Q(dst, 2), S_FROM_Q(src1, 2)); + __ vsqrt(S_FROM_Q(dst, 3), S_FROM_Q(src1, 3)); +#undef S_FROM_Q + break; + } case kArmF32x4RecipApprox: { __ vrecpe(i.OutputSimd128Register(), i.InputSimd128Register(0)); break; @@ -1919,14 +1929,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI32x4Shl: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon32, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 32. + __ and_(shift, i.InputRegister(1), Operand(31)); + __ vdup(Neon32, tmp, shift); __ vshl(NeonS32, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } case kArmI32x4ShrS: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon32, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 32. + __ and_(shift, i.InputRegister(1), Operand(31)); + __ vdup(Neon32, tmp, shift); __ vneg(Neon32, tmp, tmp); __ vshl(NeonS32, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -1998,7 +2014,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI32x4ShrU: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon32, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 32. + __ and_(shift, i.InputRegister(1), Operand(31)); + __ vdup(Neon32, tmp, shift); __ vneg(Neon32, tmp, tmp); __ vshl(NeonU32, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -2029,7 +2048,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArmI16x8ExtractLane: { - __ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonS16, + __ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonU16, i.InputInt8(1)); break; } @@ -2054,14 +2073,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI16x8Shl: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon16, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 16. + __ and_(shift, i.InputRegister(1), Operand(15)); + __ vdup(Neon16, tmp, shift); __ vshl(NeonS16, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } case kArmI16x8ShrS: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon16, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 16. + __ and_(shift, i.InputRegister(1), Operand(15)); + __ vdup(Neon16, tmp, shift); __ vneg(Neon16, tmp, tmp); __ vshl(NeonS16, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -2142,7 +2167,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI16x8ShrU: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon16, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 16. + __ and_(shift, i.InputRegister(1), Operand(15)); + __ vdup(Neon16, tmp, shift); __ vneg(Neon16, tmp, tmp); __ vshl(NeonU16, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -2186,7 +2214,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArmI8x16ExtractLane: { - __ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonS8, + __ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonU8, i.InputInt8(1)); break; } @@ -2201,6 +2229,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI8x16Shl: { QwNeonRegister tmp = i.TempSimd128Register(0); + Register shift = i.TempRegister(1); + // Take shift value modulo 8. + __ and_(shift, i.InputRegister(1), Operand(7)); __ vdup(Neon8, tmp, i.InputRegister(1)); __ vshl(NeonS8, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -2208,7 +2239,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI8x16ShrS: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon8, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 8. + __ and_(shift, i.InputRegister(1), Operand(7)); + __ vdup(Neon8, tmp, shift); __ vneg(Neon8, tmp, tmp); __ vshl(NeonS8, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); @@ -2275,7 +2309,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArmI8x16ShrU: { QwNeonRegister tmp = i.TempSimd128Register(0); - __ vdup(Neon8, tmp, i.InputRegister(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 8. + __ and_(shift, i.InputRegister(1), Operand(7)); + __ vdup(Neon8, tmp, shift); __ vneg(Neon8, tmp, tmp); __ vshl(NeonU8, i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); diff --git a/deps/v8/src/compiler/backend/arm/instruction-codes-arm.h b/deps/v8/src/compiler/backend/arm/instruction-codes-arm.h index 3551e26aea8832..d398ec0ed6e2f2 100644 --- a/deps/v8/src/compiler/backend/arm/instruction-codes-arm.h +++ b/deps/v8/src/compiler/backend/arm/instruction-codes-arm.h @@ -135,6 +135,7 @@ namespace compiler { V(ArmF32x4UConvertI32x4) \ V(ArmF32x4Abs) \ V(ArmF32x4Neg) \ + V(ArmF32x4Sqrt) \ V(ArmF32x4RecipApprox) \ V(ArmF32x4RecipSqrtApprox) \ V(ArmF32x4Add) \ diff --git a/deps/v8/src/compiler/backend/arm/instruction-scheduler-arm.cc b/deps/v8/src/compiler/backend/arm/instruction-scheduler-arm.cc index 1d7cf61dfe7374..92be55dcc3d662 100644 --- a/deps/v8/src/compiler/backend/arm/instruction-scheduler-arm.cc +++ b/deps/v8/src/compiler/backend/arm/instruction-scheduler-arm.cc @@ -115,6 +115,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArmF32x4UConvertI32x4: case kArmF32x4Abs: case kArmF32x4Neg: + case kArmF32x4Sqrt: case kArmF32x4RecipApprox: case kArmF32x4RecipSqrtApprox: case kArmF32x4Add: diff --git a/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc b/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc index ce74faa4a62422..303648051f8d85 100644 --- a/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc +++ b/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" #include "src/base/bits.h" #include "src/base/enum-set.h" +#include "src/base/iterator.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties.h" @@ -94,7 +94,7 @@ void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { void VisitSimdShiftRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { ArmOperandGenerator g(selector); - InstructionOperand temps[] = {g.TempSimd128Register()}; + InstructionOperand temps[] = {g.TempSimd128Register(), g.TempRegister()}; selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), arraysize(temps), temps); @@ -352,6 +352,26 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode div_opcode, } } +// Adds the base and offset into a register, then change the addressing +// mode of opcode_return to use this register. Certain instructions, e.g. +// vld1 and vst1, when given two registers, will post-increment the offset, i.e. +// perform the operation at base, then add offset to base. What we intend is to +// access at (base+offset). +void EmitAddBeforeS128LoadStore(InstructionSelector* selector, + InstructionCode* opcode_return, + size_t* input_count_return, + InstructionOperand* inputs) { + DCHECK(*opcode_return == kArmVld1S128 || *opcode_return == kArmVst1S128); + ArmOperandGenerator g(selector); + InstructionOperand addr = g.TempRegister(); + InstructionCode op = kArmAdd; + op |= AddressingModeField::encode(kMode_Operand2_R); + selector->Emit(op, 1, &addr, 2, inputs); + *opcode_return |= AddressingModeField::encode(kMode_Operand2_R); + *input_count_return -= 1; + inputs[0] = addr; +} + void EmitLoad(InstructionSelector* selector, InstructionCode opcode, InstructionOperand* output, Node* base, Node* index) { ArmOperandGenerator g(selector); @@ -368,7 +388,11 @@ void EmitLoad(InstructionSelector* selector, InstructionCode opcode, input_count = 3; } else { inputs[1] = g.UseRegister(index); - opcode |= AddressingModeField::encode(kMode_Offset_RR); + if (opcode == kArmVld1S128) { + EmitAddBeforeS128LoadStore(selector, &opcode, &input_count, &inputs[0]); + } else { + opcode |= AddressingModeField::encode(kMode_Offset_RR); + } } selector->Emit(opcode, 1, output, input_count, inputs); } @@ -386,7 +410,12 @@ void EmitStore(InstructionSelector* selector, InstructionCode opcode, input_count = 4; } else { inputs[input_count++] = g.UseRegister(index); - opcode |= AddressingModeField::encode(kMode_Offset_RR); + if (opcode == kArmVst1S128) { + // Inputs are value, base, index, only care about base and index. + EmitAddBeforeS128LoadStore(selector, &opcode, &input_count, &inputs[1]); + } else { + opcode |= AddressingModeField::encode(kMode_Offset_RR); + } } selector->Emit(opcode, 0, nullptr, input_count, inputs); } @@ -596,8 +625,7 @@ void InstructionSelector::VisitUnalignedLoad(Node* node) { Emit(kArmVmovF32U32, g.DefineAsRegister(node), temp); return; } - case MachineRepresentation::kFloat64: - case MachineRepresentation::kSimd128: { + case MachineRepresentation::kFloat64: { // Compute the address of the least-significant byte of the FP value. // We assume that the base node is unlikely to be an encodable immediate // or the result of a shift operation, so only consider the addressing @@ -623,13 +651,10 @@ void InstructionSelector::VisitUnalignedLoad(Node* node) { if (CpuFeatures::IsSupported(NEON)) { // With NEON we can load directly from the calculated address. - InstructionCode op = load_rep == MachineRepresentation::kFloat64 - ? kArmVld1F64 - : kArmVld1S128; + InstructionCode op = kArmVld1F64; op |= AddressingModeField::encode(kMode_Operand2_R); Emit(op, g.DefineAsRegister(node), addr); } else { - DCHECK_NE(MachineRepresentation::kSimd128, load_rep); // Load both halves and move to an FP register. InstructionOperand fp_lo = g.TempRegister(); InstructionOperand fp_hi = g.TempRegister(); @@ -670,8 +695,7 @@ void InstructionSelector::VisitUnalignedStore(Node* node) { EmitStore(this, kArmStr, input_count, inputs, index); return; } - case MachineRepresentation::kFloat64: - case MachineRepresentation::kSimd128: { + case MachineRepresentation::kFloat64: { if (CpuFeatures::IsSupported(NEON)) { InstructionOperand address = g.TempRegister(); { @@ -697,13 +721,10 @@ void InstructionSelector::VisitUnalignedStore(Node* node) { inputs[input_count++] = g.UseRegister(value); inputs[input_count++] = address; - InstructionCode op = store_rep == MachineRepresentation::kFloat64 - ? kArmVst1F64 - : kArmVst1S128; + InstructionCode op = kArmVst1F64; op |= AddressingModeField::encode(kMode_Operand2_R); Emit(op, 0, nullptr, input_count, inputs); } else { - DCHECK_NE(MachineRepresentation::kSimd128, store_rep); // Store a 64-bit floating point value using two 32-bit integer stores. // Computing the store address here would require three live temporary // registers (fp<63:32>, fp<31:0>, address), so compute base + 4 after @@ -942,7 +963,8 @@ void InstructionSelector::VisitWord32Shr(Node* node) { uint32_t lsb = m.right().Value(); Int32BinopMatcher mleft(m.left().node()); if (mleft.right().HasValue()) { - uint32_t value = (mleft.right().Value() >> lsb) << lsb; + uint32_t value = static_cast<uint32_t>(mleft.right().Value() >> lsb) + << lsb; uint32_t width = base::bits::CountPopulation(value); uint32_t msb = base::bits::CountLeadingZeros32(value); if ((width != 0) && (msb + width + lsb == 32)) { @@ -1119,6 +1141,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { VisitRR(this, kArmRev, node); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); } void InstructionSelector::VisitInt32Add(Node* node) { @@ -2513,6 +2539,14 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP) #undef SIMD_VISIT_BINOP #undef SIMD_BINOP_LIST +void InstructionSelector::VisitF32x4Sqrt(Node* node) { + ArmOperandGenerator g(this); + // Use fixed registers in the lower 8 Q-registers so we can directly access + // mapped registers S0-S31. + Emit(kArmF32x4Sqrt, g.DefineAsFixed(node, q0), + g.UseFixed(node->InputAt(0), q0)); +} + void InstructionSelector::VisitF32x4Div(Node* node) { ArmOperandGenerator g(this); // Use fixed registers in the lower 8 Q-registers so we can directly access diff --git a/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc b/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc index 66ca7f6cf0cf35..6f65c905dd136b 100644 --- a/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc +++ b/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc @@ -376,9 +376,9 @@ Condition FlagsConditionToCondition(FlagsCondition condition) { UNREACHABLE(); } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, InstructionCode opcode, Instruction* instr, - Arm64OperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, + InstructionCode opcode, Instruction* instr, + Arm64OperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); if (access_mode == kMemoryAccessPoisoned) { @@ -389,6 +389,36 @@ void EmitWordLoadPoisoningIfNeeded( } } +void EmitMaybePoisonedFPLoad(CodeGenerator* codegen, InstructionCode opcode, + Arm64OperandConverter* i, VRegister output_reg) { + const MemoryAccessMode access_mode = + static_cast<MemoryAccessMode>(MiscField::decode(opcode)); + AddressingMode address_mode = AddressingModeField::decode(opcode); + if (access_mode == kMemoryAccessPoisoned && address_mode != kMode_Root) { + UseScratchRegisterScope temps(codegen->tasm()); + Register address = temps.AcquireX(); + switch (address_mode) { + case kMode_MRI: // Fall through. + case kMode_MRR: + codegen->tasm()->Add(address, i->InputRegister(0), i->InputOperand(1)); + break; + case kMode_Operand2_R_LSL_I: + codegen->tasm()->Add(address, i->InputRegister(0), + i->InputOperand2_64(1)); + break; + default: + // Note: we don't need poisoning for kMode_Root loads as those loads + // target a fixed offset from root register which is set once when + // initializing the vm. + UNREACHABLE(); + } + codegen->tasm()->And(address, address, Operand(kSpeculationPoisonRegister)); + codegen->tasm()->Ldr(output_reg, MemOperand(address)); + } else { + codegen->tasm()->Ldr(output_reg, i->MemoryOperand()); + } +} + } // namespace #define ASSEMBLE_SHIFT(asm_instr, width) \ @@ -1198,6 +1228,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArm64Sxtw: __ Sxtw(i.OutputRegister(), i.InputRegister32(0)); break; + case kArm64Sbfx: + __ Sbfx(i.OutputRegister(), i.InputRegister(0), i.InputInt6(1), + i.InputInt6(2)); + break; case kArm64Sbfx32: __ Sbfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt5(1), i.InputInt5(2)); @@ -1586,6 +1620,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArm64Str: __ Str(i.InputOrZeroRegister64(0), i.MemoryOperand(1)); break; + case kArm64StrCompressTagged: + __ StoreTaggedField(i.InputOrZeroRegister64(0), i.MemoryOperand(1)); + break; case kArm64DecompressSigned: { __ DecompressTaggedSigned(i.OutputRegister(), i.InputRegister(0)); break; @@ -1599,13 +1636,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArm64LdrS: - __ Ldr(i.OutputDoubleRegister().S(), i.MemoryOperand()); + EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister().S()); break; case kArm64StrS: __ Str(i.InputFloat32OrZeroRegister(0), i.MemoryOperand(1)); break; case kArm64LdrD: - __ Ldr(i.OutputDoubleRegister(), i.MemoryOperand()); + EmitMaybePoisonedFPLoad(this, opcode, &i, i.OutputDoubleRegister()); break; case kArm64StrD: __ Str(i.InputFloat64OrZeroRegister(0), i.MemoryOperand(1)); @@ -1616,9 +1653,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArm64StrQ: __ Str(i.InputSimd128Register(0), i.MemoryOperand(1)); break; - case kArm64StrCompressTagged: - __ StoreTaggedField(i.InputOrZeroRegister64(0), i.MemoryOperand(1)); - break; case kArm64DmbIsh: __ Dmb(InnerShareable, BarrierAll); break; @@ -1794,6 +1828,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } SIMD_UNOP_CASE(kArm64F64x2Abs, Fabs, 2D); SIMD_UNOP_CASE(kArm64F64x2Neg, Fneg, 2D); + SIMD_UNOP_CASE(kArm64F64x2Sqrt, Fsqrt, 2D); SIMD_BINOP_CASE(kArm64F64x2Add, Fadd, 2D); SIMD_BINOP_CASE(kArm64F64x2Sub, Fsub, 2D); SIMD_BINOP_CASE(kArm64F64x2Mul, Fmul, 2D); @@ -1818,6 +1853,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( i.InputSimd128Register(0).V2D()); break; } + case kArm64F64x2Qfma: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + __ Fmla(i.OutputSimd128Register().V2D(), i.InputSimd128Register(1).V2D(), + i.InputSimd128Register(2).V2D()); + break; + } + case kArm64F64x2Qfms: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + __ Fmls(i.OutputSimd128Register().V2D(), i.InputSimd128Register(1).V2D(), + i.InputSimd128Register(2).V2D()); + break; + } case kArm64F32x4Splat: { __ Dup(i.OutputSimd128Register().V4S(), i.InputSimd128Register(0).S(), 0); break; @@ -1840,6 +1887,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_UNOP_CASE(kArm64F32x4UConvertI32x4, Ucvtf, 4S); SIMD_UNOP_CASE(kArm64F32x4Abs, Fabs, 4S); SIMD_UNOP_CASE(kArm64F32x4Neg, Fneg, 4S); + SIMD_UNOP_CASE(kArm64F32x4Sqrt, Fsqrt, 4S); SIMD_UNOP_CASE(kArm64F32x4RecipApprox, Frecpe, 4S); SIMD_UNOP_CASE(kArm64F32x4RecipSqrtApprox, Frsqrte, 4S); SIMD_BINOP_CASE(kArm64F32x4Add, Fadd, 4S); @@ -1867,6 +1915,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( i.InputSimd128Register(0).V4S()); break; } + case kArm64F32x4Qfma: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + __ Fmla(i.OutputSimd128Register().V4S(), i.InputSimd128Register(1).V4S(), + i.InputSimd128Register(2).V4S()); + break; + } + case kArm64F32x4Qfms: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + __ Fmls(i.OutputSimd128Register().V4S(), i.InputSimd128Register(1).V4S(), + i.InputSimd128Register(2).V4S()); + break; + } case kArm64I64x2Splat: { __ Dup(i.OutputSimd128Register().V2D(), i.InputRegister64(0)); break; @@ -1888,14 +1948,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_UNOP_CASE(kArm64I64x2Neg, Neg, 2D); case kArm64I64x2Shl: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V2D(), i.InputRegister64(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 64. + __ And(shift, i.InputRegister64(1), 63); + __ Dup(tmp.V2D(), shift); __ Sshl(i.OutputSimd128Register().V2D(), i.InputSimd128Register(0).V2D(), tmp.V2D()); break; } case kArm64I64x2ShrS: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V2D(), i.InputRegister64(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 64. + __ And(shift, i.InputRegister64(1), 63); + __ Dup(tmp.V2D(), shift); __ Neg(tmp.V2D(), tmp.V2D()); __ Sshl(i.OutputSimd128Register().V2D(), i.InputSimd128Register(0).V2D(), tmp.V2D()); @@ -1903,6 +1969,65 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } SIMD_BINOP_CASE(kArm64I64x2Add, Add, 2D); SIMD_BINOP_CASE(kArm64I64x2Sub, Sub, 2D); + case kArm64I64x2Mul: { + UseScratchRegisterScope scope(tasm()); + VRegister dst = i.OutputSimd128Register(); + VRegister src1 = i.InputSimd128Register(0); + VRegister src2 = i.InputSimd128Register(1); + VRegister tmp1 = scope.AcquireSameSizeAs(dst); + VRegister tmp2 = scope.AcquireSameSizeAs(dst); + VRegister tmp3 = i.ToSimd128Register(instr->TempAt(0)); + + // This 2x64-bit multiplication is performed with several 32-bit + // multiplications. + + // 64-bit numbers x and y, can be represented as: + // x = a + 2^32(b) + // y = c + 2^32(d) + + // A 64-bit multiplication is: + // x * y = ac + 2^32(ad + bc) + 2^64(bd) + // note: `2^64(bd)` can be ignored, the value is too large to fit in + // 64-bits. + + // This sequence implements a 2x64bit multiply, where the registers + // `src1` and `src2` are split up into 32-bit components: + // src1 = |d|c|b|a| + // src2 = |h|g|f|e| + // + // src1 * src2 = |cg + 2^32(ch + dg)|ae + 2^32(af + be)| + + // Reverse the 32-bit elements in the 64-bit words. + // tmp2 = |g|h|e|f| + __ Rev64(tmp2.V4S(), src2.V4S()); + + // Calculate the high half components. + // tmp2 = |dg|ch|be|af| + __ Mul(tmp2.V4S(), tmp2.V4S(), src1.V4S()); + + // Extract the low half components of src1. + // tmp1 = |c|a| + __ Xtn(tmp1.V2S(), src1.V2D()); + + // Sum the respective high half components. + // tmp2 = |dg+ch|be+af||dg+ch|be+af| + __ Addp(tmp2.V4S(), tmp2.V4S(), tmp2.V4S()); + + // Extract the low half components of src2. + // tmp3 = |g|e| + __ Xtn(tmp3.V2S(), src2.V2D()); + + // Shift the high half components, into the high half. + // dst = |dg+ch << 32|be+af << 32| + __ Shll(dst.V2D(), tmp2.V2S(), 32); + + // Multiply the low components together, and accumulate with the high + // half. + // dst = |dst[1] + cg|dst[0] + ae| + __ Umlal(dst.V2D(), tmp3.V2S(), tmp1.V2S()); + + break; + } SIMD_BINOP_CASE(kArm64I64x2Eq, Cmeq, 2D); case kArm64I64x2Ne: { VRegister dst = i.OutputSimd128Register().V2D(); @@ -1915,7 +2040,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_BINOP_CASE(kArm64I64x2GeS, Cmge, 2D); case kArm64I64x2ShrU: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V2D(), i.InputRegister64(1)); + Register shift = i.TempRegister(1); + // Take shift value modulo 64. + __ And(shift, i.InputRegister64(1), 63); + __ Dup(tmp.V2D(), shift); __ Neg(tmp.V2D(), tmp.V2D()); __ Ushl(i.OutputSimd128Register().V2D(), i.InputSimd128Register(0).V2D(), tmp.V2D()); @@ -1947,14 +2075,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_UNOP_CASE(kArm64I32x4Neg, Neg, 4S); case kArm64I32x4Shl: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V4S(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 32. + __ And(shift, i.InputRegister32(1), 31); + __ Dup(tmp.V4S(), shift); __ Sshl(i.OutputSimd128Register().V4S(), i.InputSimd128Register(0).V4S(), tmp.V4S()); break; } case kArm64I32x4ShrS: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V4S(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 32. + __ And(shift, i.InputRegister32(1), 31); + __ Dup(tmp.V4S(), shift); __ Neg(tmp.V4S(), tmp.V4S()); __ Sshl(i.OutputSimd128Register().V4S(), i.InputSimd128Register(0).V4S(), tmp.V4S()); @@ -1981,7 +2115,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_WIDENING_UNOP_CASE(kArm64I32x4UConvertI16x8High, Uxtl2, 4S, 8H); case kArm64I32x4ShrU: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V4S(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 32. + __ And(shift, i.InputRegister32(1), 31); + __ Dup(tmp.V4S(), shift); __ Neg(tmp.V4S(), tmp.V4S()); __ Ushl(i.OutputSimd128Register().V4S(), i.InputSimd128Register(0).V4S(), tmp.V4S()); @@ -1996,7 +2133,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArm64I16x8ExtractLane: { - __ Smov(i.OutputRegister32(), i.InputSimd128Register(0).V8H(), + __ Umov(i.OutputRegister32(), i.InputSimd128Register(0).V8H(), i.InputInt8(1)); break; } @@ -2014,14 +2151,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_UNOP_CASE(kArm64I16x8Neg, Neg, 8H); case kArm64I16x8Shl: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V8H(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 16. + __ And(shift, i.InputRegister32(1), 15); + __ Dup(tmp.V8H(), shift); __ Sshl(i.OutputSimd128Register().V8H(), i.InputSimd128Register(0).V8H(), tmp.V8H()); break; } case kArm64I16x8ShrS: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V8H(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 16. + __ And(shift, i.InputRegister32(1), 15); + __ Dup(tmp.V8H(), shift); __ Neg(tmp.V8H(), tmp.V8H()); __ Sshl(i.OutputSimd128Register().V8H(), i.InputSimd128Register(0).V8H(), tmp.V8H()); @@ -2070,7 +2213,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kArm64I16x8ShrU: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V8H(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 16. + __ And(shift, i.InputRegister32(1), 15); + __ Dup(tmp.V8H(), shift); __ Neg(tmp.V8H(), tmp.V8H()); __ Ushl(i.OutputSimd128Register().V8H(), i.InputSimd128Register(0).V8H(), tmp.V8H()); @@ -2101,7 +2247,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kArm64I8x16ExtractLane: { - __ Smov(i.OutputRegister32(), i.InputSimd128Register(0).V16B(), + __ Umov(i.OutputRegister32(), i.InputSimd128Register(0).V16B(), i.InputInt8(1)); break; } @@ -2117,14 +2263,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_UNOP_CASE(kArm64I8x16Neg, Neg, 16B); case kArm64I8x16Shl: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V16B(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 8. + __ And(shift, i.InputRegister32(1), 7); + __ Dup(tmp.V16B(), shift); __ Sshl(i.OutputSimd128Register().V16B(), i.InputSimd128Register(0).V16B(), tmp.V16B()); break; } case kArm64I8x16ShrS: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V16B(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 8. + __ And(shift, i.InputRegister32(1), 7); + __ Dup(tmp.V16B(), shift); __ Neg(tmp.V16B(), tmp.V16B()); __ Sshl(i.OutputSimd128Register().V16B(), i.InputSimd128Register(0).V16B(), tmp.V16B()); @@ -2163,7 +2315,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( SIMD_BINOP_CASE(kArm64I8x16GeS, Cmge, 16B); case kArm64I8x16ShrU: { VRegister tmp = i.TempSimd128Register(0); - __ Dup(tmp.V16B(), i.InputRegister32(1)); + Register shift = i.TempRegister32(1); + // Take shift value modulo 8. + __ And(shift, i.InputRegister32(1), 7); + __ Dup(tmp.V16B(), shift); __ Neg(tmp.V16B(), tmp.V16B()); __ Ushl(i.OutputSimd128Register().V16B(), i.InputSimd128Register(0).V16B(), tmp.V16B()); @@ -2277,6 +2432,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( i.InputSimd128Register(1).V16B(), i.InputInt4(2)); break; } + case kArm64S8x16Swizzle: { + __ Tbl(i.OutputSimd128Register().V16B(), i.InputSimd128Register(0).V16B(), + i.InputSimd128Register(1).V16B()); + break; + } case kArm64S8x16Shuffle: { Simd128Register dst = i.OutputSimd128Register().V16B(), src0 = i.InputSimd128Register(0).V16B(), diff --git a/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h b/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h index 4b56e402c15efe..880a3fbf9e0a3a 100644 --- a/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h +++ b/deps/v8/src/compiler/backend/arm64/instruction-codes-arm64.h @@ -70,6 +70,7 @@ namespace compiler { V(Arm64Sxtb) \ V(Arm64Sxth) \ V(Arm64Sxtw) \ + V(Arm64Sbfx) \ V(Arm64Sbfx32) \ V(Arm64Ubfx) \ V(Arm64Ubfx32) \ @@ -175,6 +176,7 @@ namespace compiler { V(Arm64F64x2ReplaceLane) \ V(Arm64F64x2Abs) \ V(Arm64F64x2Neg) \ + V(Arm64F64x2Sqrt) \ V(Arm64F64x2Add) \ V(Arm64F64x2Sub) \ V(Arm64F64x2Mul) \ @@ -185,6 +187,8 @@ namespace compiler { V(Arm64F64x2Ne) \ V(Arm64F64x2Lt) \ V(Arm64F64x2Le) \ + V(Arm64F64x2Qfma) \ + V(Arm64F64x2Qfms) \ V(Arm64F32x4Splat) \ V(Arm64F32x4ExtractLane) \ V(Arm64F32x4ReplaceLane) \ @@ -192,6 +196,7 @@ namespace compiler { V(Arm64F32x4UConvertI32x4) \ V(Arm64F32x4Abs) \ V(Arm64F32x4Neg) \ + V(Arm64F32x4Sqrt) \ V(Arm64F32x4RecipApprox) \ V(Arm64F32x4RecipSqrtApprox) \ V(Arm64F32x4Add) \ @@ -205,6 +210,8 @@ namespace compiler { V(Arm64F32x4Ne) \ V(Arm64F32x4Lt) \ V(Arm64F32x4Le) \ + V(Arm64F32x4Qfma) \ + V(Arm64F32x4Qfms) \ V(Arm64I64x2Splat) \ V(Arm64I64x2ExtractLane) \ V(Arm64I64x2ReplaceLane) \ @@ -213,6 +220,7 @@ namespace compiler { V(Arm64I64x2ShrS) \ V(Arm64I64x2Add) \ V(Arm64I64x2Sub) \ + V(Arm64I64x2Mul) \ V(Arm64I64x2Eq) \ V(Arm64I64x2Ne) \ V(Arm64I64x2GtS) \ @@ -331,6 +339,7 @@ namespace compiler { V(Arm64S8x16TransposeLeft) \ V(Arm64S8x16TransposeRight) \ V(Arm64S8x16Concat) \ + V(Arm64S8x16Swizzle) \ V(Arm64S8x16Shuffle) \ V(Arm64S32x2Reverse) \ V(Arm64S16x4Reverse) \ diff --git a/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc b/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc index 7cba2d50ea0059..b0f92029684703 100644 --- a/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc +++ b/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc @@ -71,6 +71,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64Sxth: case kArm64Sxth32: case kArm64Sxtw: + case kArm64Sbfx: case kArm64Sbfx32: case kArm64Ubfx: case kArm64Ubfx32: @@ -142,6 +143,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64F64x2ReplaceLane: case kArm64F64x2Abs: case kArm64F64x2Neg: + case kArm64F64x2Sqrt: case kArm64F64x2Add: case kArm64F64x2Sub: case kArm64F64x2Mul: @@ -152,6 +154,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64F64x2Ne: case kArm64F64x2Lt: case kArm64F64x2Le: + case kArm64F64x2Qfma: + case kArm64F64x2Qfms: case kArm64F32x4Splat: case kArm64F32x4ExtractLane: case kArm64F32x4ReplaceLane: @@ -159,6 +163,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64F32x4UConvertI32x4: case kArm64F32x4Abs: case kArm64F32x4Neg: + case kArm64F32x4Sqrt: case kArm64F32x4RecipApprox: case kArm64F32x4RecipSqrtApprox: case kArm64F32x4Add: @@ -172,6 +177,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64F32x4Ne: case kArm64F32x4Lt: case kArm64F32x4Le: + case kArm64F32x4Qfma: + case kArm64F32x4Qfms: case kArm64I64x2Splat: case kArm64I64x2ExtractLane: case kArm64I64x2ReplaceLane: @@ -180,6 +187,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64I64x2ShrS: case kArm64I64x2Add: case kArm64I64x2Sub: + case kArm64I64x2Mul: case kArm64I64x2Eq: case kArm64I64x2Ne: case kArm64I64x2GtS: @@ -298,6 +306,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kArm64S8x16TransposeLeft: case kArm64S8x16TransposeRight: case kArm64S8x16Concat: + case kArm64S8x16Swizzle: case kArm64S8x16Shuffle: case kArm64S32x2Reverse: case kArm64S16x4Reverse: @@ -439,6 +448,7 @@ int InstructionScheduler::GetInstructionLatency(const Instruction* instr) { case kArm64Clz: case kArm64Clz32: + case kArm64Sbfx: case kArm64Sbfx32: case kArm64Sxtb32: case kArm64Sxth32: diff --git a/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc b/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc index 4abbd68c49a4a5..53a289fe6a664f 100644 --- a/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc +++ b/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc @@ -153,7 +153,7 @@ void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { void VisitSimdShiftRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { Arm64OperandGenerator g(selector); - InstructionOperand temps[] = {g.TempSimd128Register()}; + InstructionOperand temps[] = {g.TempSimd128Register(), g.TempRegister()}; selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), arraysize(temps), temps); @@ -499,6 +499,7 @@ void VisitAddSub(InstructionSelector* selector, Node* node, ArchOpcode opcode, Arm64OperandGenerator g(selector); Matcher m(node); if (m.right().HasValue() && (m.right().Value() < 0) && + (m.right().Value() > std::numeric_limits<int>::min()) && g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) { selector->Emit(negate_opcode, g.DefineAsRegister(node), g.UseRegister(m.left().node()), @@ -627,9 +628,24 @@ void InstructionSelector::VisitLoad(Node* node) { #else UNREACHABLE(); #endif +#ifdef V8_COMPRESS_POINTERS + case MachineRepresentation::kTaggedSigned: + opcode = kArm64LdrDecompressTaggedSigned; + immediate_mode = kLoadStoreImm32; + break; + case MachineRepresentation::kTaggedPointer: + opcode = kArm64LdrDecompressTaggedPointer; + immediate_mode = kLoadStoreImm32; + break; + case MachineRepresentation::kTagged: + opcode = kArm64LdrDecompressAnyTagged; + immediate_mode = kLoadStoreImm32; + break; +#else case MachineRepresentation::kTaggedSigned: // Fall through. case MachineRepresentation::kTaggedPointer: // Fall through. case MachineRepresentation::kTagged: // Fall through. +#endif case MachineRepresentation::kWord64: opcode = kArm64Ldr; immediate_mode = kLoadStoreImm64; @@ -723,7 +739,7 @@ void InstructionSelector::VisitStore(Node* node) { case MachineRepresentation::kCompressedPointer: // Fall through. case MachineRepresentation::kCompressed: #ifdef V8_COMPRESS_POINTERS - opcode = kArm64StrW; + opcode = kArm64StrCompressTagged; immediate_mode = kLoadStoreImm32; break; #else @@ -731,7 +747,11 @@ void InstructionSelector::VisitStore(Node* node) { #endif case MachineRepresentation::kTaggedSigned: // Fall through. case MachineRepresentation::kTaggedPointer: // Fall through. - case MachineRepresentation::kTagged: // Fall through. + case MachineRepresentation::kTagged: + opcode = kArm64StrCompressTagged; + immediate_mode = + COMPRESS_POINTERS_BOOL ? kLoadStoreImm32 : kLoadStoreImm64; + break; case MachineRepresentation::kWord64: opcode = kArm64Str; immediate_mode = kLoadStoreImm64; @@ -770,6 +790,10 @@ void InstructionSelector::VisitProtectedStore(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + // Architecture supports unaligned access, therefore VisitLoad is used instead void InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); } @@ -1048,7 +1072,8 @@ void InstructionSelector::VisitWord32Shr(Node* node) { if (mleft.right().HasValue() && mleft.right().Value() != 0) { // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is // shifted into the least-significant bits. - uint32_t mask = (mleft.right().Value() >> lsb) << lsb; + uint32_t mask = static_cast<uint32_t>(mleft.right().Value() >> lsb) + << lsb; unsigned mask_width = base::bits::CountPopulation(mask); unsigned mask_msb = base::bits::CountLeadingZeros32(mask); if ((mask_msb + mask_width + lsb) == 32) { @@ -1091,7 +1116,8 @@ void InstructionSelector::VisitWord64Shr(Node* node) { if (mleft.right().HasValue() && mleft.right().Value() != 0) { // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is // shifted into the least-significant bits. - uint64_t mask = (mleft.right().Value() >> lsb) << lsb; + uint64_t mask = static_cast<uint64_t>(mleft.right().Value() >> lsb) + << lsb; unsigned mask_width = base::bits::CountPopulation(mask); unsigned mask_msb = base::bits::CountLeadingZeros64(mask); if ((mask_msb + mask_width + lsb) == 64) { @@ -1240,7 +1266,8 @@ void InstructionSelector::VisitWord64Ror(Node* node) { V(Float32Max, kArm64Float32Max) \ V(Float64Max, kArm64Float64Max) \ V(Float32Min, kArm64Float32Min) \ - V(Float64Min, kArm64Float64Min) + V(Float64Min, kArm64Float64Min) \ + V(S8x16Swizzle, kArm64S8x16Swizzle) #define RR_VISITOR(Name, opcode) \ void InstructionSelector::Visit##Name(Node* node) { \ @@ -1572,9 +1599,22 @@ void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { return; } EmitLoad(this, value, opcode, immediate_mode, rep, node); - } else { - VisitRR(this, kArm64Sxtw, node); + return; + } + + if (value->opcode() == IrOpcode::kWord32Sar && CanCover(node, value)) { + Int32BinopMatcher m(value); + if (m.right().HasValue()) { + Arm64OperandGenerator g(this); + // Mask the shift amount, to keep the same semantics as Word32Sar. + int right = m.right().Value() & 0x1F; + Emit(kArm64Sbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()), + g.TempImmediate(right), g.TempImmediate(32 - right)); + return; + } } + + VisitRR(this, kArm64Sxtw, node); } void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { @@ -1830,31 +1870,6 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, selector->EmitWithContinuation(opcode, left, right, cont); } -// Shared routine for multiple word compare operations. -void VisitWordCompare(InstructionSelector* selector, Node* node, - InstructionCode opcode, FlagsContinuation* cont, - ImmediateMode immediate_mode) { - Arm64OperandGenerator g(selector); - - Node* left = node->InputAt(0); - Node* right = node->InputAt(1); - - // If one of the two inputs is an immediate, make sure it's on the right. - if (!g.CanBeImmediate(right, immediate_mode) && - g.CanBeImmediate(left, immediate_mode)) { - cont->Commute(); - std::swap(left, right); - } - - if (g.CanBeImmediate(right, immediate_mode)) { - VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), - cont); - } else { - VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), - cont); - } -} - // This function checks whether we can convert: // ((a <op> b) cmp 0), b.<cond> // to: @@ -1986,9 +2001,35 @@ void EmitBranchOrDeoptimize(InstructionSelector* selector, selector->EmitWithContinuation(opcode, value, cont); } +template <int N> +struct CbzOrTbzMatchTrait {}; + +template <> +struct CbzOrTbzMatchTrait<32> { + using IntegralType = uint32_t; + using BinopMatcher = Int32BinopMatcher; + static constexpr IrOpcode::Value kAndOpcode = IrOpcode::kWord32And; + static constexpr ArchOpcode kTestAndBranchOpcode = kArm64TestAndBranch32; + static constexpr ArchOpcode kCompareAndBranchOpcode = + kArm64CompareAndBranch32; + static constexpr unsigned kSignBit = kWSignBit; +}; + +template <> +struct CbzOrTbzMatchTrait<64> { + using IntegralType = uint64_t; + using BinopMatcher = Int64BinopMatcher; + static constexpr IrOpcode::Value kAndOpcode = IrOpcode::kWord64And; + static constexpr ArchOpcode kTestAndBranchOpcode = kArm64TestAndBranch; + static constexpr ArchOpcode kCompareAndBranchOpcode = kArm64CompareAndBranch; + static constexpr unsigned kSignBit = kXSignBit; +}; + // Try to emit TBZ, TBNZ, CBZ or CBNZ for certain comparisons of {node} // against {value}, depending on the condition. -bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, uint32_t value, +template <int N> +bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, + typename CbzOrTbzMatchTrait<N>::IntegralType value, Node* user, FlagsCondition cond, FlagsContinuation* cont) { // Branch poisoning requires flags to be set, so when it's enabled for // a particular branch, we shouldn't be applying the cbz/tbz optimization. @@ -2007,28 +2048,33 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, uint32_t value, if (cont->IsDeoptimize()) return false; Arm64OperandGenerator g(selector); cont->Overwrite(MapForTbz(cond)); - Int32Matcher m(node); - if (m.IsFloat64ExtractHighWord32() && selector->CanCover(user, node)) { - // SignedLessThan(Float64ExtractHighWord32(x), 0) and - // SignedGreaterThanOrEqual(Float64ExtractHighWord32(x), 0) essentially - // check the sign bit of a 64-bit floating point value. - InstructionOperand temp = g.TempRegister(); - selector->Emit(kArm64U64MoveFloat64, temp, - g.UseRegister(node->InputAt(0))); - selector->EmitWithContinuation(kArm64TestAndBranch, temp, - g.TempImmediate(63), cont); - return true; + + if (N == 32) { + Int32Matcher m(node); + if (m.IsFloat64ExtractHighWord32() && selector->CanCover(user, node)) { + // SignedLessThan(Float64ExtractHighWord32(x), 0) and + // SignedGreaterThanOrEqual(Float64ExtractHighWord32(x), 0) + // essentially check the sign bit of a 64-bit floating point value. + InstructionOperand temp = g.TempRegister(); + selector->Emit(kArm64U64MoveFloat64, temp, + g.UseRegister(node->InputAt(0))); + selector->EmitWithContinuation(kArm64TestAndBranch, temp, + g.TempImmediate(kDSignBit), cont); + return true; + } } - selector->EmitWithContinuation(kArm64TestAndBranch32, g.UseRegister(node), - g.TempImmediate(31), cont); + + selector->EmitWithContinuation( + CbzOrTbzMatchTrait<N>::kTestAndBranchOpcode, g.UseRegister(node), + g.TempImmediate(CbzOrTbzMatchTrait<N>::kSignBit), cont); return true; } case kEqual: case kNotEqual: { - if (node->opcode() == IrOpcode::kWord32And) { + if (node->opcode() == CbzOrTbzMatchTrait<N>::kAndOpcode) { // Emit a tbz/tbnz if we are comparing with a single-bit mask: - // Branch(Word32Equal(Word32And(x, 1 << N), 1 << N), true, false) - Int32BinopMatcher m_and(node); + // Branch(WordEqual(WordAnd(x, 1 << N), 1 << N), true, false) + typename CbzOrTbzMatchTrait<N>::BinopMatcher m_and(node); if (cont->IsBranch() && base::bits::IsPowerOfTwo(value) && m_and.right().Is(value) && selector->CanCover(user, node)) { Arm64OperandGenerator g(selector); @@ -2036,7 +2082,8 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, uint32_t value, // the opposite here so negate the condition. cont->Negate(); selector->EmitWithContinuation( - kArm64TestAndBranch32, g.UseRegister(m_and.left().node()), + CbzOrTbzMatchTrait<N>::kTestAndBranchOpcode, + g.UseRegister(m_and.left().node()), g.TempImmediate(base::bits::CountTrailingZeros(value)), cont); return true; } @@ -2048,7 +2095,8 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, uint32_t value, if (value != 0) return false; Arm64OperandGenerator g(selector); cont->Overwrite(MapForCbz(cond)); - EmitBranchOrDeoptimize(selector, kArm64CompareAndBranch32, + EmitBranchOrDeoptimize(selector, + CbzOrTbzMatchTrait<N>::kCompareAndBranchOpcode, g.UseRegister(node), cont); return true; } @@ -2057,20 +2105,50 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, Node* node, uint32_t value, } } +// Shared routine for multiple word compare operations. +void VisitWordCompare(InstructionSelector* selector, Node* node, + InstructionCode opcode, FlagsContinuation* cont, + ImmediateMode immediate_mode) { + Arm64OperandGenerator g(selector); + + Node* left = node->InputAt(0); + Node* right = node->InputAt(1); + + // If one of the two inputs is an immediate, make sure it's on the right. + if (!g.CanBeImmediate(right, immediate_mode) && + g.CanBeImmediate(left, immediate_mode)) { + cont->Commute(); + std::swap(left, right); + } + + if (opcode == kArm64Cmp && !cont->IsPoisoned()) { + Int64Matcher m(right); + if (m.HasValue()) { + if (TryEmitCbzOrTbz<64>(selector, left, m.Value(), node, + cont->condition(), cont)) { + return; + } + } + } + + VisitCompare(selector, opcode, g.UseRegister(left), + g.UseOperand(right, immediate_mode), cont); +} + void VisitWord32Compare(InstructionSelector* selector, Node* node, FlagsContinuation* cont) { Int32BinopMatcher m(node); FlagsCondition cond = cont->condition(); if (!cont->IsPoisoned()) { if (m.right().HasValue()) { - if (TryEmitCbzOrTbz(selector, m.left().node(), m.right().Value(), node, - cond, cont)) { + if (TryEmitCbzOrTbz<32>(selector, m.left().node(), m.right().Value(), + node, cond, cont)) { return; } } else if (m.left().HasValue()) { FlagsCondition commuted_cond = CommuteFlagsCondition(cond); - if (TryEmitCbzOrTbz(selector, m.right().node(), m.left().Value(), node, - commuted_cond, cont)) { + if (TryEmitCbzOrTbz<32>(selector, m.right().node(), m.left().Value(), + node, commuted_cond, cont)) { return; } } @@ -2378,13 +2456,6 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, if (CanCover(value, left) && left->opcode() == IrOpcode::kWord64And) { return VisitWordCompare(this, left, kArm64Tst, cont, kLogical64Imm); } - // Merge the Word64Equal(x, 0) comparison into a cbz instruction. - if ((cont->IsBranch() || cont->IsDeoptimize()) && - !cont->IsPoisoned()) { - EmitBranchOrDeoptimize(this, kArm64CompareAndBranch, - g.UseRegister(left), cont); - return; - } } return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm); } @@ -3054,10 +3125,12 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { #define SIMD_UNOP_LIST(V) \ V(F64x2Abs, kArm64F64x2Abs) \ V(F64x2Neg, kArm64F64x2Neg) \ + V(F64x2Sqrt, kArm64F64x2Sqrt) \ V(F32x4SConvertI32x4, kArm64F32x4SConvertI32x4) \ V(F32x4UConvertI32x4, kArm64F32x4UConvertI32x4) \ V(F32x4Abs, kArm64F32x4Abs) \ V(F32x4Neg, kArm64F32x4Neg) \ + V(F32x4Sqrt, kArm64F32x4Sqrt) \ V(F32x4RecipApprox, kArm64F32x4RecipApprox) \ V(F32x4RecipSqrtApprox, kArm64F32x4RecipSqrtApprox) \ V(I64x2Neg, kArm64I64x2Neg) \ @@ -3236,6 +3309,14 @@ SIMD_BINOP_LIST(SIMD_VISIT_BINOP) #undef SIMD_VISIT_BINOP #undef SIMD_BINOP_LIST +void InstructionSelector::VisitI64x2Mul(Node* node) { + Arm64OperandGenerator g(this); + InstructionOperand temps[] = {g.TempSimd128Register()}; + Emit(kArm64I64x2Mul, g.DefineAsRegister(node), + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), + arraysize(temps), temps); +} + void InstructionSelector::VisitS128Select(Node* node) { Arm64OperandGenerator g(this); Emit(kArm64S128Select, g.DefineSameAsFirst(node), @@ -3243,6 +3324,19 @@ void InstructionSelector::VisitS128Select(Node* node) { g.UseRegister(node->InputAt(2))); } +#define VISIT_SIMD_QFMOP(op) \ + void InstructionSelector::Visit##op(Node* node) { \ + Arm64OperandGenerator g(this); \ + Emit(kArm64##op, g.DefineSameAsFirst(node), \ + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), \ + g.UseRegister(node->InputAt(2))); \ + } +VISIT_SIMD_QFMOP(F64x2Qfma) +VISIT_SIMD_QFMOP(F64x2Qfms) +VISIT_SIMD_QFMOP(F32x4Qfma) +VISIT_SIMD_QFMOP(F32x4Qfms) +#undef VISIT_SIMD_QFMOP + namespace { struct ShuffleEntry { diff --git a/deps/v8/src/compiler/backend/code-generator-impl.h b/deps/v8/src/compiler/backend/code-generator-impl.h index 2bfb009980dcf8..530dc0a8136fc0 100644 --- a/deps/v8/src/compiler/backend/code-generator-impl.h +++ b/deps/v8/src/compiler/backend/code-generator-impl.h @@ -26,7 +26,7 @@ class InstructionOperandConverter { // -- Instruction operand accesses with conversions -------------------------- - Register InputRegister(size_t index) { + Register InputRegister(size_t index) const { return ToRegister(instr_->InputAt(index)); } @@ -96,7 +96,7 @@ class InstructionOperandConverter { return ToRpoNumber(instr_->InputAt(index)); } - Register OutputRegister(size_t index = 0) { + Register OutputRegister(size_t index = 0) const { return ToRegister(instr_->OutputAt(index)); } @@ -130,7 +130,7 @@ class InstructionOperandConverter { return ToConstant(op).ToRpoNumber(); } - Register ToRegister(InstructionOperand* op) { + Register ToRegister(InstructionOperand* op) const { return LocationOperand::cast(op)->GetRegister(); } @@ -146,7 +146,7 @@ class InstructionOperandConverter { return LocationOperand::cast(op)->GetSimd128Register(); } - Constant ToConstant(InstructionOperand* op) { + Constant ToConstant(InstructionOperand* op) const { if (op->IsImmediate()) { return gen_->instructions()->GetImmediate(ImmediateOperand::cast(op)); } diff --git a/deps/v8/src/compiler/backend/code-generator.cc b/deps/v8/src/compiler/backend/code-generator.cc index e7702bcdf625d2..43eb4a1f15a590 100644 --- a/deps/v8/src/compiler/backend/code-generator.cc +++ b/deps/v8/src/compiler/backend/code-generator.cc @@ -4,7 +4,7 @@ #include "src/compiler/backend/code-generator.h" -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/macro-assembler-inl.h" #include "src/codegen/optimized-compilation-info.h" diff --git a/deps/v8/src/compiler/backend/code-generator.h b/deps/v8/src/compiler/backend/code-generator.h index e9ebf675905dbd..d56b1edae0e0a8 100644 --- a/deps/v8/src/compiler/backend/code-generator.h +++ b/deps/v8/src/compiler/backend/code-generator.h @@ -5,6 +5,8 @@ #ifndef V8_COMPILER_BACKEND_CODE_GENERATOR_H_ #define V8_COMPILER_BACKEND_CODE_GENERATOR_H_ +#include <memory> + #include "src/base/optional.h" #include "src/codegen/macro-assembler.h" #include "src/codegen/safepoint-table.h" diff --git a/deps/v8/src/compiler/backend/frame-elider.cc b/deps/v8/src/compiler/backend/frame-elider.cc index 064501b0971b06..293fc9352c4d7f 100644 --- a/deps/v8/src/compiler/backend/frame-elider.cc +++ b/deps/v8/src/compiler/backend/frame-elider.cc @@ -4,7 +4,7 @@ #include "src/compiler/backend/frame-elider.h" -#include "src/base/adapters.h" +#include "src/base/iterator.h" namespace v8 { namespace internal { diff --git a/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc b/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc index 4542da643b4b87..068268a3da4940 100644 --- a/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc +++ b/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc @@ -479,17 +479,18 @@ class OutOfLineRecordWrite final : public OutOfLineCode { __ opcode(i.OutputSimd128Register(), i.InputOperand(1), imm); \ } -#define ASSEMBLE_SIMD_ALL_TRUE(opcode) \ - do { \ - Register dst = i.OutputRegister(); \ - Operand src = i.InputOperand(0); \ - Register tmp = i.TempRegister(0); \ - __ mov(tmp, Immediate(1)); \ - __ xor_(dst, dst); \ - __ Pxor(kScratchDoubleReg, kScratchDoubleReg); \ - __ opcode(kScratchDoubleReg, src); \ - __ Ptest(kScratchDoubleReg, kScratchDoubleReg); \ - __ cmov(zero, dst, tmp); \ +#define ASSEMBLE_SIMD_ALL_TRUE(opcode) \ + do { \ + Register dst = i.OutputRegister(); \ + Operand src = i.InputOperand(0); \ + Register tmp = i.TempRegister(0); \ + XMMRegister tmp_simd = i.TempSimd128Register(1); \ + __ mov(tmp, Immediate(1)); \ + __ xor_(dst, dst); \ + __ Pxor(tmp_simd, tmp_simd); \ + __ opcode(tmp_simd, src); \ + __ Ptest(tmp_simd, tmp_simd); \ + __ cmov(zero, dst, tmp); \ } while (false) void CodeGenerator::AssembleDeconstructFrame() { @@ -1266,16 +1267,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; case kSSEFloat32Abs: { // TODO(bmeurer): Use 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psrlq(kScratchDoubleReg, 33); - __ andps(i.OutputDoubleRegister(), kScratchDoubleReg); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psrlq(tmp, 33); + __ andps(i.OutputDoubleRegister(), tmp); break; } case kSSEFloat32Neg: { // TODO(bmeurer): Use 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psllq(kScratchDoubleReg, 31); - __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psllq(tmp, 31); + __ xorps(i.OutputDoubleRegister(), tmp); break; } case kSSEFloat32Round: { @@ -1444,16 +1447,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kSSEFloat64Abs: { // TODO(bmeurer): Use 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psrlq(kScratchDoubleReg, 1); - __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psrlq(tmp, 1); + __ andpd(i.OutputDoubleRegister(), tmp); break; } case kSSEFloat64Neg: { // TODO(bmeurer): Use 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psllq(kScratchDoubleReg, 63); - __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psllq(tmp, 63); + __ xorpd(i.OutputDoubleRegister(), tmp); break; } case kSSEFloat64Sqrt: @@ -1476,13 +1481,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ cvttss2si(i.OutputRegister(), i.InputOperand(0)); break; case kSSEFloat32ToUint32: - __ Cvttss2ui(i.OutputRegister(), i.InputOperand(0), kScratchDoubleReg); + __ Cvttss2ui(i.OutputRegister(), i.InputOperand(0), + i.TempSimd128Register(0)); break; case kSSEFloat64ToInt32: __ cvttsd2si(i.OutputRegister(), i.InputOperand(0)); break; case kSSEFloat64ToUint32: - __ Cvttsd2ui(i.OutputRegister(), i.InputOperand(0), kScratchDoubleReg); + __ Cvttsd2ui(i.OutputRegister(), i.InputOperand(0), + i.TempSimd128Register(0)); break; case kSSEInt32ToFloat32: __ cvtsi2ss(i.OutputDoubleRegister(), i.InputOperand(0)); @@ -1577,34 +1584,38 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kAVXFloat32Abs: { // TODO(bmeurer): Use RIP relative 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psrlq(kScratchDoubleReg, 33); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psrlq(tmp, 33); CpuFeatureScope avx_scope(tasm(), AVX); - __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0)); + __ vandps(i.OutputDoubleRegister(), tmp, i.InputOperand(0)); break; } case kAVXFloat32Neg: { // TODO(bmeurer): Use RIP relative 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psllq(kScratchDoubleReg, 31); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psllq(tmp, 31); CpuFeatureScope avx_scope(tasm(), AVX); - __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0)); + __ vxorps(i.OutputDoubleRegister(), tmp, i.InputOperand(0)); break; } case kAVXFloat64Abs: { // TODO(bmeurer): Use RIP relative 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psrlq(kScratchDoubleReg, 1); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psrlq(tmp, 1); CpuFeatureScope avx_scope(tasm(), AVX); - __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0)); + __ vandpd(i.OutputDoubleRegister(), tmp, i.InputOperand(0)); break; } case kAVXFloat64Neg: { // TODO(bmeurer): Use RIP relative 128-bit constants. - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psllq(kScratchDoubleReg, 63); + XMMRegister tmp = i.TempSimd128Register(0); + __ pcmpeqd(tmp, tmp); + __ psllq(tmp, 63); CpuFeatureScope avx_scope(tasm(), AVX); - __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0)); + __ vxorpd(i.OutputDoubleRegister(), tmp, i.InputOperand(0)); break; } case kSSEFloat64SilenceNaN: @@ -1825,6 +1836,164 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } break; } + case kSSEF64x2Splat: { + DCHECK_EQ(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + XMMRegister dst = i.OutputSimd128Register(); + __ shufpd(dst, dst, 0x0); + break; + } + case kAVXF64x2Splat: { + CpuFeatureScope avx_scope(tasm(), AVX); + XMMRegister src = i.InputDoubleRegister(0); + __ vshufpd(i.OutputSimd128Register(), src, src, 0x0); + break; + } + case kSSEF64x2ExtractLane: { + DCHECK_EQ(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); + XMMRegister dst = i.OutputDoubleRegister(); + int8_t lane = i.InputInt8(1); + if (lane != 0) { + DCHECK_LT(lane, 4); + __ shufpd(dst, dst, lane); + } + break; + } + case kAVXF64x2ExtractLane: { + CpuFeatureScope avx_scope(tasm(), AVX); + XMMRegister dst = i.OutputDoubleRegister(); + XMMRegister src = i.InputSimd128Register(0); + int8_t lane = i.InputInt8(1); + if (lane == 0) { + if (dst != src) __ vmovapd(dst, src); + } else { + DCHECK_LT(lane, 4); + __ vshufpd(dst, src, src, lane); + } + break; + } + case kSSEF64x2ReplaceLane: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + CpuFeatureScope sse_scope(tasm(), SSE4_1); + XMMRegister dst = i.OutputSimd128Register(); + int8_t lane = i.InputInt8(1); + DoubleRegister rep = i.InputDoubleRegister(2); + + // insertps takes a mask which contains (high to low): + // - 2 bit specifying source float element to copy + // - 2 bit specifying destination float element to write to + // - 4 bits specifying which elements of the destination to zero + DCHECK_LT(lane, 2); + if (lane == 0) { + __ insertps(dst, rep, 0b00000000); + __ insertps(dst, rep, 0b01010000); + } else { + __ insertps(dst, rep, 0b00100000); + __ insertps(dst, rep, 0b01110000); + } + break; + } + case kAVXF64x2ReplaceLane: { + CpuFeatureScope avx_scope(tasm(), AVX); + XMMRegister dst = i.OutputSimd128Register(); + XMMRegister src = i.InputSimd128Register(0); + int8_t lane = i.InputInt8(1); + DoubleRegister rep = i.InputDoubleRegister(2); + + DCHECK_LT(lane, 2); + if (lane == 0) { + __ vinsertps(dst, src, rep, 0b00000000); + __ vinsertps(dst, src, rep, 0b01010000); + } else { + __ vinsertps(dst, src, rep, 0b10100000); + __ vinsertps(dst, src, rep, 0b11110000); + } + break; + } + case kIA32F64x2Sqrt: { + __ Sqrtpd(i.OutputSimd128Register(), i.InputOperand(0)); + break; + } + case kIA32F64x2Add: { + __ Addpd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Sub: { + __ Subpd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Mul: { + __ Mulpd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Div: { + __ Divpd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Min: { + Operand src1 = i.InputOperand(1); + XMMRegister dst = i.OutputSimd128Register(), + src = i.InputSimd128Register(0), + tmp = i.TempSimd128Register(0); + // The minpd instruction doesn't propagate NaNs and +0's in its first + // operand. Perform minpd in both orders, merge the resuls, and adjust. + __ Movapd(tmp, src1); + __ Minpd(tmp, tmp, src); + __ Minpd(dst, src, src1); + // propagate -0's and NaNs, which may be non-canonical. + __ Orpd(tmp, dst); + // Canonicalize NaNs by quieting and clearing the payload. + __ Cmpunordpd(dst, dst, tmp); + __ Orpd(tmp, dst); + __ Psrlq(dst, 13); + __ Andnpd(dst, tmp); + break; + } + case kIA32F64x2Max: { + Operand src1 = i.InputOperand(1); + XMMRegister dst = i.OutputSimd128Register(), + src = i.InputSimd128Register(0), + tmp = i.TempSimd128Register(0); + // The maxpd instruction doesn't propagate NaNs and +0's in its first + // operand. Perform maxpd in both orders, merge the resuls, and adjust. + __ Movapd(tmp, src1); + __ Maxpd(tmp, tmp, src); + __ Maxpd(dst, src, src1); + // Find discrepancies. + __ Xorpd(dst, tmp); + // Propagate NaNs, which may be non-canonical. + __ Orpd(tmp, dst); + // Propagate sign discrepancy and (subtle) quiet NaNs. + __ Subpd(tmp, tmp, dst); + // Canonicalize NaNs by clearing the payload. Sign is non-deterministic. + __ Cmpunordpd(dst, dst, tmp); + __ Psrlq(dst, 13); + __ Andnpd(dst, tmp); + break; + } + case kIA32F64x2Eq: { + __ Cmpeqpd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Ne: { + __ Cmpneqpd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Lt: { + __ Cmpltpd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } + case kIA32F64x2Le: { + __ Cmplepd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } case kSSEF32x4Splat: { DCHECK_EQ(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); XMMRegister dst = i.OutputSimd128Register(); @@ -1951,6 +2120,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( i.InputOperand(0)); break; } + case kSSEF32x4Sqrt: { + __ sqrtps(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } + case kAVXF32x4Sqrt: { + CpuFeatureScope avx_scope(tasm(), AVX); + __ vsqrtps(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } case kIA32F32x4RecipApprox: { __ Rcpps(i.OutputSimd128Register(), i.InputOperand(0)); break; @@ -2212,28 +2390,40 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kSSEI32x4Shl: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ pslld(i.OutputSimd128Register(), tmp); break; } case kAVXI32x4Shl: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ vpslld(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } case kSSEI32x4ShrS: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ psrad(i.OutputSimd128Register(), tmp); break; } case kAVXI32x4ShrS: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ vpsrad(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } @@ -2430,14 +2620,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kSSEI32x4ShrU: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ psrld(i.OutputSimd128Register(), tmp); break; } case kAVXI32x4ShrU: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ and_(shift, 31); + __ movd(tmp, shift); __ vpsrld(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } @@ -2514,7 +2710,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kIA32I16x8ExtractLane: { Register dst = i.OutputRegister(); __ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1)); - __ movsx_w(dst, dst); break; } case kSSEI16x8ReplaceLane: { @@ -2553,28 +2748,40 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kSSEI16x8Shl: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ psllw(i.OutputSimd128Register(), tmp); break; } case kAVXI16x8Shl: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ vpsllw(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } case kSSEI16x8ShrS: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ psraw(i.OutputSimd128Register(), tmp); break; } case kAVXI16x8ShrS: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ vpsraw(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } @@ -2745,14 +2952,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kSSEI16x8ShrU: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ psrlw(i.OutputSimd128Register(), tmp); break; } case kAVXI16x8ShrU: { CpuFeatureScope avx_scope(tasm(), AVX); XMMRegister tmp = i.TempSimd128Register(0); - __ movd(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ and_(shift, 15); + __ movd(tmp, shift); __ vpsrlw(i.OutputSimd128Register(), i.InputSimd128Register(0), tmp); break; } @@ -2875,7 +3088,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kIA32I8x16ExtractLane: { Register dst = i.OutputRegister(); __ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1)); - __ movsx_b(dst, dst); break; } case kSSEI8x16ReplaceLane: { @@ -2919,6 +3131,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( Register shift = i.InputRegister(1); Register tmp = i.ToRegister(instr->TempAt(0)); XMMRegister tmp_simd = i.TempSimd128Register(1); + // Take shift value modulo 8. + __ and_(shift, 7); // Mask off the unwanted bits before word-shifting. __ pcmpeqw(kScratchDoubleReg, kScratchDoubleReg); __ mov(tmp, shift); @@ -2938,6 +3152,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( Register shift = i.InputRegister(1); Register tmp = i.ToRegister(instr->TempAt(0)); XMMRegister tmp_simd = i.TempSimd128Register(1); + // Take shift value modulo 8. + __ and_(shift, 7); // Mask off the unwanted bits before word-shifting. __ vpcmpeqw(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg); __ mov(tmp, shift); @@ -2959,6 +3175,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ punpckhbw(kScratchDoubleReg, dst); __ punpcklbw(dst, dst); __ mov(tmp, i.InputRegister(1)); + // Take shift value modulo 8. + __ and_(tmp, 7); __ add(tmp, Immediate(8)); __ movd(tmp_simd, tmp); __ psraw(kScratchDoubleReg, tmp_simd); @@ -3223,6 +3441,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ punpckhbw(kScratchDoubleReg, dst); __ punpcklbw(dst, dst); __ mov(tmp, i.InputRegister(1)); + // Take shift value modulo 8. + __ and_(tmp, 7); __ add(tmp, Immediate(8)); __ movd(tmp_simd, tmp); __ psrlw(kScratchDoubleReg, tmp_simd); @@ -3365,6 +3585,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ vxorps(dst, kScratchDoubleReg, i.InputSimd128Register(2)); break; } + case kIA32S8x16Swizzle: { + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + XMMRegister dst = i.OutputSimd128Register(); + XMMRegister mask = i.TempSimd128Register(0); + + // Out-of-range indices should return 0, add 112 so that any value > 15 + // saturates to 128 (top bit set), so pshufb will zero that lane. + __ Move(mask, (uint32_t)0x70707070); + __ Pshufd(mask, mask, 0x0); + __ Paddusb(mask, i.InputSimd128Register(1)); + __ Pshufb(dst, mask); + break; + } case kIA32S8x16Shuffle: { XMMRegister dst = i.OutputSimd128Register(); Operand src0 = i.InputOperand(0); diff --git a/deps/v8/src/compiler/backend/ia32/instruction-codes-ia32.h b/deps/v8/src/compiler/backend/ia32/instruction-codes-ia32.h index 7530c716b85c0c..a77fb8cd372edc 100644 --- a/deps/v8/src/compiler/backend/ia32/instruction-codes-ia32.h +++ b/deps/v8/src/compiler/backend/ia32/instruction-codes-ia32.h @@ -116,6 +116,23 @@ namespace compiler { V(IA32PushSimd128) \ V(IA32Poke) \ V(IA32Peek) \ + V(SSEF64x2Splat) \ + V(AVXF64x2Splat) \ + V(SSEF64x2ExtractLane) \ + V(AVXF64x2ExtractLane) \ + V(SSEF64x2ReplaceLane) \ + V(AVXF64x2ReplaceLane) \ + V(IA32F64x2Sqrt) \ + V(IA32F64x2Add) \ + V(IA32F64x2Sub) \ + V(IA32F64x2Mul) \ + V(IA32F64x2Div) \ + V(IA32F64x2Min) \ + V(IA32F64x2Max) \ + V(IA32F64x2Eq) \ + V(IA32F64x2Ne) \ + V(IA32F64x2Lt) \ + V(IA32F64x2Le) \ V(SSEF32x4Splat) \ V(AVXF32x4Splat) \ V(SSEF32x4ExtractLane) \ @@ -129,6 +146,8 @@ namespace compiler { V(AVXF32x4Abs) \ V(SSEF32x4Neg) \ V(AVXF32x4Neg) \ + V(SSEF32x4Sqrt) \ + V(AVXF32x4Sqrt) \ V(IA32F32x4RecipApprox) \ V(IA32F32x4RecipSqrtApprox) \ V(SSEF32x4Add) \ @@ -313,6 +332,7 @@ namespace compiler { V(AVXS128Xor) \ V(SSES128Select) \ V(AVXS128Select) \ + V(IA32S8x16Swizzle) \ V(IA32S8x16Shuffle) \ V(IA32S32x4Swizzle) \ V(IA32S32x4Shuffle) \ diff --git a/deps/v8/src/compiler/backend/ia32/instruction-scheduler-ia32.cc b/deps/v8/src/compiler/backend/ia32/instruction-scheduler-ia32.cc index c2097a6691fd1b..287eb49a4803aa 100644 --- a/deps/v8/src/compiler/backend/ia32/instruction-scheduler-ia32.cc +++ b/deps/v8/src/compiler/backend/ia32/instruction-scheduler-ia32.cc @@ -97,6 +97,23 @@ int InstructionScheduler::GetTargetInstructionFlags( case kAVXFloat32Neg: case kIA32BitcastFI: case kIA32BitcastIF: + case kSSEF64x2Splat: + case kAVXF64x2Splat: + case kSSEF64x2ExtractLane: + case kAVXF64x2ExtractLane: + case kSSEF64x2ReplaceLane: + case kAVXF64x2ReplaceLane: + case kIA32F64x2Sqrt: + case kIA32F64x2Add: + case kIA32F64x2Sub: + case kIA32F64x2Mul: + case kIA32F64x2Div: + case kIA32F64x2Min: + case kIA32F64x2Max: + case kIA32F64x2Eq: + case kIA32F64x2Ne: + case kIA32F64x2Lt: + case kIA32F64x2Le: case kSSEF32x4Splat: case kAVXF32x4Splat: case kSSEF32x4ExtractLane: @@ -110,6 +127,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kAVXF32x4Abs: case kSSEF32x4Neg: case kAVXF32x4Neg: + case kSSEF32x4Sqrt: + case kAVXF32x4Sqrt: case kIA32F32x4RecipApprox: case kIA32F32x4RecipSqrtApprox: case kSSEF32x4Add: @@ -294,6 +313,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kAVXS128Xor: case kSSES128Select: case kAVXS128Select: + case kIA32S8x16Swizzle: case kIA32S8x16Shuffle: case kIA32S32x4Swizzle: case kIA32S32x4Shuffle: diff --git a/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc b/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc index ebef39a93a65ec..a24727aba20f26 100644 --- a/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc +++ b/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties.h" @@ -200,12 +200,27 @@ namespace { void VisitRO(InstructionSelector* selector, Node* node, ArchOpcode opcode) { IA32OperandGenerator g(selector); - InstructionOperand temps[] = {g.TempRegister()}; Node* input = node->InputAt(0); // We have to use a byte register as input to movsxb. InstructionOperand input_op = opcode == kIA32Movsxbl ? g.UseFixed(input, eax) : g.Use(input); - selector->Emit(opcode, g.DefineAsRegister(node), input_op, arraysize(temps), + selector->Emit(opcode, g.DefineAsRegister(node), input_op); +} + +void VisitROWithTemp(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + IA32OperandGenerator g(selector); + InstructionOperand temps[] = {g.TempRegister()}; + selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)), + arraysize(temps), temps); +} + +void VisitROWithTempSimd(InstructionSelector* selector, Node* node, + ArchOpcode opcode) { + IA32OperandGenerator g(selector); + InstructionOperand temps[] = {g.TempSimd128Register()}; + selector->Emit(opcode, g.DefineAsRegister(node), + g.UseUniqueRegister(node->InputAt(0)), arraysize(temps), temps); } @@ -231,10 +246,13 @@ void VisitRROFloat(InstructionSelector* selector, Node* node, void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input, ArchOpcode avx_opcode, ArchOpcode sse_opcode) { IA32OperandGenerator g(selector); + InstructionOperand temps[] = {g.TempSimd128Register()}; if (selector->IsSupported(AVX)) { - selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input)); + selector->Emit(avx_opcode, g.DefineAsRegister(node), g.UseUnique(input), + arraysize(temps), temps); } else { - selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input)); + selector->Emit(sse_opcode, g.DefineSameAsFirst(node), + g.UseUniqueRegister(input), arraysize(temps), temps); } } @@ -804,12 +822,8 @@ void InstructionSelector::VisitWord32Ror(Node* node) { V(ChangeFloat32ToFloat64, kSSEFloat32ToFloat64) \ V(RoundInt32ToFloat32, kSSEInt32ToFloat32) \ V(ChangeInt32ToFloat64, kSSEInt32ToFloat64) \ - V(ChangeUint32ToFloat64, kSSEUint32ToFloat64) \ V(TruncateFloat32ToInt32, kSSEFloat32ToInt32) \ - V(TruncateFloat32ToUint32, kSSEFloat32ToUint32) \ V(ChangeFloat64ToInt32, kSSEFloat64ToInt32) \ - V(ChangeFloat64ToUint32, kSSEFloat64ToUint32) \ - V(TruncateFloat64ToUint32, kSSEFloat64ToUint32) \ V(TruncateFloat64ToFloat32, kSSEFloat64ToFloat32) \ V(RoundFloat64ToInt32, kSSEFloat64ToInt32) \ V(BitcastFloat32ToInt32, kIA32BitcastFI) \ @@ -819,7 +833,15 @@ void InstructionSelector::VisitWord32Ror(Node* node) { V(Float64ExtractLowWord32, kSSEFloat64ExtractLowWord32) \ V(Float64ExtractHighWord32, kSSEFloat64ExtractHighWord32) \ V(SignExtendWord8ToInt32, kIA32Movsxbl) \ - V(SignExtendWord16ToInt32, kIA32Movsxwl) + V(SignExtendWord16ToInt32, kIA32Movsxwl) \ + V(F64x2Sqrt, kIA32F64x2Sqrt) + +#define RO_WITH_TEMP_OP_LIST(V) V(ChangeUint32ToFloat64, kSSEUint32ToFloat64) + +#define RO_WITH_TEMP_SIMD_OP_LIST(V) \ + V(TruncateFloat32ToUint32, kSSEFloat32ToUint32) \ + V(ChangeFloat64ToUint32, kSSEFloat64ToUint32) \ + V(TruncateFloat64ToUint32, kSSEFloat64ToUint32) #define RR_OP_LIST(V) \ V(TruncateFloat64ToWord32, kArchTruncateDoubleToI) \ @@ -841,13 +863,23 @@ void InstructionSelector::VisitWord32Ror(Node* node) { V(Float32Mul, kAVXFloat32Mul, kSSEFloat32Mul) \ V(Float64Mul, kAVXFloat64Mul, kSSEFloat64Mul) \ V(Float32Div, kAVXFloat32Div, kSSEFloat32Div) \ - V(Float64Div, kAVXFloat64Div, kSSEFloat64Div) + V(Float64Div, kAVXFloat64Div, kSSEFloat64Div) \ + V(F64x2Add, kIA32F64x2Add, kIA32F64x2Add) \ + V(F64x2Sub, kIA32F64x2Sub, kIA32F64x2Sub) \ + V(F64x2Mul, kIA32F64x2Mul, kIA32F64x2Mul) \ + V(F64x2Div, kIA32F64x2Div, kIA32F64x2Div) \ + V(F64x2Eq, kIA32F64x2Eq, kIA32F64x2Eq) \ + V(F64x2Ne, kIA32F64x2Ne, kIA32F64x2Ne) \ + V(F64x2Lt, kIA32F64x2Lt, kIA32F64x2Lt) \ + V(F64x2Le, kIA32F64x2Le, kIA32F64x2Le) #define FLOAT_UNOP_LIST(V) \ V(Float32Abs, kAVXFloat32Abs, kSSEFloat32Abs) \ V(Float64Abs, kAVXFloat64Abs, kSSEFloat64Abs) \ V(Float32Neg, kAVXFloat32Neg, kSSEFloat32Neg) \ - V(Float64Neg, kAVXFloat64Neg, kSSEFloat64Neg) + V(Float64Neg, kAVXFloat64Neg, kSSEFloat64Neg) \ + V(F64x2Abs, kAVXFloat64Abs, kSSEFloat64Abs) \ + V(F64x2Neg, kAVXFloat64Neg, kSSEFloat64Neg) #define RO_VISITOR(Name, opcode) \ void InstructionSelector::Visit##Name(Node* node) { \ @@ -857,6 +889,22 @@ RO_OP_LIST(RO_VISITOR) #undef RO_VISITOR #undef RO_OP_LIST +#define RO_WITH_TEMP_VISITOR(Name, opcode) \ + void InstructionSelector::Visit##Name(Node* node) { \ + VisitROWithTemp(this, node, opcode); \ + } +RO_WITH_TEMP_OP_LIST(RO_WITH_TEMP_VISITOR) +#undef RO_WITH_TEMP_VISITOR +#undef RO_WITH_TEMP_OP_LIST + +#define RO_WITH_TEMP_SIMD_VISITOR(Name, opcode) \ + void InstructionSelector::Visit##Name(Node* node) { \ + VisitROWithTempSimd(this, node, opcode); \ + } +RO_WITH_TEMP_SIMD_OP_LIST(RO_WITH_TEMP_SIMD_VISITOR) +#undef RO_WITH_TEMP_SIMD_VISITOR +#undef RO_WITH_TEMP_SIMD_OP_LIST + #define RR_VISITOR(Name, opcode) \ void InstructionSelector::Visit##Name(Node* node) { \ VisitRR(this, node, opcode); \ @@ -890,6 +938,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { Emit(kIA32Bswap, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + void InstructionSelector::VisitInt32Add(Node* node) { IA32OperandGenerator g(this); @@ -1971,6 +2023,7 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) { #define SIMD_UNOP_PREFIX_LIST(V) \ V(F32x4Abs) \ V(F32x4Neg) \ + V(F32x4Sqrt) \ V(S128Not) #define SIMD_ANYTRUE_LIST(V) \ @@ -1995,6 +2048,43 @@ void InstructionSelector::VisitWord32AtomicPairCompareExchange(Node* node) { V(I8x16ShrS) \ V(I8x16ShrU) +void InstructionSelector::VisitF64x2Min(Node* node) { + IA32OperandGenerator g(this); + InstructionOperand temps[] = {g.TempSimd128Register()}; + InstructionOperand operand0 = g.UseUniqueRegister(node->InputAt(0)); + InstructionOperand operand1 = g.UseUnique(node->InputAt(1)); + + if (IsSupported(AVX)) { + Emit(kIA32F64x2Min, g.DefineAsRegister(node), operand0, operand1, + arraysize(temps), temps); + } else { + Emit(kIA32F64x2Min, g.DefineSameAsFirst(node), operand0, operand1, + arraysize(temps), temps); + } +} + +void InstructionSelector::VisitF64x2Max(Node* node) { + IA32OperandGenerator g(this); + InstructionOperand temps[] = {g.TempSimd128Register()}; + InstructionOperand operand0 = g.UseUniqueRegister(node->InputAt(0)); + InstructionOperand operand1 = g.UseUnique(node->InputAt(1)); + if (IsSupported(AVX)) { + Emit(kIA32F64x2Max, g.DefineAsRegister(node), operand0, operand1, + arraysize(temps), temps); + } else { + Emit(kIA32F64x2Max, g.DefineSameAsFirst(node), operand0, operand1, + arraysize(temps), temps); + } +} + +void InstructionSelector::VisitF64x2Splat(Node* node) { + VisitRRSimd(this, node, kAVXF64x2Splat, kSSEF64x2Splat); +} + +void InstructionSelector::VisitF64x2ExtractLane(Node* node) { + VisitRRISimd(this, node, kAVXF64x2ExtractLane, kSSEF64x2ExtractLane); +} + void InstructionSelector::VisitF32x4Splat(Node* node) { VisitRRSimd(this, node, kAVXF32x4Splat, kSSEF32x4Splat); } @@ -2086,6 +2176,28 @@ VISIT_SIMD_REPLACE_LANE(F32x4) #undef VISIT_SIMD_REPLACE_LANE #undef SIMD_INT_TYPES +// The difference between this and VISIT_SIMD_REPLACE_LANE is that this forces +// operand2 to be UseRegister, because the codegen relies on insertps using +// registers. +// TODO(v8:9764) Remove this UseRegister requirement +#define VISIT_SIMD_REPLACE_LANE_USE_REG(Type) \ + void InstructionSelector::Visit##Type##ReplaceLane(Node* node) { \ + IA32OperandGenerator g(this); \ + InstructionOperand operand0 = g.UseRegister(node->InputAt(0)); \ + InstructionOperand operand1 = \ + g.UseImmediate(OpParameter<int32_t>(node->op())); \ + InstructionOperand operand2 = g.UseRegister(node->InputAt(1)); \ + if (IsSupported(AVX)) { \ + Emit(kAVX##Type##ReplaceLane, g.DefineAsRegister(node), operand0, \ + operand1, operand2); \ + } else { \ + Emit(kSSE##Type##ReplaceLane, g.DefineSameAsFirst(node), operand0, \ + operand1, operand2); \ + } \ + } +VISIT_SIMD_REPLACE_LANE_USE_REG(F64x2) +#undef VISIT_SIMD_REPLACE_LANE_USE_REG + #define VISIT_SIMD_SHIFT(Opcode) \ void InstructionSelector::Visit##Opcode(Node* node) { \ VisitRROSimdShift(this, node, kAVX##Opcode, kSSE##Opcode); \ @@ -2132,12 +2244,12 @@ SIMD_ANYTRUE_LIST(VISIT_SIMD_ANYTRUE) #undef VISIT_SIMD_ANYTRUE #undef SIMD_ANYTRUE_LIST -#define VISIT_SIMD_ALLTRUE(Opcode) \ - void InstructionSelector::Visit##Opcode(Node* node) { \ - IA32OperandGenerator g(this); \ - InstructionOperand temps[] = {g.TempRegister()}; \ - Emit(kIA32##Opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)), \ - arraysize(temps), temps); \ +#define VISIT_SIMD_ALLTRUE(Opcode) \ + void InstructionSelector::Visit##Opcode(Node* node) { \ + IA32OperandGenerator g(this); \ + InstructionOperand temps[] = {g.TempRegister(), g.TempSimd128Register()}; \ + Emit(kIA32##Opcode, g.DefineAsRegister(node), \ + g.UseUnique(node->InputAt(0)), arraysize(temps), temps); \ } SIMD_ALLTRUE_LIST(VISIT_SIMD_ALLTRUE) #undef VISIT_SIMD_ALLTRUE @@ -2489,6 +2601,14 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) { Emit(opcode, 1, &dst, input_count, inputs, temp_count, temps); } +void InstructionSelector::VisitS8x16Swizzle(Node* node) { + IA32OperandGenerator g(this); + InstructionOperand temps[] = {g.TempSimd128Register()}; + Emit(kIA32S8x16Swizzle, g.DefineSameAsFirst(node), + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), + arraysize(temps), temps); +} + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { diff --git a/deps/v8/src/compiler/backend/instruction-scheduler.cc b/deps/v8/src/compiler/backend/instruction-scheduler.cc index dc66813740b3ee..d4920cd575ac1e 100644 --- a/deps/v8/src/compiler/backend/instruction-scheduler.cc +++ b/deps/v8/src/compiler/backend/instruction-scheduler.cc @@ -4,7 +4,7 @@ #include "src/compiler/backend/instruction-scheduler.h" -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/base/utils/random-number-generator.h" #include "src/execution/isolate.h" diff --git a/deps/v8/src/compiler/backend/instruction-selector-impl.h b/deps/v8/src/compiler/backend/instruction-selector-impl.h index a3f62e7ba40c45..13ea049eba401f 100644 --- a/deps/v8/src/compiler/backend/instruction-selector-impl.h +++ b/deps/v8/src/compiler/backend/instruction-selector-impl.h @@ -29,8 +29,8 @@ inline bool operator<(const CaseInfo& l, const CaseInfo& r) { // Helper struct containing data about a table or lookup switch. class SwitchInfo { public: - SwitchInfo(ZoneVector<CaseInfo>& cases, // NOLINT(runtime/references) - int32_t min_value, int32_t max_value, BasicBlock* default_branch) + SwitchInfo(ZoneVector<CaseInfo> const& cases, int32_t min_value, + int32_t max_value, BasicBlock* default_branch) : cases_(cases), min_value_(min_value), max_value_(max_value), @@ -193,17 +193,6 @@ class OperandGenerator { reg.code(), GetVReg(node))); } - InstructionOperand UseExplicit(LinkageLocation location) { - MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); - if (location.IsRegister()) { - return ExplicitOperand(LocationOperand::REGISTER, rep, - location.AsRegister()); - } else { - return ExplicitOperand(LocationOperand::STACK_SLOT, rep, - location.GetLocation()); - } - } - InstructionOperand UseImmediate(int immediate) { return sequence()->AddImmediate(Constant(immediate)); } @@ -275,6 +264,16 @@ class OperandGenerator { InstructionOperand::kInvalidVirtualRegister); } + template <typename FPRegType> + InstructionOperand TempFpRegister(FPRegType reg) { + UnallocatedOperand op = + UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, reg.code(), + sequence()->NextVirtualRegister()); + sequence()->MarkAsRepresentation(MachineRepresentation::kSimd128, + op.virtual_register()); + return op; + } + InstructionOperand TempImmediate(int32_t imm) { return sequence()->AddImmediate(Constant(imm)); } diff --git a/deps/v8/src/compiler/backend/instruction-selector.cc b/deps/v8/src/compiler/backend/instruction-selector.cc index 43193ec2b110e9..e165c6c6a9e93a 100644 --- a/deps/v8/src/compiler/backend/instruction-selector.cc +++ b/deps/v8/src/compiler/backend/instruction-selector.cc @@ -6,7 +6,7 @@ #include <limits> -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/tick-counter.h" #include "src/compiler/backend/instruction-selector-impl.h" @@ -1439,6 +1439,8 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsWord64(node), VisitWord64ReverseBits(node); case IrOpcode::kWord64ReverseBytes: return MarkAsWord64(node), VisitWord64ReverseBytes(node); + case IrOpcode::kSimd128ReverseBytes: + return MarkAsSimd128(node), VisitSimd128ReverseBytes(node); case IrOpcode::kInt64AbsWithOverflow: return MarkAsWord64(node), VisitInt64AbsWithOverflow(node); case IrOpcode::kWord64Equal: @@ -1502,7 +1504,7 @@ void InstructionSelector::VisitNode(Node* node) { case IrOpcode::kUint64Mod: return MarkAsWord64(node), VisitUint64Mod(node); case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastTaggedSignedToWord: + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: return MarkAsRepresentation(MachineType::PointerRepresentation(), node), VisitBitcastTaggedToWord(node); case IrOpcode::kBitcastWordToTagged: @@ -1857,6 +1859,8 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsSimd128(node), VisitF64x2Abs(node); case IrOpcode::kF64x2Neg: return MarkAsSimd128(node), VisitF64x2Neg(node); + case IrOpcode::kF64x2Sqrt: + return MarkAsSimd128(node), VisitF64x2Sqrt(node); case IrOpcode::kF64x2Add: return MarkAsSimd128(node), VisitF64x2Add(node); case IrOpcode::kF64x2Sub: @@ -1877,6 +1881,10 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsSimd128(node), VisitF64x2Lt(node); case IrOpcode::kF64x2Le: return MarkAsSimd128(node), VisitF64x2Le(node); + case IrOpcode::kF64x2Qfma: + return MarkAsSimd128(node), VisitF64x2Qfma(node); + case IrOpcode::kF64x2Qfms: + return MarkAsSimd128(node), VisitF64x2Qfms(node); case IrOpcode::kF32x4Splat: return MarkAsSimd128(node), VisitF32x4Splat(node); case IrOpcode::kF32x4ExtractLane: @@ -1891,6 +1899,8 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsSimd128(node), VisitF32x4Abs(node); case IrOpcode::kF32x4Neg: return MarkAsSimd128(node), VisitF32x4Neg(node); + case IrOpcode::kF32x4Sqrt: + return MarkAsSimd128(node), VisitF32x4Sqrt(node); case IrOpcode::kF32x4RecipApprox: return MarkAsSimd128(node), VisitF32x4RecipApprox(node); case IrOpcode::kF32x4RecipSqrtApprox: @@ -1917,6 +1927,10 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsSimd128(node), VisitF32x4Lt(node); case IrOpcode::kF32x4Le: return MarkAsSimd128(node), VisitF32x4Le(node); + case IrOpcode::kF32x4Qfma: + return MarkAsSimd128(node), VisitF32x4Qfma(node); + case IrOpcode::kF32x4Qfms: + return MarkAsSimd128(node), VisitF32x4Qfms(node); case IrOpcode::kI64x2Splat: return MarkAsSimd128(node), VisitI64x2Splat(node); case IrOpcode::kI64x2ExtractLane: @@ -2137,6 +2151,8 @@ void InstructionSelector::VisitNode(Node* node) { return MarkAsSimd128(node), VisitS128Not(node); case IrOpcode::kS128Select: return MarkAsSimd128(node), VisitS128Select(node); + case IrOpcode::kS8x16Swizzle: + return MarkAsSimd128(node), VisitS8x16Swizzle(node); case IrOpcode::kS8x16Shuffle: return MarkAsSimd128(node), VisitS8x16Shuffle(node); case IrOpcode::kS1x2AnyTrue: @@ -2286,8 +2302,8 @@ void InstructionSelector::VisitFloat64Tanh(Node* node) { VisitFloat64Ieee754Unop(node, kIeee754Float64Tanh); } -void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw, - InstructionOperand& index_operand) { +void InstructionSelector::EmitTableSwitch( + const SwitchInfo& sw, InstructionOperand const& index_operand) { OperandGenerator g(this); size_t input_count = 2 + sw.value_range(); DCHECK_LE(sw.value_range(), std::numeric_limits<size_t>::max() - 2); @@ -2304,8 +2320,8 @@ void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw, Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr); } -void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw, - InstructionOperand& value_operand) { +void InstructionSelector::EmitLookupSwitch( + const SwitchInfo& sw, InstructionOperand const& value_operand) { OperandGenerator g(this); std::vector<CaseInfo> cases = sw.CasesSortedByOriginalOrder(); size_t input_count = 2 + sw.case_count() * 2; @@ -2322,7 +2338,7 @@ void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw, } void InstructionSelector::EmitBinarySearchSwitch( - const SwitchInfo& sw, InstructionOperand& value_operand) { + const SwitchInfo& sw, InstructionOperand const& value_operand) { OperandGenerator g(this); size_t input_count = 2 + sw.case_count() * 2; DCHECK_LE(sw.case_count(), (std::numeric_limits<size_t>::max() - 2) / 2); @@ -2607,21 +2623,25 @@ void InstructionSelector::VisitWord64AtomicCompareExchange(Node* node) { #if !V8_TARGET_ARCH_X64 #if !V8_TARGET_ARCH_ARM64 +#if !V8_TARGET_ARCH_IA32 void InstructionSelector::VisitF64x2Splat(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2ExtractLane(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Abs(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Neg(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF64x2Sqrt(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitS8x16Swizzle(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Add(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Sub(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Mul(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Div(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitF64x2Min(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitF64x2Max(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Eq(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Ne(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Lt(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF64x2Le(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF64x2Min(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF64x2Max(Node* node) { UNIMPLEMENTED(); } +#endif // !V8_TARGET_ARCH_IA32 void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); } @@ -2630,6 +2650,7 @@ void InstructionSelector::VisitI64x2Shl(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2ShrS(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2Add(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2Sub(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitI64x2Mul(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2Eq(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2Ne(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2ShrU(Node* node) { UNIMPLEMENTED(); } @@ -2639,8 +2660,11 @@ void InstructionSelector::VisitI64x2GtU(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2GeU(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS1x2AnyTrue(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS1x2AllTrue(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF64x2Qfma(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF64x2Qfms(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF32x4Qfma(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF32x4Qfms(Node* node) { UNIMPLEMENTED(); } #endif // !V8_TARGET_ARCH_ARM64 -void InstructionSelector::VisitI64x2Mul(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2MinS(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2MaxS(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitI64x2MinU(Node* node) { UNIMPLEMENTED(); } @@ -2786,10 +2810,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { // Select the appropriate opcode based on the call type. InstructionCode opcode = kArchNop; switch (call_descriptor->kind()) { - case CallDescriptor::kCallAddress: - opcode = kArchCallCFunction | MiscField::encode(static_cast<int>( - call_descriptor->ParameterCount())); + case CallDescriptor::kCallAddress: { + int misc_field = static_cast<int>(call_descriptor->ParameterCount()); +#if defined(_AIX) + // Highest misc_field bit is used on AIX to indicate if a CFunction call + // has function descriptor or not. + misc_field |= call_descriptor->HasFunctionDescriptor() + << kHasFunctionDescriptorBitShift; +#endif + opcode = kArchCallCFunction | MiscField::encode(misc_field); break; + } case CallDescriptor::kCallCodeObject: opcode = kArchCallCodeObject | MiscField::encode(flags); break; diff --git a/deps/v8/src/compiler/backend/instruction-selector.h b/deps/v8/src/compiler/backend/instruction-selector.h index eb3e0984272a30..e951c90f953f04 100644 --- a/deps/v8/src/compiler/backend/instruction-selector.h +++ b/deps/v8/src/compiler/backend/instruction-selector.h @@ -502,15 +502,12 @@ class V8_EXPORT_PRIVATE InstructionSelector final { FeedbackSource const& feedback, Node* frame_state); - void EmitTableSwitch( - const SwitchInfo& sw, - InstructionOperand& index_operand); // NOLINT(runtime/references) - void EmitLookupSwitch( - const SwitchInfo& sw, - InstructionOperand& value_operand); // NOLINT(runtime/references) - void EmitBinarySearchSwitch( - const SwitchInfo& sw, - InstructionOperand& value_operand); // NOLINT(runtime/references) + void EmitTableSwitch(const SwitchInfo& sw, + InstructionOperand const& index_operand); + void EmitLookupSwitch(const SwitchInfo& sw, + InstructionOperand const& value_operand); + void EmitBinarySearchSwitch(const SwitchInfo& sw, + InstructionOperand const& value_operand); void TryRename(InstructionOperand* op); int GetRename(int virtual_register); diff --git a/deps/v8/src/compiler/backend/instruction.cc b/deps/v8/src/compiler/backend/instruction.cc index 06158b0c72e851..076f1b596e2859 100644 --- a/deps/v8/src/compiler/backend/instruction.cc +++ b/deps/v8/src/compiler/backend/instruction.cc @@ -168,7 +168,6 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { return os << "[immediate:" << imm.indexed_value() << "]"; } } - case InstructionOperand::EXPLICIT: case InstructionOperand::ALLOCATED: { LocationOperand allocated = LocationOperand::cast(op); if (op.IsStackSlot()) { @@ -192,9 +191,6 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) { os << "[" << Simd128Register::from_code(allocated.register_code()) << "|R"; } - if (allocated.IsExplicit()) { - os << "|E"; - } switch (allocated.representation()) { case MachineRepresentation::kNone: os << "|-"; @@ -294,17 +290,6 @@ void ParallelMove::PrepareInsertAfter( if (replacement != nullptr) move->set_source(replacement->source()); } -ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep, - int index) - : LocationOperand(EXPLICIT, kind, rep, index) { - DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep), - GetRegConfig()->IsAllocatableGeneralCode(index)); - DCHECK_IMPLIES(kind == REGISTER && rep == MachineRepresentation::kFloat32, - GetRegConfig()->IsAllocatableFloatCode(index)); - DCHECK_IMPLIES(kind == REGISTER && (rep == MachineRepresentation::kFloat64), - GetRegConfig()->IsAllocatableDoubleCode(index)); -} - Instruction::Instruction(InstructionCode opcode) : opcode_(opcode), bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | diff --git a/deps/v8/src/compiler/backend/instruction.h b/deps/v8/src/compiler/backend/instruction.h index f5f7f64c51e50d..462b0daf6b9c72 100644 --- a/deps/v8/src/compiler/backend/instruction.h +++ b/deps/v8/src/compiler/backend/instruction.h @@ -43,9 +43,8 @@ class V8_EXPORT_PRIVATE InstructionOperand { CONSTANT, IMMEDIATE, // Location operand kinds. - EXPLICIT, ALLOCATED, - FIRST_LOCATION_OPERAND_KIND = EXPLICIT + FIRST_LOCATION_OPERAND_KIND = ALLOCATED // Location operand kinds must be last. }; @@ -68,11 +67,6 @@ class V8_EXPORT_PRIVATE InstructionOperand { // embedded directly in instructions, e.g. small integers and on some // platforms Objects. INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) - // ExplicitOperands do not participate in register allocation. They are - // created by the instruction selector for direct access to registers and - // stack slots, completely bypassing the register allocator. They are never - // associated with a virtual register - INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT) // AllocatedOperands are registers or stack slots that are assigned by the // register allocator and are always associated with a virtual register. INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) @@ -515,19 +509,6 @@ class LocationOperand : public InstructionOperand { using IndexField = BitField64<int32_t, 35, 29>; }; -class V8_EXPORT_PRIVATE ExplicitOperand - : public NON_EXPORTED_BASE(LocationOperand) { - public: - ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index); - - static ExplicitOperand* New(Zone* zone, LocationKind kind, - MachineRepresentation rep, int index) { - return InstructionOperand::New(zone, ExplicitOperand(kind, rep, index)); - } - - INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT) -}; - class AllocatedOperand : public LocationOperand { public: AllocatedOperand(LocationKind kind, MachineRepresentation rep, int index) @@ -643,7 +624,7 @@ uint64_t InstructionOperand::GetCanonicalizedValue() const { } return InstructionOperand::KindField::update( LocationOperand::RepresentationField::update(this->value_, canonical), - LocationOperand::EXPLICIT); + LocationOperand::ALLOCATED); } return this->value_; } @@ -776,11 +757,11 @@ class V8_EXPORT_PRIVATE Instruction final { public: size_t OutputCount() const { return OutputCountField::decode(bit_field_); } const InstructionOperand* OutputAt(size_t i) const { - DCHECK(i < OutputCount()); + DCHECK_LT(i, OutputCount()); return &operands_[i]; } InstructionOperand* OutputAt(size_t i) { - DCHECK(i < OutputCount()); + DCHECK_LT(i, OutputCount()); return &operands_[i]; } @@ -790,21 +771,21 @@ class V8_EXPORT_PRIVATE Instruction final { size_t InputCount() const { return InputCountField::decode(bit_field_); } const InstructionOperand* InputAt(size_t i) const { - DCHECK(i < InputCount()); + DCHECK_LT(i, InputCount()); return &operands_[OutputCount() + i]; } InstructionOperand* InputAt(size_t i) { - DCHECK(i < InputCount()); + DCHECK_LT(i, InputCount()); return &operands_[OutputCount() + i]; } size_t TempCount() const { return TempCountField::decode(bit_field_); } const InstructionOperand* TempAt(size_t i) const { - DCHECK(i < TempCount()); + DCHECK_LT(i, TempCount()); return &operands_[OutputCount() + InputCount() + i]; } InstructionOperand* TempAt(size_t i) { - DCHECK(i < TempCount()); + DCHECK_LT(i, TempCount()); return &operands_[OutputCount() + InputCount() + i]; } @@ -826,7 +807,8 @@ class V8_EXPORT_PRIVATE Instruction final { size_t output_count, InstructionOperand* outputs, size_t input_count, InstructionOperand* inputs, size_t temp_count, InstructionOperand* temps) { - DCHECK_LE(0, opcode); + // TODO(9872) + // DCHECK_LE(0, opcode); DCHECK(output_count == 0 || outputs != nullptr); DCHECK(input_count == 0 || inputs != nullptr); DCHECK(temp_count == 0 || temps != nullptr); diff --git a/deps/v8/src/compiler/backend/jump-threading.cc b/deps/v8/src/compiler/backend/jump-threading.cc index dfb917a58c444b..ee195bf51e16df 100644 --- a/deps/v8/src/compiler/backend/jump-threading.cc +++ b/deps/v8/src/compiler/backend/jump-threading.cc @@ -69,11 +69,11 @@ bool IsBlockWithBranchPoisoning(InstructionSequence* code, } // namespace bool JumpThreading::ComputeForwarding(Zone* local_zone, - ZoneVector<RpoNumber>& result, + ZoneVector<RpoNumber>* result, InstructionSequence* code, bool frame_at_start) { ZoneStack<RpoNumber> stack(local_zone); - JumpThreadingState state = {false, result, stack}; + JumpThreadingState state = {false, *result, stack}; state.Clear(code->InstructionBlockCount()); // Iterate over the blocks forward, pushing the blocks onto the stack. @@ -135,15 +135,15 @@ bool JumpThreading::ComputeForwarding(Zone* local_zone, } #ifdef DEBUG - for (RpoNumber num : result) { + for (RpoNumber num : *result) { DCHECK(num.IsValid()); } #endif if (FLAG_trace_turbo_jt) { - for (int i = 0; i < static_cast<int>(result.size()); i++) { + for (int i = 0; i < static_cast<int>(result->size()); i++) { TRACE("B%d ", i); - int to = result[i].ToInt(); + int to = (*result)[i].ToInt(); if (i != to) { TRACE("-> B%d\n", to); } else { @@ -156,7 +156,7 @@ bool JumpThreading::ComputeForwarding(Zone* local_zone, } void JumpThreading::ApplyForwarding(Zone* local_zone, - ZoneVector<RpoNumber>& result, + ZoneVector<RpoNumber> const& result, InstructionSequence* code) { if (!FLAG_turbo_jt) return; diff --git a/deps/v8/src/compiler/backend/jump-threading.h b/deps/v8/src/compiler/backend/jump-threading.h index ce60ebcb2e3423..ce9e3949249e74 100644 --- a/deps/v8/src/compiler/backend/jump-threading.h +++ b/deps/v8/src/compiler/backend/jump-threading.h @@ -17,17 +17,14 @@ class V8_EXPORT_PRIVATE JumpThreading { public: // Compute the forwarding map of basic blocks to their ultimate destination. // Returns {true} if there is at least one block that is forwarded. - static bool ComputeForwarding( - Zone* local_zone, - ZoneVector<RpoNumber>& result, // NOLINT(runtime/references) - InstructionSequence* code, bool frame_at_start); + static bool ComputeForwarding(Zone* local_zone, ZoneVector<RpoNumber>* result, + InstructionSequence* code, bool frame_at_start); // Rewrite the instructions to forward jumps and branches. // May also negate some branches. - static void ApplyForwarding( - Zone* local_zone, - ZoneVector<RpoNumber>& forwarding, // NOLINT(runtime/references) - InstructionSequence* code); + static void ApplyForwarding(Zone* local_zone, + ZoneVector<RpoNumber> const& forwarding, + InstructionSequence* code); }; } // namespace compiler diff --git a/deps/v8/src/compiler/backend/mips/code-generator-mips.cc b/deps/v8/src/compiler/backend/mips/code-generator-mips.cc index 239075392afb81..ee23402e69bf38 100644 --- a/deps/v8/src/compiler/backend/mips/code-generator-mips.cc +++ b/deps/v8/src/compiler/backend/mips/code-generator-mips.cc @@ -265,34 +265,33 @@ Condition FlagsConditionToConditionTst(FlagsCondition condition) { UNREACHABLE(); } -FPUCondition FlagsConditionToConditionCmpFPU( - bool& predicate, // NOLINT(runtime/references) - FlagsCondition condition) { +FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate, + FlagsCondition condition) { switch (condition) { case kEqual: - predicate = true; + *predicate = true; return EQ; case kNotEqual: - predicate = false; + *predicate = false; return EQ; case kUnsignedLessThan: - predicate = true; + *predicate = true; return OLT; case kUnsignedGreaterThanOrEqual: - predicate = false; + *predicate = false; return OLT; case kUnsignedLessThanOrEqual: - predicate = true; + *predicate = true; return OLE; case kUnsignedGreaterThan: - predicate = false; + *predicate = false; return OLE; case kUnorderedEqual: case kUnorderedNotEqual: - predicate = true; + *predicate = true; break; default: - predicate = true; + *predicate = true; break; } UNREACHABLE(); @@ -303,9 +302,9 @@ FPUCondition FlagsConditionToConditionCmpFPU( << "\""; \ UNIMPLEMENTED(); -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, InstructionCode opcode, Instruction* instr, - MipsOperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, + InstructionCode opcode, Instruction* instr, + MipsOperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); if (access_mode == kMemoryAccessPoisoned) { @@ -780,12 +779,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; case kArchCallCFunction: { int const num_parameters = MiscField::decode(instr->opcode()); - Label return_location; - if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) { + Label start_call; + bool isWasmCapiFunction = + linkage()->GetIncomingDescriptor()->IsWasmCapiFunction(); + // from start_call to return address. + int offset = 40; +#if V8_HOST_ARCH_MIPS + if (__ emit_debug_code()) { + offset += 16; + } +#endif + if (isWasmCapiFunction) { // Put the return address in a stack slot. - __ LoadAddress(kScratchReg, &return_location); - __ sw(kScratchReg, - MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); + __ mov(kScratchReg, ra); + __ bind(&start_call); + __ nal(); + __ nop(); + __ Addu(ra, ra, offset - 8); // 8 = nop + nal + __ sw(ra, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); + __ mov(ra, kScratchReg); } if (instr->InputAt(0)->IsImmediate()) { ExternalReference ref = i.InputExternalReference(0); @@ -794,7 +806,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( Register func = i.InputRegister(0); __ CallCFunction(func, num_parameters); } - __ bind(&return_location); + if (isWasmCapiFunction) { + CHECK_EQ(offset, __ SizeOfCodeGeneratedSince(&start_call)); + } + RecordSafepoint(instr->reference_map(), Safepoint::kNoLazyDeopt); frame_access_state()->SetFrameAccessToDefault(); // Ideally, we should decrement SP delta to match the change of stack @@ -1179,7 +1194,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( FPURegister right = i.InputOrZeroSingleRegister(1); bool predicate; FPUCondition cc = - FlagsConditionToConditionCmpFPU(predicate, instr->flags_condition()); + FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition()); if ((left == kDoubleRegZero || right == kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { @@ -1239,7 +1254,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( FPURegister right = i.InputOrZeroDoubleRegister(1); bool predicate; FPUCondition cc = - FlagsConditionToConditionCmpFPU(predicate, instr->flags_condition()); + FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition()); if ((left == kDoubleRegZero || right == kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { __ Move(kDoubleRegZero, 0.0); @@ -2038,6 +2053,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ bnegi_w(i.OutputSimd128Register(), i.InputSimd128Register(0), 31); break; } + case kMipsF32x4Sqrt: { + CpuFeatureScope msa_scope(tasm(), MIPS_SIMD); + __ fsqrt_w(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } case kMipsF32x4RecipApprox: { CpuFeatureScope msa_scope(tasm(), MIPS_SIMD); __ frcp_w(i.OutputSimd128Register(), i.InputSimd128Register(0)); @@ -3026,7 +3046,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm, } else if (instr->arch_opcode() == kMipsCmpS || instr->arch_opcode() == kMipsCmpD) { bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (predicate) { __ BranchTrueF(tlabel); } else { @@ -3116,7 +3136,7 @@ void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition, case kMipsCmpS: case kMipsCmpD: { bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (predicate) { __ LoadZeroIfFPUCondition(kSpeculationPoisonRegister); } else { @@ -3314,7 +3334,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, __ Move(kDoubleRegZero, 0.0); } bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (!IsMipsArchVariant(kMips32r6)) { __ li(result, Operand(1)); if (predicate) { diff --git a/deps/v8/src/compiler/backend/mips/instruction-codes-mips.h b/deps/v8/src/compiler/backend/mips/instruction-codes-mips.h index e8020d9e895661..af0774f4688441 100644 --- a/deps/v8/src/compiler/backend/mips/instruction-codes-mips.h +++ b/deps/v8/src/compiler/backend/mips/instruction-codes-mips.h @@ -159,6 +159,7 @@ namespace compiler { V(MipsI32x4MinU) \ V(MipsF32x4Abs) \ V(MipsF32x4Neg) \ + V(MipsF32x4Sqrt) \ V(MipsF32x4RecipApprox) \ V(MipsF32x4RecipSqrtApprox) \ V(MipsF32x4Add) \ diff --git a/deps/v8/src/compiler/backend/mips/instruction-scheduler-mips.cc b/deps/v8/src/compiler/backend/mips/instruction-scheduler-mips.cc index 4e6aef52f49f70..ba17ad25819cab 100644 --- a/deps/v8/src/compiler/backend/mips/instruction-scheduler-mips.cc +++ b/deps/v8/src/compiler/backend/mips/instruction-scheduler-mips.cc @@ -54,6 +54,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kMipsF32x4Div: case kMipsF32x4Ne: case kMipsF32x4Neg: + case kMipsF32x4Sqrt: case kMipsF32x4RecipApprox: case kMipsF32x4RecipSqrtApprox: case kMipsF32x4ReplaceLane: diff --git a/deps/v8/src/compiler/backend/mips/instruction-selector-mips.cc b/deps/v8/src/compiler/backend/mips/instruction-selector-mips.cc index bb47262c6c32db..7ee5c7c2c77d04 100644 --- a/deps/v8/src/compiler/backend/mips/instruction-selector-mips.cc +++ b/deps/v8/src/compiler/backend/mips/instruction-selector-mips.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" #include "src/base/bits.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" @@ -781,6 +780,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + void InstructionSelector::VisitWord32Ctz(Node* node) { MipsOperandGenerator g(this); Emit(kMipsCtz, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); @@ -2015,6 +2018,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { V(F32x4UConvertI32x4, kMipsF32x4UConvertI32x4) \ V(F32x4Abs, kMipsF32x4Abs) \ V(F32x4Neg, kMipsF32x4Neg) \ + V(F32x4Sqrt, kMipsF32x4Sqrt) \ V(F32x4RecipApprox, kMipsF32x4RecipApprox) \ V(F32x4RecipSqrtApprox, kMipsF32x4RecipSqrtApprox) \ V(I32x4SConvertF32x4, kMipsI32x4SConvertF32x4) \ diff --git a/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc b/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc index 5682bed71a42cf..9cec463e875b1f 100644 --- a/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc +++ b/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc @@ -278,42 +278,41 @@ Condition FlagsConditionToConditionOvf(FlagsCondition condition) { UNREACHABLE(); } -FPUCondition FlagsConditionToConditionCmpFPU( - bool& predicate, // NOLINT(runtime/references) - FlagsCondition condition) { +FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate, + FlagsCondition condition) { switch (condition) { case kEqual: - predicate = true; + *predicate = true; return EQ; case kNotEqual: - predicate = false; + *predicate = false; return EQ; case kUnsignedLessThan: - predicate = true; + *predicate = true; return OLT; case kUnsignedGreaterThanOrEqual: - predicate = false; + *predicate = false; return OLT; case kUnsignedLessThanOrEqual: - predicate = true; + *predicate = true; return OLE; case kUnsignedGreaterThan: - predicate = false; + *predicate = false; return OLE; case kUnorderedEqual: case kUnorderedNotEqual: - predicate = true; + *predicate = true; break; default: - predicate = true; + *predicate = true; break; } UNREACHABLE(); } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, InstructionCode opcode, Instruction* instr, - MipsOperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, + InstructionCode opcode, Instruction* instr, + MipsOperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); if (access_mode == kMemoryAccessPoisoned) { @@ -758,12 +757,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; case kArchCallCFunction: { int const num_parameters = MiscField::decode(instr->opcode()); - Label return_location; - if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) { + Label start_call; + bool isWasmCapiFunction = + linkage()->GetIncomingDescriptor()->IsWasmCapiFunction(); + // from start_call to return address. + int offset = 48; +#if V8_HOST_ARCH_MIPS64 + if (__ emit_debug_code()) { + offset += 16; + } +#endif + if (isWasmCapiFunction) { // Put the return address in a stack slot. - __ LoadAddress(kScratchReg, &return_location); - __ sd(kScratchReg, - MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); + __ mov(kScratchReg, ra); + __ bind(&start_call); + __ nal(); + __ nop(); + __ Daddu(ra, ra, offset - 8); // 8 = nop + nal + __ sd(ra, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); + __ mov(ra, kScratchReg); } if (instr->InputAt(0)->IsImmediate()) { ExternalReference ref = i.InputExternalReference(0); @@ -772,7 +784,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( Register func = i.InputRegister(0); __ CallCFunction(func, num_parameters); } - __ bind(&return_location); + if (isWasmCapiFunction) { + CHECK_EQ(offset, __ SizeOfCodeGeneratedSince(&start_call)); + } + RecordSafepoint(instr->reference_map(), Safepoint::kNoLazyDeopt); frame_access_state()->SetFrameAccessToDefault(); // Ideally, we should decrement SP delta to match the change of stack @@ -1276,7 +1291,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( FPURegister right = i.InputOrZeroSingleRegister(1); bool predicate; FPUCondition cc = - FlagsConditionToConditionCmpFPU(predicate, instr->flags_condition()); + FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition()); if ((left == kDoubleRegZero || right == kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { @@ -1339,7 +1354,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( FPURegister right = i.InputOrZeroDoubleRegister(1); bool predicate; FPUCondition cc = - FlagsConditionToConditionCmpFPU(predicate, instr->flags_condition()); + FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition()); if ((left == kDoubleRegZero || right == kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { __ Move(kDoubleRegZero, 0.0); @@ -2233,6 +2248,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ ftrunc_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0)); break; } + case kMips64F32x4Sqrt: { + CpuFeatureScope msa_scope(tasm(), MIPS_SIMD); + __ fsqrt_w(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } case kMips64I32x4Neg: { CpuFeatureScope msa_scope(tasm(), MIPS_SIMD); __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero); @@ -3151,7 +3171,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm, } else if (instr->arch_opcode() == kMips64CmpS || instr->arch_opcode() == kMips64CmpD) { bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (predicate) { __ BranchTrueF(tlabel); } else { @@ -3261,7 +3281,7 @@ void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition, case kMips64CmpS: case kMips64CmpD: { bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (predicate) { __ LoadZeroIfFPUCondition(kSpeculationPoisonRegister); } else { @@ -3470,7 +3490,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, __ Move(kDoubleRegZero, 0.0); } bool predicate; - FlagsConditionToConditionCmpFPU(predicate, condition); + FlagsConditionToConditionCmpFPU(&predicate, condition); if (kArchVariant != kMips64r6) { __ li(result, Operand(1)); if (predicate) { diff --git a/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h b/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h index edc8924757d11d..bcf3532b5725f3 100644 --- a/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h +++ b/deps/v8/src/compiler/backend/mips64/instruction-codes-mips64.h @@ -189,6 +189,7 @@ namespace compiler { V(Mips64I32x4MinU) \ V(Mips64F32x4Abs) \ V(Mips64F32x4Neg) \ + V(Mips64F32x4Sqrt) \ V(Mips64F32x4RecipApprox) \ V(Mips64F32x4RecipSqrtApprox) \ V(Mips64F32x4Add) \ diff --git a/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc b/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc index 880b424c416e8b..fe2d33d1db5865 100644 --- a/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc +++ b/deps/v8/src/compiler/backend/mips64/instruction-scheduler-mips64.cc @@ -82,6 +82,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kMips64F32x4Div: case kMips64F32x4Ne: case kMips64F32x4Neg: + case kMips64F32x4Sqrt: case kMips64F32x4RecipApprox: case kMips64F32x4RecipSqrtApprox: case kMips64F32x4ReplaceLane: diff --git a/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc b/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc index 9c717ab1e91aa9..dfc0ff5badf17b 100644 --- a/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc +++ b/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" #include "src/base/bits.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" @@ -823,6 +822,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + void InstructionSelector::VisitWord32Ctz(Node* node) { Mips64OperandGenerator g(this); Emit(kMips64Ctz, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0))); @@ -2678,6 +2681,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) { V(F32x4UConvertI32x4, kMips64F32x4UConvertI32x4) \ V(F32x4Abs, kMips64F32x4Abs) \ V(F32x4Neg, kMips64F32x4Neg) \ + V(F32x4Sqrt, kMips64F32x4Sqrt) \ V(F32x4RecipApprox, kMips64F32x4RecipApprox) \ V(F32x4RecipSqrtApprox, kMips64F32x4RecipSqrtApprox) \ V(I32x4SConvertF32x4, kMips64I32x4SConvertF32x4) \ diff --git a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc index 5c69bc34a12ee0..964f88881678da 100644 --- a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc +++ b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc @@ -263,9 +263,8 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) { UNREACHABLE(); } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, Instruction* instr, - PPCOperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr, + PPCOperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(instr->opcode())); if (access_mode == kMemoryAccessPoisoned) { @@ -1020,11 +1019,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( #endif break; case kArchCallCFunction: { - int const num_parameters = MiscField::decode(instr->opcode()); + int misc_field = MiscField::decode(instr->opcode()); + int num_parameters = misc_field; + bool has_function_descriptor = false; Label start_call; bool isWasmCapiFunction = linkage()->GetIncomingDescriptor()->IsWasmCapiFunction(); +#if defined(_AIX) + // AIX/PPC64BE Linux uses a function descriptor + int kNumParametersMask = kHasFunctionDescriptorBitMask - 1; + num_parameters = kNumParametersMask & misc_field; + has_function_descriptor = + (misc_field & kHasFunctionDescriptorBitMask) != 0; + // AIX emits 2 extra Load instructions under CallCFunctionHelper + // due to having function descriptor. + constexpr int offset = 11 * kInstrSize; +#else constexpr int offset = 9 * kInstrSize; +#endif if (isWasmCapiFunction) { __ mflr(r0); __ bind(&start_call); @@ -1036,16 +1048,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } if (instr->InputAt(0)->IsImmediate()) { ExternalReference ref = i.InputExternalReference(0); - __ CallCFunction(ref, num_parameters); + __ CallCFunction(ref, num_parameters, has_function_descriptor); } else { Register func = i.InputRegister(0); - __ CallCFunction(func, num_parameters); + __ CallCFunction(func, num_parameters, has_function_descriptor); } // TODO(miladfar): In the above block, kScratchReg must be populated with // the strictly-correct PC, which is the return address at this spot. The - // offset is set to 36 (9 * kInstrSize) right now, which is counted from - // where we are binding to the label and ends at this spot. If failed, - // replace it with the correct offset suggested. More info on f5ab7d3. + // offset is set to 36 (9 * kInstrSize) on pLinux and 44 on AIX, which is + // counted from where we are binding to the label and ends at this spot. + // If failed, replace it with the correct offset suggested. More info on + // f5ab7d3. if (isWasmCapiFunction) CHECK_EQ(offset, __ SizeOfCodeGeneratedSince(&start_call)); diff --git a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc index ef8490a7265398..2ffd6495d72e1d 100644 --- a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc +++ b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties.h" @@ -926,6 +926,12 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + // TODO(miladfar): Implement the ppc selector for reversing SIMD bytes. + // Check if the input node is a Load and do a Load Reverse at once. + UNIMPLEMENTED(); +} + void InstructionSelector::VisitInt32Add(Node* node) { VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add32, kInt16Imm); } @@ -2283,6 +2289,8 @@ void InstructionSelector::VisitF32x4Sub(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Mul(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF32x4Sqrt(Node* node) { UNIMPLEMENTED(); } + void InstructionSelector::VisitF32x4Div(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); } diff --git a/deps/v8/src/compiler/backend/register-allocator-verifier.cc b/deps/v8/src/compiler/backend/register-allocator-verifier.cc index 53349c9c2b46df..17e0b8ca755fb3 100644 --- a/deps/v8/src/compiler/backend/register-allocator-verifier.cc +++ b/deps/v8/src/compiler/backend/register-allocator-verifier.cc @@ -92,7 +92,7 @@ RegisterAllocatorVerifier::RegisterAllocatorVerifier( void RegisterAllocatorVerifier::VerifyInput( const OperandConstraint& constraint) { CHECK_NE(kSameAsFirst, constraint.type_); - if (constraint.type_ != kImmediate && constraint.type_ != kExplicit) { + if (constraint.type_ != kImmediate) { CHECK_NE(InstructionOperand::kInvalidVirtualRegister, constraint.virtual_register_); } @@ -102,14 +102,12 @@ void RegisterAllocatorVerifier::VerifyTemp( const OperandConstraint& constraint) { CHECK_NE(kSameAsFirst, constraint.type_); CHECK_NE(kImmediate, constraint.type_); - CHECK_NE(kExplicit, constraint.type_); CHECK_NE(kConstant, constraint.type_); } void RegisterAllocatorVerifier::VerifyOutput( const OperandConstraint& constraint) { CHECK_NE(kImmediate, constraint.type_); - CHECK_NE(kExplicit, constraint.type_); CHECK_NE(InstructionOperand::kInvalidVirtualRegister, constraint.virtual_register_); } @@ -149,8 +147,6 @@ void RegisterAllocatorVerifier::BuildConstraint(const InstructionOperand* op, constraint->type_ = kConstant; constraint->value_ = ConstantOperand::cast(op)->virtual_register(); constraint->virtual_register_ = constraint->value_; - } else if (op->IsExplicit()) { - constraint->type_ = kExplicit; } else if (op->IsImmediate()) { const ImmediateOperand* imm = ImmediateOperand::cast(op); int value = imm->type() == ImmediateOperand::INLINE ? imm->inline_value() @@ -235,9 +231,6 @@ void RegisterAllocatorVerifier::CheckConstraint( case kFPRegister: CHECK_WITH_MSG(op->IsFPRegister(), caller_info_); return; - case kExplicit: - CHECK_WITH_MSG(op->IsExplicit(), caller_info_); - return; case kFixedRegister: case kRegisterAndSlot: CHECK_WITH_MSG(op->IsRegister(), caller_info_); @@ -503,8 +496,7 @@ void RegisterAllocatorVerifier::VerifyGapMoves() { instr_constraint.operand_constraints_; size_t count = 0; for (size_t i = 0; i < instr->InputCount(); ++i, ++count) { - if (op_constraints[count].type_ == kImmediate || - op_constraints[count].type_ == kExplicit) { + if (op_constraints[count].type_ == kImmediate) { continue; } int virtual_register = op_constraints[count].virtual_register_; diff --git a/deps/v8/src/compiler/backend/register-allocator-verifier.h b/deps/v8/src/compiler/backend/register-allocator-verifier.h index 68e69c0d1648f6..7110c2eb42c6f4 100644 --- a/deps/v8/src/compiler/backend/register-allocator-verifier.h +++ b/deps/v8/src/compiler/backend/register-allocator-verifier.h @@ -188,7 +188,6 @@ class RegisterAllocatorVerifier final : public ZoneObject { kRegisterOrSlot, kRegisterOrSlotFP, kRegisterOrSlotOrConstant, - kExplicit, kSameAsFirst, kRegisterAndSlot }; diff --git a/deps/v8/src/compiler/backend/register-allocator.cc b/deps/v8/src/compiler/backend/register-allocator.cc index 21eef0485c5952..945554eb32361c 100644 --- a/deps/v8/src/compiler/backend/register-allocator.cc +++ b/deps/v8/src/compiler/backend/register-allocator.cc @@ -6,7 +6,7 @@ #include <iomanip> -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/base/small-vector.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/tick-counter.h" @@ -317,7 +317,6 @@ UsePositionHintType UsePosition::HintTypeForOperand( switch (op.kind()) { case InstructionOperand::CONSTANT: case InstructionOperand::IMMEDIATE: - case InstructionOperand::EXPLICIT: return UsePositionHintType::kNone; case InstructionOperand::UNALLOCATED: return UsePositionHintType::kUnresolved; @@ -797,12 +796,13 @@ LifetimePosition LiveRange::NextEndAfter(LifetimePosition position) const { return start_search->end(); } -LifetimePosition LiveRange::NextStartAfter(LifetimePosition position) const { +LifetimePosition LiveRange::NextStartAfter(LifetimePosition position) { UseInterval* start_search = FirstSearchIntervalForPosition(position); while (start_search->start() < position) { start_search = start_search->next(); } - return start_search->start(); + next_start_ = start_search->start(); + return next_start_; } LifetimePosition LiveRange::FirstIntersection(LiveRange* other) const { @@ -1940,8 +1940,8 @@ void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { // Handle fixed input operands of second instruction. for (size_t i = 0; i < second->InputCount(); i++) { InstructionOperand* input = second->InputAt(i); - if (input->IsImmediate() || input->IsExplicit()) { - continue; // Ignore immediates and explicitly reserved registers. + if (input->IsImmediate()) { + continue; // Ignore immediates. } UnallocatedOperand* cur_input = UnallocatedOperand::cast(input); if (cur_input->HasFixedPolicy()) { @@ -2323,8 +2323,8 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, for (size_t i = 0; i < instr->InputCount(); i++) { InstructionOperand* input = instr->InputAt(i); - if (input->IsImmediate() || input->IsExplicit()) { - continue; // Ignore immediates and explicitly reserved registers. + if (input->IsImmediate()) { + continue; // Ignore immediates. } LifetimePosition use_pos; if (input->IsUnallocated() && @@ -2504,10 +2504,10 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block, predecessor_hint_preference |= kNotDeferredBlockPreference; } - // - Prefer hints from allocated (or explicit) operands. + // - Prefer hints from allocated operands. // - // Already-allocated or explicit operands are typically assigned using - // the parallel moves on the last instruction. For example: + // Already-allocated operands are typically assigned using the parallel + // moves on the last instruction. For example: // // gap (v101 = [x0|R|w32]) (v100 = v101) // ArchJmp @@ -2515,7 +2515,7 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block, // phi: v100 = v101 v102 // // We have already found the END move, so look for a matching START move - // from an allocated (or explicit) operand. + // from an allocated operand. // // Note that we cannot simply look up data()->live_ranges()[vreg] here // because the live ranges are still being built when this function is @@ -2527,7 +2527,7 @@ void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block, for (MoveOperands* move : *moves) { InstructionOperand& to = move->destination(); if (predecessor_hint->Equals(to)) { - if (move->source().IsAllocated() || move->source().IsExplicit()) { + if (move->source().IsAllocated()) { predecessor_hint_preference |= kMoveIsAllocatedPreference; } break; @@ -3095,11 +3095,11 @@ LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data, : RegisterAllocator(data, kind), unhandled_live_ranges_(local_zone), active_live_ranges_(local_zone), - inactive_live_ranges_(local_zone), + inactive_live_ranges_(num_registers(), InactiveLiveRangeQueue(local_zone), + local_zone), next_active_ranges_change_(LifetimePosition::Invalid()), next_inactive_ranges_change_(LifetimePosition::Invalid()) { active_live_ranges().reserve(8); - inactive_live_ranges().reserve(8); } void LinearScanAllocator::MaybeSpillPreviousRanges(LiveRange* begin_range, @@ -3143,15 +3143,15 @@ void LinearScanAllocator::MaybeUndoPreviousSplit(LiveRange* range) { } } -void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet& to_be_live, +void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet* to_be_live, LifetimePosition position, SpillMode spill_mode) { for (auto it = active_live_ranges().begin(); it != active_live_ranges().end();) { LiveRange* active_range = *it; TopLevelLiveRange* toplevel = (*it)->TopLevel(); - auto found = to_be_live.find({toplevel, kUnassignedRegister}); - if (found == to_be_live.end()) { + auto found = to_be_live->find({toplevel, kUnassignedRegister}); + if (found == to_be_live->end()) { // Is not contained in {to_be_live}, spill it. // Fixed registers are exempt from this. They might have been // added from inactive at the block boundary but we know that @@ -3207,7 +3207,7 @@ void LinearScanAllocator::SpillNotLiveRanges(RangeWithRegisterSet& to_be_live, } else { // This range is contained in {to_be_live}, so we can keep it. int expected_register = (*found).expected_register; - to_be_live.erase(found); + to_be_live->erase(found); if (expected_register == active_range->assigned_register()) { // Was life and in correct register, simply pass through. TRACE("Keeping %d:%d in %s\n", toplevel->vreg(), @@ -3238,31 +3238,22 @@ LiveRange* LinearScanAllocator::AssignRegisterOnReload(LiveRange* range, // give reloading registers pecedence. That way we would compute the // intersection for the entire future. LifetimePosition new_end = range->End(); - for (const auto inactive : inactive_live_ranges()) { - if (kSimpleFPAliasing || !check_fp_aliasing()) { - if (inactive->assigned_register() != reg) continue; - } else { - bool conflict = inactive->assigned_register() == reg; - if (!conflict) { - int alias_base_index = -1; - int aliases = data()->config()->GetAliases(range->representation(), reg, - inactive->representation(), - &alias_base_index); - DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); - while (aliases-- && !conflict) { - int aliased_reg = alias_base_index + aliases; - if (aliased_reg == reg) { - conflict = true; - } - } - } - if (!conflict) continue; + for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) { + if ((kSimpleFPAliasing || !check_fp_aliasing()) && cur_reg != reg) { + continue; } - for (auto interval = inactive->first_interval(); interval != nullptr; - interval = interval->next()) { - if (interval->start() > new_end) break; - if (interval->end() <= range->Start()) continue; - if (new_end > interval->start()) new_end = interval->start(); + for (const auto cur_inactive : inactive_live_ranges(cur_reg)) { + if (!kSimpleFPAliasing && check_fp_aliasing() && + !data()->config()->AreAliases(cur_inactive->representation(), cur_reg, + range->representation(), reg)) { + continue; + } + for (auto interval = cur_inactive->first_interval(); interval != nullptr; + interval = interval->next()) { + if (interval->start() > new_end) break; + if (interval->end() <= range->Start()) continue; + if (new_end > interval->start()) new_end = interval->start(); + } } } if (new_end != range->End()) { @@ -3275,8 +3266,8 @@ LiveRange* LinearScanAllocator::AssignRegisterOnReload(LiveRange* range, return range; } -void LinearScanAllocator::ReloadLiveRanges(RangeWithRegisterSet& to_be_live, - LifetimePosition position) { +void LinearScanAllocator::ReloadLiveRanges( + RangeWithRegisterSet const& to_be_live, LifetimePosition position) { // Assumption: All ranges in {to_be_live} are currently spilled and there are // no conflicting registers in the active ranges. // The former is ensured by SpillNotLiveRanges, the latter is by construction @@ -3558,11 +3549,17 @@ void LinearScanAllocator::UpdateDeferredFixedRanges(SpillMode spill_mode, Min(updated->End(), next_active_ranges_change_); }); } - for (auto inactive : inactive_live_ranges()) { - split_conflicting(range, inactive, [this](LiveRange* updated) { - next_inactive_ranges_change_ = - Min(updated->End(), next_inactive_ranges_change_); - }); + for (int reg = 0; reg < num_registers(); ++reg) { + if ((kSimpleFPAliasing || !check_fp_aliasing()) && + reg != range->assigned_register()) { + continue; + } + for (auto inactive : inactive_live_ranges(reg)) { + split_conflicting(range, inactive, [this](LiveRange* updated) { + next_inactive_ranges_change_ = + Min(updated->End(), next_inactive_ranges_change_); + }); + } } }; if (mode() == GENERAL_REGISTERS) { @@ -3600,12 +3597,14 @@ void LinearScanAllocator::UpdateDeferredFixedRanges(SpillMode spill_mode, } } else { // Remove all ranges. - for (auto it = inactive_live_ranges().begin(); - it != inactive_live_ranges().end();) { - if ((*it)->TopLevel()->IsDeferredFixed()) { - it = inactive_live_ranges().erase(it); - } else { - ++it; + for (int reg = 0; reg < num_registers(); ++reg) { + for (auto it = inactive_live_ranges(reg).begin(); + it != inactive_live_ranges(reg).end();) { + if ((*it)->TopLevel()->IsDeferredFixed()) { + it = inactive_live_ranges(reg).erase(it); + } else { + ++it; + } } } } @@ -3636,7 +3635,9 @@ bool LinearScanAllocator::HasNonDeferredPredecessor(InstructionBlock* block) { void LinearScanAllocator::AllocateRegisters() { DCHECK(unhandled_live_ranges().empty()); DCHECK(active_live_ranges().empty()); - DCHECK(inactive_live_ranges().empty()); + for (int reg = 0; reg < num_registers(); ++reg) { + DCHECK(inactive_live_ranges(reg).empty()); + } SplitAndSpillRangesDefinedByMemoryOperand(); data()->ResetSpillState(); @@ -3853,7 +3854,7 @@ void LinearScanAllocator::AllocateRegisters() { } if (!no_change_required) { - SpillNotLiveRanges(to_be_live, next_block_boundary, spill_mode); + SpillNotLiveRanges(&to_be_live, next_block_boundary, spill_mode); ReloadLiveRanges(to_be_live, next_block_boundary); } @@ -3941,9 +3942,10 @@ void LinearScanAllocator::AddToActive(LiveRange* range) { void LinearScanAllocator::AddToInactive(LiveRange* range) { TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(), range->relative_id()); - inactive_live_ranges().push_back(range); next_inactive_ranges_change_ = std::min( next_inactive_ranges_change_, range->NextStartAfter(range->Start())); + DCHECK(range->HasRegisterAssigned()); + inactive_live_ranges(range->assigned_register()).insert(range); } void LinearScanAllocator::AddToUnhandled(LiveRange* range) { @@ -3966,30 +3968,36 @@ ZoneVector<LiveRange*>::iterator LinearScanAllocator::ActiveToHandled( ZoneVector<LiveRange*>::iterator LinearScanAllocator::ActiveToInactive( const ZoneVector<LiveRange*>::iterator it, LifetimePosition position) { LiveRange* range = *it; - inactive_live_ranges().push_back(range); TRACE("Moving live range %d:%d from active to inactive\n", (range)->TopLevel()->vreg(), range->relative_id()); + LifetimePosition next_active = range->NextStartAfter(position); next_inactive_ranges_change_ = - std::min(next_inactive_ranges_change_, range->NextStartAfter(position)); + std::min(next_inactive_ranges_change_, next_active); + DCHECK(range->HasRegisterAssigned()); + inactive_live_ranges(range->assigned_register()).insert(range); return active_live_ranges().erase(it); } -ZoneVector<LiveRange*>::iterator LinearScanAllocator::InactiveToHandled( - ZoneVector<LiveRange*>::iterator it) { +LinearScanAllocator::InactiveLiveRangeQueue::iterator +LinearScanAllocator::InactiveToHandled(InactiveLiveRangeQueue::iterator it) { + LiveRange* range = *it; TRACE("Moving live range %d:%d from inactive to handled\n", - (*it)->TopLevel()->vreg(), (*it)->relative_id()); - return inactive_live_ranges().erase(it); + range->TopLevel()->vreg(), range->relative_id()); + int reg = range->assigned_register(); + return inactive_live_ranges(reg).erase(it); } -ZoneVector<LiveRange*>::iterator LinearScanAllocator::InactiveToActive( - ZoneVector<LiveRange*>::iterator it, LifetimePosition position) { +LinearScanAllocator::InactiveLiveRangeQueue::iterator +LinearScanAllocator::InactiveToActive(InactiveLiveRangeQueue::iterator it, + LifetimePosition position) { LiveRange* range = *it; active_live_ranges().push_back(range); TRACE("Moving live range %d:%d from inactive to active\n", range->TopLevel()->vreg(), range->relative_id()); next_active_ranges_change_ = std::min(next_active_ranges_change_, range->NextEndAfter(position)); - return inactive_live_ranges().erase(it); + int reg = range->assigned_register(); + return inactive_live_ranges(reg).erase(it); } void LinearScanAllocator::ForwardStateTo(LifetimePosition position) { @@ -4012,18 +4020,25 @@ void LinearScanAllocator::ForwardStateTo(LifetimePosition position) { if (position >= next_inactive_ranges_change_) { next_inactive_ranges_change_ = LifetimePosition::MaxPosition(); - for (auto it = inactive_live_ranges().begin(); - it != inactive_live_ranges().end();) { - LiveRange* cur_inactive = *it; - if (cur_inactive->End() <= position) { - it = InactiveToHandled(it); - } else if (cur_inactive->Covers(position)) { - it = InactiveToActive(it, position); - } else { - next_inactive_ranges_change_ = - std::min(next_inactive_ranges_change_, - cur_inactive->NextStartAfter(position)); - ++it; + for (int reg = 0; reg < num_registers(); ++reg) { + ZoneVector<LiveRange*> reorder(data()->allocation_zone()); + for (auto it = inactive_live_ranges(reg).begin(); + it != inactive_live_ranges(reg).end();) { + LiveRange* cur_inactive = *it; + if (cur_inactive->End() <= position) { + it = InactiveToHandled(it); + } else if (cur_inactive->Covers(position)) { + it = InactiveToActive(it, position); + } else { + next_inactive_ranges_change_ = + std::min(next_inactive_ranges_change_, + cur_inactive->NextStartAfter(position)); + it = inactive_live_ranges(reg).erase(it); + reorder.push_back(cur_inactive); + } + } + for (LiveRange* range : reorder) { + inactive_live_ranges(reg).insert(range); } } } @@ -4094,31 +4109,34 @@ void LinearScanAllocator::FindFreeRegistersForRange( } } - for (LiveRange* cur_inactive : inactive_live_ranges()) { - DCHECK(cur_inactive->End() > range->Start()); - int cur_reg = cur_inactive->assigned_register(); - // No need to carry out intersections, when this register won't be - // interesting to this range anyway. - // TODO(mtrofin): extend to aliased ranges, too. - if ((kSimpleFPAliasing || !check_fp_aliasing()) && - positions[cur_reg] < range->Start()) { - continue; - } - - LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); - if (!next_intersection.IsValid()) continue; - if (kSimpleFPAliasing || !check_fp_aliasing()) { - positions[cur_reg] = Min(positions[cur_reg], next_intersection); - TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), - Min(positions[cur_reg], next_intersection).value()); - } else { - int alias_base_index = -1; - int aliases = data()->config()->GetAliases( - cur_inactive->representation(), cur_reg, rep, &alias_base_index); - DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); - while (aliases--) { - int aliased_reg = alias_base_index + aliases; - positions[aliased_reg] = Min(positions[aliased_reg], next_intersection); + for (int cur_reg = 0; cur_reg < num_regs; ++cur_reg) { + for (LiveRange* cur_inactive : inactive_live_ranges(cur_reg)) { + DCHECK_GT(cur_inactive->End(), range->Start()); + CHECK_EQ(cur_inactive->assigned_register(), cur_reg); + // No need to carry out intersections, when this register won't be + // interesting to this range anyway. + // TODO(mtrofin): extend to aliased ranges, too. + if ((kSimpleFPAliasing || !check_fp_aliasing()) && + positions[cur_reg] <= cur_inactive->NextStart()) { + break; + } + LifetimePosition next_intersection = + cur_inactive->FirstIntersection(range); + if (!next_intersection.IsValid()) continue; + if (kSimpleFPAliasing || !check_fp_aliasing()) { + positions[cur_reg] = std::min(positions[cur_reg], next_intersection); + TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), + positions[cur_reg].value()); + } else { + int alias_base_index = -1; + int aliases = data()->config()->GetAliases( + cur_inactive->representation(), cur_reg, rep, &alias_base_index); + DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); + while (aliases--) { + int aliased_reg = alias_base_index + aliases; + positions[aliased_reg] = + std::min(positions[aliased_reg], next_intersection); + } } } } @@ -4337,46 +4355,46 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current, } } - for (LiveRange* range : inactive_live_ranges()) { - DCHECK(range->End() > current->Start()); - int cur_reg = range->assigned_register(); - bool is_fixed = range->TopLevel()->IsFixed(); - - // Don't perform costly intersections if they are guaranteed to not update - // block_pos or use_pos. - // TODO(mtrofin): extend to aliased ranges, too. - if ((kSimpleFPAliasing || !check_fp_aliasing())) { - if (is_fixed) { - if (block_pos[cur_reg] < range->Start()) continue; - } else { - if (use_pos[cur_reg] < range->Start()) continue; + for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) { + for (LiveRange* range : inactive_live_ranges(cur_reg)) { + DCHECK(range->End() > current->Start()); + DCHECK_EQ(range->assigned_register(), cur_reg); + bool is_fixed = range->TopLevel()->IsFixed(); + + // Don't perform costly intersections if they are guaranteed to not update + // block_pos or use_pos. + // TODO(mtrofin): extend to aliased ranges, too. + if ((kSimpleFPAliasing || !check_fp_aliasing())) { + DCHECK_LE(use_pos[cur_reg], block_pos[cur_reg]); + if (block_pos[cur_reg] <= range->NextStart()) break; + if (!is_fixed && use_pos[cur_reg] <= range->NextStart()) continue; } - } - LifetimePosition next_intersection = range->FirstIntersection(current); - if (!next_intersection.IsValid()) continue; + LifetimePosition next_intersection = range->FirstIntersection(current); + if (!next_intersection.IsValid()) continue; - if (kSimpleFPAliasing || !check_fp_aliasing()) { - if (is_fixed) { - block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); - use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); - } else { - use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); - } - } else { - int alias_base_index = -1; - int aliases = data()->config()->GetAliases( - range->representation(), cur_reg, rep, &alias_base_index); - DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); - while (aliases--) { - int aliased_reg = alias_base_index + aliases; + if (kSimpleFPAliasing || !check_fp_aliasing()) { if (is_fixed) { - block_pos[aliased_reg] = - Min(block_pos[aliased_reg], next_intersection); - use_pos[aliased_reg] = - Min(block_pos[aliased_reg], use_pos[aliased_reg]); + block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); + use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); } else { - use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection); + use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); + } + } else { + int alias_base_index = -1; + int aliases = data()->config()->GetAliases( + range->representation(), cur_reg, rep, &alias_base_index); + DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); + while (aliases--) { + int aliased_reg = alias_base_index + aliases; + if (is_fixed) { + block_pos[aliased_reg] = + Min(block_pos[aliased_reg], next_intersection); + use_pos[aliased_reg] = + Min(block_pos[aliased_reg], use_pos[aliased_reg]); + } else { + use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection); + } } } } @@ -4490,40 +4508,38 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current, it = ActiveToHandled(it); } - for (auto it = inactive_live_ranges().begin(); - it != inactive_live_ranges().end();) { - LiveRange* range = *it; - DCHECK(range->End() > current->Start()); - if (range->TopLevel()->IsFixed()) { - ++it; - continue; - } + for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) { if (kSimpleFPAliasing || !check_fp_aliasing()) { - if (range->assigned_register() != reg) { + if (cur_reg != reg) continue; + } + for (auto it = inactive_live_ranges(cur_reg).begin(); + it != inactive_live_ranges(cur_reg).end();) { + LiveRange* range = *it; + if (!kSimpleFPAliasing && check_fp_aliasing() && + !data()->config()->AreAliases(current->representation(), reg, + range->representation(), cur_reg)) { ++it; continue; } - } else { - if (!data()->config()->AreAliases(current->representation(), reg, - range->representation(), - range->assigned_register())) { + DCHECK(range->End() > current->Start()); + if (range->TopLevel()->IsFixed()) { ++it; continue; } - } - LifetimePosition next_intersection = range->FirstIntersection(current); - if (next_intersection.IsValid()) { - UsePosition* next_pos = range->NextRegisterPosition(current->Start()); - if (next_pos == nullptr) { - SpillAfter(range, split_pos, spill_mode); + LifetimePosition next_intersection = range->FirstIntersection(current); + if (next_intersection.IsValid()) { + UsePosition* next_pos = range->NextRegisterPosition(current->Start()); + if (next_pos == nullptr) { + SpillAfter(range, split_pos, spill_mode); + } else { + next_intersection = Min(next_intersection, next_pos->pos()); + SpillBetween(range, split_pos, next_intersection, spill_mode); + } + it = InactiveToHandled(it); } else { - next_intersection = Min(next_intersection, next_pos->pos()); - SpillBetween(range, split_pos, next_intersection, spill_mode); + ++it; } - it = InactiveToHandled(it); - } else { - ++it; } } } diff --git a/deps/v8/src/compiler/backend/register-allocator.h b/deps/v8/src/compiler/backend/register-allocator.h index bc7b09d147dd06..17d664e5077897 100644 --- a/deps/v8/src/compiler/backend/register-allocator.h +++ b/deps/v8/src/compiler/backend/register-allocator.h @@ -335,7 +335,11 @@ class RegisterAllocationData final : public ZoneObject { return result; } - void ResetSpillState() { spill_state_.clear(); } + void ResetSpillState() { + for (auto& state : spill_state_) { + state.clear(); + } + } TickCounter* tick_counter() { return tick_counter_; } @@ -626,9 +630,10 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) { bool ShouldBeAllocatedBefore(const LiveRange* other) const; bool CanCover(LifetimePosition position) const; bool Covers(LifetimePosition position) const; - LifetimePosition NextStartAfter(LifetimePosition position) const; + LifetimePosition NextStartAfter(LifetimePosition position); LifetimePosition NextEndAfter(LifetimePosition position) const; LifetimePosition FirstIntersection(LiveRange* other) const; + LifetimePosition NextStart() const { return next_start_; } void VerifyChildStructure() const { VerifyIntervals(); @@ -689,6 +694,8 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) { // Cache the last position splintering stopped at. mutable UsePosition* splitting_pointer_; LiveRangeBundle* bundle_ = nullptr; + // Next interval start, relative to the current linear scan position. + LifetimePosition next_start_; DISALLOW_COPY_AND_ASSIGN(LiveRange); }; @@ -1298,29 +1305,39 @@ class LinearScanAllocator final : public RegisterAllocator { LifetimePosition begin_pos, LiveRange* end_range); void MaybeUndoPreviousSplit(LiveRange* range); - void SpillNotLiveRanges( - RangeWithRegisterSet& to_be_live, // NOLINT(runtime/references) - LifetimePosition position, SpillMode spill_mode); + void SpillNotLiveRanges(RangeWithRegisterSet* to_be_live, + LifetimePosition position, SpillMode spill_mode); LiveRange* AssignRegisterOnReload(LiveRange* range, int reg); - void ReloadLiveRanges( - RangeWithRegisterSet& to_be_live, // NOLINT(runtime/references) - LifetimePosition position); + void ReloadLiveRanges(RangeWithRegisterSet const& to_be_live, + LifetimePosition position); void UpdateDeferredFixedRanges(SpillMode spill_mode, InstructionBlock* block); bool BlockIsDeferredOrImmediatePredecessorIsNotDeferred( const InstructionBlock* block); bool HasNonDeferredPredecessor(InstructionBlock* block); - struct LiveRangeOrdering { + struct UnhandledLiveRangeOrdering { bool operator()(const LiveRange* a, const LiveRange* b) const { return a->ShouldBeAllocatedBefore(b); } }; - using LiveRangeQueue = ZoneMultiset<LiveRange*, LiveRangeOrdering>; - LiveRangeQueue& unhandled_live_ranges() { return unhandled_live_ranges_; } + + struct InactiveLiveRangeOrdering { + bool operator()(const LiveRange* a, const LiveRange* b) const { + return a->NextStart() < b->NextStart(); + } + }; + + using UnhandledLiveRangeQueue = + ZoneMultiset<LiveRange*, UnhandledLiveRangeOrdering>; + using InactiveLiveRangeQueue = + ZoneMultiset<LiveRange*, InactiveLiveRangeOrdering>; + UnhandledLiveRangeQueue& unhandled_live_ranges() { + return unhandled_live_ranges_; + } ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } - ZoneVector<LiveRange*>& inactive_live_ranges() { - return inactive_live_ranges_; + InactiveLiveRangeQueue& inactive_live_ranges(int reg) { + return inactive_live_ranges_[reg]; } void SetLiveRangeAssignedRegister(LiveRange* range, int reg); @@ -1333,10 +1350,10 @@ class LinearScanAllocator final : public RegisterAllocator { ZoneVector<LiveRange*>::iterator it); ZoneVector<LiveRange*>::iterator ActiveToInactive( ZoneVector<LiveRange*>::iterator it, LifetimePosition position); - ZoneVector<LiveRange*>::iterator InactiveToHandled( - ZoneVector<LiveRange*>::iterator it); - ZoneVector<LiveRange*>::iterator InactiveToActive( - ZoneVector<LiveRange*>::iterator it, LifetimePosition position); + InactiveLiveRangeQueue::iterator InactiveToHandled( + InactiveLiveRangeQueue::iterator it); + InactiveLiveRangeQueue::iterator InactiveToActive( + InactiveLiveRangeQueue::iterator it, LifetimePosition position); void ForwardStateTo(LifetimePosition position); @@ -1386,9 +1403,9 @@ class LinearScanAllocator final : public RegisterAllocator { void PrintRangeOverview(std::ostream& os); - LiveRangeQueue unhandled_live_ranges_; + UnhandledLiveRangeQueue unhandled_live_ranges_; ZoneVector<LiveRange*> active_live_ranges_; - ZoneVector<LiveRange*> inactive_live_ranges_; + ZoneVector<InactiveLiveRangeQueue> inactive_live_ranges_; // Approximate at what position the set of ranges will change next. // Used to avoid scanning for updates even if none are present. diff --git a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc index 4c2d862fc44a1b..d0f97eca57b08c 100644 --- a/deps/v8/src/compiler/backend/s390/code-generator-s390.cc +++ b/deps/v8/src/compiler/backend/s390/code-generator-s390.cc @@ -1246,9 +1246,8 @@ void AdjustStackPointerForTailCall( } } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, Instruction* instr, - S390OperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr, + S390OperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(instr->opcode())); if (access_mode == kMemoryAccessPoisoned) { diff --git a/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc b/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc index 7f3277fc68d831..7b002fe6d3bdfa 100644 --- a/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc +++ b/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "src/base/adapters.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties.h" @@ -436,68 +435,64 @@ void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode, #endif template <class CanCombineWithLoad> -void GenerateRightOperands( - InstructionSelector* selector, Node* node, Node* right, - InstructionCode& opcode, // NOLINT(runtime/references) - OperandModes& operand_mode, // NOLINT(runtime/references) - InstructionOperand* inputs, - size_t& input_count, // NOLINT(runtime/references) - CanCombineWithLoad canCombineWithLoad) { +void GenerateRightOperands(InstructionSelector* selector, Node* node, + Node* right, InstructionCode* opcode, + OperandModes* operand_mode, + InstructionOperand* inputs, size_t* input_count, + CanCombineWithLoad canCombineWithLoad) { S390OperandGenerator g(selector); - if ((operand_mode & OperandMode::kAllowImmediate) && - g.CanBeImmediate(right, operand_mode)) { - inputs[input_count++] = g.UseImmediate(right); + if ((*operand_mode & OperandMode::kAllowImmediate) && + g.CanBeImmediate(right, *operand_mode)) { + inputs[(*input_count)++] = g.UseImmediate(right); // Can only be RI or RRI - operand_mode &= OperandMode::kAllowImmediate; - } else if (operand_mode & OperandMode::kAllowMemoryOperand) { + *operand_mode &= OperandMode::kAllowImmediate; + } else if (*operand_mode & OperandMode::kAllowMemoryOperand) { NodeMatcher mright(right); if (mright.IsLoad() && selector->CanCover(node, right) && canCombineWithLoad(SelectLoadOpcode(right))) { AddressingMode mode = g.GetEffectiveAddressMemoryOperand( - right, inputs, &input_count, OpcodeImmMode(opcode)); - opcode |= AddressingModeField::encode(mode); - operand_mode &= ~OperandMode::kAllowImmediate; - if (operand_mode & OperandMode::kAllowRM) - operand_mode &= ~OperandMode::kAllowDistinctOps; - } else if (operand_mode & OperandMode::kAllowRM) { - DCHECK(!(operand_mode & OperandMode::kAllowRRM)); - inputs[input_count++] = g.UseAnyExceptImmediate(right); + right, inputs, input_count, OpcodeImmMode(*opcode)); + *opcode |= AddressingModeField::encode(mode); + *operand_mode &= ~OperandMode::kAllowImmediate; + if (*operand_mode & OperandMode::kAllowRM) + *operand_mode &= ~OperandMode::kAllowDistinctOps; + } else if (*operand_mode & OperandMode::kAllowRM) { + DCHECK(!(*operand_mode & OperandMode::kAllowRRM)); + inputs[(*input_count)++] = g.UseAnyExceptImmediate(right); // Can not be Immediate - operand_mode &= + *operand_mode &= ~OperandMode::kAllowImmediate & ~OperandMode::kAllowDistinctOps; - } else if (operand_mode & OperandMode::kAllowRRM) { - DCHECK(!(operand_mode & OperandMode::kAllowRM)); - inputs[input_count++] = g.UseAnyExceptImmediate(right); + } else if (*operand_mode & OperandMode::kAllowRRM) { + DCHECK(!(*operand_mode & OperandMode::kAllowRM)); + inputs[(*input_count)++] = g.UseAnyExceptImmediate(right); // Can not be Immediate - operand_mode &= ~OperandMode::kAllowImmediate; + *operand_mode &= ~OperandMode::kAllowImmediate; } else { UNREACHABLE(); } } else { - inputs[input_count++] = g.UseRegister(right); + inputs[(*input_count)++] = g.UseRegister(right); // Can only be RR or RRR - operand_mode &= OperandMode::kAllowRRR; + *operand_mode &= OperandMode::kAllowRRR; } } template <class CanCombineWithLoad> -void GenerateBinOpOperands( - InstructionSelector* selector, Node* node, Node* left, Node* right, - InstructionCode& opcode, // NOLINT(runtime/references) - OperandModes& operand_mode, // NOLINT(runtime/references) - InstructionOperand* inputs, - size_t& input_count, // NOLINT(runtime/references) - CanCombineWithLoad canCombineWithLoad) { +void GenerateBinOpOperands(InstructionSelector* selector, Node* node, + Node* left, Node* right, InstructionCode* opcode, + OperandModes* operand_mode, + InstructionOperand* inputs, size_t* input_count, + CanCombineWithLoad canCombineWithLoad) { S390OperandGenerator g(selector); // left is always register InstructionOperand const left_input = g.UseRegister(left); - inputs[input_count++] = left_input; + inputs[(*input_count)++] = left_input; if (left == right) { - inputs[input_count++] = left_input; + inputs[(*input_count)++] = left_input; // Can only be RR or RRR - operand_mode &= OperandMode::kAllowRRR; + *operand_mode &= OperandMode::kAllowRRR; } else { GenerateRightOperands(selector, node, right, opcode, operand_mode, inputs, input_count, canCombineWithLoad); @@ -575,8 +570,8 @@ void VisitUnaryOp(InstructionSelector* selector, Node* node, size_t output_count = 0; Node* input = node->InputAt(0); - GenerateRightOperands(selector, node, input, opcode, operand_mode, inputs, - input_count, canCombineWithLoad); + GenerateRightOperands(selector, node, input, &opcode, &operand_mode, inputs, + &input_count, canCombineWithLoad); bool input_is_word32 = ProduceWord32Result(input); @@ -631,8 +626,8 @@ void VisitBinOp(InstructionSelector* selector, Node* node, std::swap(left, right); } - GenerateBinOpOperands(selector, node, left, right, opcode, operand_mode, - inputs, input_count, canCombineWithLoad); + GenerateBinOpOperands(selector, node, left, right, &opcode, &operand_mode, + inputs, &input_count, canCombineWithLoad); bool left_is_word32 = ProduceWord32Result(left); @@ -1175,6 +1170,12 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + // TODO(miladfar): Implement the s390 selector for reversing SIMD bytes. + // Check if the input node is a Load and do a Load Reverse at once. + UNIMPLEMENTED(); +} + template <class Matcher, ArchOpcode neg_opcode> static inline bool TryMatchNegFromSub(InstructionSelector* selector, Node* node) { @@ -2691,6 +2692,8 @@ void InstructionSelector::VisitF32x4Sub(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Mul(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitF32x4Sqrt(Node* node) { UNIMPLEMENTED(); } + void InstructionSelector::VisitF32x4Div(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); } diff --git a/deps/v8/src/compiler/backend/x64/code-generator-x64.cc b/deps/v8/src/compiler/backend/x64/code-generator-x64.cc index a4f82b153b6387..44da872f26d0a4 100644 --- a/deps/v8/src/compiler/backend/x64/code-generator-x64.cc +++ b/deps/v8/src/compiler/backend/x64/code-generator-x64.cc @@ -361,7 +361,6 @@ class WasmProtectedInstructionTrap final : public WasmOutOfLineTrap { void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, InstructionCode opcode, Instruction* instr, - X64OperandConverter& i, // NOLINT(runtime/references) int pc) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); @@ -370,9 +369,9 @@ void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, } } -void EmitWordLoadPoisoningIfNeeded( - CodeGenerator* codegen, InstructionCode opcode, Instruction* instr, - X64OperandConverter& i) { // NOLINT(runtime/references) +void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, + InstructionCode opcode, Instruction* instr, + X64OperandConverter const& i) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); if (access_mode == kMemoryAccessPoisoned) { @@ -1876,30 +1875,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); break; case kX64Movsxbl: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movsxbl); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movzxbl: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movzxbl); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movsxbq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movsxbq); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movzxbq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movzxbq); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movb: { - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); size_t index = 0; Operand operand = i.MemoryOperand(&index); if (HasImmediateInput(instr, index)) { @@ -1911,29 +1910,29 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kX64Movsxwl: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movsxwl); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movzxwl: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movzxwl); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movsxwq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movsxwq); break; case kX64Movzxwq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movzxwq); __ AssertZeroExtended(i.OutputRegister()); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movw: { - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); size_t index = 0; Operand operand = i.MemoryOperand(&index); if (HasImmediateInput(instr, index)) { @@ -1945,7 +1944,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kX64Movl: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); if (instr->HasOutput()) { if (HasAddressingMode(instr)) { __ movl(i.OutputRegister(), i.MemoryOperand()); @@ -1969,7 +1968,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movsxlq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); ASSEMBLE_MOVX(movsxlq); EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; @@ -2021,7 +2020,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kX64Movq: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); if (instr->HasOutput()) { __ movq(i.OutputRegister(), i.MemoryOperand()); } else { @@ -2036,7 +2035,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i); break; case kX64Movss: - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); if (instr->HasOutput()) { __ Movss(i.OutputDoubleRegister(), i.MemoryOperand()); } else { @@ -2046,7 +2045,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } break; case kX64Movsd: { - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); if (instr->HasOutput()) { const MemoryAccessMode access_mode = static_cast<MemoryAccessMode>(MiscField::decode(opcode)); @@ -2069,7 +2068,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64Movdqu: { CpuFeatureScope sse_scope(tasm(), SSSE3); - EmitOOLTrapIfNeeded(zone(), this, opcode, instr, i, __ pc_offset()); + EmitOOLTrapIfNeeded(zone(), this, opcode, instr, __ pc_offset()); if (instr->HasOutput()) { __ Movdqu(i.OutputSimd128Register(), i.MemoryOperand()); } else { @@ -2293,6 +2292,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ movq(i.OutputDoubleRegister(), kScratchRegister); break; } + case kX64F64x2Sqrt: { + __ Sqrtpd(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } case kX64F64x2Add: { ASSEMBLE_SSE_BINOP(addpd); break; @@ -2350,22 +2353,48 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64F64x2Eq: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); - __ cmpeqpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Cmpeqpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64F64x2Ne: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); - __ cmpneqpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Cmpneqpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64F64x2Lt: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); - __ cmpltpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Cmpltpd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64F64x2Le: { DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); - __ cmplepd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Cmplepd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + break; + } + case kX64F64x2Qfma: { + if (CpuFeatures::IsSupported(FMA3)) { + CpuFeatureScope fma3_scope(tasm(), FMA3); + __ vfmadd231pd(i.OutputSimd128Register(), i.InputSimd128Register(1), + i.InputSimd128Register(2)); + } else { + XMMRegister tmp = i.TempSimd128Register(0); + __ movapd(tmp, i.InputSimd128Register(2)); + __ mulpd(tmp, i.InputSimd128Register(1)); + __ addpd(i.OutputSimd128Register(), tmp); + } + break; + } + case kX64F64x2Qfms: { + if (CpuFeatures::IsSupported(FMA3)) { + CpuFeatureScope fma3_scope(tasm(), FMA3); + __ vfnmadd231pd(i.OutputSimd128Register(), i.InputSimd128Register(1), + i.InputSimd128Register(2)); + } else { + XMMRegister tmp = i.TempSimd128Register(0); + __ movapd(tmp, i.InputSimd128Register(2)); + __ mulpd(tmp, i.InputSimd128Register(1)); + __ subpd(i.OutputSimd128Register(), tmp); + } break; } // TODO(gdeepti): Get rid of redundant moves for F32x4Splat/Extract below @@ -2445,6 +2474,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } break; } + case kX64F32x4Sqrt: { + __ sqrtps(i.OutputSimd128Register(), i.InputSimd128Register(0)); + break; + } case kX64F32x4RecipApprox: { __ rcpps(i.OutputSimd128Register(), i.InputSimd128Register(0)); break; @@ -2538,6 +2571,32 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ cmpleps(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } + case kX64F32x4Qfma: { + if (CpuFeatures::IsSupported(FMA3)) { + CpuFeatureScope fma3_scope(tasm(), FMA3); + __ vfmadd231ps(i.OutputSimd128Register(), i.InputSimd128Register(1), + i.InputSimd128Register(2)); + } else { + XMMRegister tmp = i.TempSimd128Register(0); + __ movaps(tmp, i.InputSimd128Register(2)); + __ mulps(tmp, i.InputSimd128Register(1)); + __ addps(i.OutputSimd128Register(), tmp); + } + break; + } + case kX64F32x4Qfms: { + if (CpuFeatures::IsSupported(FMA3)) { + CpuFeatureScope fma3_scope(tasm(), FMA3); + __ vfnmadd231ps(i.OutputSimd128Register(), i.InputSimd128Register(1), + i.InputSimd128Register(2)); + } else { + XMMRegister tmp = i.TempSimd128Register(0); + __ movaps(tmp, i.InputSimd128Register(2)); + __ mulps(tmp, i.InputSimd128Register(1)); + __ subps(i.OutputSimd128Register(), tmp); + } + break; + } case kX64I64x2Splat: { CpuFeatureScope sse_scope(tasm(), SSE3); XMMRegister dst = i.OutputSimd128Register(); @@ -2577,7 +2636,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64I64x2Shl: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 8. + __ andq(shift, Immediate(63)); + __ movq(tmp, shift); __ psllq(i.OutputSimd128Register(), tmp); break; } @@ -2588,6 +2650,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(0); Register tmp = i.ToRegister(instr->TempAt(0)); + // Modulo 64 not required as sarq_cl will mask cl to 6 bits. // lower quadword __ pextrq(tmp, src, 0x0); @@ -2640,15 +2703,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( if (CpuFeatures::IsSupported(SSE4_2)) { CpuFeatureScope sse_scope_4_2(tasm(), SSE4_2); XMMRegister dst = i.OutputSimd128Register(); - XMMRegister src = i.InputSimd128Register(1); + XMMRegister src0 = i.InputSimd128Register(0); + XMMRegister src1 = i.InputSimd128Register(1); XMMRegister tmp = i.TempSimd128Register(0); - DCHECK_EQ(dst, i.InputSimd128Register(0)); - DCHECK_EQ(src, xmm0); + DCHECK_EQ(tmp, xmm0); - __ movaps(tmp, src); - __ pcmpgtq(src, dst); - __ blendvpd(tmp, dst); // implicit use of xmm0 as mask - __ movaps(dst, tmp); + __ movaps(tmp, src1); + __ pcmpgtq(tmp, src0); + __ movaps(dst, src1); + __ blendvpd(dst, src0); // implicit use of xmm0 as mask } else { CpuFeatureScope sse_scope_4_1(tasm(), SSE4_1); XMMRegister dst = i.OutputSimd128Register(); @@ -2689,11 +2752,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( XMMRegister src = i.InputSimd128Register(1); XMMRegister tmp = i.TempSimd128Register(0); DCHECK_EQ(dst, i.InputSimd128Register(0)); - DCHECK_EQ(src, xmm0); + DCHECK_EQ(tmp, xmm0); __ movaps(tmp, src); - __ pcmpgtq(src, dst); - __ blendvpd(dst, tmp); // implicit use of xmm0 as mask + __ pcmpgtq(tmp, dst); + __ blendvpd(dst, src); // implicit use of xmm0 as mask break; } case kX64I64x2Eq: { @@ -2732,7 +2795,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64I64x2ShrU: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 64. + __ andq(shift, Immediate(63)); + __ movq(tmp, shift); __ psrlq(i.OutputSimd128Register(), tmp); break; } @@ -2740,24 +2806,23 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( CpuFeatureScope sse_scope_4_2(tasm(), SSE4_2); CpuFeatureScope sse_scope_4_1(tasm(), SSE4_1); XMMRegister dst = i.OutputSimd128Register(); - XMMRegister src = i.InputSimd128Register(1); - XMMRegister src_tmp = i.TempSimd128Register(0); - XMMRegister dst_tmp = i.TempSimd128Register(1); - DCHECK_EQ(dst, i.InputSimd128Register(0)); - DCHECK_EQ(src, xmm0); + XMMRegister src0 = i.InputSimd128Register(0); + XMMRegister src1 = i.InputSimd128Register(1); + XMMRegister tmp0 = i.TempSimd128Register(0); + XMMRegister tmp1 = i.TempSimd128Register(1); + DCHECK_EQ(tmp1, xmm0); - __ movaps(src_tmp, src); - __ movaps(dst_tmp, dst); + __ movaps(dst, src1); + __ movaps(tmp0, src0); - __ pcmpeqd(src, src); - __ psllq(src, 63); + __ pcmpeqd(tmp1, tmp1); + __ psllq(tmp1, 63); - __ pxor(dst_tmp, src); - __ pxor(src, src_tmp); + __ pxor(tmp0, tmp1); + __ pxor(tmp1, dst); - __ pcmpgtq(src, dst_tmp); - __ blendvpd(src_tmp, dst); // implicit use of xmm0 as mask - __ movaps(dst, src_tmp); + __ pcmpgtq(tmp1, tmp0); + __ blendvpd(dst, src0); // implicit use of xmm0 as mask break; } case kX64I64x2MaxU: { @@ -2765,22 +2830,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( CpuFeatureScope sse_scope_4_1(tasm(), SSE4_1); XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(1); - XMMRegister src_tmp = i.TempSimd128Register(0); - XMMRegister dst_tmp = i.TempSimd128Register(1); + XMMRegister dst_tmp = i.TempSimd128Register(0); + XMMRegister tmp = i.TempSimd128Register(1); DCHECK_EQ(dst, i.InputSimd128Register(0)); - DCHECK_EQ(src, xmm0); + DCHECK_EQ(tmp, xmm0); - __ movaps(src_tmp, src); __ movaps(dst_tmp, dst); - __ pcmpeqd(src, src); - __ psllq(src, 63); + __ pcmpeqd(tmp, tmp); + __ psllq(tmp, 63); - __ pxor(dst_tmp, src); - __ pxor(src, src_tmp); + __ pxor(dst_tmp, tmp); + __ pxor(tmp, src); - __ pcmpgtq(src, dst_tmp); - __ blendvpd(dst, src_tmp); // implicit use of xmm0 as mask + __ pcmpgtq(tmp, dst_tmp); + __ blendvpd(dst, src); // implicit use of xmm0 as mask break; } case kX64I64x2GtU: { @@ -2820,11 +2884,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kX64I32x4Splat: { XMMRegister dst = i.OutputSimd128Register(); if (HasRegisterInput(instr, 0)) { - __ movd(dst, i.InputRegister(0)); + __ Movd(dst, i.InputRegister(0)); } else { - __ movd(dst, i.InputOperand(0)); + __ Movd(dst, i.InputOperand(0)); } - __ pshufd(dst, dst, 0x0); + __ Pshufd(dst, dst, 0x0); break; } case kX64I32x4ExtractLane: { @@ -2878,28 +2942,34 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(0); if (dst == src) { - __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); - __ psignd(dst, kScratchDoubleReg); + __ Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg); + __ Psignd(dst, kScratchDoubleReg); } else { - __ pxor(dst, dst); - __ psubd(dst, src); + __ Pxor(dst, dst); + __ Psubd(dst, src); } break; } case kX64I32x4Shl: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); - __ pslld(i.OutputSimd128Register(), tmp); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ andq(shift, Immediate(31)); + __ Movq(tmp, shift); + __ Pslld(i.OutputSimd128Register(), tmp); break; } case kX64I32x4ShrS: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); - __ psrad(i.OutputSimd128Register(), tmp); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ andq(shift, Immediate(31)); + __ Movq(tmp, shift); + __ Psrad(i.OutputSimd128Register(), tmp); break; } case kX64I32x4Add: { - __ paddd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Paddd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4AddHoriz: { @@ -2908,45 +2978,45 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kX64I32x4Sub: { - __ psubd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Psubd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4Mul: { CpuFeatureScope sse_scope(tasm(), SSE4_1); - __ pmulld(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pmulld(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4MinS: { CpuFeatureScope sse_scope(tasm(), SSE4_1); - __ pminsd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pminsd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4MaxS: { CpuFeatureScope sse_scope(tasm(), SSE4_1); - __ pmaxsd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pmaxsd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4Eq: { - __ pcmpeqd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pcmpeqd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4Ne: { XMMRegister tmp = i.TempSimd128Register(0); - __ pcmpeqd(i.OutputSimd128Register(), i.InputSimd128Register(1)); - __ pcmpeqd(tmp, tmp); - __ pxor(i.OutputSimd128Register(), tmp); + __ Pcmpeqd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pcmpeqd(tmp, tmp); + __ Pxor(i.OutputSimd128Register(), tmp); break; } case kX64I32x4GtS: { - __ pcmpgtd(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pcmpgtd(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4GeS: { CpuFeatureScope sse_scope(tasm(), SSE4_1); XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(1); - __ pminsd(dst, src); - __ pcmpeqd(dst, src); + __ Pminsd(dst, src); + __ Pcmpeqd(dst, src); break; } case kX64I32x4UConvertF32x4: { @@ -2992,18 +3062,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64I32x4ShrU: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); - __ psrld(i.OutputSimd128Register(), tmp); + Register shift = i.InputRegister(1); + // Take shift value modulo 32. + __ andq(shift, Immediate(31)); + __ Movq(tmp, shift); + __ Psrld(i.OutputSimd128Register(), tmp); break; } case kX64I32x4MinU: { CpuFeatureScope sse_scope(tasm(), SSE4_1); - __ pminud(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pminud(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4MaxU: { CpuFeatureScope sse_scope(tasm(), SSE4_1); - __ pmaxud(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Pmaxud(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I32x4GtU: { @@ -3011,18 +3084,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(1); XMMRegister tmp = i.TempSimd128Register(0); - __ pmaxud(dst, src); - __ pcmpeqd(dst, src); - __ pcmpeqd(tmp, tmp); - __ pxor(dst, tmp); + __ Pmaxud(dst, src); + __ Pcmpeqd(dst, src); + __ Pcmpeqd(tmp, tmp); + __ Pxor(dst, tmp); break; } case kX64I32x4GeU: { CpuFeatureScope sse_scope(tasm(), SSE4_1); XMMRegister dst = i.OutputSimd128Register(); XMMRegister src = i.InputSimd128Register(1); - __ pminud(dst, src); - __ pcmpeqd(dst, src); + __ Pminud(dst, src); + __ Pcmpeqd(dst, src); break; } case kX64S128Zero: { @@ -3044,17 +3117,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kX64I16x8ExtractLane: { CpuFeatureScope sse_scope(tasm(), SSE4_1); Register dst = i.OutputRegister(); - __ pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1)); - __ movsxwl(dst, dst); + __ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1)); break; } case kX64I16x8ReplaceLane: { CpuFeatureScope sse_scope(tasm(), SSE4_1); if (HasRegisterInput(instr, 2)) { - __ pinsrw(i.OutputSimd128Register(), i.InputRegister(2), + __ Pinsrw(i.OutputSimd128Register(), i.InputRegister(2), i.InputInt8(1)); } else { - __ pinsrw(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); + __ Pinsrw(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); } break; } @@ -3085,13 +3157,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64I16x8Shl: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ andq(shift, Immediate(15)); + __ movq(tmp, shift); __ psllw(i.OutputSimd128Register(), tmp); break; } case kX64I16x8ShrS: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ andq(shift, Immediate(15)); + __ movq(tmp, shift); __ psraw(i.OutputSimd128Register(), tmp); break; } @@ -3173,7 +3251,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } case kX64I16x8ShrU: { XMMRegister tmp = i.TempSimd128Register(0); - __ movq(tmp, i.InputRegister(1)); + Register shift = i.InputRegister(1); + // Take shift value modulo 16. + __ andq(shift, Immediate(15)); + __ movq(tmp, shift); __ psrlw(i.OutputSimd128Register(), tmp); break; } @@ -3230,28 +3311,27 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( CpuFeatureScope sse_scope(tasm(), SSSE3); XMMRegister dst = i.OutputSimd128Register(); if (HasRegisterInput(instr, 0)) { - __ movd(dst, i.InputRegister(0)); + __ Movd(dst, i.InputRegister(0)); } else { - __ movd(dst, i.InputOperand(0)); + __ Movd(dst, i.InputOperand(0)); } - __ xorps(kScratchDoubleReg, kScratchDoubleReg); - __ pshufb(dst, kScratchDoubleReg); + __ Xorps(kScratchDoubleReg, kScratchDoubleReg); + __ Pshufb(dst, kScratchDoubleReg); break; } case kX64I8x16ExtractLane: { CpuFeatureScope sse_scope(tasm(), SSE4_1); Register dst = i.OutputRegister(); - __ pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1)); - __ movsxbl(dst, dst); + __ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1)); break; } case kX64I8x16ReplaceLane: { CpuFeatureScope sse_scope(tasm(), SSE4_1); if (HasRegisterInput(instr, 2)) { - __ pinsrb(i.OutputSimd128Register(), i.InputRegister(2), + __ Pinsrb(i.OutputSimd128Register(), i.InputRegister(2), i.InputInt8(1)); } else { - __ pinsrb(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); + __ Pinsrb(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); } break; } @@ -3279,15 +3359,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( // Temp registers for shift mask andadditional moves to XMM registers. Register tmp = i.ToRegister(instr->TempAt(0)); XMMRegister tmp_simd = i.TempSimd128Register(1); + Register shift = i.InputRegister(1); // Mask off the unwanted bits before word-shifting. __ pcmpeqw(kScratchDoubleReg, kScratchDoubleReg); - __ movq(tmp, i.InputRegister(1)); + // Take shift value modulo 8. + __ andq(shift, Immediate(7)); + __ movq(tmp, shift); __ addq(tmp, Immediate(8)); __ movq(tmp_simd, tmp); __ psrlw(kScratchDoubleReg, tmp_simd); __ packuswb(kScratchDoubleReg, kScratchDoubleReg); __ pand(dst, kScratchDoubleReg); - __ movq(tmp_simd, i.InputRegister(1)); + __ movq(tmp_simd, shift); __ psllw(dst, tmp_simd); break; } @@ -3302,6 +3385,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ punpcklbw(dst, dst); // Prepare shift value __ movq(tmp, i.InputRegister(1)); + // Take shift value modulo 8. + __ andq(tmp, Immediate(7)); __ addq(tmp, Immediate(8)); __ movq(tmp_simd, tmp); __ psraw(kScratchDoubleReg, tmp_simd); @@ -3414,6 +3499,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ punpcklbw(dst, dst); // Prepare shift value __ movq(tmp, i.InputRegister(1)); + // Take shift value modulo 8. + __ andq(tmp, Immediate(7)); __ addq(tmp, Immediate(8)); __ movq(tmp_simd, tmp); __ psrlw(kScratchDoubleReg, tmp_simd); @@ -3422,7 +3509,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( break; } case kX64I8x16AddSaturateU: { - __ paddusb(i.OutputSimd128Register(), i.InputSimd128Register(1)); + __ Paddusb(i.OutputSimd128Register(), i.InputSimd128Register(1)); break; } case kX64I8x16SubSaturateU: { @@ -3487,10 +3574,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kX64S128Select: { // Mask used here is stored in dst. XMMRegister dst = i.OutputSimd128Register(); - __ movaps(kScratchDoubleReg, i.InputSimd128Register(1)); - __ xorps(kScratchDoubleReg, i.InputSimd128Register(2)); - __ andps(dst, kScratchDoubleReg); - __ xorps(dst, i.InputSimd128Register(2)); + __ Movaps(kScratchDoubleReg, i.InputSimd128Register(1)); + __ Xorps(kScratchDoubleReg, i.InputSimd128Register(2)); + __ Andps(dst, kScratchDoubleReg); + __ Xorps(dst, i.InputSimd128Register(2)); + break; + } + case kX64S8x16Swizzle: { + CpuFeatureScope sse_scope(tasm(), SSSE3); + DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0)); + XMMRegister dst = i.OutputSimd128Register(); + XMMRegister mask = i.TempSimd128Register(0); + + // Out-of-range indices should return 0, add 112 so that any value > 15 + // saturates to 128 (top bit set), so pshufb will zero that lane. + __ Move(mask, static_cast<uint32_t>(0x70707070)); + __ Pshufd(mask, mask, 0x0); + __ Paddusb(mask, i.InputSimd128Register(1)); + __ Pshufb(dst, mask); break; } case kX64S8x16Shuffle: { @@ -3507,10 +3608,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } SetupShuffleMaskOnStack(tasm(), mask); - __ pshufb(dst, Operand(rsp, 0)); + __ Pshufb(dst, Operand(rsp, 0)); } else { // two input operands DCHECK_EQ(6, instr->InputCount()); - ASSEMBLE_SIMD_INSTR(movups, kScratchDoubleReg, 0); + ASSEMBLE_SIMD_INSTR(Movups, kScratchDoubleReg, 0); uint32_t mask[4] = {}; for (int j = 5; j > 1; j--) { uint32_t lanes = i.InputUint32(j); @@ -3520,13 +3621,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } } SetupShuffleMaskOnStack(tasm(), mask); - __ pshufb(kScratchDoubleReg, Operand(rsp, 0)); + __ Pshufb(kScratchDoubleReg, Operand(rsp, 0)); uint32_t mask1[4] = {}; if (instr->InputAt(1)->IsSimd128Register()) { XMMRegister src1 = i.InputSimd128Register(1); if (src1 != dst) __ movups(dst, src1); } else { - __ movups(dst, i.InputOperand(1)); + __ Movups(dst, i.InputOperand(1)); } for (int j = 5; j > 1; j--) { uint32_t lanes = i.InputUint32(j); @@ -3536,8 +3637,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } } SetupShuffleMaskOnStack(tasm(), mask1); - __ pshufb(dst, Operand(rsp, 0)); - __ por(dst, kScratchDoubleReg); + __ Pshufb(dst, Operand(rsp, 0)); + __ Por(dst, kScratchDoubleReg); } __ movq(rsp, tmp); break; diff --git a/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h b/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h index 8a0a45a916afc6..e390c6922c8001 100644 --- a/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h +++ b/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h @@ -160,6 +160,7 @@ namespace compiler { V(X64F64x2ReplaceLane) \ V(X64F64x2Abs) \ V(X64F64x2Neg) \ + V(X64F64x2Sqrt) \ V(X64F64x2Add) \ V(X64F64x2Sub) \ V(X64F64x2Mul) \ @@ -170,6 +171,8 @@ namespace compiler { V(X64F64x2Ne) \ V(X64F64x2Lt) \ V(X64F64x2Le) \ + V(X64F64x2Qfma) \ + V(X64F64x2Qfms) \ V(X64F32x4Splat) \ V(X64F32x4ExtractLane) \ V(X64F32x4ReplaceLane) \ @@ -177,6 +180,7 @@ namespace compiler { V(X64F32x4UConvertI32x4) \ V(X64F32x4Abs) \ V(X64F32x4Neg) \ + V(X64F32x4Sqrt) \ V(X64F32x4RecipApprox) \ V(X64F32x4RecipSqrtApprox) \ V(X64F32x4Add) \ @@ -190,6 +194,8 @@ namespace compiler { V(X64F32x4Ne) \ V(X64F32x4Lt) \ V(X64F32x4Le) \ + V(X64F32x4Qfma) \ + V(X64F32x4Qfms) \ V(X64I64x2Splat) \ V(X64I64x2ExtractLane) \ V(X64I64x2ReplaceLane) \ @@ -300,6 +306,7 @@ namespace compiler { V(X64S128Or) \ V(X64S128Xor) \ V(X64S128Select) \ + V(X64S8x16Swizzle) \ V(X64S8x16Shuffle) \ V(X64S32x4Swizzle) \ V(X64S32x4Shuffle) \ diff --git a/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc b/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc index e9fa450c3820e7..28a935fd9164fe 100644 --- a/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc +++ b/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc @@ -129,6 +129,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kX64F64x2ReplaceLane: case kX64F64x2Abs: case kX64F64x2Neg: + case kX64F64x2Sqrt: case kX64F64x2Add: case kX64F64x2Sub: case kX64F64x2Mul: @@ -139,6 +140,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kX64F64x2Ne: case kX64F64x2Lt: case kX64F64x2Le: + case kX64F64x2Qfma: + case kX64F64x2Qfms: case kX64F32x4Splat: case kX64F32x4ExtractLane: case kX64F32x4ReplaceLane: @@ -148,6 +151,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kX64F32x4RecipSqrtApprox: case kX64F32x4Abs: case kX64F32x4Neg: + case kX64F32x4Sqrt: case kX64F32x4Add: case kX64F32x4AddHoriz: case kX64F32x4Sub: @@ -159,6 +163,8 @@ int InstructionScheduler::GetTargetInstructionFlags( case kX64F32x4Ne: case kX64F32x4Lt: case kX64F32x4Le: + case kX64F32x4Qfma: + case kX64F32x4Qfms: case kX64I64x2Splat: case kX64I64x2ExtractLane: case kX64I64x2ReplaceLane: @@ -275,6 +281,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kX64S1x4AllTrue: case kX64S1x8AnyTrue: case kX64S1x8AllTrue: + case kX64S8x16Swizzle: case kX64S8x16Shuffle: case kX64S32x4Swizzle: case kX64S32x4Shuffle: diff --git a/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc b/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc index 5379074bac8666..f5d05fdd85a384 100644 --- a/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc +++ b/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc @@ -4,7 +4,7 @@ #include <algorithm> -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/base/overflowing-math.h" #include "src/compiler/backend/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" @@ -250,9 +250,21 @@ ArchOpcode GetLoadOpcode(LoadRepresentation load_rep) { #else UNREACHABLE(); #endif +#ifdef V8_COMPRESS_POINTERS + case MachineRepresentation::kTaggedSigned: + opcode = kX64MovqDecompressTaggedSigned; + break; + case MachineRepresentation::kTaggedPointer: + opcode = kX64MovqDecompressTaggedPointer; + break; + case MachineRepresentation::kTagged: + opcode = kX64MovqDecompressAnyTagged; + break; +#else case MachineRepresentation::kTaggedSigned: // Fall through. case MachineRepresentation::kTaggedPointer: // Fall through. case MachineRepresentation::kTagged: // Fall through. +#endif case MachineRepresentation::kWord64: opcode = kX64Movq; break; @@ -288,7 +300,8 @@ ArchOpcode GetStoreOpcode(StoreRepresentation store_rep) { #endif case MachineRepresentation::kTaggedSigned: // Fall through. case MachineRepresentation::kTaggedPointer: // Fall through. - case MachineRepresentation::kTagged: // Fall through. + case MachineRepresentation::kTagged: + return kX64MovqCompressTagged; case MachineRepresentation::kWord64: return kX64Movq; case MachineRepresentation::kSimd128: // Fall through. @@ -875,6 +888,10 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) { Emit(kX64Bswap32, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0))); } +void InstructionSelector::VisitSimd128ReverseBytes(Node* node) { + UNREACHABLE(); +} + void InstructionSelector::VisitInt32Add(Node* node) { X64OperandGenerator g(this); @@ -1843,17 +1860,15 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, node->op()->HasProperty(Operator::kCommutative)); } -// Shared routine for 64-bit word comparison operations. -void VisitWord64Compare(InstructionSelector* selector, Node* node, - FlagsContinuation* cont) { - X64OperandGenerator g(selector); +void VisitWord64EqualImpl(InstructionSelector* selector, Node* node, + FlagsContinuation* cont) { if (selector->CanUseRootsRegister()) { + X64OperandGenerator g(selector); const RootsTable& roots_table = selector->isolate()->roots_table(); RootIndex root_index; HeapObjectBinopMatcher m(node); if (m.right().HasValue() && roots_table.IsRootHandle(m.right().Value(), &root_index)) { - if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute(); InstructionCode opcode = kX64Cmp | AddressingModeField::encode(kMode_Root); return VisitCompare( @@ -1861,18 +1876,30 @@ void VisitWord64Compare(InstructionSelector* selector, Node* node, g.TempImmediate( TurboAssemblerBase::RootRegisterOffsetForRootIndex(root_index)), g.UseRegister(m.left().node()), cont); - } else if (m.left().HasValue() && - roots_table.IsRootHandle(m.left().Value(), &root_index)) { + } + } + VisitWordCompare(selector, node, kX64Cmp, cont); +} + +void VisitWord32EqualImpl(InstructionSelector* selector, Node* node, + FlagsContinuation* cont) { + if (COMPRESS_POINTERS_BOOL && selector->CanUseRootsRegister()) { + X64OperandGenerator g(selector); + const RootsTable& roots_table = selector->isolate()->roots_table(); + RootIndex root_index; + CompressedHeapObjectBinopMatcher m(node); + if (m.right().HasValue() && + roots_table.IsRootHandle(m.right().Value(), &root_index)) { InstructionCode opcode = - kX64Cmp | AddressingModeField::encode(kMode_Root); + kX64Cmp32 | AddressingModeField::encode(kMode_Root); return VisitCompare( selector, opcode, g.TempImmediate( TurboAssemblerBase::RootRegisterOffsetForRootIndex(root_index)), - g.UseRegister(m.right().node()), cont); + g.UseRegister(m.left().node()), cont); } } - VisitWordCompare(selector, node, kX64Cmp, cont); + VisitWordCompare(selector, node, kX64Cmp32, cont); } // Shared routine for comparison with zero. @@ -2048,7 +2075,7 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, switch (value->opcode()) { case IrOpcode::kWord32Equal: cont->OverwriteAndNegateIfEqual(kEqual); - return VisitWordCompare(this, value, kX64Cmp32, cont); + return VisitWord32EqualImpl(this, value, cont); case IrOpcode::kInt32LessThan: cont->OverwriteAndNegateIfEqual(kSignedLessThan); return VisitWordCompare(this, value, kX64Cmp32, cont); @@ -2071,7 +2098,7 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, if (CanCover(user, value)) { switch (value->opcode()) { case IrOpcode::kInt64Sub: - return VisitWord64Compare(this, value, cont); + return VisitWordCompare(this, value, kX64Cmp, cont); case IrOpcode::kWord64And: return VisitWordCompare(this, value, kX64Test, cont); default: @@ -2080,20 +2107,20 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, } return VisitCompareZero(this, user, value, kX64Cmp, cont); } - return VisitWord64Compare(this, value, cont); + return VisitWord64EqualImpl(this, value, cont); } case IrOpcode::kInt64LessThan: cont->OverwriteAndNegateIfEqual(kSignedLessThan); - return VisitWord64Compare(this, value, cont); + return VisitWordCompare(this, value, kX64Cmp, cont); case IrOpcode::kInt64LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); - return VisitWord64Compare(this, value, cont); + return VisitWordCompare(this, value, kX64Cmp, cont); case IrOpcode::kUint64LessThan: cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitWord64Compare(this, value, cont); + return VisitWordCompare(this, value, kX64Cmp, cont); case IrOpcode::kUint64LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitWord64Compare(this, value, cont); + return VisitWordCompare(this, value, kX64Cmp, cont); case IrOpcode::kFloat32Equal: cont->OverwriteAndNegateIfEqual(kUnorderedEqual); return VisitFloat32Compare(this, value, cont); @@ -2221,7 +2248,7 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { if (m.right().Is(0)) { return VisitWordCompareZero(m.node(), m.left().node(), &cont); } - VisitWordCompare(this, node, kX64Cmp32, &cont); + VisitWord32EqualImpl(this, node, &cont); } void InstructionSelector::VisitInt32LessThan(Node* node) { @@ -2246,7 +2273,7 @@ void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { VisitWordCompare(this, node, kX64Cmp32, &cont); } -void InstructionSelector::VisitWord64Equal(Node* const node) { +void InstructionSelector::VisitWord64Equal(Node* node) { FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); Int64BinopMatcher m(node); if (m.right().Is(0)) { @@ -2256,7 +2283,7 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { if (CanCover(user, value)) { switch (value->opcode()) { case IrOpcode::kInt64Sub: - return VisitWord64Compare(this, value, &cont); + return VisitWordCompare(this, value, kX64Cmp, &cont); case IrOpcode::kWord64And: return VisitWordCompare(this, value, kX64Test, &cont); default: @@ -2264,7 +2291,7 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { } } } - VisitWord64Compare(this, node, &cont); + VisitWord64EqualImpl(this, node, &cont); } void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { @@ -2287,24 +2314,24 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { void InstructionSelector::VisitInt64LessThan(Node* node) { FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); - VisitWord64Compare(this, node, &cont); + VisitWordCompare(this, node, kX64Cmp, &cont); } void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); - VisitWord64Compare(this, node, &cont); + VisitWordCompare(this, node, kX64Cmp, &cont); } void InstructionSelector::VisitUint64LessThan(Node* node) { FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); - VisitWord64Compare(this, node, &cont); + VisitWordCompare(this, node, kX64Cmp, &cont); } void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); - VisitWord64Compare(this, node, &cont); + VisitWordCompare(this, node, kX64Cmp, &cont); } void InstructionSelector::VisitFloat32Equal(Node* node) { @@ -2685,9 +2712,11 @@ VISIT_ATOMIC_BINOP(Xor) V(I8x16GtU) #define SIMD_UNOP_LIST(V) \ + V(F64x2Sqrt) \ V(F32x4SConvertI32x4) \ V(F32x4Abs) \ V(F32x4Neg) \ + V(F32x4Sqrt) \ V(F32x4RecipApprox) \ V(F32x4RecipSqrtApprox) \ V(I64x2Neg) \ @@ -2872,6 +2901,27 @@ void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) { g.UseRegister(node->InputAt(0))); } +#define VISIT_SIMD_QFMOP(Opcode) \ + void InstructionSelector::Visit##Opcode(Node* node) { \ + X64OperandGenerator g(this); \ + if (CpuFeatures::IsSupported(FMA3)) { \ + Emit(kX64##Opcode, g.DefineSameAsFirst(node), \ + g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), \ + g.UseRegister(node->InputAt(2))); \ + } else { \ + InstructionOperand temps[] = {g.TempSimd128Register()}; \ + Emit(kX64##Opcode, g.DefineSameAsFirst(node), \ + g.UseUniqueRegister(node->InputAt(0)), \ + g.UseUniqueRegister(node->InputAt(1)), \ + g.UseRegister(node->InputAt(2)), arraysize(temps), temps); \ + } \ + } +VISIT_SIMD_QFMOP(F64x2Qfma) +VISIT_SIMD_QFMOP(F64x2Qfms) +VISIT_SIMD_QFMOP(F32x4Qfma) +VISIT_SIMD_QFMOP(F32x4Qfms) +#undef VISIT_SIMD_QFMOP + void InstructionSelector::VisitI64x2ShrS(Node* node) { X64OperandGenerator g(this); InstructionOperand temps[] = {g.TempRegister()}; @@ -2893,10 +2943,10 @@ void InstructionSelector::VisitI64x2Mul(Node* node) { void InstructionSelector::VisitI64x2MinS(Node* node) { X64OperandGenerator g(this); if (this->IsSupported(SSE4_2)) { - InstructionOperand temps[] = {g.TempSimd128Register()}; - Emit(kX64I64x2MinS, g.DefineSameAsFirst(node), - g.UseRegister(node->InputAt(0)), g.UseFixed(node->InputAt(1), xmm0), - arraysize(temps), temps); + InstructionOperand temps[] = {g.TempFpRegister(xmm0)}; + Emit(kX64I64x2MinS, g.DefineAsRegister(node), + g.UseUniqueRegister(node->InputAt(0)), + g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); } else { InstructionOperand temps[] = {g.TempSimd128Register(), g.TempRegister(), g.TempRegister()}; @@ -2908,27 +2958,27 @@ void InstructionSelector::VisitI64x2MinS(Node* node) { void InstructionSelector::VisitI64x2MaxS(Node* node) { X64OperandGenerator g(this); - InstructionOperand temps[] = {g.TempSimd128Register()}; + InstructionOperand temps[] = {g.TempFpRegister(xmm0)}; Emit(kX64I64x2MaxS, g.DefineSameAsFirst(node), - g.UseRegister(node->InputAt(0)), g.UseFixed(node->InputAt(1), xmm0), + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); } void InstructionSelector::VisitI64x2MinU(Node* node) { X64OperandGenerator g(this); InstructionOperand temps[] = {g.TempSimd128Register(), - g.TempSimd128Register()}; - Emit(kX64I64x2MinU, g.DefineSameAsFirst(node), - g.UseRegister(node->InputAt(0)), g.UseFixed(node->InputAt(1), xmm0), - arraysize(temps), temps); + g.TempFpRegister(xmm0)}; + Emit(kX64I64x2MinU, g.DefineAsRegister(node), + g.UseUniqueRegister(node->InputAt(0)), + g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); } void InstructionSelector::VisitI64x2MaxU(Node* node) { X64OperandGenerator g(this); InstructionOperand temps[] = {g.TempSimd128Register(), - g.TempSimd128Register()}; + g.TempFpRegister(xmm0)}; Emit(kX64I64x2MaxU, g.DefineSameAsFirst(node), - g.UseRegister(node->InputAt(0)), g.UseFixed(node->InputAt(1), xmm0), + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); } @@ -3256,6 +3306,14 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) { Emit(opcode, 1, &dst, input_count, inputs, temp_count, temps); } +void InstructionSelector::VisitS8x16Swizzle(Node* node) { + X64OperandGenerator g(this); + InstructionOperand temps[] = {g.TempSimd128Register()}; + Emit(kX64S8x16Swizzle, g.DefineSameAsFirst(node), + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), + arraysize(temps), temps); +} + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { diff --git a/deps/v8/src/compiler/bytecode-graph-builder.cc b/deps/v8/src/compiler/bytecode-graph-builder.cc index b1051be5719e8b..17472a305dc1be 100644 --- a/deps/v8/src/compiler/bytecode-graph-builder.cc +++ b/deps/v8/src/compiler/bytecode-graph-builder.cc @@ -24,7 +24,7 @@ #include "src/objects/literal-objects-inl.h" #include "src/objects/objects-inl.h" #include "src/objects/smi.h" -#include "src/objects/template-objects-inl.h" +#include "src/objects/template-objects.h" namespace v8 { namespace internal { @@ -215,6 +215,9 @@ class BytecodeGraphBuilder { FeedbackSlot slot); JSTypeHintLowering::LoweringResult TryBuildSimplifiedConstruct( const Operator* op, Node* const* args, int arg_count, FeedbackSlot slot); + JSTypeHintLowering::LoweringResult TryBuildSimplifiedGetIterator( + const Operator* op, Node* receiver, FeedbackSlot load_slot, + FeedbackSlot call_slot); JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadNamed( const Operator* op, Node* receiver, FeedbackSlot slot); JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadKeyed( @@ -945,7 +948,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( bytecode_array().parameter_count(), bytecode_array().register_count(), shared_info.object())), bytecode_iterator_( - base::make_unique<OffHeapBytecodeArray>(bytecode_array())), + std::make_unique<OffHeapBytecodeArray>(bytecode_array())), bytecode_analysis_(broker_->GetBytecodeAnalysis( bytecode_array().object(), osr_offset, flags & BytecodeGraphBuilderFlag::kAnalyzeEnvironmentLiveness, @@ -971,12 +974,12 @@ BytecodeGraphBuilder::BytecodeGraphBuilder( if (FLAG_concurrent_inlining) { // With concurrent inlining on, the source position address doesn't change // because it's been copied from the heap. - source_position_iterator_ = base::make_unique<SourcePositionTableIterator>( + source_position_iterator_ = std::make_unique<SourcePositionTableIterator>( Vector<const byte>(bytecode_array().source_positions_address(), bytecode_array().source_positions_size())); } else { // Otherwise, we need to access the table through a handle. - source_position_iterator_ = base::make_unique<SourcePositionTableIterator>( + source_position_iterator_ = std::make_unique<SourcePositionTableIterator>( handle(bytecode_array().object()->SourcePositionTableIfCollected(), isolate())); } @@ -2087,12 +2090,13 @@ void BytecodeGraphBuilder::VisitCloneObject() { void BytecodeGraphBuilder::VisitGetTemplateObject() { DisallowHeapAccessIf no_heap_access(FLAG_concurrent_inlining); - FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1); - ObjectRef description( + FeedbackSource source = + CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1)); + TemplateObjectDescriptionRef description( broker(), bytecode_iterator().GetConstantForIndexOperand(0, isolate())); - JSArrayRef template_object = - shared_info().GetTemplateObject(description, feedback_vector(), slot); - environment()->BindAccumulator(jsgraph()->Constant(template_object)); + Node* template_object = NewNode(javascript()->GetTemplateObject( + description.object(), shared_info().object(), source)); + environment()->BindAccumulator(template_object); } Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters( @@ -3297,19 +3301,21 @@ void BytecodeGraphBuilder::VisitForInStep() { void BytecodeGraphBuilder::VisitGetIterator() { PrepareEagerCheckpoint(); - Node* object = + Node* receiver = environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - FeedbackSource feedback = + FeedbackSource load_feedback = CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1)); - const Operator* op = javascript()->GetIterator(feedback); + FeedbackSource call_feedback = + CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2)); + const Operator* op = javascript()->GetIterator(load_feedback, call_feedback); - JSTypeHintLowering::LoweringResult lowering = - TryBuildSimplifiedLoadNamed(op, object, feedback.slot); + JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedGetIterator( + op, receiver, load_feedback.slot, call_feedback.slot); if (lowering.IsExit()) return; DCHECK(!lowering.Changed()); - Node* node = NewNode(op, object); - environment()->BindAccumulator(node, Environment::kAttachFrameState); + Node* iterator = NewNode(op, receiver); + environment()->BindAccumulator(iterator, Environment::kAttachFrameState); } void BytecodeGraphBuilder::VisitSuspendGenerator() { @@ -3775,6 +3781,20 @@ BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op, return result; } +JSTypeHintLowering::LoweringResult +BytecodeGraphBuilder::TryBuildSimplifiedGetIterator(const Operator* op, + Node* receiver, + FeedbackSlot load_slot, + FeedbackSlot call_slot) { + Node* effect = environment()->GetEffectDependency(); + Node* control = environment()->GetControlDependency(); + JSTypeHintLowering::LoweringResult early_reduction = + type_hint_lowering().ReduceGetIteratorOperation( + op, receiver, effect, control, load_slot, call_slot); + ApplyEarlyReduction(early_reduction); + return early_reduction; +} + JSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op, Node* receiver, diff --git a/deps/v8/src/compiler/c-linkage.cc b/deps/v8/src/compiler/c-linkage.cc index 428ba058a7f904..4c576b771acdc0 100644 --- a/deps/v8/src/compiler/c-linkage.cc +++ b/deps/v8/src/compiler/c-linkage.cc @@ -27,7 +27,7 @@ namespace { // == x64 ==================================================================== // =========================================================================== -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // == x64 windows ============================================================ #define STACK_SHADOW_WORDS 4 #define PARAM_REGISTERS rcx, rdx, r8, r9 @@ -39,12 +39,12 @@ namespace { (1 << xmm9.code()) | (1 << xmm10.code()) | (1 << xmm11.code()) | \ (1 << xmm12.code()) | (1 << xmm13.code()) | (1 << xmm14.code()) | \ (1 << xmm15.code()) -#else +#else // V8_TARGET_OS_WIN // == x64 other ============================================================== #define PARAM_REGISTERS rdi, rsi, rdx, rcx, r8, r9 #define CALLEE_SAVE_REGISTERS \ rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit() -#endif +#endif // V8_TARGET_OS_WIN #elif V8_TARGET_ARCH_ARM // =========================================================================== diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc index 4f1801146315ec..c618daf357ea53 100644 --- a/deps/v8/src/compiler/code-assembler.cc +++ b/deps/v8/src/compiler/code-assembler.cc @@ -29,6 +29,7 @@ namespace internal { constexpr MachineType MachineTypeOf<Smi>::value; constexpr MachineType MachineTypeOf<Object>::value; +constexpr MachineType MachineTypeOf<MaybeObject>::value; namespace compiler { @@ -1349,8 +1350,8 @@ void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor, Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode, const CallInterfaceDescriptor& descriptor, - size_t result_size, Node* target, - SloppyTNode<Object> context, + size_t result_size, TNode<Object> target, + TNode<Object> context, std::initializer_list<Node*> args) { DCHECK(call_mode == StubCallMode::kCallCodeObject || call_mode == StubCallMode::kCallBuiltinPointer); @@ -1369,7 +1370,7 @@ Node* CodeAssembler::CallStubRImpl(StubCallMode call_mode, inputs.data()); } -Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl( +void CodeAssembler::TailCallStubThenBytecodeDispatchImpl( const CallInterfaceDescriptor& descriptor, Node* target, Node* context, std::initializer_list<Node*> args) { constexpr size_t kMaxNumArgs = 6; @@ -1389,33 +1390,33 @@ Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl( for (auto arg : args) inputs.Add(arg); inputs.Add(context); - return raw_assembler()->TailCallN(call_descriptor, inputs.size(), - inputs.data()); + raw_assembler()->TailCallN(call_descriptor, inputs.size(), inputs.data()); } template <class... TArgs> -Node* CodeAssembler::TailCallBytecodeDispatch( - const CallInterfaceDescriptor& descriptor, Node* target, TArgs... args) { +void CodeAssembler::TailCallBytecodeDispatch( + const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target, + TArgs... args) { DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(args)); auto call_descriptor = Linkage::GetBytecodeDispatchCallDescriptor( zone(), descriptor, descriptor.GetStackParameterCount()); Node* nodes[] = {target, args...}; CHECK_EQ(descriptor.GetParameterCount() + 1, arraysize(nodes)); - return raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes); + raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes); } // Instantiate TailCallBytecodeDispatch() for argument counts used by // CSA-generated code -template V8_EXPORT_PRIVATE Node* CodeAssembler::TailCallBytecodeDispatch( - const CallInterfaceDescriptor& descriptor, Node* target, Node*, Node*, - Node*, Node*); - -TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code, - TNode<Context> context, - TNode<JSFunction> function, - TNode<Object> new_target, - TNode<Int32T> arg_count) { +template V8_EXPORT_PRIVATE void CodeAssembler::TailCallBytecodeDispatch( + const CallInterfaceDescriptor& descriptor, TNode<RawPtrT> target, + TNode<Object>, TNode<IntPtrT>, TNode<BytecodeArray>, + TNode<ExternalReference>); + +void CodeAssembler::TailCallJSCode(TNode<Code> code, TNode<Context> context, + TNode<JSFunction> function, + TNode<Object> new_target, + TNode<Int32T> arg_count) { JSTrampolineDescriptor descriptor; auto call_descriptor = Linkage::GetStubCallDescriptor( zone(), descriptor, descriptor.GetStackParameterCount(), @@ -1423,8 +1424,7 @@ TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code, Node* nodes[] = {code, function, new_target, arg_count, context}; CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes)); - return UncheckedCast<Object>( - raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes)); + raw_assembler()->TailCallN(call_descriptor, arraysize(nodes), nodes); } Node* CodeAssembler::CallCFunctionN(Signature<MachineType>* signature, @@ -1439,6 +1439,13 @@ Node* CodeAssembler::CallCFunction( return raw_assembler()->CallCFunction(function, return_type, args); } +Node* CodeAssembler::CallCFunctionWithoutFunctionDescriptor( + Node* function, MachineType return_type, + std::initializer_list<CodeAssembler::CFunctionArg> args) { + return raw_assembler()->CallCFunctionWithoutFunctionDescriptor( + function, return_type, args); +} + Node* CodeAssembler::CallCFunctionWithCallerSavedRegisters( Node* function, MachineType return_type, SaveFPRegsMode mode, std::initializer_list<CodeAssembler::CFunctionArg> args) { @@ -1914,7 +1921,7 @@ CodeAssemblerScopedExceptionHandler::CodeAssemblerScopedExceptionHandler( compatibility_label_(label), exception_(exception) { if (has_handler_) { - label_ = base::make_unique<CodeAssemblerExceptionHandlerLabel>( + label_ = std::make_unique<CodeAssemblerExceptionHandlerLabel>( assembler, CodeAssemblerLabel::kDeferred); assembler_->state()->PushExceptionHandler(label_.get()); } diff --git a/deps/v8/src/compiler/code-assembler.h b/deps/v8/src/compiler/code-assembler.h index c9adb1601db1eb..8d5b8602854468 100644 --- a/deps/v8/src/compiler/code-assembler.h +++ b/deps/v8/src/compiler/code-assembler.h @@ -17,6 +17,7 @@ #include "src/codegen/code-factory.h" #include "src/codegen/machine-type.h" #include "src/codegen/source-position.h" +#include "src/codegen/tnode.h" #include "src/heap/heap.h" #include "src/objects/arguments.h" #include "src/objects/data-handler.h" @@ -79,210 +80,6 @@ TORQUE_STRUCT_LIST_GENERATOR(MAKE_FORWARD_DECLARATION, UNUSED) template <typename T> class Signature; -struct UntaggedT {}; - -struct IntegralT : UntaggedT {}; - -struct WordT : IntegralT { - static const MachineRepresentation kMachineRepresentation = - (kSystemPointerSize == 4) ? MachineRepresentation::kWord32 - : MachineRepresentation::kWord64; -}; - -struct RawPtrT : WordT { - static constexpr MachineType kMachineType = MachineType::Pointer(); -}; - -template <class To> -struct RawPtr : RawPtrT {}; - -struct Word32T : IntegralT { - static const MachineRepresentation kMachineRepresentation = - MachineRepresentation::kWord32; -}; -struct Int32T : Word32T { - static constexpr MachineType kMachineType = MachineType::Int32(); -}; -struct Uint32T : Word32T { - static constexpr MachineType kMachineType = MachineType::Uint32(); -}; -struct Int16T : Int32T { - static constexpr MachineType kMachineType = MachineType::Int16(); -}; -struct Uint16T : Uint32T, Int32T { - static constexpr MachineType kMachineType = MachineType::Uint16(); -}; -struct Int8T : Int16T { - static constexpr MachineType kMachineType = MachineType::Int8(); -}; -struct Uint8T : Uint16T, Int16T { - static constexpr MachineType kMachineType = MachineType::Uint8(); -}; - -struct Word64T : IntegralT { - static const MachineRepresentation kMachineRepresentation = - MachineRepresentation::kWord64; -}; -struct Int64T : Word64T { - static constexpr MachineType kMachineType = MachineType::Int64(); -}; -struct Uint64T : Word64T { - static constexpr MachineType kMachineType = MachineType::Uint64(); -}; - -struct IntPtrT : WordT { - static constexpr MachineType kMachineType = MachineType::IntPtr(); -}; -struct UintPtrT : WordT { - static constexpr MachineType kMachineType = MachineType::UintPtr(); -}; - -struct Float32T : UntaggedT { - static const MachineRepresentation kMachineRepresentation = - MachineRepresentation::kFloat32; - static constexpr MachineType kMachineType = MachineType::Float32(); -}; - -struct Float64T : UntaggedT { - static const MachineRepresentation kMachineRepresentation = - MachineRepresentation::kFloat64; - static constexpr MachineType kMachineType = MachineType::Float64(); -}; - -#ifdef V8_COMPRESS_POINTERS -using TaggedT = Int32T; -#else -using TaggedT = IntPtrT; -#endif - -// Result of a comparison operation. -struct BoolT : Word32T {}; - -// Value type of a Turbofan node with two results. -template <class T1, class T2> -struct PairT {}; - -inline constexpr MachineType CommonMachineType(MachineType type1, - MachineType type2) { - return (type1 == type2) ? type1 - : ((type1.IsTagged() && type2.IsTagged()) - ? MachineType::AnyTagged() - : MachineType::None()); -} - -template <class Type, class Enable = void> -struct MachineTypeOf { - static constexpr MachineType value = Type::kMachineType; -}; - -template <class Type, class Enable> -constexpr MachineType MachineTypeOf<Type, Enable>::value; - -template <> -struct MachineTypeOf<Object> { - static constexpr MachineType value = MachineType::AnyTagged(); -}; -template <> -struct MachineTypeOf<MaybeObject> { - static constexpr MachineType value = MachineType::AnyTagged(); -}; -template <> -struct MachineTypeOf<Smi> { - static constexpr MachineType value = MachineType::TaggedSigned(); -}; -template <class HeapObjectSubtype> -struct MachineTypeOf<HeapObjectSubtype, - typename std::enable_if<std::is_base_of< - HeapObject, HeapObjectSubtype>::value>::type> { - static constexpr MachineType value = MachineType::TaggedPointer(); -}; - -template <class HeapObjectSubtype> -constexpr MachineType MachineTypeOf< - HeapObjectSubtype, typename std::enable_if<std::is_base_of< - HeapObject, HeapObjectSubtype>::value>::type>::value; - -template <class Type, class Enable = void> -struct MachineRepresentationOf { - static const MachineRepresentation value = Type::kMachineRepresentation; -}; -template <class T> -struct MachineRepresentationOf< - T, typename std::enable_if<std::is_base_of<Object, T>::value>::type> { - static const MachineRepresentation value = - MachineTypeOf<T>::value.representation(); -}; -template <class T> -struct MachineRepresentationOf< - T, typename std::enable_if<std::is_base_of<MaybeObject, T>::value>::type> { - static const MachineRepresentation value = - MachineTypeOf<T>::value.representation(); -}; - -template <class T> -struct is_valid_type_tag { - static const bool value = std::is_base_of<Object, T>::value || - std::is_base_of<UntaggedT, T>::value || - std::is_base_of<MaybeObject, T>::value || - std::is_same<ExternalReference, T>::value; - static const bool is_tagged = std::is_base_of<Object, T>::value || - std::is_base_of<MaybeObject, T>::value; -}; - -template <class T1, class T2> -struct is_valid_type_tag<PairT<T1, T2>> { - static const bool value = - is_valid_type_tag<T1>::value && is_valid_type_tag<T2>::value; - static const bool is_tagged = false; -}; - -template <class T1, class T2> -struct UnionT; - -template <class T1, class T2> -struct is_valid_type_tag<UnionT<T1, T2>> { - static const bool is_tagged = - is_valid_type_tag<T1>::is_tagged && is_valid_type_tag<T2>::is_tagged; - static const bool value = is_tagged; -}; - -template <class T1, class T2> -struct UnionT { - static constexpr MachineType kMachineType = - CommonMachineType(MachineTypeOf<T1>::value, MachineTypeOf<T2>::value); - static const MachineRepresentation kMachineRepresentation = - kMachineType.representation(); - static_assert(kMachineRepresentation != MachineRepresentation::kNone, - "no common representation"); - static_assert(is_valid_type_tag<T1>::is_tagged && - is_valid_type_tag<T2>::is_tagged, - "union types are only possible for tagged values"); -}; - -using Number = UnionT<Smi, HeapNumber>; -using Numeric = UnionT<Number, BigInt>; - -// A pointer to a builtin function, used by Torque's function pointers. -using BuiltinPtr = Smi; - -class int31_t { - public: - int31_t() : value_(0) {} - int31_t(int value) : value_(value) { // NOLINT(runtime/explicit) - DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0); - } - int31_t& operator=(int value) { - DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0); - value_ = value; - return *this; - } - int32_t value() const { return value_; } - operator int32_t() const { return value_; } - - private: - int32_t value_; -}; - #define ENUM_ELEMENT(Name) k##Name, #define ENUM_STRUCT_ELEMENT(NAME, Name, name) k##Name, enum class ObjectType { @@ -334,6 +131,7 @@ class Undetectable; class UniqueName; class WasmCapiFunctionData; class WasmExceptionObject; +class WasmExceptionPackage; class WasmExceptionTag; class WasmExportedFunctionData; class WasmGlobalObject; @@ -396,143 +194,6 @@ using CodeAssemblerVariableList = ZoneVector<CodeAssemblerVariable*>; using CodeAssemblerCallback = std::function<void()>; -template <class T, class U> -struct is_subtype { - static const bool value = std::is_base_of<U, T>::value; -}; -template <class T1, class T2, class U> -struct is_subtype<UnionT<T1, T2>, U> { - static const bool value = - is_subtype<T1, U>::value && is_subtype<T2, U>::value; -}; -template <class T, class U1, class U2> -struct is_subtype<T, UnionT<U1, U2>> { - static const bool value = - is_subtype<T, U1>::value || is_subtype<T, U2>::value; -}; -template <class T1, class T2, class U1, class U2> -struct is_subtype<UnionT<T1, T2>, UnionT<U1, U2>> { - static const bool value = - (is_subtype<T1, U1>::value || is_subtype<T1, U2>::value) && - (is_subtype<T2, U1>::value || is_subtype<T2, U2>::value); -}; - -template <class T, class U> -struct types_have_common_values { - static const bool value = is_subtype<T, U>::value || is_subtype<U, T>::value; -}; -template <class U> -struct types_have_common_values<BoolT, U> { - static const bool value = types_have_common_values<Word32T, U>::value; -}; -template <class U> -struct types_have_common_values<Uint32T, U> { - static const bool value = types_have_common_values<Word32T, U>::value; -}; -template <class U> -struct types_have_common_values<Int32T, U> { - static const bool value = types_have_common_values<Word32T, U>::value; -}; -template <class U> -struct types_have_common_values<Uint64T, U> { - static const bool value = types_have_common_values<Word64T, U>::value; -}; -template <class U> -struct types_have_common_values<Int64T, U> { - static const bool value = types_have_common_values<Word64T, U>::value; -}; -template <class U> -struct types_have_common_values<IntPtrT, U> { - static const bool value = types_have_common_values<WordT, U>::value; -}; -template <class U> -struct types_have_common_values<UintPtrT, U> { - static const bool value = types_have_common_values<WordT, U>::value; -}; -template <class T1, class T2, class U> -struct types_have_common_values<UnionT<T1, T2>, U> { - static const bool value = types_have_common_values<T1, U>::value || - types_have_common_values<T2, U>::value; -}; - -template <class T, class U1, class U2> -struct types_have_common_values<T, UnionT<U1, U2>> { - static const bool value = types_have_common_values<T, U1>::value || - types_have_common_values<T, U2>::value; -}; -template <class T1, class T2, class U1, class U2> -struct types_have_common_values<UnionT<T1, T2>, UnionT<U1, U2>> { - static const bool value = types_have_common_values<T1, U1>::value || - types_have_common_values<T1, U2>::value || - types_have_common_values<T2, U1>::value || - types_have_common_values<T2, U2>::value; -}; - -template <class T> -struct types_have_common_values<T, MaybeObject> { - static const bool value = types_have_common_values<T, Object>::value; -}; - -template <class T> -struct types_have_common_values<MaybeObject, T> { - static const bool value = types_have_common_values<Object, T>::value; -}; - -// TNode<T> is an SSA value with the static type tag T, which is one of the -// following: -// - a subclass of internal::Object represents a tagged type -// - a subclass of internal::UntaggedT represents an untagged type -// - ExternalReference -// - PairT<T1, T2> for an operation returning two values, with types T1 -// and T2 -// - UnionT<T1, T2> represents either a value of type T1 or of type T2. -template <class T> -class TNode { - public: - template <class U, - typename std::enable_if<is_subtype<U, T>::value, int>::type = 0> - TNode(const TNode<U>& other) : node_(other) { - LazyTemplateChecks(); - } - TNode() : TNode(nullptr) {} - - TNode operator=(TNode other) { - DCHECK_NOT_NULL(other.node_); - node_ = other.node_; - return *this; - } - - operator compiler::Node*() const { return node_; } - - static TNode UncheckedCast(compiler::Node* node) { return TNode(node); } - - protected: - explicit TNode(compiler::Node* node) : node_(node) { LazyTemplateChecks(); } - - private: - // These checks shouldn't be checked before TNode is actually used. - void LazyTemplateChecks() { - static_assert(is_valid_type_tag<T>::value, "invalid type tag"); - } - - compiler::Node* node_; -}; - -// SloppyTNode<T> is a variant of TNode<T> and allows implicit casts from -// Node*. It is intended for function arguments as long as some call sites -// still use untyped Node* arguments. -// TODO(tebbi): Delete this class once transition is finished. -template <class T> -class SloppyTNode : public TNode<T> { - public: - SloppyTNode(compiler::Node* node) // NOLINT(runtime/explicit) - : TNode<T>(node) {} - template <class U, typename std::enable_if<is_subtype<U, T>::value, - int>::type = 0> - SloppyTNode(const TNode<U>& other) // NOLINT(runtime/explicit) - : TNode<T>(other) {} -}; - template <class... Types> class CodeAssemblerParameterizedLabel; @@ -627,7 +288,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b); V(Float64ExtractLowWord32, Uint32T, Float64T) \ V(Float64ExtractHighWord32, Uint32T, Float64T) \ V(BitcastTaggedToWord, IntPtrT, Object) \ - V(BitcastTaggedSignedToWord, IntPtrT, Smi) \ + V(BitcastTaggedToWordForTagAndSmiBits, IntPtrT, AnyTaggedT) \ V(BitcastMaybeObjectToWord, IntPtrT, MaybeObject) \ V(BitcastWordToTagged, Object, WordT) \ V(BitcastWordToTaggedSigned, Smi, WordT) \ @@ -641,6 +302,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b); V(ChangeInt32ToInt64, Int64T, Int32T) \ V(ChangeUint32ToFloat64, Float64T, Word32T) \ V(ChangeUint32ToUint64, Uint64T, Word32T) \ + V(ChangeTaggedToCompressed, TaggedT, AnyTaggedT) \ V(BitcastInt32ToFloat32, Float32T, Word32T) \ V(BitcastFloat32ToInt32, Uint32T, Float32T) \ V(RoundFloat64ToInt32, Int32T, Float64T) \ @@ -1187,8 +849,12 @@ class V8_EXPORT_PRIVATE CodeAssembler { TNode<RawPtrT> RawPtrAdd(TNode<RawPtrT> left, TNode<IntPtrT> right) { return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right)); } - TNode<RawPtrT> RawPtrAdd(TNode<IntPtrT> left, TNode<RawPtrT> right) { - return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right)); + TNode<RawPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<IntPtrT> right) { + return ReinterpretCast<RawPtrT>(IntPtrSub(left, right)); + } + TNode<IntPtrT> RawPtrSub(TNode<RawPtrT> left, TNode<RawPtrT> right) { + return Signed( + IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right))); } TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift); @@ -1243,7 +909,7 @@ class V8_EXPORT_PRIVATE CodeAssembler { template <class Dummy = void> TNode<IntPtrT> BitcastTaggedToWord(TNode<Smi> node) { static_assert(sizeof(Dummy) < 0, - "Should use BitcastTaggedSignedToWord instead."); + "Should use BitcastTaggedToWordForTagAndSmiBits instead."); } // Changes a double to an inptr_t for pointer arithmetic outside of Smi range. @@ -1363,26 +1029,26 @@ class V8_EXPORT_PRIVATE CodeAssembler { void TailCallStub(Callable const& callable, SloppyTNode<Object> context, TArgs... args) { TNode<Code> target = HeapConstant(callable.code()); - return TailCallStub(callable.descriptor(), target, context, args...); + TailCallStub(callable.descriptor(), target, context, args...); } template <class... TArgs> void TailCallStub(const CallInterfaceDescriptor& descriptor, SloppyTNode<Code> target, SloppyTNode<Object> context, TArgs... args) { - return TailCallStubImpl(descriptor, target, context, {args...}); + TailCallStubImpl(descriptor, target, context, {args...}); } template <class... TArgs> - Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor, - Node* target, TArgs... args); + void TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor, + TNode<RawPtrT> target, TArgs... args); template <class... TArgs> - Node* TailCallStubThenBytecodeDispatch( + void TailCallStubThenBytecodeDispatch( const CallInterfaceDescriptor& descriptor, Node* target, Node* context, TArgs... args) { - return TailCallStubThenBytecodeDispatchImpl(descriptor, target, context, - {args...}); + TailCallStubThenBytecodeDispatchImpl(descriptor, target, context, + {args...}); } // Tailcalls to the given code object with JSCall linkage. The JS arguments @@ -1392,14 +1058,13 @@ class V8_EXPORT_PRIVATE CodeAssembler { // Note that no arguments adaption is going on here - all the JavaScript // arguments are left on the stack unmodified. Therefore, this tail call can // only be used after arguments adaptation has been performed already. - TNode<Object> TailCallJSCode(TNode<Code> code, TNode<Context> context, - TNode<JSFunction> function, - TNode<Object> new_target, - TNode<Int32T> arg_count); + void TailCallJSCode(TNode<Code> code, TNode<Context> context, + TNode<JSFunction> function, TNode<Object> new_target, + TNode<Int32T> arg_count); template <class... TArgs> - Node* CallJS(Callable const& callable, Node* context, Node* function, - Node* receiver, TArgs... args) { + TNode<Object> CallJS(Callable const& callable, Node* context, Node* function, + Node* receiver, TArgs... args) { int argc = static_cast<int>(sizeof...(args)); TNode<Int32T> arity = Int32Constant(argc); return CallStub(callable, context, function, arity, receiver, args...); @@ -1438,6 +1103,18 @@ class V8_EXPORT_PRIVATE CodeAssembler { return CallCFunction(function, return_type, {cargs...}); } + // Call to a C function without a function discriptor on AIX. + template <class... CArgs> + Node* CallCFunctionWithoutFunctionDescriptor(Node* function, + MachineType return_type, + CArgs... cargs) { + static_assert(v8::internal::conjunction< + std::is_convertible<CArgs, CFunctionArg>...>::value, + "invalid argument types"); + return CallCFunctionWithoutFunctionDescriptor(function, return_type, + {cargs...}); + } + // Call to a C function, while saving/restoring caller registers. template <class... CArgs> Node* CallCFunctionWithCallerSavedRegisters(Node* function, @@ -1486,6 +1163,10 @@ class V8_EXPORT_PRIVATE CodeAssembler { Node* CallCFunction(Node* function, MachineType return_type, std::initializer_list<CFunctionArg> args); + Node* CallCFunctionWithoutFunctionDescriptor( + Node* function, MachineType return_type, + std::initializer_list<CFunctionArg> args); + Node* CallCFunctionWithCallerSavedRegisters( Node* function, MachineType return_type, SaveFPRegsMode mode, std::initializer_list<CFunctionArg> args); @@ -1511,15 +1192,14 @@ class V8_EXPORT_PRIVATE CodeAssembler { TNode<Code> target, TNode<Object> context, std::initializer_list<Node*> args); - Node* TailCallStubThenBytecodeDispatchImpl( + void TailCallStubThenBytecodeDispatchImpl( const CallInterfaceDescriptor& descriptor, Node* target, Node* context, std::initializer_list<Node*> args); Node* CallStubRImpl(StubCallMode call_mode, const CallInterfaceDescriptor& descriptor, - size_t result_size, Node* target, - SloppyTNode<Object> context, - std::initializer_list<Node*> args); + size_t result_size, TNode<Object> target, + TNode<Object> context, std::initializer_list<Node*> args); // These two don't have definitions and are here only for catching use cases // where the cast is not necessary. @@ -1810,7 +1490,7 @@ class V8_EXPORT_PRIVATE CodeAssemblerScopedExceptionHandler { } // namespace compiler -#if defined(V8_HOST_ARCH_32_BIT) || defined(V8_COMPRESS_POINTERS) +#if defined(V8_HOST_ARCH_32_BIT) #define BINT_IS_SMI using BInt = Smi; #elif defined(V8_HOST_ARCH_64_BIT) diff --git a/deps/v8/src/compiler/compilation-dependencies.cc b/deps/v8/src/compiler/compilation-dependencies.cc index 592d85440cc23b..33990dfa480ab0 100644 --- a/deps/v8/src/compiler/compilation-dependencies.cc +++ b/deps/v8/src/compiler/compilation-dependencies.cc @@ -5,6 +5,7 @@ #include "src/compiler/compilation-dependencies.h" #include "src/compiler/compilation-dependency.h" +#include "src/execution/protectors.h" #include "src/handles/handles-inl.h" #include "src/objects/allocation-site-inl.h" #include "src/objects/objects-inl.h" @@ -155,7 +156,7 @@ class FieldRepresentationDependency final : public CompilationDependency { public: // TODO(neis): Once the concurrent compiler frontend is always-on, we no // longer need to explicitly store the representation. - FieldRepresentationDependency(const MapRef& owner, int descriptor, + FieldRepresentationDependency(const MapRef& owner, InternalIndex descriptor, Representation representation) : owner_(owner), descriptor_(descriptor), @@ -180,7 +181,7 @@ class FieldRepresentationDependency final : public CompilationDependency { private: MapRef owner_; - int descriptor_; + InternalIndex descriptor_; Representation representation_; }; @@ -188,7 +189,7 @@ class FieldTypeDependency final : public CompilationDependency { public: // TODO(neis): Once the concurrent compiler frontend is always-on, we no // longer need to explicitly store the type. - FieldTypeDependency(const MapRef& owner, int descriptor, + FieldTypeDependency(const MapRef& owner, InternalIndex descriptor, const ObjectRef& type) : owner_(owner), descriptor_(descriptor), type_(type) { DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_))); @@ -210,13 +211,13 @@ class FieldTypeDependency final : public CompilationDependency { private: MapRef owner_; - int descriptor_; + InternalIndex descriptor_; ObjectRef type_; }; class FieldConstnessDependency final : public CompilationDependency { public: - FieldConstnessDependency(const MapRef& owner, int descriptor) + FieldConstnessDependency(const MapRef& owner, InternalIndex descriptor) : owner_(owner), descriptor_(descriptor) { DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_))); DCHECK_EQ(PropertyConstness::kConst, @@ -238,7 +239,7 @@ class FieldConstnessDependency final : public CompilationDependency { private: MapRef owner_; - int descriptor_; + InternalIndex descriptor_; }; class GlobalPropertyDependency final : public CompilationDependency { @@ -282,12 +283,12 @@ class GlobalPropertyDependency final : public CompilationDependency { class ProtectorDependency final : public CompilationDependency { public: explicit ProtectorDependency(const PropertyCellRef& cell) : cell_(cell) { - DCHECK_EQ(cell_.value().AsSmi(), Isolate::kProtectorValid); + DCHECK_EQ(cell_.value().AsSmi(), Protectors::kProtectorValid); } bool IsValid() const override { Handle<PropertyCell> cell = cell_.object(); - return cell->value() == Smi::FromInt(Isolate::kProtectorValid); + return cell->value() == Smi::FromInt(Protectors::kProtectorValid); } void Install(const MaybeObjectHandle& code) const override { @@ -404,7 +405,7 @@ AllocationType CompilationDependencies::DependOnPretenureMode( } PropertyConstness CompilationDependencies::DependOnFieldConstness( - const MapRef& map, int descriptor) { + const MapRef& map, InternalIndex descriptor) { MapRef owner = map.FindFieldOwner(descriptor); PropertyConstness constness = owner.GetPropertyDetails(descriptor).constness(); @@ -426,13 +427,13 @@ PropertyConstness CompilationDependencies::DependOnFieldConstness( return PropertyConstness::kConst; } -void CompilationDependencies::DependOnFieldRepresentation(const MapRef& map, - int descriptor) { +void CompilationDependencies::DependOnFieldRepresentation( + const MapRef& map, InternalIndex descriptor) { RecordDependency(FieldRepresentationDependencyOffTheRecord(map, descriptor)); } void CompilationDependencies::DependOnFieldType(const MapRef& map, - int descriptor) { + InternalIndex descriptor) { RecordDependency(FieldTypeDependencyOffTheRecord(map, descriptor)); } @@ -444,7 +445,7 @@ void CompilationDependencies::DependOnGlobalProperty( } bool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) { - if (cell.value().AsSmi() != Isolate::kProtectorValid) return false; + if (cell.value().AsSmi() != Protectors::kProtectorValid) return false; RecordDependency(new (zone_) ProtectorDependency(cell)); return true; } @@ -632,7 +633,7 @@ CompilationDependencies::TransitionDependencyOffTheRecord( CompilationDependency const* CompilationDependencies::FieldRepresentationDependencyOffTheRecord( - const MapRef& map, int descriptor) const { + const MapRef& map, InternalIndex descriptor) const { MapRef owner = map.FindFieldOwner(descriptor); PropertyDetails details = owner.GetPropertyDetails(descriptor); DCHECK(details.representation().Equals( @@ -642,8 +643,8 @@ CompilationDependencies::FieldRepresentationDependencyOffTheRecord( } CompilationDependency const* -CompilationDependencies::FieldTypeDependencyOffTheRecord(const MapRef& map, - int descriptor) const { +CompilationDependencies::FieldTypeDependencyOffTheRecord( + const MapRef& map, InternalIndex descriptor) const { MapRef owner = map.FindFieldOwner(descriptor); ObjectRef type = owner.GetFieldType(descriptor); DCHECK(type.equals(map.GetFieldType(descriptor))); diff --git a/deps/v8/src/compiler/compilation-dependencies.h b/deps/v8/src/compiler/compilation-dependencies.h index cb6cea0685f29e..0b1612487ed1dd 100644 --- a/deps/v8/src/compiler/compilation-dependencies.h +++ b/deps/v8/src/compiler/compilation-dependencies.h @@ -55,11 +55,11 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject { // Record the assumption that the field representation of a field does not // change. The field is identified by the arguments. - void DependOnFieldRepresentation(const MapRef& map, int descriptor); + void DependOnFieldRepresentation(const MapRef& map, InternalIndex descriptor); // Record the assumption that the field type of a field does not change. The // field is identified by the arguments. - void DependOnFieldType(const MapRef& map, int descriptor); + void DependOnFieldType(const MapRef& map, InternalIndex descriptor); // Return a field's constness and, if kConst, record the assumption that it // remains kConst. The field is identified by the arguments. @@ -68,7 +68,8 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject { // kConst if the map is stable (and register stability dependency in that // case). This is to ensure that fast elements kind transitions cannot be // used to mutate fields without deoptimization of the dependent code. - PropertyConstness DependOnFieldConstness(const MapRef& map, int descriptor); + PropertyConstness DependOnFieldConstness(const MapRef& map, + InternalIndex descriptor); // Record the assumption that neither {cell}'s {CellType} changes, nor the // {IsReadOnly()} flag of {cell}'s {PropertyDetails}. @@ -119,9 +120,9 @@ class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject { CompilationDependency const* TransitionDependencyOffTheRecord( const MapRef& target_map) const; CompilationDependency const* FieldRepresentationDependencyOffTheRecord( - const MapRef& map, int descriptor) const; + const MapRef& map, InternalIndex descriptor) const; CompilationDependency const* FieldTypeDependencyOffTheRecord( - const MapRef& map, int descriptor) const; + const MapRef& map, InternalIndex descriptor) const; // Exposed only for testing purposes. bool AreValid() const; diff --git a/deps/v8/src/compiler/decompression-elimination.cc b/deps/v8/src/compiler/decompression-elimination.cc index 537744652b9686..5c0f6b1cfaabf4 100644 --- a/deps/v8/src/compiler/decompression-elimination.cc +++ b/deps/v8/src/compiler/decompression-elimination.cc @@ -67,7 +67,6 @@ Reduction DecompressionElimination::ReduceCompress(Node* node) { Node* input_node = node->InputAt(0); IrOpcode::Value input_opcode = input_node->opcode(); if (IrOpcode::IsDecompressOpcode(input_opcode)) { - DCHECK(IsValidDecompress(node->opcode(), input_opcode)); DCHECK_EQ(input_node->InputCount(), 1); return Replace(input_node->InputAt(0)); } else if (IsReducibleConstantOpcode(input_opcode)) { @@ -167,6 +166,42 @@ Reduction DecompressionElimination::ReduceTypedStateValues(Node* node) { return any_change ? Changed(node) : NoChange(); } +Reduction DecompressionElimination::ReduceWord32Equal(Node* node) { + DCHECK_EQ(node->opcode(), IrOpcode::kWord32Equal); + + DCHECK_EQ(node->InputCount(), 2); + Node* lhs = node->InputAt(0); + Node* rhs = node->InputAt(1); + + if (!IrOpcode::IsCompressOpcode(lhs->opcode()) || + !IrOpcode::IsCompressOpcode(rhs->opcode())) { + return NoChange(); + } + // Input nodes for compress operation. + lhs = lhs->InputAt(0); + rhs = rhs->InputAt(0); + + bool changed = false; + + if (lhs->opcode() == IrOpcode::kBitcastWordToTaggedSigned) { + Node* input = lhs->InputAt(0); + if (IsReducibleConstantOpcode(input->opcode())) { + node->ReplaceInput(0, GetCompressedConstant(input)); + changed = true; + } + } + + if (rhs->opcode() == IrOpcode::kBitcastWordToTaggedSigned) { + Node* input = rhs->InputAt(0); + if (IsReducibleConstantOpcode(input->opcode())) { + node->ReplaceInput(1, GetCompressedConstant(input)); + changed = true; + } + } + + return changed ? Changed(node) : NoChange(); +} + Reduction DecompressionElimination::ReduceWord64Equal(Node* node) { DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal); @@ -220,6 +255,8 @@ Reduction DecompressionElimination::Reduce(Node* node) { return ReducePhi(node); case IrOpcode::kTypedStateValues: return ReduceTypedStateValues(node); + case IrOpcode::kWord32Equal: + return ReduceWord32Equal(node); case IrOpcode::kWord64Equal: return ReduceWord64Equal(node); default: diff --git a/deps/v8/src/compiler/decompression-elimination.h b/deps/v8/src/compiler/decompression-elimination.h index 85a6c98aa0bbb5..6b2be009c6b06f 100644 --- a/deps/v8/src/compiler/decompression-elimination.h +++ b/deps/v8/src/compiler/decompression-elimination.h @@ -65,6 +65,11 @@ class V8_EXPORT_PRIVATE DecompressionElimination final // value of that constant. Reduction ReduceWord64Equal(Node* node); + // This is a workaround for load elimination test. + // Replaces Compress -> BitcastWordToTaggedSigned -> ReducibleConstant + // to CompressedConstant on both inputs of Word32Equal operation. + Reduction ReduceWord32Equal(Node* node); + Graph* graph() const { return graph_; } MachineOperatorBuilder* machine() const { return machine_; } CommonOperatorBuilder* common() const { return common_; } diff --git a/deps/v8/src/compiler/effect-control-linearizer.cc b/deps/v8/src/compiler/effect-control-linearizer.cc index 8dfe356c34d485..ceff453164bbfb 100644 --- a/deps/v8/src/compiler/effect-control-linearizer.cc +++ b/deps/v8/src/compiler/effect-control-linearizer.cc @@ -187,8 +187,11 @@ class EffectControlLinearizer { Node* LowerMaybeGrowFastElements(Node* node, Node* frame_state); void LowerTransitionElementsKind(Node* node); Node* LowerLoadFieldByIndex(Node* node); + Node* LowerLoadMessage(Node* node); Node* LowerLoadTypedElement(Node* node); Node* LowerLoadDataViewElement(Node* node); + Node* LowerLoadStackArgument(Node* node); + void LowerStoreMessage(Node* node); void LowerStoreTypedElement(Node* node); void LowerStoreDataViewElement(Node* node); void LowerStoreSignedSmallElement(Node* node); @@ -227,6 +230,8 @@ class EffectControlLinearizer { Node* LowerStringComparison(Callable const& callable, Node* node); Node* IsElementsKindGreaterThan(Node* kind, ElementsKind reference_kind); + Node* BuildTypedArrayDataPointer(Node* base, Node* external); + Node* ChangeInt32ToCompressedSmi(Node* value); Node* ChangeInt32ToSmi(Node* value); Node* ChangeInt32ToIntPtr(Node* value); @@ -247,6 +252,7 @@ class EffectControlLinearizer { Node* SmiShiftBitsConstant(); void TransitionElementsTo(Node* node, Node* array, ElementsKind from, ElementsKind to); + void ConnectUnreachableToEnd(Node* effect, Node* control); Factory* factory() const { return isolate()->factory(); } Isolate* isolate() const { return jsgraph()->isolate(); } @@ -308,19 +314,8 @@ struct PendingEffectPhi { : effect_phi(effect_phi), block(block) {} }; -void ConnectUnreachableToEnd(Node* effect, Node* control, JSGraph* jsgraph) { - Graph* graph = jsgraph->graph(); - CommonOperatorBuilder* common = jsgraph->common(); - if (effect->opcode() == IrOpcode::kDead) return; - if (effect->opcode() != IrOpcode::kUnreachable) { - effect = graph->NewNode(common->Unreachable(), effect, control); - } - Node* throw_node = graph->NewNode(common->Throw(), effect, control); - NodeProperties::MergeControlToEnd(graph, common, throw_node); -} - void UpdateEffectPhi(Node* node, BasicBlock* block, - BlockEffectControlMap* block_effects, JSGraph* jsgraph) { + BlockEffectControlMap* block_effects) { // Update all inputs to an effect phi with the effects from the given // block->effect map. DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); @@ -607,7 +602,7 @@ void EffectControlLinearizer::Run() { // record the effect phi for later processing. pending_effect_phis.push_back(PendingEffectPhi(effect_phi, block)); } else { - UpdateEffectPhi(effect_phi, block, &block_effects, jsgraph()); + UpdateEffectPhi(effect_phi, block, &block_effects); } } @@ -649,7 +644,7 @@ void EffectControlLinearizer::Run() { if (control->opcode() == IrOpcode::kLoop) { pending_effect_phis.push_back(PendingEffectPhi(effect, block)); } else { - UpdateEffectPhi(effect, block, &block_effects, jsgraph()); + UpdateEffectPhi(effect, block, &block_effects); } } else if (control->opcode() == IrOpcode::kIfException) { // The IfException is connected into the effect chain, so we need @@ -734,7 +729,7 @@ void EffectControlLinearizer::Run() { // during the first pass (because they could have incoming back edges). for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) { UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block, - &block_effects, jsgraph()); + &block_effects); } } @@ -828,7 +823,7 @@ void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, // Break the effect chain on {Unreachable} and reconnect to the graph end. // Mark the following code for deletion by connecting to the {Dead} node. if (node->opcode() == IrOpcode::kUnreachable) { - ConnectUnreachableToEnd(*effect, *control, jsgraph()); + ConnectUnreachableToEnd(*effect, *control); *effect = *control = jsgraph()->Dead(); } } @@ -1243,6 +1238,12 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kTransitionElementsKind: LowerTransitionElementsKind(node); break; + case IrOpcode::kLoadMessage: + result = LowerLoadMessage(node); + break; + case IrOpcode::kStoreMessage: + LowerStoreMessage(node); + break; case IrOpcode::kLoadFieldByIndex: result = LowerLoadFieldByIndex(node); break; @@ -1252,6 +1253,9 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, case IrOpcode::kLoadDataViewElement: result = LowerLoadDataViewElement(node); break; + case IrOpcode::kLoadStackArgument: + result = LowerLoadStackArgument(node); + break; case IrOpcode::kStoreTypedElement: LowerStoreTypedElement(node); break; @@ -1325,6 +1329,13 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, return true; } +void EffectControlLinearizer::ConnectUnreachableToEnd(Node* effect, + Node* control) { + DCHECK_EQ(effect->opcode(), IrOpcode::kUnreachable); + Node* throw_node = graph()->NewNode(common()->Throw(), effect, control); + NodeProperties::MergeControlToEnd(graph(), common(), throw_node); +} + #define __ gasm()-> Node* EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node) { @@ -1601,7 +1612,7 @@ Node* EffectControlLinearizer::LowerTruncateTaggedToBit(Node* node) { __ Bind(&if_smi); { // If {value} is a Smi, then we only need to check that it's not zero. - __ Goto(&done, __ Word32Equal(__ IntPtrEqual(value, __ IntPtrConstant(0)), + __ Goto(&done, __ Word32Equal(__ TaggedEqual(value, __ SmiConstant(0)), __ Int32Constant(0))); } @@ -1952,7 +1963,7 @@ Node* EffectControlLinearizer::LowerCheckReceiverOrNullOrUndefined( __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); // Rule out all primitives except oddballs (true, false, undefined, null). - STATIC_ASSERT(LAST_PRIMITIVE_TYPE == ODDBALL_TYPE); + STATIC_ASSERT(LAST_PRIMITIVE_HEAP_OBJECT_TYPE == ODDBALL_TYPE); STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); Node* check0 = __ Uint32LessThanOrEqual(__ Uint32Constant(ODDBALL_TYPE), value_instance_type); @@ -2028,9 +2039,8 @@ Node* EffectControlLinearizer::LowerStringConcat(Node* node) { callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, Operator::kNoDeopt | Operator::kNoWrite | Operator::kNoThrow); - Node* value = - __ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs, - rhs, __ NoContextConstant()); + Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, + rhs, __ NoContextConstant()); return value; } @@ -2112,8 +2122,7 @@ Node* EffectControlLinearizer::LowerCheckedInt32Div(Node* node, // Check if {lhs} is kMinInt and {rhs} is -1, in which case we'd have // to return -kMinInt, which is not representable as Word32. - Node* check_lhs_minint = graph()->NewNode(machine()->Word32Equal(), lhs, - __ Int32Constant(kMinInt)); + Node* check_lhs_minint = __ Word32Equal(lhs, __ Int32Constant(kMinInt)); __ Branch(check_lhs_minint, &if_lhs_minint, &if_lhs_notminint); __ Bind(&if_lhs_minint); @@ -2760,7 +2769,7 @@ Node* EffectControlLinearizer::LowerChangeUint64ToBigInt(Node* node) { DCHECK(machine()->Is64()); Node* value = node->InputAt(0); - Node* map = jsgraph()->HeapConstant(factory()->bigint_map()); + Node* map = __ HeapConstant(factory()->bigint_map()); // BigInts with value 0 must be of size 0 (canonical form). auto if_zerodigits = __ MakeLabel(); auto if_onedigit = __ MakeLabel(); @@ -2963,10 +2972,11 @@ Node* EffectControlLinearizer::LowerObjectIsArrayBufferView(Node* node) { Node* value_map = __ LoadField(AccessBuilder::ForMap(), value); Node* value_instance_type = __ LoadField(AccessBuilder::ForMapInstanceType(), value_map); - STATIC_ASSERT(JS_TYPED_ARRAY_TYPE + 1 == JS_DATA_VIEW_TYPE); Node* vfalse = __ Uint32LessThan( - __ Int32Sub(value_instance_type, __ Int32Constant(JS_TYPED_ARRAY_TYPE)), - __ Int32Constant(2)); + __ Int32Sub(value_instance_type, + __ Int32Constant(FIRST_JS_ARRAY_BUFFER_VIEW_TYPE)), + __ Int32Constant(LAST_JS_ARRAY_BUFFER_VIEW_TYPE - + FIRST_JS_ARRAY_BUFFER_VIEW_TYPE + 1)); __ Goto(&done, vfalse); __ Bind(&if_smi); @@ -3521,7 +3531,7 @@ Node* EffectControlLinearizer::LowerArgumentsFrame(Node* node) { __ Load(MachineType::Pointer(), frame, __ IntPtrConstant(StandardFrameConstants::kCallerFPOffset)); Node* parent_frame_type = __ Load( - MachineType::TypeCompressedTagged(), parent_frame, + MachineType::IntPtr(), parent_frame, __ IntPtrConstant(CommonFrameConstants::kContextOrFrameTypeOffset)); __ GotoIf(__ IntPtrEqual(parent_frame_type, @@ -3541,7 +3551,7 @@ Node* EffectControlLinearizer::LowerNewDoubleElements(Node* node) { auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0)); __ GotoIf(zero_length, &done, - jsgraph()->HeapConstant(factory()->empty_fixed_array())); + __ HeapConstant(factory()->empty_fixed_array())); // Compute the effective size of the backing store. Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kDoubleSizeLog2)), @@ -3589,7 +3599,7 @@ Node* EffectControlLinearizer::LowerNewSmiOrObjectElements(Node* node) { auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); Node* zero_length = __ IntPtrEqual(length, __ IntPtrConstant(0)); __ GotoIf(zero_length, &done, - jsgraph()->HeapConstant(factory()->empty_fixed_array())); + __ HeapConstant(factory()->empty_fixed_array())); // Compute the effective size of the backing store. Node* size = __ IntAdd(__ WordShl(length, __ IntPtrConstant(kTaggedSizeLog2)), @@ -3671,10 +3681,9 @@ Node* EffectControlLinearizer::LowerNewConsString(Node* node) { __ Branch(__ Word32Equal(encoding, __ Int32Constant(kTwoByteStringTag)), &if_twobyte, &if_onebyte); __ Bind(&if_onebyte); - __ Goto(&done, - jsgraph()->HeapConstant(factory()->cons_one_byte_string_map())); + __ Goto(&done, __ HeapConstant(factory()->cons_one_byte_string_map())); __ Bind(&if_twobyte); - __ Goto(&done, jsgraph()->HeapConstant(factory()->cons_string_map())); + __ Goto(&done, __ HeapConstant(factory()->cons_string_map())); __ Bind(&done); Node* result_map = done.PhiAt(0); @@ -4287,9 +4296,8 @@ Node* EffectControlLinearizer::LowerBigIntAdd(Node* node, Node* frame_state) { graph()->zone(), callable.descriptor(), callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, Operator::kFoldable | Operator::kNoThrow); - Node* value = - __ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), lhs, - rhs, __ NoContextConstant()); + Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), lhs, + rhs, __ NoContextConstant()); // Check for exception sentinel: Smi is returned to signal BigIntTooBig. __ DeoptimizeIf(DeoptimizeReason::kBigIntTooBig, FeedbackSource{}, @@ -4305,9 +4313,8 @@ Node* EffectControlLinearizer::LowerBigIntNegate(Node* node) { graph()->zone(), callable.descriptor(), callable.descriptor().GetStackParameterCount(), CallDescriptor::kNoFlags, Operator::kFoldable | Operator::kNoThrow); - Node* value = - __ Call(call_descriptor, jsgraph()->HeapConstant(callable.code()), - node->InputAt(0), __ NoContextConstant()); + Node* value = __ Call(call_descriptor, __ HeapConstant(callable.code()), + node->InputAt(0), __ NoContextConstant()); return value; } @@ -4746,6 +4753,20 @@ void EffectControlLinearizer::LowerTransitionElementsKind(Node* node) { __ Bind(&done); } +Node* EffectControlLinearizer::LowerLoadMessage(Node* node) { + Node* offset = node->InputAt(0); + Node* object_pattern = + __ LoadField(AccessBuilder::ForExternalIntPtr(), offset); + return __ BitcastWordToTagged(object_pattern); +} + +void EffectControlLinearizer::LowerStoreMessage(Node* node) { + Node* offset = node->InputAt(0); + Node* object = node->InputAt(1); + Node* object_pattern = __ BitcastTaggedToWord(object); + __ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern); +} + Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { Node* object = node->InputAt(0); Node* index = node->InputAt(1); @@ -4801,6 +4822,7 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { // architectures, or a mutable HeapNumber. __ Bind(&if_double); { + auto loaded_field = __ MakeLabel(MachineRepresentation::kTagged); auto done_double = __ MakeLabel(MachineRepresentation::kFloat64); index = __ WordSar(index, one); @@ -4818,10 +4840,9 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { Node* result = __ Load(MachineType::Float64(), object, offset); __ Goto(&done_double, result); } else { - Node* result = + Node* field = __ Load(MachineType::TypeCompressedTagged(), object, offset); - result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result); - __ Goto(&done_double, result); + __ Goto(&loaded_field, field); } } @@ -4834,10 +4855,24 @@ Node* EffectControlLinearizer::LowerLoadFieldByIndex(Node* node) { __ IntPtrConstant(kTaggedSizeLog2)), __ IntPtrConstant((FixedArray::kHeaderSize - kTaggedSize) - kHeapObjectTag)); - Node* result = + Node* field = __ Load(MachineType::TypeCompressedTagged(), properties, offset); - result = __ LoadField(AccessBuilder::ForHeapNumberValue(), result); - __ Goto(&done_double, result); + __ Goto(&loaded_field, field); + } + + __ Bind(&loaded_field); + { + Node* field = loaded_field.PhiAt(0); + // We may have transitioned in-place away from double, so check that + // this is a HeapNumber -- otherwise the load is fine and we don't need + // to copy anything anyway. + __ GotoIf(ObjectIsSmi(field), &done, field); + Node* field_map = __ LoadField(AccessBuilder::ForMap(), field); + __ GotoIfNot(__ TaggedEqual(field_map, __ HeapNumberMapConstant()), &done, + field); + + Node* value = __ LoadField(AccessBuilder::ForHeapNumberValue(), field); + __ Goto(&done_double, value); } __ Bind(&done_double); @@ -4988,6 +5023,35 @@ void EffectControlLinearizer::LowerStoreDataViewElement(Node* node) { done.PhiAt(0)); } +// Compute the data pointer, handling the case where the {external} pointer +// is the effective data pointer (i.e. the {base} is Smi zero). +Node* EffectControlLinearizer::BuildTypedArrayDataPointer(Node* base, + Node* external) { + if (IntPtrMatcher(base).Is(0)) { + return external; + } else { + if (COMPRESS_POINTERS_BOOL) { + // TurboFan does not support loading of compressed fields without + // decompression so we add the following operations to workaround that. + // We can't load the base value as word32 because in that case the + // value will not be marked as tagged in the pointer map and will not + // survive GC. + // Compress base value back to in order to be able to decompress by + // doing an unsafe add below. Both decompression and compression + // will be removed by the decompression elimination pass. + base = __ ChangeTaggedToCompressed(base); + base = __ BitcastTaggedToWord(base); + // Zero-extend Tagged_t to UintPtr according to current compression + // scheme so that the addition with |external_pointer| (which already + // contains compensated offset value) will decompress the tagged value. + // See JSTypedArray::ExternalPointerCompensationForOnHeapArray() for + // details. + base = ChangeUint32ToUintPtr(base); + } + return __ UnsafePointerAdd(base, external); + } +} + Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) { ExternalArrayType array_type = ExternalArrayTypeOf(node->op()); Node* buffer = node->InputAt(0); @@ -4999,17 +5063,22 @@ Node* EffectControlLinearizer::LowerLoadTypedElement(Node* node) { // ArrayBuffer (if there's any) as long as we are still operating on it. __ Retain(buffer); - // Compute the effective storage pointer, handling the case where the - // {external} pointer is the effective storage pointer (i.e. the {base} - // is Smi zero). - Node* storage = IntPtrMatcher(base).Is(0) - ? external - : __ UnsafePointerAdd(base, external); + Node* data_ptr = BuildTypedArrayDataPointer(base, external); // Perform the actual typed element access. return __ LoadElement(AccessBuilder::ForTypedArrayElement( array_type, true, LoadSensitivity::kCritical), - storage, index); + data_ptr, index); +} + +Node* EffectControlLinearizer::LowerLoadStackArgument(Node* node) { + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + + Node* argument = + __ LoadElement(AccessBuilder::ForStackArgument(), base, index); + + return __ BitcastWordToTagged(argument); } void EffectControlLinearizer::LowerStoreTypedElement(Node* node) { @@ -5024,16 +5093,11 @@ void EffectControlLinearizer::LowerStoreTypedElement(Node* node) { // ArrayBuffer (if there's any) as long as we are still operating on it. __ Retain(buffer); - // Compute the effective storage pointer, handling the case where the - // {external} pointer is the effective storage pointer (i.e. the {base} - // is Smi zero). - Node* storage = IntPtrMatcher(base).Is(0) - ? external - : __ UnsafePointerAdd(base, external); + Node* data_ptr = BuildTypedArrayDataPointer(base, external); // Perform the actual typed element access. __ StoreElement(AccessBuilder::ForTypedArrayElement(array_type, true), - storage, index, value); + data_ptr, index, value); } void EffectControlLinearizer::TransitionElementsTo(Node* node, Node* array, @@ -5402,7 +5466,7 @@ void EffectControlLinearizer::LowerRuntimeAbort(Node* node) { auto call_descriptor = Linkage::GetRuntimeCallDescriptor( graph()->zone(), id, 1, properties, CallDescriptor::kNoFlags); __ Call(call_descriptor, __ CEntryStubConstant(1), - jsgraph()->SmiConstant(static_cast<int>(reason)), + __ SmiConstant(static_cast<int>(reason)), __ ExternalConstant(ExternalReference::Create(id)), __ Int32Constant(1), __ NoContextConstant()); } diff --git a/deps/v8/src/compiler/escape-analysis-reducer.cc b/deps/v8/src/compiler/escape-analysis-reducer.cc index 18ae069b21ad09..b2fb8d10ceeb97 100644 --- a/deps/v8/src/compiler/escape-analysis-reducer.cc +++ b/deps/v8/src/compiler/escape-analysis-reducer.cc @@ -326,9 +326,8 @@ void EscapeAnalysisReducer::Finalize() { TypeCache::Get()->kArgumentsLengthType); NodeProperties::ReplaceValueInput(load, arguments_frame, 0); NodeProperties::ReplaceValueInput(load, offset, 1); - NodeProperties::ChangeOp(load, - jsgraph()->simplified()->LoadElement( - AccessBuilder::ForStackArgument())); + NodeProperties::ChangeOp( + load, jsgraph()->simplified()->LoadStackArgument()); break; } case IrOpcode::kLoadField: { diff --git a/deps/v8/src/compiler/frame-states.cc b/deps/v8/src/compiler/frame-states.cc index 9478c08c6c13a3..576f6ce5427d62 100644 --- a/deps/v8/src/compiler/frame-states.cc +++ b/deps/v8/src/compiler/frame-states.cc @@ -137,13 +137,17 @@ Node* CreateStubBuiltinContinuationFrameState( // Stack parameters first. Depending on {mode}, final parameters are added // by the deoptimizer and aren't explicitly passed in the frame state. int stack_parameter_count = - descriptor.GetParameterCount() - DeoptimizerParameterCountFor(mode); - // Reserving space in the vector, except for the case where - // stack_parameter_count is -1. - actual_parameters.reserve(stack_parameter_count >= 0 - ? stack_parameter_count + - descriptor.GetRegisterParameterCount() - : 0); + descriptor.GetStackParameterCount() - DeoptimizerParameterCountFor(mode); + + // Ensure the parameters added by the deoptimizer are passed on the stack. + // This check prevents using TFS builtins as continuations while doing the + // lazy deopt. Use TFC or TFJ builtin as a lazy deopt continuation which + // would pass the result parameter on the stack. + DCHECK_GE(stack_parameter_count, 0); + + // Reserving space in the vector. + actual_parameters.reserve(stack_parameter_count + + descriptor.GetRegisterParameterCount()); for (int i = 0; i < stack_parameter_count; ++i) { actual_parameters.push_back( parameters[descriptor.GetRegisterParameterCount() + i]); diff --git a/deps/v8/src/compiler/functional-list.h b/deps/v8/src/compiler/functional-list.h index 2345f1d360539f..6af63030f83ad9 100644 --- a/deps/v8/src/compiler/functional-list.h +++ b/deps/v8/src/compiler/functional-list.h @@ -90,6 +90,8 @@ class FunctionalList { size_t Size() const { return elements_ ? elements_->size : 0; } + void Clear() { elements_ = nullptr; } + class iterator { public: explicit iterator(Cons* cur) : current_(cur) {} diff --git a/deps/v8/src/compiler/graph-assembler.cc b/deps/v8/src/compiler/graph-assembler.cc index b4ad81ecda0a1f..5c167db9805511 100644 --- a/deps/v8/src/compiler/graph-assembler.cc +++ b/deps/v8/src/compiler/graph-assembler.cc @@ -99,6 +99,10 @@ Node* GraphAssembler::IntPtrEqual(Node* left, Node* right) { } Node* GraphAssembler::TaggedEqual(Node* left, Node* right) { + if (COMPRESS_POINTERS_BOOL) { + return Word32Equal(ChangeTaggedToCompressed(left), + ChangeTaggedToCompressed(right)); + } return WordEqual(left, right); } @@ -232,10 +236,10 @@ Node* GraphAssembler::BitcastTaggedToWord(Node* value) { current_effect_, current_control_); } -Node* GraphAssembler::BitcastTaggedSignedToWord(Node* value) { +Node* GraphAssembler::BitcastTaggedToWordForTagAndSmiBits(Node* value) { return current_effect_ = - graph()->NewNode(machine()->BitcastTaggedSignedToWord(), value, - current_effect_, current_control_); + graph()->NewNode(machine()->BitcastTaggedToWordForTagAndSmiBits(), + value, current_effect_, current_control_); } Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) { diff --git a/deps/v8/src/compiler/graph-assembler.h b/deps/v8/src/compiler/graph-assembler.h index 0088f867c54f72..d2df5a75f3a168 100644 --- a/deps/v8/src/compiler/graph-assembler.h +++ b/deps/v8/src/compiler/graph-assembler.h @@ -233,7 +233,7 @@ class GraphAssembler { Node* ToNumber(Node* value); Node* BitcastWordToTagged(Node* value); Node* BitcastTaggedToWord(Node* value); - Node* BitcastTaggedSignedToWord(Node* value); + Node* BitcastTaggedToWordForTagAndSmiBits(Node* value); Node* Allocate(AllocationType allocation, Node* size); Node* LoadField(FieldAccess const&, Node* object); Node* LoadElement(ElementAccess const&, Node* object, Node* index); diff --git a/deps/v8/src/compiler/graph-visualizer.cc b/deps/v8/src/compiler/graph-visualizer.cc index 85123261dbda78..dddba7d36f62ff 100644 --- a/deps/v8/src/compiler/graph-visualizer.cc +++ b/deps/v8/src/compiler/graph-visualizer.cc @@ -163,7 +163,6 @@ void JsonPrintInlinedFunctionInfo( void JsonPrintAllSourceWithPositions(std::ostream& os, OptimizedCompilationInfo* info, Isolate* isolate) { - AllowDeferredHandleDereference allow_deference_for_print_code; os << "\"sources\" : {"; Handle<Script> script = (info->shared_info().is_null() || @@ -1055,15 +1054,9 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) { } break; } - case InstructionOperand::EXPLICIT: case InstructionOperand::ALLOCATED: { const LocationOperand* allocated = LocationOperand::cast(op); - os << "\"type\": "; - if (allocated->IsExplicit()) { - os << "\"explicit\", "; - } else { - os << "\"allocated\", "; - } + os << "\"type\": \"allocated\", "; os << "\"text\": \""; if (op->IsStackSlot()) { os << "stack:" << allocated->index(); diff --git a/deps/v8/src/compiler/heap-refs.h b/deps/v8/src/compiler/heap-refs.h index 9b1aa53eb91116..c6322ebe691936 100644 --- a/deps/v8/src/compiler/heap-refs.h +++ b/deps/v8/src/compiler/heap-refs.h @@ -29,7 +29,6 @@ class NativeContext; class ScriptContextTable; namespace compiler { - // Whether we are loading a property or storing to a property. // For a store during literal creation, do not walk up the prototype chain. enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas }; @@ -95,10 +94,12 @@ enum class OddballType : uint8_t { V(PropertyCell) \ V(SharedFunctionInfo) \ V(SourceTextModule) \ + V(TemplateObjectDescription) \ /* Subtypes of Object */ \ V(HeapObject) class CompilationDependencies; +struct FeedbackSource; class JSHeapBroker; class ObjectData; class PerIsolateCompilerCache; @@ -163,8 +164,8 @@ class V8_EXPORT_PRIVATE ObjectRef { private: friend class FunctionTemplateInfoRef; friend class JSArrayData; - friend class JSGlobalProxyRef; - friend class JSGlobalProxyData; + friend class JSGlobalObjectData; + friend class JSGlobalObjectRef; friend class JSHeapBroker; friend class JSObjectData; friend class StringData; @@ -329,8 +330,6 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef { SharedFunctionInfoRef shared() const; FeedbackVectorRef feedback_vector() const; int InitialMapInstanceSizeWithMinSlack() const; - - bool IsSerializedForCompilation() const; }; class JSRegExpRef : public JSObjectRef { @@ -344,6 +343,8 @@ class JSRegExpRef : public JSObjectRef { ObjectRef source() const; ObjectRef flags() const; ObjectRef last_index() const; + + void SerializeAsRegExpBoilerplate(); }; class HeapNumberRef : public HeapObjectRef { @@ -496,7 +497,6 @@ class FeedbackVectorRef : public HeapObjectRef { double invocation_count() const; void Serialize(); - ObjectRef get(FeedbackSlot slot) const; FeedbackCellRef GetClosureFeedbackCell(int index) const; }; @@ -535,6 +535,9 @@ class AllocationSiteRef : public HeapObjectRef { // // If PointsToLiteral() is false, then IsFastLiteral() is also false. bool IsFastLiteral() const; + + void SerializeBoilerplate(); + // We only serialize boilerplate if IsFastLiteral is true. base::Optional<JSObjectRef> boilerplate() const; @@ -585,7 +588,6 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { bool is_migration_target() const; bool supports_fast_array_iteration() const; bool supports_fast_array_resize() const; - bool IsMapOfTargetGlobalProxy() const; bool is_abandoned_prototype_map() const; OddballType oddball_type() const; @@ -609,15 +611,15 @@ class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef { // Concerning the underlying instance_descriptors: void SerializeOwnDescriptors(); - void SerializeOwnDescriptor(int descriptor_index); - bool serialized_own_descriptor(int descriptor_index) const; - MapRef FindFieldOwner(int descriptor_index) const; - PropertyDetails GetPropertyDetails(int descriptor_index) const; - NameRef GetPropertyKey(int descriptor_index) const; - FieldIndex GetFieldIndexFor(int descriptor_index) const; - ObjectRef GetFieldType(int descriptor_index) const; - bool IsUnboxedDoubleField(int descriptor_index) const; - ObjectRef GetStrongValue(int descriptor_number) const; + void SerializeOwnDescriptor(InternalIndex descriptor_index); + bool serialized_own_descriptor(InternalIndex descriptor_index) const; + MapRef FindFieldOwner(InternalIndex descriptor_index) const; + PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const; + NameRef GetPropertyKey(InternalIndex descriptor_index) const; + FieldIndex GetFieldIndexFor(InternalIndex descriptor_index) const; + ObjectRef GetFieldType(InternalIndex descriptor_index) const; + bool IsUnboxedDoubleField(InternalIndex descriptor_index) const; + ObjectRef GetStrongValue(InternalIndex descriptor_number) const; void SerializeRootMap(); base::Optional<MapRef> FindRootMap() const; @@ -727,7 +729,6 @@ class BytecodeArrayRef : public FixedArrayBaseRef { Address handler_table_address() const; int handler_table_size() const; - bool IsSerializedForCompilation() const; void SerializeForCompilation(); }; @@ -769,7 +770,8 @@ class ScopeInfoRef : public HeapObjectRef { V(bool, is_safe_to_skip_arguments_adaptor) \ V(bool, IsInlineable) \ V(int, StartPosition) \ - V(bool, is_compiled) + V(bool, is_compiled) \ + V(bool, IsUserJavaScript) class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef { public: @@ -791,7 +793,7 @@ class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef { // wraps the retrieval of the template object and creates it if // necessary. JSArrayRef GetTemplateObject( - ObjectRef description, FeedbackVectorRef vector, FeedbackSlot slot, + TemplateObjectDescriptionRef description, FeedbackSource const& source, SerializationPolicy policy = SerializationPolicy::kAssumeSerialized); void SerializeFunctionTemplateInfo(); @@ -826,7 +828,7 @@ class JSTypedArrayRef : public JSObjectRef { bool is_on_heap() const; size_t length() const; - void* external_pointer() const; + void* data_ptr() const; void Serialize(); bool serialized() const; @@ -845,6 +847,13 @@ class SourceTextModuleRef : public HeapObjectRef { base::Optional<CellRef> GetCell(int cell_index) const; }; +class TemplateObjectDescriptionRef : public HeapObjectRef { + public: + DEFINE_REF_CONSTRUCTOR(TemplateObjectDescription, HeapObjectRef) + + Handle<TemplateObjectDescription> object() const; +}; + class CellRef : public HeapObjectRef { public: DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef) @@ -859,13 +868,8 @@ class JSGlobalObjectRef : public JSObjectRef { DEFINE_REF_CONSTRUCTOR(JSGlobalObject, JSObjectRef) Handle<JSGlobalObject> object() const; -}; - -class JSGlobalProxyRef : public JSObjectRef { - public: - DEFINE_REF_CONSTRUCTOR(JSGlobalProxy, JSObjectRef) - Handle<JSGlobalProxy> object() const; + bool IsDetached() const; // If {serialize} is false: // If the property is known to exist as a property cell (on the global @@ -879,6 +883,13 @@ class JSGlobalProxyRef : public JSObjectRef { SerializationPolicy::kAssumeSerialized) const; }; +class JSGlobalProxyRef : public JSObjectRef { + public: + DEFINE_REF_CONSTRUCTOR(JSGlobalProxy, JSObjectRef) + + Handle<JSGlobalProxy> object() const; +}; + class CodeRef : public HeapObjectRef { public: DEFINE_REF_CONSTRUCTOR(Code, HeapObjectRef) diff --git a/deps/v8/src/compiler/int64-lowering.h b/deps/v8/src/compiler/int64-lowering.h index 1e2a36089b107d..0190d3a9c421f2 100644 --- a/deps/v8/src/compiler/int64-lowering.h +++ b/deps/v8/src/compiler/int64-lowering.h @@ -5,6 +5,8 @@ #ifndef V8_COMPILER_INT64_LOWERING_H_ #define V8_COMPILER_INT64_LOWERING_H_ +#include <memory> + #include "src/common/globals.h" #include "src/compiler/common-operator.h" #include "src/compiler/graph.h" diff --git a/deps/v8/src/compiler/js-call-reducer.cc b/deps/v8/src/compiler/js-call-reducer.cc index 0b7b4a65f45825..d400fa2673ee3d 100644 --- a/deps/v8/src/compiler/js-call-reducer.cc +++ b/deps/v8/src/compiler/js-call-reducer.cc @@ -473,10 +473,10 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) { if (receiver_map.NumberOfOwnDescriptors() < minimum_nof_descriptors) { return inference.NoChange(); } - if (!receiver_map.serialized_own_descriptor( - JSFunction::kLengthDescriptorIndex) || - !receiver_map.serialized_own_descriptor( - JSFunction::kNameDescriptorIndex)) { + const InternalIndex kLengthIndex(JSFunction::kLengthDescriptorIndex); + const InternalIndex kNameIndex(JSFunction::kNameDescriptorIndex); + if (!receiver_map.serialized_own_descriptor(kLengthIndex) || + !receiver_map.serialized_own_descriptor(kNameIndex)) { TRACE_BROKER_MISSING(broker(), "serialized descriptors on map " << receiver_map); return inference.NoChange(); @@ -485,14 +485,10 @@ Reduction JSCallReducer::ReduceFunctionPrototypeBind(Node* node) { StringRef length_string(broker(), roots.length_string_handle()); StringRef name_string(broker(), roots.name_string_handle()); - if (!receiver_map.GetPropertyKey(JSFunction::kLengthDescriptorIndex) - .equals(length_string) || - !receiver_map.GetStrongValue(JSFunction::kLengthDescriptorIndex) - .IsAccessorInfo() || - !receiver_map.GetPropertyKey(JSFunction::kNameDescriptorIndex) - .equals(name_string) || - !receiver_map.GetStrongValue(JSFunction::kNameDescriptorIndex) - .IsAccessorInfo()) { + if (!receiver_map.GetPropertyKey(kLengthIndex).equals(length_string) || + !receiver_map.GetStrongValue(kLengthIndex).IsAccessorInfo() || + !receiver_map.GetPropertyKey(kNameIndex).equals(name_string) || + !receiver_map.GetStrongValue(kNameIndex).IsAccessorInfo()) { return inference.NoChange(); } } @@ -3013,12 +3009,13 @@ Reduction JSCallReducer::ReduceCallOrConstructWithArrayLikeOrSpread( node->opcode() == IrOpcode::kJSConstructWithArrayLike || node->opcode() == IrOpcode::kJSConstructWithSpread); - // Check if {arguments_list} is an arguments object, and {node} is the only - // value user of {arguments_list} (except for value uses in frame states). Node* arguments_list = NodeProperties::GetValueInput(node, arity); if (arguments_list->opcode() != IrOpcode::kJSCreateArguments) { return NoChange(); } + + // Check if {node} is the only value user of {arguments_list} (except for + // value uses in frame states). If not, we give up for now. for (Edge edge : arguments_list->use_edges()) { if (!NodeProperties::IsValueEdge(edge)) continue; Node* const user = edge.from(); @@ -3704,7 +3701,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node, case Builtins::kMapIteratorPrototypeNext: return ReduceCollectionIteratorPrototypeNext( node, OrderedHashMap::kEntrySize, factory()->empty_ordered_hash_map(), - FIRST_MAP_ITERATOR_TYPE, LAST_MAP_ITERATOR_TYPE); + FIRST_JS_MAP_ITERATOR_TYPE, LAST_JS_MAP_ITERATOR_TYPE); case Builtins::kSetPrototypeEntries: return ReduceCollectionIteration(node, CollectionKind::kSet, IterationKind::kEntries); @@ -3716,7 +3713,7 @@ Reduction JSCallReducer::ReduceJSCall(Node* node, case Builtins::kSetIteratorPrototypeNext: return ReduceCollectionIteratorPrototypeNext( node, OrderedHashSet::kEntrySize, factory()->empty_ordered_hash_set(), - FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE); + FIRST_JS_SET_ITERATOR_TYPE, LAST_JS_SET_ITERATOR_TYPE); case Builtins::kDatePrototypeGetTime: return ReduceDatePrototypeGetTime(node); case Builtins::kDateNow: @@ -5676,8 +5673,6 @@ Reduction JSCallReducer::ReducePromiseConstructor(Node* node) { Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); - if (!FLAG_experimental_inline_promise_constructor) return NoChange(); - // Only handle builtins Promises, not subclasses. if (target != new_target) return NoChange(); diff --git a/deps/v8/src/compiler/js-context-specialization.cc b/deps/v8/src/compiler/js-context-specialization.cc index 035e8b7ceb9392..409fc6c9a143f2 100644 --- a/deps/v8/src/compiler/js-context-specialization.cc +++ b/deps/v8/src/compiler/js-context-specialization.cc @@ -38,7 +38,7 @@ Reduction JSContextSpecialization::ReduceParameter(Node* node) { // Constant-fold the function parameter {node}. Handle<JSFunction> function; if (closure().ToHandle(&function)) { - Node* value = jsgraph()->HeapConstant(function); + Node* value = jsgraph()->Constant(JSFunctionRef(broker_, function)); return Replace(value); } } diff --git a/deps/v8/src/compiler/js-create-lowering.cc b/deps/v8/src/compiler/js-create-lowering.cc index cb52ccaccb17f4..6ab54d793a8e46 100644 --- a/deps/v8/src/compiler/js-create-lowering.cc +++ b/deps/v8/src/compiler/js-create-lowering.cc @@ -18,6 +18,7 @@ #include "src/compiler/operator-properties.h" #include "src/compiler/simplified-operator.h" #include "src/compiler/state-values-utils.h" +#include "src/execution/protectors.h" #include "src/objects/arguments.h" #include "src/objects/hash-table-inl.h" #include "src/objects/heap-number.h" @@ -26,6 +27,7 @@ #include "src/objects/js-promise.h" #include "src/objects/js-regexp-inl.h" #include "src/objects/objects-inl.h" +#include "src/objects/template-objects.h" namespace v8 { namespace internal { @@ -84,6 +86,8 @@ Reduction JSCreateLowering::Reduce(Node* node) { return ReduceJSCreateLiteralArrayOrObject(node); case IrOpcode::kJSCreateLiteralRegExp: return ReduceJSCreateLiteralRegExp(node); + case IrOpcode::kJSGetTemplateObject: + return ReduceJSGetTemplateObject(node); case IrOpcode::kJSCreateEmptyLiteralArray: return ReduceJSCreateEmptyLiteralArray(node); case IrOpcode::kJSCreateEmptyLiteralObject: @@ -640,10 +644,10 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) { allocation = dependencies()->DependOnPretenureMode(*site_ref); dependencies()->DependOnElementsKind(*site_ref); } else { - CellRef array_constructor_protector( + PropertyCellRef array_constructor_protector( broker(), factory()->array_constructor_protector()); - can_inline_call = - array_constructor_protector.value().AsSmi() == Isolate::kProtectorValid; + can_inline_call = array_constructor_protector.value().AsSmi() == + Protectors::kProtectorValid; } if (arity == 0) { @@ -1073,15 +1077,10 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); - - FeedbackVectorRef feedback_vector(broker(), p.feedback().vector); - ObjectRef feedback = feedback_vector.get(p.feedback().slot); - // TODO(turbofan): we should consider creating a ProcessedFeedback for - // allocation sites/boiler plates so that we use GetFeedback here. Then - // we can eventually get rid of the additional copy of feedback slots that - // we currently have in FeedbackVectorData. - if (feedback.IsAllocationSite()) { - AllocationSiteRef site = feedback.AsAllocationSite(); + ProcessedFeedback const& feedback = + broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback()); + if (!feedback.IsInsufficient()) { + AllocationSiteRef site = feedback.AsLiteral().value(); if (site.IsFastLiteral()) { AllocationType allocation = AllocationType::kYoung; if (FLAG_allocation_site_pretenuring) { @@ -1095,20 +1094,17 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) { return Replace(value); } } + return NoChange(); } Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) { DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode()); FeedbackParameter const& p = FeedbackParameterOf(node->op()); - FeedbackVectorRef fv(broker(), p.feedback().vector); - ObjectRef feedback = fv.get(p.feedback().slot); - // TODO(turbofan): we should consider creating a ProcessedFeedback for - // allocation sites/boiler plates so that we use GetFeedback here. Then - // we can eventually get rid of the additional copy of feedback slots that - // we currently have in FeedbackVectorData. - if (feedback.IsAllocationSite()) { - AllocationSiteRef site = feedback.AsAllocationSite(); + ProcessedFeedback const& feedback = + broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback()); + if (!feedback.IsInsufficient()) { + AllocationSiteRef site = feedback.AsLiteral().value(); DCHECK(!site.PointsToLiteral()); MapRef initial_map = native_context().GetInitialJSArrayMap(site.GetElementsKind()); @@ -1162,22 +1158,30 @@ Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) { CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); - - FeedbackVectorRef feedback_vector(broker(), p.feedback().vector); - ObjectRef feedback = feedback_vector.get(p.feedback().slot); - // TODO(turbofan): we should consider creating a ProcessedFeedback for - // allocation sites/boiler plates so that we use GetFeedback here. Then - // we can eventually get rid of the additional copy of feedback slots that - // we currently have in FeedbackVectorData. - if (feedback.IsJSRegExp()) { - JSRegExpRef boilerplate = feedback.AsJSRegExp(); - Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate); + ProcessedFeedback const& feedback = + broker()->GetFeedbackForRegExpLiteral(p.feedback()); + if (!feedback.IsInsufficient()) { + JSRegExpRef literal = feedback.AsRegExpLiteral().value(); + Node* value = effect = AllocateLiteralRegExp(effect, control, literal); ReplaceWithValue(node, value, effect, control); return Replace(value); } return NoChange(); } +Reduction JSCreateLowering::ReduceJSGetTemplateObject(Node* node) { + DCHECK_EQ(IrOpcode::kJSGetTemplateObject, node->opcode()); + GetTemplateObjectParameters const& parameters = + GetTemplateObjectParametersOf(node->op()); + SharedFunctionInfoRef shared(broker(), parameters.shared()); + JSArrayRef template_object = shared.GetTemplateObject( + TemplateObjectDescriptionRef(broker(), parameters.description()), + parameters.feedback()); + Node* value = jsgraph()->Constant(template_object); + ReplaceWithValue(node, value); + return Replace(value); +} + Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) { DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); const CreateFunctionContextParameters& parameters = @@ -1628,7 +1632,7 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control, ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone()); inobject_fields.reserve(boilerplate_map.GetInObjectProperties()); int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors(); - for (int i = 0; i < boilerplate_nof; ++i) { + for (InternalIndex i : InternalIndex::Range(boilerplate_nof)) { PropertyDetails const property_details = boilerplate_map.GetPropertyDetails(i); if (property_details.location() != kField) continue; diff --git a/deps/v8/src/compiler/js-create-lowering.h b/deps/v8/src/compiler/js-create-lowering.h index 44a3b213b7641d..2fb28ebfd488f4 100644 --- a/deps/v8/src/compiler/js-create-lowering.h +++ b/deps/v8/src/compiler/js-create-lowering.h @@ -67,6 +67,7 @@ class V8_EXPORT_PRIVATE JSCreateLowering final Reduction ReduceJSCreateCatchContext(Node* node); Reduction ReduceJSCreateBlockContext(Node* node); Reduction ReduceJSCreateGeneratorObject(Node* node); + Reduction ReduceJSGetTemplateObject(Node* node); Reduction ReduceNewArray( Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind, AllocationType allocation, diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc index d2a9b675f96199..d419a804a57953 100644 --- a/deps/v8/src/compiler/js-generic-lowering.cc +++ b/deps/v8/src/compiler/js-generic-lowering.cc @@ -236,14 +236,15 @@ void JSGenericLowering::LowerJSLoadGlobal(Node* node) { } void JSGenericLowering::LowerJSGetIterator(Node* node) { - CallDescriptor::Flags flags = FrameStateFlagForCall(node); - const PropertyAccess& p = PropertyAccessOf(node->op()); - node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.feedback().index())); - Node* vector = jsgraph()->HeapConstant(p.feedback().vector); - node->InsertInput(zone(), 2, vector); - Callable callable = - Builtins::CallableFor(isolate(), Builtins::kGetIteratorWithFeedback); - ReplaceWithStubCall(node, callable, flags); + // TODO(v8:9625): Currently, the GetIterator operator is desugared in the + // native context specialization phase. Thus, the following generic lowering + // would never be reachable. We can add a check in native context + // specialization to avoid desugaring the GetIterator operator when in the + // case of megamorphic feedback and here, add a call to the + // 'GetIteratorWithFeedback' builtin. This would reduce the size of the + // compiled code as it would insert 1 call to the builtin instead of 2 calls + // resulting from the generic lowering of the LoadNamed and Call operators. + UNREACHABLE(); } void JSGenericLowering::LowerJSStoreProperty(Node* node) { @@ -561,6 +562,10 @@ void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { } } +void JSGenericLowering::LowerJSGetTemplateObject(Node* node) { + UNREACHABLE(); // Eliminated in native context specialization. +} + void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { CallDescriptor::Flags flags = FrameStateFlagForCall(node); FeedbackParameter const& p = FeedbackParameterOf(node->op()); diff --git a/deps/v8/src/compiler/js-heap-broker.cc b/deps/v8/src/compiler/js-heap-broker.cc index 05048f7f4b70f4..529fb8e9c128ed 100644 --- a/deps/v8/src/compiler/js-heap-broker.cc +++ b/deps/v8/src/compiler/js-heap-broker.cc @@ -16,6 +16,7 @@ #include "src/compiler/bytecode-analysis.h" #include "src/compiler/graph-reducer.h" #include "src/compiler/per-isolate-compiler-cache.h" +#include "src/execution/protectors-inl.h" #include "src/init/bootstrapper.h" #include "src/objects/allocation-site-inl.h" #include "src/objects/api-callbacks.h" @@ -86,6 +87,11 @@ class ObjectData : public ZoneObject { ObjectDataKind kind() const { return kind_; } bool is_smi() const { return kind_ == kSmi; } +#ifdef DEBUG + enum class Usage{kUnused, kOnlyIdentityUsed, kDataUsed}; + mutable Usage used_status = Usage::kUnused; +#endif // DEBUG + private: Handle<Object> const object_; ObjectDataKind const kind_; @@ -420,7 +426,7 @@ class JSTypedArrayData : public JSObjectData { bool is_on_heap() const { return is_on_heap_; } size_t length() const { return length_; } - void* external_pointer() const { return external_pointer_; } + void* data_ptr() const { return data_ptr_; } void Serialize(JSHeapBroker* broker); bool serialized() const { return serialized_; } @@ -430,7 +436,7 @@ class JSTypedArrayData : public JSObjectData { private: bool const is_on_heap_; size_t const length_; - void* const external_pointer_; + void* const data_ptr_; bool serialized_ = false; HeapObjectData* buffer_ = nullptr; @@ -441,7 +447,7 @@ JSTypedArrayData::JSTypedArrayData(JSHeapBroker* broker, ObjectData** storage, : JSObjectData(broker, storage, object), is_on_heap_(object->is_on_heap()), length_(object->length()), - external_pointer_(object->external_pointer()) {} + data_ptr_(object->DataPtr()) {} void JSTypedArrayData::Serialize(JSHeapBroker* broker) { if (serialized_) return; @@ -833,8 +839,7 @@ bool IsFastLiteralHelper(Handle<JSObject> boilerplate, int max_depth, // Check the in-object properties. Handle<DescriptorArray> descriptors(boilerplate->map().instance_descriptors(), isolate); - int limit = boilerplate->map().NumberOfOwnDescriptors(); - for (int i = 0; i < limit; i++) { + for (InternalIndex i : boilerplate->map().IterateOwnDescriptors()) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; DCHECK_EQ(kData, details.kind()); @@ -962,9 +967,6 @@ class MapData : public HeapObjectData { bool supports_fast_array_resize() const { return supports_fast_array_resize_; } - bool IsMapOfTargetGlobalProxy() const { - return is_map_of_target_global_proxy_; - } bool is_abandoned_prototype_map() const { return is_abandoned_prototype_map_; } @@ -979,9 +981,10 @@ class MapData : public HeapObjectData { // Serialize a single (or all) own slot(s) of the descriptor array and recurse // on field owner(s). - void SerializeOwnDescriptor(JSHeapBroker* broker, int descriptor_index); + void SerializeOwnDescriptor(JSHeapBroker* broker, + InternalIndex descriptor_index); void SerializeOwnDescriptors(JSHeapBroker* broker); - ObjectData* GetStrongValue(int descriptor_index) const; + ObjectData* GetStrongValue(InternalIndex descriptor_index) const; DescriptorArrayData* instance_descriptors() const { return instance_descriptors_; } @@ -1027,7 +1030,6 @@ class MapData : public HeapObjectData { int const unused_property_fields_; bool const supports_fast_array_iteration_; bool const supports_fast_array_resize_; - bool const is_map_of_target_global_proxy_; bool const is_abandoned_prototype_map_; bool serialized_elements_kind_generalizations_ = false; @@ -1109,8 +1111,9 @@ bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) { DCHECK(!jsarray_map->is_dictionary_map()); Handle<Name> length_string = isolate->factory()->length_string(); DescriptorArray descriptors = jsarray_map->instance_descriptors(); - int number = descriptors.Search(*length_string, *jsarray_map); - DCHECK_NE(DescriptorArray::kNotFound, number); + // TODO(jkummerow): We could skip the search and hardcode number == 0. + InternalIndex number = descriptors.Search(*length_string, *jsarray_map); + DCHECK(number.is_found()); return descriptors.GetDetails(number).IsReadOnly(); } @@ -1120,7 +1123,7 @@ bool SupportsFastArrayIteration(Isolate* isolate, Handle<Map> map) { map->prototype().IsJSArray() && isolate->IsAnyInitialArrayPrototype( handle(JSArray::cast(map->prototype()), isolate)) && - isolate->IsNoElementsProtectorIntact(); + Protectors::IsNoElementsIntact(isolate); } bool SupportsFastArrayResize(Isolate* isolate, Handle<Map> map) { @@ -1154,8 +1157,6 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object) SupportsFastArrayIteration(broker->isolate(), object)), supports_fast_array_resize_( SupportsFastArrayResize(broker->isolate(), object)), - is_map_of_target_global_proxy_( - object->IsMapOfGlobalProxy(broker->target_native_context().object())), is_abandoned_prototype_map_(object->is_abandoned_prototype_map()), elements_kind_generalizations_(broker->zone()) {} @@ -1268,7 +1269,6 @@ class FeedbackVectorData : public HeapObjectData { double invocation_count() const { return invocation_count_; } void Serialize(JSHeapBroker* broker); - const ZoneVector<ObjectData*>& feedback() { return feedback_; } FeedbackCellData* GetClosureFeedbackCell(JSHeapBroker* broker, int index) const; @@ -1276,7 +1276,6 @@ class FeedbackVectorData : public HeapObjectData { double const invocation_count_; bool serialized_ = false; - ZoneVector<ObjectData*> feedback_; ZoneVector<ObjectData*> closure_feedback_cell_array_; }; @@ -1285,7 +1284,6 @@ FeedbackVectorData::FeedbackVectorData(JSHeapBroker* broker, Handle<FeedbackVector> object) : HeapObjectData(broker, storage, object), invocation_count_(object->invocation_count()), - feedback_(broker->zone()), closure_feedback_cell_array_(broker->zone()) {} FeedbackCellData* FeedbackVectorData::GetClosureFeedbackCell( @@ -1309,26 +1307,6 @@ void FeedbackVectorData::Serialize(JSHeapBroker* broker) { TraceScope tracer(broker, this, "FeedbackVectorData::Serialize"); Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(object()); - DCHECK(feedback_.empty()); - feedback_.reserve(vector->length()); - for (int i = 0; i < vector->length(); ++i) { - MaybeObject value = vector->get(i); - ObjectData* slot_value = - value->IsObject() ? broker->GetOrCreateData(value->cast<Object>()) - : nullptr; - feedback_.push_back(slot_value); - if (slot_value == nullptr) continue; - - if (slot_value->IsAllocationSite() && - slot_value->AsAllocationSite()->IsFastLiteral()) { - slot_value->AsAllocationSite()->SerializeBoilerplate(broker); - } else if (slot_value->IsJSRegExp()) { - slot_value->AsJSRegExp()->SerializeAsRegExpBoilerplate(broker); - } - } - DCHECK_EQ(vector->length(), feedback_.size()); - TRACE(broker, "Copied " << feedback_.size() << " slots"); - DCHECK(closure_feedback_cell_array_.empty()); int length = vector->closure_feedback_cell_array().length(); closure_feedback_cell_array_.reserve(length); @@ -1496,10 +1474,6 @@ class BytecodeArrayData : public FixedArrayBaseData { return *(Handle<Smi>::cast(constant_pool_[index]->object())); } - bool IsSerializedForCompilation() const { - return is_serialized_for_compilation_; - } - void SerializeForCompilation(JSHeapBroker* broker) { if (is_serialized_for_compilation_) return; @@ -1843,23 +1817,15 @@ class JSGlobalObjectData : public JSObjectData { public: JSGlobalObjectData(JSHeapBroker* broker, ObjectData** storage, Handle<JSGlobalObject> object); -}; - -JSGlobalObjectData::JSGlobalObjectData(JSHeapBroker* broker, - ObjectData** storage, - Handle<JSGlobalObject> object) - : JSObjectData(broker, storage, object) {} - -class JSGlobalProxyData : public JSObjectData { - public: - JSGlobalProxyData(JSHeapBroker* broker, ObjectData** storage, - Handle<JSGlobalProxy> object); + bool IsDetached() const { return is_detached_; } PropertyCellData* GetPropertyCell( JSHeapBroker* broker, NameData* name, SerializationPolicy policy = SerializationPolicy::kAssumeSerialized); private: + bool const is_detached_; + // Properties that either // (1) are known to exist as property cells on the global object, or // (2) are known not to (possibly they don't exist at all). @@ -1867,9 +1833,22 @@ class JSGlobalProxyData : public JSObjectData { ZoneVector<std::pair<NameData*, PropertyCellData*>> properties_; }; +JSGlobalObjectData::JSGlobalObjectData(JSHeapBroker* broker, + ObjectData** storage, + Handle<JSGlobalObject> object) + : JSObjectData(broker, storage, object), + is_detached_(object->IsDetached()), + properties_(broker->zone()) {} + +class JSGlobalProxyData : public JSObjectData { + public: + JSGlobalProxyData(JSHeapBroker* broker, ObjectData** storage, + Handle<JSGlobalProxy> object); +}; + JSGlobalProxyData::JSGlobalProxyData(JSHeapBroker* broker, ObjectData** storage, Handle<JSGlobalProxy> object) - : JSObjectData(broker, storage, object), properties_(broker->zone()) {} + : JSObjectData(broker, storage, object) {} namespace { base::Optional<PropertyCellRef> GetPropertyCellFromHeap(JSHeapBroker* broker, @@ -1888,7 +1867,7 @@ base::Optional<PropertyCellRef> GetPropertyCellFromHeap(JSHeapBroker* broker, } } // namespace -PropertyCellData* JSGlobalProxyData::GetPropertyCell( +PropertyCellData* JSGlobalObjectData::GetPropertyCell( JSHeapBroker* broker, NameData* name, SerializationPolicy policy) { CHECK_NOT_NULL(name); for (auto const& p : properties_) { @@ -1911,6 +1890,13 @@ PropertyCellData* JSGlobalProxyData::GetPropertyCell( return result; } +class TemplateObjectDescriptionData : public HeapObjectData { + public: + TemplateObjectDescriptionData(JSHeapBroker* broker, ObjectData** storage, + Handle<TemplateObjectDescription> object) + : HeapObjectData(broker, storage, object) {} +}; + class CodeData : public HeapObjectData { public: CodeData(JSHeapBroker* broker, ObjectData** storage, Handle<Code> object) @@ -2001,20 +1987,20 @@ void MapData::SerializeOwnDescriptors(JSHeapBroker* broker) { Handle<Map> map = Handle<Map>::cast(object()); int const number_of_own = map->NumberOfOwnDescriptors(); - for (int i = 0; i < number_of_own; ++i) { + for (InternalIndex i : InternalIndex::Range(number_of_own)) { SerializeOwnDescriptor(broker, i); } } -ObjectData* MapData::GetStrongValue(int descriptor_index) const { - auto data = instance_descriptors_->contents().find(descriptor_index); +ObjectData* MapData::GetStrongValue(InternalIndex descriptor_index) const { + auto data = instance_descriptors_->contents().find(descriptor_index.as_int()); if (data == instance_descriptors_->contents().end()) return nullptr; return data->second.value; } void MapData::SerializeOwnDescriptor(JSHeapBroker* broker, - int descriptor_index) { + InternalIndex descriptor_index) { TraceScope tracer(broker, this, "MapData::SerializeOwnDescriptor"); Handle<Map> map = Handle<Map>::cast(object()); @@ -2025,8 +2011,8 @@ void MapData::SerializeOwnDescriptor(JSHeapBroker* broker, ZoneMap<int, PropertyDescriptor>& contents = instance_descriptors()->contents(); - CHECK_LT(descriptor_index, map->NumberOfOwnDescriptors()); - if (contents.find(descriptor_index) != contents.end()) return; + CHECK_LT(descriptor_index.as_int(), map->NumberOfOwnDescriptors()); + if (contents.find(descriptor_index.as_int()) != contents.end()) return; Isolate* const isolate = broker->isolate(); auto descriptors = @@ -2051,14 +2037,14 @@ void MapData::SerializeOwnDescriptor(JSHeapBroker* broker, broker->GetOrCreateData(descriptors->GetFieldType(descriptor_index)); d.is_unboxed_double_field = map->IsUnboxedDoubleField(d.field_index); } - contents[descriptor_index] = d; + contents[descriptor_index.as_int()] = d; if (d.details.location() == kField) { // Recurse on the owner map. d.field_owner->SerializeOwnDescriptor(broker, descriptor_index); } - TRACE(broker, "Copied descriptor " << descriptor_index << " into " + TRACE(broker, "Copied descriptor " << descriptor_index.as_int() << " into " << instance_descriptors_ << " (" << contents.size() << " total)"); } @@ -2146,8 +2132,7 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker, // Check the in-object properties. Handle<DescriptorArray> descriptors(boilerplate->map().instance_descriptors(), isolate); - int const limit = boilerplate->map().NumberOfOwnDescriptors(); - for (int i = 0; i < limit; i++) { + for (InternalIndex i : boilerplate->map().IterateOwnDescriptors()) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; DCHECK_EQ(kData, details.kind()); @@ -2210,6 +2195,12 @@ void JSRegExpData::SerializeAsRegExpBoilerplate(JSHeapBroker* broker) { } bool ObjectRef::equals(const ObjectRef& other) const { +#ifdef DEBUG + if (broker()->mode() == JSHeapBroker::kSerialized && + data_->used_status == ObjectData::Usage::kUnused) { + data_->used_status = ObjectData::Usage::kOnlyIdentityUsed; + } +#endif // DEBUG return data_ == other.data_; } @@ -2269,7 +2260,7 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, TRACE(this, "Constructing heap broker"); } -std::ostream& JSHeapBroker::Trace() { +std::ostream& JSHeapBroker::Trace() const { return trace_out_ << "[" << this << "] " << std::string(trace_indentation_ * 2, ' '); } @@ -2280,10 +2271,92 @@ void JSHeapBroker::StopSerializing() { mode_ = kSerialized; } +#ifdef DEBUG +void JSHeapBroker::PrintRefsAnalysis() const { + // Usage counts + size_t used_total = 0, unused_total = 0, identity_used_total = 0; + for (RefsMap::Entry* ref = refs_->Start(); ref != nullptr; + ref = refs_->Next(ref)) { + switch (ref->value->used_status) { + case ObjectData::Usage::kUnused: + ++unused_total; + break; + case ObjectData::Usage::kOnlyIdentityUsed: + ++identity_used_total; + break; + case ObjectData::Usage::kDataUsed: + ++used_total; + break; + } + } + + // Ref types analysis + TRACE_BROKER_MEMORY( + this, "Refs: " << refs_->occupancy() << "; data used: " << used_total + << "; only identity used: " << identity_used_total + << "; unused: " << unused_total); + size_t used_smis = 0, unused_smis = 0, identity_used_smis = 0; + size_t used[LAST_TYPE + 1] = {0}; + size_t unused[LAST_TYPE + 1] = {0}; + size_t identity_used[LAST_TYPE + 1] = {0}; + for (RefsMap::Entry* ref = refs_->Start(); ref != nullptr; + ref = refs_->Next(ref)) { + if (ref->value->is_smi()) { + switch (ref->value->used_status) { + case ObjectData::Usage::kUnused: + ++unused_smis; + break; + case ObjectData::Usage::kOnlyIdentityUsed: + ++identity_used_smis; + break; + case ObjectData::Usage::kDataUsed: + ++used_smis; + break; + } + } else { + InstanceType instance_type = + static_cast<const HeapObjectData*>(ref->value) + ->map() + ->instance_type(); + CHECK_LE(FIRST_TYPE, instance_type); + CHECK_LE(instance_type, LAST_TYPE); + switch (ref->value->used_status) { + case ObjectData::Usage::kUnused: + ++unused[instance_type]; + break; + case ObjectData::Usage::kOnlyIdentityUsed: + ++identity_used[instance_type]; + break; + case ObjectData::Usage::kDataUsed: + ++used[instance_type]; + break; + } + } + } + + TRACE_BROKER_MEMORY( + this, "Smis: " << used_smis + identity_used_smis + unused_smis + << "; data used: " << used_smis << "; only identity used: " + << identity_used_smis << "; unused: " << unused_smis); + for (uint16_t i = FIRST_TYPE; i <= LAST_TYPE; ++i) { + size_t total = used[i] + identity_used[i] + unused[i]; + if (total == 0) continue; + TRACE_BROKER_MEMORY( + this, InstanceType(i) << ": " << total << "; data used: " << used[i] + << "; only identity used: " << identity_used[i] + << "; unused: " << unused[i]); + } +} +#endif // DEBUG + void JSHeapBroker::Retire() { CHECK_EQ(mode_, kSerialized); TRACE(this, "Retiring"); mode_ = kRetired; + +#ifdef DEBUG + PrintRefsAnalysis(); +#endif // DEBUG } bool JSHeapBroker::SerializingAllowed() const { return mode() == kSerializing; } @@ -2473,6 +2546,7 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->empty_fixed_array()); GetOrCreateData(f->empty_string()); GetOrCreateData(f->eval_context_map()); + GetOrCreateData(f->exec_string()); GetOrCreateData(f->false_string()); GetOrCreateData(f->false_value()); GetOrCreateData(f->fixed_array_map()); @@ -2480,11 +2554,13 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->fixed_double_array_map()); GetOrCreateData(f->function_context_map()); GetOrCreateData(f->function_string()); + GetOrCreateData(f->has_instance_symbol()); GetOrCreateData(f->heap_number_map()); GetOrCreateData(f->length_string()); GetOrCreateData(f->many_closures_cell_map()); GetOrCreateData(f->minus_zero_value()); GetOrCreateData(f->name_dictionary_map()); + GetOrCreateData(f->name_string()); GetOrCreateData(f->NaN_string()); GetOrCreateData(f->null_map()); GetOrCreateData(f->null_string()); @@ -2495,6 +2571,7 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->optimized_out()); GetOrCreateData(f->optimized_out_map()); GetOrCreateData(f->property_array_map()); + GetOrCreateData(f->prototype_string()); GetOrCreateData(f->ReflectHas_string()); GetOrCreateData(f->ReflectGet_string()); GetOrCreateData(f->sloppy_arguments_elements_map()); @@ -2505,6 +2582,7 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->termination_exception_map()); GetOrCreateData(f->the_hole_map()); GetOrCreateData(f->the_hole_value()); + GetOrCreateData(f->then_string()); GetOrCreateData(f->true_string()); GetOrCreateData(f->true_value()); GetOrCreateData(f->undefined_map()); @@ -2517,7 +2595,9 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->array_buffer_detaching_protector()) ->AsPropertyCell() ->Serialize(this); - GetOrCreateData(f->array_constructor_protector())->AsCell()->Serialize(this); + GetOrCreateData(f->array_constructor_protector()) + ->AsPropertyCell() + ->Serialize(this); GetOrCreateData(f->array_iterator_protector()) ->AsPropertyCell() ->Serialize(this); @@ -2537,7 +2617,9 @@ void JSHeapBroker::InitializeAndStartSerializing( GetOrCreateData(f->promise_then_protector()) ->AsPropertyCell() ->Serialize(this); - GetOrCreateData(f->string_length_protector())->AsCell()->Serialize(this); + GetOrCreateData(f->string_length_protector()) + ->AsPropertyCell() + ->Serialize(this); // - CEntry stub GetOrCreateData( CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, true)); @@ -2719,16 +2801,6 @@ bool MapRef::supports_fast_array_resize() const { return data()->AsMap()->supports_fast_array_resize(); } -bool MapRef::IsMapOfTargetGlobalProxy() const { - if (broker()->mode() == JSHeapBroker::kDisabled) { - AllowHandleDereference allow_handle_dereference; - AllowHandleAllocation handle_allocation; - return object()->IsMapOfGlobalProxy( - broker()->target_native_context().object()); - } - return data()->AsMap()->IsMapOfTargetGlobalProxy(); -} - int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; @@ -2785,18 +2857,6 @@ OddballType MapRef::oddball_type() const { return OddballType::kOther; } -ObjectRef FeedbackVectorRef::get(FeedbackSlot slot) const { - if (broker()->mode() == JSHeapBroker::kDisabled) { - AllowHandleAllocation handle_allocation; - AllowHandleDereference handle_dereference; - Handle<Object> value(object()->Get(slot)->cast<Object>(), - broker()->isolate()); - return ObjectRef(broker(), value); - } - int i = FeedbackVector::GetIndex(slot); - return ObjectRef(broker(), data()->AsFeedbackVector()->feedback().at(i)); -} - FeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; @@ -2854,6 +2914,11 @@ bool AllocationSiteRef::IsFastLiteral() const { return data()->AsAllocationSite()->IsFastLiteral(); } +void AllocationSiteRef::SerializeBoilerplate() { + CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); + data()->AsAllocationSite()->SerializeBoilerplate(broker()); +} + void JSObjectRef::SerializeElements() { CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsJSObject()->SerializeElements(broker()); @@ -2880,13 +2945,13 @@ void JSObjectRef::EnsureElementsTenured() { CHECK(data()->AsJSObject()->cow_or_empty_elements_tenured()); } -FieldIndex MapRef::GetFieldIndexFor(int descriptor_index) const { +FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; return FieldIndex::ForDescriptor(*object(), descriptor_index); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return descriptors->contents().at(descriptor_index).field_index; + return descriptors->contents().at(descriptor_index.as_int()).field_index; } int MapRef::GetInObjectPropertyOffset(int i) const { @@ -2897,16 +2962,17 @@ int MapRef::GetInObjectPropertyOffset(int i) const { return (GetInObjectPropertiesStartInWords() + i) * kTaggedSize; } -PropertyDetails MapRef::GetPropertyDetails(int descriptor_index) const { +PropertyDetails MapRef::GetPropertyDetails( + InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; return object()->instance_descriptors().GetDetails(descriptor_index); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return descriptors->contents().at(descriptor_index).details; + return descriptors->contents().at(descriptor_index.as_int()).details; } -NameRef MapRef::GetPropertyKey(int descriptor_index) const { +NameRef MapRef::GetPropertyKey(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; AllowHandleDereference allow_handle_dereference; @@ -2916,7 +2982,8 @@ NameRef MapRef::GetPropertyKey(int descriptor_index) const { broker()->isolate())); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return NameRef(broker(), descriptors->contents().at(descriptor_index).key); + return NameRef(broker(), + descriptors->contents().at(descriptor_index.as_int()).key); } bool MapRef::IsFixedCowArrayMap() const { @@ -2926,10 +2993,10 @@ bool MapRef::IsFixedCowArrayMap() const { } bool MapRef::IsPrimitiveMap() const { - return instance_type() <= LAST_PRIMITIVE_TYPE; + return instance_type() <= LAST_PRIMITIVE_HEAP_OBJECT_TYPE; } -MapRef MapRef::FindFieldOwner(int descriptor_index) const { +MapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; AllowHandleDereference allow_handle_dereference; @@ -2939,11 +3006,12 @@ MapRef MapRef::FindFieldOwner(int descriptor_index) const { return MapRef(broker(), owner); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return MapRef(broker(), - descriptors->contents().at(descriptor_index).field_owner); + return MapRef( + broker(), + descriptors->contents().at(descriptor_index.as_int()).field_owner); } -ObjectRef MapRef::GetFieldType(int descriptor_index) const { +ObjectRef MapRef::GetFieldType(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; AllowHandleDereference allow_handle_dereference; @@ -2953,18 +3021,21 @@ ObjectRef MapRef::GetFieldType(int descriptor_index) const { return ObjectRef(broker(), field_type); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return ObjectRef(broker(), - descriptors->contents().at(descriptor_index).field_type); + return ObjectRef( + broker(), + descriptors->contents().at(descriptor_index.as_int()).field_type); } -bool MapRef::IsUnboxedDoubleField(int descriptor_index) const { +bool MapRef::IsUnboxedDoubleField(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; return object()->IsUnboxedDoubleField( FieldIndex::ForDescriptor(*object(), descriptor_index)); } DescriptorArrayData* descriptors = data()->AsMap()->instance_descriptors(); - return descriptors->contents().at(descriptor_index).is_unboxed_double_field; + return descriptors->contents() + .at(descriptor_index.as_int()) + .is_unboxed_double_field; } uint16_t StringRef::GetFirstChar() { @@ -3074,11 +3145,6 @@ Smi BytecodeArrayRef::GetConstantAtIndexAsSmi(int index) const { return data()->AsBytecodeArray()->GetConstantAtIndexAsSmi(index); } -bool BytecodeArrayRef::IsSerializedForCompilation() const { - if (broker()->mode() == JSHeapBroker::kDisabled) return true; - return data()->AsBytecodeArray()->IsSerializedForCompilation(); -} - void BytecodeArrayRef::SerializeForCompilation() { if (broker()->mode() == JSHeapBroker::kDisabled) return; data()->AsBytecodeArray()->SerializeForCompilation(broker()); @@ -3191,6 +3257,8 @@ BIMODAL_ACCESSOR(JSFunction, Object, prototype) BIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared) BIMODAL_ACCESSOR(JSFunction, FeedbackVector, feedback_vector) +BIMODAL_ACCESSOR_C(JSGlobalObject, bool, IsDetached) + BIMODAL_ACCESSOR_C(JSTypedArray, bool, is_on_heap) BIMODAL_ACCESSOR_C(JSTypedArray, size_t, length) BIMODAL_ACCESSOR(JSTypedArray, HeapObject, buffer) @@ -3345,7 +3413,7 @@ BIMODAL_ACCESSOR_C(String, int, length) BIMODAL_ACCESSOR(FeedbackCell, HeapObject, value) -ObjectRef MapRef::GetStrongValue(int descriptor_index) const { +ObjectRef MapRef::GetStrongValue(InternalIndex descriptor_index) const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; return ObjectRef(broker(), @@ -3376,12 +3444,12 @@ base::Optional<MapRef> MapRef::FindRootMap() const { return base::nullopt; } -void* JSTypedArrayRef::external_pointer() const { +void* JSTypedArrayRef::data_ptr() const { if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleDereference allow_handle_dereference; - return object()->external_pointer(); + return object()->DataPtr(); } - return data()->AsJSTypedArray()->external_pointer(); + return data()->AsJSTypedArray()->data_ptr(); } bool MapRef::IsInobjectSlackTrackingInProgress() const { @@ -3774,12 +3842,37 @@ ObjectRef JSRegExpRef::source() const { return ObjectRef(broker(), ObjectRef::data()->AsJSRegExp()->source()); } -Handle<Object> ObjectRef::object() const { return data_->object(); } +void JSRegExpRef::SerializeAsRegExpBoilerplate() { + CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); + JSObjectRef::data()->AsJSRegExp()->SerializeAsRegExpBoilerplate(broker()); +} +Handle<Object> ObjectRef::object() const { +#ifdef DEBUG + if (broker()->mode() == JSHeapBroker::kSerialized && + data_->used_status == ObjectData::Usage::kUnused) { + data_->used_status = ObjectData::Usage::kOnlyIdentityUsed; + } +#endif // DEBUG + return data_->object(); +} + +#ifdef DEBUG #define DEF_OBJECT_GETTER(T) \ Handle<T> T##Ref::object() const { \ + if (broker()->mode() == JSHeapBroker::kSerialized && \ + data_->used_status == ObjectData::Usage::kUnused) { \ + data_->used_status = ObjectData::Usage::kOnlyIdentityUsed; \ + } \ return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \ } +#else +#define DEF_OBJECT_GETTER(T) \ + Handle<T> T##Ref::object() const { \ + return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \ + } +#endif // DEBUG + HEAP_BROKER_OBJECT_LIST(DEF_OBJECT_GETTER) #undef DEF_OBJECT_GETTER @@ -3791,7 +3884,12 @@ ObjectData* ObjectRef::data() const { CHECK_NE(data_->kind(), kSerializedHeapObject); return data_; case JSHeapBroker::kSerializing: + CHECK_NE(data_->kind(), kUnserializedHeapObject); + return data_; case JSHeapBroker::kSerialized: +#ifdef DEBUG + data_->used_status = ObjectData::Usage::kDataUsed; +#endif // DEBUG CHECK_NE(data_->kind(), kUnserializedHeapObject); return data_; case JSHeapBroker::kRetired: @@ -3857,60 +3955,50 @@ bool JSFunctionRef::serialized() const { return data()->AsJSFunction()->serialized(); } -bool JSFunctionRef::IsSerializedForCompilation() const { - if (broker()->mode() == JSHeapBroker::kDisabled) { - return handle(object()->shared(), broker()->isolate())->HasBytecodeArray(); - } - - // We get a crash if we try to access the shared() getter without - // checking for `serialized` first. Also it's possible to have a - // JSFunctionRef without a feedback vector. - return serialized() && has_feedback_vector() && - shared().IsSerializedForCompilation(feedback_vector()); -} - JSArrayRef SharedFunctionInfoRef::GetTemplateObject( - ObjectRef description, FeedbackVectorRef vector, FeedbackSlot slot, + TemplateObjectDescriptionRef description, FeedbackSource const& source, SerializationPolicy policy) { - // Look in the feedback vector for the array. A Smi indicates that it's - // not yet cached here. - ObjectRef candidate = vector.get(slot); - if (!candidate.IsSmi()) { - return candidate.AsJSArray(); + // First, see if we have processed feedback from the vector, respecting + // the serialization policy. + ProcessedFeedback const& feedback = + policy == SerializationPolicy::kSerializeIfNeeded + ? broker()->ProcessFeedbackForTemplateObject(source) + : broker()->GetFeedbackForTemplateObject(source); + + if (!feedback.IsInsufficient()) { + return feedback.AsTemplateObject().value(); } if (broker()->mode() == JSHeapBroker::kDisabled) { AllowHandleAllocation handle_allocation; AllowHandleDereference allow_handle_dereference; - Handle<TemplateObjectDescription> tod = - Handle<TemplateObjectDescription>::cast(description.object()); Handle<JSArray> template_object = TemplateObjectDescription::GetTemplateObject( - broker()->isolate(), broker()->target_native_context().object(), - tod, object(), slot.ToInt()); + isolate(), broker()->target_native_context().object(), + description.object(), object(), source.slot.ToInt()); return JSArrayRef(broker(), template_object); } - JSArrayData* array = data()->AsSharedFunctionInfo()->GetTemplateObject(slot); + JSArrayData* array = + data()->AsSharedFunctionInfo()->GetTemplateObject(source.slot); if (array != nullptr) return JSArrayRef(broker(), array); CHECK_EQ(policy, SerializationPolicy::kSerializeIfNeeded); CHECK(broker()->SerializingAllowed()); - Handle<TemplateObjectDescription> tod = - Handle<TemplateObjectDescription>::cast(description.object()); Handle<JSArray> template_object = TemplateObjectDescription::GetTemplateObject( - broker()->isolate(), broker()->target_native_context().object(), tod, - object(), slot.ToInt()); + broker()->isolate(), broker()->target_native_context().object(), + description.object(), object(), source.slot.ToInt()); array = broker()->GetOrCreateData(template_object)->AsJSArray(); - data()->AsSharedFunctionInfo()->SetTemplateObject(slot, array); + data()->AsSharedFunctionInfo()->SetTemplateObject(source.slot, array); return JSArrayRef(broker(), array); } void SharedFunctionInfoRef::SetSerializedForCompilation( FeedbackVectorRef feedback) { CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); + CHECK(HasBytecodeArray()); data()->AsSharedFunctionInfo()->SetSerializedForCompilation(broker(), feedback); } @@ -3937,7 +4025,7 @@ SharedFunctionInfoRef::function_template_info() const { bool SharedFunctionInfoRef::IsSerializedForCompilation( FeedbackVectorRef feedback) const { - if (broker()->mode() == JSHeapBroker::kDisabled) return true; + if (broker()->mode() == JSHeapBroker::kDisabled) return HasBytecodeArray(); return data()->AsSharedFunctionInfo()->IsSerializedForCompilation(feedback); } @@ -3953,19 +4041,19 @@ void MapRef::SerializeOwnDescriptors() { data()->AsMap()->SerializeOwnDescriptors(broker()); } -void MapRef::SerializeOwnDescriptor(int descriptor_index) { +void MapRef::SerializeOwnDescriptor(InternalIndex descriptor_index) { if (broker()->mode() == JSHeapBroker::kDisabled) return; CHECK_EQ(broker()->mode(), JSHeapBroker::kSerializing); data()->AsMap()->SerializeOwnDescriptor(broker(), descriptor_index); } -bool MapRef::serialized_own_descriptor(int descriptor_index) const { - CHECK_LT(descriptor_index, NumberOfOwnDescriptors()); +bool MapRef::serialized_own_descriptor(InternalIndex descriptor_index) const { + CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); if (broker()->mode() == JSHeapBroker::kDisabled) return true; DescriptorArrayData* desc_array_data = data()->AsMap()->instance_descriptors(); if (!desc_array_data) return false; - return desc_array_data->contents().find(descriptor_index) != + return desc_array_data->contents().find(descriptor_index.as_int()) != desc_array_data->contents().end(); } @@ -4027,14 +4115,14 @@ void FunctionTemplateInfoRef::SerializeCallCode() { data()->AsFunctionTemplateInfo()->SerializeCallCode(broker()); } -base::Optional<PropertyCellRef> JSGlobalProxyRef::GetPropertyCell( +base::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell( NameRef const& name, SerializationPolicy policy) const { if (broker()->mode() == JSHeapBroker::kDisabled) { return GetPropertyCellFromHeap(broker(), name.object()); } PropertyCellData* property_cell_data = - data()->AsJSGlobalProxy()->GetPropertyCell(broker(), - name.data()->AsName(), policy); + data()->AsJSGlobalObject()->GetPropertyCell( + broker(), name.data()->AsName(), policy); if (property_cell_data == nullptr) return base::nullopt; return PropertyCellRef(broker(), property_cell_data); } @@ -4265,6 +4353,7 @@ void JSHeapBroker::SetFeedback(FeedbackSource const& source, } bool JSHeapBroker::HasFeedback(FeedbackSource const& source) const { + DCHECK(source.IsValid()); return feedback_.find(source) != feedback_.end(); } @@ -4315,7 +4404,6 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess( MapHandles maps; nexus.ExtractMaps(&maps); - DCHECK_NE(nexus.ic_state(), PREMONOMORPHIC); if (!maps.empty()) { maps = GetRelevantReceiverMaps(isolate(), maps); if (maps.empty()) return *new (zone()) InsufficientFeedback(kind); @@ -4424,6 +4512,47 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForInstanceOf( return *new (zone()) InstanceOfFeedback(optional_constructor, nexus.kind()); } +ProcessedFeedback const& JSHeapBroker::ReadFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source) { + FeedbackNexus nexus(source.vector, source.slot); + HeapObject object; + if (nexus.IsUninitialized() || !nexus.GetFeedback()->GetHeapObject(&object)) { + return *new (zone()) InsufficientFeedback(nexus.kind()); + } + + AllocationSiteRef site(this, handle(object, isolate())); + if (site.IsFastLiteral()) { + site.SerializeBoilerplate(); + } + + return *new (zone()) LiteralFeedback(site, nexus.kind()); +} + +ProcessedFeedback const& JSHeapBroker::ReadFeedbackForRegExpLiteral( + FeedbackSource const& source) { + FeedbackNexus nexus(source.vector, source.slot); + HeapObject object; + if (nexus.IsUninitialized() || !nexus.GetFeedback()->GetHeapObject(&object)) { + return *new (zone()) InsufficientFeedback(nexus.kind()); + } + + JSRegExpRef regexp(this, handle(object, isolate())); + regexp.SerializeAsRegExpBoilerplate(); + return *new (zone()) RegExpLiteralFeedback(regexp, nexus.kind()); +} + +ProcessedFeedback const& JSHeapBroker::ReadFeedbackForTemplateObject( + FeedbackSource const& source) { + FeedbackNexus nexus(source.vector, source.slot); + HeapObject object; + if (nexus.IsUninitialized() || !nexus.GetFeedback()->GetHeapObject(&object)) { + return *new (zone()) InsufficientFeedback(nexus.kind()); + } + + JSArrayRef array(this, handle(object, isolate())); + return *new (zone()) TemplateObjectFeedback(array, nexus.kind()); +} + ProcessedFeedback const& JSHeapBroker::ReadFeedbackForCall( FeedbackSource const& source) { FeedbackNexus nexus(source.vector, source.slot); @@ -4495,6 +4624,50 @@ ProcessedFeedback const& JSHeapBroker::GetFeedbackForGlobalAccess( : ProcessFeedbackForGlobalAccess(source); } +ProcessedFeedback const& JSHeapBroker::GetFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source) { + return FLAG_concurrent_inlining + ? GetFeedback(source) + : ProcessFeedbackForArrayOrObjectLiteral(source); +} + +ProcessedFeedback const& JSHeapBroker::GetFeedbackForRegExpLiteral( + FeedbackSource const& source) { + return FLAG_concurrent_inlining ? GetFeedback(source) + : ProcessFeedbackForRegExpLiteral(source); +} + +ProcessedFeedback const& JSHeapBroker::GetFeedbackForTemplateObject( + FeedbackSource const& source) { + return FLAG_concurrent_inlining ? GetFeedback(source) + : ProcessFeedbackForTemplateObject(source); +} + +ProcessedFeedback const& JSHeapBroker::ProcessFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source) { + if (HasFeedback(source)) return GetFeedback(source); + ProcessedFeedback const& feedback = + ReadFeedbackForArrayOrObjectLiteral(source); + SetFeedback(source, &feedback); + return feedback; +} + +ProcessedFeedback const& JSHeapBroker::ProcessFeedbackForRegExpLiteral( + FeedbackSource const& source) { + if (HasFeedback(source)) return GetFeedback(source); + ProcessedFeedback const& feedback = ReadFeedbackForRegExpLiteral(source); + SetFeedback(source, &feedback); + return feedback; +} + +ProcessedFeedback const& JSHeapBroker::ProcessFeedbackForTemplateObject( + FeedbackSource const& source) { + if (HasFeedback(source)) return GetFeedback(source); + ProcessedFeedback const& feedback = ReadFeedbackForTemplateObject(source); + SetFeedback(source, &feedback); + return feedback; +} + ProcessedFeedback const& JSHeapBroker::ProcessFeedbackForBinaryOperation( FeedbackSource const& source) { if (HasFeedback(source)) return GetFeedback(source); @@ -4650,9 +4823,10 @@ void ElementAccessFeedback::AddGroup(TransitionGroup&& group) { } std::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { - if (ref.broker()->mode() == JSHeapBroker::kDisabled) { - // If the broker is disabled we cannot be in a background thread so it's - // safe to read the heap. + if (ref.broker()->mode() == JSHeapBroker::kDisabled || + !FLAG_concurrent_recompilation) { + // We cannot be in a background thread so it's safe to read the heap. + AllowHandleDereference allow_handle_dereference; return os << ref.data() << " {" << ref.object() << "}"; } else { return os << ref.data(); @@ -4734,6 +4908,21 @@ NamedAccessFeedback const& ProcessedFeedback::AsNamedAccess() const { return *static_cast<NamedAccessFeedback const*>(this); } +LiteralFeedback const& ProcessedFeedback::AsLiteral() const { + CHECK_EQ(kLiteral, kind()); + return *static_cast<LiteralFeedback const*>(this); +} + +RegExpLiteralFeedback const& ProcessedFeedback::AsRegExpLiteral() const { + CHECK_EQ(kRegExpLiteral, kind()); + return *static_cast<RegExpLiteralFeedback const*>(this); +} + +TemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const { + CHECK_EQ(kTemplateObject, kind()); + return *static_cast<TemplateObjectFeedback const*>(this); +} + BytecodeAnalysis const& JSHeapBroker::GetBytecodeAnalysis( Handle<BytecodeArray> bytecode_array, BailoutId osr_bailout_id, bool analyze_liveness, SerializationPolicy policy) { diff --git a/deps/v8/src/compiler/js-heap-broker.h b/deps/v8/src/compiler/js-heap-broker.h index 8c2622bf488c7c..c9667a2fedf093 100644 --- a/deps/v8/src/compiler/js-heap-broker.h +++ b/deps/v8/src/compiler/js-heap-broker.h @@ -34,6 +34,12 @@ std::ostream& operator<<(std::ostream& os, const ObjectRef& ref); broker->Trace() << x << '\n'; \ } while (false) +#define TRACE_BROKER_MEMORY(broker, x) \ + do { \ + if (broker->tracing_enabled() && FLAG_trace_heap_broker_memory) \ + broker->Trace() << x << std::endl; \ + } while (false) + #define TRACE_BROKER_MISSING(broker, x) \ do { \ if (broker->tracing_enabled()) \ @@ -86,6 +92,10 @@ class V8_EXPORT_PRIVATE JSHeapBroker { void Retire(); bool SerializingAllowed() const; +#ifdef DEBUG + void PrintRefsAnalysis() const; +#endif // DEBUG + // Returns nullptr iff handle unknown. ObjectData* GetData(Handle<Object>) const; // Never returns nullptr. @@ -125,6 +135,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { FeedbackSource const& source); ProcessedFeedback const& GetFeedbackForInstanceOf( FeedbackSource const& source); + ProcessedFeedback const& GetFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source); + ProcessedFeedback const& GetFeedbackForRegExpLiteral( + FeedbackSource const& source); + ProcessedFeedback const& GetFeedbackForTemplateObject( + FeedbackSource const& source); ProcessedFeedback const& GetFeedbackForPropertyAccess( FeedbackSource const& source, AccessMode mode, base::Optional<NameRef> static_name); @@ -143,6 +159,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ProcessedFeedback const& ProcessFeedbackForPropertyAccess( FeedbackSource const& source, AccessMode mode, base::Optional<NameRef> static_name); + ProcessedFeedback const& ProcessFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source); + ProcessedFeedback const& ProcessFeedbackForRegExpLiteral( + FeedbackSource const& source); + ProcessedFeedback const& ProcessFeedbackForTemplateObject( + FeedbackSource const& source); bool FeedbackIsInsufficient(FeedbackSource const& source) const; @@ -157,7 +179,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { StringRef GetTypedArrayStringTag(ElementsKind kind); - std::ostream& Trace(); + std::ostream& Trace() const; void IncrementTracingIndentation(); void DecrementTracingIndentation(); @@ -182,6 +204,12 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ProcessedFeedback const& ReadFeedbackForPropertyAccess( FeedbackSource const& source, AccessMode mode, base::Optional<NameRef> static_name); + ProcessedFeedback const& ReadFeedbackForArrayOrObjectLiteral( + FeedbackSource const& source); + ProcessedFeedback const& ReadFeedbackForRegExpLiteral( + FeedbackSource const& source); + ProcessedFeedback const& ReadFeedbackForTemplateObject( + FeedbackSource const& source); void InitializeRefsMap(); void CollectArrayAndObjectPrototypes(); @@ -199,7 +227,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { array_and_object_prototypes_; BrokerMode mode_ = kDisabled; bool const tracing_enabled_; - StdoutStream trace_out_; + mutable StdoutStream trace_out_; unsigned trace_indentation_ = 0; PerIsolateCompilerCache* compiler_cache_ = nullptr; ZoneUnorderedMap<FeedbackSource, ProcessedFeedback const*, diff --git a/deps/v8/src/compiler/js-heap-copy-reducer.cc b/deps/v8/src/compiler/js-heap-copy-reducer.cc index bf4b79bf92cbbf..13bd6a12828009 100644 --- a/deps/v8/src/compiler/js-heap-copy-reducer.cc +++ b/deps/v8/src/compiler/js-heap-copy-reducer.cc @@ -12,6 +12,7 @@ #include "src/heap/factory-inl.h" #include "src/objects/map.h" #include "src/objects/scope-info.h" +#include "src/objects/template-objects.h" namespace v8 { namespace internal { @@ -27,172 +28,145 @@ JSHeapBroker* JSHeapCopyReducer::broker() { return broker_; } Reduction JSHeapCopyReducer::Reduce(Node* node) { switch (node->opcode()) { case IrOpcode::kHeapConstant: { - if (!FLAG_concurrent_inlining) { - ObjectRef object(broker(), HeapConstantOf(node->op())); - if (object.IsJSFunction()) object.AsJSFunction().Serialize(); - if (object.IsJSObject()) { - object.AsJSObject().SerializeObjectCreateMap(); - } - if (object.IsSourceTextModule()) { - object.AsSourceTextModule().Serialize(); - } + ObjectRef object(broker(), HeapConstantOf(node->op())); + if (object.IsJSFunction()) object.AsJSFunction().Serialize(); + if (object.IsJSObject()) { + object.AsJSObject().SerializeObjectCreateMap(); + } + if (object.IsSourceTextModule()) { + object.AsSourceTextModule().Serialize(); } break; } case IrOpcode::kJSCreateArray: { - if (!FLAG_concurrent_inlining) { - CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); - Handle<AllocationSite> site; - if (p.site().ToHandle(&site)) AllocationSiteRef(broker(), site); - } + CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); + Handle<AllocationSite> site; + if (p.site().ToHandle(&site)) AllocationSiteRef(broker(), site); break; } case IrOpcode::kJSCreateArguments: { - if (!FLAG_concurrent_inlining) { - Node* const frame_state = NodeProperties::GetFrameStateInput(node); - FrameStateInfo state_info = FrameStateInfoOf(frame_state->op()); - SharedFunctionInfoRef shared( - broker(), state_info.shared_info().ToHandleChecked()); - } + Node* const frame_state = NodeProperties::GetFrameStateInput(node); + FrameStateInfo state_info = FrameStateInfoOf(frame_state->op()); + SharedFunctionInfoRef shared(broker(), + state_info.shared_info().ToHandleChecked()); break; } case IrOpcode::kJSCreateBlockContext: { - if (!FLAG_concurrent_inlining) { - ScopeInfoRef(broker(), ScopeInfoOf(node->op())); - } + ScopeInfoRef(broker(), ScopeInfoOf(node->op())); break; } case IrOpcode::kJSCreateBoundFunction: { - if (!FLAG_concurrent_inlining) { - CreateBoundFunctionParameters const& p = - CreateBoundFunctionParametersOf(node->op()); - MapRef(broker(), p.map()); - } + CreateBoundFunctionParameters const& p = + CreateBoundFunctionParametersOf(node->op()); + MapRef(broker(), p.map()); break; } case IrOpcode::kJSCreateCatchContext: { - if (!FLAG_concurrent_inlining) { - ScopeInfoRef(broker(), ScopeInfoOf(node->op())); - } + ScopeInfoRef(broker(), ScopeInfoOf(node->op())); break; } case IrOpcode::kJSCreateClosure: { - if (!FLAG_concurrent_inlining) { - CreateClosureParameters const& p = - CreateClosureParametersOf(node->op()); - SharedFunctionInfoRef(broker(), p.shared_info()); - FeedbackCellRef(broker(), p.feedback_cell()); - HeapObjectRef(broker(), p.code()); - } + CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); + SharedFunctionInfoRef(broker(), p.shared_info()); + FeedbackCellRef(broker(), p.feedback_cell()); + HeapObjectRef(broker(), p.code()); break; } case IrOpcode::kJSCreateEmptyLiteralArray: { - if (!FLAG_concurrent_inlining) { - FeedbackParameter const& p = FeedbackParameterOf(node->op()); - FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); + FeedbackParameter const& p = FeedbackParameterOf(node->op()); + if (p.feedback().IsValid()) { + broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback()); } break; } case IrOpcode::kJSCreateFunctionContext: { - if (!FLAG_concurrent_inlining) { - CreateFunctionContextParameters const& p = - CreateFunctionContextParametersOf(node->op()); - ScopeInfoRef(broker(), p.scope_info()); - } + CreateFunctionContextParameters const& p = + CreateFunctionContextParametersOf(node->op()); + ScopeInfoRef(broker(), p.scope_info()); break; } case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralObject: { - if (!FLAG_concurrent_inlining) { - CreateLiteralParameters const& p = - CreateLiteralParametersOf(node->op()); - FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); + CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); + if (p.feedback().IsValid()) { + broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback()); } break; } case IrOpcode::kJSCreateLiteralRegExp: { - if (!FLAG_concurrent_inlining) { - CreateLiteralParameters const& p = - CreateLiteralParametersOf(node->op()); - FeedbackVectorRef(broker(), p.feedback().vector).Serialize(); + CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); + if (p.feedback().IsValid()) { + broker()->ProcessFeedbackForRegExpLiteral(p.feedback()); } break; } + case IrOpcode::kJSGetTemplateObject: { + GetTemplateObjectParameters const& p = + GetTemplateObjectParametersOf(node->op()); + SharedFunctionInfoRef shared(broker(), p.shared()); + TemplateObjectDescriptionRef description(broker(), p.description()); + shared.GetTemplateObject(description, p.feedback(), + SerializationPolicy::kSerializeIfNeeded); + break; + } case IrOpcode::kJSCreateWithContext: { - if (!FLAG_concurrent_inlining) { - ScopeInfoRef(broker(), ScopeInfoOf(node->op())); - } + ScopeInfoRef(broker(), ScopeInfoOf(node->op())); break; } case IrOpcode::kJSLoadNamed: { - if (!FLAG_concurrent_inlining) { - NamedAccess const& p = NamedAccessOf(node->op()); - NameRef name(broker(), p.name()); - if (p.feedback().IsValid()) { - broker()->ProcessFeedbackForPropertyAccess(p.feedback(), - AccessMode::kLoad, name); - } + NamedAccess const& p = NamedAccessOf(node->op()); + NameRef name(broker(), p.name()); + if (p.feedback().IsValid()) { + broker()->ProcessFeedbackForPropertyAccess(p.feedback(), + AccessMode::kLoad, name); } break; } case IrOpcode::kJSStoreNamed: { - if (!FLAG_concurrent_inlining) { - NamedAccess const& p = NamedAccessOf(node->op()); - NameRef name(broker(), p.name()); - } + NamedAccess const& p = NamedAccessOf(node->op()); + NameRef name(broker(), p.name()); break; } case IrOpcode::kStoreField: case IrOpcode::kLoadField: { - if (!FLAG_concurrent_inlining) { - FieldAccess access = FieldAccessOf(node->op()); - Handle<Map> map_handle; - if (access.map.ToHandle(&map_handle)) { - MapRef(broker(), map_handle); - } - Handle<Name> name_handle; - if (access.name.ToHandle(&name_handle)) { - NameRef(broker(), name_handle); - } + FieldAccess access = FieldAccessOf(node->op()); + Handle<Map> map_handle; + if (access.map.ToHandle(&map_handle)) { + MapRef(broker(), map_handle); + } + Handle<Name> name_handle; + if (access.name.ToHandle(&name_handle)) { + NameRef(broker(), name_handle); } break; } case IrOpcode::kMapGuard: { - if (!FLAG_concurrent_inlining) { - ZoneHandleSet<Map> const& maps = MapGuardMapsOf(node->op()); - for (Handle<Map> map : maps) { - MapRef(broker(), map); - } + ZoneHandleSet<Map> const& maps = MapGuardMapsOf(node->op()); + for (Handle<Map> map : maps) { + MapRef(broker(), map); } break; } case IrOpcode::kCheckMaps: { - if (!FLAG_concurrent_inlining) { - ZoneHandleSet<Map> const& maps = - CheckMapsParametersOf(node->op()).maps(); - for (Handle<Map> map : maps) { - MapRef(broker(), map); - } + ZoneHandleSet<Map> const& maps = CheckMapsParametersOf(node->op()).maps(); + for (Handle<Map> map : maps) { + MapRef(broker(), map); } break; } case IrOpcode::kCompareMaps: { - if (!FLAG_concurrent_inlining) { - ZoneHandleSet<Map> const& maps = CompareMapsParametersOf(node->op()); - for (Handle<Map> map : maps) { - MapRef(broker(), map); - } + ZoneHandleSet<Map> const& maps = CompareMapsParametersOf(node->op()); + for (Handle<Map> map : maps) { + MapRef(broker(), map); } break; } case IrOpcode::kJSLoadProperty: { - if (!FLAG_concurrent_inlining) { - PropertyAccess const& p = PropertyAccessOf(node->op()); - AccessMode access_mode = AccessMode::kLoad; - if (p.feedback().IsValid()) { - broker()->ProcessFeedbackForPropertyAccess(p.feedback(), access_mode, - base::nullopt); - } + PropertyAccess const& p = PropertyAccessOf(node->op()); + AccessMode access_mode = AccessMode::kLoad; + if (p.feedback().IsValid()) { + broker()->ProcessFeedbackForPropertyAccess(p.feedback(), access_mode, + base::nullopt); } break; } diff --git a/deps/v8/src/compiler/js-inlining-heuristic.cc b/deps/v8/src/compiler/js-inlining-heuristic.cc index ae271b3af9e986..cc3f321d6b2993 100644 --- a/deps/v8/src/compiler/js-inlining-heuristic.cc +++ b/deps/v8/src/compiler/js-inlining-heuristic.cc @@ -22,9 +22,35 @@ namespace compiler { } while (false) namespace { -bool IsSmall(BytecodeArrayRef bytecode) { +bool IsSmall(BytecodeArrayRef const& bytecode) { return bytecode.length() <= FLAG_max_inlined_bytecode_size_small; } + +bool CanConsiderForInlining(JSHeapBroker* broker, + SharedFunctionInfoRef const& shared, + FeedbackVectorRef const& feedback_vector) { + if (!shared.IsInlineable()) return false; + DCHECK(shared.HasBytecodeArray()); + if (!shared.IsSerializedForCompilation(feedback_vector)) { + TRACE_BROKER_MISSING( + broker, "data for " << shared << " (not serialized for compilation)"); + return false; + } + return true; +} + +bool CanConsiderForInlining(JSHeapBroker* broker, + JSFunctionRef const& function) { + if (!function.has_feedback_vector()) return false; + if (!function.serialized()) { + TRACE_BROKER_MISSING( + broker, "data for " << function << " (cannot consider for inlining)"); + return false; + } + return CanConsiderForInlining(broker, function.shared(), + function.feedback_vector()); +} + } // namespace JSInliningHeuristic::Candidate JSInliningHeuristic::CollectFunctions( @@ -38,11 +64,11 @@ JSInliningHeuristic::Candidate JSInliningHeuristic::CollectFunctions( if (m.HasValue() && m.Ref(broker()).IsJSFunction()) { out.functions[0] = m.Ref(broker()).AsJSFunction(); JSFunctionRef function = out.functions[0].value(); - if (function.IsSerializedForCompilation()) { + if (CanConsiderForInlining(broker(), function)) { out.bytecode[0] = function.shared().GetBytecodeArray(); + out.num_functions = 1; + return out; } - out.num_functions = 1; - return out; } if (m.IsPhi()) { int const value_input_count = m.node()->op()->ValueInputCount(); @@ -59,7 +85,7 @@ JSInliningHeuristic::Candidate JSInliningHeuristic::CollectFunctions( out.functions[n] = m.Ref(broker()).AsJSFunction(); JSFunctionRef function = out.functions[n].value(); - if (function.IsSerializedForCompilation()) { + if (CanConsiderForInlining(broker(), function)) { out.bytecode[n] = function.shared().GetBytecodeArray(); } } @@ -67,11 +93,14 @@ JSInliningHeuristic::Candidate JSInliningHeuristic::CollectFunctions( return out; } if (m.IsJSCreateClosure()) { - CreateClosureParameters const& p = CreateClosureParametersOf(m.op()); DCHECK(!out.functions[0].has_value()); - out.shared_info = SharedFunctionInfoRef(broker(), p.shared_info()); - SharedFunctionInfoRef shared_info = out.shared_info.value(); - if (shared_info.HasBytecodeArray()) { + CreateClosureParameters const& p = CreateClosureParametersOf(m.op()); + FeedbackCellRef feedback_cell(broker(), p.feedback_cell()); + SharedFunctionInfoRef shared_info(broker(), p.shared_info()); + out.shared_info = shared_info; + if (feedback_cell.value().IsFeedbackVector() && + CanConsiderForInlining(broker(), shared_info, + feedback_cell.value().AsFeedbackVector())) { out.bytecode[0] = shared_info.GetBytecodeArray(); } out.num_functions = 1; @@ -135,7 +164,8 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { SharedFunctionInfoRef shared = candidate.functions[i].has_value() ? candidate.functions[i].value().shared() : candidate.shared_info.value(); - candidate.can_inline_function[i] = shared.IsInlineable(); + candidate.can_inline_function[i] = candidate.bytecode[i].has_value(); + CHECK_IMPLIES(candidate.can_inline_function[i], shared.IsInlineable()); // Do not allow direct recursion i.e. f() -> f(). We still allow indirect // recurion like f() -> g() -> f(). The indirect recursion is helpful in // cases where f() is a small dispatch function that calls the appropriate @@ -151,14 +181,12 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { node->id(), node->op()->mnemonic()); candidate.can_inline_function[i] = false; } - // A function reaching this point should always have its bytecode - // serialized. - BytecodeArrayRef bytecode = candidate.bytecode[i].value(); if (candidate.can_inline_function[i]) { can_inline_candidate = true; + BytecodeArrayRef bytecode = candidate.bytecode[i].value(); candidate.total_size += bytecode.length(); + candidate_is_small = candidate_is_small && IsSmall(bytecode); } - candidate_is_small = candidate_is_small && IsSmall(bytecode); } if (!can_inline_candidate) return NoChange(); diff --git a/deps/v8/src/compiler/js-inlining.cc b/deps/v8/src/compiler/js-inlining.cc index 51179f1956f880..6c071438cc5b65 100644 --- a/deps/v8/src/compiler/js-inlining.cc +++ b/deps/v8/src/compiler/js-inlining.cc @@ -321,7 +321,7 @@ base::Optional<SharedFunctionInfoRef> JSInliner::DetermineCallTarget( // TODO(turbofan): We might consider to eagerly create the feedback vector // in such a case (in {DetermineCallContext} below) eventually. - FeedbackCellRef cell(FeedbackCellRef(broker(), p.feedback_cell())); + FeedbackCellRef cell(broker(), p.feedback_cell()); if (!cell.value().IsFeedbackVector()) return base::nullopt; return SharedFunctionInfoRef(broker(), p.shared_info()); @@ -413,11 +413,11 @@ Reduction JSInliner::ReduceJSCall(Node* node) { Node* exception_target = nullptr; NodeProperties::IsExceptionalCall(node, &exception_target); - // JSInliningHeuristic has already filtered candidates without a - // BytecodeArray by calling SharedFunctionInfoRef::IsInlineable. For the ones - // passing the IsInlineable check, The broker holds a reference to the - // bytecode array, which prevents it from getting flushed. - // Therefore, the following check should always hold true. + // JSInliningHeuristic has already filtered candidates without a BytecodeArray + // by calling SharedFunctionInfoRef::IsInlineable. For the ones passing the + // IsInlineable check, the broker holds a reference to the bytecode array, + // which prevents it from getting flushed. Therefore, the following check + // should always hold true. CHECK(shared_info->is_compiled()); if (!FLAG_concurrent_inlining && info_->is_source_positions_enabled()) { @@ -428,17 +428,10 @@ Reduction JSInliner::ReduceJSCall(Node* node) { TRACE("Inlining " << *shared_info << " into " << outer_shared_info << ((exception_target != nullptr) ? " (inside try-block)" : "")); - // Determine the targets feedback vector and its context. + // Determine the target's feedback vector and its context. Node* context; FeedbackVectorRef feedback_vector = DetermineCallContext(node, &context); - - if (FLAG_concurrent_inlining && - !shared_info->IsSerializedForCompilation(feedback_vector)) { - // TODO(neis): Should this be a broker message? - TRACE("Missed opportunity to inline a function (" - << *shared_info << " with " << feedback_vector << ")"); - return NoChange(); - } + CHECK(shared_info->IsSerializedForCompilation(feedback_vector)); // ---------------------------------------------------------------- // After this point, we've made a decision to inline this function. diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc index 9f950c808c2d83..80c620034b2bf8 100644 --- a/deps/v8/src/compiler/js-native-context-specialization.cc +++ b/deps/v8/src/compiler/js-native-context-specialization.cc @@ -784,12 +784,15 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess( Node* node, Node* receiver, Node* value, NameRef const& name, AccessMode access_mode, Node* key) { base::Optional<PropertyCellRef> cell = - native_context().global_proxy_object().GetPropertyCell(name); + native_context().global_object().GetPropertyCell(name); return cell.has_value() ? ReduceGlobalAccess(node, receiver, value, name, access_mode, key, *cell) : NoChange(); } +// TODO(neis): Try to merge this with ReduceNamedAccess by introducing a new +// PropertyAccessInfo kind for global accesses and using the existing mechanism +// for building loads/stores. Reduction JSNativeContextSpecialization::ReduceGlobalAccess( Node* node, Node* receiver, Node* value, NameRef const& name, AccessMode access_mode, Node* key, PropertyCellRef const& property_cell) { @@ -838,15 +841,16 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess( effect = BuildCheckEqualsName(name, key, effect, control); } - // Check if we have a {receiver} to validate. If so, we need to check that - // the {receiver} is actually the JSGlobalProxy for the native context that - // we are specializing to. + // If we have a {receiver} to validate, we do so by checking that its map is + // the (target) global proxy's map. This guarantees that in fact the receiver + // is the global proxy. if (receiver != nullptr) { - Node* check = graph()->NewNode(simplified()->ReferenceEqual(), receiver, - jsgraph()->HeapConstant(global_proxy())); effect = graph()->NewNode( - simplified()->CheckIf(DeoptimizeReason::kReceiverNotAGlobalProxy), - check, effect, control); + simplified()->CheckMaps( + CheckMapsFlag::kNone, + ZoneHandleSet<Map>( + HeapObjectRef(broker(), global_proxy()).map().object())), + receiver, effect, control); } if (access_mode == AccessMode::kLoad || access_mode == AccessMode::kHas) { @@ -1050,28 +1054,6 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreGlobal(Node* node) { } } -void JSNativeContextSpecialization::FilterMapsAndGetPropertyAccessInfos( - NamedAccessFeedback const& feedback, AccessMode access_mode, Node* receiver, - Node* effect, ZoneVector<PropertyAccessInfo>* access_infos) { - ZoneVector<Handle<Map>> receiver_maps(zone()); - - // Either infer maps from the graph or use the feedback. - if (!InferReceiverMaps(receiver, effect, &receiver_maps)) { - receiver_maps = feedback.maps(); - } - RemoveImpossibleReceiverMaps(receiver, &receiver_maps); - - for (Handle<Map> map_handle : receiver_maps) { - MapRef map(broker(), map_handle); - if (map.is_deprecated()) continue; - PropertyAccessInfo access_info = broker()->GetPropertyAccessInfo( - map, feedback.name(), access_mode, dependencies(), - FLAG_concurrent_inlining ? SerializationPolicy::kAssumeSerialized - : SerializationPolicy::kSerializeIfNeeded); - access_infos->push_back(access_info); - } -} - Reduction JSNativeContextSpecialization::ReduceNamedAccess( Node* node, Node* value, NamedAccessFeedback const& feedback, AccessMode access_mode, Node* key) { @@ -1081,36 +1063,54 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( node->opcode() == IrOpcode::kJSStoreProperty || node->opcode() == IrOpcode::kJSStoreNamedOwn || node->opcode() == IrOpcode::kJSStoreDataPropertyInLiteral || - node->opcode() == IrOpcode::kJSHasProperty || - node->opcode() == IrOpcode::kJSGetIterator); + node->opcode() == IrOpcode::kJSHasProperty); Node* receiver = NodeProperties::GetValueInput(node, 0); Node* context = NodeProperties::GetContextInput(node); Node* frame_state = NodeProperties::GetFrameStateInput(node); Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); - ZoneVector<PropertyAccessInfo> access_infos_for_feedback(zone()); - ZoneVector<PropertyAccessInfo> access_infos(zone()); - FilterMapsAndGetPropertyAccessInfos(feedback, access_mode, receiver, effect, - &access_infos_for_feedback); - AccessInfoFactory access_info_factory(broker(), dependencies(), - graph()->zone()); - if (!access_info_factory.FinalizePropertyAccessInfos( - access_infos_for_feedback, access_mode, &access_infos)) { - return NoChange(); + // Either infer maps from the graph or use the feedback. + ZoneVector<Handle<Map>> receiver_maps(zone()); + if (!InferReceiverMaps(receiver, effect, &receiver_maps)) { + receiver_maps = feedback.maps(); } + RemoveImpossibleReceiverMaps(receiver, &receiver_maps); - // Check if we have an access o.x or o.x=v where o is the current - // native contexts' global proxy, and turn that into a direct access - // to the current native context's global object instead. - if (access_infos.size() == 1 && access_infos[0].receiver_maps().size() == 1) { - MapRef receiver_map(broker(), access_infos[0].receiver_maps()[0]); - if (receiver_map.IsMapOfTargetGlobalProxy()) { + // Check if we have an access o.x or o.x=v where o is the target native + // contexts' global proxy, and turn that into a direct access to the + // corresponding global object instead. + if (receiver_maps.size() == 1) { + MapRef receiver_map(broker(), receiver_maps[0]); + if (receiver_map.equals( + broker()->target_native_context().global_proxy_object().map()) && + !broker()->target_native_context().global_object().IsDetached()) { return ReduceGlobalAccess(node, receiver, value, feedback.name(), access_mode, key); } } + ZoneVector<PropertyAccessInfo> access_infos(zone()); + { + ZoneVector<PropertyAccessInfo> access_infos_for_feedback(zone()); + for (Handle<Map> map_handle : receiver_maps) { + MapRef map(broker(), map_handle); + if (map.is_deprecated()) continue; + PropertyAccessInfo access_info = broker()->GetPropertyAccessInfo( + map, feedback.name(), access_mode, dependencies(), + FLAG_concurrent_inlining ? SerializationPolicy::kAssumeSerialized + : SerializationPolicy::kSerializeIfNeeded); + access_infos_for_feedback.push_back(access_info); + } + + AccessInfoFactory access_info_factory(broker(), dependencies(), + graph()->zone()); + if (!access_info_factory.FinalizePropertyAccessInfos( + access_infos_for_feedback, access_mode, &access_infos)) { + return NoChange(); + } + } + // Ensure that {key} matches the specified name (if {key} is given). if (key != nullptr) { effect = BuildCheckEqualsName(feedback.name(), key, effect, control); @@ -1332,24 +1332,6 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( return Replace(value); } -Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( - Node* node, Node* value, FeedbackSource const& source, NameRef const& name, - AccessMode access_mode) { - DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || - node->opcode() == IrOpcode::kJSStoreNamed || - node->opcode() == IrOpcode::kJSStoreNamedOwn); - Node* const receiver = NodeProperties::GetValueInput(node, 0); - - // Optimize accesses to the current native context's global proxy. - HeapObjectMatcher m(receiver); - if (m.HasValue() && - m.Ref(broker()).equals(native_context().global_proxy_object())) { - return ReduceGlobalAccess(node, nullptr, value, name, access_mode); - } - - return ReducePropertyAccess(node, nullptr, name, value, source, access_mode); -} - Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); NamedAccess const& p = NamedAccessOf(node->op()); @@ -1388,18 +1370,134 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { } if (!p.feedback().IsValid()) return NoChange(); - return ReduceNamedAccessFromNexus(node, jsgraph()->Dead(), - FeedbackSource(p.feedback()), name, - AccessMode::kLoad); + return ReducePropertyAccess(node, nullptr, name, jsgraph()->Dead(), + FeedbackSource(p.feedback()), AccessMode::kLoad); } Reduction JSNativeContextSpecialization::ReduceJSGetIterator(Node* node) { DCHECK_EQ(IrOpcode::kJSGetIterator, node->opcode()); - PropertyAccess const& p = PropertyAccessOf(node->op()); - NameRef name(broker(), factory()->iterator_symbol()); + GetIteratorParameters const& p = GetIteratorParametersOf(node->op()); - return ReducePropertyAccess(node, nullptr, name, jsgraph()->Dead(), - FeedbackSource(p.feedback()), AccessMode::kLoad); + Node* receiver = NodeProperties::GetValueInput(node, 0); + Node* context = NodeProperties::GetContextInput(node); + Node* frame_state = NodeProperties::GetFrameStateInput(node); + Node* effect = NodeProperties::GetEffectInput(node); + Node* control = NodeProperties::GetControlInput(node); + + Node* iterator_exception_node = nullptr; + Node* if_exception_merge = nullptr; + Node* if_exception_effect_phi = nullptr; + Node* if_exception_phi = nullptr; + bool has_exception_node = + NodeProperties::IsExceptionalCall(node, &iterator_exception_node); + if (has_exception_node) { + // If there exists an IfException node for the current {node}, we need + // exception handling for all the desugared nodes. Create a combination + // of Merge+Phi+EffectPhi nodes that consumes the exception paths from + // from all the desugared nodes including the original exception node. + // Usages of the original exception node are then rewired to the newly + // created combination of Merge+Phi+EffectPhi. Here, use dead_node as a + // placeholder for the original exception node until its uses are rewired. + + Node* dead_node = jsgraph()->Dead(); + if_exception_merge = graph()->NewNode(common()->Merge(1), dead_node); + if_exception_effect_phi = + graph()->NewNode(common()->EffectPhi(1), dead_node, if_exception_merge); + if_exception_phi = + graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 1), + dead_node, if_exception_merge); + ReplaceWithValue(iterator_exception_node, if_exception_phi, + if_exception_effect_phi, if_exception_merge); + if_exception_merge->ReplaceInput(0, iterator_exception_node); + if_exception_effect_phi->ReplaceInput(0, iterator_exception_node); + if_exception_phi->ReplaceInput(0, iterator_exception_node); + } + + // Load iterator property operator + Handle<Name> iterator_symbol = factory()->iterator_symbol(); + const Operator* load_op = + javascript()->LoadNamed(iterator_symbol, p.loadFeedback()); + + // Lazy deopt of the load iterator property + Node* call_slot = jsgraph()->SmiConstant(p.callFeedback().slot.ToInt()); + Node* call_feedback = jsgraph()->HeapConstant(p.callFeedback().vector); + Node* lazy_deopt_parameters[] = {receiver, call_slot, call_feedback}; + Node* lazy_deopt_frame_state = CreateStubBuiltinContinuationFrameState( + jsgraph(), Builtins::kGetIteratorWithFeedbackLazyDeoptContinuation, + context, lazy_deopt_parameters, arraysize(lazy_deopt_parameters), + frame_state, ContinuationFrameStateMode::LAZY); + Node* load_property = graph()->NewNode( + load_op, receiver, context, lazy_deopt_frame_state, effect, control); + effect = load_property; + control = load_property; + + // Handle exception path for the load named property + if (has_exception_node) { + control = + AppendExceptionHandling(effect, control, if_exception_merge, + if_exception_phi, if_exception_effect_phi); + } + + // Eager deopt of call iterator property + Node* parameters[] = {receiver, load_property, call_slot, call_feedback}; + Node* eager_deopt_frame_state = CreateStubBuiltinContinuationFrameState( + jsgraph(), Builtins::kCallIteratorWithFeedback, context, parameters, + arraysize(parameters), frame_state, ContinuationFrameStateMode::EAGER); + Node* deopt_checkpoint = graph()->NewNode( + common()->Checkpoint(), eager_deopt_frame_state, effect, control); + effect = deopt_checkpoint; + + // Call iterator property operator + ProcessedFeedback const& feedback = + broker()->GetFeedbackForCall(p.callFeedback()); + SpeculationMode mode = feedback.IsInsufficient() + ? SpeculationMode::kDisallowSpeculation + : feedback.AsCall().speculation_mode(); + const Operator* call_op = + javascript()->Call(2, CallFrequency(), p.callFeedback(), + ConvertReceiverMode::kNotNullOrUndefined, mode); + Node* call_property = graph()->NewNode(call_op, load_property, receiver, + context, frame_state, effect, control); + effect = call_property; + control = call_property; + if (has_exception_node) { + control = + AppendExceptionHandling(effect, control, if_exception_merge, + if_exception_phi, if_exception_effect_phi); + } + + // Check if the call property returns a valid JSReceiver else throw an invalid + // iterator runtime exception + Node* is_receiver = + graph()->NewNode(simplified()->ObjectIsReceiver(), call_property); + Node* branch_node = graph()->NewNode( + common()->Branch(BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck), + is_receiver, control); + { + // Create a version of effect and control for the false path of the branch + Node* effect = call_property; + Node* control = call_property; + Node* if_not_receiver = graph()->NewNode(common()->IfFalse(), branch_node); + control = if_not_receiver; + const Operator* call_runtime_op = + javascript()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid, 0); + Node* call_runtime = graph()->NewNode(call_runtime_op, context, frame_state, + effect, control); + control = call_runtime; + effect = call_runtime; + if (has_exception_node) { + control = + AppendExceptionHandling(effect, control, if_exception_merge, + if_exception_phi, if_exception_effect_phi); + } + Node* throw_node = + graph()->NewNode(common()->Throw(), call_runtime, control); + NodeProperties::MergeControlToEnd(graph(), common(), throw_node); + } + + Node* if_receiver = graph()->NewNode(common()->IfTrue(), branch_node); + ReplaceWithValue(node, call_property, effect, if_receiver); + return Replace(if_receiver); } Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { @@ -1408,9 +1506,8 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) { Node* const value = NodeProperties::GetValueInput(node, 1); if (!p.feedback().IsValid()) return NoChange(); - return ReduceNamedAccessFromNexus(node, value, FeedbackSource(p.feedback()), - NameRef(broker(), p.name()), - AccessMode::kStore); + return ReducePropertyAccess(node, nullptr, NameRef(broker(), p.name()), value, + FeedbackSource(p.feedback()), AccessMode::kStore); } Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) { @@ -1419,9 +1516,9 @@ Reduction JSNativeContextSpecialization::ReduceJSStoreNamedOwn(Node* node) { Node* const value = NodeProperties::GetValueInput(node, 1); if (!p.feedback().IsValid()) return NoChange(); - return ReduceNamedAccessFromNexus(node, value, FeedbackSource(p.feedback()), - NameRef(broker(), p.name()), - AccessMode::kStoreInLiteral); + return ReducePropertyAccess(node, nullptr, NameRef(broker(), p.name()), value, + FeedbackSource(p.feedback()), + AccessMode::kStoreInLiteral); } Reduction JSNativeContextSpecialization::ReduceElementAccessOnString( @@ -1578,9 +1675,7 @@ Reduction JSNativeContextSpecialization::ReduceElementAccess( // NoElementsProtector. for (ElementAccessInfo const& access_info : access_infos) { if (IsFastElementsKind(access_info.elements_kind())) { - if (!isolate()->IsNoElementsProtectorIntact()) return NoChange(); - dependencies()->DependOnProtector( - PropertyCellRef(broker(), factory()->no_elements_protector())); + if (!dependencies()->DependOnNoElementsProtector()) return NoChange(); break; } } @@ -1819,8 +1914,7 @@ Reduction JSNativeContextSpecialization::ReducePropertyAccess( node->opcode() == IrOpcode::kJSHasProperty || node->opcode() == IrOpcode::kJSLoadNamed || node->opcode() == IrOpcode::kJSStoreNamed || - node->opcode() == IrOpcode::kJSStoreNamedOwn || - node->opcode() == IrOpcode::kJSGetIterator); + node->opcode() == IrOpcode::kJSStoreNamedOwn); DCHECK_GE(node->op()->ControlOutputCount(), 1); ProcessedFeedback const& feedback = @@ -2499,12 +2593,14 @@ JSNativeContextSpecialization::BuildElementAccess( if (typed_array.has_value()) { length = jsgraph()->Constant(static_cast<double>(typed_array->length())); - // Load the (known) base and external pointer for the {receiver}. The - // {external_pointer} might be invalid if the {buffer} was detached, so - // we need to make sure that any access is properly guarded. + DCHECK(!typed_array->is_on_heap()); + // Load the (known) data pointer for the {receiver} and set {base_pointer} + // and {external_pointer} to the values that will allow to generate typed + // element accesses using the known data pointer. + // The data pointer might be invalid if the {buffer} was detached, + // so we need to make sure that any access is properly guarded. base_pointer = jsgraph()->ZeroConstant(); - external_pointer = - jsgraph()->PointerConstant(typed_array->external_pointer()); + external_pointer = jsgraph()->PointerConstant(typed_array->data_ptr()); } else { // Load the {receiver}s length. length = effect = graph()->NewNode( @@ -3168,6 +3264,22 @@ Node* JSNativeContextSpecialization::BuildCheckEqualsName(NameRef const& name, control); } +Node* JSNativeContextSpecialization::AppendExceptionHandling( + Node* effect, Node* control, Node* merge, Node* phi, Node* effect_phi) { + DCHECK_EQ(effect, control); + int input_count = merge->InputCount() + 1; + Node* if_exception = + graph()->NewNode(common()->IfException(), effect, control); + merge->InsertInput(graph()->zone(), 0, if_exception); + NodeProperties::ChangeOp(merge, common()->Merge(input_count)); + phi->InsertInput(graph()->zone(), 0, if_exception); + NodeProperties::ChangeOp( + phi, common()->Phi(MachineRepresentation::kTagged, input_count)); + effect_phi->InsertInput(graph()->zone(), 0, if_exception); + NodeProperties::ChangeOp(effect_phi, common()->EffectPhi(input_count)); + return graph()->NewNode(common()->IfSuccess(), control); +} + bool JSNativeContextSpecialization::CanTreatHoleAsUndefined( ZoneVector<Handle<Map>> const& receiver_maps) { // Check if all {receiver_maps} have one of the initial Array.prototype diff --git a/deps/v8/src/compiler/js-native-context-specialization.h b/deps/v8/src/compiler/js-native-context-specialization.h index a0707b98303d46..429be0bb242636 100644 --- a/deps/v8/src/compiler/js-native-context-specialization.h +++ b/deps/v8/src/compiler/js-native-context-specialization.h @@ -101,10 +101,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final base::Optional<NameRef> static_name, Node* value, FeedbackSource const& source, AccessMode access_mode); - Reduction ReduceNamedAccessFromNexus(Node* node, Node* value, - FeedbackSource const& source, - NameRef const& name, - AccessMode access_mode); Reduction ReduceNamedAccess(Node* node, Node* value, NamedAccessFeedback const& processed, AccessMode access_mode, Node* key = nullptr); @@ -207,6 +203,12 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final Node* BuildCheckEqualsName(NameRef const& name, Node* value, Node* effect, Node* control); + // Attach a pair of success and exception paths on a given control path. + // The exception is joined to the Merge+Phi+EffectPhi nodes while the success + // path is returned. + Node* AppendExceptionHandling(Node* effect, Node* control, Node* merge, + Node* phi, Node* effect_phi); + // Checks if we can turn the hole into undefined when loading an element // from an object with one of the {receiver_maps}; sets up appropriate // code dependencies and might use the array protector cell. @@ -219,11 +221,6 @@ class V8_EXPORT_PRIVATE JSNativeContextSpecialization final ElementAccessFeedback const& feedback, Node* receiver, Node* effect) const; - void FilterMapsAndGetPropertyAccessInfos( - NamedAccessFeedback const& feedback, AccessMode access_mode, - Node* receiver, Node* effect, - ZoneVector<PropertyAccessInfo>* access_infos); - // Try to infer maps for the given {receiver} at the current {effect}. bool InferReceiverMaps(Node* receiver, Node* effect, ZoneVector<Handle<Map>>* receiver_maps) const; diff --git a/deps/v8/src/compiler/js-operator.cc b/deps/v8/src/compiler/js-operator.cc index d0581b59a5af3a..42e5f900576bd0 100644 --- a/deps/v8/src/compiler/js-operator.cc +++ b/deps/v8/src/compiler/js-operator.cc @@ -11,6 +11,7 @@ #include "src/compiler/operator.h" #include "src/handles/handles-inl.h" #include "src/objects/objects-inl.h" +#include "src/objects/template-objects.h" namespace v8 { namespace internal { @@ -284,8 +285,7 @@ bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) { PropertyAccess const& PropertyAccessOf(const Operator* op) { DCHECK(op->opcode() == IrOpcode::kJSHasProperty || op->opcode() == IrOpcode::kJSLoadProperty || - op->opcode() == IrOpcode::kJSStoreProperty || - op->opcode() == IrOpcode::kJSGetIterator); + op->opcode() == IrOpcode::kJSStoreProperty); return OpParameter<PropertyAccess>(op); } @@ -473,6 +473,34 @@ const CreateBoundFunctionParameters& CreateBoundFunctionParametersOf( return OpParameter<CreateBoundFunctionParameters>(op); } +bool operator==(GetTemplateObjectParameters const& lhs, + GetTemplateObjectParameters const& rhs) { + return lhs.description().location() == rhs.description().location() && + lhs.shared().location() == rhs.shared().location() && + lhs.feedback() == rhs.feedback(); +} + +bool operator!=(GetTemplateObjectParameters const& lhs, + GetTemplateObjectParameters const& rhs) { + return !(lhs == rhs); +} + +size_t hash_value(GetTemplateObjectParameters const& p) { + return base::hash_combine(p.description().location(), p.shared().location(), + FeedbackSource::Hash()(p.feedback())); +} + +std::ostream& operator<<(std::ostream& os, + GetTemplateObjectParameters const& p) { + return os << Brief(*p.description()) << ", " << Brief(*p.shared()); +} + +const GetTemplateObjectParameters& GetTemplateObjectParametersOf( + const Operator* op) { + DCHECK(op->opcode() == IrOpcode::kJSGetTemplateObject); + return OpParameter<GetTemplateObjectParameters>(op); +} + bool operator==(CreateClosureParameters const& lhs, CreateClosureParameters const& rhs) { return lhs.allocation() == rhs.allocation() && @@ -562,6 +590,31 @@ const CloneObjectParameters& CloneObjectParametersOf(const Operator* op) { return OpParameter<CloneObjectParameters>(op); } +std::ostream& operator<<(std::ostream& os, GetIteratorParameters const& p) { + return os << p.loadFeedback() << ", " << p.callFeedback(); +} + +bool operator==(GetIteratorParameters const& lhs, + GetIteratorParameters const& rhs) { + return lhs.loadFeedback() == rhs.loadFeedback() && + lhs.callFeedback() == rhs.callFeedback(); +} + +bool operator!=(GetIteratorParameters const& lhs, + GetIteratorParameters const& rhs) { + return !(lhs == rhs); +} + +GetIteratorParameters const& GetIteratorParametersOf(const Operator* op) { + DCHECK(op->opcode() == IrOpcode::kJSGetIterator); + return OpParameter<GetIteratorParameters>(op); +} + +size_t hash_value(GetIteratorParameters const& p) { + return base::hash_combine(FeedbackSource::Hash()(p.loadFeedback()), + FeedbackSource::Hash()(p.callFeedback())); +} + size_t hash_value(ForInMode mode) { return static_cast<uint8_t>(mode); } std::ostream& operator<<(std::ostream& os, ForInMode mode) { @@ -957,9 +1010,10 @@ const Operator* JSOperatorBuilder::LoadProperty( access); // parameter } -const Operator* JSOperatorBuilder::GetIterator(FeedbackSource const& feedback) { - PropertyAccess access(LanguageMode::kSloppy, feedback); - return new (zone()) Operator1<PropertyAccess>( // -- +const Operator* JSOperatorBuilder::GetIterator( + FeedbackSource const& load_feedback, FeedbackSource const& call_feedback) { + GetIteratorParameters access(load_feedback, call_feedback); + return new (zone()) Operator1<GetIteratorParameters>( // -- IrOpcode::kJSGetIterator, Operator::kNoProperties, // opcode "JSGetIterator", // name 1, 1, 1, 1, 1, 2, // counts @@ -1257,6 +1311,18 @@ const Operator* JSOperatorBuilder::CreateLiteralObject( parameters); // parameter } +const Operator* JSOperatorBuilder::GetTemplateObject( + Handle<TemplateObjectDescription> description, + Handle<SharedFunctionInfo> shared, FeedbackSource const& feedback) { + GetTemplateObjectParameters parameters(description, shared, feedback); + return new (zone()) Operator1<GetTemplateObjectParameters>( // -- + IrOpcode::kJSGetTemplateObject, // opcode + Operator::kEliminatable, // properties + "JSGetTemplateObject", // name + 0, 1, 1, 1, 1, 0, // counts + parameters); // parameter +} + const Operator* JSOperatorBuilder::CloneObject(FeedbackSource const& feedback, int literal_flags) { CloneObjectParameters parameters(feedback, literal_flags); diff --git a/deps/v8/src/compiler/js-operator.h b/deps/v8/src/compiler/js-operator.h index f795a2f4029eef..47b0fff05a6eef 100644 --- a/deps/v8/src/compiler/js-operator.h +++ b/deps/v8/src/compiler/js-operator.h @@ -409,13 +409,13 @@ class StoreGlobalParameters final { : language_mode_(language_mode), name_(name), feedback_(feedback) {} LanguageMode language_mode() const { return language_mode_; } - const FeedbackSource& feedback() const { return feedback_; } - const Handle<Name>& name() const { return name_; } + FeedbackSource const& feedback() const { return feedback_; } + Handle<Name> const& name() const { return name_; } private: - const LanguageMode language_mode_; - const Handle<Name> name_; - const FeedbackSource feedback_; + LanguageMode const language_mode_; + Handle<Name> const name_; + FeedbackSource const feedback_; }; bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&); @@ -598,6 +598,35 @@ std::ostream& operator<<(std::ostream&, CreateClosureParameters const&); const CreateClosureParameters& CreateClosureParametersOf(const Operator* op); +class GetTemplateObjectParameters final { + public: + GetTemplateObjectParameters(Handle<TemplateObjectDescription> description, + Handle<SharedFunctionInfo> shared, + FeedbackSource const& feedback) + : description_(description), shared_(shared), feedback_(feedback) {} + + Handle<TemplateObjectDescription> description() const { return description_; } + Handle<SharedFunctionInfo> shared() const { return shared_; } + FeedbackSource const& feedback() const { return feedback_; } + + private: + Handle<TemplateObjectDescription> const description_; + Handle<SharedFunctionInfo> const shared_; + FeedbackSource const feedback_; +}; + +bool operator==(GetTemplateObjectParameters const&, + GetTemplateObjectParameters const&); +bool operator!=(GetTemplateObjectParameters const&, + GetTemplateObjectParameters const&); + +size_t hash_value(GetTemplateObjectParameters const&); + +std::ostream& operator<<(std::ostream&, GetTemplateObjectParameters const&); + +const GetTemplateObjectParameters& GetTemplateObjectParametersOf( + const Operator* op); + // Defines shared information for the literal that should be created. This is // used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and // JSCreateLiteralRegExp operators. @@ -653,6 +682,31 @@ std::ostream& operator<<(std::ostream&, CloneObjectParameters const&); const CloneObjectParameters& CloneObjectParametersOf(const Operator* op); +// Defines the shared information for the iterator symbol thats loaded and +// called. This is used as a parameter by JSGetIterator operator. +class GetIteratorParameters final { + public: + GetIteratorParameters(const FeedbackSource& load_feedback, + const FeedbackSource& call_feedback) + : load_feedback_(load_feedback), call_feedback_(call_feedback) {} + + FeedbackSource const& loadFeedback() const { return load_feedback_; } + FeedbackSource const& callFeedback() const { return call_feedback_; } + + private: + FeedbackSource const load_feedback_; + FeedbackSource const call_feedback_; +}; + +bool operator==(GetIteratorParameters const&, GetIteratorParameters const&); +bool operator!=(GetIteratorParameters const&, GetIteratorParameters const&); + +size_t hash_value(GetIteratorParameters const&); + +std::ostream& operator<<(std::ostream&, GetIteratorParameters const&); + +const GetIteratorParameters& GetIteratorParametersOf(const Operator* op); + // Descriptor used by the JSForInPrepare and JSForInNext opcodes. enum class ForInMode : uint8_t { kUseEnumCacheKeysAndIndices, @@ -742,7 +796,6 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final const Operator* CreateEmptyLiteralArray(FeedbackSource const& feedback); const Operator* CreateArrayFromIterable(); const Operator* CreateEmptyLiteralObject(); - const Operator* CreateLiteralObject( Handle<ObjectBoilerplateDescription> constant, FeedbackSource const& feedback, int literal_flags, @@ -753,6 +806,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final FeedbackSource const& feedback, int literal_flags); + const Operator* GetTemplateObject( + Handle<TemplateObjectDescription> description, + Handle<SharedFunctionInfo> shared, FeedbackSource const& feedback); + const Operator* CallForwardVarargs(size_t arity, uint32_t start_index); const Operator* Call( size_t arity, CallFrequency const& frequency = CallFrequency(), @@ -856,7 +913,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final const Operator* ParseInt(); const Operator* RegExpTest(); - const Operator* GetIterator(FeedbackSource const& feedback); + const Operator* GetIterator(FeedbackSource const& load_feedback, + FeedbackSource const& call_feedback); private: Zone* zone() const { return zone_; } diff --git a/deps/v8/src/compiler/js-type-hint-lowering.cc b/deps/v8/src/compiler/js-type-hint-lowering.cc index e1ff928cec646c..9a6b367ddf17bb 100644 --- a/deps/v8/src/compiler/js-type-hint-lowering.cc +++ b/deps/v8/src/compiler/js-type-hint-lowering.cc @@ -482,12 +482,32 @@ JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceConstructOperation( return LoweringResult::NoChange(); } +JSTypeHintLowering::LoweringResult +JSTypeHintLowering::ReduceGetIteratorOperation(const Operator* op, + Node* receiver, Node* effect, + Node* control, + FeedbackSlot load_slot, + FeedbackSlot call_slot) const { + DCHECK_EQ(IrOpcode::kJSGetIterator, op->opcode()); + // Insert soft deopt if the load feedback is invalid. + if (Node* node = TryBuildSoftDeopt( + load_slot, effect, control, + DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) { + return LoweringResult::Exit(node); + } + // Insert soft deopt if the call feedback is invalid. + if (Node* node = TryBuildSoftDeopt( + call_slot, effect, control, + DeoptimizeReason::kInsufficientTypeFeedbackForCall)) { + return LoweringResult::Exit(node); + } + return LoweringResult::NoChange(); +} + JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceLoadNamedOperation( const Operator* op, Node* receiver, Node* effect, Node* control, FeedbackSlot slot) const { - // JSGetIterator involves a named load of the Symbol.iterator property. - DCHECK(op->opcode() == IrOpcode::kJSLoadNamed || - op->opcode() == IrOpcode::kJSGetIterator); + DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode()); if (Node* node = TryBuildSoftDeopt( slot, effect, control, DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess)) { diff --git a/deps/v8/src/compiler/js-type-hint-lowering.h b/deps/v8/src/compiler/js-type-hint-lowering.h index 3e46fb2ec2a19c..303e2f8dcfa527 100644 --- a/deps/v8/src/compiler/js-type-hint-lowering.h +++ b/deps/v8/src/compiler/js-type-hint-lowering.h @@ -134,6 +134,13 @@ class JSTypeHintLowering { int arg_count, Node* effect, Node* control, FeedbackSlot slot) const; + + // Potential reduction of property access and call operations. + LoweringResult ReduceGetIteratorOperation(const Operator* op, Node* obj, + Node* effect, Node* control, + FeedbackSlot load_slot, + FeedbackSlot call_slot) const; + // Potential reduction of property access operations. LoweringResult ReduceLoadNamedOperation(const Operator* op, Node* obj, Node* effect, Node* control, diff --git a/deps/v8/src/compiler/js-typed-lowering.cc b/deps/v8/src/compiler/js-typed-lowering.cc index 8caafe6aadfc40..035457c62bee18 100644 --- a/deps/v8/src/compiler/js-typed-lowering.cc +++ b/deps/v8/src/compiler/js-typed-lowering.cc @@ -17,6 +17,7 @@ #include "src/compiler/operator-properties.h" #include "src/compiler/type-cache.h" #include "src/compiler/types.h" +#include "src/execution/protectors.h" #include "src/objects/js-generator.h" #include "src/objects/module-inl.h" #include "src/objects/objects-inl.h" @@ -567,9 +568,10 @@ Reduction JSTypedLowering::ReduceJSAdd(Node* node) { Node* length = graph()->NewNode(simplified()->NumberAdd(), left_length, right_length); - CellRef string_length_protector(broker(), - factory()->string_length_protector()); - if (string_length_protector.value().AsSmi() == Isolate::kProtectorValid) { + PropertyCellRef string_length_protector( + broker(), factory()->string_length_protector()); + if (string_length_protector.value().AsSmi() == + Protectors::kProtectorValid) { // We can just deoptimize if the {length} is out-of-bounds. Besides // generating a shorter code sequence than the version below, this // has the additional benefit of not holding on to the lazy {frame_state} @@ -2025,8 +2027,7 @@ Reduction JSTypedLowering::ReduceJSLoadMessage(Node* node) { ExternalReference const ref = ExternalReference::address_of_pending_message_obj(isolate()); node->ReplaceInput(0, jsgraph()->ExternalConstant(ref)); - NodeProperties::ChangeOp( - node, simplified()->LoadField(AccessBuilder::ForExternalTaggedValue())); + NodeProperties::ChangeOp(node, simplified()->LoadMessage()); return Changed(node); } @@ -2037,8 +2038,7 @@ Reduction JSTypedLowering::ReduceJSStoreMessage(Node* node) { Node* value = NodeProperties::GetValueInput(node, 0); node->ReplaceInput(0, jsgraph()->ExternalConstant(ref)); node->ReplaceInput(1, value); - NodeProperties::ChangeOp( - node, simplified()->StoreField(AccessBuilder::ForExternalTaggedValue())); + NodeProperties::ChangeOp(node, simplified()->StoreMessage()); return Changed(node); } diff --git a/deps/v8/src/compiler/linkage.h b/deps/v8/src/compiler/linkage.h index 69e7fbfa427fb8..5458d1eb6f6924 100644 --- a/deps/v8/src/compiler/linkage.h +++ b/deps/v8/src/compiler/linkage.h @@ -352,9 +352,18 @@ class V8_EXPORT_PRIVATE CallDescriptor final SaveFPRegsMode get_save_fp_mode() const { return save_fp_mode_; } + void set_has_function_descriptor(bool has_function_descriptor) { + has_function_descriptor_ = has_function_descriptor; + } + + bool HasFunctionDescriptor() const { return has_function_descriptor_; } + private: friend class Linkage; SaveFPRegsMode save_fp_mode_ = kSaveFPRegs; + // AIX has a function descriptor which we will set to true by default + // for all CFunction Calls. + bool has_function_descriptor_ = kHasFunctionDescriptor; const Kind kind_; const MachineType target_type_; diff --git a/deps/v8/src/compiler/machine-graph-verifier.cc b/deps/v8/src/compiler/machine-graph-verifier.cc index 4c7ee1d1410f36..f6b747c04daa9c 100644 --- a/deps/v8/src/compiler/machine-graph-verifier.cc +++ b/deps/v8/src/compiler/machine-graph-verifier.cc @@ -241,7 +241,7 @@ class MachineRepresentationInferrer { MachineType::PointerRepresentation(); break; case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastTaggedSignedToWord: + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: representation_vector_[node->id()] = MachineType::PointerRepresentation(); break; @@ -437,7 +437,7 @@ class MachineRepresentationChecker { MachineRepresentation::kWord64); break; case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastTaggedSignedToWord: + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: case IrOpcode::kTaggedPoisonOnSpeculation: CheckValueInputIsTagged(node, 0); break; @@ -461,7 +461,7 @@ class MachineRepresentationChecker { CheckValueInputForFloat64Op(node, 0); break; case IrOpcode::kWord64Equal: - if (Is64()) { + if (Is64() && !COMPRESS_POINTERS_BOOL) { CheckValueInputIsTaggedOrPointer(node, 0); CheckValueInputIsTaggedOrPointer(node, 1); if (!is_stub_) { @@ -1007,6 +1007,13 @@ class MachineRepresentationChecker { return IsAnyCompressed(actual); case MachineRepresentation::kTaggedSigned: case MachineRepresentation::kTaggedPointer: + // TODO(tebbi): At the moment, the machine graph doesn't contain + // reliable information if a node is kTaggedSigned, kTaggedPointer or + // kTagged, and often this is context-dependent. We should at least + // check for obvious violations: kTaggedSigned where we expect + // kTaggedPointer and the other way around, but at the moment, this + // happens in dead code. + return IsAnyTagged(actual); case MachineRepresentation::kCompressedSigned: case MachineRepresentation::kCompressedPointer: case MachineRepresentation::kFloat32: diff --git a/deps/v8/src/compiler/machine-operator-reducer.cc b/deps/v8/src/compiler/machine-operator-reducer.cc index 11124579f61d5c..38013d228c5053 100644 --- a/deps/v8/src/compiler/machine-operator-reducer.cc +++ b/deps/v8/src/compiler/machine-operator-reducer.cc @@ -681,7 +681,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { Int64Matcher m(node->InputAt(0)); if (m.HasValue()) return ReplaceInt32(static_cast<int32_t>(m.Value())); if (m.IsChangeInt32ToInt64()) return Replace(m.node()->InputAt(0)); - if (m.IsBitcastTaggedSignedToWord()) { + if (m.IsBitcastTaggedToWordForTagAndSmiBits()) { Int64Matcher n(m.node()->InputAt(0)); if (n.IsChangeCompressedToTagged()) { DCHECK(machine()->Is64() && SmiValuesAre31Bits()); @@ -725,7 +725,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { case IrOpcode::kFloat64RoundDown: return ReduceFloat64RoundDown(node); case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastTaggedSignedToWord: { + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: { NodeMatcher m(node->InputAt(0)); if (m.IsBitcastWordToTaggedSigned()) { RelaxEffectsAndControls(node); diff --git a/deps/v8/src/compiler/machine-operator.cc b/deps/v8/src/compiler/machine-operator.cc index 0355534408dbf9..b450fb60da8b78 100644 --- a/deps/v8/src/compiler/machine-operator.cc +++ b/deps/v8/src/compiler/machine-operator.cc @@ -146,7 +146,8 @@ MachineType AtomicOpType(Operator const* op) { V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \ V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ - V(BitcastTaggedSignedToWord, Operator::kNoProperties, 1, 0, 1) \ + V(Simd128ReverseBytes, Operator::kNoProperties, 1, 0, 1) \ + V(BitcastTaggedToWordForTagAndSmiBits, Operator::kNoProperties, 1, 0, 1) \ V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \ V(BitcastWord32ToCompressedSigned, Operator::kNoProperties, 1, 0, 1) \ V(BitcastCompressedSignedToWord32, Operator::kNoProperties, 1, 0, 1) \ @@ -255,6 +256,7 @@ MachineType AtomicOpType(Operator const* op) { V(F64x2Splat, Operator::kNoProperties, 1, 0, 1) \ V(F64x2Abs, Operator::kNoProperties, 1, 0, 1) \ V(F64x2Neg, Operator::kNoProperties, 1, 0, 1) \ + V(F64x2Sqrt, Operator::kNoProperties, 1, 0, 1) \ V(F64x2Add, Operator::kCommutative, 2, 0, 1) \ V(F64x2Sub, Operator::kNoProperties, 2, 0, 1) \ V(F64x2Mul, Operator::kCommutative, 2, 0, 1) \ @@ -265,11 +267,14 @@ MachineType AtomicOpType(Operator const* op) { V(F64x2Ne, Operator::kCommutative, 2, 0, 1) \ V(F64x2Lt, Operator::kNoProperties, 2, 0, 1) \ V(F64x2Le, Operator::kNoProperties, 2, 0, 1) \ + V(F64x2Qfma, Operator::kNoProperties, 3, 0, 1) \ + V(F64x2Qfms, Operator::kNoProperties, 3, 0, 1) \ V(F32x4Splat, Operator::kNoProperties, 1, 0, 1) \ V(F32x4SConvertI32x4, Operator::kNoProperties, 1, 0, 1) \ V(F32x4UConvertI32x4, Operator::kNoProperties, 1, 0, 1) \ V(F32x4Abs, Operator::kNoProperties, 1, 0, 1) \ V(F32x4Neg, Operator::kNoProperties, 1, 0, 1) \ + V(F32x4Sqrt, Operator::kNoProperties, 1, 0, 1) \ V(F32x4RecipApprox, Operator::kNoProperties, 1, 0, 1) \ V(F32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1) \ V(F32x4Add, Operator::kCommutative, 2, 0, 1) \ @@ -283,6 +288,8 @@ MachineType AtomicOpType(Operator const* op) { V(F32x4Ne, Operator::kCommutative, 2, 0, 1) \ V(F32x4Lt, Operator::kNoProperties, 2, 0, 1) \ V(F32x4Le, Operator::kNoProperties, 2, 0, 1) \ + V(F32x4Qfma, Operator::kNoProperties, 3, 0, 1) \ + V(F32x4Qfms, Operator::kNoProperties, 3, 0, 1) \ V(I64x2Splat, Operator::kNoProperties, 1, 0, 1) \ V(I64x2Neg, Operator::kNoProperties, 1, 0, 1) \ V(I64x2Shl, Operator::kNoProperties, 2, 0, 1) \ @@ -395,6 +402,7 @@ MachineType AtomicOpType(Operator const* op) { V(S1x8AllTrue, Operator::kNoProperties, 1, 0, 1) \ V(S1x16AnyTrue, Operator::kNoProperties, 1, 0, 1) \ V(S1x16AllTrue, Operator::kNoProperties, 1, 0, 1) \ + V(S8x16Swizzle, Operator::kNoProperties, 2, 0, 1) \ V(StackPointerGreaterThan, Operator::kNoProperties, 1, 0, 1) // The format is: diff --git a/deps/v8/src/compiler/machine-operator.h b/deps/v8/src/compiler/machine-operator.h index 17db145f58e449..1bd806eefbe3cd 100644 --- a/deps/v8/src/compiler/machine-operator.h +++ b/deps/v8/src/compiler/machine-operator.h @@ -239,6 +239,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const OptionalOperator Word64ReverseBits(); const Operator* Word32ReverseBytes(); const Operator* Word64ReverseBytes(); + const Operator* Simd128ReverseBytes(); const OptionalOperator Int32AbsWithOverflow(); const OptionalOperator Int64AbsWithOverflow(); @@ -301,8 +302,13 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final // This operator reinterprets the bits of a tagged pointer as a word. const Operator* BitcastTaggedToWord(); - // This operator reinterprets the bits of a Smi as a word. - const Operator* BitcastTaggedSignedToWord(); + // This operator reinterprets the bits of a tagged value as a word preserving + // non-pointer bits (all the bits that are not modified by GC): + // 1) smi tag + // 2) weak tag + // 3) smi payload if the tagged value is a smi. + // Note, that it's illegal to "look" at the pointer bits of non-smi values. + const Operator* BitcastTaggedToWordForTagAndSmiBits(); // This operator reinterprets the bits of a tagged MaybeObject pointer as // word. @@ -477,6 +483,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const Operator* F64x2Splat(); const Operator* F64x2Abs(); const Operator* F64x2Neg(); + const Operator* F64x2Sqrt(); const Operator* F64x2Add(); const Operator* F64x2Sub(); const Operator* F64x2Mul(); @@ -489,6 +496,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const Operator* F64x2Ne(); const Operator* F64x2Lt(); const Operator* F64x2Le(); + const Operator* F64x2Qfma(); + const Operator* F64x2Qfms(); const Operator* F32x4Splat(); const Operator* F32x4ExtractLane(int32_t); @@ -497,6 +506,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const Operator* F32x4UConvertI32x4(); const Operator* F32x4Abs(); const Operator* F32x4Neg(); + const Operator* F32x4Sqrt(); const Operator* F32x4RecipApprox(); const Operator* F32x4RecipSqrtApprox(); const Operator* F32x4Add(); @@ -510,6 +520,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const Operator* F32x4Ne(); const Operator* F32x4Lt(); const Operator* F32x4Le(); + const Operator* F32x4Qfma(); + const Operator* F32x4Qfms(); const Operator* I64x2Splat(); const Operator* I64x2ExtractLane(int32_t); @@ -632,6 +644,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final const Operator* S128Not(); const Operator* S128Select(); + const Operator* S8x16Swizzle(); const Operator* S8x16Shuffle(const uint8_t shuffle[16]); const Operator* S1x2AnyTrue(); diff --git a/deps/v8/src/compiler/memory-lowering.cc b/deps/v8/src/compiler/memory-lowering.cc new file mode 100644 index 00000000000000..1e112e8e824aaf --- /dev/null +++ b/deps/v8/src/compiler/memory-lowering.cc @@ -0,0 +1,551 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/memory-lowering.h" + +#include "src/codegen/interface-descriptors.h" +#include "src/compiler/js-graph.h" +#include "src/compiler/linkage.h" +#include "src/compiler/node-matchers.h" +#include "src/compiler/node-properties.h" +#include "src/compiler/node.h" +#include "src/compiler/simplified-operator.h" +#include "src/roots/roots-inl.h" + +namespace v8 { +namespace internal { +namespace compiler { + +// An allocation group represents a set of allocations that have been folded +// together. +class MemoryLowering::AllocationGroup final : public ZoneObject { + public: + AllocationGroup(Node* node, AllocationType allocation, Zone* zone); + AllocationGroup(Node* node, AllocationType allocation, Node* size, + Zone* zone); + ~AllocationGroup() = default; + + void Add(Node* object); + bool Contains(Node* object) const; + bool IsYoungGenerationAllocation() const { + return allocation() == AllocationType::kYoung; + } + + AllocationType allocation() const { return allocation_; } + Node* size() const { return size_; } + + private: + ZoneSet<NodeId> node_ids_; + AllocationType const allocation_; + Node* const size_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup); +}; + +MemoryLowering::MemoryLowering(JSGraph* jsgraph, Zone* zone, + PoisoningMitigationLevel poisoning_level, + AllocationFolding allocation_folding, + WriteBarrierAssertFailedCallback callback, + const char* function_debug_name) + : jsgraph_(jsgraph), + zone_(zone), + graph_assembler_(jsgraph, nullptr, nullptr, zone), + allocation_folding_(allocation_folding), + poisoning_level_(poisoning_level), + write_barrier_assert_failed_(callback), + function_debug_name_(function_debug_name) {} + +Reduction MemoryLowering::Reduce(Node* node) { + switch (node->opcode()) { + case IrOpcode::kAllocate: + // Allocate nodes were purged from the graph in effect-control + // linearization. + UNREACHABLE(); + case IrOpcode::kAllocateRaw: + return ReduceAllocateRaw(node); + case IrOpcode::kLoadFromObject: + return ReduceLoadFromObject(node); + case IrOpcode::kLoadElement: + return ReduceLoadElement(node); + case IrOpcode::kLoadField: + return ReduceLoadField(node); + case IrOpcode::kStoreToObject: + return ReduceStoreToObject(node); + case IrOpcode::kStoreElement: + return ReduceStoreElement(node); + case IrOpcode::kStoreField: + return ReduceStoreField(node); + case IrOpcode::kStore: + return ReduceStore(node); + default: + return NoChange(); + } +} + +#define __ gasm()-> + +Reduction MemoryLowering::ReduceAllocateRaw( + Node* node, AllocationType allocation_type, + AllowLargeObjects allow_large_objects, AllocationState const** state_ptr) { + DCHECK_EQ(IrOpcode::kAllocateRaw, node->opcode()); + DCHECK_IMPLIES(allocation_folding_ == AllocationFolding::kDoAllocationFolding, + state_ptr != nullptr); + Node* value; + Node* size = node->InputAt(0); + Node* effect = node->InputAt(1); + Node* control = node->InputAt(2); + + gasm()->Reset(effect, control); + + Node* allocate_builtin; + if (allocation_type == AllocationType::kYoung) { + if (allow_large_objects == AllowLargeObjects::kTrue) { + allocate_builtin = __ AllocateInYoungGenerationStubConstant(); + } else { + allocate_builtin = __ AllocateRegularInYoungGenerationStubConstant(); + } + } else { + if (allow_large_objects == AllowLargeObjects::kTrue) { + allocate_builtin = __ AllocateInOldGenerationStubConstant(); + } else { + allocate_builtin = __ AllocateRegularInOldGenerationStubConstant(); + } + } + + // Determine the top/limit addresses. + Node* top_address = __ ExternalConstant( + allocation_type == AllocationType::kYoung + ? ExternalReference::new_space_allocation_top_address(isolate()) + : ExternalReference::old_space_allocation_top_address(isolate())); + Node* limit_address = __ ExternalConstant( + allocation_type == AllocationType::kYoung + ? ExternalReference::new_space_allocation_limit_address(isolate()) + : ExternalReference::old_space_allocation_limit_address(isolate())); + + // Check if we can fold this allocation into a previous allocation represented + // by the incoming {state}. + IntPtrMatcher m(size); + if (m.IsInRange(0, kMaxRegularHeapObjectSize) && FLAG_inline_new && + allocation_folding_ == AllocationFolding::kDoAllocationFolding) { + intptr_t const object_size = m.Value(); + AllocationState const* state = *state_ptr; + if (state->size() <= kMaxRegularHeapObjectSize - object_size && + state->group()->allocation() == allocation_type) { + // We can fold this Allocate {node} into the allocation {group} + // represented by the given {state}. Compute the upper bound for + // the new {state}. + intptr_t const state_size = state->size() + object_size; + + // Update the reservation check to the actual maximum upper bound. + AllocationGroup* const group = state->group(); + if (machine()->Is64()) { + if (OpParameter<int64_t>(group->size()->op()) < state_size) { + NodeProperties::ChangeOp(group->size(), + common()->Int64Constant(state_size)); + } + } else { + if (OpParameter<int32_t>(group->size()->op()) < state_size) { + NodeProperties::ChangeOp( + group->size(), + common()->Int32Constant(static_cast<int32_t>(state_size))); + } + } + + // Update the allocation top with the new object allocation. + // TODO(bmeurer): Defer writing back top as much as possible. + Node* top = __ IntAdd(state->top(), size); + __ Store(StoreRepresentation(MachineType::PointerRepresentation(), + kNoWriteBarrier), + top_address, __ IntPtrConstant(0), top); + + // Compute the effective inner allocated address. + value = __ BitcastWordToTagged( + __ IntAdd(state->top(), __ IntPtrConstant(kHeapObjectTag))); + effect = __ ExtractCurrentEffect(); + control = __ ExtractCurrentControl(); + + // Extend the allocation {group}. + group->Add(value); + *state_ptr = + AllocationState::Open(group, state_size, top, effect, zone()); + } else { + auto call_runtime = __ MakeDeferredLabel(); + auto done = __ MakeLabel(MachineType::PointerRepresentation()); + + // Setup a mutable reservation size node; will be patched as we fold + // additional allocations into this new group. + Node* size = __ UniqueIntPtrConstant(object_size); + + // Load allocation top and limit. + Node* top = + __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0)); + Node* limit = + __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0)); + + // Check if we need to collect garbage before we can start bump pointer + // allocation (always done for folded allocations). + Node* check = __ UintLessThan(__ IntAdd(top, size), limit); + + __ GotoIfNot(check, &call_runtime); + __ Goto(&done, top); + + __ Bind(&call_runtime); + { + if (!allocate_operator_.is_set()) { + auto descriptor = AllocateDescriptor{}; + auto call_descriptor = Linkage::GetStubCallDescriptor( + graph()->zone(), descriptor, descriptor.GetStackParameterCount(), + CallDescriptor::kCanUseRoots, Operator::kNoThrow); + allocate_operator_.set(common()->Call(call_descriptor)); + } + Node* vfalse = __ BitcastTaggedToWord( + __ Call(allocate_operator_.get(), allocate_builtin, size)); + vfalse = __ IntSub(vfalse, __ IntPtrConstant(kHeapObjectTag)); + __ Goto(&done, vfalse); + } + + __ Bind(&done); + + // Compute the new top and write it back. + top = __ IntAdd(done.PhiAt(0), __ IntPtrConstant(object_size)); + __ Store(StoreRepresentation(MachineType::PointerRepresentation(), + kNoWriteBarrier), + top_address, __ IntPtrConstant(0), top); + + // Compute the initial object address. + value = __ BitcastWordToTagged( + __ IntAdd(done.PhiAt(0), __ IntPtrConstant(kHeapObjectTag))); + effect = __ ExtractCurrentEffect(); + control = __ ExtractCurrentControl(); + + // Start a new allocation group. + AllocationGroup* group = + new (zone()) AllocationGroup(value, allocation_type, size, zone()); + *state_ptr = + AllocationState::Open(group, object_size, top, effect, zone()); + } + } else { + auto call_runtime = __ MakeDeferredLabel(); + auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); + + // Load allocation top and limit. + Node* top = + __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0)); + Node* limit = + __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0)); + + // Compute the new top. + Node* new_top = __ IntAdd(top, size); + + // Check if we can do bump pointer allocation here. + Node* check = __ UintLessThan(new_top, limit); + __ GotoIfNot(check, &call_runtime); + if (allow_large_objects == AllowLargeObjects::kTrue) { + __ GotoIfNot( + __ UintLessThan(size, __ IntPtrConstant(kMaxRegularHeapObjectSize)), + &call_runtime); + } + __ Store(StoreRepresentation(MachineType::PointerRepresentation(), + kNoWriteBarrier), + top_address, __ IntPtrConstant(0), new_top); + __ Goto(&done, __ BitcastWordToTagged( + __ IntAdd(top, __ IntPtrConstant(kHeapObjectTag)))); + + __ Bind(&call_runtime); + if (!allocate_operator_.is_set()) { + auto descriptor = AllocateDescriptor{}; + auto call_descriptor = Linkage::GetStubCallDescriptor( + graph()->zone(), descriptor, descriptor.GetStackParameterCount(), + CallDescriptor::kCanUseRoots, Operator::kNoThrow); + allocate_operator_.set(common()->Call(call_descriptor)); + } + __ Goto(&done, __ Call(allocate_operator_.get(), allocate_builtin, size)); + + __ Bind(&done); + value = done.PhiAt(0); + effect = __ ExtractCurrentEffect(); + control = __ ExtractCurrentControl(); + + if (state_ptr) { + // Create an unfoldable allocation group. + AllocationGroup* group = + new (zone()) AllocationGroup(value, allocation_type, zone()); + *state_ptr = AllocationState::Closed(group, effect, zone()); + } + } + + // Replace all effect uses of {node} with the {effect} and replace + // all value uses of {node} with the {value}. + for (Edge edge : node->use_edges()) { + if (NodeProperties::IsEffectEdge(edge)) { + edge.UpdateTo(effect); + } else if (NodeProperties::IsValueEdge(edge)) { + edge.UpdateTo(value); + } else { + DCHECK(NodeProperties::IsControlEdge(edge)); + edge.UpdateTo(control); + } + } + + // Kill the {node} to make sure we don't leave dangling dead uses. + node->Kill(); + + return Replace(value); +} + +Reduction MemoryLowering::ReduceLoadFromObject(Node* node) { + DCHECK_EQ(IrOpcode::kLoadFromObject, node->opcode()); + ObjectAccess const& access = ObjectAccessOf(node->op()); + NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); + return Changed(node); +} + +Reduction MemoryLowering::ReduceLoadElement(Node* node) { + DCHECK_EQ(IrOpcode::kLoadElement, node->opcode()); + ElementAccess const& access = ElementAccessOf(node->op()); + Node* index = node->InputAt(1); + node->ReplaceInput(1, ComputeIndex(access, index)); + MachineType type = access.machine_type; + if (NeedsPoisoning(access.load_sensitivity)) { + NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type)); + } else { + NodeProperties::ChangeOp(node, machine()->Load(type)); + } + return Changed(node); +} + +Reduction MemoryLowering::ReduceLoadField(Node* node) { + DCHECK_EQ(IrOpcode::kLoadField, node->opcode()); + FieldAccess const& access = FieldAccessOf(node->op()); + Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); + node->InsertInput(graph()->zone(), 1, offset); + MachineType type = access.machine_type; + if (NeedsPoisoning(access.load_sensitivity)) { + NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type)); + } else { + NodeProperties::ChangeOp(node, machine()->Load(type)); + } + return Changed(node); +} + +Reduction MemoryLowering::ReduceStoreToObject(Node* node, + AllocationState const* state) { + DCHECK_EQ(IrOpcode::kStoreToObject, node->opcode()); + ObjectAccess const& access = ObjectAccessOf(node->op()); + Node* object = node->InputAt(0); + Node* value = node->InputAt(2); + WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( + node, object, value, state, access.write_barrier_kind); + NodeProperties::ChangeOp( + node, machine()->Store(StoreRepresentation( + access.machine_type.representation(), write_barrier_kind))); + return Changed(node); +} + +Reduction MemoryLowering::ReduceStoreElement(Node* node, + AllocationState const* state) { + DCHECK_EQ(IrOpcode::kStoreElement, node->opcode()); + ElementAccess const& access = ElementAccessOf(node->op()); + Node* object = node->InputAt(0); + Node* index = node->InputAt(1); + Node* value = node->InputAt(2); + node->ReplaceInput(1, ComputeIndex(access, index)); + WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( + node, object, value, state, access.write_barrier_kind); + NodeProperties::ChangeOp( + node, machine()->Store(StoreRepresentation( + access.machine_type.representation(), write_barrier_kind))); + return Changed(node); +} + +Reduction MemoryLowering::ReduceStoreField(Node* node, + AllocationState const* state) { + DCHECK_EQ(IrOpcode::kStoreField, node->opcode()); + FieldAccess const& access = FieldAccessOf(node->op()); + Node* object = node->InputAt(0); + Node* value = node->InputAt(1); + WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( + node, object, value, state, access.write_barrier_kind); + Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); + node->InsertInput(graph()->zone(), 1, offset); + NodeProperties::ChangeOp( + node, machine()->Store(StoreRepresentation( + access.machine_type.representation(), write_barrier_kind))); + return Changed(node); +} + +Reduction MemoryLowering::ReduceStore(Node* node, + AllocationState const* state) { + DCHECK_EQ(IrOpcode::kStore, node->opcode()); + StoreRepresentation representation = StoreRepresentationOf(node->op()); + Node* object = node->InputAt(0); + Node* value = node->InputAt(2); + WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( + node, object, value, state, representation.write_barrier_kind()); + if (write_barrier_kind != representation.write_barrier_kind()) { + NodeProperties::ChangeOp( + node, machine()->Store(StoreRepresentation( + representation.representation(), write_barrier_kind))); + return Changed(node); + } + return NoChange(); +} + +Node* MemoryLowering::ComputeIndex(ElementAccess const& access, Node* index) { + int const element_size_shift = + ElementSizeLog2Of(access.machine_type.representation()); + if (element_size_shift) { + index = __ WordShl(index, __ IntPtrConstant(element_size_shift)); + } + int const fixed_offset = access.header_size - access.tag(); + if (fixed_offset) { + index = __ IntAdd(index, __ IntPtrConstant(fixed_offset)); + } + return index; +} + +#undef __ + +namespace { + +bool ValueNeedsWriteBarrier(Node* value, Isolate* isolate) { + while (true) { + switch (value->opcode()) { + case IrOpcode::kBitcastWordToTaggedSigned: + case IrOpcode::kChangeTaggedSignedToCompressedSigned: + case IrOpcode::kChangeTaggedToCompressedSigned: + return false; + case IrOpcode::kChangeTaggedPointerToCompressedPointer: + case IrOpcode::kChangeTaggedToCompressed: + value = NodeProperties::GetValueInput(value, 0); + continue; + case IrOpcode::kHeapConstant: { + RootIndex root_index; + if (isolate->roots_table().IsRootHandle(HeapConstantOf(value->op()), + &root_index) && + RootsTable::IsImmortalImmovable(root_index)) { + return false; + } + break; + } + default: + break; + } + return true; + } +} + +} // namespace + +Reduction MemoryLowering::ReduceAllocateRaw(Node* node) { + DCHECK_EQ(IrOpcode::kAllocateRaw, node->opcode()); + const AllocateParameters& allocation = AllocateParametersOf(node->op()); + return ReduceAllocateRaw(node, allocation.allocation_type(), + allocation.allow_large_objects(), nullptr); +} + +WriteBarrierKind MemoryLowering::ComputeWriteBarrierKind( + Node* node, Node* object, Node* value, AllocationState const* state, + WriteBarrierKind write_barrier_kind) { + if (state && state->IsYoungGenerationAllocation() && + state->group()->Contains(object)) { + write_barrier_kind = kNoWriteBarrier; + } + if (!ValueNeedsWriteBarrier(value, isolate())) { + write_barrier_kind = kNoWriteBarrier; + } + if (write_barrier_kind == WriteBarrierKind::kAssertNoWriteBarrier) { + write_barrier_assert_failed_(node, object, function_debug_name_, zone()); + } + return write_barrier_kind; +} + +bool MemoryLowering::NeedsPoisoning(LoadSensitivity load_sensitivity) const { + // Safe loads do not need poisoning. + if (load_sensitivity == LoadSensitivity::kSafe) return false; + + switch (poisoning_level_) { + case PoisoningMitigationLevel::kDontPoison: + return false; + case PoisoningMitigationLevel::kPoisonAll: + return true; + case PoisoningMitigationLevel::kPoisonCriticalOnly: + return load_sensitivity == LoadSensitivity::kCritical; + } + UNREACHABLE(); +} + +MemoryLowering::AllocationGroup::AllocationGroup(Node* node, + AllocationType allocation, + Zone* zone) + : node_ids_(zone), allocation_(allocation), size_(nullptr) { + node_ids_.insert(node->id()); +} + +MemoryLowering::AllocationGroup::AllocationGroup(Node* node, + AllocationType allocation, + Node* size, Zone* zone) + : node_ids_(zone), allocation_(allocation), size_(size) { + node_ids_.insert(node->id()); +} + +void MemoryLowering::AllocationGroup::Add(Node* node) { + node_ids_.insert(node->id()); +} + +bool MemoryLowering::AllocationGroup::Contains(Node* node) const { + // Additions should stay within the same allocated object, so it's safe to + // ignore them. + while (node_ids_.find(node->id()) == node_ids_.end()) { + switch (node->opcode()) { + case IrOpcode::kBitcastTaggedToWord: + case IrOpcode::kBitcastWordToTagged: + case IrOpcode::kInt32Add: + case IrOpcode::kInt64Add: + node = NodeProperties::GetValueInput(node, 0); + break; + default: + return false; + } + } + return true; +} + +MemoryLowering::AllocationState::AllocationState() + : group_(nullptr), + size_(std::numeric_limits<int>::max()), + top_(nullptr), + effect_(nullptr) {} + +MemoryLowering::AllocationState::AllocationState(AllocationGroup* group, + Node* effect) + : group_(group), + size_(std::numeric_limits<int>::max()), + top_(nullptr), + effect_(effect) {} + +MemoryLowering::AllocationState::AllocationState(AllocationGroup* group, + intptr_t size, Node* top, + Node* effect) + : group_(group), size_(size), top_(top), effect_(effect) {} + +bool MemoryLowering::AllocationState::IsYoungGenerationAllocation() const { + return group() && group()->IsYoungGenerationAllocation(); +} + +Graph* MemoryLowering::graph() const { return jsgraph()->graph(); } + +Isolate* MemoryLowering::isolate() const { return jsgraph()->isolate(); } + +CommonOperatorBuilder* MemoryLowering::common() const { + return jsgraph()->common(); +} + +MachineOperatorBuilder* MemoryLowering::machine() const { + return jsgraph()->machine(); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/compiler/memory-lowering.h b/deps/v8/src/compiler/memory-lowering.h new file mode 100644 index 00000000000000..a1f1fc186185d8 --- /dev/null +++ b/deps/v8/src/compiler/memory-lowering.h @@ -0,0 +1,136 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_COMPILER_MEMORY_LOWERING_H_ +#define V8_COMPILER_MEMORY_LOWERING_H_ + +#include "src/compiler/graph-assembler.h" +#include "src/compiler/graph-reducer.h" + +namespace v8 { +namespace internal { +namespace compiler { + +// Forward declarations. +class CommonOperatorBuilder; +struct ElementAccess; +class Graph; +class JSGraph; +class MachineOperatorBuilder; +class Node; +class Operator; + +// Provides operations to lower all simplified memory access and allocation +// related nodes (i.e. Allocate, LoadField, StoreField and friends) to machine +// operators. +class MemoryLowering final : public Reducer { + public: + enum class AllocationFolding { kDoAllocationFolding, kDontAllocationFolding }; + class AllocationGroup; + + // An allocation state is propagated on the effect paths through the graph. + class AllocationState final : public ZoneObject { + public: + static AllocationState const* Empty(Zone* zone) { + return new (zone) AllocationState(); + } + static AllocationState const* Closed(AllocationGroup* group, Node* effect, + Zone* zone) { + return new (zone) AllocationState(group, effect); + } + static AllocationState const* Open(AllocationGroup* group, intptr_t size, + Node* top, Node* effect, Zone* zone) { + return new (zone) AllocationState(group, size, top, effect); + } + + bool IsYoungGenerationAllocation() const; + + AllocationGroup* group() const { return group_; } + Node* top() const { return top_; } + Node* effect() const { return effect_; } + intptr_t size() const { return size_; } + + private: + AllocationState(); + explicit AllocationState(AllocationGroup* group, Node* effect); + AllocationState(AllocationGroup* group, intptr_t size, Node* top, + Node* effect); + + AllocationGroup* const group_; + // The upper bound of the combined allocated object size on the current path + // (max int if allocation folding is impossible on this path). + intptr_t const size_; + Node* const top_; + Node* const effect_; + + DISALLOW_COPY_AND_ASSIGN(AllocationState); + }; + + using WriteBarrierAssertFailedCallback = std::function<void( + Node* node, Node* object, const char* name, Zone* temp_zone)>; + + MemoryLowering( + JSGraph* jsgraph, Zone* zone, PoisoningMitigationLevel poisoning_level, + AllocationFolding allocation_folding = + AllocationFolding::kDontAllocationFolding, + WriteBarrierAssertFailedCallback callback = [](Node*, Node*, const char*, + Zone*) { UNREACHABLE(); }, + const char* function_debug_name = nullptr); + ~MemoryLowering() = default; + + const char* reducer_name() const override { return "MemoryReducer"; } + + // Perform memory lowering reduction on the given Node. + Reduction Reduce(Node* node) override; + + // Specific reducers for each optype to enable keeping track of + // AllocationState by the MemoryOptimizer. + Reduction ReduceAllocateRaw(Node* node, AllocationType allocation_type, + AllowLargeObjects allow_large_objects, + AllocationState const** state); + Reduction ReduceLoadFromObject(Node* node); + Reduction ReduceLoadElement(Node* node); + Reduction ReduceLoadField(Node* node); + Reduction ReduceStoreToObject(Node* node, + AllocationState const* state = nullptr); + Reduction ReduceStoreElement(Node* node, + AllocationState const* state = nullptr); + Reduction ReduceStoreField(Node* node, + AllocationState const* state = nullptr); + Reduction ReduceStore(Node* node, AllocationState const* state = nullptr); + + private: + Reduction ReduceAllocateRaw(Node* node); + WriteBarrierKind ComputeWriteBarrierKind(Node* node, Node* object, + Node* value, + AllocationState const* state, + WriteBarrierKind); + Node* ComputeIndex(ElementAccess const& access, Node* node); + bool NeedsPoisoning(LoadSensitivity load_sensitivity) const; + + Graph* graph() const; + Isolate* isolate() const; + Zone* zone() const { return zone_; } + JSGraph* jsgraph() const { return jsgraph_; } + CommonOperatorBuilder* common() const; + MachineOperatorBuilder* machine() const; + GraphAssembler* gasm() { return &graph_assembler_; } + + SetOncePointer<const Operator> allocate_operator_; + JSGraph* const jsgraph_; + Zone* zone_; + GraphAssembler graph_assembler_; + AllocationFolding allocation_folding_; + PoisoningMitigationLevel poisoning_level_; + WriteBarrierAssertFailedCallback write_barrier_assert_failed_; + const char* function_debug_name_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryLowering); +}; + +} // namespace compiler +} // namespace internal +} // namespace v8 + +#endif // V8_COMPILER_MEMORY_LOWERING_H_ diff --git a/deps/v8/src/compiler/memory-optimizer.cc b/deps/v8/src/compiler/memory-optimizer.cc index 8684f2ce3cf5bc..6527dfb2877f4b 100644 --- a/deps/v8/src/compiler/memory-optimizer.cc +++ b/deps/v8/src/compiler/memory-optimizer.cc @@ -11,90 +11,12 @@ #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties.h" #include "src/compiler/node.h" -#include "src/compiler/simplified-operator.h" #include "src/roots/roots-inl.h" namespace v8 { namespace internal { namespace compiler { -MemoryOptimizer::MemoryOptimizer(JSGraph* jsgraph, Zone* zone, - PoisoningMitigationLevel poisoning_level, - AllocationFolding allocation_folding, - const char* function_debug_name, - TickCounter* tick_counter) - : jsgraph_(jsgraph), - empty_state_(AllocationState::Empty(zone)), - pending_(zone), - tokens_(zone), - zone_(zone), - graph_assembler_(jsgraph, nullptr, nullptr, zone), - poisoning_level_(poisoning_level), - allocation_folding_(allocation_folding), - function_debug_name_(function_debug_name), - tick_counter_(tick_counter) {} - -void MemoryOptimizer::Optimize() { - EnqueueUses(graph()->start(), empty_state()); - while (!tokens_.empty()) { - Token const token = tokens_.front(); - tokens_.pop(); - VisitNode(token.node, token.state); - } - DCHECK(pending_.empty()); - DCHECK(tokens_.empty()); -} - -MemoryOptimizer::AllocationGroup::AllocationGroup(Node* node, - AllocationType allocation, - Zone* zone) - : node_ids_(zone), allocation_(allocation), size_(nullptr) { - node_ids_.insert(node->id()); -} - -MemoryOptimizer::AllocationGroup::AllocationGroup(Node* node, - AllocationType allocation, - Node* size, Zone* zone) - : node_ids_(zone), allocation_(allocation), size_(size) { - node_ids_.insert(node->id()); -} - -void MemoryOptimizer::AllocationGroup::Add(Node* node) { - node_ids_.insert(node->id()); -} - -bool MemoryOptimizer::AllocationGroup::Contains(Node* node) const { - // Additions should stay within the same allocated object, so it's safe to - // ignore them. - while (node_ids_.find(node->id()) == node_ids_.end()) { - switch (node->opcode()) { - case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastWordToTagged: - case IrOpcode::kInt32Add: - case IrOpcode::kInt64Add: - node = NodeProperties::GetValueInput(node, 0); - break; - default: - return false; - } - } - return true; -} - -MemoryOptimizer::AllocationState::AllocationState() - : group_(nullptr), size_(std::numeric_limits<int>::max()), top_(nullptr) {} - -MemoryOptimizer::AllocationState::AllocationState(AllocationGroup* group) - : group_(group), size_(std::numeric_limits<int>::max()), top_(nullptr) {} - -MemoryOptimizer::AllocationState::AllocationState(AllocationGroup* group, - intptr_t size, Node* top) - : group_(group), size_(size), top_(top) {} - -bool MemoryOptimizer::AllocationState::IsYoungGenerationAllocation() const { - return group() && group()->IsYoungGenerationAllocation(); -} - namespace { bool CanAllocate(const Node* node) { @@ -221,8 +143,67 @@ Node* EffectPhiForPhi(Node* phi) { return nullptr; } +void WriteBarrierAssertFailed(Node* node, Node* object, const char* name, + Zone* temp_zone) { + std::stringstream str; + str << "MemoryOptimizer could not remove write barrier for node #" + << node->id() << "\n"; + str << " Run mksnapshot with --csa-trap-on-node=" << name << "," + << node->id() << " to break in CSA code.\n"; + Node* object_position = object; + if (object_position->opcode() == IrOpcode::kPhi) { + object_position = EffectPhiForPhi(object_position); + } + Node* allocating_node = nullptr; + if (object_position && object_position->op()->EffectOutputCount() > 0) { + allocating_node = SearchAllocatingNode(node, object_position, temp_zone); + } + if (allocating_node) { + str << "\n There is a potentially allocating node in between:\n"; + str << " " << *allocating_node << "\n"; + str << " Run mksnapshot with --csa-trap-on-node=" << name << "," + << allocating_node->id() << " to break there.\n"; + if (allocating_node->opcode() == IrOpcode::kCall) { + str << " If this is a never-allocating runtime call, you can add an " + "exception to Runtime::MayAllocate.\n"; + } + } else { + str << "\n It seems the store happened to something different than a " + "direct " + "allocation:\n"; + str << " " << *object << "\n"; + str << " Run mksnapshot with --csa-trap-on-node=" << name << "," + << object->id() << " to break there.\n"; + } + FATAL("%s", str.str().c_str()); +} + } // namespace +MemoryOptimizer::MemoryOptimizer( + JSGraph* jsgraph, Zone* zone, PoisoningMitigationLevel poisoning_level, + MemoryLowering::AllocationFolding allocation_folding, + const char* function_debug_name, TickCounter* tick_counter) + : memory_lowering_(jsgraph, zone, poisoning_level, allocation_folding, + WriteBarrierAssertFailed, function_debug_name), + jsgraph_(jsgraph), + empty_state_(AllocationState::Empty(zone)), + pending_(zone), + tokens_(zone), + zone_(zone), + tick_counter_(tick_counter) {} + +void MemoryOptimizer::Optimize() { + EnqueueUses(graph()->start(), empty_state()); + while (!tokens_.empty()) { + Token const token = tokens_.front(); + tokens_.pop(); + VisitNode(token.node, token.state); + } + DCHECK(pending_.empty()); + DCHECK(tokens_.empty()); +} + void MemoryOptimizer::VisitNode(Node* node, AllocationState const* state) { tick_counter_->DoTick(); DCHECK(!node->IsDead()); @@ -259,8 +240,6 @@ void MemoryOptimizer::VisitNode(Node* node, AllocationState const* state) { DCHECK_EQ(0, node->op()->EffectOutputCount()); } -#define __ gasm()-> - bool MemoryOptimizer::AllocationTypeNeedsUpdateToOld(Node* const node, const Edge edge) { if (COMPRESS_POINTERS_BOOL && IrOpcode::IsCompressOpcode(node->opcode())) { @@ -293,13 +272,6 @@ bool MemoryOptimizer::AllocationTypeNeedsUpdateToOld(Node* const node, void MemoryOptimizer::VisitAllocateRaw(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kAllocateRaw, node->opcode()); - Node* value; - Node* size = node->InputAt(0); - Node* effect = node->InputAt(1); - Node* control = node->InputAt(2); - - gasm()->Reset(effect, control); - const AllocateParameters& allocation = AllocateParametersOf(node->op()); AllocationType allocation_type = allocation.allocation_type(); @@ -310,7 +282,6 @@ void MemoryOptimizer::VisitAllocateRaw(Node* node, if (allocation_type == AllocationType::kOld) { for (Edge const edge : node->use_edges()) { Node* const user = edge.from(); - if (user->opcode() == IrOpcode::kStoreField && edge.index() == 0) { Node* child = user->InputAt(1); // In Pointer Compression we might have a Compress node between an @@ -339,299 +310,62 @@ void MemoryOptimizer::VisitAllocateRaw(Node* node, } } - Node* allocate_builtin; - if (allocation_type == AllocationType::kYoung) { - if (allocation.allow_large_objects() == AllowLargeObjects::kTrue) { - allocate_builtin = __ AllocateInYoungGenerationStubConstant(); - } else { - allocate_builtin = __ AllocateRegularInYoungGenerationStubConstant(); - } - } else { - if (allocation.allow_large_objects() == AllowLargeObjects::kTrue) { - allocate_builtin = __ AllocateInOldGenerationStubConstant(); - } else { - allocate_builtin = __ AllocateRegularInOldGenerationStubConstant(); - } - } - - // Determine the top/limit addresses. - Node* top_address = __ ExternalConstant( - allocation_type == AllocationType::kYoung - ? ExternalReference::new_space_allocation_top_address(isolate()) - : ExternalReference::old_space_allocation_top_address(isolate())); - Node* limit_address = __ ExternalConstant( - allocation_type == AllocationType::kYoung - ? ExternalReference::new_space_allocation_limit_address(isolate()) - : ExternalReference::old_space_allocation_limit_address(isolate())); - - // Check if we can fold this allocation into a previous allocation represented - // by the incoming {state}. - IntPtrMatcher m(size); - if (m.IsInRange(0, kMaxRegularHeapObjectSize) && FLAG_inline_new) { - intptr_t const object_size = m.Value(); - if (allocation_folding_ == AllocationFolding::kDoAllocationFolding && - state->size() <= kMaxRegularHeapObjectSize - object_size && - state->group()->allocation() == allocation_type) { - // We can fold this Allocate {node} into the allocation {group} - // represented by the given {state}. Compute the upper bound for - // the new {state}. - intptr_t const state_size = state->size() + object_size; - - // Update the reservation check to the actual maximum upper bound. - AllocationGroup* const group = state->group(); - if (machine()->Is64()) { - if (OpParameter<int64_t>(group->size()->op()) < state_size) { - NodeProperties::ChangeOp(group->size(), - common()->Int64Constant(state_size)); - } - } else { - if (OpParameter<int32_t>(group->size()->op()) < state_size) { - NodeProperties::ChangeOp( - group->size(), - common()->Int32Constant(static_cast<int32_t>(state_size))); - } - } - - // Update the allocation top with the new object allocation. - // TODO(bmeurer): Defer writing back top as much as possible. - Node* top = __ IntAdd(state->top(), size); - __ Store(StoreRepresentation(MachineType::PointerRepresentation(), - kNoWriteBarrier), - top_address, __ IntPtrConstant(0), top); - - // Compute the effective inner allocated address. - value = __ BitcastWordToTagged( - __ IntAdd(state->top(), __ IntPtrConstant(kHeapObjectTag))); - - // Extend the allocation {group}. - group->Add(value); - state = AllocationState::Open(group, state_size, top, zone()); - } else { - auto call_runtime = __ MakeDeferredLabel(); - auto done = __ MakeLabel(MachineType::PointerRepresentation()); - - // Setup a mutable reservation size node; will be patched as we fold - // additional allocations into this new group. - Node* size = __ UniqueIntPtrConstant(object_size); - - // Load allocation top and limit. - Node* top = - __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0)); - Node* limit = - __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0)); - - // Check if we need to collect garbage before we can start bump pointer - // allocation (always done for folded allocations). - Node* check = __ UintLessThan(__ IntAdd(top, size), limit); - - __ GotoIfNot(check, &call_runtime); - __ Goto(&done, top); - - __ Bind(&call_runtime); - { - if (!allocate_operator_.is_set()) { - auto descriptor = AllocateDescriptor{}; - auto call_descriptor = Linkage::GetStubCallDescriptor( - graph()->zone(), descriptor, descriptor.GetStackParameterCount(), - CallDescriptor::kCanUseRoots, Operator::kNoThrow); - allocate_operator_.set(common()->Call(call_descriptor)); - } - Node* vfalse = __ BitcastTaggedToWord( - __ Call(allocate_operator_.get(), allocate_builtin, size)); - vfalse = __ IntSub(vfalse, __ IntPtrConstant(kHeapObjectTag)); - __ Goto(&done, vfalse); - } - - __ Bind(&done); - - // Compute the new top and write it back. - top = __ IntAdd(done.PhiAt(0), __ IntPtrConstant(object_size)); - __ Store(StoreRepresentation(MachineType::PointerRepresentation(), - kNoWriteBarrier), - top_address, __ IntPtrConstant(0), top); - - // Compute the initial object address. - value = __ BitcastWordToTagged( - __ IntAdd(done.PhiAt(0), __ IntPtrConstant(kHeapObjectTag))); - - // Start a new allocation group. - AllocationGroup* group = - new (zone()) AllocationGroup(value, allocation_type, size, zone()); - state = AllocationState::Open(group, object_size, top, zone()); - } - } else { - auto call_runtime = __ MakeDeferredLabel(); - auto done = __ MakeLabel(MachineRepresentation::kTaggedPointer); - - // Load allocation top and limit. - Node* top = - __ Load(MachineType::Pointer(), top_address, __ IntPtrConstant(0)); - Node* limit = - __ Load(MachineType::Pointer(), limit_address, __ IntPtrConstant(0)); - - // Compute the new top. - Node* new_top = __ IntAdd(top, size); - - // Check if we can do bump pointer allocation here. - Node* check = __ UintLessThan(new_top, limit); - __ GotoIfNot(check, &call_runtime); - if (allocation.allow_large_objects() == AllowLargeObjects::kTrue) { - __ GotoIfNot( - __ UintLessThan(size, __ IntPtrConstant(kMaxRegularHeapObjectSize)), - &call_runtime); - } - __ Store(StoreRepresentation(MachineType::PointerRepresentation(), - kNoWriteBarrier), - top_address, __ IntPtrConstant(0), new_top); - __ Goto(&done, __ BitcastWordToTagged( - __ IntAdd(top, __ IntPtrConstant(kHeapObjectTag)))); - - __ Bind(&call_runtime); - if (!allocate_operator_.is_set()) { - auto descriptor = AllocateDescriptor{}; - auto call_descriptor = Linkage::GetStubCallDescriptor( - graph()->zone(), descriptor, descriptor.GetStackParameterCount(), - CallDescriptor::kCanUseRoots, Operator::kNoThrow); - allocate_operator_.set(common()->Call(call_descriptor)); - } - __ Goto(&done, __ Call(allocate_operator_.get(), allocate_builtin, size)); - - __ Bind(&done); - value = done.PhiAt(0); - - // Create an unfoldable allocation group. - AllocationGroup* group = - new (zone()) AllocationGroup(value, allocation_type, zone()); - state = AllocationState::Closed(group, zone()); - } - - effect = __ ExtractCurrentEffect(); - control = __ ExtractCurrentControl(); - - // Replace all effect uses of {node} with the {effect}, enqueue the - // effect uses for further processing, and replace all value uses of - // {node} with the {value}. - for (Edge edge : node->use_edges()) { - if (NodeProperties::IsEffectEdge(edge)) { - EnqueueUse(edge.from(), edge.index(), state); - edge.UpdateTo(effect); - } else if (NodeProperties::IsValueEdge(edge)) { - edge.UpdateTo(value); - } else { - DCHECK(NodeProperties::IsControlEdge(edge)); - edge.UpdateTo(control); - } - } - - // Kill the {node} to make sure we don't leave dangling dead uses. - node->Kill(); + memory_lowering()->ReduceAllocateRaw( + node, allocation_type, allocation.allow_large_objects(), &state); + EnqueueUses(state->effect(), state); } void MemoryOptimizer::VisitLoadFromObject(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kLoadFromObject, node->opcode()); - ObjectAccess const& access = ObjectAccessOf(node->op()); - NodeProperties::ChangeOp(node, machine()->Load(access.machine_type)); + memory_lowering()->ReduceLoadFromObject(node); EnqueueUses(node, state); } void MemoryOptimizer::VisitStoreToObject(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kStoreToObject, node->opcode()); - ObjectAccess const& access = ObjectAccessOf(node->op()); - Node* object = node->InputAt(0); - Node* value = node->InputAt(2); - WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( - node, object, value, state, access.write_barrier_kind); - NodeProperties::ChangeOp( - node, machine()->Store(StoreRepresentation( - access.machine_type.representation(), write_barrier_kind))); - EnqueueUses(node, state); -} - -#undef __ - -void MemoryOptimizer::VisitCall(Node* node, AllocationState const* state) { - DCHECK_EQ(IrOpcode::kCall, node->opcode()); - // If the call can allocate, we start with a fresh state. - if (!(CallDescriptorOf(node->op())->flags() & CallDescriptor::kNoAllocate)) { - state = empty_state(); - } + memory_lowering()->ReduceStoreToObject(node, state); EnqueueUses(node, state); } void MemoryOptimizer::VisitLoadElement(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kLoadElement, node->opcode()); - ElementAccess const& access = ElementAccessOf(node->op()); - Node* index = node->InputAt(1); - node->ReplaceInput(1, ComputeIndex(access, index)); - MachineType type = access.machine_type; - if (NeedsPoisoning(access.load_sensitivity)) { - NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type)); - } else { - NodeProperties::ChangeOp(node, machine()->Load(type)); - } + memory_lowering()->ReduceLoadElement(node); EnqueueUses(node, state); } void MemoryOptimizer::VisitLoadField(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kLoadField, node->opcode()); - FieldAccess const& access = FieldAccessOf(node->op()); - Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); - node->InsertInput(graph()->zone(), 1, offset); - MachineType type = access.machine_type; - if (NeedsPoisoning(access.load_sensitivity)) { - NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type)); - } else { - NodeProperties::ChangeOp(node, machine()->Load(type)); - } + memory_lowering()->ReduceLoadField(node); EnqueueUses(node, state); } void MemoryOptimizer::VisitStoreElement(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kStoreElement, node->opcode()); - ElementAccess const& access = ElementAccessOf(node->op()); - Node* object = node->InputAt(0); - Node* index = node->InputAt(1); - Node* value = node->InputAt(2); - WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( - node, object, value, state, access.write_barrier_kind); - node->ReplaceInput(1, ComputeIndex(access, index)); - NodeProperties::ChangeOp( - node, machine()->Store(StoreRepresentation( - access.machine_type.representation(), write_barrier_kind))); + memory_lowering()->ReduceStoreElement(node, state); EnqueueUses(node, state); } void MemoryOptimizer::VisitStoreField(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kStoreField, node->opcode()); - FieldAccess const& access = FieldAccessOf(node->op()); - Node* object = node->InputAt(0); - Node* value = node->InputAt(1); - WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( - node, object, value, state, access.write_barrier_kind); - Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); - node->InsertInput(graph()->zone(), 1, offset); - NodeProperties::ChangeOp( - node, machine()->Store(StoreRepresentation( - access.machine_type.representation(), write_barrier_kind))); + memory_lowering()->ReduceStoreField(node, state); EnqueueUses(node, state); } - void MemoryOptimizer::VisitStore(Node* node, AllocationState const* state) { DCHECK_EQ(IrOpcode::kStore, node->opcode()); - StoreRepresentation representation = StoreRepresentationOf(node->op()); - Node* object = node->InputAt(0); - Node* value = node->InputAt(2); - WriteBarrierKind write_barrier_kind = ComputeWriteBarrierKind( - node, object, value, state, representation.write_barrier_kind()); - if (write_barrier_kind != representation.write_barrier_kind()) { - NodeProperties::ChangeOp( - node, machine()->Store(StoreRepresentation( - representation.representation(), write_barrier_kind))); + memory_lowering()->ReduceStore(node, state); + EnqueueUses(node, state); +} + +void MemoryOptimizer::VisitCall(Node* node, AllocationState const* state) { + DCHECK_EQ(IrOpcode::kCall, node->opcode()); + // If the call can allocate, we start with a fresh state. + if (!(CallDescriptorOf(node->op())->flags() & CallDescriptor::kNoAllocate)) { + state = empty_state(); } EnqueueUses(node, state); } @@ -641,109 +375,12 @@ void MemoryOptimizer::VisitOtherEffect(Node* node, EnqueueUses(node, state); } -Node* MemoryOptimizer::ComputeIndex(ElementAccess const& access, Node* index) { - int const element_size_shift = - ElementSizeLog2Of(access.machine_type.representation()); - if (element_size_shift) { - index = graph()->NewNode(machine()->WordShl(), index, - jsgraph()->IntPtrConstant(element_size_shift)); - } - int const fixed_offset = access.header_size - access.tag(); - if (fixed_offset) { - index = graph()->NewNode(machine()->IntAdd(), index, - jsgraph()->IntPtrConstant(fixed_offset)); - } - return index; -} - -namespace { - -bool ValueNeedsWriteBarrier(Node* value, Isolate* isolate) { - while (true) { - switch (value->opcode()) { - case IrOpcode::kBitcastWordToTaggedSigned: - case IrOpcode::kChangeTaggedSignedToCompressedSigned: - case IrOpcode::kChangeTaggedToCompressedSigned: - return false; - case IrOpcode::kChangeTaggedPointerToCompressedPointer: - case IrOpcode::kChangeTaggedToCompressed: - value = NodeProperties::GetValueInput(value, 0); - continue; - case IrOpcode::kHeapConstant: { - RootIndex root_index; - if (isolate->roots_table().IsRootHandle(HeapConstantOf(value->op()), - &root_index) && - RootsTable::IsImmortalImmovable(root_index)) { - return false; - } - break; - } - default: - break; - } - return true; - } -} - -void WriteBarrierAssertFailed(Node* node, Node* object, const char* name, - Zone* temp_zone) { - std::stringstream str; - str << "MemoryOptimizer could not remove write barrier for node #" - << node->id() << "\n"; - str << " Run mksnapshot with --csa-trap-on-node=" << name << "," - << node->id() << " to break in CSA code.\n"; - Node* object_position = object; - if (object_position->opcode() == IrOpcode::kPhi) { - object_position = EffectPhiForPhi(object_position); - } - Node* allocating_node = nullptr; - if (object_position && object_position->op()->EffectOutputCount() > 0) { - allocating_node = SearchAllocatingNode(node, object_position, temp_zone); - } - if (allocating_node) { - str << "\n There is a potentially allocating node in between:\n"; - str << " " << *allocating_node << "\n"; - str << " Run mksnapshot with --csa-trap-on-node=" << name << "," - << allocating_node->id() << " to break there.\n"; - if (allocating_node->opcode() == IrOpcode::kCall) { - str << " If this is a never-allocating runtime call, you can add an " - "exception to Runtime::MayAllocate.\n"; - } - } else { - str << "\n It seems the store happened to something different than a " - "direct " - "allocation:\n"; - str << " " << *object << "\n"; - str << " Run mksnapshot with --csa-trap-on-node=" << name << "," - << object->id() << " to break there.\n"; - } - FATAL("%s", str.str().c_str()); -} - -} // namespace - -WriteBarrierKind MemoryOptimizer::ComputeWriteBarrierKind( - Node* node, Node* object, Node* value, AllocationState const* state, - WriteBarrierKind write_barrier_kind) { - if (state->IsYoungGenerationAllocation() && - state->group()->Contains(object)) { - write_barrier_kind = kNoWriteBarrier; - } - if (!ValueNeedsWriteBarrier(value, isolate())) { - write_barrier_kind = kNoWriteBarrier; - } - if (write_barrier_kind == WriteBarrierKind::kAssertNoWriteBarrier) { - WriteBarrierAssertFailed(node, object, function_debug_name_, zone()); - } - return write_barrier_kind; -} - MemoryOptimizer::AllocationState const* MemoryOptimizer::MergeStates( AllocationStates const& states) { // Check if all states are the same; or at least if all allocation // states belong to the same allocation group. AllocationState const* state = states.front(); - AllocationGroup* group = state->group(); + MemoryLowering::AllocationGroup* group = state->group(); for (size_t i = 1; i < states.size(); ++i) { if (states[i] != state) state = nullptr; if (states[i]->group() != group) group = nullptr; @@ -755,7 +392,7 @@ MemoryOptimizer::AllocationState const* MemoryOptimizer::MergeStates( // TODO(bmeurer): We could potentially just create a Phi here to merge // the various tops; but we need to pay special attention not to create // an unschedulable graph. - state = AllocationState::Closed(group, zone()); + state = AllocationState::Closed(group, nullptr, zone()); } else { // The states are from different allocation groups. state = empty_state(); @@ -830,31 +467,6 @@ void MemoryOptimizer::EnqueueUse(Node* node, int index, Graph* MemoryOptimizer::graph() const { return jsgraph()->graph(); } -Isolate* MemoryOptimizer::isolate() const { return jsgraph()->isolate(); } - -CommonOperatorBuilder* MemoryOptimizer::common() const { - return jsgraph()->common(); -} - -MachineOperatorBuilder* MemoryOptimizer::machine() const { - return jsgraph()->machine(); -} - -bool MemoryOptimizer::NeedsPoisoning(LoadSensitivity load_sensitivity) const { - // Safe loads do not need poisoning. - if (load_sensitivity == LoadSensitivity::kSafe) return false; - - switch (poisoning_level_) { - case PoisoningMitigationLevel::kDontPoison: - return false; - case PoisoningMitigationLevel::kPoisonAll: - return true; - case PoisoningMitigationLevel::kPoisonCriticalOnly: - return load_sensitivity == LoadSensitivity::kCritical; - } - UNREACHABLE(); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/src/compiler/memory-optimizer.h b/deps/v8/src/compiler/memory-optimizer.h index a663bf07ed6a49..0e0fc5684c09b3 100644 --- a/deps/v8/src/compiler/memory-optimizer.h +++ b/deps/v8/src/compiler/memory-optimizer.h @@ -5,7 +5,7 @@ #ifndef V8_COMPILER_MEMORY_OPTIMIZER_H_ #define V8_COMPILER_MEMORY_OPTIMIZER_H_ -#include "src/compiler/graph-assembler.h" +#include "src/compiler/memory-lowering.h" #include "src/zone/zone-containers.h" namespace v8 { @@ -15,95 +15,29 @@ class TickCounter; namespace compiler { -// Forward declarations. -class CommonOperatorBuilder; -struct ElementAccess; -class Graph; class JSGraph; -class MachineOperatorBuilder; -class Node; -class Operator; +class Graph; // NodeIds are identifying numbers for nodes that can be used to index auxiliary // out-of-line data associated with each node. using NodeId = uint32_t; -// Lowers all simplified memory access and allocation related nodes (i.e. -// Allocate, LoadField, StoreField and friends) to machine operators. // Performs allocation folding and store write barrier elimination -// implicitly. +// implicitly, while lowering all simplified memory access and allocation +// related nodes (i.e. Allocate, LoadField, StoreField and friends) to machine +// operators. class MemoryOptimizer final { public: - enum class AllocationFolding { kDoAllocationFolding, kDontAllocationFolding }; - MemoryOptimizer(JSGraph* jsgraph, Zone* zone, PoisoningMitigationLevel poisoning_level, - AllocationFolding allocation_folding, + MemoryLowering::AllocationFolding allocation_folding, const char* function_debug_name, TickCounter* tick_counter); ~MemoryOptimizer() = default; void Optimize(); private: - // An allocation group represents a set of allocations that have been folded - // together. - class AllocationGroup final : public ZoneObject { - public: - AllocationGroup(Node* node, AllocationType allocation, Zone* zone); - AllocationGroup(Node* node, AllocationType allocation, Node* size, - Zone* zone); - ~AllocationGroup() = default; - - void Add(Node* object); - bool Contains(Node* object) const; - bool IsYoungGenerationAllocation() const { - return allocation() == AllocationType::kYoung; - } - - AllocationType allocation() const { return allocation_; } - Node* size() const { return size_; } - - private: - ZoneSet<NodeId> node_ids_; - AllocationType const allocation_; - Node* const size_; - - DISALLOW_IMPLICIT_CONSTRUCTORS(AllocationGroup); - }; - - // An allocation state is propagated on the effect paths through the graph. - class AllocationState final : public ZoneObject { - public: - static AllocationState const* Empty(Zone* zone) { - return new (zone) AllocationState(); - } - static AllocationState const* Closed(AllocationGroup* group, Zone* zone) { - return new (zone) AllocationState(group); - } - static AllocationState const* Open(AllocationGroup* group, intptr_t size, - Node* top, Zone* zone) { - return new (zone) AllocationState(group, size, top); - } - - bool IsYoungGenerationAllocation() const; - - AllocationGroup* group() const { return group_; } - Node* top() const { return top_; } - intptr_t size() const { return size_; } - - private: - AllocationState(); - explicit AllocationState(AllocationGroup* group); - AllocationState(AllocationGroup* group, intptr_t size, Node* top); - - AllocationGroup* const group_; - // The upper bound of the combined allocated object size on the current path - // (max int if allocation folding is impossible on this path). - intptr_t const size_; - Node* const top_; - - DISALLOW_COPY_AND_ASSIGN(AllocationState); - }; + using AllocationState = MemoryLowering::AllocationState; // An array of allocation states used to collect states on merges. using AllocationStates = ZoneVector<AllocationState const*>; @@ -127,44 +61,29 @@ class MemoryOptimizer final { void VisitStore(Node*, AllocationState const*); void VisitOtherEffect(Node*, AllocationState const*); - Node* ComputeIndex(ElementAccess const&, Node*); - WriteBarrierKind ComputeWriteBarrierKind(Node* node, Node* object, - Node* value, - AllocationState const* state, - WriteBarrierKind); - AllocationState const* MergeStates(AllocationStates const& states); void EnqueueMerge(Node*, int, AllocationState const*); void EnqueueUses(Node*, AllocationState const*); void EnqueueUse(Node*, int, AllocationState const*); - bool NeedsPoisoning(LoadSensitivity load_sensitivity) const; - // Returns true if the AllocationType of the current AllocateRaw node that we // are visiting needs to be updated to kOld, due to propagation of tenuring // from outer to inner allocations. bool AllocationTypeNeedsUpdateToOld(Node* const user, const Edge edge); AllocationState const* empty_state() const { return empty_state_; } + MemoryLowering* memory_lowering() { return &memory_lowering_; } Graph* graph() const; - Isolate* isolate() const; JSGraph* jsgraph() const { return jsgraph_; } - CommonOperatorBuilder* common() const; - MachineOperatorBuilder* machine() const; Zone* zone() const { return zone_; } - GraphAssembler* gasm() { return &graph_assembler_; } - SetOncePointer<const Operator> allocate_operator_; - JSGraph* const jsgraph_; + MemoryLowering memory_lowering_; + JSGraph* jsgraph_; AllocationState const* const empty_state_; ZoneMap<NodeId, AllocationStates> pending_; ZoneQueue<Token> tokens_; Zone* const zone_; - GraphAssembler graph_assembler_; - PoisoningMitigationLevel poisoning_level_; - AllocationFolding allocation_folding_; - const char* function_debug_name_; TickCounter* const tick_counter_; DISALLOW_IMPLICIT_CONSTRUCTORS(MemoryOptimizer); diff --git a/deps/v8/src/compiler/node-matchers.h b/deps/v8/src/compiler/node-matchers.h index 20698f4cd6d637..82bc1795193c31 100644 --- a/deps/v8/src/compiler/node-matchers.h +++ b/deps/v8/src/compiler/node-matchers.h @@ -187,10 +187,11 @@ using Float64Matcher = FloatMatcher<double, IrOpcode::kFloat64Constant>; using NumberMatcher = FloatMatcher<double, IrOpcode::kNumberConstant>; // A pattern matcher for heap object constants. -struct HeapObjectMatcher final - : public ValueMatcher<Handle<HeapObject>, IrOpcode::kHeapConstant> { - explicit HeapObjectMatcher(Node* node) - : ValueMatcher<Handle<HeapObject>, IrOpcode::kHeapConstant>(node) {} +template <IrOpcode::Value kHeapConstantOpcode> +struct HeapObjectMatcherImpl final + : public ValueMatcher<Handle<HeapObject>, kHeapConstantOpcode> { + explicit HeapObjectMatcherImpl(Node* node) + : ValueMatcher<Handle<HeapObject>, kHeapConstantOpcode>(node) {} bool Is(Handle<HeapObject> const& value) const { return this->HasValue() && this->Value().address() == value.address(); @@ -201,6 +202,9 @@ struct HeapObjectMatcher final } }; +using HeapObjectMatcher = HeapObjectMatcherImpl<IrOpcode::kHeapConstant>; +using CompressedHeapObjectMatcher = + HeapObjectMatcherImpl<IrOpcode::kCompressedHeapConstant>; // A pattern matcher for external reference constants. struct ExternalReferenceMatcher final @@ -295,6 +299,8 @@ using Float64BinopMatcher = BinopMatcher<Float64Matcher, Float64Matcher>; using NumberBinopMatcher = BinopMatcher<NumberMatcher, NumberMatcher>; using HeapObjectBinopMatcher = BinopMatcher<HeapObjectMatcher, HeapObjectMatcher>; +using CompressedHeapObjectBinopMatcher = + BinopMatcher<CompressedHeapObjectMatcher, CompressedHeapObjectMatcher>; template <class BinopMatcher, IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode> diff --git a/deps/v8/src/compiler/node.h b/deps/v8/src/compiler/node.h index 76ea4bb1a9ed86..b4ff5f7185f0e7 100644 --- a/deps/v8/src/compiler/node.h +++ b/deps/v8/src/compiler/node.h @@ -149,7 +149,7 @@ class V8_EXPORT_PRIVATE Node final { Uses uses() { return Uses(this); } - // Returns true if {owner} is the user of {this} node. + // Returns true if {owner} is the only user of {this} node. bool OwnedBy(Node* owner) const { return first_use_ && first_use_->from() == owner && !first_use_->next; } diff --git a/deps/v8/src/compiler/opcodes.h b/deps/v8/src/compiler/opcodes.h index fe45d9276ac4de..76c6bfec2fee2d 100644 --- a/deps/v8/src/compiler/opcodes.h +++ b/deps/v8/src/compiler/opcodes.h @@ -156,7 +156,8 @@ V(JSCreateObject) \ V(JSCreatePromise) \ V(JSCreateStringIterator) \ - V(JSCreateTypedArray) + V(JSCreateTypedArray) \ + V(JSGetTemplateObject) #define JS_OBJECT_OP_LIST(V) \ JS_CREATE_OP_LIST(V) \ @@ -425,11 +426,14 @@ V(LoadFieldByIndex) \ V(LoadField) \ V(LoadElement) \ + V(LoadMessage) \ V(LoadTypedElement) \ V(LoadFromObject) \ V(LoadDataViewElement) \ + V(LoadStackArgument) \ V(StoreField) \ V(StoreElement) \ + V(StoreMessage) \ V(StoreTypedElement) \ V(StoreToObject) \ V(StoreDataViewElement) \ @@ -669,9 +673,10 @@ V(Word64Ctz) \ V(Word64ReverseBits) \ V(Word64ReverseBytes) \ + V(Simd128ReverseBytes) \ V(Int64AbsWithOverflow) \ V(BitcastTaggedToWord) \ - V(BitcastTaggedSignedToWord) \ + V(BitcastTaggedToWordForTagAndSmiBits) \ V(BitcastWordToTagged) \ V(BitcastWordToTaggedSigned) \ V(BitcastWord32ToCompressedSigned) \ @@ -749,6 +754,7 @@ V(F64x2ReplaceLane) \ V(F64x2Abs) \ V(F64x2Neg) \ + V(F64x2Sqrt) \ V(F64x2Add) \ V(F64x2Sub) \ V(F64x2Mul) \ @@ -759,6 +765,8 @@ V(F64x2Ne) \ V(F64x2Lt) \ V(F64x2Le) \ + V(F64x2Qfma) \ + V(F64x2Qfms) \ V(F32x4Splat) \ V(F32x4ExtractLane) \ V(F32x4ReplaceLane) \ @@ -766,6 +774,7 @@ V(F32x4UConvertI32x4) \ V(F32x4Abs) \ V(F32x4Neg) \ + V(F32x4Sqrt) \ V(F32x4RecipApprox) \ V(F32x4RecipSqrtApprox) \ V(F32x4Add) \ @@ -781,6 +790,8 @@ V(F32x4Le) \ V(F32x4Gt) \ V(F32x4Ge) \ + V(F32x4Qfma) \ + V(F32x4Qfms) \ V(I64x2Splat) \ V(I64x2ExtractLane) \ V(I64x2ReplaceLane) \ @@ -905,6 +916,7 @@ V(S128Or) \ V(S128Xor) \ V(S128Select) \ + V(S8x16Swizzle) \ V(S8x16Shuffle) \ V(S1x2AnyTrue) \ V(S1x2AllTrue) \ diff --git a/deps/v8/src/compiler/operator-properties.cc b/deps/v8/src/compiler/operator-properties.cc index 1fcc12291d9136..731a6c8496c985 100644 --- a/deps/v8/src/compiler/operator-properties.cc +++ b/deps/v8/src/compiler/operator-properties.cc @@ -41,6 +41,7 @@ bool OperatorProperties::NeedsExactContext(const Operator* op) { case IrOpcode::kJSCreateEmptyLiteralObject: case IrOpcode::kJSCreateArrayFromIterable: case IrOpcode::kJSCreateLiteralRegExp: + case IrOpcode::kJSGetTemplateObject: case IrOpcode::kJSForInEnumerate: case IrOpcode::kJSForInNext: case IrOpcode::kJSForInPrepare: diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc index 8b2f4247898918..b9648d91955a08 100644 --- a/deps/v8/src/compiler/pipeline.cc +++ b/deps/v8/src/compiler/pipeline.cc @@ -9,7 +9,6 @@ #include <memory> #include <sstream> -#include "src/base/adapters.h" #include "src/base/optional.h" #include "src/base/platform/elapsed-timer.h" #include "src/codegen/assembler-inl.h" @@ -97,6 +96,35 @@ namespace v8 { namespace internal { namespace compiler { +static constexpr char kCodegenZoneName[] = "codegen-zone"; +static constexpr char kGraphZoneName[] = "graph-zone"; +static constexpr char kInstructionZoneName[] = "instruction-zone"; +static constexpr char kMachineGraphVerifierZoneName[] = + "machine-graph-verifier-zone"; +static constexpr char kPipelineCompilationJobZoneName[] = + "pipeline-compilation-job-zone"; +static constexpr char kRegisterAllocationZoneName[] = + "register-allocation-zone"; +static constexpr char kRegisterAllocatorVerifierZoneName[] = + "register-allocator-verifier-zone"; +namespace { + +Maybe<OuterContext> GetModuleContext(Handle<JSFunction> closure) { + Context current = closure->context(); + size_t distance = 0; + while (!current.IsNativeContext()) { + if (current.IsModuleContext()) { + return Just( + OuterContext(handle(current, current.GetIsolate()), distance)); + } + current = current.previous(); + distance++; + } + return Nothing<OuterContext>(); +} + +} // anonymous namespace + class PipelineData { public: // For main entry point. @@ -113,15 +141,16 @@ class PipelineData { roots_relative_addressing_enabled_( !isolate->serializer_enabled() && !isolate->IsGeneratingEmbeddedBuiltins()), - graph_zone_scope_(zone_stats_, ZONE_NAME), + graph_zone_scope_(zone_stats_, kGraphZoneName), graph_zone_(graph_zone_scope_.zone()), - instruction_zone_scope_(zone_stats_, ZONE_NAME), + instruction_zone_scope_(zone_stats_, kInstructionZoneName), instruction_zone_(instruction_zone_scope_.zone()), - codegen_zone_scope_(zone_stats_, ZONE_NAME), + codegen_zone_scope_(zone_stats_, kCodegenZoneName), codegen_zone_(codegen_zone_scope_.zone()), broker_(new JSHeapBroker(isolate_, info_->zone(), info_->trace_heap_broker_enabled())), - register_allocation_zone_scope_(zone_stats_, ZONE_NAME), + register_allocation_zone_scope_(zone_stats_, + kRegisterAllocationZoneName), register_allocation_zone_(register_allocation_zone_scope_.zone()), assembler_options_(AssemblerOptions::Default(isolate)) { PhaseScope scope(pipeline_statistics, "V8.TFInitPipelineData"); @@ -158,7 +187,7 @@ class PipelineData { may_have_unverifiable_graph_(false), zone_stats_(zone_stats), pipeline_statistics_(pipeline_statistics), - graph_zone_scope_(zone_stats_, ZONE_NAME), + graph_zone_scope_(zone_stats_, kGraphZoneName), graph_zone_(graph_zone_scope_.zone()), graph_(mcgraph->graph()), source_positions_(source_positions), @@ -166,11 +195,12 @@ class PipelineData { machine_(mcgraph->machine()), common_(mcgraph->common()), mcgraph_(mcgraph), - instruction_zone_scope_(zone_stats_, ZONE_NAME), + instruction_zone_scope_(zone_stats_, kInstructionZoneName), instruction_zone_(instruction_zone_scope_.zone()), - codegen_zone_scope_(zone_stats_, ZONE_NAME), + codegen_zone_scope_(zone_stats_, kCodegenZoneName), codegen_zone_(codegen_zone_scope_.zone()), - register_allocation_zone_scope_(zone_stats_, ZONE_NAME), + register_allocation_zone_scope_(zone_stats_, + kRegisterAllocationZoneName), register_allocation_zone_(register_allocation_zone_scope_.zone()), assembler_options_(assembler_options) {} @@ -185,17 +215,18 @@ class PipelineData { info_(info), debug_name_(info_->GetDebugName()), zone_stats_(zone_stats), - graph_zone_scope_(zone_stats_, ZONE_NAME), + graph_zone_scope_(zone_stats_, kGraphZoneName), graph_zone_(graph_zone_scope_.zone()), graph_(graph), source_positions_(source_positions), node_origins_(node_origins), schedule_(schedule), - instruction_zone_scope_(zone_stats_, ZONE_NAME), + instruction_zone_scope_(zone_stats_, kInstructionZoneName), instruction_zone_(instruction_zone_scope_.zone()), - codegen_zone_scope_(zone_stats_, ZONE_NAME), + codegen_zone_scope_(zone_stats_, kCodegenZoneName), codegen_zone_(codegen_zone_scope_.zone()), - register_allocation_zone_scope_(zone_stats_, ZONE_NAME), + register_allocation_zone_scope_(zone_stats_, + kRegisterAllocationZoneName), register_allocation_zone_(register_allocation_zone_scope_.zone()), jump_optimization_info_(jump_opt), assembler_options_(assembler_options) { @@ -218,13 +249,14 @@ class PipelineData { info_(info), debug_name_(info_->GetDebugName()), zone_stats_(zone_stats), - graph_zone_scope_(zone_stats_, ZONE_NAME), - instruction_zone_scope_(zone_stats_, ZONE_NAME), + graph_zone_scope_(zone_stats_, kGraphZoneName), + instruction_zone_scope_(zone_stats_, kInstructionZoneName), instruction_zone_(sequence->zone()), sequence_(sequence), - codegen_zone_scope_(zone_stats_, ZONE_NAME), + codegen_zone_scope_(zone_stats_, kCodegenZoneName), codegen_zone_(codegen_zone_scope_.zone()), - register_allocation_zone_scope_(zone_stats_, ZONE_NAME), + register_allocation_zone_scope_(zone_stats_, + kRegisterAllocationZoneName), register_allocation_zone_(register_allocation_zone_scope_.zone()), assembler_options_(AssemblerOptions::Default(isolate)) {} @@ -323,6 +355,20 @@ class PipelineData { return assembler_options_; } + void ChooseSpecializationContext() { + if (info()->is_function_context_specializing()) { + DCHECK(info()->has_context()); + specialization_context_ = + Just(OuterContext(handle(info()->context(), isolate()), 0)); + } else { + specialization_context_ = GetModuleContext(info()->closure()); + } + } + + Maybe<OuterContext> specialization_context() const { + return specialization_context_; + } + size_t* address_of_max_unoptimized_frame_height() { return &max_unoptimized_frame_height_; } @@ -531,6 +577,7 @@ class PipelineData { JumpOptimizationInfo* jump_optimization_info_ = nullptr; AssemblerOptions assembler_options_; + Maybe<OuterContext> specialization_context_ = Nothing<OuterContext>(); // The maximal combined height of all inlined frames in their unoptimized // state. Calculated during instruction selection, applied during code @@ -548,12 +595,19 @@ class PipelineImpl final { template <typename Phase, typename... Args> void Run(Args&&... args); - // Step A. Run the graph creation and initial optimization passes. + // Step A.1. Serialize the data needed for the compilation front-end. + void Serialize(); + + // Step A.2. Run the graph creation and initial optimization passes. bool CreateGraph(); - // B. Run the concurrent optimization passes. + // Step B. Run the concurrent optimization passes. bool OptimizeGraph(Linkage* linkage); + // Alternative step B. Run minimal concurrent optimization passes for + // mid-tier. + bool OptimizeGraphForMidTier(Linkage* linkage); + // Substep B.1. Produce a scheduled graph. void ComputeScheduledGraph(); @@ -642,8 +696,6 @@ void PrintInlinedFunctionInfo( // compilation. For inlined functions print source position of their inlining. void PrintParticipatingSource(OptimizedCompilationInfo* info, Isolate* isolate) { - AllowDeferredHandleDereference allow_deference_for_print_code; - SourceIdAssigner id_assigner(info->inlined_functions().size()); PrintFunctionSource(info, isolate, -1, info->shared_info()); const auto& inlined = info->inlined_functions(); @@ -662,7 +714,6 @@ void PrintCode(Isolate* isolate, Handle<Code> code, } #ifdef ENABLE_DISASSEMBLER - AllowDeferredHandleDereference allow_deference_for_print_code; bool print_code = FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code && @@ -703,7 +754,7 @@ void PrintCode(Isolate* isolate, Handle<Code> code, Handle<SharedFunctionInfo> shared = info->shared_info(); os << "source_position = " << shared->StartPosition() << "\n"; } - code->Disassemble(debug_name.get(), os); + code->Disassemble(debug_name.get(), os, isolate); os << "--- End code ---\n"; } #endif // ENABLE_DISASSEMBLER @@ -800,8 +851,10 @@ class PipelineRunScope { public: PipelineRunScope(PipelineData* data, const char* phase_name) : phase_scope_(data->pipeline_statistics(), phase_name), - zone_scope_(data->zone_stats(), ZONE_NAME), - origin_scope_(data->node_origins(), phase_name) {} + zone_scope_(data->zone_stats(), phase_name), + origin_scope_(data->node_origins(), phase_name) { + DCHECK_NOT_NULL(phase_name); + } Zone* zone() { return zone_scope_.zone(); } @@ -886,7 +939,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob { PipelineCompilationJob(Isolate* isolate, Handle<SharedFunctionInfo> shared_info, Handle<JSFunction> function); - ~PipelineCompilationJob(); + ~PipelineCompilationJob() final; protected: Status PrepareJobImpl(Isolate* isolate) final; @@ -915,7 +968,8 @@ PipelineCompilationJob::PipelineCompilationJob( // we pass it to the CompilationJob constructor, but it is not // dereferenced there. : OptimizedCompilationJob(&compilation_info_, "TurboFan"), - zone_(function->GetIsolate()->allocator(), ZONE_NAME), + zone_(function->GetIsolate()->allocator(), + kPipelineCompilationJobZoneName), zone_stats_(function->GetIsolate()->allocator()), compilation_info_(&zone_, function->GetIsolate(), shared_info, function), pipeline_statistics_(CreatePipelineStatistics( @@ -976,9 +1030,16 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl( compilation_info()->MarkAsAllocationFoldingEnabled(); } + // Determine whether to specialize the code for the function's context. + // We can't do this in the case of OSR, because we want to cache the + // generated code on the native context keyed on SharedFunctionInfo. + // TODO(mythria): Check if it is better to key the OSR cache on JSFunction and + // allow context specialization for OSR code. if (compilation_info()->closure()->raw_feedback_cell().map() == - ReadOnlyRoots(isolate).one_closure_cell_map()) { + ReadOnlyRoots(isolate).one_closure_cell_map() && + !compilation_info()->is_osr()) { compilation_info()->MarkAsFunctionContextSpecializing(); + data_.ChooseSpecializationContext(); } if (compilation_info()->is_source_positions_enabled()) { @@ -999,9 +1060,13 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl( // assembly. Deoptimizer::EnsureCodeForDeoptimizationEntries(isolate); - if (!pipeline_.CreateGraph()) { - CHECK(!isolate->has_pending_exception()); - return AbortOptimization(BailoutReason::kGraphBuildingFailed); + pipeline_.Serialize(); + + if (!FLAG_concurrent_inlining) { + if (!pipeline_.CreateGraph()) { + CHECK(!isolate->has_pending_exception()); + return AbortOptimization(BailoutReason::kGraphBuildingFailed); + } } return SUCCEEDED; @@ -1012,7 +1077,21 @@ PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl() { TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.optimizingCompile.execute", this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "function", compilation_info()->shared_info()->TraceIDRef()); - if (!pipeline_.OptimizeGraph(linkage_)) return FAILED; + + if (FLAG_concurrent_inlining) { + if (!pipeline_.CreateGraph()) { + return AbortOptimization(BailoutReason::kGraphBuildingFailed); + } + } + + bool success; + if (FLAG_turboprop) { + success = pipeline_.OptimizeGraphForMidTier(linkage_); + } else { + success = pipeline_.OptimizeGraph(linkage_); + } + if (!success) return FAILED; + pipeline_.AssembleCode(linkage_); return SUCCEEDED; } @@ -1091,8 +1170,6 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob { pipeline_(&data_), wasm_engine_(wasm_engine) {} - ~WasmHeapStubCompilationJob() = default; - protected: Status PrepareJobImpl(Isolate* isolate) final; Status ExecuteJobImpl() final; @@ -1119,7 +1196,7 @@ Pipeline::NewWasmHeapStubCompilationJob( CallDescriptor* call_descriptor, std::unique_ptr<Zone> zone, Graph* graph, Code::Kind kind, std::unique_ptr<char[]> debug_name, const AssemblerOptions& options, SourcePositionTable* source_positions) { - return base::make_unique<WasmHeapStubCompilationJob>( + return std::make_unique<WasmHeapStubCompilationJob>( isolate, wasm_engine, call_descriptor, std::move(zone), graph, kind, std::move(debug_name), options, source_positions); } @@ -1175,7 +1252,7 @@ CompilationJob::Status WasmHeapStubCompilationJob::FinalizeJobImpl( if (FLAG_print_opt_code) { CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); OFStream os(tracing_scope.file()); - code->Disassemble(compilation_info()->GetDebugName().get(), os); + code->Disassemble(compilation_info()->GetDebugName().get(), os, isolate); } #endif return SUCCEEDED; @@ -1212,38 +1289,10 @@ struct GraphBuilderPhase { } }; -namespace { - -Maybe<OuterContext> GetModuleContext(Handle<JSFunction> closure) { - Context current = closure->context(); - size_t distance = 0; - while (!current.IsNativeContext()) { - if (current.IsModuleContext()) { - return Just( - OuterContext(handle(current, current.GetIsolate()), distance)); - } - current = current.previous(); - distance++; - } - return Nothing<OuterContext>(); -} - -Maybe<OuterContext> ChooseSpecializationContext( - Isolate* isolate, OptimizedCompilationInfo* info) { - if (info->is_function_context_specializing()) { - DCHECK(info->has_context()); - return Just(OuterContext(handle(info->context(), isolate), 0)); - } - return GetModuleContext(info->closure()); -} - -} // anonymous namespace - struct InliningPhase { static const char* phase_name() { return "V8.TFInlining"; } void Run(PipelineData* data, Zone* temp_zone) { - Isolate* isolate = data->isolate(); OptimizedCompilationInfo* info = data->info(); GraphReducer graph_reducer(temp_zone, data->graph(), &info->tick_counter(), data->jsgraph()->Dead()); @@ -1260,7 +1309,7 @@ struct InliningPhase { data->dependencies()); JSContextSpecialization context_specialization( &graph_reducer, data->jsgraph(), data->broker(), - ChooseSpecializationContext(isolate, data->info()), + data->specialization_context(), data->info()->is_function_context_specializing() ? data->info()->closure() : MaybeHandle<JSFunction>()); @@ -1389,9 +1438,13 @@ struct SerializationPhase { flags |= SerializerForBackgroundCompilationFlag::kAnalyzeEnvironmentLiveness; } - RunSerializerForBackgroundCompilation(data->broker(), data->dependencies(), - temp_zone, data->info()->closure(), - flags, data->info()->osr_offset()); + RunSerializerForBackgroundCompilation( + data->zone_stats(), data->broker(), data->dependencies(), + data->info()->closure(), flags, data->info()->osr_offset()); + if (data->specialization_context().IsJust()) { + ContextRef(data->broker(), + data->specialization_context().FromJust().context); + } } }; @@ -1682,8 +1735,8 @@ struct MemoryOptimizationPhase { MemoryOptimizer optimizer( data->jsgraph(), temp_zone, data->info()->GetPoisoningMitigationLevel(), data->info()->is_allocation_folding_enabled() - ? MemoryOptimizer::AllocationFolding::kDoAllocationFolding - : MemoryOptimizer::AllocationFolding::kDontAllocationFolding, + ? MemoryLowering::AllocationFolding::kDoAllocationFolding + : MemoryLowering::AllocationFolding::kDontAllocationFolding, data->debug_name(), &data->info()->tick_counter()); optimizer.Optimize(); } @@ -1705,13 +1758,15 @@ struct LateOptimizationPhase { CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), data->broker(), data->common(), data->machine(), temp_zone); - SelectLowering select_lowering(data->jsgraph()->graph(), - data->jsgraph()->common()); -#ifdef V8_COMPRESS_POINTERS + SelectLowering select_lowering(data->jsgraph(), temp_zone); + // TODO(v8:7703, solanes): go back to using #if guards once + // FLAG_turbo_decompression_elimination gets removed. DecompressionElimination decompression_elimination( &graph_reducer, data->graph(), data->machine(), data->common()); - AddReducer(data, &graph_reducer, &decompression_elimination); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + AddReducer(data, &graph_reducer, &decompression_elimination); + } + USE(decompression_elimination); AddReducer(data, &graph_reducer, &branch_condition_elimination); AddReducer(data, &graph_reducer, &dead_code_elimination); AddReducer(data, &graph_reducer, &machine_reducer); @@ -1738,6 +1793,23 @@ struct MachineOperatorOptimizationPhase { } }; +struct MidTierMachineLoweringPhase { + static const char* phase_name() { return "V8.TFMidTierMachineLoweringPhase"; } + + void Run(PipelineData* data, Zone* temp_zone) { + GraphReducer graph_reducer(temp_zone, data->graph(), + &data->info()->tick_counter(), + data->jsgraph()->Dead()); + SelectLowering select_lowering(data->jsgraph(), temp_zone); + MemoryLowering memory_lowering(data->jsgraph(), temp_zone, + data->info()->GetPoisoningMitigationLevel()); + + AddReducer(data, &graph_reducer, &memory_lowering); + AddReducer(data, &graph_reducer, &select_lowering); + graph_reducer.ReduceGraph(); + } +}; + struct CsaEarlyOptimizationPhase { static const char* phase_name() { return "V8.CSAEarlyOptimization"; } @@ -1779,11 +1851,14 @@ struct CsaOptimizationPhase { CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), data->broker(), data->common(), data->machine(), temp_zone); -#ifdef V8_COMPRESS_POINTERS + // TODO(v8:7703, solanes): go back to using #if guards once + // FLAG_turbo_decompression_elimination gets removed. DecompressionElimination decompression_elimination( &graph_reducer, data->graph(), data->machine(), data->common()); - AddReducer(data, &graph_reducer, &decompression_elimination); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + AddReducer(data, &graph_reducer, &decompression_elimination); + } + USE(decompression_elimination); AddReducer(data, &graph_reducer, &branch_condition_elimination); AddReducer(data, &graph_reducer, &dead_code_elimination); AddReducer(data, &graph_reducer, &machine_reducer); @@ -2077,7 +2152,7 @@ struct JumpThreadingPhase { void Run(PipelineData* data, Zone* temp_zone, bool frame_at_start) { ZoneVector<RpoNumber> result(temp_zone); - if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence(), + if (JumpThreading::ComputeForwarding(temp_zone, &result, data->sequence(), frame_at_start)) { JumpThreading::ApplyForwarding(temp_zone, result, data->sequence()); } @@ -2102,7 +2177,7 @@ struct FinalizeCodePhase { struct PrintGraphPhase { - static const char* phase_name() { return nullptr; } + static const char* phase_name() { return "V8.TFPrintGraph"; } void Run(PipelineData* data, Zone* temp_zone, const char* phase) { OptimizedCompilationInfo* info = data->info(); @@ -2143,7 +2218,7 @@ struct PrintGraphPhase { struct VerifyGraphPhase { - static const char* phase_name() { return nullptr; } + static const char* phase_name() { return "V8.TFVerifyGraph"; } void Run(PipelineData* data, Zone* temp_zone, const bool untyped, bool values_only = false) { @@ -2176,10 +2251,10 @@ void PipelineImpl::RunPrintAndVerify(const char* phase, bool untyped) { } } -bool PipelineImpl::CreateGraph() { +void PipelineImpl::Serialize() { PipelineData* data = this->data_; - data->BeginPhaseKind("V8.TFGraphCreation"); + data->BeginPhaseKind("V8.TFBrokerInitAndSerialization"); if (info()->trace_turbo_json_enabled() || info()->trace_turbo_graph_enabled()) { @@ -2203,15 +2278,19 @@ bool PipelineImpl::CreateGraph() { if (FLAG_concurrent_inlining) { Run<HeapBrokerInitializationPhase>(); Run<SerializationPhase>(); + data->broker()->StopSerializing(); } + data->EndPhaseKind(); +} + +bool PipelineImpl::CreateGraph() { + PipelineData* data = this->data_; + + data->BeginPhaseKind("V8.TFGraphCreation"); Run<GraphBuilderPhase>(); RunPrintAndVerify(GraphBuilderPhase::phase_name(), true); - if (FLAG_concurrent_inlining) { - Run<CopyMetadataForConcurrentCompilePhase>(); - } - // Perform function context specialization and inlining (if enabled). Run<InliningPhase>(); RunPrintAndVerify(InliningPhase::phase_name(), true); @@ -2222,12 +2301,13 @@ bool PipelineImpl::CreateGraph() { // Determine the Typer operation flags. { - if (is_sloppy(info()->shared_info()->language_mode()) && - info()->shared_info()->IsUserJavaScript()) { + SharedFunctionInfoRef shared_info(data->broker(), info()->shared_info()); + if (is_sloppy(shared_info.language_mode()) && + shared_info.IsUserJavaScript()) { // Sloppy mode functions always have an Object for this. data->AddTyperFlag(Typer::kThisIsReceiver); } - if (IsClassConstructor(info()->shared_info()->kind())) { + if (IsClassConstructor(shared_info.kind())) { // Class constructors cannot be [[Call]]ed. data->AddTyperFlag(Typer::kNewTargetIsReceiver); } @@ -2235,12 +2315,7 @@ bool PipelineImpl::CreateGraph() { // Run the type-sensitive lowerings and optimizations on the graph. { - if (FLAG_concurrent_inlining) { - // TODO(neis): Remove CopyMetadataForConcurrentCompilePhase call once - // brokerization of JSNativeContextSpecialization is complete. - Run<CopyMetadataForConcurrentCompilePhase>(); - data->broker()->StopSerializing(); - } else { + if (!FLAG_concurrent_inlining) { Run<HeapBrokerInitializationPhase>(); Run<CopyMetadataForConcurrentCompilePhase>(); data->broker()->StopSerializing(); @@ -2359,6 +2434,70 @@ bool PipelineImpl::OptimizeGraph(Linkage* linkage) { return SelectInstructions(linkage); } +bool PipelineImpl::OptimizeGraphForMidTier(Linkage* linkage) { + PipelineData* data = this->data_; + + data->BeginPhaseKind("V8.TFLowering"); + + // Type the graph and keep the Typer running such that new nodes get + // automatically typed when they are created. + Run<TyperPhase>(data->CreateTyper()); + RunPrintAndVerify(TyperPhase::phase_name()); + Run<TypedLoweringPhase>(); + RunPrintAndVerify(TypedLoweringPhase::phase_name()); + + // TODO(9684): Consider rolling this into the preceeding phase or not creating + // LoopExit nodes at all. + Run<LoopExitEliminationPhase>(); + RunPrintAndVerify(LoopExitEliminationPhase::phase_name(), true); + + data->DeleteTyper(); + + if (FLAG_assert_types) { + Run<TypeAssertionsPhase>(); + RunPrintAndVerify(TypeAssertionsPhase::phase_name()); + } + + // Perform simplified lowering. This has to run w/o the Typer decorator, + // because we cannot compute meaningful types anyways, and the computed types + // might even conflict with the representation/truncation logic. + Run<SimplifiedLoweringPhase>(); + RunPrintAndVerify(SimplifiedLoweringPhase::phase_name(), true); + + // From now on it is invalid to look at types on the nodes, because the types + // on the nodes might not make sense after representation selection due to the + // way we handle truncations; if we'd want to look at types afterwards we'd + // essentially need to re-type (large portions of) the graph. + + // In order to catch bugs related to type access after this point, we now + // remove the types from the nodes (currently only in Debug builds). +#ifdef DEBUG + Run<UntyperPhase>(); + RunPrintAndVerify(UntyperPhase::phase_name(), true); +#endif + + // Run generic lowering pass. + Run<GenericLoweringPhase>(); + RunPrintAndVerify(GenericLoweringPhase::phase_name(), true); + + data->BeginPhaseKind("V8.TFBlockBuilding"); + + Run<EffectControlLinearizationPhase>(); + RunPrintAndVerify(EffectControlLinearizationPhase::phase_name(), true); + + Run<MidTierMachineLoweringPhase>(); + RunPrintAndVerify(MidTierMachineLoweringPhase::phase_name(), true); + + data->source_positions()->RemoveDecorator(); + if (data->info()->trace_turbo_json_enabled()) { + data->node_origins()->RemoveDecorator(); + } + + ComputeScheduledGraph(); + + return SelectInstructions(linkage); +} + MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub( Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph, SourcePositionTable* source_positions, Code::Kind kind, @@ -2571,6 +2710,7 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info)); Deoptimizer::EnsureCodeForDeoptimizationEntries(isolate); + pipeline.Serialize(); if (!pipeline.CreateGraph()) return MaybeHandle<Code>(); if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>(); pipeline.AssembleCode(&linkage); @@ -2628,7 +2768,7 @@ std::unique_ptr<OptimizedCompilationJob> Pipeline::NewCompilationJob( Isolate* isolate, Handle<JSFunction> function, bool has_script) { Handle<SharedFunctionInfo> shared = handle(function->shared(), function->GetIsolate()); - return base::make_unique<PipelineCompilationJob>(isolate, shared, function); + return std::make_unique<PipelineCompilationJob>(isolate, shared, function); } // static @@ -2709,7 +2849,7 @@ void Pipeline::GenerateCodeForWasmFunction( if (!pipeline.SelectInstructions(&linkage)) return; pipeline.AssembleCode(&linkage, instruction_buffer->CreateView()); - auto result = base::make_unique<wasm::WasmCompilationResult>(); + auto result = std::make_unique<wasm::WasmCompilationResult>(); CodeGenerator* code_generator = pipeline.code_generator(); code_generator->tasm()->GetCode( nullptr, &result->code_desc, code_generator->safepoint_table_builder(), @@ -2818,7 +2958,7 @@ bool PipelineImpl::SelectInstructions(Linkage* linkage) { << "--- End of " << data->debug_name() << " generated by TurboFan\n" << "--------------------------------------------------\n"; } - Zone temp_zone(data->allocator(), ZONE_NAME); + Zone temp_zone(data->allocator(), kMachineGraphVerifierZoneName); MachineGraphVerifier::Run( data->graph(), data->schedule(), linkage, data->info()->IsNotOptimizedFunctionOrWasmFunction(), @@ -2993,6 +3133,7 @@ void PipelineImpl::AssembleCode(Linkage* linkage, MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) { PipelineData* data = this->data_; + data->BeginPhaseKind("V8.TFFinalizeCode"); if (data->broker() && retire_broker) { data->broker()->Retire(); } @@ -3007,7 +3148,7 @@ MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) { if (data->profiler_data()) { #ifdef ENABLE_DISASSEMBLER std::ostringstream os; - code->Disassemble(nullptr, os); + code->Disassemble(nullptr, os, isolate()); data->profiler_data()->SetCode(&os); #endif // ENABLE_DISASSEMBLER } @@ -3023,7 +3164,7 @@ MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) { << "\"data\":\""; #ifdef ENABLE_DISASSEMBLER std::stringstream disassembly_stream; - code->Disassemble(nullptr, disassembly_stream); + code->Disassemble(nullptr, disassembly_stream, isolate()); std::string disassembly_string(disassembly_stream.str()); for (const auto& c : disassembly_string) { json_of << AsEscapedUC16ForJSON(c); @@ -3043,6 +3184,7 @@ MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) { << "Finished compiling method " << info()->GetDebugName().get() << " using TurboFan" << std::endl; } + data->EndPhaseKind(); return code; } @@ -3100,7 +3242,8 @@ void PipelineImpl::AllocateRegisters(const RegisterConfiguration* config, std::unique_ptr<Zone> verifier_zone; RegisterAllocatorVerifier* verifier = nullptr; if (run_verifier) { - verifier_zone.reset(new Zone(data->allocator(), ZONE_NAME)); + verifier_zone.reset( + new Zone(data->allocator(), kRegisterAllocatorVerifierZoneName)); verifier = new (verifier_zone.get()) RegisterAllocatorVerifier( verifier_zone.get(), config, data->sequence()); } diff --git a/deps/v8/src/compiler/pipeline.h b/deps/v8/src/compiler/pipeline.h index 3707bfb06e5d59..42f31472a9be36 100644 --- a/deps/v8/src/compiler/pipeline.h +++ b/deps/v8/src/compiler/pipeline.h @@ -5,6 +5,8 @@ #ifndef V8_COMPILER_PIPELINE_H_ #define V8_COMPILER_PIPELINE_H_ +#include <memory> + // Clients of this interface shouldn't depend on lots of compiler internals. // Do not include anything from src/compiler here! #include "src/common/globals.h" diff --git a/deps/v8/src/compiler/processed-feedback.h b/deps/v8/src/compiler/processed-feedback.h index 17829863de1a09..1d1ee538d8b6d7 100644 --- a/deps/v8/src/compiler/processed-feedback.h +++ b/deps/v8/src/compiler/processed-feedback.h @@ -18,7 +18,10 @@ class ElementAccessFeedback; class ForInFeedback; class GlobalAccessFeedback; class InstanceOfFeedback; +class LiteralFeedback; class NamedAccessFeedback; +class RegExpLiteralFeedback; +class TemplateObjectFeedback; class ProcessedFeedback : public ZoneObject { public: @@ -31,7 +34,10 @@ class ProcessedFeedback : public ZoneObject { kForIn, kGlobalAccess, kInstanceOf, + kLiteral, kNamedAccess, + kRegExpLiteral, + kTemplateObject, }; Kind kind() const { return kind_; } @@ -46,6 +52,9 @@ class ProcessedFeedback : public ZoneObject { GlobalAccessFeedback const& AsGlobalAccess() const; InstanceOfFeedback const& AsInstanceOf() const; NamedAccessFeedback const& AsNamedAccess() const; + LiteralFeedback const& AsLiteral() const; + RegExpLiteralFeedback const& AsRegExpLiteral() const; + TemplateObjectFeedback const& AsTemplateObject() const; protected: ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind); @@ -187,7 +196,9 @@ class SingleValueFeedback : public ProcessedFeedback { (K == kBinaryOperation && slot_kind == FeedbackSlotKind::kBinaryOp) || (K == kCompareOperation && slot_kind == FeedbackSlotKind::kCompareOp) || (K == kForIn && slot_kind == FeedbackSlotKind::kForIn) || - (K == kInstanceOf && slot_kind == FeedbackSlotKind::kInstanceOf)); + (K == kInstanceOf && slot_kind == FeedbackSlotKind::kInstanceOf) || + ((K == kLiteral || K == kRegExpLiteral || K == kTemplateObject) && + slot_kind == FeedbackSlotKind::kLiteral)); } T value() const { return value_; } @@ -202,6 +213,24 @@ class InstanceOfFeedback using SingleValueFeedback::SingleValueFeedback; }; +class LiteralFeedback + : public SingleValueFeedback<AllocationSiteRef, + ProcessedFeedback::kLiteral> { + using SingleValueFeedback::SingleValueFeedback; +}; + +class RegExpLiteralFeedback + : public SingleValueFeedback<JSRegExpRef, + ProcessedFeedback::kRegExpLiteral> { + using SingleValueFeedback::SingleValueFeedback; +}; + +class TemplateObjectFeedback + : public SingleValueFeedback<JSArrayRef, + ProcessedFeedback::kTemplateObject> { + using SingleValueFeedback::SingleValueFeedback; +}; + class BinaryOperationFeedback : public SingleValueFeedback<BinaryOperationHint, ProcessedFeedback::kBinaryOperation> { diff --git a/deps/v8/src/compiler/raw-machine-assembler.cc b/deps/v8/src/compiler/raw-machine-assembler.cc index e399b9c4f6b424..7031437cc20bd7 100644 --- a/deps/v8/src/compiler/raw-machine-assembler.cc +++ b/deps/v8/src/compiler/raw-machine-assembler.cc @@ -690,15 +690,14 @@ Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* call_descriptor, return AddNode(common()->Call(call_descriptor), input_count, inputs); } -Node* RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor, - int input_count, Node* const* inputs) { +void RawMachineAssembler::TailCallN(CallDescriptor* call_descriptor, + int input_count, Node* const* inputs) { // +1 is for target. DCHECK_EQ(input_count, call_descriptor->ParameterCount() + 1); Node* tail_call = MakeNode(common()->TailCall(call_descriptor), input_count, inputs); schedule()->AddTailCall(CurrentBlock(), tail_call); current_block_ = nullptr; - return tail_call; } namespace { @@ -706,7 +705,8 @@ namespace { Node* CallCFunctionImpl( RawMachineAssembler* rasm, Node* function, MachineType return_type, std::initializer_list<RawMachineAssembler::CFunctionArg> args, - bool caller_saved_regs, SaveFPRegsMode mode) { + bool caller_saved_regs, SaveFPRegsMode mode, + bool has_function_descriptor = kHasFunctionDescriptor) { static constexpr std::size_t kNumCArgs = 10; MachineSignature::Builder builder(rasm->zone(), 1, args.size()); @@ -720,6 +720,8 @@ Node* CallCFunctionImpl( if (caller_saved_regs) call_descriptor->set_save_fp_mode(mode); + call_descriptor->set_has_function_descriptor(has_function_descriptor); + base::SmallVector<Node*, kNumCArgs> nodes(args.size() + 1); nodes[0] = function; std::transform( @@ -740,6 +742,13 @@ Node* RawMachineAssembler::CallCFunction( kDontSaveFPRegs); } +Node* RawMachineAssembler::CallCFunctionWithoutFunctionDescriptor( + Node* function, MachineType return_type, + std::initializer_list<RawMachineAssembler::CFunctionArg> args) { + return CallCFunctionImpl(this, function, return_type, args, false, + kDontSaveFPRegs, kNoFunctionDescriptor); +} + Node* RawMachineAssembler::CallCFunctionWithCallerSavedRegisters( Node* function, MachineType return_type, SaveFPRegsMode mode, std::initializer_list<RawMachineAssembler::CFunctionArg> args) { diff --git a/deps/v8/src/compiler/raw-machine-assembler.h b/deps/v8/src/compiler/raw-machine-assembler.h index 46940df44f88f5..c0bfd84a617a6f 100644 --- a/deps/v8/src/compiler/raw-machine-assembler.h +++ b/deps/v8/src/compiler/raw-machine-assembler.h @@ -131,7 +131,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { std::pair<MachineType, const Operator*> InsertDecompressionIfNeeded( MachineType type) { const Operator* decompress_op = nullptr; - if (COMPRESS_POINTERS_BOOL) { + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { switch (type.representation()) { case MachineRepresentation::kTaggedPointer: type = MachineType::CompressedPointer(); @@ -188,7 +188,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { std::pair<MachineRepresentation, Node*> InsertCompressionIfNeeded( MachineRepresentation rep, Node* value) { - if (COMPRESS_POINTERS_BOOL) { + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { switch (rep) { case MachineRepresentation::kTaggedPointer: rep = MachineRepresentation::kCompressedPointer; @@ -237,7 +237,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { object, value); } void OptimizedStoreMap(Node* object, Node* value) { - if (COMPRESS_POINTERS_BOOL) { + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { DCHECK(AccessBuilder::ForMap().machine_type.IsCompressedPointer()); value = AddNode(machine()->ChangeTaggedPointerToCompressedPointer(), value); @@ -736,8 +736,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { Node* BitcastTaggedToWord(Node* a) { return AddNode(machine()->BitcastTaggedToWord(), a); } - Node* BitcastTaggedSignedToWord(Node* a) { - return AddNode(machine()->BitcastTaggedSignedToWord(), a); + Node* BitcastTaggedToWordForTagAndSmiBits(Node* a) { + return AddNode(machine()->BitcastTaggedToWordForTagAndSmiBits(), a); } Node* BitcastMaybeObjectToWord(Node* a) { return AddNode(machine()->BitcastMaybeObjectToWord(), a); @@ -965,8 +965,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { // Tail call a given call descriptor and the given arguments. // The call target is passed as part of the {inputs} array. - Node* TailCallN(CallDescriptor* call_descriptor, int input_count, - Node* const* inputs); + void TailCallN(CallDescriptor* call_descriptor, int input_count, + Node* const* inputs); // Type representing C function argument with type info. using CFunctionArg = std::pair<MachineType, Node*>; @@ -983,6 +983,22 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { Node* CallCFunction(Node* function, MachineType return_type, std::initializer_list<CFunctionArg> args); + // Call to a C function without a function discriptor on AIX. + template <class... CArgs> + Node* CallCFunctionWithoutFunctionDescriptor(Node* function, + MachineType return_type, + CArgs... cargs) { + static_assert(v8::internal::conjunction< + std::is_convertible<CArgs, CFunctionArg>...>::value, + "invalid argument types"); + return CallCFunctionWithoutFunctionDescriptor(function, return_type, + {cargs...}); + } + + Node* CallCFunctionWithoutFunctionDescriptor( + Node* function, MachineType return_type, + std::initializer_list<CFunctionArg> args); + // Call to a C function, while saving/restoring caller registers. template <class... CArgs> Node* CallCFunctionWithCallerSavedRegisters(Node* function, diff --git a/deps/v8/src/compiler/representation-change.cc b/deps/v8/src/compiler/representation-change.cc index fd0cbabe6685d1..ca1b1e221f3fbf 100644 --- a/deps/v8/src/compiler/representation-change.cc +++ b/deps/v8/src/compiler/representation-change.cc @@ -1272,8 +1272,13 @@ Node* RepresentationChanger::GetBitRepresentationFor( } } } else if (output_rep == MachineRepresentation::kTaggedSigned) { - node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node, - jsgraph()->IntPtrConstant(0)); + if (COMPRESS_POINTERS_BOOL) { + node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, + jsgraph()->Int32Constant(0)); + } else { + node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node, + jsgraph()->IntPtrConstant(0)); + } return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node, jsgraph()->Int32Constant(0)); } else if (output_rep == MachineRepresentation::kCompressed) { @@ -1546,14 +1551,17 @@ const Operator* RepresentationChanger::TaggedSignedOperatorFor( IrOpcode::Value opcode) { switch (opcode) { case IrOpcode::kSpeculativeNumberLessThan: - return machine()->Is32() ? machine()->Int32LessThan() - : machine()->Int64LessThan(); + return (COMPRESS_POINTERS_BOOL || machine()->Is32()) + ? machine()->Int32LessThan() + : machine()->Int64LessThan(); case IrOpcode::kSpeculativeNumberLessThanOrEqual: - return machine()->Is32() ? machine()->Int32LessThanOrEqual() - : machine()->Int64LessThanOrEqual(); + return (COMPRESS_POINTERS_BOOL || machine()->Is32()) + ? machine()->Int32LessThanOrEqual() + : machine()->Int64LessThanOrEqual(); case IrOpcode::kSpeculativeNumberEqual: - return machine()->Is32() ? machine()->Word32Equal() - : machine()->Word64Equal(); + return (COMPRESS_POINTERS_BOOL || machine()->Is32()) + ? machine()->Word32Equal() + : machine()->Word64Equal(); default: UNREACHABLE(); } diff --git a/deps/v8/src/compiler/scheduler.cc b/deps/v8/src/compiler/scheduler.cc index bf23e436f68f1e..2999cbfcd6e5b0 100644 --- a/deps/v8/src/compiler/scheduler.cc +++ b/deps/v8/src/compiler/scheduler.cc @@ -6,7 +6,7 @@ #include <iomanip> -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/codegen/tick-counter.h" #include "src/compiler/common-operator.h" #include "src/compiler/control-equivalence.h" diff --git a/deps/v8/src/compiler/select-lowering.cc b/deps/v8/src/compiler/select-lowering.cc index 4d5bb99053f6d1..290306a966bf5f 100644 --- a/deps/v8/src/compiler/select-lowering.cc +++ b/deps/v8/src/compiler/select-lowering.cc @@ -14,29 +14,39 @@ namespace v8 { namespace internal { namespace compiler { -SelectLowering::SelectLowering(Graph* graph, CommonOperatorBuilder* common) - : common_(common), graph_(graph) {} +SelectLowering::SelectLowering(JSGraph* jsgraph, Zone* zone) + : graph_assembler_(jsgraph, nullptr, nullptr, zone), + start_(jsgraph->graph()->start()) {} SelectLowering::~SelectLowering() = default; - Reduction SelectLowering::Reduce(Node* node) { if (node->opcode() != IrOpcode::kSelect) return NoChange(); + return Changed(LowerSelect(node)); +} + +#define __ gasm()-> + +Node* SelectLowering::LowerSelect(Node* node) { SelectParameters const p = SelectParametersOf(node->op()); - Node* cond = node->InputAt(0); - Node* vthen = node->InputAt(1); - Node* velse = node->InputAt(2); - - // Create a diamond and a phi. - Diamond d(graph(), common(), cond, p.hint()); - node->ReplaceInput(0, vthen); - node->ReplaceInput(1, velse); - node->ReplaceInput(2, d.merge); - NodeProperties::ChangeOp(node, common()->Phi(p.representation(), 2)); - return Changed(node); + Node* condition = node->InputAt(0); + Node* vtrue = node->InputAt(1); + Node* vfalse = node->InputAt(2); + + gasm()->Reset(start(), start()); + + auto done = __ MakeLabel(p.representation()); + + __ GotoIf(condition, &done, vtrue); + __ Goto(&done, vfalse); + __ Bind(&done); + + return done.PhiAt(0); } +#undef __ + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/src/compiler/select-lowering.h b/deps/v8/src/compiler/select-lowering.h index d8c12d4d5468be..53890a7898152d 100644 --- a/deps/v8/src/compiler/select-lowering.h +++ b/deps/v8/src/compiler/select-lowering.h @@ -5,33 +5,31 @@ #ifndef V8_COMPILER_SELECT_LOWERING_H_ #define V8_COMPILER_SELECT_LOWERING_H_ +#include "src/compiler/graph-assembler.h" #include "src/compiler/graph-reducer.h" namespace v8 { namespace internal { namespace compiler { -// Forward declarations. -class CommonOperatorBuilder; -class Graph; - - // Lowers Select nodes to diamonds. class SelectLowering final : public Reducer { public: - SelectLowering(Graph* graph, CommonOperatorBuilder* common); + SelectLowering(JSGraph* jsgraph, Zone* zone); ~SelectLowering() override; const char* reducer_name() const override { return "SelectLowering"; } Reduction Reduce(Node* node) override; + Node* LowerSelect(Node* node); + private: - CommonOperatorBuilder* common() const { return common_; } - Graph* graph() const { return graph_; } + GraphAssembler* gasm() { return &graph_assembler_; } + Node* start() { return start_; } - CommonOperatorBuilder* common_; - Graph* graph_; + GraphAssembler graph_assembler_; + Node* start_; }; } // namespace compiler diff --git a/deps/v8/src/compiler/serializer-for-background-compilation.cc b/deps/v8/src/compiler/serializer-for-background-compilation.cc index 20d405b77579f9..ebf3dbd482e7fe 100644 --- a/deps/v8/src/compiler/serializer-for-background-compilation.cc +++ b/deps/v8/src/compiler/serializer-for-background-compilation.cc @@ -10,7 +10,9 @@ #include "src/compiler/access-info.h" #include "src/compiler/bytecode-analysis.h" #include "src/compiler/compilation-dependencies.h" +#include "src/compiler/functional-list.h" #include "src/compiler/js-heap-broker.h" +#include "src/compiler/zone-stats.h" #include "src/handles/handles-inl.h" #include "src/ic/call-optimization.h" #include "src/interpreter/bytecode-array-iterator.h" @@ -41,7 +43,6 @@ namespace compiler { V(CallRuntime) \ V(CloneObject) \ V(CreateArrayFromIterable) \ - V(CreateEmptyArrayLiteral) \ V(CreateEmptyObjectLiteral) \ V(CreateMappedArguments) \ V(CreateRestParameter) \ @@ -160,6 +161,7 @@ namespace compiler { V(CreateBlockContext) \ V(CreateCatchContext) \ V(CreateClosure) \ + V(CreateEmptyArrayLiteral) \ V(CreateEvalContext) \ V(CreateFunctionContext) \ V(CreateObjectLiteral) \ @@ -230,13 +232,41 @@ namespace compiler { UNCONDITIONAL_JUMPS_LIST(V) \ UNREACHABLE_BYTECODE_LIST(V) -template <typename T> -struct HandleComparator { - bool operator()(const Handle<T>& lhs, const Handle<T>& rhs) const { - return lhs.address() < rhs.address(); +template <typename T, typename EqualTo> +class FunctionalSet { + public: + void Add(T const& elem, Zone* zone) { + for (auto const& l : data_) { + if (equal_to(l, elem)) return; + } + data_.PushFront(elem, zone); + } + + bool Includes(FunctionalSet<T, EqualTo> const& other) const { + return std::all_of(other.begin(), other.end(), [&](T const& other_elem) { + return std::any_of(this->begin(), this->end(), [&](T const& this_elem) { + return equal_to(this_elem, other_elem); + }); + }); } + + bool IsEmpty() const { return data_.begin() == data_.end(); } + + void Clear() { data_.Clear(); } + + using iterator = typename FunctionalList<T>::iterator; + + iterator begin() const { return data_.begin(); } + iterator end() const { return data_.end(); } + + private: + static EqualTo equal_to; + FunctionalList<T> data_; }; +template <typename T, typename EqualTo> +EqualTo FunctionalSet<T, EqualTo>::equal_to; + struct VirtualContext { unsigned int distance; Handle<Context> context; @@ -245,21 +275,22 @@ struct VirtualContext { : distance(distance_in), context(context_in) { CHECK_GT(distance, 0); } - bool operator<(const VirtualContext& other) const { - return HandleComparator<Context>()(context, other.context) && - distance < other.distance; + bool operator==(const VirtualContext& other) const { + return context.equals(other.context) && distance == other.distance; } }; class FunctionBlueprint; -using ConstantsSet = ZoneSet<Handle<Object>, HandleComparator<Object>>; -using VirtualContextsSet = ZoneSet<VirtualContext>; -using MapsSet = ZoneSet<Handle<Map>, HandleComparator<Map>>; -using BlueprintsSet = ZoneSet<FunctionBlueprint>; +using ConstantsSet = FunctionalSet<Handle<Object>, Handle<Object>::equal_to>; +using VirtualContextsSet = + FunctionalSet<VirtualContext, std::equal_to<VirtualContext>>; +using MapsSet = FunctionalSet<Handle<Map>, Handle<Map>::equal_to>; +using BlueprintsSet = + FunctionalSet<FunctionBlueprint, std::equal_to<FunctionBlueprint>>; class Hints { public: - explicit Hints(Zone* zone); + Hints() = default; static Hints SingleConstant(Handle<Object> constant, Zone* zone); @@ -268,12 +299,13 @@ class Hints { const BlueprintsSet& function_blueprints() const; const VirtualContextsSet& virtual_contexts() const; - void AddConstant(Handle<Object> constant); - void AddMap(Handle<Map> map); - void AddFunctionBlueprint(FunctionBlueprint function_blueprint); - void AddVirtualContext(VirtualContext virtual_context); + void AddConstant(Handle<Object> constant, Zone* zone); + void AddMap(Handle<Map> map, Zone* zone); + void AddFunctionBlueprint(FunctionBlueprint function_blueprint, Zone* zone); + void AddVirtualContext(VirtualContext virtual_context, Zone* zone); - void Add(const Hints& other); + void Add(const Hints& other, Zone* zone); + void AddFromChildSerializer(const Hints& other, Zone* zone); void Clear(); bool IsEmpty() const; @@ -292,6 +324,8 @@ class Hints { using HintsVector = ZoneVector<Hints>; +// A FunctionBlueprint is a SharedFunctionInfo and a FeedbackVector, plus +// Hints about the context in which a closure will be created from them. class FunctionBlueprint { public: FunctionBlueprint(Handle<JSFunction> function, Isolate* isolate, Zone* zone); @@ -304,13 +338,23 @@ class FunctionBlueprint { Handle<FeedbackVector> feedback_vector() const { return feedback_vector_; } const Hints& context_hints() const { return context_hints_; } - bool operator<(const FunctionBlueprint& other) const { - // A feedback vector is never used for more than one SFI, so it can - // be used for strict ordering of blueprints. + bool operator==(const FunctionBlueprint& other) const { + // A feedback vector is never used for more than one SFI. Moreover, we can + // never have two blueprints with identical feedback vector (and SFI) but + // different hints, because: + // (1) A blueprint originates either (i) from the data associated with a + // CreateClosure bytecode, in which case two different CreateClosure + // bytecodes never have the same feedback vector, or (ii) from a + // JSFunction, in which case the hints are determined by the closure. + // (2) We never extend a blueprint's hints after construction. + // + // It is therefore sufficient to look at the feedback vector in order to + // decide equality. DCHECK_IMPLIES(feedback_vector_.equals(other.feedback_vector_), shared_.equals(other.shared_)); - return HandleComparator<FeedbackVector>()(feedback_vector_, - other.feedback_vector_); + SLOW_DCHECK(!feedback_vector_.equals(other.feedback_vector_) || + context_hints_.Equals(other.context_hints_)); + return feedback_vector_.equals(other.feedback_vector_); } private: @@ -319,6 +363,8 @@ class FunctionBlueprint { Hints context_hints_; }; +// A CompilationSubject is a FunctionBlueprint, optionally with a matching +// closure. class CompilationSubject { public: explicit CompilationSubject(FunctionBlueprint blueprint) @@ -336,24 +382,67 @@ class CompilationSubject { MaybeHandle<JSFunction> closure_; }; +// A Callee is either a JSFunction (which may not have a feedback vector), or a +// FunctionBlueprint. Note that this is different from CompilationSubject, which +// always has a FunctionBlueprint. +class Callee { + public: + explicit Callee(Handle<JSFunction> jsfunction) + : jsfunction_(jsfunction), blueprint_() {} + explicit Callee(FunctionBlueprint const& blueprint) + : jsfunction_(), blueprint_(blueprint) {} + + Handle<SharedFunctionInfo> shared(Isolate* isolate) const { + return blueprint_.has_value() + ? blueprint_->shared() + : handle(jsfunction_.ToHandleChecked()->shared(), isolate); + } + + bool HasFeedbackVector() const { + Handle<JSFunction> function; + return blueprint_.has_value() || + jsfunction_.ToHandleChecked()->has_feedback_vector(); + } + + CompilationSubject ToCompilationSubject(Isolate* isolate, Zone* zone) const { + CHECK(HasFeedbackVector()); + return blueprint_.has_value() + ? CompilationSubject(*blueprint_) + : CompilationSubject(jsfunction_.ToHandleChecked(), isolate, + zone); + } + + private: + MaybeHandle<JSFunction> const jsfunction_; + base::Optional<FunctionBlueprint> const blueprint_; +}; + +// If a list of arguments (hints) is shorter than the function's parameter +// count, this enum expresses what we know about the missing arguments. +enum MissingArgumentsPolicy { + kMissingArgumentsAreUndefined, // ... as in the JS undefined value + kMissingArgumentsAreUnknown, +}; + // The SerializerForBackgroundCompilation makes sure that the relevant function // data such as bytecode, SharedFunctionInfo and FeedbackVector, used by later // optimizations in the compiler, is copied to the heap broker. class SerializerForBackgroundCompilation { public: SerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - Handle<JSFunction> closure, SerializerForBackgroundCompilationFlags flags, - BailoutId osr_offset); + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, Handle<JSFunction> closure, + SerializerForBackgroundCompilationFlags flags, BailoutId osr_offset); Hints Run(); // NOTE: Returns empty for an already-serialized function. class Environment; private: SerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - CompilationSubject function, base::Optional<Hints> new_target, - const HintsVector& arguments, + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, CompilationSubject function, + base::Optional<Hints> new_target, const HintsVector& arguments, + MissingArgumentsPolicy padding, SerializerForBackgroundCompilationFlags flags); bool BailoutOnUninitialized(ProcessedFeedback const& feedback); @@ -365,36 +454,39 @@ class SerializerForBackgroundCompilation { SUPPORTED_BYTECODE_LIST(DECLARE_VISIT_BYTECODE) #undef DECLARE_VISIT_BYTECODE - // Returns whether the callee with the given SFI should be processed further, - // i.e. whether it's inlineable. - bool ProcessSFIForCallOrConstruct(Handle<SharedFunctionInfo> shared, + void ProcessSFIForCallOrConstruct(Callee const& callee, + base::Optional<Hints> new_target, const HintsVector& arguments, - SpeculationMode speculation_mode); - // Returns whether {function} should be serialized for compilation. - bool ProcessCalleeForCallOrConstruct(Handle<JSFunction> function, + SpeculationMode speculation_mode, + MissingArgumentsPolicy padding); + void ProcessCalleeForCallOrConstruct(Handle<Object> callee, + base::Optional<Hints> new_target, const HintsVector& arguments, - SpeculationMode speculation_mode); + SpeculationMode speculation_mode, + MissingArgumentsPolicy padding); void ProcessCallOrConstruct(Hints callee, base::Optional<Hints> new_target, const HintsVector& arguments, FeedbackSlot slot, - bool with_spread = false); - void ProcessCallVarArgs(ConvertReceiverMode receiver_mode, - Hints const& callee, interpreter::Register first_reg, - int reg_count, FeedbackSlot slot, - bool with_spread = false); + MissingArgumentsPolicy padding); + void ProcessCallVarArgs( + ConvertReceiverMode receiver_mode, Hints const& callee, + interpreter::Register first_reg, int reg_count, FeedbackSlot slot, + MissingArgumentsPolicy padding = kMissingArgumentsAreUndefined); void ProcessApiCall(Handle<SharedFunctionInfo> target, const HintsVector& arguments); void ProcessReceiverMapForApiCall(FunctionTemplateInfoRef target, Handle<Map> receiver); void ProcessBuiltinCall(Handle<SharedFunctionInfo> target, + base::Optional<Hints> new_target, const HintsVector& arguments, - SpeculationMode speculation_mode); + SpeculationMode speculation_mode, + MissingArgumentsPolicy padding); void ProcessJump(interpreter::BytecodeArrayIterator* iterator); void ProcessKeyedPropertyAccess(Hints const& receiver, Hints const& key, FeedbackSlot slot, AccessMode access_mode, bool honor_bailout_on_uninitialized); - void ProcessNamedPropertyAccess(Hints receiver, NameRef const& name, + void ProcessNamedPropertyAccess(Hints const& receiver, NameRef const& name, FeedbackSlot slot, AccessMode access_mode); void ProcessNamedAccess(Hints receiver, NamedAccessFeedback const& feedback, AccessMode access_mode, Hints* new_accumulator_hints); @@ -411,7 +503,6 @@ class SerializerForBackgroundCompilation { void ProcessHintsForHasInPrototypeChain(Hints const& instance_hints); void ProcessHintsForRegExpTest(Hints const& regexp_hints); PropertyAccessInfo ProcessMapForRegExpTest(MapRef map); - void ProcessHintsForFunctionCall(Hints const& target_hints); void ProcessHintsForFunctionBind(Hints const& receiver_hints); void ProcessHintsForObjectGetPrototype(Hints const& object_hints); void ProcessConstantForOrdinaryHasInstance(HeapObjectRef const& constructor, @@ -456,7 +547,8 @@ class SerializerForBackgroundCompilation { Hints RunChildSerializer(CompilationSubject function, base::Optional<Hints> new_target, - const HintsVector& arguments, bool with_spread); + const HintsVector& arguments, + MissingArgumentsPolicy padding); // When (forward-)branching bytecodes are encountered, e.g. a conditional // jump, we call ContributeToJumpTargetEnvironment to "remember" the current @@ -475,14 +567,14 @@ class SerializerForBackgroundCompilation { JSHeapBroker* broker() const { return broker_; } CompilationDependencies* dependencies() const { return dependencies_; } - Zone* zone() const { return zone_; } + Zone* zone() { return zone_scope_.zone(); } Environment* environment() const { return environment_; } SerializerForBackgroundCompilationFlags flags() const { return flags_; } BailoutId osr_offset() const { return osr_offset_; } JSHeapBroker* const broker_; CompilationDependencies* const dependencies_; - Zone* const zone_; + ZoneStats::Scope zone_scope_; Environment* const environment_; ZoneUnorderedMap<int, Environment*> jump_target_environments_; SerializerForBackgroundCompilationFlags const flags_; @@ -490,11 +582,11 @@ class SerializerForBackgroundCompilation { }; void RunSerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - Handle<JSFunction> closure, SerializerForBackgroundCompilationFlags flags, - BailoutId osr_offset) { - SerializerForBackgroundCompilation serializer(broker, dependencies, zone, - closure, flags, osr_offset); + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, Handle<JSFunction> closure, + SerializerForBackgroundCompilationFlags flags, BailoutId osr_offset) { + SerializerForBackgroundCompilation serializer( + zone_stats, broker, dependencies, closure, flags, osr_offset); serializer.Run(); } @@ -505,14 +597,19 @@ FunctionBlueprint::FunctionBlueprint(Handle<SharedFunctionInfo> shared, const Hints& context_hints) : shared_(shared), feedback_vector_(feedback_vector), - context_hints_(context_hints) {} + context_hints_(context_hints) { + // The checked invariant rules out recursion and thus avoids complexity. + CHECK(context_hints_.function_blueprints().IsEmpty()); +} FunctionBlueprint::FunctionBlueprint(Handle<JSFunction> function, Isolate* isolate, Zone* zone) : shared_(handle(function->shared(), isolate)), - feedback_vector_(handle(function->feedback_vector(), isolate)), - context_hints_(zone) { - context_hints_.AddConstant(handle(function->context(), isolate)); + feedback_vector_(function->feedback_vector(), isolate), + context_hints_() { + context_hints_.AddConstant(handle(function->context(), isolate), zone); + // The checked invariant rules out recursion and thus avoids complexity. + CHECK(context_hints_.function_blueprints().IsEmpty()); } CompilationSubject::CompilationSubject(Handle<JSFunction> closure, @@ -521,25 +618,11 @@ CompilationSubject::CompilationSubject(Handle<JSFunction> closure, CHECK(closure->has_feedback_vector()); } -Hints::Hints(Zone* zone) - : virtual_contexts_(zone), - constants_(zone), - maps_(zone), - function_blueprints_(zone) {} - #ifdef ENABLE_SLOW_DCHECKS -namespace { -template <typename K, typename Compare> -bool SetIncludes(ZoneSet<K, Compare> const& lhs, - ZoneSet<K, Compare> const& rhs) { - return std::all_of(rhs.cbegin(), rhs.cend(), - [&](K const& x) { return lhs.find(x) != lhs.cend(); }); -} -} // namespace bool Hints::Includes(Hints const& other) const { - return SetIncludes(constants(), other.constants()) && - SetIncludes(function_blueprints(), other.function_blueprints()) && - SetIncludes(maps(), other.maps()); + return constants().Includes(other.constants()) && + function_blueprints().Includes(other.function_blueprints()) && + maps().Includes(other.maps()); } bool Hints::Equals(Hints const& other) const { return this->Includes(other) && other.Includes(*this); @@ -547,8 +630,8 @@ bool Hints::Equals(Hints const& other) const { #endif Hints Hints::SingleConstant(Handle<Object> constant, Zone* zone) { - Hints result(zone); - result.AddConstant(constant); + Hints result; + result.AddConstant(constant, zone); return result; } @@ -564,30 +647,49 @@ const VirtualContextsSet& Hints::virtual_contexts() const { return virtual_contexts_; } -void Hints::AddVirtualContext(VirtualContext virtual_context) { - virtual_contexts_.insert(virtual_context); +void Hints::AddVirtualContext(VirtualContext virtual_context, Zone* zone) { + virtual_contexts_.Add(virtual_context, zone); } -void Hints::AddConstant(Handle<Object> constant) { - constants_.insert(constant); +void Hints::AddConstant(Handle<Object> constant, Zone* zone) { + constants_.Add(constant, zone); } -void Hints::AddMap(Handle<Map> map) { maps_.insert(map); } +void Hints::AddMap(Handle<Map> map, Zone* zone) { maps_.Add(map, zone); } + +void Hints::AddFunctionBlueprint(FunctionBlueprint function_blueprint, + Zone* zone) { + function_blueprints_.Add(function_blueprint, zone); +} -void Hints::AddFunctionBlueprint(FunctionBlueprint function_blueprint) { - function_blueprints_.insert(function_blueprint); +void Hints::Add(const Hints& other, Zone* zone) { + for (auto x : other.constants()) AddConstant(x, zone); + for (auto x : other.maps()) AddMap(x, zone); + for (auto x : other.function_blueprints()) AddFunctionBlueprint(x, zone); + for (auto x : other.virtual_contexts()) AddVirtualContext(x, zone); } -void Hints::Add(const Hints& other) { - for (auto x : other.constants()) AddConstant(x); - for (auto x : other.maps()) AddMap(x); - for (auto x : other.function_blueprints()) AddFunctionBlueprint(x); - for (auto x : other.virtual_contexts()) AddVirtualContext(x); +void Hints::AddFromChildSerializer(const Hints& other, Zone* zone) { + for (auto x : other.constants()) AddConstant(x, zone); + for (auto x : other.maps()) AddMap(x, zone); + for (auto x : other.virtual_contexts()) AddVirtualContext(x, zone); + + // Adding hints from a child serializer run means copying data out from + // a zone that's being destroyed. FunctionBlueprints have zone allocated + // data, so we've got to make a deep copy to eliminate traces of the + // dying zone. + for (auto x : other.function_blueprints()) { + Hints new_blueprint_hints; + new_blueprint_hints.AddFromChildSerializer(x.context_hints(), zone); + FunctionBlueprint new_blueprint(x.shared(), x.feedback_vector(), + new_blueprint_hints); + AddFunctionBlueprint(new_blueprint, zone); + } } bool Hints::IsEmpty() const { - return constants().empty() && maps().empty() && - function_blueprints().empty() && virtual_contexts().empty(); + return constants().IsEmpty() && maps().IsEmpty() && + function_blueprints().IsEmpty() && virtual_contexts().IsEmpty(); } std::ostream& operator<<(std::ostream& out, @@ -625,10 +727,10 @@ std::ostream& operator<<(std::ostream& out, const Hints& hints) { } void Hints::Clear() { - virtual_contexts_.clear(); - constants_.clear(); - maps_.clear(); - function_blueprints_.clear(); + virtual_contexts_.Clear(); + constants_.Clear(); + maps_.Clear(); + function_blueprints_.Clear(); DCHECK(IsEmpty()); } @@ -636,7 +738,8 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject { public: Environment(Zone* zone, CompilationSubject function); Environment(Zone* zone, Isolate* isolate, CompilationSubject function, - base::Optional<Hints> new_target, const HintsVector& arguments); + base::Optional<Hints> new_target, const HintsVector& arguments, + MissingArgumentsPolicy padding); bool IsDead() const { return ephemeral_hints_.empty(); } @@ -648,7 +751,7 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject { void Revive() { DCHECK(IsDead()); - ephemeral_hints_.resize(ephemeral_hints_size(), Hints(zone())); + ephemeral_hints_.resize(ephemeral_hints_size(), Hints()); DCHECK(!IsDead()); } @@ -691,7 +794,6 @@ class SerializerForBackgroundCompilation::Environment : public ZoneObject { int RegisterToLocalIndex(interpreter::Register reg) const; - Zone* zone() const { return zone_; } int parameter_count() const { return parameter_count_; } int register_count() const { return register_count_; } @@ -722,24 +824,25 @@ SerializerForBackgroundCompilation::Environment::Environment( parameter_count_( function_.shared()->GetBytecodeArray().parameter_count()), register_count_(function_.shared()->GetBytecodeArray().register_count()), - closure_hints_(zone), - current_context_hints_(zone), - return_value_hints_(zone), - ephemeral_hints_(ephemeral_hints_size(), Hints(zone), zone) { + closure_hints_(), + current_context_hints_(), + return_value_hints_(), + ephemeral_hints_(ephemeral_hints_size(), Hints(), zone) { Handle<JSFunction> closure; if (function.closure().ToHandle(&closure)) { - closure_hints_.AddConstant(closure); + closure_hints_.AddConstant(closure, zone); } else { - closure_hints_.AddFunctionBlueprint(function.blueprint()); + closure_hints_.AddFunctionBlueprint(function.blueprint(), zone); } // Consume blueprint context hint information. - current_context_hints().Add(function.blueprint().context_hints()); + current_context_hints().Add(function.blueprint().context_hints(), zone); } SerializerForBackgroundCompilation::Environment::Environment( Zone* zone, Isolate* isolate, CompilationSubject function, - base::Optional<Hints> new_target, const HintsVector& arguments) + base::Optional<Hints> new_target, const HintsVector& arguments, + MissingArgumentsPolicy padding) : Environment(zone, function) { // Copy the hints for the actually passed arguments, at most up to // the parameter_count. @@ -748,11 +851,14 @@ SerializerForBackgroundCompilation::Environment::Environment( ephemeral_hints_[i] = arguments[i]; } - // Pad the rest with "undefined". - Hints undefined_hint = - Hints::SingleConstant(isolate->factory()->undefined_value(), zone); - for (size_t i = arguments.size(); i < param_count; ++i) { - ephemeral_hints_[i] = undefined_hint; + if (padding == kMissingArgumentsAreUndefined) { + Hints undefined_hint = + Hints::SingleConstant(isolate->factory()->undefined_value(), zone); + for (size_t i = arguments.size(); i < param_count; ++i) { + ephemeral_hints_[i] = undefined_hint; + } + } else { + DCHECK_EQ(padding, kMissingArgumentsAreUnknown); } interpreter::Register new_target_reg = @@ -762,7 +868,7 @@ SerializerForBackgroundCompilation::Environment::Environment( if (new_target_reg.is_valid()) { DCHECK(register_hints(new_target_reg).IsEmpty()); if (new_target.has_value()) { - register_hints(new_target_reg).Add(*new_target); + register_hints(new_target_reg).Add(*new_target, zone); } } } @@ -785,10 +891,10 @@ void SerializerForBackgroundCompilation::Environment::Merge( CHECK_EQ(ephemeral_hints_.size(), other->ephemeral_hints_.size()); for (size_t i = 0; i < ephemeral_hints_.size(); ++i) { - ephemeral_hints_[i].Add(other->ephemeral_hints_[i]); + ephemeral_hints_[i].Add(other->ephemeral_hints_[i], zone_); } - return_value_hints_.Add(other->return_value_hints_); + return_value_hints_.Add(other->return_value_hints_, zone_); } std::ostream& operator<<( @@ -845,30 +951,33 @@ int SerializerForBackgroundCompilation::Environment::RegisterToLocalIndex( } SerializerForBackgroundCompilation::SerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - Handle<JSFunction> closure, SerializerForBackgroundCompilationFlags flags, - BailoutId osr_offset) + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, Handle<JSFunction> closure, + SerializerForBackgroundCompilationFlags flags, BailoutId osr_offset) : broker_(broker), dependencies_(dependencies), - zone_(zone), - environment_(new (zone) Environment( - zone, CompilationSubject(closure, broker_->isolate(), zone))), - jump_target_environments_(zone), + zone_scope_(zone_stats, ZONE_NAME), + environment_(new (zone()) Environment( + zone(), CompilationSubject(closure, broker_->isolate(), zone()))), + jump_target_environments_(zone()), flags_(flags), osr_offset_(osr_offset) { JSFunctionRef(broker, closure).Serialize(); } SerializerForBackgroundCompilation::SerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - CompilationSubject function, base::Optional<Hints> new_target, - const HintsVector& arguments, SerializerForBackgroundCompilationFlags flags) + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, CompilationSubject function, + base::Optional<Hints> new_target, const HintsVector& arguments, + MissingArgumentsPolicy padding, + SerializerForBackgroundCompilationFlags flags) : broker_(broker), dependencies_(dependencies), - zone_(zone), - environment_(new (zone) Environment(zone, broker_->isolate(), function, - new_target, arguments)), - jump_target_environments_(zone), + zone_scope_(zone_stats, ZONE_NAME), + environment_(new (zone()) + Environment(zone(), broker_->isolate(), function, + new_target, arguments, padding)), + jump_target_environments_(zone()), flags_(flags), osr_offset_(BailoutId::None()) { TraceScope tracer( @@ -902,13 +1011,15 @@ bool SerializerForBackgroundCompilation::BailoutOnUninitialized( Hints SerializerForBackgroundCompilation::Run() { TraceScope tracer(broker(), this, "SerializerForBackgroundCompilation::Run"); + TRACE_BROKER_MEMORY(broker(), "[serializer start] Broker zone usage: " + << broker()->zone()->allocation_size()); SharedFunctionInfoRef shared(broker(), environment()->function().shared()); FeedbackVectorRef feedback_vector_ref(broker(), feedback_vector()); if (shared.IsSerializedForCompilation(feedback_vector_ref)) { TRACE_BROKER(broker(), "Already ran serializer for SharedFunctionInfo " << Brief(*shared.object()) << ", bailing out.\n"); - return Hints(zone()); + return Hints(); } shared.SetSerializedForCompilation(feedback_vector_ref); @@ -923,6 +1034,9 @@ Hints SerializerForBackgroundCompilation::Run() { feedback_vector_ref.Serialize(); TraverseBytecode(); + + TRACE_BROKER_MEMORY(broker(), "[serializer end] Broker zone usage: " + << broker()->zone()->allocation_size()); return environment()->return_value_hints(); } @@ -1036,12 +1150,19 @@ void SerializerForBackgroundCompilation::TraverseBytecode() { void SerializerForBackgroundCompilation::VisitGetIterator( BytecodeArrayIterator* iterator) { - AccessMode mode = AccessMode::kLoad; Hints const& receiver = environment()->register_hints(iterator->GetRegisterOperand(0)); Handle<Name> name = broker()->isolate()->factory()->iterator_symbol(); - FeedbackSlot slot = iterator->GetSlotOperand(1); - ProcessNamedPropertyAccess(receiver, NameRef(broker(), name), slot, mode); + FeedbackSlot load_slot = iterator->GetSlotOperand(1); + ProcessNamedPropertyAccess(receiver, NameRef(broker(), name), load_slot, + AccessMode::kLoad); + if (environment()->IsDead()) return; + + const Hints& callee = Hints(); + FeedbackSlot call_slot = iterator->GetSlotOperand(2); + HintsVector parameters({receiver}, zone()); + ProcessCallOrConstruct(callee, base::nullopt, parameters, call_slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitGetSuperConstructor( @@ -1057,72 +1178,74 @@ void SerializerForBackgroundCompilation::VisitGetSuperConstructor( map.SerializePrototype(); ObjectRef proto = map.prototype(); if (proto.IsHeapObject() && proto.AsHeapObject().map().is_constructor()) { - environment()->register_hints(dst).AddConstant(proto.object()); + environment()->register_hints(dst).AddConstant(proto.object(), zone()); } } } void SerializerForBackgroundCompilation::VisitGetTemplateObject( BytecodeArrayIterator* iterator) { - ObjectRef description( + TemplateObjectDescriptionRef description( broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate())); FeedbackSlot slot = iterator->GetSlotOperand(1); - FeedbackVectorRef feedback_vector_ref(broker(), feedback_vector()); + FeedbackSource source(feedback_vector(), slot); SharedFunctionInfoRef shared(broker(), environment()->function().shared()); - JSArrayRef template_object = - shared.GetTemplateObject(description, feedback_vector_ref, slot, - SerializationPolicy::kSerializeIfNeeded); + JSArrayRef template_object = shared.GetTemplateObject( + description, source, SerializationPolicy::kSerializeIfNeeded); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().AddConstant(template_object.object()); + environment()->accumulator_hints().AddConstant(template_object.object(), + zone()); } void SerializerForBackgroundCompilation::VisitLdaTrue( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - broker()->isolate()->factory()->true_value()); + broker()->isolate()->factory()->true_value(), zone()); } void SerializerForBackgroundCompilation::VisitLdaFalse( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - broker()->isolate()->factory()->false_value()); + broker()->isolate()->factory()->false_value(), zone()); } void SerializerForBackgroundCompilation::VisitLdaTheHole( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - broker()->isolate()->factory()->the_hole_value()); + broker()->isolate()->factory()->the_hole_value(), zone()); } void SerializerForBackgroundCompilation::VisitLdaUndefined( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - broker()->isolate()->factory()->undefined_value()); + broker()->isolate()->factory()->undefined_value(), zone()); } void SerializerForBackgroundCompilation::VisitLdaNull( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - broker()->isolate()->factory()->null_value()); + broker()->isolate()->factory()->null_value(), zone()); } void SerializerForBackgroundCompilation::VisitLdaZero( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().AddConstant( - handle(Smi::FromInt(0), broker()->isolate())); + handle(Smi::FromInt(0), broker()->isolate()), zone()); } void SerializerForBackgroundCompilation::VisitLdaSmi( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().AddConstant(handle( - Smi::FromInt(iterator->GetImmediateOperand(0)), broker()->isolate())); + environment()->accumulator_hints().AddConstant( + handle(Smi::FromInt(iterator->GetImmediateOperand(0)), + broker()->isolate()), + zone()); } void SerializerForBackgroundCompilation::VisitInvokeIntrinsic( @@ -1215,7 +1338,7 @@ void SerializerForBackgroundCompilation::VisitLdaConstant( ObjectRef object( broker(), iterator->GetConstantForIndexOperand(0, broker()->isolate())); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().AddConstant(object.object()); + environment()->accumulator_hints().AddConstant(object.object(), zone()); } void SerializerForBackgroundCompilation::VisitPushContext( @@ -1225,12 +1348,12 @@ void SerializerForBackgroundCompilation::VisitPushContext( Hints& saved_context_hints = environment()->register_hints(iterator->GetRegisterOperand(0)); saved_context_hints.Clear(); - saved_context_hints.Add(current_context_hints); + saved_context_hints.Add(current_context_hints, zone()); // New context is in the accumulator. Put those hints into the current context // register hints. current_context_hints.Clear(); - current_context_hints.Add(environment()->accumulator_hints()); + current_context_hints.Add(environment()->accumulator_hints(), zone()); } void SerializerForBackgroundCompilation::VisitPopContext( @@ -1239,7 +1362,7 @@ void SerializerForBackgroundCompilation::VisitPopContext( Hints& new_context_hints = environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->current_context_hints().Clear(); - environment()->current_context_hints().Add(new_context_hints); + environment()->current_context_hints().Add(new_context_hints, zone()); } void SerializerForBackgroundCompilation::ProcessImmutableLoad( @@ -1251,7 +1374,7 @@ void SerializerForBackgroundCompilation::ProcessImmutableLoad( // If requested, record the object as a hint for the result value. if (result_hints != nullptr && slot_value.has_value()) { - result_hints->AddConstant(slot_value.value().object()); + result_hints->AddConstant(slot_value.value().object(), zone()); } } @@ -1294,11 +1417,11 @@ void SerializerForBackgroundCompilation::VisitLdaContextSlot( environment()->register_hints(iterator->GetRegisterOperand(0)); const int slot = iterator->GetIndexOperand(1); const int depth = iterator->GetUnsignedImmediateOperand(2); - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; ProcessContextAccess(context_hints, slot, depth, kIgnoreSlot, &new_accumulator_hints); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } void SerializerForBackgroundCompilation::VisitLdaCurrentContextSlot( @@ -1306,11 +1429,11 @@ void SerializerForBackgroundCompilation::VisitLdaCurrentContextSlot( const int slot = iterator->GetIndexOperand(0); const int depth = 0; Hints const& context_hints = environment()->current_context_hints(); - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; ProcessContextAccess(context_hints, slot, depth, kIgnoreSlot, &new_accumulator_hints); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } void SerializerForBackgroundCompilation::VisitLdaImmutableContextSlot( @@ -1319,11 +1442,11 @@ void SerializerForBackgroundCompilation::VisitLdaImmutableContextSlot( const int depth = iterator->GetUnsignedImmediateOperand(2); Hints const& context_hints = environment()->register_hints(iterator->GetRegisterOperand(0)); - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; ProcessContextAccess(context_hints, slot, depth, kSerializeSlot, &new_accumulator_hints); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } void SerializerForBackgroundCompilation::VisitLdaImmutableCurrentContextSlot( @@ -1331,11 +1454,11 @@ void SerializerForBackgroundCompilation::VisitLdaImmutableCurrentContextSlot( const int slot = iterator->GetIndexOperand(0); const int depth = 0; Hints const& context_hints = environment()->current_context_hints(); - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; ProcessContextAccess(context_hints, slot, depth, kSerializeSlot, &new_accumulator_hints); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } void SerializerForBackgroundCompilation::ProcessModuleVariableAccess( @@ -1344,7 +1467,7 @@ void SerializerForBackgroundCompilation::ProcessModuleVariableAccess( const int depth = iterator->GetUnsignedImmediateOperand(1); Hints const& context_hints = environment()->current_context_hints(); - Hints result_hints(zone()); + Hints result_hints; ProcessContextAccess(context_hints, slot, depth, kSerializeSlot, &result_hints); for (Handle<Object> constant : result_hints.constants()) { @@ -1392,14 +1515,15 @@ void SerializerForBackgroundCompilation::VisitLdar( BytecodeArrayIterator* iterator) { environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Add( - environment()->register_hints(iterator->GetRegisterOperand(0))); + environment()->register_hints(iterator->GetRegisterOperand(0)), zone()); } void SerializerForBackgroundCompilation::VisitStar( BytecodeArrayIterator* iterator) { interpreter::Register reg = iterator->GetRegisterOperand(0); environment()->register_hints(reg).Clear(); - environment()->register_hints(reg).Add(environment()->accumulator_hints()); + environment()->register_hints(reg).Add(environment()->accumulator_hints(), + zone()); } void SerializerForBackgroundCompilation::VisitMov( @@ -1407,7 +1531,8 @@ void SerializerForBackgroundCompilation::VisitMov( interpreter::Register src = iterator->GetRegisterOperand(0); interpreter::Register dst = iterator->GetRegisterOperand(1); environment()->register_hints(dst).Clear(); - environment()->register_hints(dst).Add(environment()->register_hints(src)); + environment()->register_hints(dst).Add(environment()->register_hints(src), + zone()); } void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral( @@ -1415,6 +1540,9 @@ void SerializerForBackgroundCompilation::VisitCreateRegExpLiteral( Handle<String> constant_pattern = Handle<String>::cast( iterator->GetConstantForIndexOperand(0, broker()->isolate())); StringRef description(broker(), constant_pattern); + FeedbackSlot slot = iterator->GetSlotOperand(1); + FeedbackSource source(feedback_vector(), slot); + broker()->ProcessFeedbackForRegExpLiteral(source); environment()->accumulator_hints().Clear(); } @@ -1425,6 +1553,17 @@ void SerializerForBackgroundCompilation::VisitCreateArrayLiteral( iterator->GetConstantForIndexOperand(0, broker()->isolate())); ArrayBoilerplateDescriptionRef description(broker(), array_boilerplate_description); + FeedbackSlot slot = iterator->GetSlotOperand(1); + FeedbackSource source(feedback_vector(), slot); + broker()->ProcessFeedbackForArrayOrObjectLiteral(source); + environment()->accumulator_hints().Clear(); +} + +void SerializerForBackgroundCompilation::VisitCreateEmptyArrayLiteral( + BytecodeArrayIterator* iterator) { + FeedbackSlot slot = iterator->GetSlotOperand(0); + FeedbackSource source(feedback_vector(), slot); + broker()->ProcessFeedbackForArrayOrObjectLiteral(source); environment()->accumulator_hints().Clear(); } @@ -1434,6 +1573,9 @@ void SerializerForBackgroundCompilation::VisitCreateObjectLiteral( Handle<ObjectBoilerplateDescription>::cast( iterator->GetConstantForIndexOperand(0, broker()->isolate())); ObjectBoilerplateDescriptionRef description(broker(), constant_properties); + FeedbackSlot slot = iterator->GetSlotOperand(1); + FeedbackSource source(feedback_vector(), slot); + broker()->ProcessFeedbackForArrayOrObjectLiteral(source); environment()->accumulator_hints().Clear(); } @@ -1490,7 +1632,8 @@ void SerializerForBackgroundCompilation::ProcessCreateContext( for (auto x : current_context_hints.constants()) { if (x->IsContext()) { Handle<Context> as_context(Handle<Context>::cast(x)); - accumulator_hints.AddVirtualContext(VirtualContext(1, as_context)); + accumulator_hints.AddVirtualContext(VirtualContext(1, as_context), + zone()); } } @@ -1498,7 +1641,7 @@ void SerializerForBackgroundCompilation::ProcessCreateContext( // it of distance {existing distance} + 1. for (auto x : current_context_hints.virtual_contexts()) { accumulator_hints.AddVirtualContext( - VirtualContext(x.distance + 1, x.context)); + VirtualContext(x.distance + 1, x.context), zone()); } } @@ -1518,7 +1661,7 @@ void SerializerForBackgroundCompilation::VisitCreateClosure( FunctionBlueprint blueprint(shared, Handle<FeedbackVector>::cast(cell_value), environment()->current_context_hints()); - environment()->accumulator_hints().AddFunctionBlueprint(blueprint); + environment()->accumulator_hints().AddFunctionBlueprint(blueprint, zone()); } } @@ -1542,7 +1685,8 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver0( Hints receiver = Hints::SingleConstant( broker()->isolate()->factory()->undefined_value(), zone()); HintsVector parameters({receiver}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1( @@ -1556,7 +1700,8 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver1( Hints receiver = Hints::SingleConstant( broker()->isolate()->factory()->undefined_value(), zone()); HintsVector parameters({receiver, arg0}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2( @@ -1572,7 +1717,8 @@ void SerializerForBackgroundCompilation::VisitCallUndefinedReceiver2( Hints receiver = Hints::SingleConstant( broker()->isolate()->factory()->undefined_value(), zone()); HintsVector parameters({receiver, arg0, arg1}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallAnyReceiver( @@ -1616,7 +1762,8 @@ void SerializerForBackgroundCompilation::VisitCallProperty0( FeedbackSlot slot = iterator->GetSlotOperand(2); HintsVector parameters({receiver}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallProperty1( @@ -1630,7 +1777,8 @@ void SerializerForBackgroundCompilation::VisitCallProperty1( FeedbackSlot slot = iterator->GetSlotOperand(3); HintsVector parameters({receiver, arg0}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallProperty2( @@ -1646,7 +1794,8 @@ void SerializerForBackgroundCompilation::VisitCallProperty2( FeedbackSlot slot = iterator->GetSlotOperand(4); HintsVector parameters({receiver, arg0, arg1}, zone()); - ProcessCallOrConstruct(callee, base::nullopt, parameters, slot); + ProcessCallOrConstruct(callee, base::nullopt, parameters, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitCallWithSpread( @@ -1657,7 +1806,7 @@ void SerializerForBackgroundCompilation::VisitCallWithSpread( int reg_count = static_cast<int>(iterator->GetRegisterCountOperand(2)); FeedbackSlot slot = iterator->GetSlotOperand(3); ProcessCallVarArgs(ConvertReceiverMode::kAny, callee, first_reg, reg_count, - slot, true); + slot, kMissingArgumentsAreUnknown); } void SerializerForBackgroundCompilation::VisitCallJSRuntime( @@ -1677,61 +1826,45 @@ void SerializerForBackgroundCompilation::VisitCallJSRuntime( Hints SerializerForBackgroundCompilation::RunChildSerializer( CompilationSubject function, base::Optional<Hints> new_target, - const HintsVector& arguments, bool with_spread) { - if (with_spread) { - DCHECK_LT(0, arguments.size()); - // Pad the missing arguments in case we were called with spread operator. - // Drop the last actually passed argument, which contains the spread. - // We don't know what the spread element produces. Therefore we pretend - // that the function is called with the maximal number of parameters and - // that we have no information about the parameters that were not - // explicitly provided. - HintsVector padded = arguments; - padded.pop_back(); // Remove the spread element. - // Fill the rest with empty hints. - padded.resize( - function.blueprint().shared()->GetBytecodeArray().parameter_count(), - Hints(zone())); - return RunChildSerializer(function, new_target, padded, false); - } - + const HintsVector& arguments, MissingArgumentsPolicy padding) { SerializerForBackgroundCompilation child_serializer( - broker(), dependencies(), zone(), function, new_target, arguments, - flags()); - return child_serializer.Run(); -} - -bool SerializerForBackgroundCompilation::ProcessSFIForCallOrConstruct( - Handle<SharedFunctionInfo> shared, const HintsVector& arguments, - SpeculationMode speculation_mode) { + zone_scope_.zone_stats(), broker(), dependencies(), function, new_target, + arguments, padding, flags()); + // The Hints returned by the call to Run are allocated in the zone + // created by the child serializer. Adding those hints to a hints + // object created in our zone will preserve the information. + Hints hints; + hints.AddFromChildSerializer(child_serializer.Run(), zone()); + return hints; +} + +void SerializerForBackgroundCompilation::ProcessSFIForCallOrConstruct( + Callee const& callee, base::Optional<Hints> new_target, + const HintsVector& arguments, SpeculationMode speculation_mode, + MissingArgumentsPolicy padding) { + Handle<SharedFunctionInfo> shared = callee.shared(broker()->isolate()); if (shared->IsApiFunction()) { ProcessApiCall(shared, arguments); DCHECK(!shared->IsInlineable()); } else if (shared->HasBuiltinId()) { - ProcessBuiltinCall(shared, arguments, speculation_mode); + ProcessBuiltinCall(shared, new_target, arguments, speculation_mode, + padding); DCHECK(!shared->IsInlineable()); + } else if (shared->IsInlineable() && callee.HasFeedbackVector()) { + CompilationSubject subject = + callee.ToCompilationSubject(broker()->isolate(), zone()); + environment()->accumulator_hints().Add( + RunChildSerializer(subject, new_target, arguments, padding), zone()); } - return shared->IsInlineable(); -} - -bool SerializerForBackgroundCompilation::ProcessCalleeForCallOrConstruct( - Handle<JSFunction> function, const HintsVector& arguments, - SpeculationMode speculation_mode) { - JSFunctionRef(broker(), function).Serialize(); - - Handle<SharedFunctionInfo> shared(function->shared(), broker()->isolate()); - - return ProcessSFIForCallOrConstruct(shared, arguments, speculation_mode) && - function->has_feedback_vector(); } namespace { -// Returns the innermost bound target, if it's a JSFunction and inserts -// all bound arguments and {original_arguments} into {expanded_arguments} -// in the appropriate order. -MaybeHandle<JSFunction> UnrollBoundFunction( - JSBoundFunctionRef const& bound_function, JSHeapBroker* broker, - const HintsVector& original_arguments, HintsVector* expanded_arguments) { +// Returns the innermost bound target and inserts all bound arguments and +// {original_arguments} into {expanded_arguments} in the appropriate order. +JSReceiverRef UnrollBoundFunction(JSBoundFunctionRef const& bound_function, + JSHeapBroker* broker, + const HintsVector& original_arguments, + HintsVector* expanded_arguments) { DCHECK(expanded_arguments->empty()); JSReceiverRef target = bound_function.AsJSReceiver(); @@ -1750,8 +1883,6 @@ MaybeHandle<JSFunction> UnrollBoundFunction( reversed_bound_arguments.push_back(arg); } - if (!target.IsJSFunction()) return MaybeHandle<JSFunction>(); - expanded_arguments->insert(expanded_arguments->end(), reversed_bound_arguments.rbegin(), reversed_bound_arguments.rend()); @@ -1759,13 +1890,38 @@ MaybeHandle<JSFunction> UnrollBoundFunction( original_arguments.begin(), original_arguments.end()); - return target.AsJSFunction().object(); + return target; } } // namespace +void SerializerForBackgroundCompilation::ProcessCalleeForCallOrConstruct( + Handle<Object> callee, base::Optional<Hints> new_target, + const HintsVector& arguments, SpeculationMode speculation_mode, + MissingArgumentsPolicy padding) { + const HintsVector* actual_arguments = &arguments; + HintsVector expanded_arguments(zone()); + if (callee->IsJSBoundFunction()) { + JSBoundFunctionRef bound_function(broker(), + Handle<JSBoundFunction>::cast(callee)); + bound_function.Serialize(); + callee = UnrollBoundFunction(bound_function, broker(), arguments, + &expanded_arguments) + .object(); + actual_arguments = &expanded_arguments; + } + if (!callee->IsJSFunction()) return; + + JSFunctionRef function(broker(), Handle<JSFunction>::cast(callee)); + function.Serialize(); + Callee new_callee(function.object()); + ProcessSFIForCallOrConstruct(new_callee, new_target, *actual_arguments, + speculation_mode, padding); +} + void SerializerForBackgroundCompilation::ProcessCallOrConstruct( Hints callee, base::Optional<Hints> new_target, - const HintsVector& arguments, FeedbackSlot slot, bool with_spread) { + const HintsVector& arguments, FeedbackSlot slot, + MissingArgumentsPolicy padding) { SpeculationMode speculation_mode = SpeculationMode::kDisallowSpeculation; if (!slot.IsInvalid()) { FeedbackSource source(feedback_vector(), slot); @@ -1782,11 +1938,11 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct( // site, and it may make sense to add the Array JSFunction constant. if (new_target.has_value()) { // Construct; feedback is new_target, which often is also the callee. - new_target->AddConstant(target->object()); - callee.AddConstant(target->object()); + new_target->AddConstant(target->object(), zone()); + callee.AddConstant(target->object(), zone()); } else { // Call; target is callee. - callee.AddConstant(target->object()); + callee.AddConstant(target->object(), zone()); } } } @@ -1795,50 +1951,22 @@ void SerializerForBackgroundCompilation::ProcessCallOrConstruct( environment()->accumulator_hints().Clear(); // For JSCallReducer::ReduceJSCall and JSCallReducer::ReduceJSConstruct. - for (auto hint : callee.constants()) { - const HintsVector* actual_arguments = &arguments; - Handle<JSFunction> function; - HintsVector expanded_arguments(zone()); - if (hint->IsJSBoundFunction()) { - JSBoundFunctionRef bound_function(broker(), - Handle<JSBoundFunction>::cast(hint)); - bound_function.Serialize(); - - MaybeHandle<JSFunction> maybe_function = UnrollBoundFunction( - bound_function, broker(), arguments, &expanded_arguments); - if (maybe_function.is_null()) continue; - function = maybe_function.ToHandleChecked(); - actual_arguments = &expanded_arguments; - } else if (hint->IsJSFunction()) { - function = Handle<JSFunction>::cast(hint); - } else { - continue; - } - - if (ProcessCalleeForCallOrConstruct(function, *actual_arguments, - speculation_mode)) { - environment()->accumulator_hints().Add(RunChildSerializer( - CompilationSubject(function, broker()->isolate(), zone()), new_target, - *actual_arguments, with_spread)); - } + for (auto constant : callee.constants()) { + ProcessCalleeForCallOrConstruct(constant, new_target, arguments, + speculation_mode, padding); } // For JSCallReducer::ReduceJSCall and JSCallReducer::ReduceJSConstruct. for (auto hint : callee.function_blueprints()) { - Handle<SharedFunctionInfo> shared = hint.shared(); - if (!ProcessSFIForCallOrConstruct(shared, arguments, speculation_mode)) { - continue; - } - - environment()->accumulator_hints().Add(RunChildSerializer( - CompilationSubject(hint), new_target, arguments, with_spread)); + ProcessSFIForCallOrConstruct(Callee(hint), new_target, arguments, + speculation_mode, padding); } } void SerializerForBackgroundCompilation::ProcessCallVarArgs( ConvertReceiverMode receiver_mode, Hints const& callee, interpreter::Register first_reg, int reg_count, FeedbackSlot slot, - bool with_spread) { + MissingArgumentsPolicy padding) { HintsVector arguments(zone()); // The receiver is either given in the first register or it is implicitly // the {undefined} value. @@ -1848,7 +1976,7 @@ void SerializerForBackgroundCompilation::ProcessCallVarArgs( } environment()->ExportRegisterHints(first_reg, reg_count, &arguments); - ProcessCallOrConstruct(callee, base::nullopt, arguments, slot); + ProcessCallOrConstruct(callee, base::nullopt, arguments, slot, padding); } void SerializerForBackgroundCompilation::ProcessApiCall( @@ -1866,17 +1994,17 @@ void SerializerForBackgroundCompilation::ProcessApiCall( FunctionTemplateInfoRef target_template_info( broker(), handle(target->function_data(), broker()->isolate())); if (!target_template_info.has_call_code()) return; - target_template_info.SerializeCallCode(); SharedFunctionInfoRef target_ref(broker(), target); target_ref.SerializeFunctionTemplateInfo(); if (target_template_info.accept_any_receiver() && - target_template_info.is_signature_undefined()) + target_template_info.is_signature_undefined()) { return; + } - CHECK_GE(arguments.size(), 1); + if (arguments.empty()) return; Hints const& receiver_hints = arguments[0]; for (auto hint : receiver_hints.constants()) { if (hint->IsUndefined()) { @@ -1920,8 +2048,9 @@ void SerializerForBackgroundCompilation::ProcessHintsForObjectCreate( } void SerializerForBackgroundCompilation::ProcessBuiltinCall( - Handle<SharedFunctionInfo> target, const HintsVector& arguments, - SpeculationMode speculation_mode) { + Handle<SharedFunctionInfo> target, base::Optional<Hints> new_target, + const HintsVector& arguments, SpeculationMode speculation_mode, + MissingArgumentsPolicy padding) { DCHECK(target->HasBuiltinId()); const int builtin_id = target->builtin_id(); const char* name = Builtins::name(builtin_id); @@ -1963,20 +2092,31 @@ void SerializerForBackgroundCompilation::ProcessBuiltinCall( case Builtins::kPromiseResolveTrampoline: // For JSCallReducer::ReducePromiseInternalResolve and // JSNativeContextSpecialization::ReduceJSResolvePromise. - if (arguments.size() >= 2) { - Hints const& resolution_hints = arguments[1]; + if (arguments.size() >= 1) { + Hints const& resolution_hints = + arguments.size() >= 2 + ? arguments[1] + : Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), + zone()); ProcessHintsForPromiseResolve(resolution_hints); } break; case Builtins::kPromiseInternalResolve: // For JSCallReducer::ReducePromiseInternalResolve and // JSNativeContextSpecialization::ReduceJSResolvePromise. - if (arguments.size() >= 3) { - Hints const& resolution_hints = arguments[2]; + if (arguments.size() >= 2) { + Hints const& resolution_hints = + arguments.size() >= 3 + ? arguments[2] + : Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), + zone()); ProcessHintsForPromiseResolve(resolution_hints); } break; case Builtins::kRegExpPrototypeTest: + case Builtins::kRegExpPrototypeTestFast: // For JSCallReducer::ReduceRegExpPrototypeTest. if (arguments.size() >= 1 && speculation_mode != SpeculationMode::kDisallowSpeculation) { @@ -1990,35 +2130,105 @@ void SerializerForBackgroundCompilation::ProcessBuiltinCall( case Builtins::kArrayPrototypeFind: case Builtins::kArrayPrototypeFindIndex: case Builtins::kArrayMap: + case Builtins::kArraySome: + if (arguments.size() >= 2 && + speculation_mode != SpeculationMode::kDisallowSpeculation) { + Hints const& callback = arguments[1]; + // "Call(callbackfn, T, « kValue, k, O »)" + HintsVector new_arguments(zone()); + new_arguments.push_back( + arguments.size() < 3 + ? Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), zone()) + : arguments[2]); // T + new_arguments.push_back(Hints()); // kValue + new_arguments.push_back(Hints()); // k + new_arguments.push_back(arguments[0]); // O + for (auto constant : callback.constants()) { + ProcessCalleeForCallOrConstruct(constant, base::nullopt, + new_arguments, + SpeculationMode::kDisallowSpeculation, + kMissingArgumentsAreUndefined); + } + } + break; case Builtins::kArrayReduce: case Builtins::kArrayReduceRight: - case Builtins::kArraySome: if (arguments.size() >= 2 && speculation_mode != SpeculationMode::kDisallowSpeculation) { - Hints const& callback_hints = arguments[1]; - ProcessHintsForFunctionCall(callback_hints); + Hints const& callback = arguments[1]; + // "Call(callbackfn, undefined, « accumulator, kValue, k, O »)" + HintsVector new_arguments(zone()); + new_arguments.push_back(Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), zone())); + new_arguments.push_back(Hints()); // accumulator + new_arguments.push_back(Hints()); // kValue + new_arguments.push_back(Hints()); // k + new_arguments.push_back(arguments[0]); // O + for (auto constant : callback.constants()) { + ProcessCalleeForCallOrConstruct(constant, base::nullopt, + new_arguments, + SpeculationMode::kDisallowSpeculation, + kMissingArgumentsAreUndefined); + } } break; + // TODO(neis): At least for Array* we should look at blueprints too. + // TODO(neis): Might need something like a FunctionBlueprint but for + // creating bound functions rather than creating closures. case Builtins::kFunctionPrototypeApply: - case Builtins::kFunctionPrototypeCall: + if (arguments.size() >= 1) { + // Drop hints for all arguments except the user-given receiver. + Hints new_receiver = + arguments.size() >= 2 + ? arguments[1] + : Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), + zone()); + HintsVector new_arguments({new_receiver}, zone()); + for (auto constant : arguments[0].constants()) { + ProcessCalleeForCallOrConstruct(constant, base::nullopt, + new_arguments, + SpeculationMode::kDisallowSpeculation, + kMissingArgumentsAreUnknown); + } + } + break; case Builtins::kPromiseConstructor: - // TODO(mslekova): Since the reducer for all these introduce a - // JSCall/JSConstruct that will again get optimized by the JSCallReducer, - // we basically might have to do all the serialization that we do for that - // here as well. The only difference is that the new JSCall/JSConstruct - // has speculation disabled, causing the JSCallReducer to do much less - // work. To account for that, ProcessCallOrConstruct should have a way of - // taking the speculation mode as an argument rather than getting that - // from the feedback. (Also applies to Reflect.apply and - // Reflect.construct.) if (arguments.size() >= 1) { - ProcessHintsForFunctionCall(arguments[0]); + // "Call(executor, undefined, « resolvingFunctions.[[Resolve]], + // resolvingFunctions.[[Reject]] »)" + HintsVector new_arguments( + {Hints::SingleConstant( + broker()->isolate()->factory()->undefined_value(), zone())}, + zone()); + for (auto constant : arguments[0].constants()) { + ProcessCalleeForCallOrConstruct(constant, base::nullopt, + new_arguments, + SpeculationMode::kDisallowSpeculation, + kMissingArgumentsAreUnknown); + } + } + break; + case Builtins::kFunctionPrototypeCall: + if (arguments.size() >= 1) { + HintsVector new_arguments(arguments.begin() + 1, arguments.end(), + zone()); + for (auto constant : arguments[0].constants()) { + ProcessCalleeForCallOrConstruct( + constant, base::nullopt, new_arguments, + SpeculationMode::kDisallowSpeculation, padding); + } } break; case Builtins::kReflectApply: case Builtins::kReflectConstruct: if (arguments.size() >= 2) { - ProcessHintsForFunctionCall(arguments[1]); + for (auto constant : arguments[1].constants()) { + if (constant->IsJSFunction()) { + JSFunctionRef(broker(), constant).Serialize(); + } + } } break; case Builtins::kObjectPrototypeIsPrototypeOf: @@ -2181,13 +2391,6 @@ void SerializerForBackgroundCompilation::ProcessHintsForRegExpTest( } } -void SerializerForBackgroundCompilation::ProcessHintsForFunctionCall( - Hints const& target_hints) { - for (auto constant : target_hints.constants()) { - if (constant->IsJSFunction()) JSFunctionRef(broker(), constant).Serialize(); - } -} - namespace { void ProcessMapForFunctionBind(MapRef map) { map.SerializePrototype(); @@ -2195,8 +2398,9 @@ void ProcessMapForFunctionBind(MapRef map) { JSFunction::kNameDescriptorIndex) + 1; if (map.NumberOfOwnDescriptors() >= min_nof_descriptors) { - map.SerializeOwnDescriptor(JSFunction::kLengthDescriptorIndex); - map.SerializeOwnDescriptor(JSFunction::kNameDescriptorIndex); + map.SerializeOwnDescriptor( + InternalIndex(JSFunction::kLengthDescriptorIndex)); + map.SerializeOwnDescriptor(InternalIndex(JSFunction::kNameDescriptorIndex)); } } } // namespace @@ -2261,7 +2465,8 @@ void SerializerForBackgroundCompilation::ProcessJump( void SerializerForBackgroundCompilation::VisitReturn( BytecodeArrayIterator* iterator) { - environment()->return_value_hints().Add(environment()->accumulator_hints()); + environment()->return_value_hints().Add(environment()->accumulator_hints(), + zone()); environment()->ClearEphemeralHints(); } @@ -2301,7 +2506,8 @@ void SerializerForBackgroundCompilation::VisitConstruct( HintsVector arguments(zone()); environment()->ExportRegisterHints(first_reg, reg_count, &arguments); - ProcessCallOrConstruct(callee, new_target, arguments, slot); + ProcessCallOrConstruct(callee, new_target, arguments, slot, + kMissingArgumentsAreUndefined); } void SerializerForBackgroundCompilation::VisitConstructWithSpread( @@ -2315,8 +2521,10 @@ void SerializerForBackgroundCompilation::VisitConstructWithSpread( HintsVector arguments(zone()); environment()->ExportRegisterHints(first_reg, reg_count, &arguments); - - ProcessCallOrConstruct(callee, new_target, arguments, slot, true); + DCHECK(!arguments.empty()); + arguments.pop_back(); // Remove the spread element. + ProcessCallOrConstruct(callee, new_target, arguments, slot, + kMissingArgumentsAreUnknown); } void SerializerForBackgroundCompilation::ProcessGlobalAccess(FeedbackSlot slot, @@ -2333,7 +2541,7 @@ void SerializerForBackgroundCompilation::ProcessGlobalAccess(FeedbackSlot slot, base::Optional<ObjectRef> value = feedback.AsGlobalAccess().GetConstantHint(); if (value.has_value()) { - environment()->accumulator_hints().AddConstant(value->object()); + environment()->accumulator_hints().AddConstant(value->object(), zone()); } } else { DCHECK(feedback.IsInsufficient()); @@ -2480,9 +2688,16 @@ SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( receiver_map.SerializeRootMap(); // For JSNativeContextSpecialization::ReduceNamedAccess. - if (receiver_map.IsMapOfTargetGlobalProxy()) { - broker()->target_native_context().global_proxy_object().GetPropertyCell( + JSGlobalProxyRef global_proxy = + broker()->target_native_context().global_proxy_object(); + JSGlobalObjectRef global_object = + broker()->target_native_context().global_object(); + if (receiver_map.equals(global_proxy.map())) { + base::Optional<PropertyCellRef> cell = global_object.GetPropertyCell( name, SerializationPolicy::kSerializeIfNeeded); + if (access_mode == AccessMode::kLoad && cell.has_value()) { + new_accumulator_hints->AddConstant(cell->value().object(), zone()); + } } PropertyAccessInfo access_info = broker()->GetPropertyAccessInfo( @@ -2515,6 +2730,10 @@ SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( FunctionTemplateInfoRef fti(broker(), access_info.constant()); if (fti.has_call_code()) fti.SerializeCallCode(); } + } else if (access_info.IsModuleExport()) { + // For JSNativeContextSpecialization::BuildPropertyLoad + DCHECK(!access_info.constant().is_null()); + CellRef(broker(), access_info.constant()); } // For PropertyAccessBuilder::TryBuildLoadConstantDataField @@ -2535,7 +2754,7 @@ SerializerForBackgroundCompilation::ProcessMapForNamedPropertyAccess( access_info.field_representation(), access_info.field_index(), SerializationPolicy::kSerializeIfNeeded)); if (constant.has_value()) { - new_accumulator_hints->AddConstant(constant->object()); + new_accumulator_hints->AddConstant(constant->object(), zone()); } } } @@ -2565,7 +2784,7 @@ void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess( return; } - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; switch (feedback.kind()) { case ProcessedFeedback::kElementAccess: ProcessElementAccess(receiver, key, feedback.AsElementAccess(), @@ -2583,14 +2802,14 @@ void SerializerForBackgroundCompilation::ProcessKeyedPropertyAccess( if (access_mode == AccessMode::kLoad) { environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } else { DCHECK(new_accumulator_hints.IsEmpty()); } } void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( - Hints receiver, NameRef const& name, FeedbackSlot slot, + Hints const& receiver, NameRef const& name, FeedbackSlot slot, AccessMode access_mode) { if (slot.IsInvalid() || feedback_vector().is_null()) return; FeedbackSource source(feedback_vector(), slot); @@ -2598,12 +2817,13 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( broker()->ProcessFeedbackForPropertyAccess(source, access_mode, name); if (BailoutOnUninitialized(feedback)) return; - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; switch (feedback.kind()) { case ProcessedFeedback::kNamedAccess: DCHECK(name.equals(feedback.AsNamedAccess().name())); ProcessNamedAccess(receiver, feedback.AsNamedAccess(), access_mode, &new_accumulator_hints); + // TODO(neis): Propagate feedback maps to receiver hints. break; case ProcessedFeedback::kInsufficient: break; @@ -2613,7 +2833,7 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( if (access_mode == AccessMode::kLoad) { environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } else { DCHECK(new_accumulator_hints.IsEmpty()); } @@ -2622,7 +2842,7 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( void SerializerForBackgroundCompilation::ProcessNamedAccess( Hints receiver, NamedAccessFeedback const& feedback, AccessMode access_mode, Hints* new_accumulator_hints) { - for (Handle<Map> map : feedback.AsNamedAccess().maps()) { + for (Handle<Map> map : feedback.maps()) { MapRef map_ref(broker(), map); ProcessMapForNamedPropertyAccess(map_ref, feedback.name(), access_mode, base::nullopt, new_accumulator_hints); @@ -2635,8 +2855,6 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess( base::nullopt, new_accumulator_hints); } - JSGlobalProxyRef global_proxy = - broker()->target_native_context().global_proxy_object(); for (Handle<Object> hint : receiver.constants()) { ObjectRef object(broker(), hint); if (access_mode == AccessMode::kLoad && object.IsJSObject()) { @@ -2645,13 +2863,6 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess( object.AsJSObject(), new_accumulator_hints); } - // For JSNativeContextSpecialization::ReduceNamedAccessFromNexus. - if (object.equals(global_proxy)) { - // TODO(neis): Record accumulator hint? Also for string.length and maybe - // more. - global_proxy.GetPropertyCell(feedback.name(), - SerializationPolicy::kSerializeIfNeeded); - } // For JSNativeContextSpecialization::ReduceJSLoadNamed. if (access_mode == AccessMode::kLoad && object.IsJSFunction() && feedback.name().equals(ObjectRef( @@ -2659,9 +2870,12 @@ void SerializerForBackgroundCompilation::ProcessNamedAccess( JSFunctionRef function = object.AsJSFunction(); function.Serialize(); if (new_accumulator_hints != nullptr && function.has_prototype()) { - new_accumulator_hints->AddConstant(function.prototype().object()); + new_accumulator_hints->AddConstant(function.prototype().object(), + zone()); } } + // TODO(neis): Also record accumulator hint for string.length and maybe + // more? } } @@ -2841,7 +3055,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf( environment()->register_hints(iterator->GetRegisterOperand(0)); Hints rhs = environment()->accumulator_hints(); FeedbackSlot slot = iterator->GetSlotOperand(1); - Hints new_accumulator_hints(zone()); + Hints new_accumulator_hints; if (slot.IsInvalid() || feedback_vector().is_null()) return; FeedbackSource source(feedback_vector(), slot); @@ -2853,7 +3067,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf( InstanceOfFeedback const& rhs_feedback = feedback.AsInstanceOf(); if (rhs_feedback.value().has_value()) { Handle<JSObject> constructor = rhs_feedback.value()->object(); - rhs.AddConstant(constructor); + rhs.AddConstant(constructor, zone()); } } @@ -2865,7 +3079,7 @@ void SerializerForBackgroundCompilation::VisitTestInstanceOf( if (walk_prototypes) ProcessHintsForHasInPrototypeChain(lhs); environment()->accumulator_hints().Clear(); - environment()->accumulator_hints().Add(new_accumulator_hints); + environment()->accumulator_hints().Add(new_accumulator_hints, zone()); } void SerializerForBackgroundCompilation::VisitToNumeric( diff --git a/deps/v8/src/compiler/serializer-for-background-compilation.h b/deps/v8/src/compiler/serializer-for-background-compilation.h index 881ed61a555231..8f7883eeba7397 100644 --- a/deps/v8/src/compiler/serializer-for-background-compilation.h +++ b/deps/v8/src/compiler/serializer-for-background-compilation.h @@ -17,6 +17,7 @@ namespace compiler { class CompilationDependencies; class JSHeapBroker; +class ZoneStats; enum class SerializerForBackgroundCompilationFlag : uint8_t { kBailoutOnUninitialized = 1 << 0, @@ -27,9 +28,9 @@ using SerializerForBackgroundCompilationFlags = base::Flags<SerializerForBackgroundCompilationFlag>; void RunSerializerForBackgroundCompilation( - JSHeapBroker* broker, CompilationDependencies* dependencies, Zone* zone, - Handle<JSFunction> closure, SerializerForBackgroundCompilationFlags flags, - BailoutId osr_offset); + ZoneStats* zone_stats, JSHeapBroker* broker, + CompilationDependencies* dependencies, Handle<JSFunction> closure, + SerializerForBackgroundCompilationFlags flags, BailoutId osr_offset); } // namespace compiler } // namespace internal diff --git a/deps/v8/src/compiler/simd-scalar-lowering.cc b/deps/v8/src/compiler/simd-scalar-lowering.cc index 783f3bcc113f19..2781cc248f08f2 100644 --- a/deps/v8/src/compiler/simd-scalar-lowering.cc +++ b/deps/v8/src/compiler/simd-scalar-lowering.cc @@ -132,6 +132,7 @@ void SimdScalarLowering::LowerGraph() { V(F32x4UConvertI32x4) \ V(F32x4Abs) \ V(F32x4Neg) \ + V(F32x4Sqrt) \ V(F32x4RecipApprox) \ V(F32x4RecipSqrtApprox) \ V(F32x4Add) \ @@ -210,6 +211,7 @@ void SimdScalarLowering::LowerGraph() { V(I8x16LeS) \ V(I8x16LtU) \ V(I8x16LeU) \ + V(S8x16Swizzle) \ V(S8x16Shuffle) MachineType SimdScalarLowering::MachineTypeFrom(SimdType simdType) { @@ -940,6 +942,28 @@ void SimdScalarLowering::LowerNode(Node* node) { } break; } + case IrOpcode::kSimd128ReverseBytes: { + DCHECK_EQ(1, node->InputCount()); + bool is_float = ReplacementType(node->InputAt(0)) == SimdType::kFloat32x4; + replacements_[node->id()].type = + is_float ? SimdType::kFloat32x4 : SimdType::kInt32x4; + Node** rep = GetReplacementsWithType( + node->InputAt(0), + is_float ? SimdType::kFloat32x4 : SimdType::kInt32x4); + Node* rep_node[kNumLanes32]; + for (int i = 0; i < kNumLanes32; ++i) { + Node* temp = is_float ? graph()->NewNode( + machine()->BitcastFloat32ToInt32(), rep[i]) + : rep[i]; + temp = graph()->NewNode(machine()->Word32ReverseBytes(), temp); + rep_node[kNumLanes32 - 1 - i] = + is_float + ? graph()->NewNode(machine()->BitcastInt32ToFloat32(), temp) + : temp; + } + ReplaceNode(node, rep_node, kNumLanes32); + break; + } case IrOpcode::kLoad: case IrOpcode::kUnalignedLoad: case IrOpcode::kProtectedLoad: { @@ -1219,6 +1243,7 @@ void SimdScalarLowering::LowerNode(Node* node) { } F32X4_UNOP_CASE(Abs) F32X4_UNOP_CASE(Neg) + F32X4_UNOP_CASE(Sqrt) #undef F32X4_UNOP_CASE case IrOpcode::kF32x4RecipApprox: case IrOpcode::kF32x4RecipSqrtApprox: { @@ -1368,6 +1393,45 @@ void SimdScalarLowering::LowerNode(Node* node) { ReplaceNode(node, rep_node, num_lanes); break; } + case IrOpcode::kS8x16Swizzle: { + DCHECK_EQ(2, node->InputCount()); + Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); + Node** indices = GetReplacementsWithType(node->InputAt(1), rep_type); + Node** rep_nodes = zone()->NewArray<Node*>(num_lanes); + Node* stack_slot = graph()->NewNode( + machine()->StackSlot(MachineRepresentation::kSimd128)); + + // Push all num_lanes values into stack slot. + const Operator* store_op = machine()->Store( + StoreRepresentation(MachineRepresentation::kWord8, kNoWriteBarrier)); + Node* effect_input = graph()->start(); + for (int i = num_lanes - 1; i >= 0; i--) { + // We want all the stores to happen first before any of the loads + // below, so connect them via effect edge from i-1 to i. + Node* store = + graph()->NewNode(store_op, stack_slot, mcgraph_->Int32Constant(i), + rep_left[i], effect_input, graph()->start()); + effect_input = store; + } + + for (int i = num_lanes - 1; i >= 0; i--) { + // Only select lane when index is < num_lanes, otherwise write 0 to + // lane. Use Uint32 to take care of negative indices. + Diamond d(graph(), common(), + graph()->NewNode(machine()->Uint32LessThan(), indices[i], + mcgraph_->Int32Constant(num_lanes))); + + Node* load = + graph()->NewNode(machine()->Load(LoadRepresentation::Uint8()), + stack_slot, indices[i], effect_input, d.if_true); + + rep_nodes[i] = d.Phi(MachineRepresentation::kWord8, load, + mcgraph_->Int32Constant(0)); + } + + ReplaceNode(node, rep_nodes, num_lanes); + break; + } case IrOpcode::kS8x16Shuffle: { DCHECK_EQ(2, node->InputCount()); const uint8_t* shuffle = S8x16ShuffleOf(node->op()); diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc index 1ca7bfe707e3b4..fadc9bf6d99491 100644 --- a/deps/v8/src/compiler/simplified-lowering.cc +++ b/deps/v8/src/compiler/simplified-lowering.cc @@ -1197,7 +1197,7 @@ class RepresentationSelector { // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize // truncated BigInts. if (TypeOf(input).Is(Type::BigInt())) { - ProcessInput(node, i, UseInfo::AnyTagged()); + ConvertInput(node, i, UseInfo::AnyTagged()); } (*types)[i] = @@ -1220,11 +1220,22 @@ class RepresentationSelector { // Accumulator is a special flower - we need to remember its type in // a singleton typed-state-values node (as if it was a singleton // state-values node). + Node* accumulator = node->InputAt(2); if (propagate()) { - EnqueueInput(node, 2, UseInfo::Any()); + // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize + // truncated BigInts. + if (TypeOf(accumulator).Is(Type::BigInt())) { + EnqueueInput(node, 2, UseInfo::AnyTagged()); + } else { + EnqueueInput(node, 2, UseInfo::Any()); + } } else if (lower()) { + // TODO(nicohartmann): Remove, once the deoptimizer can rematerialize + // truncated BigInts. + if (TypeOf(accumulator).Is(Type::BigInt())) { + ConvertInput(node, 2, UseInfo::AnyTagged()); + } Zone* zone = jsgraph_->zone(); - Node* accumulator = node->InputAt(2); if (accumulator == jsgraph_->OptimizedOutConstant()) { node->ReplaceInput(2, jsgraph_->SingleDeadTypedStateValues()); } else { @@ -1237,7 +1248,7 @@ class RepresentationSelector { node->ReplaceInput( 2, jsgraph_->graph()->NewNode(jsgraph_->common()->TypedStateValues( types, SparseInputMask::Dense()), - accumulator)); + node->InputAt(2))); } } @@ -2667,7 +2678,11 @@ class RepresentationSelector { case IrOpcode::kReferenceEqual: { VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); if (lower()) { - NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); + if (COMPRESS_POINTERS_BOOL) { + NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); + } else { + NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); + } } return; } @@ -2894,6 +2909,18 @@ class RepresentationSelector { SetOutput(node, MachineRepresentation::kTaggedPointer); return; } + case IrOpcode::kLoadMessage: { + if (truncation.IsUnused()) return VisitUnused(node); + VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTagged); + return; + } + case IrOpcode::kStoreMessage: { + ProcessInput(node, 0, UseInfo::Word()); + ProcessInput(node, 1, UseInfo::AnyTagged()); + ProcessRemainingInputs(node, 2); + SetOutput(node, MachineRepresentation::kNone); + return; + } case IrOpcode::kLoadFieldByIndex: { if (truncation.IsUnused()) return VisitUnused(node); VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(), @@ -2945,6 +2972,11 @@ class RepresentationSelector { access.machine_type.representation()); return; } + case IrOpcode::kLoadStackArgument: { + if (truncation.IsUnused()) return VisitUnused(node); + VisitBinop(node, UseInfo::Word(), MachineRepresentation::kTagged); + return; + } case IrOpcode::kStoreElement: { ElementAccess access = ElementAccessOf(node->op()); Node* value_node = node->InputAt(2); diff --git a/deps/v8/src/compiler/simplified-operator-reducer.cc b/deps/v8/src/compiler/simplified-operator-reducer.cc index 885a86286ebb83..0f293d2b38b6a8 100644 --- a/deps/v8/src/compiler/simplified-operator-reducer.cc +++ b/deps/v8/src/compiler/simplified-operator-reducer.cc @@ -155,23 +155,6 @@ Reduction SimplifiedOperatorReducer::Reduce(Node* node) { Node* new_node = graph()->NewNode( simplified()->ChangeInt31ToCompressedSigned(), m.InputAt(0)); return Replace(new_node); - } else if (m.IsCheckedInt32ToTaggedSigned()) { - // Create a new checked node that outputs CompressedSigned values, with - // an explicit decompression after it. - Node* new_checked = graph()->CloneNode(m.node()); - NodeProperties::ChangeOp( - new_checked, simplified()->CheckedInt32ToCompressedSigned( - CheckParametersOf(m.node()->op()).feedback())); - Node* new_decompression = graph()->NewNode( - machine()->ChangeCompressedSignedToTaggedSigned(), new_checked); - - // For all uses of the old checked node, instead insert the new "checked - // + decompression". Also, update control and effect. - ReplaceWithValue(m.node(), new_decompression, new_checked, new_checked); - - // In the current node, we can skip the decompression since we are going - // to have a Decompression + Compression combo. - return Replace(new_checked); } break; } diff --git a/deps/v8/src/compiler/simplified-operator.cc b/deps/v8/src/compiler/simplified-operator.cc index 6b86a95e01b2db..63d24274ece34f 100644 --- a/deps/v8/src/compiler/simplified-operator.cc +++ b/deps/v8/src/compiler/simplified-operator.cc @@ -1149,6 +1149,17 @@ struct SimplifiedOperatorGlobalCache final { }; LoadFieldByIndexOperator kLoadFieldByIndex; + struct LoadStackArgumentOperator final : public Operator { + LoadStackArgumentOperator() + : Operator( // -- + IrOpcode::kLoadStackArgument, // opcode + Operator::kNoDeopt | Operator::kNoThrow | + Operator::kNoWrite, // flags + "LoadStackArgument", // name + 2, 1, 1, 1, 1, 0) {} // counts + }; + LoadStackArgumentOperator kLoadStackArgument; + #define SPECULATIVE_NUMBER_BINOP(Name) \ template <NumberOperationHint kHint> \ struct Name##Operator final : public Operator1<NumberOperationHint> { \ @@ -1754,6 +1765,24 @@ SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) ACCESS_OP_LIST(ACCESS) #undef ACCESS +const Operator* SimplifiedOperatorBuilder::LoadMessage() { + return new (zone()) + Operator(IrOpcode::kLoadMessage, + Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, + "LoadMessage", 1, 1, 1, 1, 1, 0); +} + +const Operator* SimplifiedOperatorBuilder::StoreMessage() { + return new (zone()) + Operator(IrOpcode::kStoreMessage, + Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoRead, + "StoreMessage", 2, 1, 1, 0, 1, 0); +} + +const Operator* SimplifiedOperatorBuilder::LoadStackArgument() { + return &cache_.kLoadStackArgument; +} + const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement( Handle<Map> double_map, Handle<Map> fast_map) { TransitionAndStoreElementParameters parameters(double_map, fast_map); diff --git a/deps/v8/src/compiler/simplified-operator.h b/deps/v8/src/compiler/simplified-operator.h index 58e9bfdffbbf17..a1438cdce0a81f 100644 --- a/deps/v8/src/compiler/simplified-operator.h +++ b/deps/v8/src/compiler/simplified-operator.h @@ -876,6 +876,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final Type type, AllocationType allocation = AllocationType::kYoung, AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse); + const Operator* LoadMessage(); + const Operator* StoreMessage(); + const Operator* LoadFieldByIndex(); const Operator* LoadField(FieldAccess const&); const Operator* StoreField(FieldAccess const&); @@ -883,6 +886,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final // load-element [base + index] const Operator* LoadElement(ElementAccess const&); + // load-stack-argument [base + index] + const Operator* LoadStackArgument(); + // store-element [base + index], value const Operator* StoreElement(ElementAccess const&); diff --git a/deps/v8/src/compiler/store-store-elimination.cc b/deps/v8/src/compiler/store-store-elimination.cc index bd53fb895fadc5..08accd61c5ce7d 100644 --- a/deps/v8/src/compiler/store-store-elimination.cc +++ b/deps/v8/src/compiler/store-store-elimination.cc @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <iterator> - #include "src/compiler/store-store-elimination.h" #include "src/codegen/tick-counter.h" #include "src/compiler/all-nodes.h" +#include "src/compiler/common-operator.h" #include "src/compiler/js-graph.h" #include "src/compiler/node-properties.h" +#include "src/compiler/persistent-map.h" +#include "src/compiler/simplified-operator.h" +#include "src/zone/zone-containers.h" namespace v8 { namespace internal { @@ -41,7 +43,199 @@ namespace compiler { #define DCHECK_EXTRA(condition, fmt, ...) ((void)0) #endif -void StoreStoreElimination::RedundantStoreFinder::Find() { +namespace { + +using StoreOffset = uint32_t; + +struct UnobservableStore { + NodeId id_; + StoreOffset offset_; + + bool operator==(const UnobservableStore other) const { + return (id_ == other.id_) && (offset_ == other.offset_); + } + + bool operator<(const UnobservableStore other) const { + return (id_ < other.id_) || (id_ == other.id_ && offset_ < other.offset_); + } +}; + +size_t hash_value(const UnobservableStore& p) { + return base::hash_combine(p.id_, p.offset_); +} + +// Instances of UnobservablesSet are immutable. They represent either a set of +// UnobservableStores, or the "unvisited empty set". +// +// We apply some sharing to save memory. The class UnobservablesSet is only a +// pointer wide, and a copy does not use any heap (or temp_zone) memory. Most +// changes to an UnobservablesSet might allocate in the temp_zone. +// +// The size of an instance should be the size of a pointer, plus additional +// space in the zone in the case of non-unvisited UnobservablesSets. Copying +// an UnobservablesSet allocates no memory. +class UnobservablesSet final { + private: + using KeyT = UnobservableStore; + using ValueT = bool; // Emulates set semantics in the map. + + // The PersistentMap uses a special value to signify 'not present'. We use + // a boolean value to emulate set semantics. + static constexpr ValueT kNotPresent = false; + static constexpr ValueT kPresent = true; + + public: + using SetT = PersistentMap<KeyT, ValueT>; + + // Creates a new UnobservablesSet, with the null set. + static UnobservablesSet Unvisited() { return UnobservablesSet(); } + + // Create a new empty UnobservablesSet. This allocates in the zone, and + // can probably be optimized to use a global singleton. + static UnobservablesSet VisitedEmpty(Zone* zone); + UnobservablesSet(const UnobservablesSet& other) V8_NOEXCEPT = default; + + // Computes the intersection of two UnobservablesSets. If one of the sets is + // empty, will return empty. + UnobservablesSet Intersect(const UnobservablesSet& other, + const UnobservablesSet& empty, Zone* zone) const; + + // Returns a set that it is the current one, plus the observation obs passed + // as parameter. If said obs it's already in the set, we don't have to + // create a new one. + UnobservablesSet Add(UnobservableStore obs, Zone* zone) const; + + // Returns a set that it is the current one, except for all of the + // observations with offset off. This is done by creating a new set and + // copying all observations with different offsets. + // This can probably be done better if the observations are stored first by + // offset and then by node. + // We are removing all nodes with offset off since different nodes may + // alias one another, and we currently we don't have the means to know if + // two nodes are definitely the same value. + UnobservablesSet RemoveSameOffset(StoreOffset off, Zone* zone) const; + + const SetT* set() const { return set_; } + + bool IsUnvisited() const { return set_ == nullptr; } + bool IsEmpty() const { + return set_ == nullptr || set_->begin() == set_->end(); + } + bool Contains(UnobservableStore obs) const { + return set_ != nullptr && set_->Get(obs) != kNotPresent; + } + + bool operator==(const UnobservablesSet& other) const { + if (IsUnvisited() || other.IsUnvisited()) { + return IsEmpty() && other.IsEmpty(); + } else { + // Both pointers guaranteed not to be nullptrs. + return *set() == *(other.set()); + } + } + + bool operator!=(const UnobservablesSet& other) const { + return !(*this == other); + } + + private: + UnobservablesSet() = default; + explicit UnobservablesSet(const SetT* set) : set_(set) {} + + static SetT* NewSet(Zone* zone) { + return new (zone->New(sizeof(UnobservablesSet::SetT))) + UnobservablesSet::SetT(zone, kNotPresent); + } + + static void SetAdd(SetT* set, const KeyT& key) { set->Set(key, kPresent); } + static void SetErase(SetT* set, const KeyT& key) { + set->Set(key, kNotPresent); + } + + const SetT* set_ = nullptr; +}; + +class RedundantStoreFinder final { + public: + // Note that we Initialize unobservable_ with js_graph->graph->NodeCount() + // amount of empty sets. + RedundantStoreFinder(JSGraph* js_graph, TickCounter* tick_counter, + Zone* temp_zone) + : jsgraph_(js_graph), + tick_counter_(tick_counter), + temp_zone_(temp_zone), + revisit_(temp_zone), + in_revisit_(js_graph->graph()->NodeCount(), temp_zone), + unobservable_(js_graph->graph()->NodeCount(), + UnobservablesSet::Unvisited(), temp_zone), + to_remove_(temp_zone), + unobservables_visited_empty_( + UnobservablesSet::VisitedEmpty(temp_zone)) {} + + // Crawls from the end of the graph to the beginning, with the objective of + // finding redundant stores. + void Find(); + + // This method is used for const correctness to go through the final list of + // redundant stores that are replaced on the graph. + const ZoneSet<Node*>& to_remove_const() { return to_remove_; } + + private: + // Assumption: All effectful nodes are reachable from End via a sequence of + // control, then a sequence of effect edges. + // Visit goes through the control chain, visiting effectful nodes that it + // encounters. + void Visit(Node* node); + + // Marks effect inputs for visiting, if we are able to update this path of + // the graph. + void VisitEffectfulNode(Node* node); + + // Compute the intersection of the UnobservablesSets of all effect uses and + // return it. + // The result UnobservablesSet will never be null. + UnobservablesSet RecomputeUseIntersection(Node* node); + + // Recompute unobservables-set for a node. Will also mark superfluous nodes + // as to be removed. + UnobservablesSet RecomputeSet(Node* node, const UnobservablesSet& uses); + + // Returns true if node's opcode cannot observe StoreFields. + static bool CannotObserveStoreField(Node* node); + + void MarkForRevisit(Node* node); + bool HasBeenVisited(Node* node); + + // To safely cast an offset from a FieldAccess, which has a potentially + // wider range (namely int). + StoreOffset ToOffset(const FieldAccess& access) { + DCHECK_GE(access.offset, 0); + return static_cast<StoreOffset>(access.offset); + } + + JSGraph* jsgraph() const { return jsgraph_; } + Isolate* isolate() { return jsgraph()->isolate(); } + Zone* temp_zone() const { return temp_zone_; } + UnobservablesSet& unobservable_for_id(NodeId id) { + DCHECK_LT(id, unobservable_.size()); + return unobservable_[id]; + } + ZoneSet<Node*>& to_remove() { return to_remove_; } + + JSGraph* const jsgraph_; + TickCounter* const tick_counter_; + Zone* const temp_zone_; + + ZoneStack<Node*> revisit_; + ZoneVector<bool> in_revisit_; + + // Maps node IDs to UnobservableNodeSets. + ZoneVector<UnobservablesSet> unobservable_; + ZoneSet<Node*> to_remove_; + const UnobservablesSet unobservables_visited_empty_; +}; + +void RedundantStoreFinder::Find() { Visit(jsgraph()->graph()->end()); while (!revisit_.empty()) { @@ -65,7 +259,7 @@ void StoreStoreElimination::RedundantStoreFinder::Find() { #endif } -void StoreStoreElimination::RedundantStoreFinder::MarkForRevisit(Node* node) { +void RedundantStoreFinder::MarkForRevisit(Node* node) { DCHECK_LT(node->id(), in_revisit_.size()); if (!in_revisit_[node->id()]) { revisit_.push(node); @@ -73,32 +267,12 @@ void StoreStoreElimination::RedundantStoreFinder::MarkForRevisit(Node* node) { } } -bool StoreStoreElimination::RedundantStoreFinder::HasBeenVisited(Node* node) { +bool RedundantStoreFinder::HasBeenVisited(Node* node) { return !unobservable_for_id(node->id()).IsUnvisited(); } -void StoreStoreElimination::Run(JSGraph* js_graph, TickCounter* tick_counter, - Zone* temp_zone) { - // Find superfluous nodes - RedundantStoreFinder finder(js_graph, tick_counter, temp_zone); - finder.Find(); - - // Remove superfluous nodes - for (Node* node : finder.to_remove_const()) { - if (FLAG_trace_store_elimination) { - PrintF("StoreStoreElimination::Run: Eliminating node #%d:%s\n", - node->id(), node->op()->mnemonic()); - } - Node* previous_effect = NodeProperties::GetEffectInput(node); - NodeProperties::ReplaceUses(node, nullptr, previous_effect, nullptr, - nullptr); - node->Kill(); - } -} - -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::RedundantStoreFinder::RecomputeSet( - Node* node, const StoreStoreElimination::UnobservablesSet& uses) { +UnobservablesSet RedundantStoreFinder::RecomputeSet( + Node* node, const UnobservablesSet& uses) { switch (node->op()->opcode()) { case IrOpcode::kStoreField: { Node* stored_to = node->InputAt(0); @@ -150,8 +324,7 @@ StoreStoreElimination::RedundantStoreFinder::RecomputeSet( UNREACHABLE(); } -bool StoreStoreElimination::RedundantStoreFinder::CannotObserveStoreField( - Node* node) { +bool RedundantStoreFinder::CannotObserveStoreField(Node* node) { IrOpcode::Value opcode = node->opcode(); return opcode == IrOpcode::kLoadElement || opcode == IrOpcode::kLoad || opcode == IrOpcode::kStore || opcode == IrOpcode::kEffectPhi || @@ -159,7 +332,7 @@ bool StoreStoreElimination::RedundantStoreFinder::CannotObserveStoreField( opcode == IrOpcode::kUnsafePointerAdd || opcode == IrOpcode::kRetain; } -void StoreStoreElimination::RedundantStoreFinder::Visit(Node* node) { +void RedundantStoreFinder::Visit(Node* node) { if (!HasBeenVisited(node)) { for (int i = 0; i < node->op()->ControlInputCount(); i++) { Node* control_input = NodeProperties::GetControlInput(node, i); @@ -180,19 +353,15 @@ void StoreStoreElimination::RedundantStoreFinder::Visit(Node* node) { } } -void StoreStoreElimination::RedundantStoreFinder::VisitEffectfulNode( - Node* node) { +void RedundantStoreFinder::VisitEffectfulNode(Node* node) { if (HasBeenVisited(node)) { TRACE("- Revisiting: #%d:%s", node->id(), node->op()->mnemonic()); } - StoreStoreElimination::UnobservablesSet after_set = - RecomputeUseIntersection(node); - StoreStoreElimination::UnobservablesSet before_set = - RecomputeSet(node, after_set); + UnobservablesSet after_set = RecomputeUseIntersection(node); + UnobservablesSet before_set = RecomputeSet(node, after_set); DCHECK(!before_set.IsUnvisited()); - StoreStoreElimination::UnobservablesSet stores_for_node = - unobservable_for_id(node->id()); + UnobservablesSet stores_for_node = unobservable_for_id(node->id()); bool cur_set_changed = stores_for_node.IsUnvisited() || stores_for_node != before_set; if (!cur_set_changed) { @@ -212,9 +381,7 @@ void StoreStoreElimination::RedundantStoreFinder::VisitEffectfulNode( } } -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::RedundantStoreFinder::RecomputeUseIntersection( - Node* node) { +UnobservablesSet RedundantStoreFinder::RecomputeUseIntersection(Node* node) { // There were no effect uses. Break early. if (node->op()->EffectOutputCount() == 0) { IrOpcode::Value opcode = node->opcode(); @@ -236,8 +403,7 @@ StoreStoreElimination::RedundantStoreFinder::RecomputeUseIntersection( // {first} == false indicates that cur_set is the intersection of at least one // thing. bool first = true; - StoreStoreElimination::UnobservablesSet cur_set = - StoreStoreElimination::UnobservablesSet::Unvisited(); // irrelevant + UnobservablesSet cur_set = UnobservablesSet::Unvisited(); // irrelevant for (Edge edge : node->use_edges()) { if (!NodeProperties::IsEffectEdge(edge)) { continue; @@ -245,8 +411,7 @@ StoreStoreElimination::RedundantStoreFinder::RecomputeUseIntersection( // Intersect with the new use node. Node* use = edge.from(); - StoreStoreElimination::UnobservablesSet new_set = - unobservable_for_id(use->id()); + UnobservablesSet new_set = unobservable_for_id(use->id()); if (first) { first = false; cur_set = new_set; @@ -268,72 +433,70 @@ StoreStoreElimination::RedundantStoreFinder::RecomputeUseIntersection( return cur_set; } -StoreStoreElimination::UnobservablesSet::UnobservablesSet() : set_(nullptr) {} - -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::UnobservablesSet::VisitedEmpty(Zone* zone) { - ZoneSet<UnobservableStore>* empty_set = - new (zone->New(sizeof(ZoneSet<UnobservableStore>))) - ZoneSet<UnobservableStore>(zone); - return StoreStoreElimination::UnobservablesSet(empty_set); +UnobservablesSet UnobservablesSet::VisitedEmpty(Zone* zone) { + return UnobservablesSet(NewSet(zone)); } -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::UnobservablesSet::Intersect( - const StoreStoreElimination::UnobservablesSet& other, - const StoreStoreElimination::UnobservablesSet& empty, Zone* zone) const { - if (IsEmpty() || other.IsEmpty()) { - return empty; - } else { - ZoneSet<UnobservableStore>* intersection = - new (zone->New(sizeof(ZoneSet<UnobservableStore>))) - ZoneSet<UnobservableStore>(zone); - // Put the intersection of set() and other.set() in intersection. - set_intersection(set()->begin(), set()->end(), other.set()->begin(), - other.set()->end(), - std::inserter(*intersection, intersection->end())); - - return StoreStoreElimination::UnobservablesSet(intersection); +UnobservablesSet UnobservablesSet::Intersect(const UnobservablesSet& other, + const UnobservablesSet& empty, + Zone* zone) const { + if (IsEmpty() || other.IsEmpty()) return empty; + + UnobservablesSet::SetT* intersection = NewSet(zone); + for (const auto& triple : set()->Zip(*other.set())) { + if (std::get<1>(triple) && std::get<2>(triple)) { + intersection->Set(std::get<0>(triple), kPresent); + } } + + return UnobservablesSet(intersection); } -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::UnobservablesSet::Add(UnobservableStore obs, - Zone* zone) const { - bool found = set()->find(obs) != set()->end(); - if (found) { - return *this; - } else { - // Make a new empty set. - ZoneSet<UnobservableStore>* new_set = - new (zone->New(sizeof(ZoneSet<UnobservableStore>))) - ZoneSet<UnobservableStore>(zone); - // Copy the old elements over. - *new_set = *set(); - // Add the new element. - bool inserted = new_set->insert(obs).second; - DCHECK(inserted); - USE(inserted); // silence warning about unused variable - - return StoreStoreElimination::UnobservablesSet(new_set); +UnobservablesSet UnobservablesSet::Add(UnobservableStore obs, + Zone* zone) const { + if (set()->Get(obs) != kNotPresent) return *this; + + UnobservablesSet::SetT* new_set = NewSet(zone); + *new_set = *set(); + SetAdd(new_set, obs); + + return UnobservablesSet(new_set); +} + +UnobservablesSet UnobservablesSet::RemoveSameOffset(StoreOffset offset, + Zone* zone) const { + UnobservablesSet::SetT* new_set = NewSet(zone); + *new_set = *set(); + + // Remove elements with the given offset. + for (const auto& entry : *new_set) { + const UnobservableStore& obs = entry.first; + if (obs.offset_ == offset) SetErase(new_set, obs); } + + return UnobservablesSet(new_set); } -StoreStoreElimination::UnobservablesSet -StoreStoreElimination::UnobservablesSet::RemoveSameOffset(StoreOffset offset, - Zone* zone) const { - // Make a new empty set. - ZoneSet<UnobservableStore>* new_set = - new (zone->New(sizeof(ZoneSet<UnobservableStore>))) - ZoneSet<UnobservableStore>(zone); - // Copy all elements over that have a different offset. - for (auto obs : *set()) { - if (obs.offset_ != offset) { - new_set->insert(obs); +} // namespace + +// static +void StoreStoreElimination::Run(JSGraph* js_graph, TickCounter* tick_counter, + Zone* temp_zone) { + // Find superfluous nodes + RedundantStoreFinder finder(js_graph, tick_counter, temp_zone); + finder.Find(); + + // Remove superfluous nodes + for (Node* node : finder.to_remove_const()) { + if (FLAG_trace_store_elimination) { + PrintF("StoreStoreElimination::Run: Eliminating node #%d:%s\n", + node->id(), node->op()->mnemonic()); } + Node* previous_effect = NodeProperties::GetEffectInput(node); + NodeProperties::ReplaceUses(node, nullptr, previous_effect, nullptr, + nullptr); + node->Kill(); } - - return StoreStoreElimination::UnobservablesSet(new_set); } #undef TRACE diff --git a/deps/v8/src/compiler/store-store-elimination.h b/deps/v8/src/compiler/store-store-elimination.h index 7704938fc0d6dc..0813adb1f0c85a 100644 --- a/deps/v8/src/compiler/store-store-elimination.h +++ b/deps/v8/src/compiler/store-store-elimination.h @@ -5,18 +5,18 @@ #ifndef V8_COMPILER_STORE_STORE_ELIMINATION_H_ #define V8_COMPILER_STORE_STORE_ELIMINATION_H_ -#include "src/compiler/common-operator.h" -#include "src/compiler/js-graph.h" -#include "src/compiler/simplified-operator.h" -#include "src/zone/zone-containers.h" +#include "src/common/globals.h" namespace v8 { namespace internal { class TickCounter; +class Zone; namespace compiler { +class JSGraph; + // Store-store elimination. // // The aim of this optimization is to detect the following pattern in the @@ -44,176 +44,10 @@ namespace compiler { // // This implementation needs all dead nodes removed from the graph, and the // graph should be trimmed. -class StoreStoreElimination final { +class StoreStoreElimination final : public AllStatic { public: static void Run(JSGraph* js_graph, TickCounter* tick_counter, Zone* temp_zone); - - private: - using StoreOffset = uint32_t; - - struct UnobservableStore { - NodeId id_; - StoreOffset offset_; - - bool operator==(const UnobservableStore other) const { - return (id_ == other.id_) && (offset_ == other.offset_); - } - - bool operator<(const UnobservableStore other) const { - return (id_ < other.id_) || (id_ == other.id_ && offset_ < other.offset_); - } - }; - - // Instances of UnobservablesSet are immutable. They represent either a set of - // UnobservableStores, or the "unvisited empty set". - // - // We apply some sharing to save memory. The class UnobservablesSet is only a - // pointer wide, and a copy does not use any heap (or temp_zone) memory. Most - // changes to an UnobservablesSet might allocate in the temp_zone. - // - // The size of an instance should be the size of a pointer, plus additional - // space in the zone in the case of non-unvisited UnobservablesSets. Copying - // an UnobservablesSet allocates no memory. - class UnobservablesSet final { - public: - // Creates a new UnobservablesSet, with the null set. - static UnobservablesSet Unvisited() { return UnobservablesSet(); } - - // Create a new empty UnobservablesSet. This allocates in the zone, and - // can probably be optimized to use a global singleton. - static UnobservablesSet VisitedEmpty(Zone* zone); - UnobservablesSet(const UnobservablesSet& other) V8_NOEXCEPT = default; - - // Computes the intersection of two UnobservablesSets. If one of the sets is - // empty, will return empty. - UnobservablesSet Intersect(const UnobservablesSet& other, - const UnobservablesSet& empty, Zone* zone) const; - - // Returns a set that it is the current one, plus the observation obs passed - // as parameter. If said obs it's already in the set, we don't have to - // create a new one. - UnobservablesSet Add(UnobservableStore obs, Zone* zone) const; - - // Returns a set that it is the current one, except for all of the - // observations with offset off. This is done by creating a new set and - // copying all observations with different offsets. - // This can probably be done better if the observations are stored first by - // offset and then by node. - // We are removing all nodes with offset off since different nodes may - // alias one another, and we currently we don't have the means to know if - // two nodes are definitely the same value. - UnobservablesSet RemoveSameOffset(StoreOffset off, Zone* zone) const; - - const ZoneSet<UnobservableStore>* set() const { return set_; } - - bool IsUnvisited() const { return set_ == nullptr; } - bool IsEmpty() const { return set_ == nullptr || set_->empty(); } - bool Contains(UnobservableStore obs) const { - return set_ != nullptr && (set_->find(obs) != set_->end()); - } - - bool operator==(const UnobservablesSet& other) const { - if (IsUnvisited() || other.IsUnvisited()) { - return IsEmpty() && other.IsEmpty(); - } else { - // Both pointers guaranteed not to be nullptrs. - return *set() == *(other.set()); - } - } - - bool operator!=(const UnobservablesSet& other) const { - return !(*this == other); - } - - private: - UnobservablesSet(); - explicit UnobservablesSet(const ZoneSet<UnobservableStore>* set) - : set_(set) {} - const ZoneSet<UnobservableStore>* set_; - }; - - class RedundantStoreFinder final { - public: - // Note that we Initialize unobservable_ with js_graph->graph->NodeCount() - // amount of empty sets. - RedundantStoreFinder(JSGraph* js_graph, TickCounter* tick_counter, - Zone* temp_zone) - : jsgraph_(js_graph), - tick_counter_(tick_counter), - temp_zone_(temp_zone), - revisit_(temp_zone), - in_revisit_(js_graph->graph()->NodeCount(), temp_zone), - unobservable_(js_graph->graph()->NodeCount(), - StoreStoreElimination::UnobservablesSet::Unvisited(), - temp_zone), - to_remove_(temp_zone), - unobservables_visited_empty_( - StoreStoreElimination::UnobservablesSet::VisitedEmpty( - temp_zone)) {} - - // Crawls from the end of the graph to the beginning, with the objective of - // finding redundant stores. - void Find(); - - // This method is used for const correctness to go through the final list of - // redundant stores that are replaced on the graph. - const ZoneSet<Node*>& to_remove_const() { return to_remove_; } - - private: - // Assumption: All effectful nodes are reachable from End via a sequence of - // control, then a sequence of effect edges. - // Visit goes through the control chain, visiting effectful nodes that it - // encounters. - void Visit(Node* node); - - // Marks effect inputs for visiting, if we are able to update this path of - // the graph. - void VisitEffectfulNode(Node* node); - - // Compute the intersection of the UnobservablesSets of all effect uses and - // return it. - // The result UnobservablesSet will never be null. - UnobservablesSet RecomputeUseIntersection(Node* node); - - // Recompute unobservables-set for a node. Will also mark superfluous nodes - // as to be removed. - UnobservablesSet RecomputeSet(Node* node, const UnobservablesSet& uses); - - // Returns true if node's opcode cannot observe StoreFields. - static bool CannotObserveStoreField(Node* node); - - void MarkForRevisit(Node* node); - bool HasBeenVisited(Node* node); - - // To safely cast an offset from a FieldAccess, which has a potentially - // wider range (namely int). - StoreOffset ToOffset(const FieldAccess& access) { - DCHECK_GE(access.offset, 0); - return static_cast<StoreOffset>(access.offset); - } - - JSGraph* jsgraph() const { return jsgraph_; } - Isolate* isolate() { return jsgraph()->isolate(); } - Zone* temp_zone() const { return temp_zone_; } - UnobservablesSet& unobservable_for_id(NodeId id) { - DCHECK_LT(id, unobservable_.size()); - return unobservable_[id]; - } - ZoneSet<Node*>& to_remove() { return to_remove_; } - - JSGraph* const jsgraph_; - TickCounter* const tick_counter_; - Zone* const temp_zone_; - - ZoneStack<Node*> revisit_; - ZoneVector<bool> in_revisit_; - - // Maps node IDs to UnobservableNodeSets. - ZoneVector<UnobservablesSet> unobservable_; - ZoneSet<Node*> to_remove_; - const UnobservablesSet unobservables_visited_empty_; - }; }; } // namespace compiler diff --git a/deps/v8/src/compiler/typer.cc b/deps/v8/src/compiler/typer.cc index 6ba1b39431bd0c..e5ee0aa733689a 100644 --- a/deps/v8/src/compiler/typer.cc +++ b/deps/v8/src/compiler/typer.cc @@ -1339,6 +1339,10 @@ Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) { return Type::OtherObject(); } +Type Typer::Visitor::TypeJSGetTemplateObject(Node* node) { + return Type::Array(); +} + Type Typer::Visitor::TypeJSLoadProperty(Node* node) { return Type::NonInternal(); } @@ -2192,10 +2196,16 @@ Type Typer::Visitor::TypeLoadField(Node* node) { return FieldAccessOf(node->op()).type; } +Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); } + Type Typer::Visitor::TypeLoadElement(Node* node) { return ElementAccessOf(node->op()).type; } +Type Typer::Visitor::TypeLoadStackArgument(Node* node) { + return Type::NonInternal(); +} + Type Typer::Visitor::TypeLoadFromObject(Node* node) { UNREACHABLE(); } Type Typer::Visitor::TypeLoadTypedElement(Node* node) { @@ -2222,6 +2232,8 @@ Type Typer::Visitor::TypeLoadDataViewElement(Node* node) { Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); } +Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); } + Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); } Type Typer::Visitor::TypeStoreToObject(Node* node) { UNREACHABLE(); } diff --git a/deps/v8/src/compiler/types.cc b/deps/v8/src/compiler/types.cc index 018c54c3d57ce8..caa086bbd3bfc6 100644 --- a/deps/v8/src/compiler/types.cc +++ b/deps/v8/src/compiler/types.cc @@ -183,7 +183,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case HEAP_NUMBER_TYPE: return kNumber; case JS_OBJECT_TYPE: - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: case JS_ERROR_TYPE: case JS_GLOBAL_OBJECT_TYPE: case JS_GLOBAL_PROXY_TYPE: @@ -207,16 +207,16 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case JS_MESSAGE_OBJECT_TYPE: case JS_DATE_TYPE: #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: - case JS_INTL_COLLATOR_TYPE: - case JS_INTL_DATE_TIME_FORMAT_TYPE: - case JS_INTL_LIST_FORMAT_TYPE: - case JS_INTL_LOCALE_TYPE: - case JS_INTL_NUMBER_FORMAT_TYPE: - case JS_INTL_PLURAL_RULES_TYPE: - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: - case JS_INTL_SEGMENT_ITERATOR_TYPE: - case JS_INTL_SEGMENTER_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: + case JS_COLLATOR_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: + case JS_LOCALE_TYPE: + case JS_NUMBER_FORMAT_TYPE: + case JS_PLURAL_RULES_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENTER_TYPE: #endif // V8_INTL_SUPPORT case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_GENERATOR_OBJECT_TYPE: @@ -225,8 +225,8 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case JS_MODULE_NAMESPACE_TYPE: case JS_ARRAY_BUFFER_TYPE: case JS_ARRAY_ITERATOR_TYPE: - case JS_REGEXP_TYPE: // TODO(rossberg): there should be a RegExp type. - case JS_REGEXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: case JS_TYPED_ARRAY_TYPE: case JS_DATA_VIEW_TYPE: case JS_SET_TYPE: @@ -244,12 +244,12 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case JS_WEAK_REF_TYPE: case JS_WEAK_SET_TYPE: case JS_PROMISE_TYPE: - case WASM_EXCEPTION_TYPE: - case WASM_GLOBAL_TYPE: - case WASM_INSTANCE_TYPE: - case WASM_MEMORY_TYPE: - case WASM_MODULE_TYPE: - case WASM_TABLE_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: + case WASM_MEMORY_OBJECT_TYPE: + case WASM_MODULE_OBJECT_TYPE: + case WASM_TABLE_OBJECT_TYPE: case WEAK_CELL_TYPE: DCHECK(!map.is_callable()); DCHECK(!map.is_undetectable()); @@ -365,7 +365,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { case PROMISE_REJECT_REACTION_JOB_TASK_TYPE: case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE: #define MAKE_TORQUE_CLASS_TYPE(V) case V: - TORQUE_DEFINED_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE) + TORQUE_INTERNAL_INSTANCE_TYPES(MAKE_TORQUE_CLASS_TYPE) #undef MAKE_TORQUE_CLASS_TYPE UNREACHABLE(); } diff --git a/deps/v8/src/compiler/verifier.cc b/deps/v8/src/compiler/verifier.cc index 608d6ffee689bd..d7fdd4269ebf50 100644 --- a/deps/v8/src/compiler/verifier.cc +++ b/deps/v8/src/compiler/verifier.cc @@ -732,6 +732,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { // Type is OtherObject. CheckTypeIs(node, Type::OtherObject()); break; + case IrOpcode::kJSGetTemplateObject: + // Type is Array + CheckTypeIs(node, Type::Array()); + break; case IrOpcode::kJSLoadProperty: // Type can be anything. CheckTypeIs(node, Type::Any()); @@ -1594,12 +1598,14 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { CheckTypeIs(node, Type::NonInternal()); break; case IrOpcode::kLoadField: + case IrOpcode::kLoadMessage: // Object -> fieldtype // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); // CheckTypeIs(node, FieldAccessOf(node->op()).type)); break; case IrOpcode::kLoadElement: + case IrOpcode::kLoadStackArgument: // Object -> elementtype // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); @@ -1613,6 +1619,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { case IrOpcode::kLoadDataViewElement: break; case IrOpcode::kStoreField: + case IrOpcode::kStoreMessage: // (Object, fieldtype) -> _|_ // TODO(rossberg): activate once machine ops are typed. // CheckValueInputIs(node, 0, Type::Object()); @@ -1700,6 +1707,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { case IrOpcode::kWord64Ctz: case IrOpcode::kWord64ReverseBits: case IrOpcode::kWord64ReverseBytes: + case IrOpcode::kSimd128ReverseBytes: case IrOpcode::kInt64AbsWithOverflow: case IrOpcode::kWord64Equal: case IrOpcode::kInt32Add: @@ -1801,7 +1809,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { case IrOpcode::kBitcastInt32ToFloat32: case IrOpcode::kBitcastInt64ToFloat64: case IrOpcode::kBitcastTaggedToWord: - case IrOpcode::kBitcastTaggedSignedToWord: + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: case IrOpcode::kBitcastWordToTagged: case IrOpcode::kBitcastWordToTaggedSigned: case IrOpcode::kBitcastWord32ToCompressedSigned: diff --git a/deps/v8/src/compiler/wasm-compiler.cc b/deps/v8/src/compiler/wasm-compiler.cc index 28f9943e591905..ddc97ce5031161 100644 --- a/deps/v8/src/compiler/wasm-compiler.cc +++ b/deps/v8/src/compiler/wasm-compiler.cc @@ -176,8 +176,6 @@ WasmGraphBuilder::WasmGraphBuilder( : zone_(zone), mcgraph_(mcgraph), env_(env), - cur_buffer_(def_buffer_), - cur_bufsize_(kDefaultBufferSize), has_simd_(ContainsSimd(sig)), untrusted_code_mitigations_(FLAG_untrusted_code_mitigations), sig_(sig), @@ -255,24 +253,19 @@ Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) { return graph()->NewNode(mcgraph()->common()->Merge(count), count, controls); } -Node* WasmGraphBuilder::Phi(wasm::ValueType type, unsigned count, Node** vals, - Node* control) { - DCHECK(IrOpcode::IsMergeOpcode(control->opcode())); - Vector<Node*> buf = Realloc(vals, count, count + 1); - buf[count] = control; +Node* WasmGraphBuilder::Phi(wasm::ValueType type, unsigned count, + Node** vals_and_control) { + DCHECK(IrOpcode::IsMergeOpcode(vals_and_control[count]->opcode())); return graph()->NewNode( mcgraph()->common()->Phi(wasm::ValueTypes::MachineRepresentationFor(type), count), - count + 1, buf.begin()); + count + 1, vals_and_control); } -Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects, - Node* control) { - DCHECK(IrOpcode::IsMergeOpcode(control->opcode())); - Vector<Node*> buf = Realloc(effects, count, count + 1); - buf[count] = control; +Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects_and_control) { + DCHECK(IrOpcode::IsMergeOpcode(effects_and_control[count]->opcode())); return graph()->NewNode(mcgraph()->common()->EffectPhi(count), count + 1, - buf.begin()); + effects_and_control); } Node* WasmGraphBuilder::RefNull() { @@ -1114,6 +1107,10 @@ Node* WasmGraphBuilder::ZeroCheck64(wasm::TrapReason reason, Node* node, } Node* WasmGraphBuilder::Switch(unsigned count, Node* key) { + // The instruction selector will use {kArchTableSwitch} for large switches, + // which has limited input count, see {InstructionSelector::EmitTableSwitch}. + DCHECK_LE(count, Instruction::kMaxInputCount - 2); // value_range + 2 + DCHECK_LE(count, wasm::kV8MaxWasmFunctionBrTableSize + 1); // plus IfDefault return graph()->NewNode(mcgraph()->common()->Switch(count), key, Control()); } @@ -1266,27 +1263,9 @@ Node* WasmGraphBuilder::BuildChangeEndiannessStore( case 8: result = graph()->NewNode(m->Word64ReverseBytes(), value); break; - case 16: { - Node* byte_reversed_lanes[4]; - for (int lane = 0; lane < 4; lane++) { - byte_reversed_lanes[lane] = graph()->NewNode( - m->Word32ReverseBytes(), - graph()->NewNode(mcgraph()->machine()->I32x4ExtractLane(lane), - value)); - } - - // This is making a copy of the value. - result = - graph()->NewNode(mcgraph()->machine()->S128And(), value, value); - - for (int lane = 0; lane < 4; lane++) { - result = - graph()->NewNode(mcgraph()->machine()->I32x4ReplaceLane(3 - lane), - result, byte_reversed_lanes[lane]); - } - + case 16: + result = graph()->NewNode(m->Simd128ReverseBytes(), value); break; - } default: UNREACHABLE(); break; @@ -1405,27 +1384,9 @@ Node* WasmGraphBuilder::BuildChangeEndiannessLoad(Node* node, case 8: result = graph()->NewNode(m->Word64ReverseBytes(), value); break; - case 16: { - Node* byte_reversed_lanes[4]; - for (int lane = 0; lane < 4; lane++) { - byte_reversed_lanes[lane] = graph()->NewNode( - m->Word32ReverseBytes(), - graph()->NewNode(mcgraph()->machine()->I32x4ExtractLane(lane), - value)); - } - - // This is making a copy of the value. - result = - graph()->NewNode(mcgraph()->machine()->S128And(), value, value); - - for (int lane = 0; lane < 4; lane++) { - result = - graph()->NewNode(mcgraph()->machine()->I32x4ReplaceLane(3 - lane), - result, byte_reversed_lanes[lane]); - } - + case 16: + result = graph()->NewNode(m->Simd128ReverseBytes(), value); break; - } default: UNREACHABLE(); } @@ -2295,13 +2256,14 @@ Node* WasmGraphBuilder::GetExceptionTag(Node* except_obj) { return BuildCallToRuntime(Runtime::kWasmExceptionGetTag, &except_obj, 1); } -Vector<Node*> WasmGraphBuilder::GetExceptionValues( - Node* except_obj, const wasm::WasmException* exception) { +Node* WasmGraphBuilder::GetExceptionValues(Node* except_obj, + const wasm::WasmException* exception, + Vector<Node*> values) { Node* values_array = BuildCallToRuntime(Runtime::kWasmExceptionGetValues, &except_obj, 1); uint32_t index = 0; const wasm::WasmExceptionSig* sig = exception->sig; - Vector<Node*> values = Buffer(sig->parameter_count()); + DCHECK_EQ(sig->parameter_count(), values.size()); for (size_t i = 0; i < sig->parameter_count(); ++i) { Node* value; switch (sig->GetParam(i)) { @@ -2347,7 +2309,7 @@ Vector<Node*> WasmGraphBuilder::GetExceptionValues( values[i] = value; } DCHECK_EQ(index, WasmExceptionPackage::GetEncodedSize(exception)); - return values; + return values_array; } Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right, @@ -2682,7 +2644,8 @@ Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node* function, return SetEffect(graph()->NewNode(op, arraysize(call_args), call_args)); } -Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, Node** args, +Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, + Vector<Node*> args, wasm::WasmCodePosition position, Node* instance_node, const Operator* op) { if (instance_node == nullptr) { @@ -2695,25 +2658,28 @@ Node* WasmGraphBuilder::BuildCallNode(wasm::FunctionSig* sig, Node** args, const size_t count = 1 + params + extra; // Reallocate the buffer to make space for extra inputs. - args = Realloc(args, 1 + params, count).begin(); + base::SmallVector<Node*, 16 + extra> inputs(count); + DCHECK_EQ(1 + params, args.size()); // Make room for the instance_node parameter at index 1, just after code. - memmove(&args[2], &args[1], params * sizeof(Node*)); - args[1] = instance_node; + inputs[0] = args[0]; // code + inputs[1] = instance_node; + if (params > 0) memcpy(&inputs[2], &args[1], params * sizeof(Node*)); // Add effect and control inputs. - args[params + 2] = Effect(); - args[params + 3] = Control(); + inputs[params + 2] = Effect(); + inputs[params + 3] = Control(); - Node* call = SetEffect(graph()->NewNode(op, static_cast<int>(count), args)); + Node* call = + SetEffect(graph()->NewNode(op, static_cast<int>(count), inputs.begin())); DCHECK(position == wasm::kNoCodePosition || position > 0); if (position > 0) SetSourcePosition(call, position); return call; } -Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, - Node*** rets, +Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, + Vector<Node*> args, Vector<Node*> rets, wasm::WasmCodePosition position, Node* instance_node, UseRetpoline use_retpoline) { @@ -2725,21 +2691,22 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, size_t ret_count = sig->return_count(); if (ret_count == 0) return call; // No return value. - *rets = Buffer(ret_count).begin(); + DCHECK_EQ(ret_count, rets.size()); if (ret_count == 1) { // Only a single return value. - (*rets)[0] = call; + rets[0] = call; } else { // Create projections for all return values. for (size_t i = 0; i < ret_count; i++) { - (*rets)[i] = graph()->NewNode(mcgraph()->common()->Projection(i), call, - graph()->start()); + rets[i] = graph()->NewNode(mcgraph()->common()->Projection(i), call, + graph()->start()); } } return call; } -Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args, +Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig, + Vector<Node*> args, wasm::WasmCodePosition position, Node* instance_node, UseRetpoline use_retpoline) { @@ -2753,8 +2720,8 @@ Node* WasmGraphBuilder::BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args, return call; } -Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args, - Node*** rets, +Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, + Vector<Node*> args, Vector<Node*> rets, wasm::WasmCodePosition position, int func_index, IsReturnCall continuation) { @@ -2779,13 +2746,13 @@ Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args, case kCallContinues: return BuildWasmCall(sig, args, rets, position, ref_node, use_retpoline); case kReturnCall: - DCHECK_NULL(rets); + DCHECK(rets.empty()); return BuildWasmReturnCall(sig, args, position, ref_node, use_retpoline); } } -Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args, - Node*** rets, +Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, + Vector<Node*> args, Vector<Node*> rets, wasm::WasmCodePosition position, Node* func_index, IsReturnCall continuation) { @@ -2829,12 +2796,13 @@ Node* WasmGraphBuilder::BuildImportCall(wasm::FunctionSig* sig, Node** args, case kCallContinues: return BuildWasmCall(sig, args, rets, position, ref_node, use_retpoline); case kReturnCall: - DCHECK_NULL(rets); + DCHECK(rets.empty()); return BuildWasmReturnCall(sig, args, position, ref_node, use_retpoline); } } -Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets, +Node* WasmGraphBuilder::CallDirect(uint32_t index, Vector<Node*> args, + Vector<Node*> rets, wasm::WasmCodePosition position) { DCHECK_NULL(args[0]); wasm::FunctionSig* sig = env_->module->functions[index].sig; @@ -2853,7 +2821,7 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, Node*** rets, } Node* WasmGraphBuilder::CallIndirect(uint32_t table_index, uint32_t sig_index, - Node** args, Node*** rets, + Vector<Node*> args, Vector<Node*> rets, wasm::WasmCodePosition position) { return BuildIndirectCall(table_index, sig_index, args, rets, position, kCallContinues); @@ -2902,8 +2870,9 @@ void WasmGraphBuilder::LoadIndirectFunctionTable(uint32_t table_index, } Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index, - uint32_t sig_index, Node** args, - Node*** rets, + uint32_t sig_index, + Vector<Node*> args, + Vector<Node*> rets, wasm::WasmCodePosition position, IsReturnCall continuation) { DCHECK_NOT_NULL(args[0]); @@ -2993,14 +2962,14 @@ Node* WasmGraphBuilder::BuildIndirectCall(uint32_t table_index, } } -Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args, +Node* WasmGraphBuilder::ReturnCall(uint32_t index, Vector<Node*> args, wasm::WasmCodePosition position) { DCHECK_NULL(args[0]); wasm::FunctionSig* sig = env_->module->functions[index].sig; if (env_ && index < env_->module->num_imported_functions) { // Return Call to an imported function. - return BuildImportCall(sig, args, nullptr, position, index, kReturnCall); + return BuildImportCall(sig, args, {}, position, index, kReturnCall); } // A direct tail call to a wasm function defined in this module. @@ -3013,9 +2982,10 @@ Node* WasmGraphBuilder::ReturnCall(uint32_t index, Node** args, } Node* WasmGraphBuilder::ReturnCallIndirect(uint32_t table_index, - uint32_t sig_index, Node** args, + uint32_t sig_index, + Vector<Node*> args, wasm::WasmCodePosition position) { - return BuildIndirectCall(table_index, sig_index, args, nullptr, position, + return BuildIndirectCall(table_index, sig_index, args, {}, position, kReturnCall); } @@ -3062,6 +3032,14 @@ bool CanCover(Node* value, IrOpcode::Value opcode) { return true; } +Node* WasmGraphBuilder::BuildTruncateIntPtrToInt32(Node* value) { + if (mcgraph()->machine()->Is64()) { + value = + graph()->NewNode(mcgraph()->machine()->TruncateInt64ToInt32(), value); + } + return value; +} + Node* WasmGraphBuilder::BuildChangeInt32ToIntPtr(Node* value) { if (mcgraph()->machine()->Is64()) { value = graph()->NewNode(mcgraph()->machine()->ChangeInt32ToInt64(), value); @@ -3070,12 +3048,20 @@ Node* WasmGraphBuilder::BuildChangeInt32ToIntPtr(Node* value) { } Node* WasmGraphBuilder::BuildChangeInt32ToSmi(Node* value) { + if (COMPRESS_POINTERS_BOOL) { + return graph()->NewNode(mcgraph()->machine()->Word32Shl(), value, + BuildSmiShiftBitsConstant32()); + } value = BuildChangeInt32ToIntPtr(value); return graph()->NewNode(mcgraph()->machine()->WordShl(), value, BuildSmiShiftBitsConstant()); } Node* WasmGraphBuilder::BuildChangeUint31ToSmi(Node* value) { + if (COMPRESS_POINTERS_BOOL) { + return graph()->NewNode(mcgraph()->machine()->Word32Shl(), value, + BuildSmiShiftBitsConstant32()); + } return graph()->NewNode(mcgraph()->machine()->WordShl(), Uint32ToUintptr(value), BuildSmiShiftBitsConstant()); } @@ -3084,16 +3070,32 @@ Node* WasmGraphBuilder::BuildSmiShiftBitsConstant() { return mcgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); } +Node* WasmGraphBuilder::BuildSmiShiftBitsConstant32() { + return mcgraph()->Int32Constant(kSmiShiftSize + kSmiTagSize); +} + Node* WasmGraphBuilder::BuildChangeSmiToInt32(Node* value) { - value = graph()->NewNode(mcgraph()->machine()->WordSar(), value, - BuildSmiShiftBitsConstant()); - if (mcgraph()->machine()->Is64()) { + if (COMPRESS_POINTERS_BOOL) { value = graph()->NewNode(mcgraph()->machine()->TruncateInt64ToInt32(), value); + value = graph()->NewNode(mcgraph()->machine()->Word32Sar(), value, + BuildSmiShiftBitsConstant32()); + } else { + value = BuildChangeSmiToIntPtr(value); + value = BuildTruncateIntPtrToInt32(value); } return value; } +Node* WasmGraphBuilder::BuildChangeSmiToIntPtr(Node* value) { + if (COMPRESS_POINTERS_BOOL) { + value = BuildChangeSmiToInt32(value); + return BuildChangeInt32ToIntPtr(value); + } + return graph()->NewNode(mcgraph()->machine()->WordSar(), value, + BuildSmiShiftBitsConstant()); +} + Node* WasmGraphBuilder::BuildConvertUint32ToSmiWithSaturation(Node* value, uint32_t maxval) { DCHECK(Smi::IsValid(maxval)); @@ -3181,14 +3183,16 @@ Node* WasmGraphBuilder::CreateOrMergeIntoPhi(MachineRepresentation rep, if (IsPhiWithMerge(tnode, merge)) { AppendToPhi(tnode, fnode); } else if (tnode != fnode) { + // Note that it is not safe to use {Buffer} here since this method is used + // via {CheckForException} while the {Buffer} is in use by another method. uint32_t count = merge->InputCount(); // + 1 for the merge node. - Vector<Node*> vals = Buffer(count + 1); - for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; - vals[count - 1] = fnode; - vals[count] = merge; - return graph()->NewNode(mcgraph()->common()->Phi(rep, count), count + 1, - vals.begin()); + base::SmallVector<Node*, 9> inputs(count + 1); + for (uint32_t j = 0; j < count - 1; j++) inputs[j] = tnode; + inputs[count - 1] = fnode; + inputs[count] = merge; + tnode = graph()->NewNode(mcgraph()->common()->Phi(rep, count), count + 1, + inputs.begin()); } return tnode; } @@ -3198,13 +3202,18 @@ Node* WasmGraphBuilder::CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode, if (IsPhiWithMerge(tnode, merge)) { AppendToPhi(tnode, fnode); } else if (tnode != fnode) { + // Note that it is not safe to use {Buffer} here since this method is used + // via {CheckForException} while the {Buffer} is in use by another method. uint32_t count = merge->InputCount(); - Vector<Node*> effects = Buffer(count); + // + 1 for the merge node. + base::SmallVector<Node*, 9> inputs(count + 1); for (uint32_t j = 0; j < count - 1; j++) { - effects[j] = tnode; + inputs[j] = tnode; } - effects[count - 1] = fnode; - tnode = EffectPhi(count, effects.begin(), merge); + inputs[count - 1] = fnode; + inputs[count] = merge; + tnode = graph()->NewNode(mcgraph()->common()->EffectPhi(count), count + 1, + inputs.begin()); } return tnode; } @@ -3310,10 +3319,7 @@ Node* WasmGraphBuilder::CurrentMemoryPages() { Node* result = graph()->NewNode(mcgraph()->machine()->WordShr(), mem_size, mcgraph()->Int32Constant(wasm::kWasmPageSizeLog2)); - if (mcgraph()->machine()->Is64()) { - result = - graph()->NewNode(mcgraph()->machine()->TruncateInt64ToInt32(), result); - } + result = BuildTruncateIntPtrToInt32(result); return result; } @@ -3365,7 +3371,7 @@ Node* WasmGraphBuilder::BuildCallToRuntime(Runtime::FunctionId f, parameter_count, effect_, Control()); } -Node* WasmGraphBuilder::GetGlobal(uint32_t index) { +Node* WasmGraphBuilder::GlobalGet(uint32_t index) { const wasm::WasmGlobal& global = env_->module->globals[index]; if (wasm::ValueTypes::IsReferenceType(global.type)) { if (global.mutability && global.imported) { @@ -3395,7 +3401,7 @@ Node* WasmGraphBuilder::GetGlobal(uint32_t index) { return result; } -Node* WasmGraphBuilder::SetGlobal(uint32_t index, Node* val) { +Node* WasmGraphBuilder::GlobalSet(uint32_t index, Node* val) { const wasm::WasmGlobal& global = env_->module->globals[index]; if (wasm::ValueTypes::IsReferenceType(global.type)) { if (global.mutability && global.imported) { @@ -4008,6 +4014,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) { return graph()->NewNode(mcgraph()->machine()->F64x2Abs(), inputs[0]); case wasm::kExprF64x2Neg: return graph()->NewNode(mcgraph()->machine()->F64x2Neg(), inputs[0]); + case wasm::kExprF64x2Sqrt: + return graph()->NewNode(mcgraph()->machine()->F64x2Sqrt(), inputs[0]); case wasm::kExprF64x2Add: return graph()->NewNode(mcgraph()->machine()->F64x2Add(), inputs[0], inputs[1]); @@ -4044,6 +4052,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) { case wasm::kExprF64x2Ge: return graph()->NewNode(mcgraph()->machine()->F64x2Le(), inputs[1], inputs[0]); + case wasm::kExprF64x2Qfma: + return graph()->NewNode(mcgraph()->machine()->F64x2Qfma(), inputs[0], + inputs[1], inputs[2]); + case wasm::kExprF64x2Qfms: + return graph()->NewNode(mcgraph()->machine()->F64x2Qfms(), inputs[0], + inputs[1], inputs[2]); case wasm::kExprF32x4Splat: return graph()->NewNode(mcgraph()->machine()->F32x4Splat(), inputs[0]); case wasm::kExprF32x4SConvertI32x4: @@ -4056,6 +4070,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) { return graph()->NewNode(mcgraph()->machine()->F32x4Abs(), inputs[0]); case wasm::kExprF32x4Neg: return graph()->NewNode(mcgraph()->machine()->F32x4Neg(), inputs[0]); + case wasm::kExprF32x4Sqrt: + return graph()->NewNode(mcgraph()->machine()->F32x4Sqrt(), inputs[0]); case wasm::kExprF32x4RecipApprox: return graph()->NewNode(mcgraph()->machine()->F32x4RecipApprox(), inputs[0]); @@ -4101,6 +4117,12 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) { case wasm::kExprF32x4Ge: return graph()->NewNode(mcgraph()->machine()->F32x4Le(), inputs[1], inputs[0]); + case wasm::kExprF32x4Qfma: + return graph()->NewNode(mcgraph()->machine()->F32x4Qfma(), inputs[0], + inputs[1], inputs[2]); + case wasm::kExprF32x4Qfms: + return graph()->NewNode(mcgraph()->machine()->F32x4Qfms(), inputs[0], + inputs[1], inputs[2]); case wasm::kExprI64x2Splat: return graph()->NewNode(mcgraph()->machine()->I64x2Splat(), inputs[0]); case wasm::kExprI64x2Neg: @@ -4459,6 +4481,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) { return graph()->NewNode(mcgraph()->machine()->S1x16AnyTrue(), inputs[0]); case wasm::kExprS1x16AllTrue: return graph()->NewNode(mcgraph()->machine()->S1x16AllTrue(), inputs[0]); + case wasm::kExprS8x16Swizzle: + return graph()->NewNode(mcgraph()->machine()->S8x16Swizzle(), inputs[0], + inputs[1]); default: FATAL_UNSUPPORTED_OPCODE(opcode); } @@ -4492,13 +4517,23 @@ Node* WasmGraphBuilder::SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane, case wasm::kExprI32x4ReplaceLane: return graph()->NewNode(mcgraph()->machine()->I32x4ReplaceLane(lane), inputs[0], inputs[1]); - case wasm::kExprI16x8ExtractLane: + case wasm::kExprI16x8ExtractLaneS: + return graph()->NewNode( + mcgraph()->machine()->SignExtendWord16ToInt32(), + graph()->NewNode(mcgraph()->machine()->I16x8ExtractLane(lane), + inputs[0])); + case wasm::kExprI16x8ExtractLaneU: return graph()->NewNode(mcgraph()->machine()->I16x8ExtractLane(lane), inputs[0]); case wasm::kExprI16x8ReplaceLane: return graph()->NewNode(mcgraph()->machine()->I16x8ReplaceLane(lane), inputs[0], inputs[1]); - case wasm::kExprI8x16ExtractLane: + case wasm::kExprI8x16ExtractLaneS: + return graph()->NewNode( + mcgraph()->machine()->SignExtendWord8ToInt32(), + graph()->NewNode(mcgraph()->machine()->I8x16ExtractLane(lane), + inputs[0])); + case wasm::kExprI8x16ExtractLaneU: return graph()->NewNode(mcgraph()->machine()->I8x16ExtractLane(lane), inputs[0]); case wasm::kExprI8x16ReplaceLane: @@ -5076,7 +5111,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { CallDescriptor* GetI64ToBigIntCallDescriptor() { if (!lowering_special_case_) { - lowering_special_case_ = base::make_unique<Int64LoweringSpecialCase>(); + lowering_special_case_ = std::make_unique<Int64LoweringSpecialCase>(); } if (lowering_special_case_->i64_to_bigint_call_descriptor) { @@ -5112,7 +5147,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { CallDescriptor* GetBigIntToI64CallDescriptor() { if (!lowering_special_case_) { - lowering_special_case_ = base::make_unique<Int64LoweringSpecialCase>(); + lowering_special_case_ = std::make_unique<Int64LoweringSpecialCase>(); } if (lowering_special_case_->bigint_to_i64_call_descriptor) { @@ -5613,7 +5648,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { Node* function_index_smi = LOAD_RAW( function_data, WasmExportedFunctionData::kFunctionIndexOffset - kHeapObjectTag, - MachineType::TypeCompressedTagged()); + MachineType::TypeCompressedTaggedSigned()); Node* function_index = BuildChangeSmiToInt32(function_index_smi); return function_index; } @@ -5622,13 +5657,30 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { Node* jump_table_offset_smi = LOAD_RAW( function_data, WasmExportedFunctionData::kJumpTableOffsetOffset - kHeapObjectTag, - MachineType::TypeCompressedTagged()); - Node* jump_table_offset = BuildChangeSmiToInt32(jump_table_offset_smi); + MachineType::TypeCompressedTaggedSigned()); + Node* jump_table_offset = BuildChangeSmiToIntPtr(jump_table_offset_smi); return jump_table_offset; } + Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig, + Node* iterable, Node* context) { + Node* iterable_to_fixed_array = + BuildLoadBuiltinFromIsolateRoot(Builtins::kIterableToFixedArrayForWasm); + IterableToFixedArrayForWasmDescriptor interface_descriptor; + Node* length = BuildChangeUint31ToSmi( + Uint32Constant(static_cast<uint32_t>(sig->return_count()))); + auto call_descriptor = Linkage::GetStubCallDescriptor( + mcgraph()->zone(), interface_descriptor, + interface_descriptor.GetStackParameterCount(), CallDescriptor::kNoFlags, + Operator::kNoProperties, StubCallMode::kCallCodeObject); + return SetEffect(graph()->NewNode( + mcgraph()->common()->Call(call_descriptor), iterable_to_fixed_array, + iterable, length, context, Effect(), Control())); + } + void BuildJSToWasmWrapper(bool is_import) { const int wasm_count = static_cast<int>(sig_->parameter_count()); + const int rets_count = static_cast<int>(sig_->return_count()); // Build the start and the JS parameter nodes. SetEffect(SetControl(Start(wasm_count + 5))); @@ -5662,8 +5714,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { } const int args_count = wasm_count + 1; // +1 for wasm_code. - Vector<Node*> args = Buffer(args_count); - Node** rets; + base::SmallVector<Node*, 16> args(args_count); + base::SmallVector<Node*, 1> rets(rets_count); // Convert JS parameters to wasm numbers. for (int i = 0; i < wasm_count; ++i) { @@ -5680,8 +5732,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { // Load function index from {WasmExportedFunctionData}. Node* function_index = BuildLoadFunctionIndexFromExportedFunctionData(function_data); - BuildImportCall(sig_, args.begin(), &rets, wasm::kNoCodePosition, - function_index, kCallContinues); + BuildImportCall(sig_, VectorOf(args), VectorOf(rets), + wasm::kNoCodePosition, function_index, kCallContinues); } else { // Call to a wasm function defined in this module. // The call target is the jump table slot for that function. @@ -5693,8 +5745,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { mcgraph()->machine()->IntAdd(), jump_table_start, jump_table_offset); args[0] = jump_table_slot; - BuildWasmCall(sig_, args.begin(), &rets, wasm::kNoCodePosition, nullptr, - kNoRetpoline); + BuildWasmCall(sig_, VectorOf(args), VectorOf(rets), wasm::kNoCodePosition, + nullptr, kNoRetpoline); } // Clear the ThreadInWasm flag. @@ -5765,7 +5817,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { sloppy_receiver = false; V8_FALLTHROUGH; // fallthru case WasmImportCallKind::kJSFunctionArityMatchSloppy: { - Vector<Node*> args = Buffer(wasm_count + 7); + base::SmallVector<Node*, 16> args(wasm_count + 7); int pos = 0; Node* function_context = LOAD_RAW(callable_node, @@ -5785,7 +5837,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); // Convert wasm numbers to JS values. - pos = AddArgumentNodes(args, pos, wasm_count, sig_); + pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_); args[pos++] = undefined_node; // new target args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count @@ -5805,7 +5857,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { sloppy_receiver = false; V8_FALLTHROUGH; // fallthru case WasmImportCallKind::kJSFunctionArityMismatchSloppy: { - Vector<Node*> args = Buffer(wasm_count + 9); + base::SmallVector<Node*, 16> args(wasm_count + 9); int pos = 0; Node* function_context = LOAD_RAW(callable_node, @@ -5852,7 +5904,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { flags, Operator::kNoProperties); // Convert wasm numbers to JS values. - pos = AddArgumentNodes(args, pos, wasm_count, sig_); + pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_); args[pos++] = function_context; args[pos++] = Effect(); args[pos++] = Control(); @@ -5866,7 +5918,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { // === General case of unknown callable ================================== // ======================================================================= case WasmImportCallKind::kUseCallBuiltin: { - Vector<Node*> args = Buffer(wasm_count + 7); + base::SmallVector<Node*, 16> args(wasm_count + 7); int pos = 0; args[pos++] = BuildLoadBuiltinFromIsolateRoot(Builtins::kCall_ReceiverIsAny); @@ -5879,7 +5931,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { CallDescriptor::kNoFlags, Operator::kNoProperties); // Convert wasm numbers to JS values. - pos = AddArgumentNodes(args, pos, wasm_count, sig_); + pos = AddArgumentNodes(VectorOf(args), pos, wasm_count, sig_); // The native_context is sufficient here, because all kind of callables // which depend on the context provide their own context. The context @@ -5903,15 +5955,24 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { SetEffect(call); SetSourcePosition(call, 0); - // Convert the return value back. - Node* val = sig_->return_count() == 0 - ? mcgraph()->Int32Constant(0) - : FromJS(call, native_context, sig_->GetReturn()); - - // Set the ThreadInWasm flag again. - BuildModifyThreadInWasmFlag(true); - - Return(val); + // Convert the return value(s) back. + if (sig_->return_count() <= 1) { + Node* val = sig_->return_count() == 0 + ? mcgraph()->Int32Constant(0) + : FromJS(call, native_context, sig_->GetReturn()); + BuildModifyThreadInWasmFlag(true); + Return(val); + } else { + Node* fixed_array = + BuildMultiReturnFixedArrayFromIterable(sig_, call, native_context); + base::SmallVector<Node*, 8> wasm_values(sig_->return_count()); + for (unsigned i = 0; i < sig_->return_count(); ++i) { + wasm_values[i] = FromJS(LOAD_FIXED_ARRAY_SLOT_ANY(fixed_array, i), + native_context, sig_->GetReturn(i)); + } + BuildModifyThreadInWasmFlag(true); + Return(VectorOf(wasm_values)); + } if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm); return true; @@ -6006,7 +6067,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { if (return_count == 0) { Return(Int32Constant(0)); } else { - Vector<Node*> returns = Buffer(return_count); + base::SmallVector<Node*, 8> returns(return_count); offset = 0; for (size_t i = 0; i < return_count; ++i) { wasm::ValueType type = sig_->GetReturn(i); @@ -6016,7 +6077,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { returns[i] = val; offset += wasm::ValueTypes::ElementSizeInBytes(type); } - Return(returns); + Return(VectorOf(returns)); } if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm); @@ -6078,7 +6139,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { if (return_count == 0) { Return(Int32Constant(0)); } else { - Vector<Node*> returns = Buffer(return_count); + base::SmallVector<Node*, 8> returns(return_count); offset = 0; for (size_t i = 0; i < return_count; ++i) { wasm::ValueType type = sig_->GetReturn(i); @@ -6088,7 +6149,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { returns[i] = val; offset += wasm::ValueTypes::ElementSizeInBytes(type); } - Return(returns); + Return(VectorOf(returns)); } if (ContainsInt64(sig_)) LowerInt64(kCalledFromWasm); @@ -6130,10 +6191,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { wasm::ObjectAccess::ToTagged(WasmJSFunctionData::kCallableOffset)); // Call the underlying closure. - Vector<Node*> args = Buffer(wasm_count + 7); + base::SmallVector<Node*, 16> args(wasm_count + 7); int pos = 0; - args[pos++] = graph()->NewNode(mcgraph()->common()->HeapConstant( - BUILTIN_CODE(isolate, Call_ReceiverIsAny))); + args[pos++] = + BuildLoadBuiltinFromIsolateRoot(Builtins::kCall_ReceiverIsAny); args[pos++] = callable; args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count args[pos++] = BuildLoadUndefinedValueFromInstance(); // receiver @@ -6158,14 +6219,30 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { Node* call = SetEffect(graph()->NewNode( mcgraph()->common()->Call(call_descriptor), pos, args.begin())); - // TODO(wasm): Extend this to support multi-return. - DCHECK_LE(sig_->return_count(), 1); - // Convert return JS values to wasm numbers and back to JS values. - Node* jsval = - sig_->return_count() == 0 - ? BuildLoadUndefinedValueFromInstance() - : ToJS(FromJS(call, context, sig_->GetReturn()), sig_->GetReturn()); + Node* jsval; + if (sig_->return_count() == 0) { + jsval = BuildLoadUndefinedValueFromInstance(); + } else if (sig_->return_count() == 1) { + jsval = ToJS(FromJS(call, context, sig_->GetReturn()), sig_->GetReturn()); + } else { + Node* fixed_array = + BuildMultiReturnFixedArrayFromIterable(sig_, call, context); + int32_t return_count = static_cast<int32_t>(sig_->return_count()); + Node* size = + graph()->NewNode(mcgraph()->common()->NumberConstant(return_count)); + Node* result_fixed_array = + BuildCallToRuntime(Runtime::kWasmNewMultiReturnFixedArray, &size, 1); + for (unsigned i = 0; i < sig_->return_count(); ++i) { + const auto& type = sig_->GetReturn(i); + Node* elem = LOAD_FIXED_ARRAY_SLOT_ANY(fixed_array, i); + Node* cast = ToJS(FromJS(elem, context, type), type); + STORE_FIXED_ARRAY_SLOT_ANY(result_fixed_array, i, cast); + } + jsval = BuildCallToRuntimeWithContext(Runtime::kWasmNewMultiReturnJSArray, + context, &result_fixed_array, 1, + effect_, Control()); + } Return(jsval); } @@ -6184,7 +6261,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { kNoWriteBarrier); int wasm_arg_count = static_cast<int>(sig_->parameter_count()); - Vector<Node*> args = Buffer(wasm_arg_count + 4); + base::SmallVector<Node*, 16> args(wasm_arg_count + 4); int pos = 0; args[pos++] = code_entry; @@ -6222,14 +6299,12 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { pos = 0; offset = 0; for (wasm::ValueType type : sig_->returns()) { - StoreRepresentation store_rep( - wasm::ValueTypes::MachineRepresentationFor(type), kNoWriteBarrier); Node* value = sig_->return_count() == 1 ? call : graph()->NewNode(mcgraph()->common()->Projection(pos), call, Control()); - SetEffect(graph()->NewNode(mcgraph()->machine()->Store(store_rep), - arg_buffer, Int32Constant(offset), value, + SetEffect(graph()->NewNode(GetSafeStoreOperator(offset, type), arg_buffer, + Int32Constant(offset), value, Effect(), Control())); offset += wasm::ValueTypes::ElementSizeInBytes(type); pos++; @@ -6287,7 +6362,7 @@ std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob( // Create the Graph. //---------------------------------------------------------------------------- std::unique_ptr<Zone> zone = - base::make_unique<Zone>(wasm_engine->allocator(), ZONE_NAME); + std::make_unique<Zone>(wasm_engine->allocator(), ZONE_NAME); Graph* graph = new (zone.get()) Graph(zone.get()); CommonOperatorBuilder common(zone.get()); MachineOperatorBuilder machine( @@ -6702,7 +6777,7 @@ wasm::WasmCompilationResult CompileWasmInterpreterEntry( MaybeHandle<Code> CompileJSToJSWrapper(Isolate* isolate, wasm::FunctionSig* sig) { std::unique_ptr<Zone> zone = - base::make_unique<Zone>(isolate->allocator(), ZONE_NAME); + std::make_unique<Zone>(isolate->allocator(), ZONE_NAME); Graph* graph = new (zone.get()) Graph(zone.get()); CommonOperatorBuilder common(zone.get()); MachineOperatorBuilder machine( @@ -6749,7 +6824,7 @@ MaybeHandle<Code> CompileJSToJSWrapper(Isolate* isolate, MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) { std::unique_ptr<Zone> zone = - base::make_unique<Zone>(isolate->allocator(), ZONE_NAME); + std::make_unique<Zone>(isolate->allocator(), ZONE_NAME); Graph* graph = new (zone.get()) Graph(zone.get()); CommonOperatorBuilder common(zone.get()); MachineOperatorBuilder machine( @@ -6916,6 +6991,7 @@ wasm::WasmCompilationResult ExecuteTurbofanWasmCompilation( counters->wasm_compile_function_peak_memory_bytes()->AddSample( static_cast<int>(mcgraph->graph()->zone()->allocation_size())); auto result = info.ReleaseWasmCompilationResult(); + CHECK_NOT_NULL(result); // Compilation expected to succeed. DCHECK_EQ(wasm::ExecutionTier::kTurbofan, result->result_tier); return std::move(*result); } diff --git a/deps/v8/src/compiler/wasm-compiler.h b/deps/v8/src/compiler/wasm-compiler.h index dd86ea14997359..de0ca58c23a3db 100644 --- a/deps/v8/src/compiler/wasm-compiler.h +++ b/deps/v8/src/compiler/wasm-compiler.h @@ -179,16 +179,6 @@ class WasmGraphBuilder { wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph, wasm::FunctionSig* sig, compiler::SourcePositionTable* spt = nullptr); - Vector<Node*> Buffer(size_t count) { - if (count > cur_bufsize_) { - size_t new_size = count + cur_bufsize_ + 5; - cur_buffer_ = - reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*))); - cur_bufsize_ = new_size; - } - return {cur_buffer_, count}; - } - //----------------------------------------------------------------------- // Operations independent of {control} or {effect}. //----------------------------------------------------------------------- @@ -199,11 +189,11 @@ class WasmGraphBuilder { Node* TerminateLoop(Node* effect, Node* control); Node* TerminateThrow(Node* effect, Node* control); Node* Merge(unsigned count, Node** controls); - Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control); + Node* Phi(wasm::ValueType type, unsigned count, Node** vals_and_control); Node* CreateOrMergeIntoPhi(MachineRepresentation rep, Node* merge, Node* tnode, Node* fnode); Node* CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode, Node* fnode); - Node* EffectPhi(unsigned count, Node** effects, Node* control); + Node* EffectPhi(unsigned count, Node** effects_and_control); Node* RefNull(); Node* RefFunc(uint32_t function_index); Node* Uint32Constant(uint32_t value); @@ -223,8 +213,9 @@ class WasmGraphBuilder { Node* ExceptionTagEqual(Node* caught_tag, Node* expected_tag); Node* LoadExceptionTagFromTable(uint32_t exception_index); Node* GetExceptionTag(Node* except_obj); - Vector<Node*> GetExceptionValues(Node* except_obj, - const wasm::WasmException* exception); + Node* GetExceptionValues(Node* except_obj, + const wasm::WasmException* exception, + Vector<Node*> values_out); bool IsPhiWithMerge(Node* phi, Node* merge); bool ThrowsException(Node* node, Node** if_success, Node** if_exception); void AppendToMerge(Node* merge, Node* from); @@ -275,20 +266,21 @@ class WasmGraphBuilder { } Node* Unreachable(wasm::WasmCodePosition position); - Node* CallDirect(uint32_t index, Node** args, Node*** rets, + Node* CallDirect(uint32_t index, Vector<Node*> args, Vector<Node*> rets, wasm::WasmCodePosition position); - Node* CallIndirect(uint32_t table_index, uint32_t sig_index, Node** args, - Node*** rets, wasm::WasmCodePosition position); + Node* CallIndirect(uint32_t table_index, uint32_t sig_index, + Vector<Node*> args, Vector<Node*> rets, + wasm::WasmCodePosition position); - Node* ReturnCall(uint32_t index, Node** args, + Node* ReturnCall(uint32_t index, Vector<Node*> args, wasm::WasmCodePosition position); Node* ReturnCallIndirect(uint32_t table_index, uint32_t sig_index, - Node** args, wasm::WasmCodePosition position); + Vector<Node*> args, wasm::WasmCodePosition position); Node* Invert(Node* node); - Node* GetGlobal(uint32_t index); - Node* SetGlobal(uint32_t index, Node* val); + Node* GlobalGet(uint32_t index); + Node* GlobalSet(uint32_t index, Node* val); Node* TableGet(uint32_t table_index, Node* index, wasm::WasmCodePosition position); Node* TableSet(uint32_t table_index, Node* index, Node* val, @@ -427,8 +419,6 @@ class WasmGraphBuilder { void RemoveBytecodePositionDecorator(); protected: - static const int kDefaultBufferSize = 16; - Zone* const zone_; MachineGraph* const mcgraph_; wasm::CompilationEnv* const env_; @@ -444,9 +434,6 @@ class WasmGraphBuilder { SetOncePointer<Node> isolate_root_node_; SetOncePointer<const Operator> stack_check_call_operator_; - Node** cur_buffer_; - size_t cur_bufsize_; - Node* def_buffer_[kDefaultBufferSize]; bool has_simd_ = false; bool needs_stack_check_ = false; const bool untrusted_code_mitigations_ = true; @@ -496,28 +483,29 @@ class WasmGraphBuilder { template <typename... Args> Node* BuildCCall(MachineSignature* sig, Node* function, Args... args); - Node* BuildCallNode(wasm::FunctionSig* sig, Node** args, + Node* BuildCallNode(wasm::FunctionSig* sig, Vector<Node*> args, wasm::WasmCodePosition position, Node* instance_node, const Operator* op); // Helper function for {BuildIndirectCall}. void LoadIndirectFunctionTable(uint32_t table_index, Node** ift_size, Node** ift_sig_ids, Node** ift_targets, Node** ift_instances); - Node* BuildIndirectCall(uint32_t table_index, uint32_t sig_index, Node** args, - Node*** rets, wasm::WasmCodePosition position, + Node* BuildIndirectCall(uint32_t table_index, uint32_t sig_index, + Vector<Node*> args, Vector<Node*> rets, + wasm::WasmCodePosition position, IsReturnCall continuation); - Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args, Node*** rets, - wasm::WasmCodePosition position, Node* instance_node, - UseRetpoline use_retpoline); - Node* BuildWasmReturnCall(wasm::FunctionSig* sig, Node** args, + Node* BuildWasmCall(wasm::FunctionSig* sig, Vector<Node*> args, + Vector<Node*> rets, wasm::WasmCodePosition position, + Node* instance_node, UseRetpoline use_retpoline); + Node* BuildWasmReturnCall(wasm::FunctionSig* sig, Vector<Node*> args, wasm::WasmCodePosition position, Node* instance_node, UseRetpoline use_retpoline); - Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets, - wasm::WasmCodePosition position, int func_index, - IsReturnCall continuation); - Node* BuildImportCall(wasm::FunctionSig* sig, Node** args, Node*** rets, - wasm::WasmCodePosition position, Node* func_index, - IsReturnCall continuation); + Node* BuildImportCall(wasm::FunctionSig* sig, Vector<Node*> args, + Vector<Node*> rets, wasm::WasmCodePosition position, + int func_index, IsReturnCall continuation); + Node* BuildImportCall(wasm::FunctionSig* sig, Vector<Node*> args, + Vector<Node*> rets, wasm::WasmCodePosition position, + Node* func_index, IsReturnCall continuation); Node* BuildF32CopySign(Node* left, Node* right); Node* BuildF64CopySign(Node* left, Node* right); @@ -574,11 +562,14 @@ class WasmGraphBuilder { MachineType result_type, wasm::TrapReason trap_zero, wasm::WasmCodePosition position); + Node* BuildTruncateIntPtrToInt32(Node* value); Node* BuildChangeInt32ToIntPtr(Node* value); Node* BuildChangeInt32ToSmi(Node* value); Node* BuildChangeUint31ToSmi(Node* value); Node* BuildSmiShiftBitsConstant(); + Node* BuildSmiShiftBitsConstant32(); Node* BuildChangeSmiToInt32(Node* value); + Node* BuildChangeSmiToIntPtr(Node* value); // generates {index > max ? Smi(max) : Smi(index)} Node* BuildConvertUint32ToSmiWithSaturation(Node* index, uint32_t maxval); @@ -599,15 +590,8 @@ class WasmGraphBuilder { Node* BuildDecodeException32BitValue(Node* values_array, uint32_t* index); Node* BuildDecodeException64BitValue(Node* values_array, uint32_t* index); - Vector<Node*> Realloc(Node* const* buffer, size_t old_count, - size_t new_count) { - DCHECK_GE(new_count, old_count); // Only support growing. - Vector<Node*> buf = Buffer(new_count); - if (buf.begin() != buffer) { - memcpy(buf.begin(), buffer, old_count * sizeof(Node*)); - } - return buf; - } + Node* BuildMultiReturnFixedArrayFromIterable(const wasm::FunctionSig* sig, + Node* iterable, Node* context); //----------------------------------------------------------------------- // Operations involving the CEntry, a dependency we want to remove diff --git a/deps/v8/src/compiler/zone-stats.h b/deps/v8/src/compiler/zone-stats.h index 63d58eb99f298d..68036f116da429 100644 --- a/deps/v8/src/compiler/zone-stats.h +++ b/deps/v8/src/compiler/zone-stats.h @@ -33,6 +33,8 @@ class V8_EXPORT_PRIVATE ZoneStats final { zone_ = nullptr; } + ZoneStats* zone_stats() const { return zone_stats_; } + private: const char* zone_name_; ZoneStats* const zone_stats_; diff --git a/deps/v8/src/d8/OWNERS b/deps/v8/src/d8/OWNERS index ff3b6d73724117..0f3e3d8e5cdee7 100644 --- a/deps/v8/src/d8/OWNERS +++ b/deps/v8/src/d8/OWNERS @@ -1,5 +1,5 @@ binji@chromium.org bmeurer@chromium.org -clemensh@chromium.org +clemensb@chromium.org verwaest@chromium.org yangguo@chromium.org diff --git a/deps/v8/src/d8/d8-platforms.cc b/deps/v8/src/d8/d8-platforms.cc index 42ce14f4f79df2..8faf893c803ac6 100644 --- a/deps/v8/src/d8/d8-platforms.cc +++ b/deps/v8/src/d8/d8-platforms.cc @@ -11,7 +11,6 @@ #include "src/base/platform/mutex.h" #include "src/base/platform/platform.h" #include "src/base/platform/time.h" -#include "src/base/template-utils.h" #include "src/base/utils/random-number-generator.h" #include "src/d8/d8-platforms.h" @@ -94,7 +93,7 @@ class PredictablePlatform : public Platform { std::unique_ptr<Platform> MakePredictablePlatform( std::unique_ptr<Platform> platform) { - return base::make_unique<PredictablePlatform>(std::move(platform)); + return std::make_unique<PredictablePlatform>(std::move(platform)); } class DelayedTasksPlatform : public Platform { @@ -284,14 +283,14 @@ class DelayedTasksPlatform : public Platform { } std::unique_ptr<Task> MakeDelayedTask(std::unique_ptr<Task> task) { - return base::make_unique<DelayedTask>(std::move(task), - GetRandomDelayInMilliseconds()); + return std::make_unique<DelayedTask>(std::move(task), + GetRandomDelayInMilliseconds()); } std::unique_ptr<IdleTask> MakeDelayedIdleTask( std::unique_ptr<IdleTask> task) { - return base::make_unique<DelayedIdleTask>(std::move(task), - GetRandomDelayInMilliseconds()); + return std::make_unique<DelayedIdleTask>(std::move(task), + GetRandomDelayInMilliseconds()); } DISALLOW_COPY_AND_ASSIGN(DelayedTasksPlatform); @@ -300,10 +299,10 @@ class DelayedTasksPlatform : public Platform { std::unique_ptr<Platform> MakeDelayedTasksPlatform( std::unique_ptr<Platform> platform, int64_t random_seed) { if (random_seed) { - return base::make_unique<DelayedTasksPlatform>(std::move(platform), - random_seed); + return std::make_unique<DelayedTasksPlatform>(std::move(platform), + random_seed); } - return base::make_unique<DelayedTasksPlatform>(std::move(platform)); + return std::make_unique<DelayedTasksPlatform>(std::move(platform)); } } // namespace v8 diff --git a/deps/v8/src/d8/d8.cc b/deps/v8/src/d8/d8.cc index 13a35b0cd349c2..7129b9dc30f19d 100644 --- a/deps/v8/src/d8/d8.cc +++ b/deps/v8/src/d8/d8.cc @@ -71,6 +71,11 @@ #define CHECK(condition) assert(condition) #endif +#define TRACE_BS(...) \ + do { \ + if (i::FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ + } while (false) + namespace v8 { namespace { @@ -213,12 +218,20 @@ static Local<Value> Throw(Isolate* isolate, const char* message) { .ToLocalChecked()); } -static Local<Value> GetValue(v8::Isolate* isolate, Local<Context> context, - Local<v8::Object> object, const char* property) { +static MaybeLocal<Value> TryGetValue(v8::Isolate* isolate, + Local<Context> context, + Local<v8::Object> object, + const char* property) { Local<String> v8_str = String::NewFromUtf8(isolate, property, NewStringType::kNormal) - .ToLocalChecked(); - return object->Get(context, v8_str).ToLocalChecked(); + .FromMaybe(Local<String>()); + if (v8_str.IsEmpty()) return Local<Value>(); + return object->Get(context, v8_str); +} + +static Local<Value> GetValue(v8::Isolate* isolate, Local<Context> context, + Local<v8::Object> object, const char* property) { + return TryGetValue(isolate, context, object, property).ToLocalChecked(); } Worker* GetWorkerFromInternalField(Isolate* isolate, Local<Object> object) { @@ -333,7 +346,6 @@ Global<Function> Shell::stringify_function_; base::LazyMutex Shell::workers_mutex_; bool Shell::allow_new_workers_ = true; std::unordered_set<std::shared_ptr<Worker>> Shell::running_workers_; -std::vector<ExternalizedContents> Shell::externalized_contents_; std::atomic<bool> Shell::script_executed_{false}; base::LazyMutex Shell::isolate_status_lock_; std::map<v8::Isolate*, bool> Shell::isolate_status_; @@ -377,7 +389,7 @@ class BackgroundCompileThread : public base::Thread { BackgroundCompileThread(Isolate* isolate, Local<String> source) : base::Thread(GetThreadOptions("BackgroundCompileThread")), source_(source), - streamed_source_(base::make_unique<DummySourceStream>(source, isolate), + streamed_source_(std::make_unique<DummySourceStream>(source, isolate), v8::ScriptCompiler::StreamedSource::UTF8), task_(v8::ScriptCompiler::StartStreamingScript(isolate, &streamed_source_)) {} @@ -740,8 +752,60 @@ struct DynamicImportData { Global<Promise::Resolver> resolver; }; +struct ModuleResolutionData { + ModuleResolutionData(Isolate* isolate_, Local<Value> module_namespace_, + Local<Promise::Resolver> resolver_) + : isolate(isolate_) { + module_namespace.Reset(isolate, module_namespace_); + resolver.Reset(isolate, resolver_); + } + + Isolate* isolate; + Global<Value> module_namespace; + Global<Promise::Resolver> resolver; +}; + } // namespace +void Shell::ModuleResolutionSuccessCallback( + const FunctionCallbackInfo<Value>& info) { + std::unique_ptr<ModuleResolutionData> module_resolution_data( + static_cast<ModuleResolutionData*>( + info.Data().As<v8::External>()->Value())); + Isolate* isolate(module_resolution_data->isolate); + HandleScope handle_scope(isolate); + + Local<Promise::Resolver> resolver( + module_resolution_data->resolver.Get(isolate)); + Local<Value> module_namespace( + module_resolution_data->module_namespace.Get(isolate)); + + PerIsolateData* data = PerIsolateData::Get(isolate); + Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); + Context::Scope context_scope(realm); + + resolver->Resolve(realm, module_namespace).ToChecked(); +} + +void Shell::ModuleResolutionFailureCallback( + const FunctionCallbackInfo<Value>& info) { + std::unique_ptr<ModuleResolutionData> module_resolution_data( + static_cast<ModuleResolutionData*>( + info.Data().As<v8::External>()->Value())); + Isolate* isolate(module_resolution_data->isolate); + HandleScope handle_scope(isolate); + + Local<Promise::Resolver> resolver( + module_resolution_data->resolver.Get(isolate)); + + PerIsolateData* data = PerIsolateData::Get(isolate); + Local<Context> realm = data->realms_[data->realm_current_].Get(isolate); + Context::Scope context_scope(realm); + + DCHECK_EQ(info.Length(), 1); + resolver->Reject(realm, info[0]).ToChecked(); +} + MaybeLocal<Promise> Shell::HostImportModuleDynamically( Local<Context> context, Local<ScriptOrModule> referrer, Local<String> specifier) { @@ -829,19 +893,44 @@ void Shell::DoHostImportModuleDynamically(void* import_data) { if (root_module->InstantiateModule(realm, ResolveModuleCallback) .FromMaybe(false)) { maybe_result = root_module->Evaluate(realm); + CHECK_IMPLIES(i::FLAG_harmony_top_level_await, !maybe_result.IsEmpty()); EmptyMessageQueues(isolate); } - Local<Value> module; - if (!maybe_result.ToLocal(&module)) { + Local<Value> result; + if (!maybe_result.ToLocal(&result)) { DCHECK(try_catch.HasCaught()); resolver->Reject(realm, try_catch.Exception()).ToChecked(); return; } - DCHECK(!try_catch.HasCaught()); Local<Value> module_namespace = root_module->GetModuleNamespace(); - resolver->Resolve(realm, module_namespace).ToChecked(); + if (i::FLAG_harmony_top_level_await) { + Local<Promise> result_promise(Local<Promise>::Cast(result)); + if (result_promise->State() == Promise::kRejected) { + resolver->Reject(realm, result_promise->Result()).ToChecked(); + return; + } + + // Setup callbacks, and then chain them to the result promise. + // ModuleResolutionData will be deleted by the callbacks. + auto module_resolution_data = + new ModuleResolutionData(isolate, module_namespace, resolver); + Local<v8::External> edata = External::New(isolate, module_resolution_data); + Local<Function> callback_success; + CHECK(Function::New(realm, ModuleResolutionSuccessCallback, edata) + .ToLocal(&callback_success)); + Local<Function> callback_failure; + CHECK(Function::New(realm, ModuleResolutionFailureCallback, edata) + .ToLocal(&callback_failure)); + result_promise->Then(realm, callback_success, callback_failure) + .ToLocalChecked(); + } else { + // TODO(joshualitt): Clean up exception handling after introucing new + // API for evaluating async modules. + DCHECK(!try_catch.HasCaught()); + resolver->Resolve(realm, module_namespace).ToChecked(); + } } bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { @@ -857,7 +946,6 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { try_catch.SetVerbose(true); Local<Module> root_module; - MaybeLocal<Value> maybe_exception; if (!FetchModuleTree(realm, absolute_path).ToLocal(&root_module)) { CHECK(try_catch.HasCaught()); @@ -869,6 +957,7 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { if (root_module->InstantiateModule(realm, ResolveModuleCallback) .FromMaybe(false)) { maybe_result = root_module->Evaluate(realm); + CHECK_IMPLIES(i::FLAG_harmony_top_level_await, !maybe_result.IsEmpty()); EmptyMessageQueues(isolate); } Local<Value> result; @@ -878,6 +967,30 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) { ReportException(isolate, &try_catch); return false; } + if (i::FLAG_harmony_top_level_await) { + // Loop until module execution finishes + // TODO(joshualitt): This is a bit wonky. "Real" engines would not be + // able to just busy loop waiting for execution to finish. + Local<Promise> result_promise(Local<Promise>::Cast(result)); + while (result_promise->State() == Promise::kPending) { + isolate->RunMicrotasks(); + } + + if (result_promise->State() == Promise::kRejected) { + // If the exception has been caught by the promise pipeline, we rethrow + // here in order to ReportException. + // TODO(joshualitt): Clean this up after we create a new API for the case + // where TLA is enabled. + if (!try_catch.HasCaught()) { + isolate->ThrowException(result_promise->Result()); + } else { + DCHECK_EQ(try_catch.Exception(), result_promise->Result()); + } + ReportException(isolate, &try_catch); + return false; + } + } + DCHECK(!try_catch.HasCaught()); return true; } @@ -984,6 +1097,27 @@ void Shell::PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args) { } } +// performance.measureMemory() implements JavaScript Memory API proposal. +// See https://github.com/ulan/javascript-agent-memory/blob/master/explainer.md. +void Shell::PerformanceMeasureMemory( + const v8::FunctionCallbackInfo<v8::Value>& args) { + v8::MeasureMemoryMode mode = v8::MeasureMemoryMode::kSummary; + v8::Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); + if (args.Length() >= 1 && args[0]->IsObject()) { + Local<Object> object = args[0].As<Object>(); + Local<Value> value = TryGetValue(isolate, context, object, "detailed") + .FromMaybe(Local<Value>()); + if (!value.IsEmpty() && value->IsBoolean() && + value->BooleanValue(isolate)) { + mode = v8::MeasureMemoryMode::kDetailed; + } + } + v8::MaybeLocal<v8::Promise> result = + args.GetIsolate()->MeasureMemory(context, mode); + args.GetReturnValue().Set(result.FromMaybe(v8::Local<v8::Promise>())); +} + // Realm.current() returns the index of the currently active realm. void Shell::RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args) { Isolate* isolate = args.GetIsolate(); @@ -1820,6 +1954,10 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) { String::NewFromUtf8(isolate, "now", NewStringType::kNormal) .ToLocalChecked(), FunctionTemplate::New(isolate, PerformanceNow)); + performance_template->Set( + String::NewFromUtf8(isolate, "measureMemory", NewStringType::kNormal) + .ToLocalChecked(), + FunctionTemplate::New(isolate, PerformanceMeasureMemory)); global_template->Set( String::NewFromUtf8(isolate, "performance", NewStringType::kNormal) .ToLocalChecked(), @@ -2364,6 +2502,33 @@ class InspectorClient : public v8_inspector::V8InspectorClient { context_.Reset(isolate_, context); } + void runMessageLoopOnPause(int contextGroupId) override { + v8::Isolate::AllowJavascriptExecutionScope allow_script(isolate_); + v8::HandleScope handle_scope(isolate_); + Local<String> callback_name = + v8::String::NewFromUtf8(isolate_, "handleInspectorMessage", + v8::NewStringType::kNormal) + .ToLocalChecked(); + Local<Context> context = context_.Get(isolate_); + Local<Value> callback = + context->Global()->Get(context, callback_name).ToLocalChecked(); + if (!callback->IsFunction()) return; + + v8::TryCatch try_catch(isolate_); + is_paused = true; + + while (is_paused) { + USE(Local<Function>::Cast(callback)->Call(context, Undefined(isolate_), 0, + {})); + if (try_catch.HasCaught()) { + Shell::ReportException(isolate_, &try_catch); + is_paused = false; + } + } + } + + void quitMessageLoopOnPause() override { is_paused = false; } + private: static v8_inspector::V8InspectorSession* GetSession(Local<Context> context) { InspectorClient* inspector_client = static_cast<InspectorClient*>( @@ -2402,6 +2567,7 @@ class InspectorClient : public v8_inspector::V8InspectorClient { std::unique_ptr<v8_inspector::V8Inspector> inspector_; std::unique_ptr<v8_inspector::V8InspectorSession> session_; std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_; + bool is_paused = false; Global<Context> context_; Isolate* isolate_; }; @@ -2548,12 +2714,6 @@ void SourceGroup::JoinThread() { thread_->Join(); } -ExternalizedContents::~ExternalizedContents() { - if (data_ != nullptr) { - deleter_(data_, length_, deleter_data_); - } -} - void SerializationDataQueue::Enqueue(std::unique_ptr<SerializationData> data) { base::MutexGuard lock_guard(&mutex_); data_.push_back(std::move(data)); @@ -2841,9 +3001,6 @@ bool Shell::SetOptions(int argc, char* argv[]) { options.icu_locale = argv[i] + 13; argv[i] = nullptr; #ifdef V8_USE_EXTERNAL_STARTUP_DATA - } else if (strncmp(argv[i], "--natives_blob=", 15) == 0) { - options.natives_blob = argv[i] + 15; - argv[i] = nullptr; } else if (strncmp(argv[i], "--snapshot_blob=", 16) == 0) { options.snapshot_blob = argv[i] + 16; argv[i] = nullptr; @@ -3133,11 +3290,10 @@ class Serializer : public ValueSerializer::Delegate { std::unique_ptr<SerializationData> Release() { return std::move(data_); } - void AppendExternalizedContentsTo(std::vector<ExternalizedContents>* to) { - to->insert(to->end(), - std::make_move_iterator(externalized_contents_.begin()), - std::make_move_iterator(externalized_contents_.end())); - externalized_contents_.clear(); + void AppendBackingStoresTo(std::vector<std::shared_ptr<BackingStore>>* to) { + to->insert(to->end(), std::make_move_iterator(backing_stores_.begin()), + std::make_move_iterator(backing_stores_.end())); + backing_stores_.clear(); } protected: @@ -3157,8 +3313,8 @@ class Serializer : public ValueSerializer::Delegate { size_t index = shared_array_buffers_.size(); shared_array_buffers_.emplace_back(isolate_, shared_array_buffer); - data_->shared_array_buffer_contents_.push_back( - MaybeExternalize(shared_array_buffer)); + data_->sab_backing_stores_.push_back( + shared_array_buffer->GetBackingStore()); return Just<uint32_t>(static_cast<uint32_t>(index)); } @@ -3229,17 +3385,6 @@ class Serializer : public ValueSerializer::Delegate { } } - template <typename T> - typename T::Contents MaybeExternalize(Local<T> array_buffer) { - if (array_buffer->IsExternal()) { - return array_buffer->GetContents(); - } else { - typename T::Contents contents = array_buffer->Externalize(); - externalized_contents_.emplace_back(contents); - return contents; - } - } - Maybe<bool> FinalizeTransfer() { for (const auto& global_array_buffer : array_buffers_) { Local<ArrayBuffer> array_buffer = @@ -3249,9 +3394,12 @@ class Serializer : public ValueSerializer::Delegate { return Nothing<bool>(); } - ArrayBuffer::Contents contents = MaybeExternalize(array_buffer); + auto backing_store = array_buffer->GetBackingStore(); + if (!array_buffer->IsExternal()) { + array_buffer->Externalize(backing_store); + } + data_->backing_stores_.push_back(std::move(backing_store)); array_buffer->Detach(); - data_->array_buffer_contents_.push_back(contents); } return Just(true); @@ -3263,7 +3411,7 @@ class Serializer : public ValueSerializer::Delegate { std::vector<Global<ArrayBuffer>> array_buffers_; std::vector<Global<SharedArrayBuffer>> shared_array_buffers_; std::vector<Global<WasmModuleObject>> wasm_modules_; - std::vector<ExternalizedContents> externalized_contents_; + std::vector<std::shared_ptr<v8::BackingStore>> backing_stores_; size_t current_memory_usage_; DISALLOW_COPY_AND_ASSIGN(Serializer); @@ -3285,9 +3433,9 @@ class Deserializer : public ValueDeserializer::Delegate { } uint32_t index = 0; - for (const auto& contents : data_->array_buffer_contents()) { + for (const auto& backing_store : data_->backing_stores()) { Local<ArrayBuffer> array_buffer = - ArrayBuffer::New(isolate_, contents.Data(), contents.ByteLength()); + ArrayBuffer::New(isolate_, std::move(backing_store)); deserializer_.TransferArrayBuffer(index++, array_buffer); } @@ -3297,11 +3445,9 @@ class Deserializer : public ValueDeserializer::Delegate { MaybeLocal<SharedArrayBuffer> GetSharedArrayBufferFromId( Isolate* isolate, uint32_t clone_id) override { DCHECK_NOT_NULL(data_); - if (clone_id < data_->shared_array_buffer_contents().size()) { - const SharedArrayBuffer::Contents contents = - data_->shared_array_buffer_contents().at(clone_id); - return SharedArrayBuffer::New(isolate_, contents.Data(), - contents.ByteLength()); + if (clone_id < data_->sab_backing_stores().size()) { + return SharedArrayBuffer::New( + isolate_, std::move(data_->sab_backing_stores().at(clone_id))); } return MaybeLocal<SharedArrayBuffer>(); } @@ -3333,9 +3479,6 @@ std::unique_ptr<SerializationData> Shell::SerializeValue( if (serializer.WriteValue(context, value, transfer).To(&ok)) { data = serializer.Release(); } - // Append externalized contents even when WriteValue fails. - base::MutexGuard lock_guard(workers_mutex_.Pointer()); - serializer.AppendExternalizedContentsTo(&externalized_contents_); return data; } @@ -3377,7 +3520,6 @@ void Shell::WaitForRunningWorkers() { base::MutexGuard lock_guard(workers_mutex_.Pointer()); DCHECK(running_workers_.empty()); allow_new_workers_ = true; - externalized_contents_.clear(); } int Shell::Main(int argc, char* argv[]) { @@ -3402,7 +3544,7 @@ int Shell::Main(int argc, char* argv[]) { std::unique_ptr<platform::tracing::TracingController> tracing; std::ofstream trace_file; if (options.trace_enabled && !i::FLAG_verify_predictable) { - tracing = base::make_unique<platform::tracing::TracingController>(); + tracing = std::make_unique<platform::tracing::TracingController>(); trace_file.open(options.trace_path ? options.trace_path : "v8_trace.json"); DCHECK(trace_file.good()); @@ -3447,9 +3589,8 @@ int Shell::Main(int argc, char* argv[]) { } v8::V8::InitializePlatform(g_platform.get()); v8::V8::Initialize(); - if (options.natives_blob || options.snapshot_blob) { - v8::V8::InitializeExternalStartupData(options.natives_blob, - options.snapshot_blob); + if (options.snapshot_blob) { + v8::V8::InitializeExternalStartupDataFromFile(options.snapshot_blob); } else { v8::V8::InitializeExternalStartupData(argv[0]); } @@ -3626,3 +3767,4 @@ int main(int argc, char* argv[]) { return v8::Shell::Main(argc, argv); } #undef CHECK #undef DCHECK +#undef TRACE_BS diff --git a/deps/v8/src/d8/d8.h b/deps/v8/src/d8/d8.h index 04fc5f5d341919..58bfbcb3b91b5b 100644 --- a/deps/v8/src/d8/d8.h +++ b/deps/v8/src/d8/d8.h @@ -111,66 +111,17 @@ class SourceGroup { int end_offset_; }; -// The backing store of an ArrayBuffer or SharedArrayBuffer, after -// Externalize() has been called on it. -class ExternalizedContents { - public: - explicit ExternalizedContents(const ArrayBuffer::Contents& contents) - : data_(contents.Data()), - length_(contents.ByteLength()), - deleter_(contents.Deleter()), - deleter_data_(contents.DeleterData()) {} - explicit ExternalizedContents(const SharedArrayBuffer::Contents& contents) - : data_(contents.Data()), - length_(contents.ByteLength()), - deleter_(contents.Deleter()), - deleter_data_(contents.DeleterData()) {} - ExternalizedContents(ExternalizedContents&& other) V8_NOEXCEPT - : data_(other.data_), - length_(other.length_), - deleter_(other.deleter_), - deleter_data_(other.deleter_data_) { - other.data_ = nullptr; - other.length_ = 0; - other.deleter_ = nullptr; - other.deleter_data_ = nullptr; - } - ExternalizedContents& operator=(ExternalizedContents&& other) V8_NOEXCEPT { - if (this != &other) { - data_ = other.data_; - length_ = other.length_; - deleter_ = other.deleter_; - deleter_data_ = other.deleter_data_; - other.data_ = nullptr; - other.length_ = 0; - other.deleter_ = nullptr; - other.deleter_data_ = nullptr; - } - return *this; - } - ~ExternalizedContents(); - - private: - void* data_; - size_t length_; - ArrayBuffer::Contents::DeleterCallback deleter_; - void* deleter_data_; - - DISALLOW_COPY_AND_ASSIGN(ExternalizedContents); -}; - class SerializationData { public: SerializationData() : size_(0) {} uint8_t* data() { return data_.get(); } size_t size() { return size_; } - const std::vector<ArrayBuffer::Contents>& array_buffer_contents() { - return array_buffer_contents_; + const std::vector<std::shared_ptr<v8::BackingStore>>& backing_stores() { + return backing_stores_; } - const std::vector<SharedArrayBuffer::Contents>& - shared_array_buffer_contents() { - return shared_array_buffer_contents_; + const std::vector<std::shared_ptr<v8::BackingStore>>& sab_backing_stores() { + return sab_backing_stores_; } const std::vector<WasmModuleObject::TransferrableModule>& transferrable_modules() { @@ -184,8 +135,8 @@ class SerializationData { std::unique_ptr<uint8_t, DataDeleter> data_; size_t size_; - std::vector<ArrayBuffer::Contents> array_buffer_contents_; - std::vector<SharedArrayBuffer::Contents> shared_array_buffer_contents_; + std::vector<std::shared_ptr<v8::BackingStore>> backing_stores_; + std::vector<std::shared_ptr<v8::BackingStore>> sab_backing_stores_; std::vector<WasmModuleObject::TransferrableModule> transferrable_modules_; private: @@ -334,7 +285,6 @@ class ShellOptions { SourceGroup* isolate_sources = nullptr; const char* icu_data_file = nullptr; const char* icu_locale = nullptr; - const char* natives_blob = nullptr; const char* snapshot_blob = nullptr; bool trace_enabled = false; const char* trace_path = nullptr; @@ -389,6 +339,8 @@ class Shell : public i::AllStatic { static void MapCounters(v8::Isolate* isolate, const char* name); static void PerformanceNow(const v8::FunctionCallbackInfo<v8::Value>& args); + static void PerformanceMeasureMemory( + const v8::FunctionCallbackInfo<v8::Value>& args); static void RealmCurrent(const v8::FunctionCallbackInfo<v8::Value>& args); static void RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args); @@ -473,6 +425,10 @@ class Shell : public i::AllStatic { static MaybeLocal<Promise> HostImportModuleDynamically( Local<Context> context, Local<ScriptOrModule> referrer, Local<String> specifier); + static void ModuleResolutionSuccessCallback( + const v8::FunctionCallbackInfo<v8::Value>& info); + static void ModuleResolutionFailureCallback( + const v8::FunctionCallbackInfo<v8::Value>& info); static void HostInitializeImportMetaObject(Local<Context> context, Local<Module> module, Local<Object> meta); @@ -519,7 +475,6 @@ class Shell : public i::AllStatic { static base::LazyMutex workers_mutex_; // Guards the following members. static bool allow_new_workers_; static std::unordered_set<std::shared_ptr<Worker>> running_workers_; - static std::vector<ExternalizedContents> externalized_contents_; // Multiple isolates may update this flag concurrently. static std::atomic<bool> script_executed_; diff --git a/deps/v8/src/debug/debug-coverage.cc b/deps/v8/src/debug/debug-coverage.cc index cb466ab6ab7596..5f368683f25f74 100644 --- a/deps/v8/src/debug/debug-coverage.cc +++ b/deps/v8/src/debug/debug-coverage.cc @@ -577,11 +577,15 @@ struct SharedFunctionInfoAndCount { // Sort by: // - start, ascending. // - end, descending. - // - count, ascending. + // - info.is_toplevel() first + // - count, descending. bool operator<(const SharedFunctionInfoAndCount& that) const { if (this->start != that.start) return this->start < that.start; if (this->end != that.end) return this->end > that.end; - return this->count < that.count; + if (this->info.is_toplevel() != that.info.is_toplevel()) { + return this->info.is_toplevel(); + } + return this->count > that.count; } SharedFunctionInfo info; @@ -653,12 +657,30 @@ std::unique_ptr<Coverage> Coverage::Collect( // Find the correct outer function based on start position. // - // This is not robust when considering two functions with identical source - // ranges. In this case, it is unclear which function is the inner / outer - // function. Above, we ensure that such functions are sorted in ascending - // `count` order, so at least our `parent_is_covered` optimization below - // should be fine. - // TODO(jgruber): Consider removing the optimization. + // This is, in general, not robust when considering two functions with + // identical source ranges; then the notion of inner and outer is unclear. + // Identical source ranges arise when the source range of top-most entity + // (e.g. function) in the script is identical to the whole script, e.g. + // <script>function foo() {}<script>. The script has its own shared + // function info, which has the same source range as the SFI for `foo`. + // Node.js creates an additional wrapper for scripts (again with identical + // source range) and those wrappers will have a call count of zero even if + // the wrapped script was executed (see v8:9212). We mitigate this issue + // by sorting top-level SFIs first among SFIs with the same source range: + // This ensures top-level SFIs are processed first. If a top-level SFI has + // a non-zero call count, it gets recorded due to `function_is_relevant` + // below (e.g. script wrappers), while top-level SFIs with zero call count + // do not get reported (this ensures node's extra wrappers do not get + // reported). If two SFIs with identical source ranges get reported, we + // report them in decreasing order of call count, as in all known cases + // this corresponds to the nesting order. In the case of the script tag + // example above, we report the zero call count of `foo` last. As it turns + // out, embedders started to rely on functions being reported in nesting + // order. + // TODO(jgruber): Investigate whether it is possible to remove node's + // extra top-level wrapper script, or change its source range, or ensure + // that it follows the invariant that nesting order is descending count + // order for SFIs with identical source ranges. while (!nesting.empty() && functions->at(nesting.back()).end <= start) { nesting.pop_back(); } diff --git a/deps/v8/src/debug/debug-coverage.h b/deps/v8/src/debug/debug-coverage.h index 9c1f0bcc2c4076..81b178181a62c6 100644 --- a/deps/v8/src/debug/debug-coverage.h +++ b/deps/v8/src/debug/debug-coverage.h @@ -5,6 +5,7 @@ #ifndef V8_DEBUG_DEBUG_COVERAGE_H_ #define V8_DEBUG_DEBUG_COVERAGE_H_ +#include <memory> #include <vector> #include "src/debug/debug-interface.h" diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc index 203885143fa1c8..3568860e7d253a 100644 --- a/deps/v8/src/debug/debug-evaluate.cc +++ b/deps/v8/src/debug/debug-evaluate.cc @@ -23,9 +23,13 @@ namespace internal { MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, Handle<String> source, - bool throw_on_side_effect) { + debug::EvaluateGlobalMode mode) { // Disable breaks in side-effect free mode. - DisableBreak disable_break_scope(isolate->debug(), throw_on_side_effect); + DisableBreak disable_break_scope( + isolate->debug(), + mode == debug::EvaluateGlobalMode::kDisableBreaks || + mode == + debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect); Handle<Context> context = isolate->native_context(); ScriptOriginOptions origin_options(false, true); @@ -42,11 +46,15 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, Handle<JSFunction> fun = isolate->factory()->NewFunctionFromSharedFunctionInfo(shared_info, context); - if (throw_on_side_effect) isolate->debug()->StartSideEffectCheckMode(); + if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { + isolate->debug()->StartSideEffectCheckMode(); + } MaybeHandle<Object> result = Execution::Call( isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0, nullptr); - if (throw_on_side_effect) isolate->debug()->StopSideEffectCheckMode(); + if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { + isolate->debug()->StopSideEffectCheckMode(); + } return result; } @@ -174,31 +182,31 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, // - To make stack-allocated variables visible, we materialize them and // use a debug-evaluate context to wrap both the materialized object and // the original context. - // - We use the original context chain from the function context to the - // native context. + // - We also wrap all contexts on the chain between the original context + // and the function context. // - Between the function scope and the native context, we only resolve - // variable names that the current function already uses. Only for these - // names we can be sure that they will be correctly resolved. For the - // rest, we only resolve to with, script, and native contexts. We use a - // whitelist to implement that. + // variable names that are guaranteed to not be shadowed by stack-allocated + // variables. Contexts between the function context and the original + // context have a blacklist attached to implement that. // Context::Lookup has special handling for debug-evaluate contexts: // - Look up in the materialized stack variables. + // - Check the blacklist to find out whether to abort further lookup. // - Look up in the original context. - // - Check the whitelist to find out whether to skip contexts during lookup. - for (; scope_iterator_.InInnerScope(); scope_iterator_.Next()) { + for (; !scope_iterator_.Done(); scope_iterator_.Next()) { ScopeIterator::ScopeType scope_type = scope_iterator_.Type(); if (scope_type == ScopeIterator::ScopeTypeScript) break; ContextChainElement context_chain_element; - if (scope_type == ScopeIterator::ScopeTypeLocal || - scope_iterator_.DeclaresLocals(ScopeIterator::Mode::STACK)) { + if (scope_iterator_.InInnerScope() && + (scope_type == ScopeIterator::ScopeTypeLocal || + scope_iterator_.DeclaresLocals(ScopeIterator::Mode::STACK))) { context_chain_element.materialized_object = scope_iterator_.ScopeObject(ScopeIterator::Mode::STACK); } if (scope_iterator_.HasContext()) { context_chain_element.wrapped_context = scope_iterator_.CurrentContext(); } - if (scope_type == ScopeIterator::ScopeTypeLocal) { - context_chain_element.whitelist = scope_iterator_.GetNonLocals(); + if (!scope_iterator_.InInnerScope()) { + context_chain_element.blacklist = scope_iterator_.GetLocals(); } context_chain_.push_back(context_chain_element); } @@ -214,7 +222,7 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, scope_info->SetIsDebugEvaluateScope(); evaluation_context_ = factory->NewDebugEvaluateContext( evaluation_context_, scope_info, element.materialized_object, - element.wrapped_context, element.whitelist); + element.wrapped_context, element.blacklist); } } diff --git a/deps/v8/src/debug/debug-evaluate.h b/deps/v8/src/debug/debug-evaluate.h index 7819892050261e..b04bd76e22f547 100644 --- a/deps/v8/src/debug/debug-evaluate.h +++ b/deps/v8/src/debug/debug-evaluate.h @@ -24,7 +24,7 @@ class FrameInspector; class DebugEvaluate : public AllStatic { public: static MaybeHandle<Object> Global(Isolate* isolate, Handle<String> source, - bool throw_on_side_effect); + debug::EvaluateGlobalMode mode); // Evaluate a piece of JavaScript in the context of a stack frame for // debugging. Things that need special attention are: @@ -83,7 +83,7 @@ class DebugEvaluate : public AllStatic { struct ContextChainElement { Handle<Context> wrapped_context; Handle<JSObject> materialized_object; - Handle<StringSet> whitelist; + Handle<StringSet> blacklist; }; Handle<Context> evaluation_context_; diff --git a/deps/v8/src/debug/debug-frames.cc b/deps/v8/src/debug/debug-frames.cc index 78c4c323fcdfdb..19178d34ce02c8 100644 --- a/deps/v8/src/debug/debug-frames.cc +++ b/deps/v8/src/debug/debug-frames.cc @@ -70,7 +70,7 @@ int FrameInspector::GetParametersCount() { Handle<Object> FrameInspector::GetParameter(int index) { if (is_optimized_) return deoptimized_frame_->GetParameter(index); - // TODO(clemensh): Handle wasm_interpreted_frame_. + // TODO(clemensb): Handle wasm_interpreted_frame_. return handle(frame_->GetParameter(index), isolate_); } @@ -93,8 +93,10 @@ bool FrameInspector::ParameterIsShadowedByContextLocal( VariableMode mode; InitializationFlag init_flag; MaybeAssignedFlag maybe_assigned_flag; + IsStaticFlag is_static_flag; return ScopeInfo::ContextSlotIndex(*info, *parameter_name, &mode, &init_flag, - &maybe_assigned_flag) != -1; + &maybe_assigned_flag, + &is_static_flag) != -1; } RedirectActiveFunctions::RedirectActiveFunctions(SharedFunctionInfo shared, diff --git a/deps/v8/src/debug/debug-frames.h b/deps/v8/src/debug/debug-frames.h index 274d10030af516..78248614e20170 100644 --- a/deps/v8/src/debug/debug-frames.h +++ b/deps/v8/src/debug/debug-frames.h @@ -5,6 +5,8 @@ #ifndef V8_DEBUG_DEBUG_FRAMES_H_ #define V8_DEBUG_DEBUG_FRAMES_H_ +#include <memory> + #include "src/deoptimizer/deoptimizer.h" #include "src/execution/isolate.h" #include "src/execution/v8threads.h" diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h index 59bc6d08632e75..5f10e2a55a1f7c 100644 --- a/deps/v8/src/debug/debug-interface.h +++ b/deps/v8/src/debug/debug-interface.h @@ -5,6 +5,8 @@ #ifndef V8_DEBUG_DEBUG_INTERFACE_H_ #define V8_DEBUG_DEBUG_INTERFACE_H_ +#include <memory> + #include "include/v8-inspector.h" #include "include/v8-util.h" #include "include/v8.h" @@ -157,6 +159,7 @@ class WasmScript : public Script { int NumFunctions() const; int NumImportedFunctions() const; + MemorySpan<const uint8_t> Bytecode() const; std::pair<int, int> GetFunctionRange(int function_index) const; @@ -468,9 +471,15 @@ enum class NativeAccessorType { int64_t GetNextRandomInt64(v8::Isolate* isolate); +enum class EvaluateGlobalMode { + kDefault, + kDisableBreaks, + kDisableBreaksAndThrowOnSideEffect +}; + V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Value> EvaluateGlobal( v8::Isolate* isolate, v8::Local<v8::String> source, - bool throw_on_side_effect); + EvaluateGlobalMode mode); int GetDebuggingId(v8::Local<v8::Function> function); diff --git a/deps/v8/src/debug/debug-scopes.cc b/deps/v8/src/debug/debug-scopes.cc index 4569780d00105f..512b85fb096d73 100644 --- a/deps/v8/src/debug/debug-scopes.cc +++ b/deps/v8/src/debug/debug-scopes.cc @@ -84,6 +84,117 @@ void ScopeIterator::Restart() { UnwrapEvaluationContext(); } +namespace { + +// Takes the scope of a parsed script, a function and a break location +// inside the function. The result is the innermost lexical scope around +// the break point, which serves as the starting point of the ScopeIterator. +// And the scope of the function that was passed in (called closure scope). +// +// The start scope is guaranteed to be either the closure scope itself, +// or a child of the closure scope. +class ScopeChainRetriever { + public: + ScopeChainRetriever(DeclarationScope* scope, Handle<JSFunction> function, + int position) + : scope_(scope), + break_scope_start_(function->shared().StartPosition()), + break_scope_end_(function->shared().EndPosition()), + is_default_constructor_( + IsDefaultConstructor(function->shared().kind())), + position_(position) { + DCHECK_NOT_NULL(scope); + RetrieveScopes(); + } + + DeclarationScope* ClosureScope() { return closure_scope_; } + Scope* StartScope() { return start_scope_; } + + private: + DeclarationScope* scope_; + const int break_scope_start_; + const int break_scope_end_; + const bool is_default_constructor_; + const int position_; + + DeclarationScope* closure_scope_ = nullptr; + Scope* start_scope_ = nullptr; + + void RetrieveScopes() { + if (is_default_constructor_) { + // Even though the DefaultBaseConstructor is a child of a Class scope, the + // source positions are *not* nested. This means the actual scope for the + // DefaultBaseConstructor needs to be found by doing a DFS. + RetrieveScopeChainDefaultConstructor(scope_); + } else { + RetrieveScopeChain(); + } + DCHECK_NOT_NULL(closure_scope_); + DCHECK_NOT_NULL(start_scope_); + } + + bool RetrieveScopeChainDefaultConstructor(Scope* scope) { + const int beg_pos = scope->start_position(); + const int end_pos = scope->end_position(); + if (beg_pos == position_ && end_pos == position_) { + DCHECK(scope->is_function_scope()); + DCHECK( + IsDefaultConstructor(scope->AsDeclarationScope()->function_kind())); + start_scope_ = scope; + closure_scope_ = scope->AsDeclarationScope(); + return true; + } + + for (Scope* inner_scope = scope->inner_scope(); inner_scope != nullptr; + inner_scope = inner_scope->sibling()) { + if (RetrieveScopeChainDefaultConstructor(inner_scope)) return true; + } + return false; + } + + void RetrieveScopeChain() { + Scope* parent = nullptr; + Scope* current = scope_; + SetClosureScopeIfFound(current); + + while (parent != current) { + parent = current; + for (Scope* inner_scope = current->inner_scope(); inner_scope != nullptr; + inner_scope = inner_scope->sibling()) { + if (SetClosureScopeIfFound(inner_scope) || + ContainsPosition(inner_scope)) { + current = inner_scope; + break; + } + } + } + start_scope_ = current; + } + + bool SetClosureScopeIfFound(Scope* scope) { + const int start = scope->start_position(); + const int end = scope->end_position(); + if (start == break_scope_start_ && end == break_scope_end_) { + closure_scope_ = scope->AsDeclarationScope(); + return true; + } + return false; + } + + bool ContainsPosition(Scope* scope) { + const int start = scope->start_position(); + const int end = scope->end_position(); + // In case the closure_scope_ hasn't been found yet, we are less strict + // about recursing downwards. This might be the case for nested arrow + // functions that have the same end position. + const bool position_fits_end = + closure_scope_ ? position_ < end : position_ <= end; + return start < position_ && position_fits_end; + } +}; + +} // namespace + void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) { // Catch the case when the debugger stops in an internal function. Handle<SharedFunctionInfo> shared_info(function_->shared(), isolate_); @@ -105,7 +216,6 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) { return; } - DCHECK_NE(IGNORE_NESTED_SCOPES, option); bool ignore_nested_scopes = false; if (shared_info->HasBreakInfo() && frame_inspector_ != nullptr) { // The source position at return is always the end of the function, @@ -123,44 +233,39 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) { } // Reparse the code and analyze the scopes. - // Check whether we are in global, eval or function code. - if (scope_info->scope_type() == FUNCTION_SCOPE) { - // Inner function. - info_ = new ParseInfo(isolate_, shared_info); - } else { - // Global or eval code. - Handle<Script> script(Script::cast(shared_info->script()), isolate_); - info_ = new ParseInfo(isolate_, script); - if (scope_info->scope_type() == EVAL_SCOPE) { - info_->set_eval(); - if (!context_->IsNativeContext()) { - info_->set_outer_scope_info(handle(context_->scope_info(), isolate_)); - } - // Language mode may be inherited from the eval caller. - // Retrieve it from shared function info. - info_->set_language_mode(shared_info->language_mode()); - } else if (scope_info->scope_type() == MODULE_SCOPE) { - DCHECK(info_->is_module()); - } else { - DCHECK_EQ(SCRIPT_SCOPE, scope_info->scope_type()); + Handle<Script> script(Script::cast(shared_info->script()), isolate_); + info_ = new ParseInfo(isolate_, script); + info_->set_eager(); + if (scope_info->scope_type() == EVAL_SCOPE || script->is_wrapped()) { + info_->set_eval(); + if (!context_->IsNativeContext()) { + info_->set_outer_scope_info(handle(context_->scope_info(), isolate_)); } + // Language mode may be inherited from the eval caller. + // Retrieve it from shared function info. + info_->set_language_mode(shared_info->language_mode()); + } else if (scope_info->scope_type() == MODULE_SCOPE) { + DCHECK(info_->is_module()); + } else { + DCHECK(scope_info->scope_type() == SCRIPT_SCOPE || + scope_info->scope_type() == FUNCTION_SCOPE); } if (parsing::ParseAny(info_, shared_info, isolate_) && Rewriter::Rewrite(info_)) { info_->ast_value_factory()->Internalize(isolate_); - closure_scope_ = info_->literal()->scope(); + DeclarationScope* literal_scope = info_->literal()->scope(); - if (option == COLLECT_NON_LOCALS) { - DCHECK(non_locals_.is_null()); - non_locals_ = info_->literal()->scope()->CollectNonLocals( - isolate_, info_, StringSet::New(isolate_)); - if (!closure_scope_->has_this_declaration() && - closure_scope_->HasThisReference()) { - non_locals_ = StringSet::Add(isolate_, non_locals_, - isolate_->factory()->this_string()); - } - } + ScopeChainRetriever scope_chain_retriever(literal_scope, function_, + GetSourcePosition()); + start_scope_ = scope_chain_retriever.StartScope(); + current_scope_ = start_scope_; + + // In case of a FUNCTION_SCOPE, the ScopeIterator expects + // {closure_scope_} to be set to the scope of the function. + closure_scope_ = scope_info->scope_type() == FUNCTION_SCOPE + ? scope_chain_retriever.ClosureScope() + : literal_scope; CHECK(DeclarationScope::Analyze(info_)); if (ignore_nested_scopes) { @@ -169,9 +274,8 @@ void ScopeIterator::TryParseAndRetrieveScopes(ScopeIterator::Option option) { if (closure_scope_->NeedsContext()) { context_ = handle(context_->closure_context(), isolate_); } - } else { - RetrieveScopeChain(closure_scope_); } + UnwrapEvaluationContext(); } else { // A failed reparse indicates that the preparser has diverged from the @@ -260,6 +364,38 @@ bool ScopeIterator::HasContext() const { return !InInnerScope() || current_scope_->NeedsContext(); } +void ScopeIterator::AdvanceOneScope() { + if (current_scope_->NeedsContext()) { + DCHECK(!context_->previous().is_null()); + context_ = handle(context_->previous(), isolate_); + } + DCHECK(current_scope_->outer_scope() != nullptr); + current_scope_ = current_scope_->outer_scope(); +} + +void ScopeIterator::AdvanceToNonHiddenScope() { + do { + AdvanceOneScope(); + } while (current_scope_->is_hidden()); +} + +void ScopeIterator::AdvanceContext() { + DCHECK(!context_->IsNativeContext()); + context_ = handle(context_->previous(), isolate_); + + // While advancing one context, we need to advance at least one + // scope, but until we hit the next scope that actually requires + // a context. All the locals collected along the way build the + // blacklist for debug-evaluate for this context. + locals_ = StringSet::New(isolate_); + do { + if (!current_scope_ || !current_scope_->outer_scope()) break; + + current_scope_ = current_scope_->outer_scope(); + CollectLocalsFromCurrentScope(); + } while (!current_scope_->NeedsContext()); +} + void ScopeIterator::Next() { DCHECK(!Done()); @@ -283,19 +419,17 @@ void ScopeIterator::Next() { context_ = handle(context_->previous(), isolate_); } } else if (!inner) { - DCHECK(!context_->IsNativeContext()); - context_ = handle(context_->previous(), isolate_); + AdvanceContext(); } else { DCHECK_NOT_NULL(current_scope_); - do { - if (current_scope_->NeedsContext()) { - DCHECK(!context_->previous().is_null()); - context_ = handle(context_->previous(), isolate_); - } - DCHECK_IMPLIES(InInnerScope(), current_scope_->outer_scope() != nullptr); - current_scope_ = current_scope_->outer_scope(); - // Repeat to skip hidden scopes. - } while (current_scope_->is_hidden()); + AdvanceToNonHiddenScope(); + + if (!InInnerScope() && current_scope_ != closure_scope_) { + // Edge case when we just go past {closure_scope_}. This case + // already needs to start collecting locals for the blacklist. + locals_ = StringSet::New(isolate_); + CollectLocalsFromCurrentScope(); + } } UnwrapEvaluationContext(); @@ -453,7 +587,20 @@ bool ScopeIterator::SetVariableValue(Handle<String> name, return false; } -Handle<StringSet> ScopeIterator::GetNonLocals() { return non_locals_; } +bool ScopeIterator::ClosureScopeHasThisReference() const { + return !closure_scope_->has_this_declaration() && + closure_scope_->HasThisReference(); +} + +void ScopeIterator::CollectLocalsFromCurrentScope() { + DCHECK(locals_->IsStringSet()); + for (Variable* var : *current_scope_->locals()) { + if (var->location() == VariableLocation::PARAMETER || + var->location() == VariableLocation::LOCAL) { + locals_ = StringSet::Add(isolate_, locals_, var->name()); + } + } +} #ifdef DEBUG // Debug print of the content of the current scope. @@ -524,31 +671,6 @@ int ScopeIterator::GetSourcePosition() { } } -void ScopeIterator::RetrieveScopeChain(DeclarationScope* scope) { - DCHECK_NOT_NULL(scope); - - const int position = GetSourcePosition(); - - Scope* parent = nullptr; - Scope* current = scope; - while (parent != current) { - parent = current; - for (Scope* inner_scope = current->inner_scope(); inner_scope != nullptr; - inner_scope = inner_scope->sibling()) { - int beg_pos = inner_scope->start_position(); - int end_pos = inner_scope->end_position(); - DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); - if (beg_pos < position && position < end_pos) { - current = inner_scope; - break; - } - } - } - - start_scope_ = current; - current_scope_ = current; -} - void ScopeIterator::VisitScriptScope(const Visitor& visitor) const { Handle<JSGlobalObject> global(context_->global_object(), isolate_); Handle<ScriptContextTable> script_contexts( @@ -884,9 +1006,10 @@ bool ScopeIterator::SetContextVariableValue(Handle<String> variable_name, VariableMode mode; InitializationFlag flag; MaybeAssignedFlag maybe_assigned_flag; + IsStaticFlag is_static_flag; int slot_index = ScopeInfo::ContextSlotIndex(context_->scope_info(), *variable_name, &mode, - &flag, &maybe_assigned_flag); + &flag, &maybe_assigned_flag, &is_static_flag); if (slot_index < 0) return false; context_->set(slot_index, *new_value); diff --git a/deps/v8/src/debug/debug-scopes.h b/deps/v8/src/debug/debug-scopes.h index 5c3361619a2839..29d84ed6406327 100644 --- a/deps/v8/src/debug/debug-scopes.h +++ b/deps/v8/src/debug/debug-scopes.h @@ -41,7 +41,7 @@ class ScopeIterator { static const int kScopeDetailsFunctionIndex = 5; static const int kScopeDetailsSize = 6; - enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS }; + enum Option { DEFAULT, COLLECT_NON_LOCALS }; ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, Option options = DEFAULT); @@ -77,8 +77,10 @@ class ScopeIterator { // Set variable value and return true on success. bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value); + bool ClosureScopeHasThisReference() const; + // Populate the set with collected non-local variable names. - Handle<StringSet> GetNonLocals(); + Handle<StringSet> GetLocals() { return locals_; } // Similar to JSFunction::GetName return the function's name or it's inferred // name. @@ -110,7 +112,7 @@ class ScopeIterator { Handle<JSFunction> function_; Handle<Context> context_; Handle<Script> script_; - Handle<StringSet> non_locals_; + Handle<StringSet> locals_; DeclarationScope* closure_scope_ = nullptr; Scope* start_scope_ = nullptr; Scope* current_scope_ = nullptr; @@ -120,12 +122,15 @@ class ScopeIterator { return frame_inspector_->javascript_frame(); } + void AdvanceOneScope(); + void AdvanceToNonHiddenScope(); + void AdvanceContext(); + void CollectLocalsFromCurrentScope(); + int GetSourcePosition(); void TryParseAndRetrieveScopes(ScopeIterator::Option option); - void RetrieveScopeChain(DeclarationScope* scope); - void UnwrapEvaluationContext(); using Visitor = diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.cc b/deps/v8/src/debug/debug-stack-trace-iterator.cc index 4f691e63a22666..12f492dbd2f286 100644 --- a/deps/v8/src/debug/debug-stack-trace-iterator.cc +++ b/deps/v8/src/debug/debug-stack-trace-iterator.cc @@ -87,25 +87,26 @@ v8::MaybeLocal<v8::Value> DebugStackTraceIterator::GetReceiver() const { // Arrow function defined in top level function without references to // variables may have NativeContext as context. if (!context->IsFunctionContext()) return v8::MaybeLocal<v8::Value>(); - ScopeIterator scope_iterator(isolate_, frame_inspector_.get(), - ScopeIterator::COLLECT_NON_LOCALS); + ScopeIterator scope_iterator(isolate_, frame_inspector_.get()); // We lookup this variable in function context only when it is used in arrow // function otherwise V8 can optimize it out. - if (!scope_iterator.GetNonLocals()->Has(isolate_, - isolate_->factory()->this_string())) + if (!scope_iterator.ClosureScopeHasThisReference()) { return v8::MaybeLocal<v8::Value>(); + } DisallowHeapAllocation no_gc; VariableMode mode; InitializationFlag flag; MaybeAssignedFlag maybe_assigned_flag; + IsStaticFlag is_static_flag; int slot_index = ScopeInfo::ContextSlotIndex( context->scope_info(), ReadOnlyRoots(isolate_->heap()).this_string(), - &mode, &flag, &maybe_assigned_flag); + &mode, &flag, &maybe_assigned_flag, &is_static_flag); if (slot_index < 0) return v8::MaybeLocal<v8::Value>(); Handle<Object> value = handle(context->get(slot_index), isolate_); if (value->IsTheHole(isolate_)) return v8::MaybeLocal<v8::Value>(); return Utils::ToLocal(value); } + Handle<Object> value = frame_inspector_->GetReceiver(); if (value.is_null() || (value->IsSmi() || !value->IsTheHole(isolate_))) { return Utils::ToLocal(value); diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.h b/deps/v8/src/debug/debug-stack-trace-iterator.h index 15b8a85c5e8b0b..3319bc15f50ade 100644 --- a/deps/v8/src/debug/debug-stack-trace-iterator.h +++ b/deps/v8/src/debug/debug-stack-trace-iterator.h @@ -5,6 +5,8 @@ #ifndef V8_DEBUG_DEBUG_STACK_TRACE_ITERATOR_H_ #define V8_DEBUG_DEBUG_STACK_TRACE_ITERATOR_H_ +#include <memory> + #include "src/debug/debug-frames.h" #include "src/debug/debug-interface.h" #include "src/execution/frames.h" diff --git a/deps/v8/src/debug/debug-type-profile.h b/deps/v8/src/debug/debug-type-profile.h index 16f739e4536d3f..f06af0c4713a0f 100644 --- a/deps/v8/src/debug/debug-type-profile.h +++ b/deps/v8/src/debug/debug-type-profile.h @@ -5,6 +5,7 @@ #ifndef V8_DEBUG_DEBUG_TYPE_PROFILE_H_ #define V8_DEBUG_DEBUG_TYPE_PROFILE_H_ +#include <memory> #include <vector> #include "src/debug/debug-interface.h" diff --git a/deps/v8/src/debug/debug.cc b/deps/v8/src/debug/debug.cc index aa308150acb48c..27f30d8c058960 100644 --- a/deps/v8/src/debug/debug.cc +++ b/deps/v8/src/debug/debug.cc @@ -622,9 +622,7 @@ bool Debug::SetBreakPointForScript(Handle<Script> script, Handle<BreakPoint> break_point = isolate_->factory()->NewBreakPoint(*id, condition); if (script->type() == Script::TYPE_WASM) { - Handle<WasmModuleObject> module_object( - WasmModuleObject::cast(script->wasm_module_object()), isolate_); - return WasmModuleObject::SetBreakPoint(module_object, source_position, + return WasmModuleObject::SetBreakPoint(script, source_position, break_point); } @@ -1039,7 +1037,7 @@ void Debug::PrepareStep(StepAction step_action) { // and deoptimize every frame along the way. bool in_current_frame = true; for (; !frames_it.done(); frames_it.Advance()) { - // TODO(clemensh): Implement stepping out from JS to wasm. + // TODO(clemensb): Implement stepping out from JS to wasm. if (frames_it.frame()->is_wasm()) continue; JavaScriptFrame* frame = JavaScriptFrame::cast(frames_it.frame()); if (last_step_action() == StepIn) { @@ -1069,7 +1067,7 @@ void Debug::PrepareStep(StepAction step_action) { thread_local_.target_frame_count_ = current_frame_count; V8_FALLTHROUGH; case StepIn: - // TODO(clemensh): Implement stepping from JS into wasm. + // TODO(clemensb): Implement stepping from JS into wasm. FloodWithOneShot(shared); break; } @@ -1171,7 +1169,7 @@ void Debug::PrepareFunctionForDebugExecution( if (debug_info->flags() & DebugInfo::kPreparedForDebugExecution) return; // Make a copy of the bytecode array if available. - Handle<Object> maybe_original_bytecode_array = + Handle<HeapObject> maybe_original_bytecode_array = isolate_->factory()->undefined_value(); if (shared->HasBytecodeArray()) { Handle<BytecodeArray> original_bytecode_array = @@ -1250,7 +1248,7 @@ void Debug::InstallDebugBreakTrampoline() { JSObject object = JSObject::cast(obj); DescriptorArray descriptors = object.map().instance_descriptors(); - for (int i = 0; i < object.map().NumberOfOwnDescriptors(); ++i) { + for (InternalIndex i : object.map().IterateOwnDescriptors()) { if (descriptors.GetDetails(i).kind() == PropertyKind::kAccessor) { Object value = descriptors.GetStrongValue(i); if (!value.IsAccessorPair()) continue; @@ -1901,6 +1899,7 @@ bool Debug::CanBreakAtEntry(Handle<SharedFunctionInfo> shared) { bool Debug::SetScriptSource(Handle<Script> script, Handle<String> source, bool preview, debug::LiveEditResult* result) { DebugScope debug_scope(this); + feature_tracker()->Track(DebugFeatureTracker::kLiveEdit); running_live_edit_ = true; LiveEdit::PatchScript(isolate_, script, source, preview, result); running_live_edit_ = false; @@ -1968,11 +1967,11 @@ void Debug::UpdateState() { if (is_active) { // Note that the debug context could have already been loaded to // bootstrap test cases. - isolate_->compilation_cache()->Disable(); + isolate_->compilation_cache()->DisableScriptAndEval(); is_active = true; feature_tracker()->Track(DebugFeatureTracker::kActive); } else { - isolate_->compilation_cache()->Enable(); + isolate_->compilation_cache()->EnableScriptAndEval(); Unload(); } is_active_ = is_active; diff --git a/deps/v8/src/debug/debug.h b/deps/v8/src/debug/debug.h index eef89f93725aa6..73bcceb4a235d3 100644 --- a/deps/v8/src/debug/debug.h +++ b/deps/v8/src/debug/debug.h @@ -5,6 +5,7 @@ #ifndef V8_DEBUG_DEBUG_H_ #define V8_DEBUG_DEBUG_H_ +#include <memory> #include <vector> #include "src/codegen/source-position-table.h" diff --git a/deps/v8/src/debug/interface-types.h b/deps/v8/src/debug/interface-types.h index 2375827b1bfeb1..a4204bb739c553 100644 --- a/deps/v8/src/debug/interface-types.h +++ b/deps/v8/src/debug/interface-types.h @@ -129,7 +129,7 @@ class ConsoleCallArguments : private v8::FunctionCallbackInfo<v8::Value> { } explicit ConsoleCallArguments(const v8::FunctionCallbackInfo<v8::Value>&); - explicit ConsoleCallArguments(internal::BuiltinArguments&); + explicit ConsoleCallArguments(const internal::BuiltinArguments&); }; class ConsoleContext { diff --git a/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc b/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc index 2befb70264abc8..45ff06eb70195f 100644 --- a/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc +++ b/deps/v8/src/deoptimizer/arm/deoptimizer-arm.cc @@ -123,6 +123,17 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ vstr(d0, r1, dst_offset); } + // Mark the stack as not iterable for the CPU profiler which won't be able to + // walk the stack without the return address. + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register zero = r4; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ mov(zero, Operand(0)); + __ strb(zero, MemOperand(is_iterable)); + } + // Remove the saved registers from the stack. __ add(sp, sp, Operand(kSavedRegistersAreaSize)); @@ -209,6 +220,15 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // Restore the registers from the stack. __ ldm(ia_w, sp, restored_regs); // all but pc registers. + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register one = r4; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ mov(one, Operand(1)); + __ strb(one, MemOperand(is_iterable)); + } + // Remove sp, lr and pc. __ Drop(3); { @@ -218,6 +238,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ pop(lr); __ Jump(scratch); } + __ stop(); } diff --git a/deps/v8/src/deoptimizer/arm64/deoptimizer-arm64.cc b/deps/v8/src/deoptimizer/arm64/deoptimizer-arm64.cc index 82ae764e506602..17091259d6e535 100644 --- a/deps/v8/src/deoptimizer/arm64/deoptimizer-arm64.cc +++ b/deps/v8/src/deoptimizer/arm64/deoptimizer-arm64.cc @@ -189,6 +189,15 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, CopyRegListToFrame(masm, x1, FrameDescription::double_registers_offset(), saved_double_registers, x2, x3, kDoubleRegistersOffset); + // Mark the stack as not iterable for the CPU profiler which won't be able to + // walk the stack without the return address. + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.AcquireX(); + __ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ strb(xzr, MemOperand(is_iterable)); + } + // Remove the saved registers from the stack. DCHECK_EQ(kSavedRegistersAreaSize % kXRegSize, 0); __ Drop(kSavedRegistersAreaSize / kXRegSize); @@ -251,6 +260,15 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, RestoreRegList(masm, saved_double_registers, x1, FrameDescription::double_registers_offset()); + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.AcquireX(); + Register one = x4; + __ Mov(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ Mov(one, Operand(1)); + __ strb(one, MemOperand(is_iterable)); + } + // TODO(all): ARM copies a lot (if not all) of the last output frame onto the // stack, then pops it all into registers. Here, we try to load it directly // into the relevant registers. Is this correct? If so, we should improve the diff --git a/deps/v8/src/deoptimizer/deoptimize-reason.h b/deps/v8/src/deoptimizer/deoptimize-reason.h index ac2273460a3092..71eaa8b6267551 100644 --- a/deps/v8/src/deoptimizer/deoptimize-reason.h +++ b/deps/v8/src/deoptimizer/deoptimize-reason.h @@ -48,7 +48,6 @@ namespace internal { V(NotASymbol, "not a Symbol") \ V(OutOfBounds, "out of bounds") \ V(Overflow, "overflow") \ - V(ReceiverNotAGlobalProxy, "receiver was not a global proxy") \ V(Smi, "Smi") \ V(Unknown, "(unknown)") \ V(ValueMismatch, "value mismatch") \ diff --git a/deps/v8/src/deoptimizer/deoptimizer.cc b/deps/v8/src/deoptimizer/deoptimizer.cc index 64551c68996f8c..fcb4c27d0b76cd 100644 --- a/deps/v8/src/deoptimizer/deoptimizer.cc +++ b/deps/v8/src/deoptimizer/deoptimizer.cc @@ -357,6 +357,9 @@ void Deoptimizer::DeoptimizeMarkedCodeForContext(NativeContext native_context) { for (Code code : codes) { isolate->heap()->InvalidateCodeDeoptimizationData(code); } + + native_context.GetOSROptimizedCodeCache().EvictMarkedCode( + native_context.GetIsolate()); } void Deoptimizer::DeoptimizeAll(Isolate* isolate) { @@ -375,6 +378,7 @@ void Deoptimizer::DeoptimizeAll(Isolate* isolate) { while (!context.IsUndefined(isolate)) { NativeContext native_context = NativeContext::cast(context); MarkAllCodeForContext(native_context); + OSROptimizedCodeCache::Clear(native_context); DeoptimizeMarkedCodeForContext(native_context); context = native_context.next_context_link(); } @@ -432,6 +436,13 @@ void Deoptimizer::DeoptimizeFunction(JSFunction function, Code code) { code.set_deopt_already_counted(true); } DeoptimizeMarkedCodeForContext(function.context().native_context()); + // TODO(mythria): Ideally EvictMarkCode should compact the cache without + // having to explicitly call this. We don't do this currently because + // compacting causes GC and DeoptimizeMarkedCodeForContext uses raw + // pointers. Update DeoptimizeMarkedCodeForContext to use handles and remove + // this call from here. + OSROptimizedCodeCache::Compact( + Handle<NativeContext>(function.context().native_context(), isolate)); } } @@ -3640,8 +3651,7 @@ void TranslatedState::EnsurePropertiesAllocatedAndMarked( // Set markers for the double properties. Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); - int field_count = map->NumberOfOwnDescriptors(); - for (int i = 0; i < field_count; i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { FieldIndex index = FieldIndex::ForDescriptor(*map, i); if (descriptors->GetDetails(i).representation().IsDouble() && !index.is_inobject()) { @@ -3673,10 +3683,9 @@ void TranslatedState::EnsureJSObjectAllocated(TranslatedValue* slot, Handle<ByteArray> object_storage = AllocateStorageFor(slot); // Now we handle the interesting (JSObject) case. Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate()); - int field_count = map->NumberOfOwnDescriptors(); // Set markers for the double properties. - for (int i = 0; i < field_count; i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { FieldIndex index = FieldIndex::ForDescriptor(*map, i); if (descriptors->GetDetails(i).representation().IsDouble() && index.is_inobject()) { @@ -3712,8 +3721,7 @@ void TranslatedState::InitializeJSObjectAt( CHECK_GE(slot->GetChildrenCount(), 2); // Notify the concurrent marker about the layout change. - isolate()->heap()->NotifyObjectLayoutChange( - *object_storage, slot->GetChildrenCount() * kTaggedSize, no_allocation); + isolate()->heap()->NotifyObjectLayoutChange(*object_storage, no_allocation); // Fill the property array field. { @@ -3772,8 +3780,7 @@ void TranslatedState::InitializeObjectWithTaggedFieldsAt( } // Notify the concurrent marker about the layout change. - isolate()->heap()->NotifyObjectLayoutChange( - *object_storage, slot->GetChildrenCount() * kTaggedSize, no_allocation); + isolate()->heap()->NotifyObjectLayoutChange(*object_storage, no_allocation); // Write the fields to the object. for (int i = 1; i < slot->GetChildrenCount(); i++) { diff --git a/deps/v8/src/deoptimizer/deoptimizer.h b/deps/v8/src/deoptimizer/deoptimizer.h index 6d0a350aaceb59..beb2a9aa50e826 100644 --- a/deps/v8/src/deoptimizer/deoptimizer.h +++ b/deps/v8/src/deoptimizer/deoptimizer.h @@ -488,14 +488,14 @@ class Deoptimizer : public Malloced { DeoptimizeKind* type); // Code generation support. - static int input_offset() { return OFFSET_OF(Deoptimizer, input_); } + static int input_offset() { return offsetof(Deoptimizer, input_); } static int output_count_offset() { - return OFFSET_OF(Deoptimizer, output_count_); + return offsetof(Deoptimizer, output_count_); } - static int output_offset() { return OFFSET_OF(Deoptimizer, output_); } + static int output_offset() { return offsetof(Deoptimizer, output_); } static int caller_frame_top_offset() { - return OFFSET_OF(Deoptimizer, caller_frame_top_); + return offsetof(Deoptimizer, caller_frame_top_); } V8_EXPORT_PRIVATE static int GetDeoptimizedCodeCount(Isolate* isolate); @@ -731,11 +731,11 @@ class FrameDescription { int parameter_count() { return parameter_count_; } static int registers_offset() { - return OFFSET_OF(FrameDescription, register_values_.registers_); + return offsetof(FrameDescription, register_values_.registers_); } static int double_registers_offset() { - return OFFSET_OF(FrameDescription, register_values_.double_registers_); + return offsetof(FrameDescription, register_values_.double_registers_); } static int frame_size_offset() { diff --git a/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc b/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc index 864e9dbe368b63..4036b73443b365 100644 --- a/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc +++ b/deps/v8/src/deoptimizer/ppc/deoptimizer-ppc.cc @@ -113,6 +113,17 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ stfd(d0, MemOperand(r4, dst_offset)); } + // Mark the stack as not iterable for the CPU profiler which won't be able to + // walk the stack without the return address. + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register zero = r7; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ li(zero, Operand(0)); + __ stb(zero, MemOperand(is_iterable)); + } + // Remove the saved registers from the stack. __ addi(sp, sp, Operand(kSavedRegistersAreaSize)); @@ -208,6 +219,15 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, } } + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register one = r7; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ li(one, Operand(1)); + __ stb(one, MemOperand(is_iterable)); + } + { UseScratchRegisterScope temps(masm); Register scratch = temps.Acquire(); @@ -216,6 +236,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ mtlr(r0); __ Jump(scratch); } + __ stop(); } diff --git a/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc b/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc index 616a57ba0e420c..7ea6e56b8cf29a 100644 --- a/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc +++ b/deps/v8/src/deoptimizer/s390/deoptimizer-s390.cc @@ -40,7 +40,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, } // Push all GPRs onto the stack - __ lay(sp, MemOperand(sp, -kNumberOfRegisters * kPointerSize)); + __ lay(sp, MemOperand(sp, -kNumberOfRegisters * kSystemPointerSize)); __ StoreMultipleP(r0, sp, MemOperand(sp)); // Save all 16 registers __ mov(r1, Operand(ExternalReference::Create( @@ -48,7 +48,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ StoreP(fp, MemOperand(r1)); const int kSavedRegistersAreaSize = - (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; + (kNumberOfRegisters * kSystemPointerSize) + kDoubleRegsSize; // The bailout id is passed using r10 __ LoadRR(r4, r10); @@ -79,7 +79,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // r6: Fp-to-sp delta. // Parm6: isolate is passed on the stack. __ mov(r7, Operand(ExternalReference::isolate_address(isolate))); - __ StoreP(r7, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); + __ StoreP(r7, MemOperand(sp, kStackFrameExtraParamSlot * kSystemPointerSize)); // Call Deoptimizer::New(). { @@ -94,13 +94,14 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // Copy core registers into FrameDescription::registers_[kNumRegisters]. // DCHECK_EQ(Register::kNumRegisters, kNumberOfRegisters); // __ mvc(MemOperand(r3, FrameDescription::registers_offset()), - // MemOperand(sp), kNumberOfRegisters * kPointerSize); + // MemOperand(sp), kNumberOfRegisters * kSystemPointerSize); // Copy core registers into FrameDescription::registers_[kNumRegisters]. // TODO(john.yan): optimize the following code by using mvc instruction DCHECK_EQ(Register::kNumRegisters, kNumberOfRegisters); for (int i = 0; i < kNumberOfRegisters; i++) { - int offset = (i * kPointerSize) + FrameDescription::registers_offset(); - __ LoadP(r4, MemOperand(sp, i * kPointerSize)); + int offset = + (i * kSystemPointerSize) + FrameDescription::registers_offset(); + __ LoadP(r4, MemOperand(sp, i * kSystemPointerSize)); __ StoreP(r4, MemOperand(r3, offset)); } @@ -110,12 +111,24 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { int code = config->GetAllocatableDoubleCode(i); int dst_offset = code * kDoubleSize + double_regs_offset; - int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize; + int src_offset = + code * kDoubleSize + kNumberOfRegisters * kSystemPointerSize; // TODO(joransiu): MVC opportunity __ LoadDouble(d0, MemOperand(sp, src_offset)); __ StoreDouble(d0, MemOperand(r3, dst_offset)); } + // Mark the stack as not iterable for the CPU profiler which won't be able to + // walk the stack without the return address. + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register zero = r6; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ lhi(zero, Operand(0)); + __ StoreByte(zero, MemOperand(is_iterable)); + } + // Remove the saved registers from the stack. __ la(sp, MemOperand(sp, kSavedRegistersAreaSize)); @@ -134,7 +147,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ bind(&pop_loop); __ pop(r6); __ StoreP(r6, MemOperand(r5, 0)); - __ la(r5, MemOperand(r5, kPointerSize)); + __ la(r5, MemOperand(r5, kSystemPointerSize)); __ bind(&pop_loop_header); __ CmpP(r4, sp); __ bne(&pop_loop); @@ -158,7 +171,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // r3 = one past the last FrameDescription**. __ LoadlW(r3, MemOperand(r2, Deoptimizer::output_count_offset())); __ LoadP(r6, MemOperand(r2, Deoptimizer::output_offset())); // r6 is output_. - __ ShiftLeftP(r3, r3, Operand(kPointerSizeLog2)); + __ ShiftLeftP(r3, r3, Operand(kSystemPointerSizeLog2)); __ AddP(r3, r6, r3); __ b(&outer_loop_header, Label::kNear); @@ -178,7 +191,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, __ CmpP(r5, Operand::Zero()); __ bne(&inner_push_loop); // test for gt? - __ AddP(r6, r6, Operand(kPointerSize)); + __ AddP(r6, r6, Operand(kSystemPointerSize)); __ bind(&outer_loop_header); __ CmpP(r6, r3); __ blt(&outer_push_loop); @@ -200,15 +213,26 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // Restore the registers from the last output frame. __ LoadRR(r1, r4); for (int i = kNumberOfRegisters - 1; i > 0; i--) { - int offset = (i * kPointerSize) + FrameDescription::registers_offset(); + int offset = + (i * kSystemPointerSize) + FrameDescription::registers_offset(); if ((restored_regs & (1 << i)) != 0) { __ LoadP(ToRegister(i), MemOperand(r1, offset)); } } + { + UseScratchRegisterScope temps(masm); + Register is_iterable = temps.Acquire(); + Register one = r6; + __ Move(is_iterable, ExternalReference::stack_is_iterable_address(isolate)); + __ lhi(one, Operand(1)); + __ StoreByte(one, MemOperand(is_iterable)); + } + __ pop(ip); // get continuation, leave pc on stack __ pop(r14); __ Jump(ip); + __ stop(); } diff --git a/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc b/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc index 29c81f195c1679..03d7c759c09a7c 100644 --- a/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc +++ b/deps/v8/src/deoptimizer/x64/deoptimizer-x64.cc @@ -81,7 +81,7 @@ void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, // On windows put the arguments on the stack (PrepareCallCFunction // has created space for this). On linux pass the arguments in r8 and r9. -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN __ movq(Operand(rsp, 4 * kSystemPointerSize), arg5); __ LoadAddress(arg5, ExternalReference::isolate_address(isolate)); __ movq(Operand(rsp, 5 * kSystemPointerSize), arg5); diff --git a/deps/v8/src/diagnostics/arm/disasm-arm.cc b/deps/v8/src/diagnostics/arm/disasm-arm.cc index 51b6594e70e901..891ab0662e008b 100644 --- a/deps/v8/src/diagnostics/arm/disasm-arm.cc +++ b/deps/v8/src/diagnostics/arm/disasm-arm.cc @@ -590,7 +590,7 @@ int Decoder::FormatOption(Instruction* instr, const char* format) { } case 't': { // 'target: target of branch instructions DCHECK(STRING_STARTS_WITH(format, "target")); - int off = (instr->SImmed24Value() << 2) + 8; + int off = (static_cast<uint32_t>(instr->SImmed24Value()) << 2) + 8u; out_buffer_pos_ += SNPrintF( out_buffer_ + out_buffer_pos_, "%+d -> %s", off, converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); @@ -1890,6 +1890,17 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { op, size, Vd, Vn, Vm); break; } + case 0x4: { + if (instr->Bit(4) == 0) { + // vshl.s<size> Qd, Qm, Qn. + out_buffer_pos_ += + SNPrintF(out_buffer_ + out_buffer_pos_, + "vshl.s%d q%d, q%d, q%d", size, Vd, Vm, Vn); + } else { + Unknown(instr); + } + break; + } case 0x6: { // vmin/vmax.s<size> Qd, Qm, Qn. const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; @@ -2083,6 +2094,17 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { op, size, Vd, Vn, Vm); break; } + case 0x4: { + if (instr->Bit(4) == 0) { + // vshl.u<size> Qd, Qm, Qn. + out_buffer_pos_ += + SNPrintF(out_buffer_ + out_buffer_pos_, + "vshl.u%d q%d, q%d, q%d", size, Vd, Vm, Vn); + } else { + Unknown(instr); + } + break; + } case 0x6: { // vmin/vmax.u<size> Qd, Qm, Qn. const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; diff --git a/deps/v8/src/diagnostics/arm64/disasm-arm64.cc b/deps/v8/src/diagnostics/arm64/disasm-arm64.cc index 7141cdf2837dbd..db14689ad1c596 100644 --- a/deps/v8/src/diagnostics/arm64/disasm-arm64.cc +++ b/deps/v8/src/diagnostics/arm64/disasm-arm64.cc @@ -3840,8 +3840,8 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr, case 'L': { switch (format[2]) { case 'L': { // ILLiteral - Immediate Load Literal. - AppendToOutput("pc%+" PRId32, instr->ImmLLiteral() - << kLoadLiteralScaleLog2); + AppendToOutput("pc%+" PRId32, + instr->ImmLLiteral() * kLoadLiteralScale); return 9; } case 'S': { // ILS - Immediate Load/Store. @@ -3960,7 +3960,7 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr, unsigned rd_index, rn_index; unsigned imm5 = instr->ImmNEON5(); unsigned imm4 = instr->ImmNEON4(); - int tz = CountTrailingZeros(imm5, 32); + int tz = base::bits::CountTrailingZeros(imm5); if (tz <= 3) { // Defined for 0 <= tz <= 3 only. rd_index = imm5 >> (tz + 1); rn_index = imm4 >> tz; @@ -4179,7 +4179,7 @@ int DisassemblingDecoder::SubstituteBranchTargetField(Instruction* instr, default: UNREACHABLE(); } - offset <<= kInstrSizeLog2; + offset *= kInstrSize; char sign = '+'; if (offset < 0) { sign = '-'; diff --git a/deps/v8/src/diagnostics/basic-block-profiler.h b/deps/v8/src/diagnostics/basic-block-profiler.h index 960b4b43e116e5..9639e0b66154d4 100644 --- a/deps/v8/src/diagnostics/basic-block-profiler.h +++ b/deps/v8/src/diagnostics/basic-block-profiler.h @@ -7,6 +7,7 @@ #include <iosfwd> #include <list> +#include <memory> #include <string> #include <vector> diff --git a/deps/v8/src/diagnostics/ia32/disasm-ia32.cc b/deps/v8/src/diagnostics/ia32/disasm-ia32.cc index e8c9588bbe4ae5..ead0a5a7094af1 100644 --- a/deps/v8/src/diagnostics/ia32/disasm-ia32.cc +++ b/deps/v8/src/diagnostics/ia32/disasm-ia32.cc @@ -1057,6 +1057,10 @@ int DisassemblerIA32::AVXInstruction(byte* data) { AppendToBuffer("vmovaps %s,", NameOfXMMRegister(regop)); current += PrintRightXMMOperand(current); break; + case 0x51: + AppendToBuffer("vsqrtps %s,", NameOfXMMRegister(regop)); + current += PrintRightXMMOperand(current); + break; case 0x52: AppendToBuffer("vrsqrtps %s,", NameOfXMMRegister(regop)); current += PrintRightXMMOperand(current); @@ -1075,6 +1079,11 @@ int DisassemblerIA32::AVXInstruction(byte* data) { NameOfXMMRegister(vvvv)); current += PrintRightXMMOperand(current); break; + case 0x56: + AppendToBuffer("vorps %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + break; case 0x57: AppendToBuffer("vxorps %s,%s,", NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); @@ -1138,11 +1147,25 @@ int DisassemblerIA32::AVXInstruction(byte* data) { int mod, regop, rm, vvvv = vex_vreg(); get_modrm(*current, &mod, ®op, &rm); switch (opcode) { + case 0x28: + AppendToBuffer("vmovapd %s,", NameOfXMMRegister(regop)); + current += PrintRightXMMOperand(current); + break; case 0x54: AppendToBuffer("vandpd %s,%s,", NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); current += PrintRightXMMOperand(current); break; + case 0x55: + AppendToBuffer("vandnpd %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + break; + case 0x56: + AppendToBuffer("vorpd %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + break; case 0x57: AppendToBuffer("vxorpd %s,%s,", NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); @@ -1200,11 +1223,26 @@ int DisassemblerIA32::AVXInstruction(byte* data) { current++; AppendToBuffer(",%u", *current++); break; + case 0x73: + AppendToBuffer("vps%sq %s,%s", sf_str[regop / 2], + NameOfXMMRegister(vvvv), NameOfXMMRegister(rm)); + current++; + AppendToBuffer(",%u", *current++); + break; case 0x7E: AppendToBuffer("vmovd "); current += PrintRightOperand(current); AppendToBuffer(",%s", NameOfXMMRegister(regop)); break; + case 0xC2: { + const char* const pseudo_op[] = {"eq", "lt", "le", "unord", "neq"}; + AppendToBuffer("vcmppd %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + AppendToBuffer(", (%s)", pseudo_op[*current]); + current++; + break; + } case 0xC4: AppendToBuffer("vpinsrw %s,%s,", NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); @@ -1212,6 +1250,13 @@ int DisassemblerIA32::AVXInstruction(byte* data) { AppendToBuffer(",%d", Imm8(current)); current++; break; + case 0xC6: + AppendToBuffer("vshufpd %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + AppendToBuffer(",%d", Imm8(current)); + current++; + break; #define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \ case 0x##opcode: { \ AppendToBuffer("v" #instruction " %s,%s,", NameOfXMMRegister(regop), \ @@ -1763,17 +1808,17 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, get_modrm(*data, &mod, ®op, &rm); AppendToBuffer("ucomiss %s,", NameOfXMMRegister(regop)); data += PrintRightXMMOperand(data); - } else if (f0byte >= 0x52 && f0byte <= 0x5F) { + } else if (f0byte >= 0x51 && f0byte <= 0x5F) { const char* const pseudo_op[] = { - "rsqrtps", "rcpps", "andps", "andnps", "orps", - "xorps", "addps", "mulps", "cvtps2pd", "cvtdq2ps", - "subps", "minps", "divps", "maxps", + "sqrtps", "rsqrtps", "rcpps", "andps", "andnps", + "orps", "xorps", "addps", "mulps", "cvtps2pd", + "cvtdq2ps", "subps", "minps", "divps", "maxps", }; data += 2; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); - AppendToBuffer("%s %s,", pseudo_op[f0byte - 0x52], + AppendToBuffer("%s %s,", pseudo_op[f0byte - 0x51], NameOfXMMRegister(regop)); data += PrintRightXMMOperand(data); } else if (f0byte == 0x50) { @@ -2026,7 +2071,13 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, data += 2; } else if (*data == 0x0F) { data++; - if (*data == 0x38) { + if (*data == 0x28) { + data++; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + AppendToBuffer("movapd %s,", NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); + } else if (*data == 0x38) { data++; byte op = *data; data++; @@ -2160,27 +2211,31 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, AppendToBuffer("movmskpd %s,%s", NameOfCPURegister(regop), NameOfXMMRegister(rm)); data++; - } else if (*data == 0x54) { - data++; - int mod, regop, rm; - get_modrm(*data, &mod, ®op, &rm); - AppendToBuffer("andpd %s,%s", NameOfXMMRegister(regop), - NameOfXMMRegister(rm)); - data++; - } else if (*data == 0x56) { + } else if (*data >= 0x54 && *data <= 0x59) { + const char* const pseudo_op[] = { + "andpd", "andnpd", "orpd", "xorpd", "addpd", "mulpd", + }; + byte op = *data; data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); - AppendToBuffer("orpd %s,%s", NameOfXMMRegister(regop), - NameOfXMMRegister(rm)); - data++; - } else if (*data == 0x57) { + AppendToBuffer("%s %s,", pseudo_op[op - 0x54], + NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); + } else if (*data >= 0x5c && *data <= 0x5f) { + const char* const pseudo_op[] = { + "subpd", + "minpd", + "divpd", + "maxpd", + }; + byte op = *data; data++; int mod, regop, rm; get_modrm(*data, &mod, ®op, &rm); - AppendToBuffer("xorpd %s,%s", NameOfXMMRegister(regop), - NameOfXMMRegister(rm)); - data++; + AppendToBuffer("%s %s,", pseudo_op[op - 0x5c], + NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); } else if (*data == 0x6E) { data++; int mod, regop, rm; @@ -2257,6 +2312,15 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, AppendToBuffer("movd "); data += PrintRightOperand(data); AppendToBuffer(",%s", NameOfXMMRegister(regop)); + } else if (*data == 0xC2) { + data++; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + const char* const pseudo_op[] = {"eq", "lt", "le", "unord", "neq"}; + AppendToBuffer("cmppd %s, ", NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); + AppendToBuffer(", (%s)", pseudo_op[*data]); + data++; } else if (*data == 0xC4) { data++; int mod, regop, rm; @@ -2265,6 +2329,15 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, data += PrintRightOperand(data); AppendToBuffer(",%d", Imm8(data)); data++; + } else if (*data == 0xC6) { + // shufpd xmm, xmm/m128, imm8 + data++; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + AppendToBuffer("shufpd %s,", NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); + AppendToBuffer(",%d", Imm8(data)); + data++; } else if (*data == 0xE7) { data++; int mod, regop, rm; diff --git a/deps/v8/src/diagnostics/objects-debug.cc b/deps/v8/src/diagnostics/objects-debug.cc index 6860ead0223dec..9c4b176dc65c75 100644 --- a/deps/v8/src/diagnostics/objects-debug.cc +++ b/deps/v8/src/diagnostics/objects-debug.cc @@ -26,6 +26,7 @@ #include "src/objects/field-type.h" #include "src/objects/foreign-inl.h" #include "src/objects/free-space-inl.h" +#include "src/objects/function-kind.h" #include "src/objects/hash-table-inl.h" #include "src/objects/js-array-inl.h" #include "src/objects/layout-descriptor.h" @@ -258,25 +259,25 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { case JS_CONTEXT_EXTENSION_OBJECT_TYPE: JSObject::cast(*this).JSObjectVerify(isolate); break; - case WASM_MODULE_TYPE: + case WASM_MODULE_OBJECT_TYPE: WasmModuleObject::cast(*this).WasmModuleObjectVerify(isolate); break; - case WASM_TABLE_TYPE: + case WASM_TABLE_OBJECT_TYPE: WasmTableObject::cast(*this).WasmTableObjectVerify(isolate); break; - case WASM_MEMORY_TYPE: + case WASM_MEMORY_OBJECT_TYPE: WasmMemoryObject::cast(*this).WasmMemoryObjectVerify(isolate); break; - case WASM_GLOBAL_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: WasmGlobalObject::cast(*this).WasmGlobalObjectVerify(isolate); break; - case WASM_EXCEPTION_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: WasmExceptionObject::cast(*this).WasmExceptionObjectVerify(isolate); break; - case WASM_INSTANCE_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: WasmInstanceObject::cast(*this).WasmInstanceObjectVerify(isolate); break; - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: JSArgumentsObject::cast(*this).JSArgumentsObjectVerify(isolate); break; case JS_GENERATOR_OBJECT_TYPE: @@ -365,10 +366,10 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { case JS_PROMISE_TYPE: JSPromise::cast(*this).JSPromiseVerify(isolate); break; - case JS_REGEXP_TYPE: + case JS_REG_EXP_TYPE: JSRegExp::cast(*this).JSRegExpVerify(isolate); break; - case JS_REGEXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: JSRegExpStringIterator::cast(*this).JSRegExpStringIteratorVerify(isolate); break; case FILLER_TYPE: @@ -425,34 +426,34 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { CodeDataContainer::cast(*this).CodeDataContainerVerify(isolate); break; #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: JSV8BreakIterator::cast(*this).JSV8BreakIteratorVerify(isolate); break; - case JS_INTL_COLLATOR_TYPE: + case JS_COLLATOR_TYPE: JSCollator::cast(*this).JSCollatorVerify(isolate); break; - case JS_INTL_DATE_TIME_FORMAT_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: JSDateTimeFormat::cast(*this).JSDateTimeFormatVerify(isolate); break; - case JS_INTL_LIST_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: JSListFormat::cast(*this).JSListFormatVerify(isolate); break; - case JS_INTL_LOCALE_TYPE: + case JS_LOCALE_TYPE: JSLocale::cast(*this).JSLocaleVerify(isolate); break; - case JS_INTL_NUMBER_FORMAT_TYPE: + case JS_NUMBER_FORMAT_TYPE: JSNumberFormat::cast(*this).JSNumberFormatVerify(isolate); break; - case JS_INTL_PLURAL_RULES_TYPE: + case JS_PLURAL_RULES_TYPE: JSPluralRules::cast(*this).JSPluralRulesVerify(isolate); break; - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: JSRelativeTimeFormat::cast(*this).JSRelativeTimeFormatVerify(isolate); break; - case JS_INTL_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: JSSegmentIterator::cast(*this).JSSegmentIteratorVerify(isolate); break; - case JS_INTL_SEGMENTER_TYPE: + case JS_SEGMENTER_TYPE: JSSegmenter::cast(*this).JSSegmenterVerify(isolate); break; #endif // V8_INTL_SUPPORT @@ -512,8 +513,6 @@ void BytecodeArray::BytecodeArrayVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(FreeSpace) -USE_TORQUE_VERIFIER(FeedbackCell) - void FeedbackVector::FeedbackVectorVerify(Isolate* isolate) { TorqueGeneratedClassVerifiers::FeedbackVectorVerify(*this, isolate); MaybeObject code = optimized_code_weak_or_smi(); @@ -590,7 +589,7 @@ void JSObject::JSObjectVerify(Isolate* isolate) { bool is_transitionable_fast_elements_kind = IsTransitionableFastElementsKind(map().elements_kind()); - for (int i = 0; i < map().NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map().IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(i); if (details.location() == kField) { DCHECK_EQ(kData, details.kind()); @@ -668,7 +667,7 @@ void Map::MapVerify(Isolate* isolate) { CHECK(!is_dictionary_map()); CHECK(!is_access_check_needed()); DescriptorArray const descriptors = instance_descriptors(); - for (int i = 0; i < NumberOfOwnDescriptors(); ++i) { + for (InternalIndex i : IterateOwnDescriptors()) { CHECK(!descriptors.GetKey(i).IsInterestingSymbol()); } } @@ -803,9 +802,9 @@ void DescriptorArray::DescriptorArrayVerify(Isolate* isolate) { // Check that properties with private symbols names are non-enumerable, and // that fields are in order. int expected_field_index = 0; - for (int descriptor = 0; descriptor < number_of_descriptors(); - descriptor++) { - Object key = *(GetDescriptorSlot(descriptor) + kEntryKeyIndex); + for (InternalIndex descriptor : + InternalIndex::Range(number_of_descriptors())) { + Object key = *(GetDescriptorSlot(descriptor.as_int()) + kEntryKeyIndex); // number_of_descriptors() may be out of sync with the actual descriptors // written during descriptor array construction. if (key.IsUndefined(isolate)) continue; @@ -1050,7 +1049,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) { if (scope_info().length() > 0) { ScopeInfo info = scope_info(); CHECK(kind() == info.function_kind()); - CHECK_EQ(kind() == kModule, info.scope_type() == MODULE_SCOPE); + CHECK_EQ(internal::IsModule(kind()), info.scope_type() == MODULE_SCOPE); } if (IsApiFunction()) { @@ -1449,7 +1448,7 @@ void JSRegExp::JSRegExpVerify(Isolate* isolate) { CHECK(arr.get(JSRegExp::kIrregexpCaptureCountIndex).IsSmi()); CHECK(arr.get(JSRegExp::kIrregexpMaxRegisterCountIndex).IsSmi()); - CHECK(arr.get(JSRegExp::kIrregexpTierUpTicksIndex).IsSmi()); + CHECK(arr.get(JSRegExp::kIrregexpTicksUntilTierUpIndex).IsSmi()); break; } default: @@ -1543,10 +1542,18 @@ void Module::ModuleVerify(Isolate* isolate) { void SourceTextModule::SourceTextModuleVerify(Isolate* isolate) { TorqueGeneratedClassVerifiers::SourceTextModuleVerify(*this, isolate); - CHECK((status() >= kEvaluating && code().IsSourceTextModuleInfo()) || - (status() == kInstantiated && code().IsJSGeneratorObject()) || - (status() == kInstantiating && code().IsJSFunction()) || - (code().IsSharedFunctionInfo())); + if (status() == kErrored) { + CHECK(code().IsSourceTextModuleInfo()); + } else if (status() == kEvaluating || status() == kEvaluated) { + CHECK(code().IsJSGeneratorObject()); + } else { + CHECK((status() == kInstantiated && code().IsJSGeneratorObject()) || + (status() == kInstantiating && code().IsJSFunction()) || + (status() == kPreInstantiating && code().IsSharedFunctionInfo()) || + (status() == kUninstantiated && code().IsSharedFunctionInfo())); + CHECK(top_level_capability().IsUndefined() && !AsyncParentModuleCount() && + !pending_async_dependencies() && !async_evaluating()); + } CHECK_EQ(requested_modules().length(), info().module_requests().length()); } @@ -1679,8 +1686,6 @@ void StoreHandler::StoreHandlerVerify(Isolate* isolate) { USE_TORQUE_VERIFIER(AccessorInfo) -USE_TORQUE_VERIFIER(AccessorPair) - void CallHandlerInfo::CallHandlerInfoVerify(Isolate* isolate) { TorqueGeneratedClassVerifiers::CallHandlerInfoVerify(*this, isolate); CHECK(map() == ReadOnlyRoots(isolate).side_effect_call_handler_info_map() || @@ -1733,8 +1738,6 @@ void NormalizedMapCache::NormalizedMapCacheVerify(Isolate* isolate) { } } -USE_TORQUE_VERIFIER(DebugInfo) - USE_TORQUE_VERIFIER(StackFrameInfo) void PreparseData::PreparseDataVerify(Isolate* isolate) { @@ -1749,19 +1752,6 @@ void PreparseData::PreparseDataVerify(Isolate* isolate) { } } -void UncompiledDataWithPreparseData::UncompiledDataWithPreparseDataVerify( - Isolate* isolate) { - CHECK(IsUncompiledDataWithPreparseData()); - VerifyPointer(isolate, inferred_name()); - VerifyPointer(isolate, preparse_data()); -} - -void UncompiledDataWithoutPreparseData::UncompiledDataWithoutPreparseDataVerify( - Isolate* isolate) { - CHECK(IsUncompiledDataWithoutPreparseData()); - VerifyPointer(isolate, inferred_name()); -} - USE_TORQUE_VERIFIER(InterpreterData) #ifdef V8_INTL_SUPPORT diff --git a/deps/v8/src/diagnostics/objects-printer.cc b/deps/v8/src/diagnostics/objects-printer.cc index 39614091c74b94..20afb9e5204d84 100644 --- a/deps/v8/src/diagnostics/objects-printer.cc +++ b/deps/v8/src/diagnostics/objects-printer.cc @@ -215,25 +215,25 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT case JS_API_OBJECT_TYPE: case JS_SPECIAL_API_OBJECT_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE: - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: case JS_ERROR_TYPE: // TODO(titzer): debug printing for more wasm objects - case WASM_EXCEPTION_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: JSObject::cast(*this).JSObjectPrint(os); break; - case WASM_MODULE_TYPE: + case WASM_MODULE_OBJECT_TYPE: WasmModuleObject::cast(*this).WasmModuleObjectPrint(os); break; - case WASM_MEMORY_TYPE: + case WASM_MEMORY_OBJECT_TYPE: WasmMemoryObject::cast(*this).WasmMemoryObjectPrint(os); break; - case WASM_TABLE_TYPE: + case WASM_TABLE_OBJECT_TYPE: WasmTableObject::cast(*this).WasmTableObjectPrint(os); break; - case WASM_GLOBAL_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: WasmGlobalObject::cast(*this).WasmGlobalObjectPrint(os); break; - case WASM_INSTANCE_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: WasmInstanceObject::cast(*this).WasmInstanceObjectPrint(os); break; case JS_ASYNC_FUNCTION_OBJECT_TYPE: @@ -247,10 +247,10 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT case JS_ARRAY_TYPE: JSArray::cast(*this).JSArrayPrint(os); break; - case JS_REGEXP_TYPE: + case JS_REG_EXP_TYPE: JSRegExp::cast(*this).JSRegExpPrint(os); break; - case JS_REGEXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: JSRegExpStringIterator::cast(*this).JSRegExpStringIteratorPrint(os); break; case ODDBALL_TYPE: @@ -362,34 +362,34 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT JSDataView::cast(*this).JSDataViewPrint(os); break; #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: JSV8BreakIterator::cast(*this).JSV8BreakIteratorPrint(os); break; - case JS_INTL_COLLATOR_TYPE: + case JS_COLLATOR_TYPE: JSCollator::cast(*this).JSCollatorPrint(os); break; - case JS_INTL_DATE_TIME_FORMAT_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: JSDateTimeFormat::cast(*this).JSDateTimeFormatPrint(os); break; - case JS_INTL_LIST_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: JSListFormat::cast(*this).JSListFormatPrint(os); break; - case JS_INTL_LOCALE_TYPE: + case JS_LOCALE_TYPE: JSLocale::cast(*this).JSLocalePrint(os); break; - case JS_INTL_NUMBER_FORMAT_TYPE: + case JS_NUMBER_FORMAT_TYPE: JSNumberFormat::cast(*this).JSNumberFormatPrint(os); break; - case JS_INTL_PLURAL_RULES_TYPE: + case JS_PLURAL_RULES_TYPE: JSPluralRules::cast(*this).JSPluralRulesPrint(os); break; - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: JSRelativeTimeFormat::cast(*this).JSRelativeTimeFormatPrint(os); break; - case JS_INTL_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: JSSegmentIterator::cast(*this).JSSegmentIteratorPrint(os); break; - case JS_INTL_SEGMENTER_TYPE: + case JS_SEGMENTER_TYPE: JSSegmenter::cast(*this).JSSegmenterPrint(os); break; #endif // V8_INTL_SUPPORT @@ -477,8 +477,8 @@ bool JSObject::PrintProperties(std::ostream& os) { // NOLINT if (HasFastProperties()) { DescriptorArray descs = map().instance_descriptors(); int nof_inobject_properties = map().GetInObjectProperties(); - int i = 0; - for (; i < map().NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : + InternalIndex::Range(map().NumberOfOwnDescriptors())) { os << "\n "; descs.GetKey(i).NamePrint(os); os << ": "; @@ -506,7 +506,7 @@ bool JSObject::PrintProperties(std::ostream& os) { // NOLINT os << " properties[" << field_index << "]"; } } - return i > 0; + return map().NumberOfOwnDescriptors() > 0; } else if (IsJSGlobalObject()) { JSGlobalObject::cast(*this).global_dictionary().Print(os); } else { @@ -1379,7 +1379,6 @@ void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) { // NOLINT if (is_detachable()) os << "\n - detachable"; if (was_detached()) os << "\n - detached"; if (is_shared()) os << "\n - shared"; - if (is_wasm_memory()) os << "\n - is_wasm_memory"; JSObjectPrintBody(os, *this, !was_detached()); } @@ -1389,6 +1388,12 @@ void JSTypedArray::JSTypedArrayPrint(std::ostream& os) { // NOLINT os << "\n - byte_offset: " << byte_offset(); os << "\n - byte_length: " << byte_length(); os << "\n - length: " << length(); + os << "\n - data_ptr: " << DataPtr(); + Tagged_t base_ptr = static_cast<Tagged_t>(base_pointer().ptr()); + os << "\n - base_pointer: " + << reinterpret_cast<void*>(static_cast<Address>(base_ptr)); + os << "\n - external_pointer: " + << reinterpret_cast<void*>(external_pointer()); if (!buffer().IsJSArrayBuffer()) { os << "\n <invalid buffer>\n"; return; @@ -1627,7 +1632,7 @@ void Code::CodePrint(std::ostream& os) { // NOLINT os << "\n"; #ifdef ENABLE_DISASSEMBLER if (FLAG_use_verbose_printer) { - Disassemble(nullptr, os); + Disassemble(nullptr, os, GetIsolate()); } #endif } @@ -1911,9 +1916,6 @@ void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT if (has_asm_js_offset_table()) { os << "\n - asm_js_offset_table: " << Brief(asm_js_offset_table()); } - if (has_breakpoint_infos()) { - os << "\n - breakpoint_infos: " << Brief(breakpoint_infos()); - } os << "\n"; } @@ -2146,6 +2148,9 @@ void Script::ScriptPrint(std::ostream& os) { // NOLINT os << "\n - wrapped arguments: " << Brief(wrapped_arguments()); } os << "\n - eval from position: " << eval_from_position(); + if (has_wasm_breakpoint_infos()) { + os << "\n - wasm_breakpoint_infos: " << Brief(wasm_breakpoint_infos()); + } os << "\n - shared function infos: " << Brief(shared_function_infos()); os << "\n"; } @@ -2280,6 +2285,7 @@ void ScopeInfo::ScopeInfoPrint(std::ostream& os) { // NOLINT os << "\n - receiver: " << ReceiverVariableField::decode(flags); } if (HasClassBrand()) os << "\n - has class brand"; + if (HasSavedClassVariableIndex()) os << "\n - has saved class variable index"; if (HasNewTarget()) os << "\n - needs new target"; if (HasFunctionName()) { os << "\n - function name(" << FunctionVariableField::decode(flags) @@ -2578,9 +2584,9 @@ void Map::MapPrint(std::ostream& os) { // NOLINT } void DescriptorArray::PrintDescriptors(std::ostream& os) { - for (int i = 0; i < number_of_descriptors(); i++) { + for (InternalIndex i : InternalIndex::Range(number_of_descriptors())) { Name key = GetKey(i); - os << "\n [" << i << "]: "; + os << "\n [" << i.as_int() << "]: "; #ifdef OBJECT_PRINT key.NamePrint(os); #else @@ -2592,7 +2598,8 @@ void DescriptorArray::PrintDescriptors(std::ostream& os) { os << "\n"; } -void DescriptorArray::PrintDescriptorDetails(std::ostream& os, int descriptor, +void DescriptorArray::PrintDescriptorDetails(std::ostream& os, + InternalIndex descriptor, PropertyDetails::PrintMode mode) { PropertyDetails details = GetDetails(descriptor); details.PrintAsFastTo(os, mode); @@ -2655,7 +2662,7 @@ void TransitionsAccessor::PrintOneTransition(std::ostream& os, Name key, } else { DCHECK(!IsSpecialTransition(roots, key)); os << "(transition to "; - int descriptor = target.LastAdded(); + InternalIndex descriptor = target.LastAdded(); DescriptorArray descriptors = target.instance_descriptors(); descriptors.PrintDescriptorDetails(os, descriptor, PropertyDetails::kForTransitions); @@ -2733,7 +2740,7 @@ void TransitionsAccessor::PrintTransitionTree(std::ostream& os, int level, os << " "; DCHECK(!IsSpecialTransition(ReadOnlyRoots(isolate_), key)); os << "to "; - int descriptor = target.LastAdded(); + InternalIndex descriptor = target.LastAdded(); DescriptorArray descriptors = target.instance_descriptors(); descriptors.PrintDescriptorDetails(os, descriptor, PropertyDetails::kForTransitions); @@ -2816,7 +2823,7 @@ V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) { } #ifdef ENABLE_DISASSEMBLER i::StdoutStream os; - code.Disassemble(nullptr, os, address); + code.Disassemble(nullptr, os, isolate, address); #else // ENABLE_DISASSEMBLER code.Print(); #endif // ENABLE_DISASSEMBLER diff --git a/deps/v8/src/diagnostics/x64/disasm-x64.cc b/deps/v8/src/diagnostics/x64/disasm-x64.cc index aada6a43813daa..2195556af7a94e 100644 --- a/deps/v8/src/diagnostics/x64/disasm-x64.cc +++ b/deps/v8/src/diagnostics/x64/disasm-x64.cc @@ -91,9 +91,9 @@ static const ByteMnemonic zero_operands_instr[] = { {0x61, UNSET_OP_ORDER, "popad"}, {0x9C, UNSET_OP_ORDER, "pushfd"}, {0x9D, UNSET_OP_ORDER, "popfd"}, {0x9E, UNSET_OP_ORDER, "sahf"}, {0x99, UNSET_OP_ORDER, "cdq"}, {0x9B, UNSET_OP_ORDER, "fwait"}, - {0xA4, UNSET_OP_ORDER, "movs"}, {0xA5, UNSET_OP_ORDER, "movs"}, - {0xA6, UNSET_OP_ORDER, "cmps"}, {0xA7, UNSET_OP_ORDER, "cmps"}, - {-1, UNSET_OP_ORDER, ""}}; + {0xAB, UNSET_OP_ORDER, "stos"}, {0xA4, UNSET_OP_ORDER, "movs"}, + {0xA5, UNSET_OP_ORDER, "movs"}, {0xA6, UNSET_OP_ORDER, "cmps"}, + {0xA7, UNSET_OP_ORDER, "cmps"}, {-1, UNSET_OP_ORDER, ""}}; static const ByteMnemonic call_jump_instr[] = {{0xE8, UNSET_OP_ORDER, "call"}, {0xE9, UNSET_OP_ORDER, "jmp"}, @@ -1845,7 +1845,9 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { current += 1; } else { const char* mnemonic; - if (opcode == 0x54) { + if (opcode == 0x51) { + mnemonic = "sqrtpd"; + } else if (opcode == 0x54) { mnemonic = "andpd"; } else if (opcode == 0x55) { mnemonic = "andnpd"; @@ -2432,13 +2434,13 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, byte_size_operand_ = idesc.byte_size_operation; switch (idesc.type) { case ZERO_OPERANDS_INSTR: - if (current >= 0xA4 && current <= 0xA7) { + if ((current >= 0xA4 && current <= 0xA7) || + (current >= 0xAA && current <= 0xAD)) { // String move or compare operations. if (group_1_prefix_ == REP_PREFIX) { // REP. AppendToBuffer("rep "); } - if (rex_w()) AppendToBuffer("REX.W "); AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); } else { AppendToBuffer("%s%c", idesc.mnem, operand_size_code()); diff --git a/deps/v8/src/execution/arguments-inl.h b/deps/v8/src/execution/arguments-inl.h index ecdc4ef359ad4b..4565f5d265e13b 100644 --- a/deps/v8/src/execution/arguments-inl.h +++ b/deps/v8/src/execution/arguments-inl.h @@ -14,15 +14,15 @@ namespace v8 { namespace internal { template <class S> -Handle<S> Arguments::at(int index) { +Handle<S> Arguments::at(int index) const { return Handle<S>::cast(at<Object>(index)); } -int Arguments::smi_at(int index) { +int Arguments::smi_at(int index) const { return Smi::ToInt(Object(*address_of_arg_at(index))); } -double Arguments::number_at(int index) { return (*this)[index].Number(); } +double Arguments::number_at(int index) const { return (*this)[index].Number(); } } // namespace internal } // namespace v8 diff --git a/deps/v8/src/execution/arguments.h b/deps/v8/src/execution/arguments.h index 8f07dd9db3eca3..77bbe62dfc64cd 100644 --- a/deps/v8/src/execution/arguments.h +++ b/deps/v8/src/execution/arguments.h @@ -37,24 +37,26 @@ class Arguments { DCHECK_GE(length_, 0); } - Object operator[](int index) { return Object(*address_of_arg_at(index)); } + Object operator[](int index) const { + return Object(*address_of_arg_at(index)); + } template <class S = Object> - inline Handle<S> at(int index); + inline Handle<S> at(int index) const; - inline int smi_at(int index); + inline int smi_at(int index) const; - inline double number_at(int index); + inline double number_at(int index) const; inline void set_at(int index, Object value) { *address_of_arg_at(index) = value.ptr(); } - inline FullObjectSlot slot_at(int index) { + inline FullObjectSlot slot_at(int index) const { return FullObjectSlot(address_of_arg_at(index)); } - inline Address* address_of_arg_at(int index) { + inline Address* address_of_arg_at(int index) const { DCHECK_LT(static_cast<uint32_t>(index), static_cast<uint32_t>(length_)); return reinterpret_cast<Address*>(reinterpret_cast<Address>(arguments_) - index * kSystemPointerSize); @@ -64,8 +66,8 @@ class Arguments { int length() const { return static_cast<int>(length_); } // Arguments on the stack are in reverse order (compared to an array). - FullObjectSlot first_slot() { return slot_at(length() - 1); } - FullObjectSlot last_slot() { return slot_at(0); } + FullObjectSlot first_slot() const { return slot_at(length() - 1); } + FullObjectSlot last_slot() const { return slot_at(0); } private: intptr_t length_; @@ -73,7 +75,7 @@ class Arguments { }; template <> -inline Handle<Object> Arguments::at(int index) { +inline Handle<Object> Arguments::at(int index) const { return Handle<Object>(address_of_arg_at(index)); } diff --git a/deps/v8/src/execution/arm/simulator-arm.cc b/deps/v8/src/execution/arm/simulator-arm.cc index 26771350961f7d..841ff4bfd4f573 100644 --- a/deps/v8/src/execution/arm/simulator-arm.cc +++ b/deps/v8/src/execution/arm/simulator-arm.cc @@ -12,6 +12,8 @@ #include "src/base/bits.h" #include "src/base/lazy-instance.h" +#include "src/base/memory.h" +#include "src/base/overflowing-math.h" #include "src/codegen/arm/constants-arm.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/macro-assembler.h" @@ -899,16 +901,14 @@ int Simulator::ReadW(int32_t addr) { // check the alignment here. base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<intptr_t>(addr); } int Simulator::ReadExW(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoadExcl(addr, TransactionSize::Word); GlobalMonitor::Get()->NotifyLoadExcl_Locked(addr, &global_monitor_processor_); - intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<intptr_t>(addr); } void Simulator::WriteW(int32_t addr, int value) { @@ -917,8 +917,7 @@ void Simulator::WriteW(int32_t addr, int value) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); - *ptr = value; + base::WriteUnalignedValue<intptr_t>(addr, value); } int Simulator::WriteExW(int32_t addr, int value) { @@ -926,8 +925,7 @@ int Simulator::WriteExW(int32_t addr, int value) { if (local_monitor_.NotifyStoreExcl(addr, TransactionSize::Word) && GlobalMonitor::Get()->NotifyStoreExcl_Locked( addr, &global_monitor_processor_)) { - intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); - *ptr = value; + base::WriteUnalignedValue<intptr_t>(addr, value); return 0; } else { return 1; @@ -939,8 +937,7 @@ uint16_t Simulator::ReadHU(int32_t addr) { // check the alignment here. base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<uint16_t>(addr); } int16_t Simulator::ReadH(int32_t addr) { @@ -948,16 +945,14 @@ int16_t Simulator::ReadH(int32_t addr) { // check the alignment here. base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - int16_t* ptr = reinterpret_cast<int16_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<int16_t>(addr); } uint16_t Simulator::ReadExHU(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoadExcl(addr, TransactionSize::HalfWord); GlobalMonitor::Get()->NotifyLoadExcl_Locked(addr, &global_monitor_processor_); - uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<uint16_t>(addr); } void Simulator::WriteH(int32_t addr, uint16_t value) { @@ -966,8 +961,7 @@ void Simulator::WriteH(int32_t addr, uint16_t value) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); } void Simulator::WriteH(int32_t addr, int16_t value) { @@ -976,8 +970,7 @@ void Simulator::WriteH(int32_t addr, int16_t value) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - int16_t* ptr = reinterpret_cast<int16_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); } int Simulator::WriteExH(int32_t addr, uint16_t value) { @@ -985,8 +978,7 @@ int Simulator::WriteExH(int32_t addr, uint16_t value) { if (local_monitor_.NotifyStoreExcl(addr, TransactionSize::HalfWord) && GlobalMonitor::Get()->NotifyStoreExcl_Locked( addr, &global_monitor_processor_)) { - uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); return 0; } else { return 1; @@ -996,39 +988,34 @@ int Simulator::WriteExH(int32_t addr, uint16_t value) { uint8_t Simulator::ReadBU(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<uint8_t>(addr); } int8_t Simulator::ReadB(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - int8_t* ptr = reinterpret_cast<int8_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<int8_t>(addr); } uint8_t Simulator::ReadExBU(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoadExcl(addr, TransactionSize::Byte); GlobalMonitor::Get()->NotifyLoadExcl_Locked(addr, &global_monitor_processor_); - uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); - return *ptr; + return base::ReadUnalignedValue<uint8_t>(addr); } void Simulator::WriteB(int32_t addr, uint8_t value) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); } void Simulator::WriteB(int32_t addr, int8_t value) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - int8_t* ptr = reinterpret_cast<int8_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); } int Simulator::WriteExB(int32_t addr, uint8_t value) { @@ -1036,8 +1023,7 @@ int Simulator::WriteExB(int32_t addr, uint8_t value) { if (local_monitor_.NotifyStoreExcl(addr, TransactionSize::Byte) && GlobalMonitor::Get()->NotifyStoreExcl_Locked( addr, &global_monitor_processor_)) { - uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); - *ptr = value; + base::WriteUnalignedValue(addr, value); return 0; } else { return 1; @@ -1049,16 +1035,14 @@ int32_t* Simulator::ReadDW(int32_t addr) { // check the alignment here. base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoad(addr); - int32_t* ptr = reinterpret_cast<int32_t*>(addr); - return ptr; + return reinterpret_cast<int32_t*>(addr); } int32_t* Simulator::ReadExDW(int32_t addr) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyLoadExcl(addr, TransactionSize::DoubleWord); GlobalMonitor::Get()->NotifyLoadExcl_Locked(addr, &global_monitor_processor_); - int32_t* ptr = reinterpret_cast<int32_t*>(addr); - return ptr; + return reinterpret_cast<int32_t*>(addr); } void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) { @@ -1067,9 +1051,8 @@ void Simulator::WriteDW(int32_t addr, int32_t value1, int32_t value2) { base::MutexGuard lock_guard(&GlobalMonitor::Get()->mutex); local_monitor_.NotifyStore(addr); GlobalMonitor::Get()->NotifyStore_Locked(addr, &global_monitor_processor_); - int32_t* ptr = reinterpret_cast<int32_t*>(addr); - *ptr++ = value1; - *ptr = value2; + base::WriteUnalignedValue(addr, value1); + base::WriteUnalignedValue(addr + sizeof(value1), value2); } int Simulator::WriteExDW(int32_t addr, int32_t value1, int32_t value2) { @@ -1077,9 +1060,8 @@ int Simulator::WriteExDW(int32_t addr, int32_t value1, int32_t value2) { if (local_monitor_.NotifyStoreExcl(addr, TransactionSize::DoubleWord) && GlobalMonitor::Get()->NotifyStoreExcl_Locked( addr, &global_monitor_processor_)) { - intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); - *ptr++ = value1; - *ptr = value2; + base::WriteUnalignedValue(addr, value1); + base::WriteUnalignedValue(addr + sizeof(value1), value2); return 0; } else { return 1; @@ -1291,9 +1273,9 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) { if (shift_amount == 0) { *carry_out = c_flag_; } else { - result <<= (shift_amount - 1); + result = static_cast<uint32_t>(result) << (shift_amount - 1); *carry_out = (result < 0); - result <<= 1; + result = static_cast<uint32_t>(result) << 1; } break; } @@ -1316,9 +1298,7 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) { if (shift_amount == 0) { *carry_out = c_flag_; } else { - uint32_t left = static_cast<uint32_t>(result) >> shift_amount; - uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount); - result = right | left; + result = base::bits::RotateRight32(result, shift_amount); *carry_out = (static_cast<uint32_t>(result) >> 31) != 0; } break; @@ -1358,9 +1338,9 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) { if (shift_amount == 0) { *carry_out = c_flag_; } else if (shift_amount < 32) { - result <<= (shift_amount - 1); + result = static_cast<uint32_t>(result) << (shift_amount - 1); *carry_out = (result < 0); - result <<= 1; + result = static_cast<uint32_t>(result) << 1; } else if (shift_amount == 32) { *carry_out = (result & 1) == 1; result = 0; @@ -1395,9 +1375,8 @@ int32_t Simulator::GetShiftRm(Instruction* instr, bool* carry_out) { if (shift_amount == 0) { *carry_out = c_flag_; } else { - uint32_t left = static_cast<uint32_t>(result) >> shift_amount; - uint32_t right = static_cast<uint32_t>(result) << (32 - shift_amount); - result = right | left; + // Avoid undefined behavior. Rotating by multiples of 32 is no-op. + result = base::bits::RotateRight32(result, shift_amount & 31); *carry_out = (static_cast<uint32_t>(result) >> 31) != 0; } break; @@ -1580,6 +1559,34 @@ using SimulatorRuntimeDirectGetterCall = void (*)(int32_t arg0, int32_t arg1); using SimulatorRuntimeProfilingGetterCall = void (*)(int32_t arg0, int32_t arg1, void* arg2); +// Separate for fine-grained UBSan blacklisting. Casting any given C++ +// function to {SimulatorRuntimeCall} is undefined behavior; but since +// the target function can indeed be any function that's exposed via +// the "fast C call" mechanism, we can't reconstruct its signature here. +int64_t UnsafeGenericFunctionCall(intptr_t function, int32_t arg0, int32_t arg1, + int32_t arg2, int32_t arg3, int32_t arg4, + int32_t arg5, int32_t arg6, int32_t arg7, + int32_t arg8, int32_t arg9) { + SimulatorRuntimeCall target = + reinterpret_cast<SimulatorRuntimeCall>(function); + return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); +} +void UnsafeDirectApiCall(intptr_t function, int32_t arg0) { + SimulatorRuntimeDirectApiCall target = + reinterpret_cast<SimulatorRuntimeDirectApiCall>(function); + target(arg0); +} +void UnsafeProfilingApiCall(intptr_t function, int32_t arg0, int32_t arg1) { + SimulatorRuntimeProfilingApiCall target = + reinterpret_cast<SimulatorRuntimeProfilingApiCall>(function); + target(arg0, Redirection::ReverseRedirection(arg1)); +} +void UnsafeDirectGetterCall(intptr_t function, int32_t arg0, int32_t arg1) { + SimulatorRuntimeDirectGetterCall target = + reinterpret_cast<SimulatorRuntimeDirectGetterCall>(function); + target(arg0, arg1); +} + // Software interrupt instructions are used by the simulator to call into the // C-based V8 runtime. void Simulator::SoftwareInterrupt(Instruction* instr) { @@ -1710,9 +1717,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { PrintF("\n"); } CHECK(stack_aligned); - SimulatorRuntimeDirectApiCall target = - reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); - target(arg0); + UnsafeDirectApiCall(external, arg0); } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) { PrintF("Call to host function at %p args %08x %08x", @@ -1723,9 +1728,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { PrintF("\n"); } CHECK(stack_aligned); - SimulatorRuntimeProfilingApiCall target = - reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); - target(arg0, Redirection::ReverseRedirection(arg1)); + UnsafeProfilingApiCall(external, arg0, arg1); } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) { PrintF("Call to host function at %p args %08x %08x", @@ -1736,9 +1739,7 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { PrintF("\n"); } CHECK(stack_aligned); - SimulatorRuntimeDirectGetterCall target = - reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); - target(arg0, arg1); + UnsafeDirectGetterCall(external, arg0, arg1); } else if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) { if (::v8::internal::FLAG_trace_sim || !stack_aligned) { @@ -1757,14 +1758,12 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { // builtin call. DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL || redirection->type() == ExternalReference::BUILTIN_CALL_PAIR); - SimulatorRuntimeCall target = - reinterpret_cast<SimulatorRuntimeCall>(external); if (::v8::internal::FLAG_trace_sim || !stack_aligned) { PrintF( "Call to host function at %p " "args %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x", - reinterpret_cast<void*>(FUNCTION_ADDR(target)), arg0, arg1, arg2, - arg3, arg4, arg5, arg6, arg7, arg8, arg9); + reinterpret_cast<void*>(external), arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9); if (!stack_aligned) { PrintF(" with unaligned stack %08x\n", get_register(sp)); } @@ -1772,7 +1771,8 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { } CHECK(stack_aligned); int64_t result = - target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + UnsafeGenericFunctionCall(external, arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9); int32_t lo_res = static_cast<int32_t>(result); int32_t hi_res = static_cast<int32_t>(result >> 32); if (::v8::internal::FLAG_trace_sim) { @@ -1938,7 +1938,7 @@ void Simulator::DecodeType01(Instruction* instr) { // Rn field to encode it. // Format(instr, "mul'cond's 'rn, 'rm, 'rs"); int rd = rn; // Remap the rn field to the Rd register. - int32_t alu_out = rm_val * rs_val; + int32_t alu_out = base::MulWithWraparound(rm_val, rs_val); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -1952,13 +1952,13 @@ void Simulator::DecodeType01(Instruction* instr) { // Rn field to encode the Rd register and the Rd field to encode // the Rn register. // Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); - int32_t mul_out = rm_val * rs_val; - int32_t result = acc_value + mul_out; + int32_t mul_out = base::MulWithWraparound(rm_val, rs_val); + int32_t result = base::AddWithWraparound(acc_value, mul_out); set_register(rn, result); } else { // Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd"); - int32_t mul_out = rm_val * rs_val; - int32_t result = acc_value - mul_out; + int32_t mul_out = base::MulWithWraparound(rm_val, rs_val); + int32_t result = base::SubWithWraparound(acc_value, mul_out); set_register(rn, result); } } @@ -2096,7 +2096,7 @@ void Simulator::DecodeType01(Instruction* instr) { // Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm"); DCHECK(!instr->HasW()); addr = rn_val; - rn_val -= rm_val; + rn_val = base::SubWithWraparound(rn_val, rm_val); set_register(rn, rn_val); break; } @@ -2104,13 +2104,13 @@ void Simulator::DecodeType01(Instruction* instr) { // Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm"); DCHECK(!instr->HasW()); addr = rn_val; - rn_val += rm_val; + rn_val = base::AddWithWraparound(rn_val, rm_val); set_register(rn, rn_val); break; } case db_x: { // Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w"); - rn_val -= rm_val; + rn_val = base::SubWithWraparound(rn_val, rm_val); addr = rn_val; if (instr->HasW()) { set_register(rn, rn_val); @@ -2119,7 +2119,7 @@ void Simulator::DecodeType01(Instruction* instr) { } case ib_x: { // Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w"); - rn_val += rm_val; + rn_val = base::AddWithWraparound(rn_val, rm_val); addr = rn_val; if (instr->HasW()) { set_register(rn, rn_val); @@ -2139,7 +2139,7 @@ void Simulator::DecodeType01(Instruction* instr) { // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8"); DCHECK(!instr->HasW()); addr = rn_val; - rn_val -= imm_val; + rn_val = base::SubWithWraparound(rn_val, imm_val); set_register(rn, rn_val); break; } @@ -2147,13 +2147,13 @@ void Simulator::DecodeType01(Instruction* instr) { // Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8"); DCHECK(!instr->HasW()); addr = rn_val; - rn_val += imm_val; + rn_val = base::AddWithWraparound(rn_val, imm_val); set_register(rn, rn_val); break; } case db_x: { // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w"); - rn_val -= imm_val; + rn_val = base::SubWithWraparound(rn_val, imm_val); addr = rn_val; if (instr->HasW()) { set_register(rn, rn_val); @@ -2162,7 +2162,7 @@ void Simulator::DecodeType01(Instruction* instr) { } case ib_x: { // Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w"); - rn_val += imm_val; + rn_val = base::AddWithWraparound(rn_val, imm_val); addr = rn_val; if (instr->HasW()) { set_register(rn, rn_val); @@ -2328,7 +2328,7 @@ void Simulator::DecodeType01(Instruction* instr) { case SUB: { // Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm"); // Format(instr, "sub'cond's 'rd, 'rn, 'imm"); - alu_out = rn_val - shifter_operand; + alu_out = base::SubWithWraparound(rn_val, shifter_operand); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -2341,7 +2341,7 @@ void Simulator::DecodeType01(Instruction* instr) { case RSB: { // Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm"); // Format(instr, "rsb'cond's 'rd, 'rn, 'imm"); - alu_out = shifter_operand - rn_val; + alu_out = base::SubWithWraparound(shifter_operand, rn_val); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -2354,7 +2354,7 @@ void Simulator::DecodeType01(Instruction* instr) { case ADD: { // Format(instr, "add'cond's 'rd, 'rn, 'shift_rm"); // Format(instr, "add'cond's 'rd, 'rn, 'imm"); - alu_out = rn_val + shifter_operand; + alu_out = base::AddWithWraparound(rn_val, shifter_operand); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -2367,7 +2367,8 @@ void Simulator::DecodeType01(Instruction* instr) { case ADC: { // Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm"); // Format(instr, "adc'cond's 'rd, 'rn, 'imm"); - alu_out = rn_val + shifter_operand + GetCarry(); + alu_out = base::AddWithWraparound( + base::AddWithWraparound(rn_val, shifter_operand), GetCarry()); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -2380,7 +2381,9 @@ void Simulator::DecodeType01(Instruction* instr) { case SBC: { // Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm"); // Format(instr, "sbc'cond's 'rd, 'rn, 'imm"); - alu_out = (rn_val - shifter_operand) - (GetCarry() ? 0 : 1); + alu_out = base::SubWithWraparound( + base::SubWithWraparound(rn_val, shifter_operand), + (GetCarry() ? 0 : 1)); set_register(rd, alu_out); if (instr->HasS()) { SetNZFlags(alu_out); @@ -2430,7 +2433,7 @@ void Simulator::DecodeType01(Instruction* instr) { if (instr->HasS()) { // Format(instr, "cmp'cond 'rn, 'shift_rm"); // Format(instr, "cmp'cond 'rn, 'imm"); - alu_out = rn_val - shifter_operand; + alu_out = base::SubWithWraparound(rn_val, shifter_operand); SetNZFlags(alu_out); SetCFlag(!BorrowFrom(rn_val, shifter_operand)); SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); @@ -2447,7 +2450,7 @@ void Simulator::DecodeType01(Instruction* instr) { if (instr->HasS()) { // Format(instr, "cmn'cond 'rn, 'shift_rm"); // Format(instr, "cmn'cond 'rn, 'imm"); - alu_out = rn_val + shifter_operand; + alu_out = base::AddWithWraparound(rn_val, shifter_operand); SetNZFlags(alu_out); SetCFlag(CarryFrom(rn_val, shifter_operand)); SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true)); @@ -2937,7 +2940,7 @@ void Simulator::DecodeType3(Instruction* instr) { } else { // sbfx - signed bitfield extract. int32_t rm_val = get_register(instr->RmValue()); - int32_t extr_val = rm_val << (31 - msbit); + int32_t extr_val = static_cast<uint32_t>(rm_val) << (31 - msbit); extr_val = extr_val >> (31 - widthminus1); set_register(instr->RdValue(), extr_val); } @@ -2969,7 +2972,7 @@ void Simulator::DecodeType3(Instruction* instr) { return; } else { // Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); - addr = rn_val + shifter_operand; + addr = base::AddWithWraparound(rn_val, shifter_operand); if (instr->HasW()) { set_register(rn, addr); } @@ -3010,7 +3013,8 @@ void Simulator::DecodeType4(Instruction* instr) { void Simulator::DecodeType5(Instruction* instr) { // Format(instr, "b'l'cond 'target"); - int off = (instr->SImmed24Value() << 2); + int off = + static_cast<int>(static_cast<uint32_t>(instr->SImmed24Value()) << 2); intptr_t pc_address = get_pc(); if (instr->HasLink()) { set_register(lr, pc_address + kInstrSize); @@ -3259,14 +3263,14 @@ void Simulator::DecodeTypeVFP(Instruction* instr) { if (instr->SzValue() == 0x1) { double dn_value = get_double_from_d_register(vn).get_scalar(); double dm_value = get_double_from_d_register(vm).get_scalar(); - double dd_value = dn_value / dm_value; + double dd_value = base::Divide(dn_value, dm_value); div_zero_vfp_flag_ = (dm_value == 0); dd_value = canonicalizeNaN(dd_value); set_d_register_from_double(vd, dd_value); } else { float sn_value = get_float_from_s_register(n).get_scalar(); float sm_value = get_float_from_s_register(m).get_scalar(); - float sd_value = sn_value / sm_value; + float sd_value = base::Divide(sn_value, sm_value); div_zero_vfp_flag_ = (sm_value == 0); sd_value = canonicalizeNaN(sd_value); set_s_register_from_float(d, sd_value); @@ -3594,10 +3598,22 @@ int VFPConversionSaturate(double val, bool unsigned_res) { int32_t Simulator::ConvertDoubleToInt(double val, bool unsigned_integer, VFPRoundingMode mode) { - // TODO(jkummerow): These casts are undefined behavior if the integral - // part of {val} does not fit into the destination type. - int32_t result = - unsigned_integer ? static_cast<uint32_t>(val) : static_cast<int32_t>(val); + int32_t result; + if (unsigned_integer) { + // The FastD2UI helper does not have the rounding behavior we want here + // (it doesn't guarantee any particular rounding, and it doesn't check + // for or handle overflow), so do the conversion by hand. + using limits = std::numeric_limits<uint32_t>; + if (val > limits::max()) { + result = limits::max(); + } else if (!(val >= 0)) { // Negation to catch NaNs. + result = 0; + } else { + result = static_cast<uint32_t>(val); + } + } else { + result = FastD2IChecked(val); + } inv_op_vfp_flag_ = get_inv_op_vfp_flag(mode, val, unsigned_integer); @@ -3617,7 +3633,9 @@ int32_t Simulator::ConvertDoubleToInt(double val, bool unsigned_integer, result += val_sign; } else if (abs_diff == 0.5) { // Round to even if exactly halfway. - result = ((result % 2) == 0) ? result : result + val_sign; + result = ((result % 2) == 0) + ? result + : base::AddWithWraparound(result, val_sign); } break; } @@ -3873,7 +3891,11 @@ void Neg(Simulator* simulator, int Vd, int Vm) { T src[kElems]; simulator->get_neon_register<T, SIZE>(Vm, src); for (int i = 0; i < kElems; i++) { - src[i] = -src[i]; + if (src[i] != std::numeric_limits<T>::min()) { + src[i] = -src[i]; + } else { + // The respective minimum (negative) value maps to itself. + } } simulator->set_neon_register<T, SIZE>(Vd, src); } @@ -3998,6 +4020,17 @@ void Sub(Simulator* simulator, int Vd, int Vm, int Vn) { simulator->set_neon_register<T, SIZE>(Vd, src1); } +namespace { +uint32_t Multiply(uint32_t a, uint32_t b) { return a * b; } +uint8_t Multiply(uint8_t a, uint8_t b) { return a * b; } +// 16-bit integers are special due to C++'s implicit conversion rules. +// See https://bugs.llvm.org/show_bug.cgi?id=25580. +uint16_t Multiply(uint16_t a, uint16_t b) { + uint32_t result = static_cast<uint32_t>(a) * static_cast<uint32_t>(b); + return static_cast<uint16_t>(result); +} +} // namespace + template <typename T, int SIZE> void Mul(Simulator* simulator, int Vd, int Vm, int Vn) { static const int kElems = SIZE / sizeof(T); @@ -4005,7 +4038,7 @@ void Mul(Simulator* simulator, int Vd, int Vm, int Vn) { simulator->get_neon_register<T, SIZE>(Vn, src1); simulator->get_neon_register<T, SIZE>(Vm, src2); for (int i = 0; i < kElems; i++) { - src1[i] *= src2[i]; + src1[i] = Multiply(src1[i], src2[i]); } simulator->set_neon_register<T, SIZE>(Vd, src1); } @@ -4090,7 +4123,8 @@ void ShiftByRegister(Simulator* simulator, int Vd, int Vm, int Vn) { if (shift_value >= size) { src[i] = 0; } else { - src[i] <<= shift_value; + using unsignedT = typename std::make_unsigned<T>::type; + src[i] = static_cast<unsignedT>(src[i]) << shift_value; } } else { // If the shift value is greater/equal than size, always end up with -1. @@ -5721,7 +5755,7 @@ void Simulator::Execute() { // should be stopping at a particular executed instruction. while (program_counter != end_sim_pc) { Instruction* instr = reinterpret_cast<Instruction*>(program_counter); - icount_++; + icount_ = base::AddWithWraparound(icount_, 1); InstructionDecode(instr); program_counter = get_pc(); } @@ -5730,7 +5764,7 @@ void Simulator::Execute() { // we reach the particular instruction count. while (program_counter != end_sim_pc) { Instruction* instr = reinterpret_cast<Instruction*>(program_counter); - icount_++; + icount_ = base::AddWithWraparound(icount_, 1); if (icount_ == ::v8::internal::FLAG_stop_sim_at) { ArmDebugger dbg(this); dbg.Debug(); diff --git a/deps/v8/src/execution/arm64/simulator-arm64.cc b/deps/v8/src/execution/arm64/simulator-arm64.cc index 71fedd5b2fff5c..d3a73cbad87218 100644 --- a/deps/v8/src/execution/arm64/simulator-arm64.cc +++ b/deps/v8/src/execution/arm64/simulator-arm64.cc @@ -12,6 +12,7 @@ #include <type_traits> #include "src/base/lazy-instance.h" +#include "src/base/overflowing-math.h" #include "src/codegen/arm64/decoder-arm64-inl.h" #include "src/codegen/assembler-inl.h" #include "src/codegen/macro-assembler.h" @@ -154,6 +155,22 @@ void Simulator::CallImpl(Address entry, CallArgument* args) { set_sp(original_stack); } +#ifdef DEBUG +namespace { +int PopLowestIndexAsCode(CPURegList* list) { + if (list->IsEmpty()) { + return -1; + } + RegList reg_list = list->list(); + int index = base::bits::CountTrailingZeros(reg_list); + DCHECK((1LL << index) & reg_list); + list->Remove(index); + + return index; +} +} // namespace +#endif + void Simulator::CheckPCSComplianceAndRun() { // Adjust JS-based stack limit to C-based stack limit. isolate_->stack_guard()->AdjustStackLimitForSimulator(); @@ -171,10 +188,10 @@ void Simulator::CheckPCSComplianceAndRun() { for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) { // x31 is not a caller saved register, so no need to specify if we want // the stack or zero. - saved_registers[i] = xreg(register_list.PopLowestIndex().code()); + saved_registers[i] = xreg(PopLowestIndexAsCode(®ister_list)); } for (int i = 0; i < kNumberOfCalleeSavedVRegisters; i++) { - saved_fpregisters[i] = dreg_bits(fpregister_list.PopLowestIndex().code()); + saved_fpregisters[i] = dreg_bits(PopLowestIndexAsCode(&fpregister_list)); } int64_t original_stack = sp(); #endif @@ -186,11 +203,11 @@ void Simulator::CheckPCSComplianceAndRun() { register_list = kCalleeSaved; fpregister_list = kCalleeSavedV; for (int i = 0; i < kNumberOfCalleeSavedRegisters; i++) { - DCHECK_EQ(saved_registers[i], xreg(register_list.PopLowestIndex().code())); + DCHECK_EQ(saved_registers[i], xreg(PopLowestIndexAsCode(®ister_list))); } for (int i = 0; i < kNumberOfCalleeSavedVRegisters; i++) { DCHECK(saved_fpregisters[i] == - dreg_bits(fpregister_list.PopLowestIndex().code())); + dreg_bits(PopLowestIndexAsCode(&fpregister_list))); } // Corrupt caller saved register minus the return regiters. @@ -217,13 +234,13 @@ void Simulator::CheckPCSComplianceAndRun() { void Simulator::CorruptRegisters(CPURegList* list, uint64_t value) { if (list->type() == CPURegister::kRegister) { while (!list->IsEmpty()) { - unsigned code = list->PopLowestIndex().code(); + unsigned code = PopLowestIndexAsCode(list); set_xreg(code, value | code); } } else { DCHECK_EQ(list->type(), CPURegister::kVRegister); while (!list->IsEmpty()) { - unsigned code = list->PopLowestIndex().code(); + unsigned code = PopLowestIndexAsCode(list); set_dreg_bits(code, value | code); } } @@ -414,6 +431,34 @@ using SimulatorRuntimeDirectGetterCall = void (*)(int64_t arg0, int64_t arg1); using SimulatorRuntimeProfilingGetterCall = void (*)(int64_t arg0, int64_t arg1, void* arg2); +// Separate for fine-grained UBSan blacklisting. Casting any given C++ +// function to {SimulatorRuntimeCall} is undefined behavior; but since +// the target function can indeed be any function that's exposed via +// the "fast C call" mechanism, we can't reconstruct its signature here. +ObjectPair UnsafeGenericFunctionCall(int64_t function, int64_t arg0, + int64_t arg1, int64_t arg2, int64_t arg3, + int64_t arg4, int64_t arg5, int64_t arg6, + int64_t arg7, int64_t arg8, int64_t arg9) { + SimulatorRuntimeCall target = + reinterpret_cast<SimulatorRuntimeCall>(function); + return target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); +} +void UnsafeDirectApiCall(int64_t function, int64_t arg0) { + SimulatorRuntimeDirectApiCall target = + reinterpret_cast<SimulatorRuntimeDirectApiCall>(function); + target(arg0); +} +void UnsafeProfilingApiCall(int64_t function, int64_t arg0, void* arg1) { + SimulatorRuntimeProfilingApiCall target = + reinterpret_cast<SimulatorRuntimeProfilingApiCall>(function); + target(arg0, arg1); +} +void UnsafeDirectGetterCall(int64_t function, int64_t arg0, int64_t arg1) { + SimulatorRuntimeDirectGetterCall target = + reinterpret_cast<SimulatorRuntimeDirectGetterCall>(function); + target(arg0, arg1); +} + void Simulator::DoRuntimeCall(Instruction* instr) { Redirection* redirection = Redirection::FromInstruction(instr); @@ -515,10 +560,8 @@ void Simulator::DoRuntimeCall(Instruction* instr) { ", " "0x%016" PRIx64 ", 0x%016" PRIx64, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); - SimulatorRuntimeCall target = - reinterpret_cast<SimulatorRuntimeCall>(external); - ObjectPair result = - target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + ObjectPair result = UnsafeGenericFunctionCall( + external, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); TraceSim("Returned: {%p, %p}\n", reinterpret_cast<void*>(result.x), reinterpret_cast<void*>(result.y)); #ifdef DEBUG @@ -532,10 +575,8 @@ void Simulator::DoRuntimeCall(Instruction* instr) { case ExternalReference::DIRECT_API_CALL: { // void f(v8::FunctionCallbackInfo&) TraceSim("Type: DIRECT_API_CALL\n"); - SimulatorRuntimeDirectApiCall target = - reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); TraceSim("Arguments: 0x%016" PRIx64 "\n", xreg(0)); - target(xreg(0)); + UnsafeDirectApiCall(external, xreg(0)); TraceSim("No return value."); #ifdef DEBUG CorruptAllCallerSavedCPURegisters(); @@ -606,11 +647,9 @@ void Simulator::DoRuntimeCall(Instruction* instr) { case ExternalReference::DIRECT_GETTER_CALL: { // void f(Local<String> property, PropertyCallbackInfo& info) TraceSim("Type: DIRECT_GETTER_CALL\n"); - SimulatorRuntimeDirectGetterCall target = - reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external); TraceSim("Arguments: 0x%016" PRIx64 ", 0x%016" PRIx64 "\n", xreg(0), xreg(1)); - target(xreg(0), xreg(1)); + UnsafeDirectGetterCall(external, xreg(0), xreg(1)); TraceSim("No return value."); #ifdef DEBUG CorruptAllCallerSavedCPURegisters(); @@ -621,11 +660,9 @@ void Simulator::DoRuntimeCall(Instruction* instr) { case ExternalReference::PROFILING_API_CALL: { // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback) TraceSim("Type: PROFILING_API_CALL\n"); - SimulatorRuntimeProfilingApiCall target = - reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external); void* arg1 = Redirection::ReverseRedirection(xreg(1)); TraceSim("Arguments: 0x%016" PRIx64 ", %p\n", xreg(0), arg1); - target(xreg(0), arg1); + UnsafeProfilingApiCall(external, xreg(0), arg1); TraceSim("No return value."); #ifdef DEBUG CorruptAllCallerSavedCPURegisters(); @@ -849,10 +886,12 @@ T Simulator::ShiftOperand(T value, Shift shift_type, unsigned amount) { if (amount == 0) { return value; } + // Larger shift {amount}s would be undefined behavior in C++. + DCHECK(amount < sizeof(value) * kBitsPerByte); switch (shift_type) { case LSL: - return value << amount; + return static_cast<unsignedT>(value) << amount; case LSR: return static_cast<unsignedT>(value) >> amount; case ASR: @@ -873,6 +912,7 @@ T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8; const unsigned kSignExtendHShift = (sizeof(T) - 2) * 8; const unsigned kSignExtendWShift = (sizeof(T) - 4) * 8; + using unsignedT = typename std::make_unsigned<T>::type; switch (extend_type) { case UXTB: @@ -885,13 +925,19 @@ T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { value &= kWordMask; break; case SXTB: - value = (value << kSignExtendBShift) >> kSignExtendBShift; + value = + static_cast<T>(static_cast<unsignedT>(value) << kSignExtendBShift) >> + kSignExtendBShift; break; case SXTH: - value = (value << kSignExtendHShift) >> kSignExtendHShift; + value = + static_cast<T>(static_cast<unsignedT>(value) << kSignExtendHShift) >> + kSignExtendHShift; break; case SXTW: - value = (value << kSignExtendWShift) >> kSignExtendWShift; + value = + static_cast<T>(static_cast<unsignedT>(value) << kSignExtendWShift) >> + kSignExtendWShift; break; case UXTX: case SXTX: @@ -899,7 +945,7 @@ T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { default: UNREACHABLE(); } - return value << left_shift; + return static_cast<T>(static_cast<unsignedT>(value) << left_shift); } template <typename T> @@ -2283,7 +2329,9 @@ void Simulator::VisitConditionalSelect(Instruction* instr) { break; case CSNEG_w: case CSNEG_x: - new_val = (uint64_t)(-(int64_t)new_val); + // Simulate two's complement (instead of casting to signed and negating) + // to avoid undefined behavior on signed overflow. + new_val = (~new_val) + 1; break; default: UNIMPLEMENTED(); @@ -2446,23 +2494,27 @@ void Simulator::VisitDataProcessing3Source(Instruction* instr) { switch (instr->Mask(DataProcessing3SourceMask)) { case MADD_w: case MADD_x: - result = xreg(instr->Ra()) + (xreg(instr->Rn()) * xreg(instr->Rm())); + result = base::AddWithWraparound( + xreg(instr->Ra()), + base::MulWithWraparound(xreg(instr->Rn()), xreg(instr->Rm()))); break; case MSUB_w: case MSUB_x: - result = xreg(instr->Ra()) - (xreg(instr->Rn()) * xreg(instr->Rm())); + result = base::SubWithWraparound( + xreg(instr->Ra()), + base::MulWithWraparound(xreg(instr->Rn()), xreg(instr->Rm()))); break; case SMADDL_x: - result = xreg(instr->Ra()) + (rn_s32 * rm_s32); + result = base::AddWithWraparound(xreg(instr->Ra()), (rn_s32 * rm_s32)); break; case SMSUBL_x: - result = xreg(instr->Ra()) - (rn_s32 * rm_s32); + result = base::SubWithWraparound(xreg(instr->Ra()), (rn_s32 * rm_s32)); break; case UMADDL_x: - result = xreg(instr->Ra()) + (rn_u32 * rm_u32); + result = static_cast<uint64_t>(xreg(instr->Ra())) + (rn_u32 * rm_u32); break; case UMSUBL_x: - result = xreg(instr->Ra()) - (rn_u32 * rm_u32); + result = static_cast<uint64_t>(xreg(instr->Ra())) - (rn_u32 * rm_u32); break; case SMULH_x: DCHECK_EQ(instr->Ra(), kZeroRegCode); @@ -2488,10 +2540,10 @@ void Simulator::BitfieldHelper(Instruction* instr) { T diff = S - R; T mask; if (diff >= 0) { - mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 + mask = diff < reg_size - 1 ? (static_cast<unsignedT>(1) << (diff + 1)) - 1 : static_cast<T>(-1); } else { - uint64_t umask = ((1LL << (S + 1)) - 1); + uint64_t umask = ((1ULL << (S + 1)) - 1); umask = (umask >> R) | (umask << (reg_size - R)); mask = static_cast<T>(umask); diff += reg_size; @@ -2522,11 +2574,15 @@ void Simulator::BitfieldHelper(Instruction* instr) { T dst = inzero ? 0 : reg<T>(instr->Rd()); T src = reg<T>(instr->Rn()); // Rotate source bitfield into place. - T result = (static_cast<unsignedT>(src) >> R) | (src << (reg_size - R)); + T result = R == 0 ? src + : (static_cast<unsignedT>(src) >> R) | + (static_cast<unsignedT>(src) << (reg_size - R)); // Determine the sign extension. - T topbits_preshift = (static_cast<T>(1) << (reg_size - diff - 1)) - 1; - T signbits = (extend && ((src >> S) & 1) ? topbits_preshift : 0) - << (diff + 1); + T topbits_preshift = (static_cast<unsignedT>(1) << (reg_size - diff - 1)) - 1; + T signbits = + diff >= reg_size - 1 + ? 0 + : ((extend && ((src >> S) & 1) ? topbits_preshift : 0) << (diff + 1)); // Merge sign extension, dest/zero and bitfield. result = signbits | (result & mask) | (dst & ~mask); diff --git a/deps/v8/src/execution/frames.cc b/deps/v8/src/execution/frames.cc index 3b334739da389c..04768a365c24bc 100644 --- a/deps/v8/src/execution/frames.cc +++ b/deps/v8/src/execution/frames.cc @@ -553,14 +553,6 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, return WASM_EXIT; case wasm::WasmCode::kWasmToJsWrapper: return WASM_TO_JS; - case wasm::WasmCode::kRuntimeStub: - // Some stubs, like e.g. {WasmCode::kWasmCompileLazy} build their own - // specialized frame which already carries a type marker. - // TODO(mstarzinger): This is only needed for the case where embedded - // builtins are disabled. It can be removed once all non-embedded - // builtins are gone. - if (StackFrame::IsTypeMarker(marker)) break; - return STUB; case wasm::WasmCode::kInterpreterEntry: return WASM_INTERPRETER_ENTRY; default: @@ -1079,13 +1071,12 @@ Address StubFrame::GetCallerStackPointer() const { return fp() + ExitFrameConstants::kCallerSPOffset; } -int StubFrame::LookupExceptionHandlerInTable(int* stack_slots) { +int StubFrame::LookupExceptionHandlerInTable() { Code code = LookupCode(); DCHECK(code.is_turbofanned()); DCHECK_EQ(code.kind(), Code::BUILTIN); HandlerTable table(code); int pc_offset = static_cast<int>(pc() - code.InstructionStart()); - *stack_slots = code.stack_slots(); return table.LookupReturn(pc_offset); } @@ -1271,6 +1262,7 @@ void JavaScriptFrame::CollectFunctionAndOffsetForICStats(JSFunction function, if (maybe_script.IsScript()) { Script script = Script::cast(maybe_script); ic_info.line_num = script.GetLineNumber(source_pos) + 1; + ic_info.column_num = script.GetColumnNumber(source_pos); ic_info.script_name = ic_stats->GetOrCacheScriptName(script); } } @@ -1627,7 +1619,7 @@ void OptimizedFrame::Summarize(std::vector<FrameSummary>* frames) const { } int OptimizedFrame::LookupExceptionHandlerInTable( - int* stack_slots, HandlerTable::CatchPrediction* prediction) { + int* data, HandlerTable::CatchPrediction* prediction) { // We cannot perform exception prediction on optimized code. Instead, we need // to use FrameSummary to find the corresponding code offset in unoptimized // code to perform prediction there. @@ -1635,7 +1627,7 @@ int OptimizedFrame::LookupExceptionHandlerInTable( Code code = LookupCode(); HandlerTable table(code); int pc_offset = static_cast<int>(pc() - code.InstructionStart()); - if (stack_slots) *stack_slots = code.stack_slots(); + DCHECK_NULL(data); // Data is not used and will not return a value. // When the return pc has been replaced by a trampoline there won't be // a handler for this trampoline. Thus we need to use the return pc that @@ -1676,8 +1668,8 @@ DeoptimizationData OptimizedFrame::GetDeoptimizationData( Object OptimizedFrame::receiver() const { Code code = LookupCode(); if (code.kind() == Code::BUILTIN) { - Address argc_ptr = fp() + OptimizedBuiltinFrameConstants::kArgCOffset; - intptr_t argc = *reinterpret_cast<intptr_t*>(argc_ptr); + intptr_t argc = static_cast<int>( + Memory<intptr_t>(fp() + OptimizedBuiltinFrameConstants::kArgCOffset)); intptr_t args_size = (StandardFrameConstants::kFixedSlotCountAboveFp + argc) * kSystemPointerSize; @@ -1950,15 +1942,13 @@ bool WasmCompiledFrame::at_to_number_conversion() const { return !!pos; } -int WasmCompiledFrame::LookupExceptionHandlerInTable(int* stack_slots) { - DCHECK_NOT_NULL(stack_slots); +int WasmCompiledFrame::LookupExceptionHandlerInTable() { wasm::WasmCode* code = isolate()->wasm_engine()->code_manager()->LookupCode(pc()); if (!code->IsAnonymous() && code->handler_table_size() > 0) { HandlerTable table(code->handler_table(), code->handler_table_size(), HandlerTable::kReturnAddressBasedEncoding); int pc_offset = static_cast<int>(pc() - code->instruction_start()); - *stack_slots = static_cast<int>(code->stack_slots()); return table.LookupReturn(pc_offset); } return -1; diff --git a/deps/v8/src/execution/frames.h b/deps/v8/src/execution/frames.h index d1e7a7890d65ec..165ff854647960 100644 --- a/deps/v8/src/execution/frames.h +++ b/deps/v8/src/execution/frames.h @@ -145,7 +145,12 @@ class StackFrame { intptr_t type = marker >> kSmiTagSize; // TODO(petermarshall): There is a bug in the arm simulators that causes // invalid frame markers. -#if !(defined(USE_SIMULATOR) && (V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM)) +#if defined(USE_SIMULATOR) && (V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM) + if (static_cast<uintptr_t>(type) >= Type::NUMBER_OF_TYPES) { + // Appease UBSan. + return Type::NUMBER_OF_TYPES; + } +#else DCHECK_LT(static_cast<uintptr_t>(type), Type::NUMBER_OF_TYPES); #endif return static_cast<Type>(type); @@ -733,7 +738,7 @@ class JavaScriptFrame : public StandardFrame { // Lookup exception handler for current {pc}, returns -1 if none found. Also // returns data associated with the handler site specific to the frame type: - // - OptimizedFrame : Data is the stack slot count of the entire frame. + // - OptimizedFrame : Data is not used and will not return a value. // - InterpretedFrame: Data is the register index holding the context. virtual int LookupExceptionHandlerInTable( int* data, HandlerTable::CatchPrediction* prediction); @@ -783,10 +788,8 @@ class StubFrame : public StandardFrame { Code unchecked_code() const override; // Lookup exception handler for current {pc}, returns -1 if none found. Only - // TurboFan stub frames are supported. Also returns data associated with the - // handler site: - // - TurboFan stub: Data is the stack slot count of the entire frame. - int LookupExceptionHandlerInTable(int* data); + // TurboFan stub frames are supported. + int LookupExceptionHandlerInTable(); protected: inline explicit StubFrame(StackFrameIteratorBase* iterator); @@ -938,9 +941,8 @@ class WasmCompiledFrame : public StandardFrame { void Print(StringStream* accumulator, PrintMode mode, int index) const override; - // Lookup exception handler for current {pc}, returns -1 if none found. Also - // returns the stack slot count of the entire frame. - int LookupExceptionHandlerInTable(int* data); + // Lookup exception handler for current {pc}, returns -1 if none found. + int LookupExceptionHandlerInTable(); // Determine the code for the frame. Code unchecked_code() const override; diff --git a/deps/v8/src/execution/isolate-inl.h b/deps/v8/src/execution/isolate-inl.h index e1b021b921d2d4..091b185a302fff 100644 --- a/deps/v8/src/execution/isolate-inl.h +++ b/deps/v8/src/execution/isolate-inl.h @@ -113,61 +113,6 @@ Isolate::ExceptionScope::~ExceptionScope() { NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR) #undef NATIVE_CONTEXT_FIELD_ACCESSOR -bool Isolate::IsArrayConstructorIntact() { - Cell array_constructor_cell = - Cell::cast(root(RootIndex::kArrayConstructorProtector)); - return array_constructor_cell.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsTypedArraySpeciesLookupChainIntact() { - PropertyCell species_cell = - PropertyCell::cast(root(RootIndex::kTypedArraySpeciesProtector)); - return species_cell.value().IsSmi() && - Smi::ToInt(species_cell.value()) == kProtectorValid; -} - -bool Isolate::IsPromiseSpeciesLookupChainIntact() { - PropertyCell species_cell = - PropertyCell::cast(root(RootIndex::kPromiseSpeciesProtector)); - return species_cell.value().IsSmi() && - Smi::ToInt(species_cell.value()) == kProtectorValid; -} - -bool Isolate::IsStringLengthOverflowIntact() { - Cell string_length_cell = Cell::cast(root(RootIndex::kStringLengthProtector)); - return string_length_cell.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsArrayBufferDetachingIntact() { - PropertyCell buffer_detaching = - PropertyCell::cast(root(RootIndex::kArrayBufferDetachingProtector)); - return buffer_detaching.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsArrayIteratorLookupChainIntact() { - PropertyCell array_iterator_cell = - PropertyCell::cast(root(RootIndex::kArrayIteratorProtector)); - return array_iterator_cell.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsMapIteratorLookupChainIntact() { - PropertyCell map_iterator_cell = - PropertyCell::cast(root(RootIndex::kMapIteratorProtector)); - return map_iterator_cell.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsSetIteratorLookupChainIntact() { - PropertyCell set_iterator_cell = - PropertyCell::cast(root(RootIndex::kSetIteratorProtector)); - return set_iterator_cell.value() == Smi::FromInt(kProtectorValid); -} - -bool Isolate::IsStringIteratorLookupChainIntact() { - PropertyCell string_iterator_cell = - PropertyCell::cast(root(RootIndex::kStringIteratorProtector)); - return string_iterator_cell.value() == Smi::FromInt(kProtectorValid); -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc index 3ba39562b15289..e2d5ce8a40af0f 100644 --- a/deps/v8/src/execution/isolate.cc +++ b/deps/v8/src/execution/isolate.cc @@ -15,7 +15,6 @@ #include "src/api/api-inl.h" #include "src/ast/ast-value-factory.h" #include "src/ast/scopes.h" -#include "src/base/adapters.h" #include "src/base/hashmap.h" #include "src/base/platform/platform.h" #include "src/base/sys-info.h" @@ -36,6 +35,7 @@ #include "src/execution/isolate-inl.h" #include "src/execution/messages.h" #include "src/execution/microtask-queue.h" +#include "src/execution/protectors-inl.h" #include "src/execution/runtime-profiler.h" #include "src/execution/simulator.h" #include "src/execution/v8threads.h" @@ -51,6 +51,7 @@ #include "src/logging/counters.h" #include "src/logging/log.h" #include "src/numbers/hash-seed-inl.h" +#include "src/objects/backing-store.h" #include "src/objects/elements.h" #include "src/objects/frame-array-inl.h" #include "src/objects/hash-table-inl.h" @@ -320,7 +321,9 @@ Isolate::FindOrAllocatePerThreadDataForThisThread() { base::MutexGuard lock_guard(&thread_data_table_mutex_); per_thread = thread_data_table_.Lookup(thread_id); if (per_thread == nullptr) { - base::OS::AdjustSchedulingParams(); + if (FLAG_adjust_os_scheduling_parameters) { + base::OS::AdjustSchedulingParams(); + } per_thread = new PerIsolateThreadData(this, thread_id); thread_data_table_.Insert(per_thread); } @@ -1091,12 +1094,14 @@ Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller, } else { Handle<JSAsyncGeneratorObject> async_generator_object = Handle<JSAsyncGeneratorObject>::cast(generator_object); - Handle<AsyncGeneratorRequest> async_generator_request( - AsyncGeneratorRequest::cast(async_generator_object->queue()), - isolate); - Handle<JSPromise> promise( - JSPromise::cast(async_generator_request->promise()), isolate); - CaptureAsyncStackTrace(isolate, promise, &builder); + Handle<Object> queue(async_generator_object->queue(), isolate); + if (!queue->IsUndefined(isolate)) { + Handle<AsyncGeneratorRequest> async_generator_request = + Handle<AsyncGeneratorRequest>::cast(queue); + Handle<JSPromise> promise( + JSPromise::cast(async_generator_request->promise()), isolate); + CaptureAsyncStackTrace(isolate, promise, &builder); + } } } } else { @@ -1701,22 +1706,20 @@ Object Isolate::UnwindAndFindHandler() { // currently being executed. wasm::WasmCodeRefScope code_ref_scope; WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame); - int stack_slots = 0; // Will contain stack slot count of frame. - int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots); + wasm::WasmCode* wasm_code = + wasm_engine()->code_manager()->LookupCode(frame->pc()); + int offset = wasm_frame->LookupExceptionHandlerInTable(); if (offset < 0) break; // Compute the stack pointer from the frame pointer. This ensures that // argument slots on the stack are dropped as returning would. Address return_sp = frame->fp() + StandardFrameConstants::kFixedFrameSizeAboveFp - - stack_slots * kSystemPointerSize; + wasm_code->stack_slots() * kSystemPointerSize; // This is going to be handled by Wasm, so we need to set the TLS flag // again. It was cleared above assuming the frame would be unwound. trap_handler::SetThreadInWasm(); - // Gather information from the frame. - wasm::WasmCode* wasm_code = - wasm_engine()->code_manager()->LookupCode(frame->pc()); return FoundHandler(Context(), wasm_code->instruction_start(), offset, wasm_code->constant_pool(), return_sp, frame->fp()); } @@ -1735,18 +1738,14 @@ Object Isolate::UnwindAndFindHandler() { // For optimized frames we perform a lookup in the handler table. if (!catchable_by_js) break; OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame); - int stack_slots = 0; // Will contain stack slot count of frame. - int offset = - js_frame->LookupExceptionHandlerInTable(&stack_slots, nullptr); + Code code = frame->LookupCode(); + int offset = js_frame->LookupExceptionHandlerInTable(nullptr, nullptr); if (offset < 0) break; // Compute the stack pointer from the frame pointer. This ensures // that argument slots on the stack are dropped as returning would. Address return_sp = frame->fp() + StandardFrameConstants::kFixedFrameSizeAboveFp - - stack_slots * kSystemPointerSize; - - // Gather information from the frame. - Code code = frame->LookupCode(); + code.stack_slots() * kSystemPointerSize; // TODO(bmeurer): Turbofanned BUILTIN frames appear as OPTIMIZED, // but do not have a code kind of OPTIMIZED_FUNCTION. @@ -1767,31 +1766,24 @@ Object Isolate::UnwindAndFindHandler() { // Some stubs are able to handle exceptions. if (!catchable_by_js) break; StubFrame* stub_frame = static_cast<StubFrame*>(frame); +#ifdef DEBUG wasm::WasmCodeRefScope code_ref_scope; - wasm::WasmCode* wasm_code = - wasm_engine()->code_manager()->LookupCode(frame->pc()); - if (wasm_code != nullptr) { - // It is safe to skip Wasm runtime stubs as none of them contain local - // exception handlers. - CHECK_EQ(wasm::WasmCode::kRuntimeStub, wasm_code->kind()); - CHECK_EQ(0, wasm_code->handler_table_size()); - break; - } + DCHECK_NULL(wasm_engine()->code_manager()->LookupCode(frame->pc())); +#endif // DEBUG Code code = stub_frame->LookupCode(); if (!code.IsCode() || code.kind() != Code::BUILTIN || !code.has_handler_table() || !code.is_turbofanned()) { break; } - int stack_slots = 0; // Will contain stack slot count of frame. - int offset = stub_frame->LookupExceptionHandlerInTable(&stack_slots); + int offset = stub_frame->LookupExceptionHandlerInTable(); if (offset < 0) break; // Compute the stack pointer from the frame pointer. This ensures // that argument slots on the stack are dropped as returning would. Address return_sp = frame->fp() + StandardFrameConstants::kFixedFrameSizeAboveFp - - stack_slots * kSystemPointerSize; + code.stack_slots() * kSystemPointerSize; return FoundHandler(Context(), code.InstructionStart(), offset, code.constant_pool(), return_sp, frame->fp()); @@ -2063,7 +2055,7 @@ void Isolate::PrintCurrentStackTrace(FILE* out) { for (int i = 0; i < frames->length(); ++i) { Handle<StackTraceFrame> frame(StackTraceFrame::cast(frames->get(i)), this); - SerializeStackTraceFrame(this, frame, builder); + SerializeStackTraceFrame(this, frame, &builder); } Handle<String> stack_trace = builder.Finish().ToHandleChecked(); @@ -2821,7 +2813,7 @@ Isolate* Isolate::New(IsolateAllocationMode mode) { // IsolateAllocator allocates the memory for the Isolate object according to // the given allocation mode. std::unique_ptr<IsolateAllocator> isolate_allocator = - base::make_unique<IsolateAllocator>(mode); + std::make_unique<IsolateAllocator>(mode); // Construct Isolate object in the allocated memory. void* isolate_ptr = isolate_allocator->isolate_memory(); Isolate* isolate = new (isolate_ptr) Isolate(std::move(isolate_allocator)); @@ -2986,7 +2978,7 @@ void Isolate::Deinit() { optimizing_compile_dispatcher_ = nullptr; } - wasm_engine()->memory_tracker()->DeleteSharedMemoryObjectsOnIsolate(this); + BackingStore::RemoveSharedWasmMemoryObjects(this); heap_.mark_compact_collector()->EnsureSweepingCompleted(); heap_.memory_allocator()->unmapper()->EnsureUnmappingCompleted(); @@ -3805,308 +3797,12 @@ bool Isolate::IsInAnyContext(Object object, uint32_t index) { return false; } -bool Isolate::IsNoElementsProtectorIntact(Context context) { - PropertyCell no_elements_cell = heap()->no_elements_protector(); - bool cell_reports_intact = - no_elements_cell.value().IsSmi() && - Smi::ToInt(no_elements_cell.value()) == kProtectorValid; - -#ifdef DEBUG - Context native_context = context.native_context(); - - Map root_array_map = - native_context.GetInitialJSArrayMap(GetInitialFastElementsKind()); - JSObject initial_array_proto = JSObject::cast( - native_context.get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); - JSObject initial_object_proto = JSObject::cast( - native_context.get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX)); - JSObject initial_string_proto = JSObject::cast( - native_context.get(Context::INITIAL_STRING_PROTOTYPE_INDEX)); - - if (root_array_map.is_null() || initial_array_proto == initial_object_proto) { - // We are in the bootstrapping process, and the entire check sequence - // shouldn't be performed. - return cell_reports_intact; - } - - // Check that the array prototype hasn't been altered WRT empty elements. - if (root_array_map.prototype() != initial_array_proto) { - DCHECK_EQ(false, cell_reports_intact); - return cell_reports_intact; - } - - FixedArrayBase elements = initial_array_proto.elements(); - ReadOnlyRoots roots(heap()); - if (elements != roots.empty_fixed_array() && - elements != roots.empty_slow_element_dictionary()) { - DCHECK_EQ(false, cell_reports_intact); - return cell_reports_intact; - } - - // Check that the Object.prototype hasn't been altered WRT empty elements. - elements = initial_object_proto.elements(); - if (elements != roots.empty_fixed_array() && - elements != roots.empty_slow_element_dictionary()) { - DCHECK_EQ(false, cell_reports_intact); - return cell_reports_intact; - } - - // Check that the Array.prototype has the Object.prototype as its - // [[Prototype]] and that the Object.prototype has a null [[Prototype]]. - PrototypeIterator iter(this, initial_array_proto); - if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) { - DCHECK_EQ(false, cell_reports_intact); - DCHECK(!has_pending_exception()); - return cell_reports_intact; - } - iter.Advance(); - if (!iter.IsAtEnd()) { - DCHECK_EQ(false, cell_reports_intact); - DCHECK(!has_pending_exception()); - return cell_reports_intact; - } - DCHECK(!has_pending_exception()); - - // Check that the String.prototype hasn't been altered WRT empty elements. - elements = initial_string_proto.elements(); - if (elements != roots.empty_fixed_array() && - elements != roots.empty_slow_element_dictionary()) { - DCHECK_EQ(false, cell_reports_intact); - return cell_reports_intact; - } - - // Check that the String.prototype has the Object.prototype - // as its [[Prototype]] still. - if (initial_string_proto.map().prototype() != initial_object_proto) { - DCHECK_EQ(false, cell_reports_intact); - return cell_reports_intact; - } -#endif - - return cell_reports_intact; -} - -bool Isolate::IsNoElementsProtectorIntact() { - return Isolate::IsNoElementsProtectorIntact(context()); -} - -bool Isolate::IsIsConcatSpreadableLookupChainIntact() { - Cell is_concat_spreadable_cell = heap()->is_concat_spreadable_protector(); - bool is_is_concat_spreadable_set = - Smi::ToInt(is_concat_spreadable_cell.value()) == kProtectorInvalid; -#ifdef DEBUG - Map root_array_map = - raw_native_context().GetInitialJSArrayMap(GetInitialFastElementsKind()); - if (root_array_map.is_null()) { - // Ignore the value of is_concat_spreadable during bootstrap. - return !is_is_concat_spreadable_set; - } - Handle<Object> array_prototype(array_function()->prototype(), this); - Handle<Symbol> key = factory()->is_concat_spreadable_symbol(); - Handle<Object> value; - LookupIterator it(this, array_prototype, key); - if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined(this)) { - // TODO(cbruni): Currently we do not revert if we unset the - // @@isConcatSpreadable property on Array.prototype or Object.prototype - // hence the reverse implication doesn't hold. - DCHECK(is_is_concat_spreadable_set); - return false; - } -#endif // DEBUG - - return !is_is_concat_spreadable_set; -} - -bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver receiver) { - if (!IsIsConcatSpreadableLookupChainIntact()) return false; - return !receiver.HasProxyInPrototype(this); -} - -bool Isolate::IsPromiseHookProtectorIntact() { - PropertyCell promise_hook_cell = heap()->promise_hook_protector(); - bool is_promise_hook_protector_intact = - Smi::ToInt(promise_hook_cell.value()) == kProtectorValid; - DCHECK_IMPLIES(is_promise_hook_protector_intact, - !promise_hook_or_async_event_delegate_); - DCHECK_IMPLIES(is_promise_hook_protector_intact, - !promise_hook_or_debug_is_active_or_async_event_delegate_); - return is_promise_hook_protector_intact; -} - -bool Isolate::IsPromiseResolveLookupChainIntact() { - Cell promise_resolve_cell = heap()->promise_resolve_protector(); - bool is_promise_resolve_protector_intact = - Smi::ToInt(promise_resolve_cell.value()) == kProtectorValid; - return is_promise_resolve_protector_intact; -} - -bool Isolate::IsPromiseThenLookupChainIntact() { - PropertyCell promise_then_cell = heap()->promise_then_protector(); - bool is_promise_then_protector_intact = - Smi::ToInt(promise_then_cell.value()) == kProtectorValid; - return is_promise_then_protector_intact; -} - -bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) { - DisallowHeapAllocation no_gc; - if (!receiver->IsJSPromise()) return false; - if (!IsInAnyContext(receiver->map().prototype(), - Context::PROMISE_PROTOTYPE_INDEX)) { - return false; - } - return IsPromiseThenLookupChainIntact(); -} - void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) { DisallowHeapAllocation no_gc; if (!object->map().is_prototype_map()) return; - if (!IsNoElementsProtectorIntact()) return; + if (!Protectors::IsNoElementsIntact(this)) return; if (!IsArrayOrObjectOrStringPrototype(*object)) return; - PropertyCell::SetValueWithInvalidation( - this, "no_elements_protector", factory()->no_elements_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); -} - -void Isolate::TraceProtectorInvalidation(const char* protector_name) { - static constexpr char kInvalidateProtectorTracingCategory[] = - "V8.InvalidateProtector"; - static constexpr char kInvalidateProtectorTracingArg[] = "protector-name"; - - DCHECK(FLAG_trace_protector_invalidation); - - // TODO(jgruber): Remove the PrintF once tracing can output to stdout. - i::PrintF("Invalidating protector cell %s in isolate %p\n", protector_name, - this); - TRACE_EVENT_INSTANT1("v8", kInvalidateProtectorTracingCategory, - TRACE_EVENT_SCOPE_THREAD, kInvalidateProtectorTracingArg, - protector_name); -} - -void Isolate::InvalidateIsConcatSpreadableProtector() { - DCHECK(factory()->is_concat_spreadable_protector()->value().IsSmi()); - DCHECK(IsIsConcatSpreadableLookupChainIntact()); - if (FLAG_trace_protector_invalidation) { - TraceProtectorInvalidation("is_concat_spreadable_protector"); - } - factory()->is_concat_spreadable_protector()->set_value( - Smi::FromInt(kProtectorInvalid)); - DCHECK(!IsIsConcatSpreadableLookupChainIntact()); -} - -void Isolate::InvalidateArrayConstructorProtector() { - DCHECK(factory()->array_constructor_protector()->value().IsSmi()); - DCHECK(IsArrayConstructorIntact()); - if (FLAG_trace_protector_invalidation) { - TraceProtectorInvalidation("array_constructor_protector"); - } - factory()->array_constructor_protector()->set_value( - Smi::FromInt(kProtectorInvalid)); - DCHECK(!IsArrayConstructorIntact()); -} - -void Isolate::InvalidateTypedArraySpeciesProtector() { - DCHECK(factory()->typed_array_species_protector()->value().IsSmi()); - DCHECK(IsTypedArraySpeciesLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "typed_array_species_protector", - factory()->typed_array_species_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsTypedArraySpeciesLookupChainIntact()); -} - -void Isolate::InvalidatePromiseSpeciesProtector() { - DCHECK(factory()->promise_species_protector()->value().IsSmi()); - DCHECK(IsPromiseSpeciesLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "promise_species_protector", factory()->promise_species_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsPromiseSpeciesLookupChainIntact()); -} - -void Isolate::InvalidateStringLengthOverflowProtector() { - DCHECK(factory()->string_length_protector()->value().IsSmi()); - DCHECK(IsStringLengthOverflowIntact()); - if (FLAG_trace_protector_invalidation) { - TraceProtectorInvalidation("string_length_protector"); - } - factory()->string_length_protector()->set_value( - Smi::FromInt(kProtectorInvalid)); - DCHECK(!IsStringLengthOverflowIntact()); -} - -void Isolate::InvalidateArrayIteratorProtector() { - DCHECK(factory()->array_iterator_protector()->value().IsSmi()); - DCHECK(IsArrayIteratorLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "array_iterator_protector", factory()->array_iterator_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsArrayIteratorLookupChainIntact()); -} - -void Isolate::InvalidateMapIteratorProtector() { - DCHECK(factory()->map_iterator_protector()->value().IsSmi()); - DCHECK(IsMapIteratorLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "map_iterator_protector", factory()->map_iterator_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsMapIteratorLookupChainIntact()); -} - -void Isolate::InvalidateSetIteratorProtector() { - DCHECK(factory()->set_iterator_protector()->value().IsSmi()); - DCHECK(IsSetIteratorLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "set_iterator_protector", factory()->set_iterator_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsSetIteratorLookupChainIntact()); -} - -void Isolate::InvalidateStringIteratorProtector() { - DCHECK(factory()->string_iterator_protector()->value().IsSmi()); - DCHECK(IsStringIteratorLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "string_iterator_protector", factory()->string_iterator_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsStringIteratorLookupChainIntact()); -} - -void Isolate::InvalidateArrayBufferDetachingProtector() { - DCHECK(factory()->array_buffer_detaching_protector()->value().IsSmi()); - DCHECK(IsArrayBufferDetachingIntact()); - PropertyCell::SetValueWithInvalidation( - this, "array_buffer_detaching_protector", - factory()->array_buffer_detaching_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsArrayBufferDetachingIntact()); -} - -void Isolate::InvalidatePromiseHookProtector() { - DCHECK(factory()->promise_hook_protector()->value().IsSmi()); - DCHECK(IsPromiseHookProtectorIntact()); - PropertyCell::SetValueWithInvalidation( - this, "promise_hook_protector", factory()->promise_hook_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsPromiseHookProtectorIntact()); -} - -void Isolate::InvalidatePromiseResolveProtector() { - DCHECK(factory()->promise_resolve_protector()->value().IsSmi()); - DCHECK(IsPromiseResolveLookupChainIntact()); - if (FLAG_trace_protector_invalidation) { - TraceProtectorInvalidation("promise_resolve_protector"); - } - factory()->promise_resolve_protector()->set_value( - Smi::FromInt(kProtectorInvalid)); - DCHECK(!IsPromiseResolveLookupChainIntact()); -} - -void Isolate::InvalidatePromiseThenProtector() { - DCHECK(factory()->promise_then_protector()->value().IsSmi()); - DCHECK(IsPromiseThenLookupChainIntact()); - PropertyCell::SetValueWithInvalidation( - this, "promise_then_protector", factory()->promise_then_protector(), - handle(Smi::FromInt(kProtectorInvalid), this)); - DCHECK(!IsPromiseThenLookupChainIntact()); + Protectors::InvalidateNoElements(this); } bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) { @@ -4256,9 +3952,9 @@ void Isolate::PromiseHookStateUpdated() { bool promise_hook_or_debug_is_active_or_async_event_delegate = promise_hook_or_async_event_delegate || debug()->is_active(); if (promise_hook_or_debug_is_active_or_async_event_delegate && - IsPromiseHookProtectorIntact()) { + Protectors::IsPromiseHookIntact(this)) { HandleScope scope(this); - InvalidatePromiseHookProtector(); + Protectors::InvalidatePromiseHook(this); } promise_hook_or_async_event_delegate_ = promise_hook_or_async_event_delegate; promise_hook_or_debug_is_active_or_async_event_delegate_ = @@ -4578,12 +4274,20 @@ void Isolate::AddDetachedContext(Handle<Context> context) { HandleScope scope(this); Handle<WeakArrayList> detached_contexts = factory()->detached_contexts(); detached_contexts = WeakArrayList::AddToEnd( - this, detached_contexts, MaybeObjectHandle(Smi::kZero, this)); - detached_contexts = WeakArrayList::AddToEnd(this, detached_contexts, - MaybeObjectHandle::Weak(context)); + this, detached_contexts, MaybeObjectHandle(Smi::kZero, this), + MaybeObjectHandle::Weak(context)); heap()->set_detached_contexts(*detached_contexts); } +void Isolate::AddSharedWasmMemory(Handle<WasmMemoryObject> memory_object) { + HandleScope scope(this); + Handle<WeakArrayList> shared_wasm_memories = + factory()->shared_wasm_memories(); + shared_wasm_memories = WeakArrayList::AddToEnd( + this, shared_wasm_memories, MaybeObjectHandle::Weak(memory_object)); + heap()->set_shared_wasm_memories(*shared_wasm_memories); +} + void Isolate::CheckDetachedContextsAfterGC() { HandleScope scope(this); Handle<WeakArrayList> detached_contexts = factory()->detached_contexts(); diff --git a/deps/v8/src/execution/isolate.h b/deps/v8/src/execution/isolate.h index 4eadb42438f9c4..ef16dfa5140c05 100644 --- a/deps/v8/src/execution/isolate.h +++ b/deps/v8/src/execution/isolate.h @@ -1163,87 +1163,8 @@ class Isolate final : private HiddenFactory { #endif // V8_INTL_SUPPORT - static const int kProtectorValid = 1; - static const int kProtectorInvalid = 0; - - inline bool IsArrayConstructorIntact(); - - // The version with an explicit context parameter can be used when - // Isolate::context is not set up, e.g. when calling directly into C++ from - // CSA. - bool IsNoElementsProtectorIntact(Context context); - V8_EXPORT_PRIVATE bool IsNoElementsProtectorIntact(); - bool IsArrayOrObjectOrStringPrototype(Object object); - inline bool IsTypedArraySpeciesLookupChainIntact(); - - // Check that the @@species protector is intact, which guards the lookup of - // "constructor" on JSPromise instances, whose [[Prototype]] is the initial - // %PromisePrototype%, and the Symbol.species lookup on the - // %PromisePrototype%. - inline bool IsPromiseSpeciesLookupChainIntact(); - - bool IsIsConcatSpreadableLookupChainIntact(); - bool IsIsConcatSpreadableLookupChainIntact(JSReceiver receiver); - inline bool IsStringLengthOverflowIntact(); - inline bool IsArrayIteratorLookupChainIntact(); - - // The MapIterator protector protects the original iteration behaviors of - // Map.prototype.keys(), Map.prototype.values(), and Set.prototype.entries(). - // It does not protect the original iteration behavior of - // Map.prototype[Symbol.iterator](). The protector is invalidated when: - // * The 'next' property is set on an object where the property holder is the - // %MapIteratorPrototype% (e.g. because the object is that very prototype). - // * The 'Symbol.iterator' property is set on an object where the property - // holder is the %IteratorPrototype%. Note that this also invalidates the - // SetIterator protector (see below). - inline bool IsMapIteratorLookupChainIntact(); - - // The SetIterator protector protects the original iteration behavior of - // Set.prototype.keys(), Set.prototype.values(), Set.prototype.entries(), - // and Set.prototype[Symbol.iterator](). The protector is invalidated when: - // * The 'next' property is set on an object where the property holder is the - // %SetIteratorPrototype% (e.g. because the object is that very prototype). - // * The 'Symbol.iterator' property is set on an object where the property - // holder is the %SetPrototype% OR %IteratorPrototype%. This means that - // setting Symbol.iterator on a MapIterator object can also invalidate the - // SetIterator protector, and vice versa, setting Symbol.iterator on a - // SetIterator object can also invalidate the MapIterator. This is an over- - // approximation for the sake of simplicity. - inline bool IsSetIteratorLookupChainIntact(); - - // The StringIteratorProtector protects the original string iteration behavior - // for primitive strings. As long as the StringIteratorProtector is valid, - // iterating over a primitive string is guaranteed to be unobservable from - // user code and can thus be cut short. More specifically, the protector gets - // invalidated as soon as either String.prototype[Symbol.iterator] or - // String.prototype[Symbol.iterator]().next is modified. This guarantee does - // not apply to string objects (as opposed to primitives), since they could - // define their own Symbol.iterator. - // String.prototype itself does not need to be protected, since it is - // non-configurable and non-writable. - inline bool IsStringIteratorLookupChainIntact(); - - // Make sure we do check for detached array buffers. - inline bool IsArrayBufferDetachingIntact(); - - // Disable promise optimizations if promise (debug) hooks have ever been - // active, because those can observe promises. - bool IsPromiseHookProtectorIntact(); - - // Make sure a lookup of "resolve" on the %Promise% intrinsic object - // yeidls the initial Promise.resolve method. - bool IsPromiseResolveLookupChainIntact(); - - // Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the - // initial %PromisePrototype% yields the initial method. In addition this - // protector also guards the negative lookup of "then" on the intrinsic - // %ObjectPrototype%, meaning that such lookups are guaranteed to yield - // undefined without triggering any side-effects. - bool IsPromiseThenLookupChainIntact(); - bool IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver); - // On intent to set an element in object, make sure that appropriate // notifications occur if the set is on the elements of the array or // object prototype. Also ensure that changes to prototype chain between @@ -1259,24 +1180,6 @@ class Isolate final : private HiddenFactory { UpdateNoElementsProtectorOnSetElement(object); } - // The `protector_name` C string must be statically allocated. - void TraceProtectorInvalidation(const char* protector_name); - - void InvalidateArrayConstructorProtector(); - void InvalidateTypedArraySpeciesProtector(); - void InvalidateRegExpSpeciesProtector(Handle<NativeContext> native_context); - void InvalidatePromiseSpeciesProtector(); - void InvalidateIsConcatSpreadableProtector(); - void InvalidateStringLengthOverflowProtector(); - void InvalidateArrayIteratorProtector(); - void InvalidateMapIteratorProtector(); - void InvalidateSetIteratorProtector(); - void InvalidateStringIteratorProtector(); - void InvalidateArrayBufferDetachingProtector(); - V8_EXPORT_PRIVATE void InvalidatePromiseHookProtector(); - void InvalidatePromiseResolveProtector(); - void InvalidatePromiseThenProtector(); - // Returns true if array is the initial array prototype in any native context. bool IsAnyInitialArrayPrototype(Handle<JSArray> array); @@ -1406,6 +1309,8 @@ class Isolate final : private HiddenFactory { void AddDetachedContext(Handle<Context> context); void CheckDetachedContextsAfterGC(); + void AddSharedWasmMemory(Handle<WasmMemoryObject> memory_object); + std::vector<Object>* partial_snapshot_cache() { return &partial_snapshot_cache_; } @@ -1442,6 +1347,15 @@ class Isolate final : private HiddenFactory { return array_buffer_allocator_; } + void set_array_buffer_allocator_shared( + std::shared_ptr<v8::ArrayBuffer::Allocator> allocator) { + array_buffer_allocator_shared_ = std::move(allocator); + } + std::shared_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_shared() + const { + return array_buffer_allocator_shared_; + } + FutexWaitListNode* futex_wait_list_node() { return &futex_wait_list_node_; } CancelableTaskManager* cancelable_task_manager() { @@ -1513,6 +1427,11 @@ class Isolate final : private HiddenFactory { bool HasPrepareStackTraceCallback() const; void SetAddCrashKeyCallback(AddCrashKeyCallback callback); + void AddCrashKey(CrashKeyId id, const std::string& value) { + if (add_crash_key_callback_) { + add_crash_key_callback_(id, value); + } + } void SetRAILMode(RAILMode rail_mode); @@ -1848,6 +1767,7 @@ class Isolate final : private HiddenFactory { uint32_t embedded_blob_size_ = 0; v8::ArrayBuffer::Allocator* array_buffer_allocator_ = nullptr; + std::shared_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_shared_; FutexWaitListNode futex_wait_list_node_; diff --git a/deps/v8/src/execution/messages.cc b/deps/v8/src/execution/messages.cc index 63d1e2be1ff7af..96fb94cd4e64b8 100644 --- a/deps/v8/src/execution/messages.cc +++ b/deps/v8/src/execution/messages.cc @@ -603,7 +603,7 @@ int WasmStackFrame::GetColumnNumber() { return GetModuleOffset(); } int WasmStackFrame::GetModuleOffset() const { const int function_offset = - wasm_instance_->module_object().GetFunctionOffset(wasm_func_index_); + GetWasmFunctionOffset(wasm_instance_->module(), wasm_func_index_); return function_offset + GetPosition(); } @@ -631,7 +631,7 @@ Handle<Object> AsmJsWasmStackFrame::GetReceiver() const { } Handle<Object> AsmJsWasmStackFrame::GetFunction() const { - // TODO(clemensh): Return lazily created JSFunction. + // TODO(clemensb): Return lazily created JSFunction. return Null(); } @@ -894,7 +894,7 @@ MaybeHandle<Object> ErrorUtils::FormatStackTrace(Isolate* isolate, Handle<StackTraceFrame> frame(StackTraceFrame::cast(elems->get(i)), isolate); - SerializeStackTraceFrame(isolate, frame, builder); + SerializeStackTraceFrame(isolate, frame, &builder); if (isolate->has_pending_exception()) { // CallSite.toString threw. Parts of the current frame might have been diff --git a/deps/v8/src/execution/protectors.cc b/deps/v8/src/execution/protectors.cc index 3ac07eede38326..b5b4c47a1bb81f 100644 --- a/deps/v8/src/execution/protectors.cc +++ b/deps/v8/src/execution/protectors.cc @@ -16,12 +16,32 @@ namespace v8 { namespace internal { +namespace { +void TraceProtectorInvalidation(const char* protector_name) { + DCHECK(FLAG_trace_protector_invalidation); + static constexpr char kInvalidateProtectorTracingCategory[] = + "V8.InvalidateProtector"; + static constexpr char kInvalidateProtectorTracingArg[] = "protector-name"; + + DCHECK(FLAG_trace_protector_invalidation); + + // TODO(jgruber): Remove the PrintF once tracing can output to stdout. + i::PrintF("Invalidating protector cell %s", protector_name); + TRACE_EVENT_INSTANT1("v8", kInvalidateProtectorTracingCategory, + TRACE_EVENT_SCOPE_THREAD, kInvalidateProtectorTracingArg, + protector_name); +} +} // namespace + #define INVALIDATE_PROTECTOR_ON_NATIVE_CONTEXT_DEFINITION(name, cell) \ void Protectors::Invalidate##name(Isolate* isolate, \ Handle<NativeContext> native_context) { \ DCHECK_EQ(*native_context, isolate->raw_native_context()); \ DCHECK(native_context->cell().value().IsSmi()); \ DCHECK(Is##name##Intact(native_context)); \ + if (FLAG_trace_protector_invalidation) { \ + TraceProtectorInvalidation(#name); \ + } \ Handle<PropertyCell> species_cell(native_context->cell(), isolate); \ PropertyCell::SetValueWithInvalidation( \ isolate, #cell, species_cell, \ @@ -36,6 +56,9 @@ DECLARED_PROTECTORS_ON_NATIVE_CONTEXT( void Protectors::Invalidate##name(Isolate* isolate) { \ DCHECK(isolate->factory()->cell()->value().IsSmi()); \ DCHECK(Is##name##Intact(isolate)); \ + if (FLAG_trace_protector_invalidation) { \ + TraceProtectorInvalidation(#name); \ + } \ PropertyCell::SetValueWithInvalidation( \ isolate, #cell, isolate->factory()->cell(), \ handle(Smi::FromInt(kProtectorInvalid), isolate)); \ diff --git a/deps/v8/src/execution/protectors.h b/deps/v8/src/execution/protectors.h index 5c54613bb19633..4601f16cf01038 100644 --- a/deps/v8/src/execution/protectors.h +++ b/deps/v8/src/execution/protectors.h @@ -18,19 +18,82 @@ class Protectors : public AllStatic { #define DECLARED_PROTECTORS_ON_NATIVE_CONTEXT(V) \ V(RegExpSpeciesLookupChainProtector, regexp_species_protector) -#define DECLARED_PROTECTORS_ON_ISOLATE(V) \ - V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) +#define DECLARED_PROTECTORS_ON_ISOLATE(V) \ + V(ArrayBufferDetaching, ArrayBufferDetachingProtector, \ + array_buffer_detaching_protector) \ + V(ArrayConstructor, ArrayConstructorProtector, array_constructor_protector) \ + V(ArrayIteratorLookupChain, ArrayIteratorProtector, \ + array_iterator_protector) \ + V(ArraySpeciesLookupChain, ArraySpeciesProtector, array_species_protector) \ + V(IsConcatSpreadableLookupChain, IsConcatSpreadableProtector, \ + is_concat_spreadable_protector) \ + V(NoElements, NoElementsProtector, no_elements_protector) \ + \ + /* The MapIterator protector protects the original iteration behaviors */ \ + /* of Map.prototype.keys(), Map.prototype.values(), and */ \ + /* Set.prototype.entries(). It does not protect the original iteration */ \ + /* behavior of Map.prototype[Symbol.iterator](). */ \ + /* The protector is invalidated when: */ \ + /* * The 'next' property is set on an object where the property holder */ \ + /* is the %MapIteratorPrototype% (e.g. because the object is that very */ \ + /* prototype). */ \ + /* * The 'Symbol.iterator' property is set on an object where the */ \ + /* property holder is the %IteratorPrototype%. Note that this also */ \ + /* invalidates the SetIterator protector (see below). */ \ + V(MapIteratorLookupChain, MapIteratorProtector, map_iterator_protector) \ + V(PromiseHook, PromiseHookProtector, promise_hook_protector) \ + V(PromiseThenLookupChain, PromiseThenProtector, promise_then_protector) \ + V(PromiseResolveLookupChain, PromiseResolveProtector, \ + promise_resolve_protector) \ + V(PromiseSpeciesLookupChain, PromiseSpeciesProtector, \ + promise_species_protector) \ + \ + /* The SetIterator protector protects the original iteration behavior of */ \ + /* Set.prototype.keys(), Set.prototype.values(), */ \ + /* Set.prototype.entries(), and Set.prototype[Symbol.iterator](). The */ \ + /* protector is invalidated when: */ \ + /* * The 'next' property is set on an object where the property holder */ \ + /* is the %SetIteratorPrototype% (e.g. because the object is that very */ \ + /* prototype). */ \ + /* * The 'Symbol.iterator' property is set on an object where the */ \ + /* property holder is the %SetPrototype% OR %IteratorPrototype%. This */ \ + /* means that setting Symbol.iterator on a MapIterator object can also */ \ + /* invalidate the SetIterator protector, and vice versa, setting */ \ + /* Symbol.iterator on a SetIterator object can also invalidate the */ \ + /* MapIterator. This is an over-approximation for the sake of */ \ + /* simplicity. */ \ + V(SetIteratorLookupChain, SetIteratorProtector, set_iterator_protector) \ + \ + /* The StringIteratorProtector protects the original string iteration */ \ + /* behavior for primitive strings. As long as the */ \ + /* StringIteratorProtector is valid, iterating over a primitive string */ \ + /* is guaranteed to be unobservable from user code and can thus be cut */ \ + /* short. More specifically, the protector gets invalidated as soon as */ \ + /* either String.prototype[Symbol.iterator] or */ \ + /* String.prototype[Symbol.iterator]().next is modified. This guarantee */ \ + /* does not apply to string objects (as opposed to primitives), since */ \ + /* they could define their own Symbol.iterator. */ \ + /* String.prototype itself does not need to be protected, since it is */ \ + /* non-configurable and non-writable. */ \ + V(StringIteratorLookupChain, StringIteratorProtector, \ + string_iterator_protector) \ + V(StringLengthOverflowLookupChain, StringLengthProtector, \ + string_length_protector) \ + V(TypedArraySpeciesLookupChain, TypedArraySpeciesProtector, \ + typed_array_species_protector) + +#define DECLARE_PROTECTOR_ON_NATIVE_CONTEXT(name, unused_cell) \ + V8_EXPORT_PRIVATE static inline bool Is##name##Intact( \ + Handle<NativeContext> native_context); \ + V8_EXPORT_PRIVATE static void Invalidate##name( \ + Isolate* isolate, Handle<NativeContext> native_context); -#define DECLARE_PROTECTOR_ON_NATIVE_CONTEXT(name, unused_cell) \ - static inline bool Is##name##Intact(Handle<NativeContext> native_context); \ - static void Invalidate##name(Isolate* isolate, \ - Handle<NativeContext> native_context); DECLARED_PROTECTORS_ON_NATIVE_CONTEXT(DECLARE_PROTECTOR_ON_NATIVE_CONTEXT) #undef DECLARE_PROTECTOR_ON_NATIVE_CONTEXT #define DECLARE_PROTECTOR_ON_ISOLATE(name, unused_root_index, unused_cell) \ - static inline bool Is##name##Intact(Isolate* isolate); \ - static void Invalidate##name(Isolate* isolate); + V8_EXPORT_PRIVATE static inline bool Is##name##Intact(Isolate* isolate); \ + V8_EXPORT_PRIVATE static void Invalidate##name(Isolate* isolate); DECLARED_PROTECTORS_ON_ISOLATE(DECLARE_PROTECTOR_ON_ISOLATE) #undef DECLARE_PROTECTOR_ON_ISOLATE diff --git a/deps/v8/src/execution/s390/frame-constants-s390.h b/deps/v8/src/execution/s390/frame-constants-s390.h index a48a78fd42d9ef..34ae136aadad57 100644 --- a/deps/v8/src/execution/s390/frame-constants-s390.h +++ b/deps/v8/src/execution/s390/frame-constants-s390.h @@ -14,7 +14,7 @@ namespace internal { class EntryFrameConstants : public AllStatic { public: static constexpr int kCallerFPOffset = - -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); + -(StandardFrameConstants::kFixedFrameSizeFromFp + kSystemPointerSize); // Stack offsets for arguments passed to JSEntry. static constexpr int kArgvOffset = 20 * kSystemPointerSize; }; @@ -25,13 +25,13 @@ class ExitFrameConstants : public TypedFrameConstants { DEFINE_TYPED_FRAME_SIZES(1); // The caller fields are below the frame pointer on the stack. - static constexpr int kCallerFPOffset = 0 * kPointerSize; + static constexpr int kCallerFPOffset = 0 * kSystemPointerSize; // The calling JS function is below FP. - static constexpr int kCallerPCOffset = 1 * kPointerSize; + static constexpr int kCallerPCOffset = 1 * kSystemPointerSize; // FP-relative displacement of the caller's SP. It points just // below the saved PC. - static constexpr int kCallerSPDisplacement = 2 * kPointerSize; + static constexpr int kCallerSPDisplacement = 2 * kSystemPointerSize; }; class WasmCompileLazyFrameConstants : public TypedFrameConstants { @@ -47,7 +47,7 @@ class WasmCompileLazyFrameConstants : public TypedFrameConstants { static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0); static constexpr int kFixedFrameSizeFromFp = TypedFrameConstants::kFixedFrameSizeFromFp + - kNumberOfSavedGpParamRegs * kPointerSize + + kNumberOfSavedGpParamRegs * kSystemPointerSize + kNumberOfSavedFpParamRegs * kDoubleSize; }; @@ -56,13 +56,13 @@ class JavaScriptFrameConstants : public AllStatic { // FP-relative. static constexpr int kLocal0Offset = StandardFrameConstants::kExpressionsOffset; - static constexpr int kLastParameterOffset = +2 * kPointerSize; + static constexpr int kLastParameterOffset = +2 * kSystemPointerSize; static constexpr int kFunctionOffset = StandardFrameConstants::kFunctionOffset; // Caller SP-relative. - static constexpr int kParam0Offset = -2 * kPointerSize; - static constexpr int kReceiverOffset = -1 * kPointerSize; + static constexpr int kParam0Offset = -2 * kSystemPointerSize; + static constexpr int kReceiverOffset = -1 * kSystemPointerSize; }; } // namespace internal diff --git a/deps/v8/src/execution/simulator.h b/deps/v8/src/execution/simulator.h index 9f98f2039bcaec..4000973a24397d 100644 --- a/deps/v8/src/execution/simulator.h +++ b/deps/v8/src/execution/simulator.h @@ -115,15 +115,19 @@ class GeneratedCode { #ifdef USE_SIMULATOR // Defined in simulator-base.h. Return Call(Args... args) { +#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) + FATAL("Generated code execution not possible during cross-compilation."); +#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) return Simulator::current(isolate_)->template Call<Return>( reinterpret_cast<Address>(fn_ptr_), args...); } - - DISABLE_CFI_ICALL Return CallIrregexp(Args... args) { return Call(args...); } #else DISABLE_CFI_ICALL Return Call(Args... args) { // When running without a simulator we call the entry directly. +#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) + FATAL("Generated code execution not possible during cross-compilation."); +#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN) #if V8_OS_AIX // AIX ABI requires function descriptors (FD). Artificially create a pseudo // FD to ensure correct dispatch to generated code. The 'volatile' @@ -138,11 +142,6 @@ class GeneratedCode { return fn_ptr_(args...); #endif // V8_OS_AIX } - - DISABLE_CFI_ICALL Return CallIrregexp(Args... args) { - // When running without a simulator we call the entry directly. - return fn_ptr_(args...); - } #endif // USE_SIMULATOR private: diff --git a/deps/v8/src/execution/stack-guard.cc b/deps/v8/src/execution/stack-guard.cc index 1cf4c4605a6d7d..d37327f1c3d6bc 100644 --- a/deps/v8/src/execution/stack-guard.cc +++ b/deps/v8/src/execution/stack-guard.cc @@ -10,6 +10,7 @@ #include "src/execution/runtime-profiler.h" #include "src/execution/simulator.h" #include "src/logging/counters.h" +#include "src/objects/backing-store.h" #include "src/roots/roots-inl.h" #include "src/utils/memcopy.h" #include "src/wasm/wasm-engine.h" @@ -86,6 +87,8 @@ void StackGuard::PushInterruptsScope(InterruptsScope* scope) { current->intercepted_flags_ &= ~scope->intercept_mask_; } thread_local_.interrupt_flags_ |= restored_flags; + + if (has_pending_interrupts(access)) set_interrupt_limits(access); } if (!has_pending_interrupts(access)) reset_limits(access); // Add scope to the chain. @@ -271,8 +274,7 @@ Object StackGuard::HandleInterrupts() { if (TestAndClear(&interrupt_flags, GROW_SHARED_MEMORY)) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "V8.WasmGrowSharedMemory"); - isolate_->wasm_engine()->memory_tracker()->UpdateSharedMemoryInstances( - isolate_); + BackingStore::UpdateSharedWasmMemoryObjects(isolate_); } if (TestAndClear(&interrupt_flags, DEOPT_MARKED_ALLOCATION_SITES)) { @@ -305,8 +307,6 @@ Object StackGuard::HandleInterrupts() { } isolate_->counters()->stack_interrupts()->Increment(); - isolate_->counters()->runtime_profiler_ticks()->Increment(); - isolate_->runtime_profiler()->MarkCandidatesForOptimization(); return ReadOnlyRoots(isolate_).undefined_value(); } diff --git a/deps/v8/src/execution/x64/frame-constants-x64.h b/deps/v8/src/execution/x64/frame-constants-x64.h index 5af35b1b3bf154..49d69829f0302a 100644 --- a/deps/v8/src/execution/x64/frame-constants-x64.h +++ b/deps/v8/src/execution/x64/frame-constants-x64.h @@ -13,7 +13,7 @@ namespace internal { class EntryFrameConstants : public AllStatic { public: -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN static constexpr int kCalleeSaveXMMRegisters = 10; static constexpr int kXMMRegisterSize = 16; static constexpr int kXMMRegistersBlockSize = diff --git a/deps/v8/src/extensions/free-buffer-extension.cc b/deps/v8/src/extensions/free-buffer-extension.cc index 975e9543c82f19..9fdfe920eb8802 100644 --- a/deps/v8/src/extensions/free-buffer-extension.cc +++ b/deps/v8/src/extensions/free-buffer-extension.cc @@ -21,9 +21,8 @@ void FreeBufferExtension::FreeBuffer( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::Local<v8::ArrayBuffer> arrayBuffer = args[0].As<v8::ArrayBuffer>(); v8::ArrayBuffer::Contents contents = arrayBuffer->Externalize(); - Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate()); - isolate->array_buffer_allocator()->Free(contents.Data(), - contents.ByteLength()); + contents.Deleter()(contents.Data(), contents.ByteLength(), + contents.DeleterData()); } } // namespace internal diff --git a/deps/v8/src/extensions/gc-extension.cc b/deps/v8/src/extensions/gc-extension.cc index 4f446627fd0f25..fddd40b3525c19 100644 --- a/deps/v8/src/extensions/gc-extension.cc +++ b/deps/v8/src/extensions/gc-extension.cc @@ -4,23 +4,160 @@ #include "src/extensions/gc-extension.h" +#include "include/v8.h" #include "src/base/platform/platform.h" +#include "src/execution/isolate.h" +#include "src/heap/heap.h" +#include "src/tasks/cancelable-task.h" namespace v8 { namespace internal { +namespace { + +enum class ExecutionType { kAsync, kSync }; + +struct GCOptions { + v8::Isolate::GarbageCollectionType type; + ExecutionType execution; +}; + +Maybe<bool> IsProperty(v8::Isolate* isolate, v8::Local<v8::Context> ctx, + v8::Local<v8::Object> object, const char* key, + const char* value) { + auto k = v8::String::NewFromUtf8(isolate, key).ToLocalChecked(); + // Get will return undefined for non-existing keys which will make + // StrictEquals fail. + auto maybe_property = object->Get(ctx, k); + if (maybe_property.IsEmpty()) return Nothing<bool>(); + return Just<bool>(maybe_property.ToLocalChecked()->StrictEquals( + v8::String::NewFromUtf8(isolate, value).ToLocalChecked())); +} + +Maybe<GCOptions> Parse(v8::Isolate* isolate, + const v8::FunctionCallbackInfo<v8::Value>& args) { + // Default values. + auto options = + GCOptions{v8::Isolate::GarbageCollectionType::kFullGarbageCollection, + ExecutionType::kSync}; + bool found_options_object = false; + + if (args.Length() > 0 && args[0]->IsObject()) { + v8::HandleScope scope(isolate); + auto ctx = isolate->GetCurrentContext(); + auto param = v8::Local<v8::Object>::Cast(args[0]); + auto maybe_type = IsProperty(isolate, ctx, param, "type", "minor"); + if (maybe_type.IsNothing()) return Nothing<GCOptions>(); + if (maybe_type.ToChecked()) { + found_options_object = true; + options.type = + v8::Isolate::GarbageCollectionType::kMinorGarbageCollection; + } + auto maybe_execution = + IsProperty(isolate, ctx, param, "execution", "async"); + if (maybe_execution.IsNothing()) return Nothing<GCOptions>(); + if (maybe_execution.ToChecked()) { + found_options_object = true; + options.execution = ExecutionType::kAsync; + } + } + + // If no options object is present default to legacy behavior. + if (!found_options_object) { + options.type = + args[0]->BooleanValue(isolate) + ? v8::Isolate::GarbageCollectionType::kMinorGarbageCollection + : v8::Isolate::GarbageCollectionType::kFullGarbageCollection; + } + + return Just<GCOptions>(options); +} + +void InvokeGC(v8::Isolate* isolate, v8::Isolate::GarbageCollectionType type, + v8::EmbedderHeapTracer::EmbedderStackState embedder_stack_state) { + Heap* heap = reinterpret_cast<Isolate*>(isolate)->heap(); + switch (type) { + case v8::Isolate::GarbageCollectionType::kMinorGarbageCollection: + heap->CollectGarbage(i::NEW_SPACE, i::GarbageCollectionReason::kTesting, + kGCCallbackFlagForced); + break; + case v8::Isolate::GarbageCollectionType::kFullGarbageCollection: + heap->SetEmbedderStackStateForNextFinalizaton(embedder_stack_state); + heap->PreciseCollectAllGarbage(i::Heap::kNoGCFlags, + i::GarbageCollectionReason::kTesting, + kGCCallbackFlagForced); + break; + } +} + +class AsyncGC final : public CancelableTask { + public: + ~AsyncGC() final = default; + + AsyncGC(v8::Isolate* isolate, v8::Local<v8::Promise::Resolver> resolver, + v8::Isolate::GarbageCollectionType type) + : CancelableTask(reinterpret_cast<Isolate*>(isolate)), + isolate_(isolate), + ctx_(isolate, isolate->GetCurrentContext()), + resolver_(isolate, resolver), + type_(type) {} + + void RunInternal() final { + v8::HandleScope scope(isolate_); + InvokeGC(isolate_, type_, + v8::EmbedderHeapTracer::EmbedderStackState::kEmpty); + auto resolver = v8::Local<v8::Promise::Resolver>::New(isolate_, resolver_); + auto ctx = Local<v8::Context>::New(isolate_, ctx_); + resolver->Resolve(ctx, v8::Undefined(isolate_)).ToChecked(); + } + + private: + v8::Isolate* isolate_; + v8::Persistent<v8::Context> ctx_; + v8::Persistent<v8::Promise::Resolver> resolver_; + v8::Isolate::GarbageCollectionType type_; + + DISALLOW_COPY_AND_ASSIGN(AsyncGC); +}; + +} // namespace v8::Local<v8::FunctionTemplate> GCExtension::GetNativeFunctionTemplate( v8::Isolate* isolate, v8::Local<v8::String> str) { return v8::FunctionTemplate::New(isolate, GCExtension::GC); } - void GCExtension::GC(const v8::FunctionCallbackInfo<v8::Value>& args) { - args.GetIsolate()->RequestGarbageCollectionForTesting( - args[0]->BooleanValue(args.GetIsolate()) - ? v8::Isolate::kMinorGarbageCollection - : v8::Isolate::kFullGarbageCollection); + v8::Isolate* isolate = args.GetIsolate(); + + // Immediate bailout if no arguments are provided. + if (args.Length() == 0) { + InvokeGC(isolate, + v8::Isolate::GarbageCollectionType::kFullGarbageCollection, + v8::EmbedderHeapTracer::EmbedderStackState::kUnknown); + return; + } + + auto maybe_options = Parse(isolate, args); + if (maybe_options.IsNothing()) return; + GCOptions options = maybe_options.ToChecked(); + switch (options.execution) { + case ExecutionType::kSync: + InvokeGC(isolate, options.type, + v8::EmbedderHeapTracer::EmbedderStackState::kUnknown); + break; + case ExecutionType::kAsync: { + v8::HandleScope scope(isolate); + auto resolver = v8::Promise::Resolver::New(isolate->GetCurrentContext()) + .ToLocalChecked(); + args.GetReturnValue().Set(resolver->GetPromise()); + auto task_runner = + V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate); + CHECK(task_runner->NonNestableTasksEnabled()); + task_runner->PostNonNestableTask( + std::make_unique<AsyncGC>(isolate, resolver, options.type)); + } break; + } } } // namespace internal diff --git a/deps/v8/src/extensions/gc-extension.h b/deps/v8/src/extensions/gc-extension.h index 7b517637f7a3e7..061bb725a31009 100644 --- a/deps/v8/src/extensions/gc-extension.h +++ b/deps/v8/src/extensions/gc-extension.h @@ -11,6 +11,21 @@ namespace v8 { namespace internal { +// Provides garbage collection on invoking |fun_name|(options), where +// - options is a dictionary like object. See supported properties below. +// - no parameter refers to options: +// {type: 'major', execution: 'sync'}. +// - truthy parameter that is not setting any options: +// {type: 'minor', execution: 'sync'}. +// +// Supported options: +// - type: 'major' or 'minor' for full GC and Scavenge, respectively. +// - execution: 'sync' or 'async' for synchronous and asynchronous execution, +// respectively. +// - Defaults to {type: 'major', execution: 'sync'}. +// +// Returns a Promise that resolves when GC is done when asynchronous execution +// is requested, and undefined otherwise. class GCExtension : public v8::Extension { public: explicit GCExtension(const char* fun_name) diff --git a/deps/v8/src/flags/flag-definitions.h b/deps/v8/src/flags/flag-definitions.h index c7c07e6dc654e8..3b0f6de650c48f 100644 --- a/deps/v8/src/flags/flag-definitions.h +++ b/deps/v8/src/flags/flag-definitions.h @@ -204,32 +204,33 @@ DEFINE_IMPLICATION(harmony_import_meta, harmony_dynamic_import) // Features that are still work in progress (behind individual flags). #define HARMONY_INPROGRESS_BASE(V) \ - V(harmony_private_methods, "harmony private methods in class literals") \ V(harmony_regexp_sequence, "RegExp Unicode sequence properties") \ V(harmony_weak_refs, "harmony weak references") \ - V(harmony_optional_chaining, "harmony optional chaining syntax") \ - V(harmony_nullish, "harmony nullish operator") + V(harmony_regexp_match_indices, "harmony regexp match indices") \ + V(harmony_top_level_await, "harmony top level await") #ifdef V8_INTL_SUPPORT -#define HARMONY_INPROGRESS(V) \ - HARMONY_INPROGRESS_BASE(V) \ - V(harmony_intl_dateformat_quarter, "Add quarter option to DateTimeFormat") +#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V) #else #define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V) #endif // Features that are complete (but still behind --harmony/es-staging flag). -#define HARMONY_STAGED_BASE(V) +#define HARMONY_STAGED_BASE(V) \ + V(harmony_optional_chaining, "harmony optional chaining syntax") \ + V(harmony_nullish, "harmony nullish operator") \ + V(harmony_private_methods, "harmony private methods in class literals") #ifdef V8_INTL_SUPPORT -#define HARMONY_STAGED(V) \ - HARMONY_STAGED_BASE(V) \ - V(harmony_intl_add_calendar_numbering_system, \ - "Add calendar and numberingSystem to DateTimeFormat") \ - V(harmony_intl_dateformat_day_period, \ - "Add dayPeriod option to DateTimeFormat") \ - V(harmony_intl_dateformat_fractional_second_digits, \ - "Add fractionalSecondDigits option to DateTimeFormat") \ +#define HARMONY_STAGED(V) \ + HARMONY_STAGED_BASE(V) \ + V(harmony_intl_add_calendar_numbering_system, \ + "Add calendar and numberingSystem to DateTimeFormat") \ + V(harmony_intl_dateformat_day_period, \ + "Add dayPeriod option to DateTimeFormat") \ + V(harmony_intl_dateformat_fractional_second_digits, \ + "Add fractionalSecondDigits option to DateTimeFormat") \ + V(harmony_intl_other_calendars, "DateTimeFormat other calendars") \ V(harmony_intl_segmenter, "Intl.Segmenter") #else #define HARMONY_STAGED(V) HARMONY_STAGED_BASE(V) @@ -245,12 +246,7 @@ DEFINE_IMPLICATION(harmony_import_meta, harmony_dynamic_import) V(harmony_promise_all_settled, "harmony Promise.allSettled") #ifdef V8_INTL_SUPPORT -#define HARMONY_SHIPPING(V) \ - HARMONY_SHIPPING_BASE(V) \ - V(harmony_intl_bigint, "BigInt.prototype.toLocaleString") \ - V(harmony_intl_date_format_range, "DateTimeFormat formatRange") \ - V(harmony_intl_datetime_style, "dateStyle timeStyle for DateTimeFormat") \ - V(harmony_intl_numberformat_unified, "Unified Intl.NumberFormat Features") +#define HARMONY_SHIPPING(V) HARMONY_SHIPPING_BASE(V) #else #define HARMONY_SHIPPING(V) HARMONY_SHIPPING_BASE(V) #endif @@ -390,7 +386,7 @@ DEFINE_BOOL(enable_one_shot_optimization, true, "only be executed once") // Flag for sealed, frozen elements kind instead of dictionary elements kind -DEFINE_BOOL_READONLY(enable_sealed_frozen_elements_kind, false, +DEFINE_BOOL_READONLY(enable_sealed_frozen_elements_kind, true, "Enable sealed, frozen elements kind") // Flags for data representation optimizations @@ -469,6 +465,12 @@ DEFINE_BOOL(trace_track_allocation_sites, false, DEFINE_BOOL(trace_migration, false, "trace object migration") DEFINE_BOOL(trace_generalization, false, "trace map generalization") +// Flags for TurboProp. +DEFINE_BOOL(turboprop, false, + "enable experimental turboprop mid-tier compiler.") +DEFINE_NEG_IMPLICATION(turboprop, turbo_inlining) +DEFINE_NEG_IMPLICATION(turboprop, inline_accessors) + // Flags for concurrent recompilation. DEFINE_BOOL(concurrent_recompilation, true, "optimizing hot functions asynchronously on a separate thread") @@ -485,9 +487,12 @@ DEFINE_BOOL(concurrent_inlining, false, DEFINE_IMPLICATION(future, concurrent_inlining) DEFINE_BOOL(trace_heap_broker_verbose, false, "trace the heap broker verbosely (all reports)") +DEFINE_BOOL(trace_heap_broker_memory, false, + "trace the heap broker memory (refs analysis and zone numbers)") DEFINE_BOOL(trace_heap_broker, false, "trace the heap broker (reports on missing data only)") DEFINE_IMPLICATION(trace_heap_broker_verbose, trace_heap_broker) +DEFINE_IMPLICATION(trace_heap_broker_memory, trace_heap_broker) // Flags for stress-testing the compiler. DEFINE_INT(stress_runs, 0, "number of stress runs") @@ -499,7 +504,7 @@ DEFINE_BOOL(print_deopt_stress, false, "print number of possible deopt points") DEFINE_BOOL(opt, true, "use adaptive optimizations") DEFINE_BOOL(turbo_sp_frame_access, false, "use stack pointer-relative access to frame wherever possible") -DEFINE_BOOL(turbo_control_flow_aware_allocation, false, +DEFINE_BOOL(turbo_control_flow_aware_allocation, true, "consider control flow while allocating registers") DEFINE_STRING(turbo_filter, "*", "optimization filter for TurboFan compiler") @@ -608,8 +613,6 @@ DEFINE_BOOL(turbo_store_elimination, true, DEFINE_BOOL(trace_store_elimination, false, "trace store elimination") DEFINE_BOOL(turbo_rewrite_far_jumps, true, "rewrite far to near jumps (ia32,x64)") -DEFINE_BOOL(experimental_inline_promise_constructor, true, - "inline the Promise constructor in TurboFan") DEFINE_BOOL( stress_gc_during_compilation, false, "simulate GC/compiler thread race related to https://crbug.com/v8/8520") @@ -750,7 +753,7 @@ DEFINE_BOOL(wasm_lazy_compilation, false, "enable lazy compilation for all wasm modules") DEFINE_DEBUG_BOOL(trace_wasm_lazy_compilation, false, "trace lazy compilation of wasm functions") -DEFINE_BOOL(wasm_grow_shared_memory, false, +DEFINE_BOOL(wasm_grow_shared_memory, true, "allow growing shared WebAssembly memory objects") DEFINE_BOOL(wasm_lazy_validation, false, "enable lazy validation for lazily compiled wasm functions") @@ -762,6 +765,11 @@ DEFINE_BOOL(wasm_code_gc, true, "enable garbage collection of wasm code") DEFINE_BOOL(trace_wasm_code_gc, false, "trace garbage collection of wasm code") DEFINE_BOOL(stress_wasm_code_gc, false, "stress test garbage collection of wasm code") +DEFINE_BOOL(wasm_far_jump_table, true, + "use multiple separate code spaces that might require far jumps " + "between them") +DEFINE_INT(wasm_max_initial_code_space_reservation, 0, + "maximum size of the initial wasm code space reservation (in MB)") // Profiler flags. DEFINE_INT(frame_count, 1, "number of stack frames inspected by the profiler") @@ -885,6 +893,7 @@ DEFINE_BOOL(trace_gc_object_stats, false, DEFINE_BOOL(trace_zone_stats, false, "trace zone memory usage") DEFINE_BOOL(track_retaining_path, false, "enable support for tracking retaining path") +DEFINE_DEBUG_BOOL(trace_backing_store, false, "trace backing store events") DEFINE_BOOL(concurrent_array_buffer_freeing, true, "free array buffer allocations on a background thread") DEFINE_INT(gc_stats, 0, "Used by tracing internally to enable gc statistics") @@ -961,6 +970,10 @@ DEFINE_BOOL(gc_experiment_less_compaction, false, DEFINE_BOOL(disable_abortjs, false, "disables AbortJS runtime function") +DEFINE_BOOL(randomize_all_allocations, false, + "randomize virtual memory reservations by ignoring any hints " + "passed when allocating pages") + DEFINE_BOOL(manual_evacuation_candidates_selection, false, "Test mode only flag. It allows an unit test to select evacuation " "candidates pages (requires --stress_compaction).") @@ -1227,6 +1240,8 @@ DEFINE_BOOL(print_all_exceptions, false, DEFINE_BOOL( detailed_error_stack_trace, false, "includes arguments for each function call in the error stack frames array") +DEFINE_BOOL(adjust_os_scheduling_parameters, true, + "adjust OS specific scheduling params for the isolate") // runtime.cc DEFINE_BOOL(runtime_call_stats, false, "report runtime call counts and times") @@ -1254,9 +1269,26 @@ DEFINE_UINT(serialization_chunk_size, 4096, DEFINE_BOOL(regexp_optimization, true, "generate optimized regexp code") DEFINE_BOOL(regexp_mode_modifiers, false, "enable inline flags in regexp.") DEFINE_BOOL(regexp_interpret_all, false, "interpret all regexp code") -DEFINE_BOOL(regexp_tier_up, false, - "enable regexp interpreter and tier up to the compiler") -DEFINE_NEG_IMPLICATION(regexp_interpret_all, regexp_tier_up) +#ifdef V8_TARGET_BIG_ENDIAN +#define REGEXP_PEEPHOLE_OPTIMIZATION_BOOL false +#else +#define REGEXP_PEEPHOLE_OPTIMIZATION_BOOL true +#endif +DEFINE_BOOL(regexp_tier_up, true, + "enable regexp interpreter and tier up to the compiler after the " + "number of executions set by the tier up ticks flag") +DEFINE_INT(regexp_tier_up_ticks, 1, + "set the number of executions for the regexp interpreter before " + "tiering-up to the compiler") +DEFINE_BOOL(regexp_peephole_optimization, REGEXP_PEEPHOLE_OPTIMIZATION_BOOL, + "enable peephole optimization for regexp bytecode") +DEFINE_BOOL(trace_regexp_peephole_optimization, false, + "trace regexp bytecode peephole optimization") +DEFINE_BOOL(trace_regexp_bytecodes, false, "trace regexp bytecode execution") +DEFINE_BOOL(trace_regexp_assembler, false, + "trace regexp macro assembler calls.") +DEFINE_BOOL(trace_regexp_parser, false, "trace regexp parsing") +DEFINE_BOOL(trace_regexp_tier_up, false, "trace regexp tiering up execution") // Testing flags test/cctest/test-{flags,api,serialization}.cc DEFINE_BOOL(testing_bool_flag, true, "testing_bool_flag") @@ -1391,11 +1423,6 @@ DEFINE_BOOL(trace_isolates, false, "trace isolate state changes") // Regexp DEFINE_BOOL(regexp_possessive_quantifier, false, "enable possessive quantifier syntax for testing") -DEFINE_BOOL(trace_regexp_bytecodes, false, "trace regexp bytecode execution") -DEFINE_BOOL(trace_regexp_assembler, false, - "trace regexp macro assembler calls.") -DEFINE_BOOL(trace_regexp_parser, false, "trace regexp parsing") -DEFINE_BOOL(trace_regexp_tier_up, false, "trace regexp tiering up execution") // Debugger DEFINE_BOOL(print_break_location, false, "print source location on debug break") @@ -1498,6 +1525,11 @@ DEFINE_BOOL(interpreted_frames_native_stack, false, "profilers).") #endif +// TODO(v8:9206, solanes): remove this when smi-corrupting reducer is fully on. +DEFINE_BOOL_READONLY(turbo_decompression_elimination, true, + "enable the decompression elimination system when " + "pointer compression is enabled.") + // // Disassembler only flags // diff --git a/deps/v8/src/handles/global-handles.cc b/deps/v8/src/handles/global-handles.cc index aed5b3fa834e84..416c65fabd4e48 100644 --- a/deps/v8/src/handles/global-handles.cc +++ b/deps/v8/src/handles/global-handles.cc @@ -901,8 +901,13 @@ void GlobalHandles::IdentifyWeakUnmodifiedObjects( DCHECK(node->is_root()); if (is_unmodified(node->location())) { v8::Value* value = ToApi<v8::Value>(node->handle()); - node->set_root(tracer->IsRootForNonTracingGC( - *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value))); + if (node->has_destructor()) { + node->set_root(tracer->IsRootForNonTracingGC( + *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value))); + } else { + node->set_root(tracer->IsRootForNonTracingGC( + *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value))); + } } } } @@ -990,7 +995,7 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles( } else { v8::Value* value = ToApi<v8::Value>(node->handle()); tracer->ResetHandleInNonTracingGC( - *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value)); + *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value)); DCHECK(!node->IsInUse()); } @@ -1271,8 +1276,13 @@ void GlobalHandles::IterateTracedNodes( for (TracedNode* node : *traced_nodes_) { if (node->IsInUse()) { v8::Value* value = ToApi<v8::Value>(node->handle()); - visitor->VisitTracedGlobalHandle( - *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value)); + if (node->has_destructor()) { + visitor->VisitTracedGlobalHandle( + *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value)); + } else { + visitor->VisitTracedReference( + *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value)); + } } } } diff --git a/deps/v8/src/handles/global-handles.h b/deps/v8/src/handles/global-handles.h index a07f7a772a9878..37b42a54b7aa79 100644 --- a/deps/v8/src/handles/global-handles.h +++ b/deps/v8/src/handles/global-handles.h @@ -5,6 +5,7 @@ #ifndef V8_HANDLES_GLOBAL_HANDLES_H_ #define V8_HANDLES_GLOBAL_HANDLES_H_ +#include <memory> #include <type_traits> #include <utility> #include <vector> diff --git a/deps/v8/src/handles/handles.cc b/deps/v8/src/handles/handles.cc index 7f320a271c3ebf..87c435061e5da6 100644 --- a/deps/v8/src/handles/handles.cc +++ b/deps/v8/src/handles/handles.cc @@ -28,7 +28,7 @@ ASSERT_TRIVIALLY_COPYABLE(Handle<Object>); ASSERT_TRIVIALLY_COPYABLE(MaybeHandle<Object>); #ifdef DEBUG -bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const { +bool HandleBase::IsDereferenceAllowed() const { DCHECK_NOT_NULL(location_); Object object(*location_); if (object.IsSmi()) return true; @@ -40,16 +40,7 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const { RootsTable::IsImmortalImmovable(root_index)) { return true; } - if (!AllowHandleDereference::IsAllowed()) return false; - if (mode == INCLUDE_DEFERRED_CHECK && - !AllowDeferredHandleDereference::IsAllowed()) { - // Accessing cells, maps and internalized strings is safe. - if (heap_object.IsCell()) return true; - if (heap_object.IsMap()) return true; - if (heap_object.IsInternalizedString()) return true; - return !isolate->IsDeferredHandle(location_); - } - return true; + return AllowHandleDereference::IsAllowed(); } #endif @@ -188,13 +179,13 @@ DeferredHandleScope::DeferredHandleScope(Isolate* isolate) } DeferredHandleScope::~DeferredHandleScope() { - impl_->isolate()->handle_scope_data()->level--; DCHECK(handles_detached_); - DCHECK(impl_->isolate()->handle_scope_data()->level == prev_level_); + impl_->isolate()->handle_scope_data()->level--; + DCHECK_EQ(impl_->isolate()->handle_scope_data()->level, prev_level_); } -DeferredHandles* DeferredHandleScope::Detach() { - DeferredHandles* deferred = impl_->Detach(prev_limit_); +std::unique_ptr<DeferredHandles> DeferredHandleScope::Detach() { + std::unique_ptr<DeferredHandles> deferred = impl_->Detach(prev_limit_); HandleScopeData* data = impl_->isolate()->handle_scope_data(); data->next = prev_next_; data->limit = prev_limit_; diff --git a/deps/v8/src/handles/handles.h b/deps/v8/src/handles/handles.h index 5f9b170d4b1e2a..2fea55d1a0de10 100644 --- a/deps/v8/src/handles/handles.h +++ b/deps/v8/src/handles/handles.h @@ -41,11 +41,8 @@ class HandleBase { // Check if this handle refers to the exact same object as the other handle. V8_INLINE bool is_identical_to(const HandleBase that) const { - // Dereferencing deferred handles to check object equality is safe. - SLOW_DCHECK((this->location_ == nullptr || - this->IsDereferenceAllowed(NO_DEFERRED_CHECK)) && - (that.location_ == nullptr || - that.IsDereferenceAllowed(NO_DEFERRED_CHECK))); + SLOW_DCHECK((this->location_ == nullptr || this->IsDereferenceAllowed()) && + (that.location_ == nullptr || that.IsDereferenceAllowed())); if (this->location_ == that.location_) return true; if (this->location_ == nullptr || that.location_ == nullptr) return false; return *this->location_ == *that.location_; @@ -59,20 +56,16 @@ class HandleBase { // Returns the address to where the raw pointer is stored. V8_INLINE Address* location() const { - SLOW_DCHECK(location_ == nullptr || - IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); + SLOW_DCHECK(location_ == nullptr || IsDereferenceAllowed()); return location_; } protected: - enum DereferenceCheckMode { INCLUDE_DEFERRED_CHECK, NO_DEFERRED_CHECK }; #ifdef DEBUG - bool V8_EXPORT_PRIVATE IsDereferenceAllowed(DereferenceCheckMode mode) const; + bool V8_EXPORT_PRIVATE IsDereferenceAllowed() const; #else V8_INLINE - bool V8_EXPORT_PRIVATE IsDereferenceAllowed(DereferenceCheckMode mode) const { - return true; - } + bool V8_EXPORT_PRIVATE IsDereferenceAllowed() const { return true; } #endif // DEBUG // This uses type Address* as opposed to a pointer type to a typed @@ -140,7 +133,7 @@ class Handle final : public HandleBase { V8_INLINE T operator*() const { // unchecked_cast because we rather trust Handle<T> to contain a T than // include all the respective -inl.h headers for SLOW_DCHECKs. - SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK)); + SLOW_DCHECK(IsDereferenceAllowed()); return T::unchecked_cast(Object(*location())); } @@ -318,7 +311,7 @@ class V8_EXPORT_PRIVATE DeferredHandleScope final { // The DeferredHandles object returned stores the Handles created // since the creation of this DeferredHandleScope. The Handles are // alive as long as the DeferredHandles object is alive. - DeferredHandles* Detach(); + std::unique_ptr<DeferredHandles> Detach(); ~DeferredHandleScope(); private: diff --git a/deps/v8/src/heap/array-buffer-collector.cc b/deps/v8/src/heap/array-buffer-collector.cc index b6d7df8191f0f6..672d5e68f059b0 100644 --- a/deps/v8/src/heap/array-buffer-collector.cc +++ b/deps/v8/src/heap/array-buffer-collector.cc @@ -14,33 +14,22 @@ namespace v8 { namespace internal { -namespace { - -void FreeAllocationsHelper( - Heap* heap, const std::vector<JSArrayBuffer::Allocation>& allocations) { - for (JSArrayBuffer::Allocation alloc : allocations) { - JSArrayBuffer::FreeBackingStore(heap->isolate(), alloc); - } -} - -} // namespace - void ArrayBufferCollector::QueueOrFreeGarbageAllocations( - std::vector<JSArrayBuffer::Allocation> allocations) { + std::vector<std::shared_ptr<BackingStore>> backing_stores) { if (heap_->ShouldReduceMemory()) { - FreeAllocationsHelper(heap_, allocations); + // Destruct the vector, which destructs the std::shared_ptrs, freeing + // the backing stores. + backing_stores.clear(); } else { base::MutexGuard guard(&allocations_mutex_); - allocations_.push_back(std::move(allocations)); + allocations_.push_back(std::move(backing_stores)); } } void ArrayBufferCollector::PerformFreeAllocations() { base::MutexGuard guard(&allocations_mutex_); - for (const std::vector<JSArrayBuffer::Allocation>& allocations : - allocations_) { - FreeAllocationsHelper(heap_, allocations); - } + // Destruct the vector, which destructs the vecotr of std::shared_ptrs, + // freeing the backing stores if their refcount drops to zero. allocations_.clear(); } diff --git a/deps/v8/src/heap/array-buffer-collector.h b/deps/v8/src/heap/array-buffer-collector.h index 784092e936d6c7..2d060cc595bd17 100644 --- a/deps/v8/src/heap/array-buffer-collector.h +++ b/deps/v8/src/heap/array-buffer-collector.h @@ -31,7 +31,7 @@ class ArrayBufferCollector { // // FreeAllocations() potentially triggers a background task for processing. void QueueOrFreeGarbageAllocations( - std::vector<JSArrayBuffer::Allocation> allocations); + std::vector<std::shared_ptr<BackingStore>> allocations); // Calls FreeAllocations() on a background thread. void FreeAllocations(); @@ -45,7 +45,7 @@ class ArrayBufferCollector { Heap* const heap_; base::Mutex allocations_mutex_; - std::vector<std::vector<JSArrayBuffer::Allocation>> allocations_; + std::vector<std::vector<std::shared_ptr<BackingStore>>> allocations_; }; } // namespace internal diff --git a/deps/v8/src/heap/array-buffer-tracker-inl.h b/deps/v8/src/heap/array-buffer-tracker-inl.h index 763300cffe2cd9..21106cee4b11a2 100644 --- a/deps/v8/src/heap/array-buffer-tracker-inl.h +++ b/deps/v8/src/heap/array-buffer-tracker-inl.h @@ -12,16 +12,31 @@ #include "src/objects/js-array-buffer-inl.h" #include "src/objects/objects.h" +#define TRACE_BS(...) \ + do { \ + if (FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ + } while (false) + namespace v8 { namespace internal { -void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer buffer) { - if (buffer.backing_store() == nullptr) return; +inline size_t PerIsolateAccountingLength(JSArrayBuffer buffer) { + // TODO(titzer): SharedArrayBuffers and shared WasmMemorys cause problems with + // accounting for per-isolate external memory. In particular, sharing the same + // array buffer or memory multiple times, which happens in stress tests, can + // cause overcounting, leading to GC thrashing. Fix with global accounting? + return buffer.is_shared() ? 0 : buffer.byte_length(); +} + +void ArrayBufferTracker::RegisterNew( + Heap* heap, JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store) { + if (!backing_store) return; // ArrayBuffer tracking works only for small objects. DCHECK(!heap->IsLargeObject(buffer)); + DCHECK_EQ(backing_store->buffer_start(), buffer.backing_store()); - const size_t length = buffer.byte_length(); Page* page = Page::FromHeapObject(buffer); { base::MutexGuard guard(page->mutex()); @@ -31,44 +46,63 @@ void ArrayBufferTracker::RegisterNew(Heap* heap, JSArrayBuffer buffer) { tracker = page->local_tracker(); } DCHECK_NOT_NULL(tracker); - tracker->Add(buffer, length); + TRACE_BS("ABT:reg bs=%p mem=%p (length=%zu) cnt=%ld\n", + backing_store.get(), backing_store->buffer_start(), + backing_store->byte_length(), backing_store.use_count()); + tracker->Add(buffer, std::move(backing_store)); } // TODO(wez): Remove backing-store from external memory accounting. // We may go over the limit of externally allocated memory here. We call the // api function to trigger a GC in this case. + const size_t length = PerIsolateAccountingLength(buffer); reinterpret_cast<v8::Isolate*>(heap->isolate()) ->AdjustAmountOfExternalAllocatedMemory(length); } -void ArrayBufferTracker::Unregister(Heap* heap, JSArrayBuffer buffer) { - if (buffer.backing_store() == nullptr) return; +std::shared_ptr<BackingStore> ArrayBufferTracker::Unregister( + Heap* heap, JSArrayBuffer buffer) { + std::shared_ptr<BackingStore> backing_store; + const size_t length = PerIsolateAccountingLength(buffer); Page* page = Page::FromHeapObject(buffer); - const size_t length = buffer.byte_length(); { base::MutexGuard guard(page->mutex()); LocalArrayBufferTracker* tracker = page->local_tracker(); DCHECK_NOT_NULL(tracker); - tracker->Remove(buffer, length); + backing_store = tracker->Remove(buffer); } // TODO(wez): Remove backing-store from external memory accounting. heap->update_external_memory(-static_cast<intptr_t>(length)); + return backing_store; +} + +std::shared_ptr<BackingStore> ArrayBufferTracker::Lookup(Heap* heap, + JSArrayBuffer buffer) { + if (buffer.backing_store() == nullptr) return {}; + + Page* page = Page::FromHeapObject(buffer); + base::MutexGuard guard(page->mutex()); + LocalArrayBufferTracker* tracker = page->local_tracker(); + DCHECK_NOT_NULL(tracker); + return tracker->Lookup(buffer); } template <typename Callback> void LocalArrayBufferTracker::Free(Callback should_free) { size_t freed_memory = 0; - Isolate* isolate = page_->heap()->isolate(); for (TrackingData::iterator it = array_buffers_.begin(); it != array_buffers_.end();) { // Unchecked cast because the map might already be dead at this point. JSArrayBuffer buffer = JSArrayBuffer::unchecked_cast(it->first); - const size_t length = it->second.length; + const size_t length = PerIsolateAccountingLength(buffer); if (should_free(buffer)) { - JSArrayBuffer::FreeBackingStore(isolate, it->second); + // Destroy the shared pointer, (perhaps) freeing the backing store. + TRACE_BS("ABT:die bs=%p mem=%p (length=%zu) cnt=%ld\n", + it->second.get(), it->second->buffer_start(), + it->second->byte_length(), it->second.use_count()); it = array_buffers_.erase(it); freed_memory += length; } else { @@ -97,35 +131,60 @@ void ArrayBufferTracker::FreeDead(Page* page, MarkingState* marking_state) { } } -void LocalArrayBufferTracker::Add(JSArrayBuffer buffer, size_t length) { +void LocalArrayBufferTracker::Add(JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store) { + auto length = PerIsolateAccountingLength(buffer); page_->IncrementExternalBackingStoreBytes( ExternalBackingStoreType::kArrayBuffer, length); - AddInternal(buffer, length); + AddInternal(buffer, std::move(backing_store)); } -void LocalArrayBufferTracker::AddInternal(JSArrayBuffer buffer, size_t length) { - auto ret = array_buffers_.insert( - {buffer, - {buffer.backing_store(), length, buffer.backing_store(), - buffer.is_wasm_memory()}}); +void LocalArrayBufferTracker::AddInternal( + JSArrayBuffer buffer, std::shared_ptr<BackingStore> backing_store) { + auto ret = array_buffers_.insert({buffer, std::move(backing_store)}); USE(ret); // Check that we indeed inserted a new value and did not overwrite an existing // one (which would be a bug). DCHECK(ret.second); } -void LocalArrayBufferTracker::Remove(JSArrayBuffer buffer, size_t length) { - page_->DecrementExternalBackingStoreBytes( - ExternalBackingStoreType::kArrayBuffer, length); - +std::shared_ptr<BackingStore> LocalArrayBufferTracker::Remove( + JSArrayBuffer buffer) { TrackingData::iterator it = array_buffers_.find(buffer); + // Check that we indeed find a key to remove. DCHECK(it != array_buffers_.end()); - DCHECK_EQ(length, it->second.length); + + // Steal the underlying shared pointer before erasing the entry. + std::shared_ptr<BackingStore> backing_store = std::move(it->second); + + TRACE_BS("ABT:rm bs=%p mem=%p (length=%zu) cnt=%ld\n", backing_store.get(), + backing_store->buffer_start(), backing_store->byte_length(), + backing_store.use_count()); + + // Erase the entry. array_buffers_.erase(it); + + // Update accounting. + auto length = PerIsolateAccountingLength(buffer); + page_->DecrementExternalBackingStoreBytes( + ExternalBackingStoreType::kArrayBuffer, length); + + return backing_store; +} + +std::shared_ptr<BackingStore> LocalArrayBufferTracker::Lookup( + JSArrayBuffer buffer) { + TrackingData::iterator it = array_buffers_.find(buffer); + if (it != array_buffers_.end()) { + return it->second; + } + return {}; } +#undef TRACE_BS + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/heap/array-buffer-tracker.cc b/deps/v8/src/heap/array-buffer-tracker.cc index fdca6e8df27b56..b284a65f66aa3c 100644 --- a/deps/v8/src/heap/array-buffer-tracker.cc +++ b/deps/v8/src/heap/array-buffer-tracker.cc @@ -11,6 +11,11 @@ #include "src/heap/heap.h" #include "src/heap/spaces.h" +#define TRACE_BS(...) \ + do { \ + if (FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ + } while (false) + namespace v8 { namespace internal { @@ -20,7 +25,7 @@ LocalArrayBufferTracker::~LocalArrayBufferTracker() { template <typename Callback> void LocalArrayBufferTracker::Process(Callback callback) { - std::vector<JSArrayBuffer::Allocation> backing_stores_to_free; + std::vector<std::shared_ptr<BackingStore>> backing_stores_to_free; TrackingData kept_array_buffers; JSArrayBuffer new_buffer; @@ -32,8 +37,9 @@ void LocalArrayBufferTracker::Process(Callback callback) { DCHECK_EQ(page_, Page::FromHeapObject(old_buffer)); const CallbackResult result = callback(old_buffer, &new_buffer); if (result == kKeepEntry) { - kept_array_buffers.insert(*it); + kept_array_buffers.insert(std::move(*it)); } else if (result == kUpdateEntry) { + DCHECK_EQ(old_buffer.byte_length(), new_buffer.byte_length()); DCHECK(!new_buffer.is_null()); Page* target_page = Page::FromHeapObject(new_buffer); { @@ -44,22 +50,28 @@ void LocalArrayBufferTracker::Process(Callback callback) { tracker = target_page->local_tracker(); } DCHECK_NOT_NULL(tracker); - const size_t length = it->second.length; + const size_t length = PerIsolateAccountingLength(old_buffer); // We should decrement before adding to avoid potential overflows in // the external memory counters. - DCHECK_EQ(it->first.is_wasm_memory(), it->second.is_wasm_memory); - tracker->AddInternal(new_buffer, length); + tracker->AddInternal(new_buffer, std::move(it->second)); MemoryChunk::MoveExternalBackingStoreBytes( ExternalBackingStoreType::kArrayBuffer, static_cast<MemoryChunk*>(page_), static_cast<MemoryChunk*>(target_page), length); } } else if (result == kRemoveEntry) { - freed_memory += it->second.length; - // We pass backing_store() and stored length to the collector for freeing - // the backing store. Wasm allocations will go through their own tracker - // based on the backing store. - backing_stores_to_free.push_back(it->second); + freed_memory += PerIsolateAccountingLength(old_buffer); + auto backing_store = std::move(it->second); + TRACE_BS("ABT:queue bs=%p mem=%p (length=%zu) cnt=%ld\n", + backing_store.get(), backing_store->buffer_start(), + backing_store->byte_length(), backing_store.use_count()); + if (!backing_store->is_shared()) { + // Only retain non-shared backing stores. For shared backing stores, + // drop the shared_ptr right away, since this should be cheap, + // as it only updates a refcount, except that last, which will + // destruct it, which is rare. + backing_stores_to_free.push_back(backing_store); + } } else { UNREACHABLE(); } @@ -147,3 +159,4 @@ void ArrayBufferTracker::TearDown(Heap* heap) { } // namespace internal } // namespace v8 +#undef TRACE_BS diff --git a/deps/v8/src/heap/array-buffer-tracker.h b/deps/v8/src/heap/array-buffer-tracker.h index b7950c25069016..156c226406224d 100644 --- a/deps/v8/src/heap/array-buffer-tracker.h +++ b/deps/v8/src/heap/array-buffer-tracker.h @@ -9,6 +9,7 @@ #include "src/base/platform/mutex.h" #include "src/common/globals.h" +#include "src/objects/backing-store.h" #include "src/objects/js-array-buffer.h" #include "src/utils/allocation.h" @@ -31,8 +32,12 @@ class ArrayBufferTracker : public AllStatic { // Register/unregister a new JSArrayBuffer |buffer| for tracking. Guards all // access to the tracker by taking the page lock for the corresponding page. - inline static void RegisterNew(Heap* heap, JSArrayBuffer buffer); - inline static void Unregister(Heap* heap, JSArrayBuffer buffer); + inline static void RegisterNew(Heap* heap, JSArrayBuffer buffer, + std::shared_ptr<BackingStore>); + inline static std::shared_ptr<BackingStore> Unregister(Heap* heap, + JSArrayBuffer buffer); + inline static std::shared_ptr<BackingStore> Lookup(Heap* heap, + JSArrayBuffer buffer); // Identifies all backing store pointers for dead JSArrayBuffers in new space. // Does not take any locks and can only be called during Scavenge. @@ -70,8 +75,10 @@ class LocalArrayBufferTracker { explicit LocalArrayBufferTracker(Page* page) : page_(page) {} ~LocalArrayBufferTracker(); - inline void Add(JSArrayBuffer buffer, size_t length); - inline void Remove(JSArrayBuffer buffer, size_t length); + inline void Add(JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store); + inline std::shared_ptr<BackingStore> Remove(JSArrayBuffer buffer); + inline std::shared_ptr<BackingStore> Lookup(JSArrayBuffer buffer); // Frees up array buffers. // @@ -105,17 +112,13 @@ class LocalArrayBufferTracker { } }; - // Keep track of the backing store and the corresponding length at time of - // registering. The length is accessed from JavaScript and can be a - // HeapNumber. The reason for tracking the length is that in the case of - // length being a HeapNumber, the buffer and its length may be stored on - // different memory pages, making it impossible to guarantee order of freeing. using TrackingData = - std::unordered_map<JSArrayBuffer, JSArrayBuffer::Allocation, Hasher>; + std::unordered_map<JSArrayBuffer, std::shared_ptr<BackingStore>, Hasher>; // Internal version of add that does not update counters. Requires separate // logic for updating external memory counters. - inline void AddInternal(JSArrayBuffer buffer, size_t length); + inline void AddInternal(JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store); Page* page_; // The set contains raw heap pointers which are removed by the GC upon diff --git a/deps/v8/src/heap/basic-memory-chunk.h b/deps/v8/src/heap/basic-memory-chunk.h index 65fc072bd24337..c0d4ade522b00d 100644 --- a/deps/v8/src/heap/basic-memory-chunk.h +++ b/deps/v8/src/heap/basic-memory-chunk.h @@ -10,12 +10,19 @@ #include "src/base/atomic-utils.h" #include "src/common/globals.h" #include "src/heap/marking.h" +#include "src/heap/slot-set.h" namespace v8 { namespace internal { class MemoryChunk; +enum RememberedSetType { + OLD_TO_NEW, + OLD_TO_OLD, + NUMBER_OF_REMEMBERED_SET_TYPES +}; + class BasicMemoryChunk { public: enum Flag { @@ -170,6 +177,11 @@ class BasicMemoryChunk { static const intptr_t kHeapOffset = kMarkBitmapOffset + kSystemPointerSize; static const intptr_t kHeaderSentinelOffset = kHeapOffset + kSystemPointerSize; + static const intptr_t kAreaStartOffset = + kHeaderSentinelOffset + kSystemPointerSize; + static const intptr_t kAreaEndOffset = kAreaStartOffset + kSystemPointerSize; + static const intptr_t kOldToNewSlotSetOffset = + kAreaEndOffset + kSystemPointerSize; static const size_t kHeaderSize = kSizeOffset + kSizetSize // size_t size @@ -178,7 +190,8 @@ class BasicMemoryChunk { + kSystemPointerSize // Heap* heap_ + kSystemPointerSize // Address header_sentinel_ + kSystemPointerSize // Address area_start_ - + kSystemPointerSize; // Address area_end_ + + kSystemPointerSize // Address area_end_ + + kSystemPointerSize * NUMBER_OF_REMEMBERED_SET_TYPES; // SlotSet* array protected: // Overall size of the chunk, including the header and guards. @@ -204,6 +217,11 @@ class BasicMemoryChunk { Address area_start_; Address area_end_; + // A single slot set for small pages (of size kPageSize) or an array of slot + // set for large pages. In the latter case the number of entries in the array + // is ceil(size() / kPageSize). + SlotSet* slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]; + friend class BasicMemoryChunkValidator; }; @@ -221,6 +239,8 @@ class BasicMemoryChunkValidator { offsetof(BasicMemoryChunk, heap_)); STATIC_ASSERT(BasicMemoryChunk::kHeaderSentinelOffset == offsetof(BasicMemoryChunk, header_sentinel_)); + STATIC_ASSERT(BasicMemoryChunk::kOldToNewSlotSetOffset == + offsetof(BasicMemoryChunk, slot_set_)); }; } // namespace internal diff --git a/deps/v8/src/heap/concurrent-marking.cc b/deps/v8/src/heap/concurrent-marking.cc index 12bb28f1c8e20f..6a155c78ea8afc 100644 --- a/deps/v8/src/heap/concurrent-marking.cc +++ b/deps/v8/src/heap/concurrent-marking.cc @@ -8,7 +8,6 @@ #include <unordered_map> #include "include/v8config.h" -#include "src/base/template-utils.h" #include "src/execution/isolate.h" #include "src/heap/gc-tracer.h" #include "src/heap/heap-inl.h" @@ -225,6 +224,9 @@ class ConcurrentMarkingVisitor final } if (weak_ref.target().IsHeapObject()) { HeapObject target = HeapObject::cast(weak_ref.target()); +#ifdef THREAD_SANITIZER + MemoryChunk::FromHeapObject(target)->SynchronizedHeapLoad(); +#endif if (marking_state_.IsBlackOrGrey(target)) { // Record the slot inside the JSWeakRef, since the // VisitJSObjectSubclass above didn't visit it. @@ -247,6 +249,9 @@ class ConcurrentMarkingVisitor final WeakCell::BodyDescriptor::IterateBody(map, weak_cell, size, this); if (weak_cell.target().IsHeapObject()) { HeapObject target = HeapObject::cast(weak_cell.target()); +#ifdef THREAD_SANITIZER + MemoryChunk::FromHeapObject(target)->SynchronizedHeapLoad(); +#endif if (marking_state_.IsBlackOrGrey(target)) { // Record the slot inside the WeakCell, since the IterateBody above // didn't visit it. @@ -478,6 +483,9 @@ class ConcurrentMarkingVisitor final ObjectSlot key_slot = table.RawFieldOfElementAt(EphemeronHashTable::EntryToIndex(i)); HeapObject key = HeapObject::cast(table.KeyAt(i)); +#ifdef THREAD_SANITIZER + MemoryChunk::FromHeapObject(key)->SynchronizedHeapLoad(); +#endif MarkCompactCollector::RecordSlot(table, key_slot, key); ObjectSlot value_slot = @@ -491,6 +499,9 @@ class ConcurrentMarkingVisitor final if (value_obj.IsHeapObject()) { HeapObject value = HeapObject::cast(value_obj); +#ifdef THREAD_SANITIZER + MemoryChunk::FromHeapObject(value)->SynchronizedHeapLoad(); +#endif MarkCompactCollector::RecordSlot(table, value_slot, value); // Revisit ephemerons with both key and value unreachable at end @@ -864,8 +875,7 @@ void ConcurrentMarking::ScheduleTasks() { DCHECK(FLAG_parallel_marking || FLAG_concurrent_marking); DCHECK(!heap_->IsTearingDown()); base::MutexGuard guard(&pending_lock_); - DCHECK_EQ(0, pending_task_count_); - if (task_count_ == 0) { + if (total_task_count_ == 0) { static const int num_cores = V8::GetCurrentPlatform()->NumberOfWorkerThreads() + 1; #if defined(V8_OS_MACOSX) @@ -873,15 +883,18 @@ void ConcurrentMarking::ScheduleTasks() { // marking on competing hyper-threads (regresses Octane/Splay). As such, // only use num_cores/2, leaving one of those for the main thread. // TODO(ulan): Use all cores on Mac 10.12+. - task_count_ = Max(1, Min(kMaxTasks, (num_cores / 2) - 1)); + total_task_count_ = Max(1, Min(kMaxTasks, (num_cores / 2) - 1)); #else // defined(OS_MACOSX) // On other platforms use all logical cores, leaving one for the main // thread. - task_count_ = Max(1, Min(kMaxTasks, num_cores - 1)); + total_task_count_ = Max(1, Min(kMaxTasks, num_cores - 1)); #endif // defined(OS_MACOSX) + DCHECK_LE(total_task_count_, kMaxTasks); + // One task is for the main thread. + STATIC_ASSERT(kMaxTasks + 1 <= MarkingWorklist::kMaxNumTasks); } // Task id 0 is for the main thread. - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { if (!is_pending_[i]) { if (FLAG_trace_concurrent_marking) { heap_->isolate()->PrintWithTimestamp( @@ -894,12 +907,12 @@ void ConcurrentMarking::ScheduleTasks() { is_pending_[i] = true; ++pending_task_count_; auto task = - base::make_unique<Task>(heap_->isolate(), this, &task_state_[i], i); + std::make_unique<Task>(heap_->isolate(), this, &task_state_[i], i); cancelable_id_[i] = task->id(); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task)); } } - DCHECK_EQ(task_count_, pending_task_count_); + DCHECK_EQ(total_task_count_, pending_task_count_); } void ConcurrentMarking::RescheduleTasksIfNeeded() { @@ -907,11 +920,15 @@ void ConcurrentMarking::RescheduleTasksIfNeeded() { if (heap_->IsTearingDown()) return; { base::MutexGuard guard(&pending_lock_); - if (pending_task_count_ > 0) return; + // The total task count is initialized in ScheduleTasks from + // NumberOfWorkerThreads of the platform. + if (total_task_count_ > 0 && pending_task_count_ == total_task_count_) { + return; + } } if (!shared_->IsGlobalPoolEmpty() || - !weak_objects_->current_ephemerons.IsEmpty() || - !weak_objects_->discovered_ephemerons.IsEmpty()) { + !weak_objects_->current_ephemerons.IsGlobalPoolEmpty() || + !weak_objects_->discovered_ephemerons.IsGlobalPoolEmpty()) { ScheduleTasks(); } } @@ -925,7 +942,7 @@ bool ConcurrentMarking::Stop(StopRequest stop_request) { if (stop_request != StopRequest::COMPLETE_TASKS_FOR_TESTING) { CancelableTaskManager* task_manager = heap_->isolate()->cancelable_task_manager(); - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { if (is_pending_[i]) { if (task_manager->TryAbort(cancelable_id_[i]) == TryAbortResult::kTaskAborted) { @@ -940,7 +957,7 @@ bool ConcurrentMarking::Stop(StopRequest stop_request) { while (pending_task_count_ > 0) { pending_condition_.Wait(&pending_lock_); } - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { DCHECK(!is_pending_[i]); } return true; @@ -956,7 +973,7 @@ bool ConcurrentMarking::IsStopped() { void ConcurrentMarking::FlushMemoryChunkData( MajorNonAtomicMarkingState* marking_state) { DCHECK_EQ(pending_task_count_, 0); - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { MemoryChunkDataMap& memory_chunk_data = task_state_[i].memory_chunk_data; for (auto& pair : memory_chunk_data) { // ClearLiveness sets the live bytes to zero. @@ -978,7 +995,7 @@ void ConcurrentMarking::FlushMemoryChunkData( } void ConcurrentMarking::ClearMemoryChunkData(MemoryChunk* chunk) { - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { auto it = task_state_[i].memory_chunk_data.find(chunk); if (it != task_state_[i].memory_chunk_data.end()) { it->second.live_bytes = 0; @@ -989,7 +1006,7 @@ void ConcurrentMarking::ClearMemoryChunkData(MemoryChunk* chunk) { size_t ConcurrentMarking::TotalMarkedBytes() { size_t result = 0; - for (int i = 1; i <= task_count_; i++) { + for (int i = 1; i <= total_task_count_; i++) { result += base::AsAtomicWord::Relaxed_Load<size_t>(&task_state_[i].marked_bytes); } diff --git a/deps/v8/src/heap/concurrent-marking.h b/deps/v8/src/heap/concurrent-marking.h index be2fc03d462d5a..c08a9c47b05db0 100644 --- a/deps/v8/src/heap/concurrent-marking.h +++ b/deps/v8/src/heap/concurrent-marking.h @@ -5,6 +5,8 @@ #ifndef V8_HEAP_CONCURRENT_MARKING_H_ #define V8_HEAP_CONCURRENT_MARKING_H_ +#include <memory> + #include "include/v8-platform.h" #include "src/base/atomic-utils.h" #include "src/base/platform/condition-variable.h" @@ -86,8 +88,6 @@ class V8_EXPORT_PRIVATE ConcurrentMarking { // scavenge and is going to be re-used. void ClearMemoryChunkData(MemoryChunk* chunk); - int TaskCount() { return task_count_; } - // Checks if all threads are stopped. bool IsStopped(); @@ -124,7 +124,7 @@ class V8_EXPORT_PRIVATE ConcurrentMarking { int pending_task_count_ = 0; bool is_pending_[kMaxTasks + 1] = {}; CancelableTaskManager::Id cancelable_id_[kMaxTasks + 1] = {}; - int task_count_ = 0; + int total_task_count_ = 0; }; } // namespace internal diff --git a/deps/v8/src/heap/embedder-tracing.h b/deps/v8/src/heap/embedder-tracing.h index 7c67ccfab71ea6..a150f2c26a3e39 100644 --- a/deps/v8/src/heap/embedder-tracing.h +++ b/deps/v8/src/heap/embedder-tracing.h @@ -57,7 +57,12 @@ class V8_EXPORT_PRIVATE LocalEmbedderHeapTracer final { bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) { return !InUse() || remote_tracer_->IsRootForNonTracingGC(handle); } - void ResetHandleInNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) { + + bool IsRootForNonTracingGC(const v8::TracedReference<v8::Value>& handle) { + return !InUse() || remote_tracer_->IsRootForNonTracingGC(handle); + } + + void ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value>& handle) { // Resetting is only called when IsRootForNonTracingGC returns false which // can only happen the EmbedderHeapTracer is set on API level. DCHECK(InUse()); diff --git a/deps/v8/src/heap/factory-inl.h b/deps/v8/src/heap/factory-inl.h index bcad5d271410cf..f0f61bbb2c1aeb 100644 --- a/deps/v8/src/heap/factory-inl.h +++ b/deps/v8/src/heap/factory-inl.h @@ -43,44 +43,41 @@ Handle<String> Factory::NewSubString(Handle<String> str, int begin, int end) { return NewProperSubString(str, begin, end); } -Handle<Object> Factory::NewNumberFromSize(size_t value, - AllocationType allocation) { +Handle<Object> Factory::NewNumberFromSize(size_t value) { // We can't use Smi::IsValid() here because that operates on a signed // intptr_t, and casting from size_t could create a bogus sign bit. if (value <= static_cast<size_t>(Smi::kMaxValue)) { return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)), isolate()); } - return NewNumber(static_cast<double>(value), allocation); + return NewNumber(static_cast<double>(value)); } -Handle<Object> Factory::NewNumberFromInt64(int64_t value, - AllocationType allocation) { +Handle<Object> Factory::NewNumberFromInt64(int64_t value) { if (value <= std::numeric_limits<int32_t>::max() && value >= std::numeric_limits<int32_t>::min() && Smi::IsValid(static_cast<int32_t>(value))) { return Handle<Object>(Smi::FromInt(static_cast<int32_t>(value)), isolate()); } - return NewNumber(static_cast<double>(value), allocation); + return NewNumber(static_cast<double>(value)); } -Handle<HeapNumber> Factory::NewHeapNumber(double value, - AllocationType allocation) { - Handle<HeapNumber> heap_number = NewHeapNumber(allocation); +template <AllocationType allocation> +Handle<HeapNumber> Factory::NewHeapNumber(double value) { + Handle<HeapNumber> heap_number = NewHeapNumber<allocation>(); heap_number->set_value(value); return heap_number; } -Handle<HeapNumber> Factory::NewHeapNumberFromBits(uint64_t bits, - AllocationType allocation) { - Handle<HeapNumber> heap_number = NewHeapNumber(allocation); +template <AllocationType allocation> +Handle<HeapNumber> Factory::NewHeapNumberFromBits(uint64_t bits) { + Handle<HeapNumber> heap_number = NewHeapNumber<allocation>(); heap_number->set_value_as_bits(bits); return heap_number; } -Handle<HeapNumber> Factory::NewHeapNumberWithHoleNaN( - AllocationType allocation) { - return NewHeapNumberFromBits(kHoleNanInt64, allocation); +Handle<HeapNumber> Factory::NewHeapNumberWithHoleNaN() { + return NewHeapNumberFromBits(kHoleNanInt64); } Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc index 9bf46be6e815a1..721682f00f26de 100644 --- a/deps/v8/src/heap/factory.cc +++ b/deps/v8/src/heap/factory.cc @@ -11,6 +11,7 @@ #include "src/builtins/constants-table-builder.h" #include "src/codegen/compiler.h" #include "src/execution/isolate-inl.h" +#include "src/execution/protectors-inl.h" #include "src/heap/heap-inl.h" #include "src/heap/incremental-marking.h" #include "src/heap/mark-compact-inl.h" @@ -117,11 +118,11 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal( CodePageCollectionMemoryModificationScope code_allocation(heap); HeapObject result; if (retry_allocation_or_fail) { - result = - heap->AllocateRawWithRetryOrFail(object_size, AllocationType::kCode); + result = heap->AllocateRawWith<Heap::kRetryOrFail>(object_size, + AllocationType::kCode); } else { - result = - heap->AllocateRawWithLightRetry(object_size, AllocationType::kCode); + result = heap->AllocateRawWith<Heap::kLightRetry>(object_size, + AllocationType::kCode); // Return an empty handle if we cannot allocate the code object. if (result.is_null()) return MaybeHandle<Code>(); } @@ -209,8 +210,8 @@ HeapObject Factory::AllocateRawWithImmortalMap(int size, AllocationType allocation, Map map, AllocationAlignment alignment) { - HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail( - size, allocation, alignment); + HeapObject result = isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>( + size, allocation, AllocationOrigin::kRuntime, alignment); result.set_map_after_allocation(map, SKIP_WRITE_BARRIER); return result; } @@ -222,7 +223,7 @@ HeapObject Factory::AllocateRawWithAllocationSite( int size = map->instance_size(); if (!allocation_site.is_null()) size += AllocationMemento::kSize; HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, allocation); + isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>(size, allocation); WriteBarrierMode write_barrier_mode = allocation == AllocationType::kYoung ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; @@ -247,7 +248,7 @@ void Factory::InitializeAllocationMemento(AllocationMemento memento, HeapObject Factory::AllocateRawArray(int size, AllocationType allocation) { HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, allocation); + isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>(size, allocation); if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) { MemoryChunk* chunk = MemoryChunk::FromHeapObject(result); chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR); @@ -275,7 +276,7 @@ HeapObject Factory::New(Handle<Map> map, AllocationType allocation) { DCHECK(map->instance_type() != MAP_TYPE); int size = map->instance_size(); HeapObject result = - isolate()->heap()->AllocateRawWithRetryOrFail(size, allocation); + isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>(size, allocation); // New space objects are allocated white. WriteBarrierMode write_barrier_mode = allocation == AllocationType::kYoung ? SKIP_WRITE_BARRIER @@ -289,8 +290,8 @@ Handle<HeapObject> Factory::NewFillerObject(int size, bool double_align, AllocationOrigin origin) { AllocationAlignment alignment = double_align ? kDoubleAligned : kWordAligned; Heap* heap = isolate()->heap(); - HeapObject result = - heap->AllocateRawWithRetryOrFail(size, allocation, origin, alignment); + HeapObject result = heap->AllocateRawWith<Heap::kRetryOrFail>( + size, allocation, origin, alignment); heap->CreateFillerObjectAt(result.address(), size, ClearRecordedSlots::kNo); return Handle<HeapObject>(result, isolate()); } @@ -323,17 +324,6 @@ Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, Handle<Object> value2, return result; } -Handle<Tuple3> Factory::NewTuple3(Handle<Object> value1, Handle<Object> value2, - Handle<Object> value3, - AllocationType allocation) { - Handle<Tuple3> result = - Handle<Tuple3>::cast(NewStruct(TUPLE3_TYPE, allocation)); - result->set_value1(*value1); - result->set_value2(*value2); - result->set_value3(*value3); - return result; -} - Handle<ArrayBoilerplateDescription> Factory::NewArrayBoilerplateDescription( ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) { Handle<ArrayBoilerplateDescription> result = @@ -358,24 +348,23 @@ Handle<TemplateObjectDescription> Factory::NewTemplateObjectDescription( Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string, Handle<Object> to_number, - const char* type_of, byte kind, - AllocationType allocation) { - Handle<Oddball> oddball(Oddball::cast(New(map, allocation)), isolate()); + const char* type_of, byte kind) { + Handle<Oddball> oddball(Oddball::cast(New(map, AllocationType::kReadOnly)), + isolate()); Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind); return oddball; } -Handle<Oddball> Factory::NewSelfReferenceMarker(AllocationType allocation) { +Handle<Oddball> Factory::NewSelfReferenceMarker() { return NewOddball(self_reference_marker_map(), "self_reference_marker", handle(Smi::FromInt(-1), isolate()), "undefined", - Oddball::kSelfReferenceMarker, allocation); + Oddball::kSelfReferenceMarker); } -Handle<PropertyArray> Factory::NewPropertyArray(int length, - AllocationType allocation) { +Handle<PropertyArray> Factory::NewPropertyArray(int length) { DCHECK_LE(0, length); if (length == 0) return empty_property_array(); - HeapObject result = AllocateRawFixedArray(length, allocation); + HeapObject result = AllocateRawFixedArray(length, AllocationType::kYoung); result.set_map_after_allocation(*property_array_map(), SKIP_WRITE_BARRIER); Handle<PropertyArray> array(PropertyArray::cast(result), isolate()); array->initialize_length(length); @@ -419,7 +408,7 @@ Handle<T> Factory::NewWeakFixedArrayWithMap(RootIndex map_root_index, DCHECK_LT(0, length); HeapObject result = - AllocateRawArray(WeakFixedArray::SizeFor(length), allocation); + AllocateRawArray(WeakFixedArray::SizeFor(length), AllocationType::kOld); Map map = Map::cast(isolate()->root(map_root_index)); result.set_map_after_allocation(map, SKIP_WRITE_BARRIER); @@ -485,8 +474,7 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int length, *the_hole_value(), allocation); } -Handle<FixedArray> Factory::NewUninitializedFixedArray( - int length, AllocationType allocation) { +Handle<FixedArray> Factory::NewUninitializedFixedArray(int length) { DCHECK_LE(0, length); if (length == 0) return empty_fixed_array(); @@ -494,30 +482,30 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray( // array. After getting canary/performance coverage, either remove the // function or revert to returning uninitilized array. return NewFixedArrayWithFiller(RootIndex::kFixedArrayMap, length, - *undefined_value(), allocation); + *undefined_value(), AllocationType::kYoung); } Handle<ClosureFeedbackCellArray> Factory::NewClosureFeedbackCellArray( - int length, AllocationType allocation) { + int length) { if (length == 0) return empty_closure_feedback_cell_array(); Handle<ClosureFeedbackCellArray> feedback_cell_array = NewFixedArrayWithMap<ClosureFeedbackCellArray>( - RootIndex::kClosureFeedbackCellArrayMap, length, allocation); + RootIndex::kClosureFeedbackCellArrayMap, length, + AllocationType::kYoung); return feedback_cell_array; } Handle<FeedbackVector> Factory::NewFeedbackVector( Handle<SharedFunctionInfo> shared, - Handle<ClosureFeedbackCellArray> closure_feedback_cell_array, - AllocationType allocation) { + Handle<ClosureFeedbackCellArray> closure_feedback_cell_array) { int length = shared->feedback_metadata().slot_count(); DCHECK_LE(0, length); int size = FeedbackVector::SizeFor(length); - HeapObject result = - AllocateRawWithImmortalMap(size, allocation, *feedback_vector_map()); + HeapObject result = AllocateRawWithImmortalMap(size, AllocationType::kOld, + *feedback_vector_map()); Handle<FeedbackVector> vector(FeedbackVector::cast(result), isolate()); vector->set_shared_function_info(*shared); vector->set_optimized_code_weak_or_smi(MaybeObject::FromSmi(Smi::FromEnum( @@ -534,13 +522,12 @@ Handle<FeedbackVector> Factory::NewFeedbackVector( return vector; } -Handle<EmbedderDataArray> Factory::NewEmbedderDataArray( - int length, AllocationType allocation) { +Handle<EmbedderDataArray> Factory::NewEmbedderDataArray(int length) { DCHECK_LE(0, length); int size = EmbedderDataArray::SizeFor(length); - HeapObject result = - AllocateRawWithImmortalMap(size, allocation, *embedder_data_array_map()); + HeapObject result = AllocateRawWithImmortalMap(size, AllocationType::kYoung, + *embedder_data_array_map()); Handle<EmbedderDataArray> array(EmbedderDataArray::cast(result), isolate()); array->set_length(length); @@ -589,25 +576,23 @@ Handle<ObjectBoilerplateDescription> Factory::NewObjectBoilerplateDescription( return description; } -Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int length, - AllocationType allocation) { +Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int length) { if (length == 0) return empty_fixed_array(); if (length < 0 || length > FixedDoubleArray::kMaxLength) { isolate()->heap()->FatalProcessOutOfMemory("invalid array length"); } int size = FixedDoubleArray::SizeFor(length); Map map = *fixed_double_array_map(); - HeapObject result = - AllocateRawWithImmortalMap(size, allocation, map, kDoubleAligned); + HeapObject result = AllocateRawWithImmortalMap(size, AllocationType::kYoung, + map, kDoubleAligned); Handle<FixedDoubleArray> array(FixedDoubleArray::cast(result), isolate()); array->set_length(length); return array; } -Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles( - int length, AllocationType allocation) { +Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(int length) { DCHECK_LE(0, length); - Handle<FixedArrayBase> array = NewFixedDoubleArray(length, allocation); + Handle<FixedArrayBase> array = NewFixedDoubleArray(length); if (length > 0) { Handle<FixedDoubleArray>::cast(array)->FillWithHoles(0, length); } @@ -633,11 +618,10 @@ Handle<FeedbackMetadata> Factory::NewFeedbackMetadata( return data; } -Handle<FrameArray> Factory::NewFrameArray(int number_of_frames, - AllocationType allocation) { +Handle<FrameArray> Factory::NewFrameArray(int number_of_frames) { DCHECK_LE(0, number_of_frames); - Handle<FixedArray> result = NewFixedArrayWithHoles( - FrameArray::LengthFor(number_of_frames), allocation); + Handle<FixedArray> result = + NewFixedArrayWithHoles(FrameArray::LengthFor(number_of_frames)); result->set(FrameArray::kFrameCountIndex, Smi::kZero); return Handle<FrameArray>::cast(result); } @@ -1438,7 +1422,7 @@ Handle<Context> Factory::NewContext(RootIndex map_root_index, int size, Map map = Map::cast(isolate()->root(map_root_index)); HeapObject result = AllocateRawWithImmortalMap(size, allocation, map); Handle<Context> context(Context::cast(result), isolate()); - context->set_length(variadic_part_length); + context->initialize_length_and_extension_bit(variadic_part_length); DCHECK_EQ(context->SizeFromMap(map), size); if (size > Context::kTodoHeaderSize) { ObjectSlot start = context->RawField(Context::kTodoHeaderSize); @@ -1461,6 +1445,7 @@ Handle<NativeContext> Factory::NewNativeContext() { context->set_math_random_index(Smi::zero()); context->set_serialized_objects(*empty_fixed_array()); context->set_microtask_queue(nullptr); + context->set_osr_code_cache(*empty_weak_fixed_array()); return context; } @@ -1549,8 +1534,8 @@ Handle<Context> Factory::NewDebugEvaluateContext(Handle<Context> previous, Handle<ScopeInfo> scope_info, Handle<JSReceiver> extension, Handle<Context> wrapped, - Handle<StringSet> whitelist) { - STATIC_ASSERT(Context::WHITE_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1); + Handle<StringSet> blacklist) { + STATIC_ASSERT(Context::BLACK_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1); DCHECK(scope_info->IsDebugEvaluateScope()); Handle<HeapObject> ext = extension.is_null() ? Handle<HeapObject>::cast(the_hole_value()) @@ -1565,7 +1550,7 @@ Handle<Context> Factory::NewDebugEvaluateContext(Handle<Context> previous, c->set_native_context(previous->native_context()); c->set_extension(*ext); if (!wrapped.is_null()) c->set(Context::WRAPPED_CONTEXT_INDEX, *wrapped); - if (!whitelist.is_null()) c->set(Context::WHITE_LIST_INDEX, *whitelist); + if (!blacklist.is_null()) c->set(Context::BLACK_LIST_INDEX, *blacklist); return c; } @@ -1648,20 +1633,16 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() { return info; } -Handle<Script> Factory::NewScript(Handle<String> source, - AllocationType allocation) { - return NewScriptWithId(source, isolate()->heap()->NextScriptId(), allocation); +Handle<Script> Factory::NewScript(Handle<String> source) { + return NewScriptWithId(source, isolate()->heap()->NextScriptId()); } -Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id, - AllocationType allocation) { - DCHECK(allocation == AllocationType::kOld || - allocation == AllocationType::kReadOnly); +Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id) { // Create and initialize script object. Heap* heap = isolate()->heap(); ReadOnlyRoots roots(heap); Handle<Script> script = - Handle<Script>::cast(NewStruct(SCRIPT_TYPE, allocation)); + Handle<Script>::cast(NewStruct(SCRIPT_TYPE, AllocationType::kOld)); script->set_source(*source); script->set_name(roots.undefined_value()); script->set_id(script_id); @@ -1748,20 +1729,19 @@ Handle<PromiseResolveThenableJobTask> Factory::NewPromiseResolveThenableJobTask( return microtask; } -Handle<Foreign> Factory::NewForeign(Address addr, AllocationType allocation) { +Handle<Foreign> Factory::NewForeign(Address addr) { // Statically ensure that it is safe to allocate foreigns in paged spaces. STATIC_ASSERT(Foreign::kSize <= kMaxRegularHeapObjectSize); Map map = *foreign_map(); - HeapObject result = - AllocateRawWithImmortalMap(map.instance_size(), allocation, map); + HeapObject result = AllocateRawWithImmortalMap(map.instance_size(), + AllocationType::kYoung, map); Handle<Foreign> foreign(Foreign::cast(result), isolate()); foreign->set_foreign_address(addr); return foreign; } Handle<ByteArray> Factory::NewByteArray(int length, AllocationType allocation) { - DCHECK_LE(0, length); - if (length > ByteArray::kMaxLength) { + if (length < 0 || length > ByteArray::kMaxLength) { isolate()->heap()->FatalProcessOutOfMemory("invalid array length"); } int size = ByteArray::SizeFor(length); @@ -1776,8 +1756,7 @@ Handle<ByteArray> Factory::NewByteArray(int length, AllocationType allocation) { Handle<BytecodeArray> Factory::NewBytecodeArray( int length, const byte* raw_bytecodes, int frame_size, int parameter_count, Handle<FixedArray> constant_pool) { - DCHECK_LE(0, length); - if (length > BytecodeArray::kMaxLength) { + if (length < 0 || length > BytecodeArray::kMaxLength) { isolate()->heap()->FatalProcessOutOfMemory("invalid array length"); } // Bytecode array is AllocationType::kOld, so constant pool array should be @@ -1806,7 +1785,6 @@ Handle<BytecodeArray> Factory::NewBytecodeArray( } Handle<Cell> Factory::NewCell(Handle<Object> value) { - AllowDeferredHandleDereference convert_to_cell; STATIC_ASSERT(Cell::kSize <= kMaxRegularHeapObjectSize); HeapObject result = AllocateRawWithImmortalMap( Cell::kSize, AllocationType::kOld, *cell_map()); @@ -1816,7 +1794,6 @@ Handle<Cell> Factory::NewCell(Handle<Object> value) { } Handle<FeedbackCell> Factory::NewNoClosuresCell(Handle<HeapObject> value) { - AllowDeferredHandleDereference convert_to_cell; HeapObject result = AllocateRawWithImmortalMap(FeedbackCell::kAlignedSize, AllocationType::kOld, *no_closures_cell_map()); Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate()); @@ -1827,7 +1804,6 @@ Handle<FeedbackCell> Factory::NewNoClosuresCell(Handle<HeapObject> value) { } Handle<FeedbackCell> Factory::NewOneClosureCell(Handle<HeapObject> value) { - AllowDeferredHandleDereference convert_to_cell; HeapObject result = AllocateRawWithImmortalMap(FeedbackCell::kAlignedSize, AllocationType::kOld, *one_closure_cell_map()); Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate()); @@ -1838,7 +1814,6 @@ Handle<FeedbackCell> Factory::NewOneClosureCell(Handle<HeapObject> value) { } Handle<FeedbackCell> Factory::NewManyClosuresCell(Handle<HeapObject> value) { - AllowDeferredHandleDereference convert_to_cell; HeapObject result = AllocateRawWithImmortalMap(FeedbackCell::kAlignedSize, AllocationType::kOld, *many_closures_cell_map()); Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate()); @@ -1864,15 +1839,13 @@ Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name, } Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors, - int slack, - AllocationType allocation) { - DCHECK(Heap::IsRegularObjectAllocation(allocation)); + int slack) { int number_of_all_descriptors = number_of_descriptors + slack; // Zero-length case must be handled outside. DCHECK_LT(0, number_of_all_descriptors); int size = DescriptorArray::SizeFor(number_of_all_descriptors); - HeapObject obj = - isolate()->heap()->AllocateRawWithRetryOrFail(size, allocation); + HeapObject obj = isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>( + size, AllocationType::kYoung); obj.set_map_after_allocation(*descriptor_array_map(), SKIP_WRITE_BARRIER); DescriptorArray array = DescriptorArray::cast(obj); array.Initialize(*empty_enum_cache(), *undefined_value(), @@ -1923,7 +1896,7 @@ Handle<Map> Factory::NewMap(InstanceType type, int instance_size, !Map::CanHaveFastTransitionableElementsKind(type), IsDictionaryElementsKind(elements_kind) || IsTerminalElementsKind(elements_kind)); - HeapObject result = isolate()->heap()->AllocateRawWithRetryOrFail( + HeapObject result = isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>( Map::kSize, AllocationType::kMap); result.set_map_after_allocation(*meta_map(), SKIP_WRITE_BARRIER); return handle(InitializeMap(Map::cast(result), type, instance_size, @@ -1985,23 +1958,23 @@ Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( // We can only clone regexps, normal objects, api objects, errors or arrays. // Copying anything else will break invariants. - CHECK(map->instance_type() == JS_REGEXP_TYPE || + CHECK(map->instance_type() == JS_REG_EXP_TYPE || map->instance_type() == JS_OBJECT_TYPE || map->instance_type() == JS_ERROR_TYPE || map->instance_type() == JS_ARRAY_TYPE || map->instance_type() == JS_API_OBJECT_TYPE || - map->instance_type() == WASM_GLOBAL_TYPE || - map->instance_type() == WASM_INSTANCE_TYPE || - map->instance_type() == WASM_MEMORY_TYPE || - map->instance_type() == WASM_MODULE_TYPE || - map->instance_type() == WASM_TABLE_TYPE || + map->instance_type() == WASM_GLOBAL_OBJECT_TYPE || + map->instance_type() == WASM_INSTANCE_OBJECT_TYPE || + map->instance_type() == WASM_MEMORY_OBJECT_TYPE || + map->instance_type() == WASM_MODULE_OBJECT_TYPE || + map->instance_type() == WASM_TABLE_OBJECT_TYPE || map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE); DCHECK(site.is_null() || AllocationSite::CanTrack(map->instance_type())); int object_size = map->instance_size(); int adjusted_object_size = site.is_null() ? object_size : object_size + AllocationMemento::kSize; - HeapObject raw_clone = isolate()->heap()->AllocateRawWithRetryOrFail( + HeapObject raw_clone = isolate()->heap()->AllocateRawWith<Heap::kRetryOrFail>( adjusted_object_size, AllocationType::kYoung); DCHECK(Heap::InYoungGeneration(raw_clone) || FLAG_single_generation); @@ -2062,6 +2035,13 @@ void initialize_length<PropertyArray>(Handle<PropertyArray> array, int length) { array->initialize_length(length); } +inline void ZeroEmbedderFields(i::Handle<i::JSObject> obj) { + auto count = obj->GetEmbedderFieldCount(); + for (int i = 0; i < count; i++) { + obj->SetEmbedderField(i, Smi::kZero); + } +} + } // namespace template <typename T> @@ -2107,15 +2087,14 @@ Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, } Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array, - int grow_by, - AllocationType allocation) { - return CopyArrayAndGrow(array, grow_by, allocation); + int grow_by) { + return CopyArrayAndGrow(array, grow_by, AllocationType::kYoung); } Handle<WeakFixedArray> Factory::CopyWeakFixedArrayAndGrow( - Handle<WeakFixedArray> src, int grow_by, AllocationType allocation) { + Handle<WeakFixedArray> src, int grow_by) { DCHECK(!src->IsTransitionArray()); // Compacted by GC, this code doesn't work - return CopyArrayAndGrow(src, grow_by, allocation); + return CopyArrayAndGrow(src, grow_by, AllocationType::kOld); } Handle<WeakArrayList> Factory::CopyWeakArrayListAndGrow( @@ -2142,8 +2121,8 @@ Handle<WeakArrayList> Factory::CopyWeakArrayListAndGrow( } Handle<PropertyArray> Factory::CopyPropertyArrayAndGrow( - Handle<PropertyArray> array, int grow_by, AllocationType allocation) { - return CopyArrayAndGrow(array, grow_by, allocation); + Handle<PropertyArray> array, int grow_by) { + return CopyArrayAndGrow(array, grow_by, AllocationType::kYoung); } Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array, @@ -2187,8 +2166,8 @@ Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray( Handle<FixedDoubleArray> array) { int len = array->length(); if (len == 0) return array; - Handle<FixedDoubleArray> result = Handle<FixedDoubleArray>::cast( - NewFixedDoubleArray(len, AllocationType::kYoung)); + Handle<FixedDoubleArray> result = + Handle<FixedDoubleArray>::cast(NewFixedDoubleArray(len)); Heap::CopyBlock( result->address() + FixedDoubleArray::kLengthOffset, array->address() + FixedDoubleArray::kLengthOffset, @@ -2196,32 +2175,39 @@ Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray( return result; } -Handle<Object> Factory::NewNumber(double value, AllocationType allocation) { +template <AllocationType allocation> +Handle<Object> Factory::NewNumber(double value) { // Materialize as a SMI if possible. int32_t int_value; if (DoubleToSmiInteger(value, &int_value)) { return handle(Smi::FromInt(int_value), isolate()); } - return NewHeapNumber(value, allocation); + return NewHeapNumber<allocation>(value); } -Handle<Object> Factory::NewNumberFromInt(int32_t value, - AllocationType allocation) { +template Handle<Object> V8_EXPORT_PRIVATE +Factory::NewNumber<AllocationType::kYoung>(double); +template Handle<Object> V8_EXPORT_PRIVATE +Factory::NewNumber<AllocationType::kOld>(double); +template Handle<Object> V8_EXPORT_PRIVATE +Factory::NewNumber<AllocationType::kReadOnly>(double); + +Handle<Object> Factory::NewNumberFromInt(int32_t value) { if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate()); // Bypass NewNumber to avoid various redundant checks. - return NewHeapNumber(FastI2D(value), allocation); + return NewHeapNumber(FastI2D(value)); } -Handle<Object> Factory::NewNumberFromUint(uint32_t value, - AllocationType allocation) { +Handle<Object> Factory::NewNumberFromUint(uint32_t value) { int32_t int32v = static_cast<int32_t>(value); if (int32v >= 0 && Smi::IsValid(int32v)) { return handle(Smi::FromInt(int32v), isolate()); } - return NewHeapNumber(FastUI2D(value), allocation); + return NewHeapNumber(FastUI2D(value)); } -Handle<HeapNumber> Factory::NewHeapNumber(AllocationType allocation) { +template <AllocationType allocation> +Handle<HeapNumber> Factory::NewHeapNumber() { STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize); Map map = *heap_number_map(); HeapObject result = AllocateRawWithImmortalMap(HeapNumber::kSize, allocation, @@ -2229,10 +2215,17 @@ Handle<HeapNumber> Factory::NewHeapNumber(AllocationType allocation) { return handle(HeapNumber::cast(result), isolate()); } +template Handle<HeapNumber> V8_EXPORT_PRIVATE +Factory::NewHeapNumber<AllocationType::kYoung>(); +template Handle<HeapNumber> V8_EXPORT_PRIVATE +Factory::NewHeapNumber<AllocationType::kOld>(); +template Handle<HeapNumber> V8_EXPORT_PRIVATE +Factory::NewHeapNumber<AllocationType::kReadOnly>(); + Handle<HeapNumber> Factory::NewHeapNumberForCodeAssembler(double value) { - return NewHeapNumber(value, isolate()->heap()->CanAllocateInReadOnlySpace() - ? AllocationType::kReadOnly - : AllocationType::kOld); + return isolate()->heap()->CanAllocateInReadOnlySpace() + ? NewHeapNumber<AllocationType::kReadOnly>(value) + : NewHeapNumber<AllocationType::kOld>(value); } Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length, @@ -2299,8 +2292,8 @@ Handle<Object> Factory::NewInvalidStringLengthError() { FATAL("Aborting on invalid string length"); } // Invalidate the "string length" protector. - if (isolate()->IsStringLengthOverflowIntact()) { - isolate()->InvalidateStringLengthOverflowProtector(); + if (Protectors::IsStringLengthOverflowLookupChainIntact(isolate())) { + Protectors::InvalidateStringLengthOverflowLookupChain(isolate()); } return NewRangeError(MessageTemplate::kInvalidStringLength); } @@ -2412,7 +2405,7 @@ Handle<JSFunction> Factory::NewFunction(const NewFunctionArgs& args) { case JS_ARRAY_TYPE: elements_kind = PACKED_SMI_ELEMENTS; break; - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: elements_kind = PACKED_ELEMENTS; break; default: @@ -2679,8 +2672,8 @@ Handle<Code> Factory::CopyCode(Handle<Code> code) { { int obj_size = code->Size(); CodePageCollectionMemoryModificationScope code_allocation(heap); - HeapObject result = - heap->AllocateRawWithRetryOrFail(obj_size, AllocationType::kCode); + HeapObject result = heap->AllocateRawWith<Heap::kRetryOrFail>( + obj_size, AllocationType::kCode); // Copy code object. Address old_addr = code->address(); @@ -2696,7 +2689,9 @@ Handle<Code> Factory::CopyCode(Handle<Code> code) { // allocation is on. heap->incremental_marking()->ProcessBlackAllocatedObject(*new_code); // Record all references to embedded objects in the new code object. +#ifndef V8_DISABLE_WRITE_BARRIERS WriteBarrierForCode(*new_code); +#endif } #ifdef VERIFY_HEAP @@ -2737,9 +2732,8 @@ Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, return NewJSObjectFromMap(map, allocation); } -Handle<JSObject> Factory::NewJSObjectWithNullProto(AllocationType allocation) { - Handle<JSObject> result = - NewJSObject(isolate()->object_function(), allocation); +Handle<JSObject> Factory::NewJSObjectWithNullProto() { + Handle<JSObject> result = NewJSObject(isolate()->object_function()); Handle<Map> new_map = Map::Copy( isolate(), Handle<Map>(result->map(), isolate()), "ObjectWithNullProto"); Map::SetPrototype(isolate(), new_map, null_value()); @@ -2776,7 +2770,7 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject( // The global object might be created from an object template with accessors. // Fill these accessors into the dictionary. Handle<DescriptorArray> descs(map->instance_descriptors(), isolate()); - for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : InternalIndex::Range(map->NumberOfOwnDescriptors())) { PropertyDetails details = descs->GetDetails(i); // Only accessors are expected. DCHECK_EQ(kAccessor, details.kind()); @@ -2888,13 +2882,14 @@ Handle<JSObject> Factory::NewSlowJSObjectFromMap( Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements( Handle<HeapObject> prototype, Handle<NameDictionary> properties, - Handle<FixedArrayBase> elements, AllocationType allocation) { + Handle<FixedArrayBase> elements) { Handle<Map> object_map = isolate()->slow_object_with_object_prototype_map(); if (object_map->prototype() != *prototype) { object_map = Map::TransitionToPrototype(isolate(), object_map, prototype); } DCHECK(object_map->is_dictionary_map()); - Handle<JSObject> object = NewJSObjectFromMap(object_map, allocation); + Handle<JSObject> object = + NewJSObjectFromMap(object_map, AllocationType::kYoung); object->set_raw_properties_or_hash(*properties); if (*elements != ReadOnlyRoots(isolate()).empty_fixed_array()) { DCHECK(elements->IsNumberDictionary()); @@ -3010,7 +3005,7 @@ Handle<JSModuleNamespace> Factory::NewJSModuleNamespace() { Handle<JSModuleNamespace> module_namespace( Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map))); FieldIndex index = FieldIndex::ForDescriptor( - *map, JSModuleNamespace::kToStringTagFieldIndex); + *map, InternalIndex(JSModuleNamespace::kToStringTagFieldIndex)); module_namespace->FastPropertyAtPut(index, ReadOnlyRoots(isolate()).Module_string()); return module_namespace; @@ -3042,6 +3037,7 @@ Handle<SourceTextModule> Factory::NewSourceTextModule( Handle<FixedArray> requested_modules = requested_modules_length > 0 ? NewFixedArray(requested_modules_length) : empty_fixed_array(); + Handle<ArrayList> async_parent_modules = ArrayList::New(isolate(), 0); ReadOnlyRoots roots(isolate()); Handle<SourceTextModule> module( @@ -3061,6 +3057,12 @@ Handle<SourceTextModule> Factory::NewSourceTextModule( module->set_import_meta(roots.the_hole_value()); module->set_dfs_index(-1); module->set_dfs_ancestor_index(-1); + module->set_top_level_capability(roots.undefined_value()); + module->set_flags(0); + module->set_async(IsAsyncModule(code->kind())); + module->set_async_evaluating(false); + module->set_async_parent_modules(*async_parent_modules); + module->set_pending_async_dependencies(0); return module; } @@ -3086,15 +3088,43 @@ Handle<SyntheticModule> Factory::NewSyntheticModule( return module; } -Handle<JSArrayBuffer> Factory::NewJSArrayBuffer(SharedFlag shared, - AllocationType allocation) { - Handle<JSFunction> array_buffer_fun( - shared == SharedFlag::kShared - ? isolate()->native_context()->shared_array_buffer_fun() - : isolate()->native_context()->array_buffer_fun(), +Handle<JSArrayBuffer> Factory::NewJSArrayBuffer( + std::shared_ptr<BackingStore> backing_store, AllocationType allocation) { + Handle<Map> map(isolate()->native_context()->array_buffer_fun().initial_map(), + isolate()); + auto result = + Handle<JSArrayBuffer>::cast(NewJSObjectFromMap(map, allocation)); + result->Setup(SharedFlag::kNotShared, std::move(backing_store)); + return result; +} + +MaybeHandle<JSArrayBuffer> Factory::NewJSArrayBufferAndBackingStore( + size_t byte_length, InitializedFlag initialized, + AllocationType allocation) { + std::unique_ptr<BackingStore> backing_store = nullptr; + + if (byte_length > 0) { + backing_store = BackingStore::Allocate(isolate(), byte_length, + SharedFlag::kNotShared, initialized); + if (!backing_store) return MaybeHandle<JSArrayBuffer>(); + } + Handle<Map> map(isolate()->native_context()->array_buffer_fun().initial_map(), + isolate()); + auto array_buffer = + Handle<JSArrayBuffer>::cast(NewJSObjectFromMap(map, allocation)); + array_buffer->Setup(SharedFlag::kNotShared, std::move(backing_store)); + return array_buffer; +} + +Handle<JSArrayBuffer> Factory::NewJSSharedArrayBuffer( + std::shared_ptr<BackingStore> backing_store) { + Handle<Map> map( + isolate()->native_context()->shared_array_buffer_fun().initial_map(), isolate()); - Handle<Map> map(array_buffer_fun->initial_map(), isolate()); - return Handle<JSArrayBuffer>::cast(NewJSObjectFromMap(map, allocation)); + auto result = Handle<JSArrayBuffer>::cast( + NewJSObjectFromMap(map, AllocationType::kYoung)); + result->Setup(SharedFlag::kShared, std::move(backing_store)); + return result; } Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value, @@ -3172,20 +3202,17 @@ void ForFixedTypedArray(ExternalArrayType array_type, size_t* element_size, Handle<JSArrayBufferView> Factory::NewJSArrayBufferView( Handle<Map> map, Handle<FixedArrayBase> elements, - Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length, - AllocationType allocation) { + Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length) { CHECK_LE(byte_length, buffer->byte_length()); CHECK_LE(byte_offset, buffer->byte_length()); CHECK_LE(byte_offset + byte_length, buffer->byte_length()); - Handle<JSArrayBufferView> array_buffer_view = - Handle<JSArrayBufferView>::cast(NewJSObjectFromMap(map, allocation)); + Handle<JSArrayBufferView> array_buffer_view = Handle<JSArrayBufferView>::cast( + NewJSObjectFromMap(map, AllocationType::kYoung)); array_buffer_view->set_elements(*elements); array_buffer_view->set_buffer(*buffer); array_buffer_view->set_byte_offset(byte_offset); array_buffer_view->set_byte_length(byte_length); - for (int i = 0; i < v8::ArrayBufferView::kEmbedderFieldCount; i++) { - array_buffer_view->SetEmbedderField(i, Smi::kZero); - } + ZeroEmbedderFields(array_buffer_view); DCHECK_EQ(array_buffer_view->GetEmbedderFieldCount(), v8::ArrayBufferView::kEmbedderFieldCount); return array_buffer_view; @@ -3193,8 +3220,8 @@ Handle<JSArrayBufferView> Factory::NewJSArrayBufferView( Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type, Handle<JSArrayBuffer> buffer, - size_t byte_offset, size_t length, - AllocationType allocation) { + size_t byte_offset, + size_t length) { size_t element_size; ElementsKind elements_kind; ForFixedTypedArray(type, &element_size, &elements_kind); @@ -3219,24 +3246,21 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type, default: UNREACHABLE(); } - Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast( - NewJSArrayBufferView(map, empty_byte_array(), buffer, byte_offset, - byte_length, allocation)); + Handle<JSTypedArray> typed_array = + Handle<JSTypedArray>::cast(NewJSArrayBufferView( + map, empty_byte_array(), buffer, byte_offset, byte_length)); typed_array->set_length(length); - typed_array->set_external_pointer( - reinterpret_cast<byte*>(buffer->backing_store()) + byte_offset); - typed_array->set_base_pointer(Smi::kZero); + typed_array->SetOffHeapDataPtr(buffer->backing_store(), byte_offset); return typed_array; } Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer, size_t byte_offset, - size_t byte_length, - AllocationType allocation) { + size_t byte_length) { Handle<Map> map(isolate()->native_context()->data_view_fun().initial_map(), isolate()); Handle<JSDataView> obj = Handle<JSDataView>::cast(NewJSArrayBufferView( - map, empty_fixed_array(), buffer, byte_offset, byte_length, allocation)); + map, empty_fixed_array(), buffer, byte_offset, byte_length)); obj->set_data_pointer(static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); return obj; @@ -3499,11 +3523,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( share->clear_padding(); } - // Link into the list. - Handle<WeakArrayList> noscript_list = noscript_shared_function_infos(); - noscript_list = WeakArrayList::AddToEnd(isolate(), noscript_list, - MaybeObjectHandle::Weak(share)); - isolate()->heap()->set_noscript_shared_function_infos(*noscript_list); #ifdef VERIFY_HEAP share->SharedFunctionInfoVerify(isolate()); @@ -3894,6 +3913,9 @@ void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, JSRegExp::Flags flags, int capture_count) { Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); Smi uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); + Smi ticks_until_tier_up = FLAG_regexp_tier_up + ? Smi::FromInt(FLAG_regexp_tier_up_ticks) + : uninitialized; store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); store->set(JSRegExp::kSourceIndex, *source); store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags)); @@ -3904,7 +3926,7 @@ void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::kZero); store->set(JSRegExp::kIrregexpCaptureCountIndex, Smi::FromInt(capture_count)); store->set(JSRegExp::kIrregexpCaptureNameMapIndex, uninitialized); - store->set(JSRegExp::kIrregexpTierUpTicksIndex, Smi::kZero); + store->set(JSRegExp::kIrregexpTicksUntilTierUpIndex, ticks_until_tier_up); regexp->set_data(*store); } @@ -4141,19 +4163,18 @@ Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) { return map; } -Handle<JSPromise> Factory::NewJSPromiseWithoutHook(AllocationType allocation) { - Handle<JSPromise> promise = Handle<JSPromise>::cast( - NewJSObject(isolate()->promise_function(), allocation)); +Handle<JSPromise> Factory::NewJSPromiseWithoutHook() { + Handle<JSPromise> promise = + Handle<JSPromise>::cast(NewJSObject(isolate()->promise_function())); promise->set_reactions_or_result(Smi::kZero); promise->set_flags(0); - for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) { - promise->SetEmbedderField(i, Smi::kZero); - } + ZeroEmbedderFields(promise); + DCHECK_EQ(promise->GetEmbedderFieldCount(), v8::Promise::kEmbedderFieldCount); return promise; } -Handle<JSPromise> Factory::NewJSPromise(AllocationType allocation) { - Handle<JSPromise> promise = NewJSPromiseWithoutHook(allocation); +Handle<JSPromise> Factory::NewJSPromise() { + Handle<JSPromise> promise = NewJSPromiseWithoutHook(); isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value()); return promise; } diff --git a/deps/v8/src/heap/factory.h b/deps/v8/src/heap/factory.h index 1e47926e8e4166..35de6425c9af31 100644 --- a/deps/v8/src/heap/factory.h +++ b/deps/v8/src/heap/factory.h @@ -74,7 +74,8 @@ class WeakCell; struct SourceRange; template <typename T> class ZoneVector; -enum class SharedFlag : uint32_t; +enum class SharedFlag : uint8_t; +enum class InitializedFlag : uint8_t; enum FunctionMode { kWithNameBit = 1 << 0, @@ -107,14 +108,12 @@ enum FunctionMode { // Interface for handle based allocation. class V8_EXPORT_PRIVATE Factory { public: - Handle<Oddball> NewOddball( - Handle<Map> map, const char* to_string, Handle<Object> to_number, - const char* type_of, byte kind, - AllocationType allocation = AllocationType::kReadOnly); + Handle<Oddball> NewOddball(Handle<Map> map, const char* to_string, + Handle<Object> to_number, const char* type_of, + byte kind); // Marks self references within code generation. - Handle<Oddball> NewSelfReferenceMarker( - AllocationType allocation = AllocationType::kOld); + Handle<Oddball> NewSelfReferenceMarker(); // Allocates a fixed array-like object with given map and initialized with // undefined values. @@ -140,8 +139,7 @@ class V8_EXPORT_PRIVATE Factory { int length, AllocationType allocation = AllocationType::kYoung); // Allocates a property array initialized with undefined values. - Handle<PropertyArray> NewPropertyArray( - int length, AllocationType allocation = AllocationType::kYoung); + Handle<PropertyArray> NewPropertyArray(int length); // Tries allocating a fixed array initialized with undefined values. // In case of an allocation failure (OOM) an empty handle is returned. // The caller has to manually signal an @@ -156,24 +154,20 @@ class V8_EXPORT_PRIVATE Factory { int length, AllocationType allocation = AllocationType::kYoung); // Allocates an uninitialized fixed array. It must be filled by the caller. - Handle<FixedArray> NewUninitializedFixedArray( - int length, AllocationType allocation = AllocationType::kYoung); + Handle<FixedArray> NewUninitializedFixedArray(int length); // Allocates a closure feedback cell array whose feedback cells are // initialized with undefined values. - Handle<ClosureFeedbackCellArray> NewClosureFeedbackCellArray( - int num_slots, AllocationType allocation = AllocationType::kYoung); + Handle<ClosureFeedbackCellArray> NewClosureFeedbackCellArray(int num_slots); // Allocates a feedback vector whose slots are initialized with undefined // values. Handle<FeedbackVector> NewFeedbackVector( Handle<SharedFunctionInfo> shared, - Handle<ClosureFeedbackCellArray> closure_feedback_cell_array, - AllocationType allocation = AllocationType::kYoung); + Handle<ClosureFeedbackCellArray> closure_feedback_cell_array); // Allocates a clean embedder data array with given capacity. - Handle<EmbedderDataArray> NewEmbedderDataArray( - int length, AllocationType allocation = AllocationType::kYoung); + Handle<EmbedderDataArray> NewEmbedderDataArray(int length); // Allocates a fixed array for name-value pairs of boilerplate properties and // calculates the number of properties we need to store in the backing store. @@ -183,20 +177,17 @@ class V8_EXPORT_PRIVATE Factory { // Allocate a new uninitialized fixed double array. // The function returns a pre-allocated empty fixed array for length = 0, // so the return type must be the general fixed array class. - Handle<FixedArrayBase> NewFixedDoubleArray( - int length, AllocationType allocation = AllocationType::kYoung); + Handle<FixedArrayBase> NewFixedDoubleArray(int length); // Allocate a new fixed double array with hole values. - Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles( - int size, AllocationType allocation = AllocationType::kYoung); + Handle<FixedArrayBase> NewFixedDoubleArrayWithHoles(int size); // Allocates a FeedbackMedata object and zeroes the data section. Handle<FeedbackMetadata> NewFeedbackMetadata( int slot_count, int feedback_cell_count, AllocationType allocation = AllocationType::kOld); - Handle<FrameArray> NewFrameArray( - int number_of_frames, AllocationType allocation = AllocationType::kYoung); + Handle<FrameArray> NewFrameArray(int number_of_frames); Handle<OrderedHashSet> NewOrderedHashSet(); Handle<OrderedHashMap> NewOrderedHashMap(); @@ -223,10 +214,6 @@ class V8_EXPORT_PRIVATE Factory { Handle<Tuple2> NewTuple2(Handle<Object> value1, Handle<Object> value2, AllocationType allocation); - // Create a new Tuple3 struct. - Handle<Tuple3> NewTuple3(Handle<Object> value1, Handle<Object> value2, - Handle<Object> value3, AllocationType allocation); - // Create a new ArrayBoilerplateDescription struct. Handle<ArrayBoilerplateDescription> NewArrayBoilerplateDescription( ElementsKind elements_kind, Handle<FixedArrayBase> constant_values); @@ -451,11 +438,8 @@ class V8_EXPORT_PRIVATE Factory { Handle<AccessorInfo> NewAccessorInfo(); - Handle<Script> NewScript(Handle<String> source, - AllocationType allocation = AllocationType::kOld); - Handle<Script> NewScriptWithId( - Handle<String> source, int script_id, - AllocationType allocation = AllocationType::kOld); + Handle<Script> NewScript(Handle<String> source); + Handle<Script> NewScriptWithId(Handle<String> source, int script_id); Handle<Script> CloneScript(Handle<Script> script); Handle<BreakPointInfo> NewBreakPointInfo(int source_position); @@ -479,8 +463,7 @@ class V8_EXPORT_PRIVATE Factory { Handle<JSReceiver> thenable, Handle<Context> context); // Foreign objects are pretenured when allocated by the bootstrapper. - Handle<Foreign> NewForeign( - Address addr, AllocationType allocation = AllocationType::kYoung); + Handle<Foreign> NewForeign(Address addr); Handle<ByteArray> NewByteArray( int length, AllocationType allocation = AllocationType::kYoung); @@ -498,9 +481,8 @@ class V8_EXPORT_PRIVATE Factory { Handle<FeedbackCell> NewOneClosureCell(Handle<HeapObject> value); Handle<FeedbackCell> NewManyClosuresCell(Handle<HeapObject> value); - Handle<DescriptorArray> NewDescriptorArray( - int number_of_entries, int slack = 0, - AllocationType allocation = AllocationType::kYoung); + Handle<DescriptorArray> NewDescriptorArray(int number_of_entries, + int slack = 0); Handle<TransitionArray> NewTransitionArray(int number_of_transitions, int slack = 0); @@ -537,21 +519,18 @@ class V8_EXPORT_PRIVATE Factory { Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array, Handle<Map> map); - Handle<FixedArray> CopyFixedArrayAndGrow( - Handle<FixedArray> array, int grow_by, - AllocationType allocation = AllocationType::kYoung); + Handle<FixedArray> CopyFixedArrayAndGrow(Handle<FixedArray> array, + int grow_by); - Handle<WeakFixedArray> CopyWeakFixedArrayAndGrow( - Handle<WeakFixedArray> array, int grow_by, - AllocationType allocation = AllocationType::kYoung); + Handle<WeakFixedArray> CopyWeakFixedArrayAndGrow(Handle<WeakFixedArray> array, + int grow_by); Handle<WeakArrayList> CopyWeakArrayListAndGrow( Handle<WeakArrayList> array, int grow_by, AllocationType allocation = AllocationType::kYoung); - Handle<PropertyArray> CopyPropertyArrayAndGrow( - Handle<PropertyArray> array, int grow_by, - AllocationType allocation = AllocationType::kYoung); + Handle<PropertyArray> CopyPropertyArrayAndGrow(Handle<PropertyArray> array, + int grow_by); Handle<FixedArray> CopyFixedArrayUpTo( Handle<FixedArray> array, int new_len, @@ -567,32 +546,28 @@ class V8_EXPORT_PRIVATE Factory { // Numbers (e.g. literals) are pretenured by the parser. // The return value may be a smi or a heap number. - Handle<Object> NewNumber(double value, - AllocationType allocation = AllocationType::kYoung); - - Handle<Object> NewNumberFromInt( - int32_t value, AllocationType allocation = AllocationType::kYoung); - Handle<Object> NewNumberFromUint( - uint32_t value, AllocationType allocation = AllocationType::kYoung); - inline Handle<Object> NewNumberFromSize( - size_t value, AllocationType allocation = AllocationType::kYoung); - inline Handle<Object> NewNumberFromInt64( - int64_t value, AllocationType allocation = AllocationType::kYoung); - inline Handle<HeapNumber> NewHeapNumber( - double value, AllocationType allocation = AllocationType::kYoung); - inline Handle<HeapNumber> NewHeapNumberFromBits( - uint64_t bits, AllocationType allocation = AllocationType::kYoung); + template <AllocationType allocation = AllocationType::kYoung> + EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) + Handle<Object> NewNumber(double value); + Handle<Object> NewNumberFromInt(int32_t value); + Handle<Object> NewNumberFromUint(uint32_t value); + inline Handle<Object> NewNumberFromSize(size_t value); + inline Handle<Object> NewNumberFromInt64(int64_t value); + template <AllocationType allocation = AllocationType::kYoung> + inline Handle<HeapNumber> NewHeapNumber(double value); + template <AllocationType allocation = AllocationType::kYoung> + inline Handle<HeapNumber> NewHeapNumberFromBits(uint64_t bits); // Creates heap number object with not yet set value field. - Handle<HeapNumber> NewHeapNumber( - AllocationType allocation = AllocationType::kYoung); + template <AllocationType allocation = AllocationType::kYoung> + EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) + Handle<HeapNumber> NewHeapNumber(); // Creates a new HeapNumber in read-only space if possible otherwise old // space. Handle<HeapNumber> NewHeapNumberForCodeAssembler(double value); - inline Handle<HeapNumber> NewHeapNumberWithHoleNaN( - AllocationType allocation = AllocationType::kYoung); + inline Handle<HeapNumber> NewHeapNumberWithHoleNaN(); // Allocates a new BigInt with {length} digits. Only to be used by // MutableBigInt::New*. @@ -609,8 +584,7 @@ class V8_EXPORT_PRIVATE Factory { Handle<JSFunction> constructor, AllocationType allocation = AllocationType::kYoung); // JSObject without a prototype. - Handle<JSObject> NewJSObjectWithNullProto( - AllocationType allocation = AllocationType::kYoung); + Handle<JSObject> NewJSObjectWithNullProto(); // Global objects are pretenured and initialized based on a constructor. Handle<JSGlobalObject> NewJSGlobalObject(Handle<JSFunction> constructor); @@ -644,8 +618,7 @@ class V8_EXPORT_PRIVATE Factory { // object will have dictionary elements. Handle<JSObject> NewSlowJSObjectWithPropertiesAndElements( Handle<HeapObject> prototype, Handle<NameDictionary> properties, - Handle<FixedArrayBase> elements, - AllocationType allocation = AllocationType::kYoung); + Handle<FixedArrayBase> elements); // JS arrays are pretenured when allocated by the parser. @@ -692,20 +665,27 @@ class V8_EXPORT_PRIVATE Factory { v8::Module::SyntheticModuleEvaluationSteps evaluation_steps); Handle<JSArrayBuffer> NewJSArrayBuffer( - SharedFlag shared, AllocationType allocation = AllocationType::kYoung); + std::shared_ptr<BackingStore> backing_store, + AllocationType allocation = AllocationType::kYoung); + + MaybeHandle<JSArrayBuffer> NewJSArrayBufferAndBackingStore( + size_t byte_length, InitializedFlag initialized, + AllocationType allocation = AllocationType::kYoung); + + Handle<JSArrayBuffer> NewJSSharedArrayBuffer( + std::shared_ptr<BackingStore> backing_store); static void TypeAndSizeForElementsKind(ElementsKind kind, ExternalArrayType* array_type, size_t* element_size); // Creates a new JSTypedArray with the specified buffer. - Handle<JSTypedArray> NewJSTypedArray( - ExternalArrayType type, Handle<JSArrayBuffer> buffer, size_t byte_offset, - size_t length, AllocationType allocation = AllocationType::kYoung); + Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type, + Handle<JSArrayBuffer> buffer, + size_t byte_offset, size_t length); - Handle<JSDataView> NewJSDataView( - Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length, - AllocationType allocation = AllocationType::kYoung); + Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer, + size_t byte_offset, size_t byte_length); Handle<JSIteratorResult> NewJSIteratorResult(Handle<Object> value, bool done); Handle<JSAsyncFromSyncIterator> NewJSAsyncFromSyncIterator( @@ -922,10 +902,8 @@ class V8_EXPORT_PRIVATE Factory { // Converts the given ToPrimitive hint to it's string representation. Handle<String> ToPrimitiveHintString(ToPrimitiveHint hint); - Handle<JSPromise> NewJSPromiseWithoutHook( - AllocationType allocation = AllocationType::kYoung); - Handle<JSPromise> NewJSPromise( - AllocationType allocation = AllocationType::kYoung); + Handle<JSPromise> NewJSPromiseWithoutHook(); + Handle<JSPromise> NewJSPromise(); Handle<CallHandlerInfo> NewCallHandlerInfo(bool has_no_side_effect = false); @@ -1034,8 +1012,7 @@ class V8_EXPORT_PRIVATE Factory { Handle<JSArrayBufferView> NewJSArrayBufferView( Handle<Map> map, Handle<FixedArrayBase> elements, - Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length, - AllocationType allocation); + Handle<JSArrayBuffer> buffer, size_t byte_offset, size_t byte_length); // Allocate memory for an uninitialized array (e.g., a FixedArray or similar). HeapObject AllocateRawArray(int size, AllocationType allocation); diff --git a/deps/v8/src/heap/heap-inl.h b/deps/v8/src/heap/heap-inl.h index da803f33395364..56f3590b8aa8da 100644 --- a/deps/v8/src/heap/heap-inl.h +++ b/deps/v8/src/heap/heap-inl.h @@ -111,10 +111,6 @@ void Heap::SetRootStringTable(StringTable value) { roots_table()[RootIndex::kStringTable] = value.ptr(); } -void Heap::SetRootNoScriptSharedFunctionInfos(Object value) { - roots_table()[RootIndex::kNoScriptSharedFunctionInfos] = value.ptr(); -} - void Heap::SetMessageListeners(TemplateList value) { roots_table()[RootIndex::kMessageListeners] = value.ptr(); } @@ -163,7 +159,7 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type, AllocationAlignment alignment) { DCHECK(AllowHandleAllocation::IsAllowed()); DCHECK(AllowHeapAllocation::IsAllowed()); - DCHECK(gc_state_ == NOT_IN_GC); + DCHECK_EQ(gc_state_, NOT_IN_GC); #ifdef V8_ENABLE_ALLOCATION_TIMEOUT if (FLAG_random_gc_interval > 0 || FLAG_gc_interval >= 0) { if (!always_allocate() && Heap::allocation_timeout_-- <= 0) { @@ -180,8 +176,9 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type, HeapObject object; AllocationResult allocation; - if (FLAG_single_generation && type == AllocationType::kYoung) + if (FLAG_single_generation && type == AllocationType::kYoung) { type = AllocationType::kOld; + } if (AllocationType::kYoung == type) { if (large_object) { @@ -212,9 +209,7 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type, } else if (AllocationType::kMap == type) { allocation = map_space_->AllocateRawUnaligned(size_in_bytes); } else if (AllocationType::kReadOnly == type) { -#ifdef V8_USE_SNAPSHOT DCHECK(isolate_->serializer_enabled()); -#endif DCHECK(!large_object); DCHECK(CanAllocateInReadOnlySpace()); DCHECK_EQ(AllocationOrigin::kRuntime, origin); @@ -242,6 +237,40 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type, return allocation; } +template <Heap::AllocationRetryMode mode> +HeapObject Heap::AllocateRawWith(int size, AllocationType allocation, + AllocationOrigin origin, + AllocationAlignment alignment) { + DCHECK(AllowHandleAllocation::IsAllowed()); + DCHECK(AllowHeapAllocation::IsAllowed()); + DCHECK_EQ(gc_state_, NOT_IN_GC); + Heap* heap = isolate()->heap(); + Address* top = heap->NewSpaceAllocationTopAddress(); + Address* limit = heap->NewSpaceAllocationLimitAddress(); + if (allocation == AllocationType::kYoung && + alignment == AllocationAlignment::kWordAligned && + size <= kMaxRegularHeapObjectSize && + (*limit - *top >= static_cast<unsigned>(size)) && + V8_LIKELY(!FLAG_single_generation && FLAG_inline_new && + FLAG_gc_interval == 0)) { + DCHECK(IsAligned(size, kTaggedSize)); + HeapObject obj = HeapObject::FromAddress(*top); + *top += size; + heap->CreateFillerObjectAt(obj.address(), size, ClearRecordedSlots::kNo); + MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj.address(), size); + return obj; + } + switch (mode) { + case kLightRetry: + return AllocateRawWithLightRetrySlowPath(size, allocation, origin, + alignment); + case kRetryOrFail: + return AllocateRawWithRetryOrFailSlowPath(size, allocation, origin, + alignment); + } + UNREACHABLE(); +} + void Heap::OnAllocationEvent(HeapObject object, int size_in_bytes) { for (auto& tracker : allocation_trackers_) { tracker->AllocationEvent(object.address(), size_in_bytes); diff --git a/deps/v8/src/heap/heap-write-barrier-inl.h b/deps/v8/src/heap/heap-write-barrier-inl.h index 5687284b1e8562..a0d9902006f553 100644 --- a/deps/v8/src/heap/heap-write-barrier-inl.h +++ b/deps/v8/src/heap/heap-write-barrier-inl.h @@ -212,6 +212,7 @@ inline void MarkingBarrierForDescriptorArray(Heap* heap, HeapObject host, inline WriteBarrierMode GetWriteBarrierModeForObject( HeapObject object, const DisallowHeapAllocation* promise) { + if (FLAG_disable_write_barriers) return SKIP_WRITE_BARRIER; DCHECK(Heap_PageFlagsAreConsistent(object)); heap_internals::MemoryChunk* chunk = heap_internals::MemoryChunk::FromHeapObject(object); @@ -221,6 +222,9 @@ inline WriteBarrierMode GetWriteBarrierModeForObject( } inline bool ObjectInYoungGeneration(Object object) { + // TODO(rong): Fix caller of this function when we deploy + // v8_use_third_party_heap. + if (FLAG_single_generation) return false; if (object.IsSmi()) return false; return heap_internals::MemoryChunk::FromHeapObject(HeapObject::cast(object)) ->InYoungGeneration(); diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index ff3b34cfb4f29b..45b2273c50d688 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -39,6 +39,7 @@ #include "src/heap/incremental-marking.h" #include "src/heap/mark-compact-inl.h" #include "src/heap/mark-compact.h" +#include "src/heap/memory-measurement.h" #include "src/heap/memory-reducer.h" #include "src/heap/object-stats.h" #include "src/heap/objects-visiting-inl.h" @@ -47,7 +48,6 @@ #include "src/heap/remembered-set.h" #include "src/heap/scavenge-job.h" #include "src/heap/scavenger-inl.h" -#include "src/heap/store-buffer.h" #include "src/heap/stress-marking-observer.h" #include "src/heap/stress-scavenge-observer.h" #include "src/heap/sweeper.h" @@ -913,23 +913,6 @@ void Heap::RemoveAllocationObserversFromAllSpaces( } } -class Heap::SkipStoreBufferScope { - public: - explicit SkipStoreBufferScope(StoreBuffer* store_buffer) - : store_buffer_(store_buffer) { - store_buffer_->MoveAllEntriesToRememberedSet(); - store_buffer_->SetMode(StoreBuffer::IN_GC); - } - - ~SkipStoreBufferScope() { - DCHECK(store_buffer_->Empty()); - store_buffer_->SetMode(StoreBuffer::NOT_IN_GC); - } - - private: - StoreBuffer* store_buffer_; -}; - namespace { inline bool MakePretenureDecision( AllocationSite site, AllocationSite::PretenureDecision current_decision, @@ -1965,44 +1948,40 @@ bool Heap::PerformGarbageCollection( size_t start_young_generation_size = Heap::new_space()->Size() + new_lo_space()->SizeOfObjects(); - { - Heap::SkipStoreBufferScope skip_store_buffer_scope(store_buffer_.get()); - - switch (collector) { - case MARK_COMPACTOR: - UpdateOldGenerationAllocationCounter(); - // Perform mark-sweep with optional compaction. - MarkCompact(); - old_generation_size_configured_ = true; - // This should be updated before PostGarbageCollectionProcessing, which - // can cause another GC. Take into account the objects promoted during - // GC. - old_generation_allocation_counter_at_last_gc_ += - static_cast<size_t>(promoted_objects_size_); - old_generation_size_at_last_gc_ = OldGenerationSizeOfObjects(); - break; - case MINOR_MARK_COMPACTOR: - MinorMarkCompact(); - break; - case SCAVENGER: - if ((fast_promotion_mode_ && - CanExpandOldGeneration(new_space()->Size() + - new_lo_space()->Size()))) { - tracer()->NotifyYoungGenerationHandling( - YoungGenerationHandling::kFastPromotionDuringScavenge); - EvacuateYoungGeneration(); - } else { - tracer()->NotifyYoungGenerationHandling( - YoungGenerationHandling::kRegularScavenge); - - Scavenge(); - } - break; - } + switch (collector) { + case MARK_COMPACTOR: + UpdateOldGenerationAllocationCounter(); + // Perform mark-sweep with optional compaction. + MarkCompact(); + old_generation_size_configured_ = true; + // This should be updated before PostGarbageCollectionProcessing, which + // can cause another GC. Take into account the objects promoted during + // GC. + old_generation_allocation_counter_at_last_gc_ += + static_cast<size_t>(promoted_objects_size_); + old_generation_size_at_last_gc_ = OldGenerationSizeOfObjects(); + break; + case MINOR_MARK_COMPACTOR: + MinorMarkCompact(); + break; + case SCAVENGER: + if ((fast_promotion_mode_ && + CanExpandOldGeneration(new_space()->Size() + + new_lo_space()->Size()))) { + tracer()->NotifyYoungGenerationHandling( + YoungGenerationHandling::kFastPromotionDuringScavenge); + EvacuateYoungGeneration(); + } else { + tracer()->NotifyYoungGenerationHandling( + YoungGenerationHandling::kRegularScavenge); - ProcessPretenuringFeedback(); + Scavenge(); + } + break; } + ProcessPretenuringFeedback(); + UpdateSurvivalStatistics(static_cast<int>(start_young_generation_size)); ConfigureInitialOldGenerationSize(); @@ -2780,12 +2759,34 @@ HeapObject Heap::AlignWithFiller(HeapObject object, int object_size, return object; } -void Heap::RegisterNewArrayBuffer(JSArrayBuffer buffer) { - ArrayBufferTracker::RegisterNew(this, buffer); +void* Heap::AllocateExternalBackingStore( + const std::function<void*(size_t)>& allocate, size_t byte_length) { + // TODO(ulan): Perform GCs proactively based on the byte_length and + // the current external backing store counters. + void* result = allocate(byte_length); + if (result) return result; + for (int i = 0; i < 2; i++) { + CollectGarbage(OLD_SPACE, GarbageCollectionReason::kExternalMemoryPressure); + result = allocate(byte_length); + if (result) return result; + } + isolate()->counters()->gc_last_resort_from_handles()->Increment(); + CollectAllAvailableGarbage(GarbageCollectionReason::kExternalMemoryPressure); + return allocate(byte_length); +} + +void Heap::RegisterBackingStore(JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store) { + ArrayBufferTracker::RegisterNew(this, buffer, std::move(backing_store)); } -void Heap::UnregisterArrayBuffer(JSArrayBuffer buffer) { - ArrayBufferTracker::Unregister(this, buffer); +std::shared_ptr<BackingStore> Heap::UnregisterBackingStore( + JSArrayBuffer buffer) { + return ArrayBufferTracker::Unregister(this, buffer); +} + +std::shared_ptr<BackingStore> Heap::LookupBackingStore(JSArrayBuffer buffer) { + return ArrayBufferTracker::Lookup(this, buffer); } void Heap::ConfigureInitialOldGenerationSize() { @@ -3387,16 +3388,23 @@ void Heap::RegisterDeserializedObjectsForBlackAllocation( } } -void Heap::NotifyObjectLayoutChange(HeapObject object, int size, - const DisallowHeapAllocation&) { +void Heap::NotifyObjectLayoutChange( + HeapObject object, const DisallowHeapAllocation&, + InvalidateRecordedSlots invalidate_recorded_slots) { if (incremental_marking()->IsMarking()) { incremental_marking()->MarkBlackAndVisitObjectDueToLayoutChange(object); if (incremental_marking()->IsCompacting() && + invalidate_recorded_slots == InvalidateRecordedSlots::kYes && MayContainRecordedSlots(object)) { MemoryChunk::FromHeapObject(object) - ->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(object, size); + ->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(object); } } + if (invalidate_recorded_slots == InvalidateRecordedSlots::kYes && + MayContainRecordedSlots(object)) { + MemoryChunk::FromHeapObject(object) + ->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(object); + } #ifdef VERIFY_HEAP if (FLAG_verify_heap) { DCHECK(pending_layout_change_object_.is_null()); @@ -3684,8 +3692,7 @@ void Heap::MemoryPressureNotification(MemoryPressureLevel level, isolate()->stack_guard()->RequestGC(); auto taskrunner = V8::GetCurrentPlatform()->GetForegroundTaskRunner( reinterpret_cast<v8::Isolate*>(isolate())); - taskrunner->PostTask( - base::make_unique<MemoryPressureInterruptTask>(this)); + taskrunner->PostTask(std::make_unique<MemoryPressureInterruptTask>(this)); } } } @@ -3748,6 +3755,11 @@ bool Heap::InvokeNearHeapLimitCallback() { return false; } +Handle<JSPromise> Heap::MeasureMemory(Handle<NativeContext> context, + v8::MeasureMemoryMode mode) { + return memory_measurement_->EnqueueRequest(context, mode); +} + void Heap::CollectCodeStatistics() { TRACE_EVENT0("v8", "Heap::CollectCodeStatistics"); CodeStatistics::ResetCodeAndMetadataStatistics(isolate()); @@ -4096,7 +4108,19 @@ void CollectSlots(MemoryChunk* chunk, Address start, Address end, } return KEEP_SLOT; }, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); + if (direction == OLD_TO_NEW) { + CHECK(chunk->SweepingDone()); + RememberedSetSweeping::Iterate( + chunk, + [start, end, untyped](MaybeObjectSlot slot) { + if (start <= slot.address() && slot.address() < end) { + untyped->insert(slot.address()); + } + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); + } RememberedSet<direction>::IterateTyped( chunk, [=](SlotType type, Address slot) { if (start <= slot && slot < end) { @@ -4117,7 +4141,6 @@ void Heap::VerifyRememberedSetFor(HeapObject object) { std::set<Address> old_to_new; std::set<std::pair<SlotType, Address> > typed_old_to_new; if (!InYoungGeneration(object)) { - store_buffer()->MoveAllEntriesToRememberedSet(); CollectSlots<OLD_TO_NEW>(chunk, start, end, &old_to_new, &typed_old_to_new); OldToNewSlotVerifyingVisitor visitor(&old_to_new, &typed_old_to_new, &this->ephemeron_remembered_set_); @@ -4288,6 +4311,7 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) { FixStaleLeftTrimmedHandlesVisitor left_trim_visitor(this); isolate_->handle_scope_implementer()->Iterate(&left_trim_visitor); isolate_->handle_scope_implementer()->Iterate(v); + isolate_->IterateDeferredHandles(&left_trim_visitor); isolate_->IterateDeferredHandles(v); v->Synchronize(VisitorSynchronization::kHandleScope); @@ -4879,9 +4903,9 @@ HeapObject Heap::EnsureImmovableCode(HeapObject heap_object, int object_size) { return heap_object; } -HeapObject Heap::AllocateRawWithLightRetry(int size, AllocationType allocation, - AllocationOrigin origin, - AllocationAlignment alignment) { +HeapObject Heap::AllocateRawWithLightRetrySlowPath( + int size, AllocationType allocation, AllocationOrigin origin, + AllocationAlignment alignment) { HeapObject result; AllocationResult alloc = AllocateRaw(size, allocation, origin, alignment); if (alloc.To(&result)) { @@ -4901,12 +4925,12 @@ HeapObject Heap::AllocateRawWithLightRetry(int size, AllocationType allocation, return HeapObject(); } -HeapObject Heap::AllocateRawWithRetryOrFail(int size, AllocationType allocation, - AllocationOrigin origin, - AllocationAlignment alignment) { +HeapObject Heap::AllocateRawWithRetryOrFailSlowPath( + int size, AllocationType allocation, AllocationOrigin origin, + AllocationAlignment alignment) { AllocationResult alloc; HeapObject result = - AllocateRawWithLightRetry(size, allocation, origin, alignment); + AllocateRawWithLightRetrySlowPath(size, allocation, origin, alignment); if (!result.is_null()) return result; isolate()->counters()->gc_last_resort_from_handles()->Increment(); @@ -4979,8 +5003,6 @@ void Heap::SetUp() { memory_allocator_.reset( new MemoryAllocator(isolate_, MaxReserved(), code_range_size_)); - store_buffer_.reset(new StoreBuffer(this)); - mark_compact_collector_.reset(new MarkCompactCollector(this)); scavenger_collector_.reset(new ScavengerCollector(this)); @@ -5039,6 +5061,7 @@ void Heap::SetUpSpaces() { #endif // ENABLE_MINOR_MC array_buffer_collector_.reset(new ArrayBufferCollector(this)); gc_idle_time_handler_.reset(new GCIdleTimeHandler()); + memory_measurement_.reset(new MemoryMeasurement(isolate())); memory_reducer_.reset(new MemoryReducer(this)); if (V8_UNLIKELY(TracingFlags::is_gc_stats_enabled())) { live_object_stats_.reset(new ObjectStats(this)); @@ -5049,8 +5072,6 @@ void Heap::SetUpSpaces() { LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); LOG(isolate_, IntPtrTEvent("heap-available", Available())); - store_buffer()->SetUp(); - mark_compact_collector()->SetUp(); #ifdef ENABLE_MINOR_MC if (minor_mark_compact_collector() != nullptr) { @@ -5282,8 +5303,6 @@ void Heap::TearDown() { space_[i] = nullptr; } - store_buffer()->TearDown(); - memory_allocator()->TearDown(); StrongRootsList* next = nullptr; @@ -5293,7 +5312,6 @@ void Heap::TearDown() { } strong_roots_list_ = nullptr; - store_buffer_.reset(); memory_allocator_.reset(); } @@ -5404,13 +5422,6 @@ void Heap::CompactWeakArrayLists(AllocationType allocation) { DCHECK_IMPLIES(allocation == AllocationType::kOld, InOldSpace(*scripts)); scripts = CompactWeakArrayList(this, scripts, allocation); set_script_list(*scripts); - - Handle<WeakArrayList> no_script_list(noscript_shared_function_infos(), - isolate()); - DCHECK_IMPLIES(allocation == AllocationType::kOld, - InOldSpace(*no_script_list)); - no_script_list = CompactWeakArrayList(this, no_script_list, allocation); - set_noscript_shared_function_infos(*no_script_list); } void Heap::AddRetainedMap(Handle<Map> map) { @@ -5511,53 +5522,55 @@ void Heap::CheckHandleCount() { isolate_->handle_scope_implementer()->Iterate(&v); } -Address* Heap::store_buffer_top_address() { - return store_buffer()->top_address(); -} - -// static -intptr_t Heap::store_buffer_mask_constant() { - return StoreBuffer::kStoreBufferMask; -} - -// static -Address Heap::store_buffer_overflow_function_address() { - return FUNCTION_ADDR(StoreBuffer::StoreBufferOverflow); -} - void Heap::ClearRecordedSlot(HeapObject object, ObjectSlot slot) { +#ifndef V8_DISABLE_WRITE_BARRIERS DCHECK(!IsLargeObject(object)); Page* page = Page::FromAddress(slot.address()); if (!page->InYoungGeneration()) { DCHECK_EQ(page->owner_identity(), OLD_SPACE); - store_buffer()->MoveAllEntriesToRememberedSet(); - RememberedSet<OLD_TO_NEW>::Remove(page, slot.address()); + + if (!page->SweepingDone()) { + RememberedSet<OLD_TO_NEW>::Remove(page, slot.address()); + } } +#endif +} + +// static +int Heap::InsertIntoRememberedSetFromCode(MemoryChunk* chunk, Address slot) { + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::NON_ATOMIC>(chunk, slot); + return 0; } #ifdef DEBUG void Heap::VerifyClearedSlot(HeapObject object, ObjectSlot slot) { +#ifndef V8_DISABLE_WRITE_BARRIERS DCHECK(!IsLargeObject(object)); if (InYoungGeneration(object)) return; Page* page = Page::FromAddress(slot.address()); DCHECK_EQ(page->owner_identity(), OLD_SPACE); - store_buffer()->MoveAllEntriesToRememberedSet(); - CHECK(!RememberedSet<OLD_TO_NEW>::Contains(page, slot.address())); - // Old to old slots are filtered with invalidated slots. + // Slots are filtered with invalidated slots. + CHECK_IMPLIES(RememberedSet<OLD_TO_NEW>::Contains(page, slot.address()), + page->RegisteredObjectWithInvalidatedSlots<OLD_TO_NEW>(object)); CHECK_IMPLIES(RememberedSet<OLD_TO_OLD>::Contains(page, slot.address()), page->RegisteredObjectWithInvalidatedSlots<OLD_TO_OLD>(object)); +#endif } #endif void Heap::ClearRecordedSlotRange(Address start, Address end) { +#ifndef V8_DISABLE_WRITE_BARRIERS Page* page = Page::FromAddress(start); DCHECK(!page->IsLargePage()); if (!page->InYoungGeneration()) { DCHECK_EQ(page->owner_identity(), OLD_SPACE); - store_buffer()->MoveAllEntriesToRememberedSet(); - RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end, - SlotSet::KEEP_EMPTY_BUCKETS); + + if (!page->SweepingDone()) { + RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end, + SlotSet::KEEP_EMPTY_BUCKETS); + } } +#endif } PagedSpace* PagedSpaceIterator::Next() { @@ -6164,8 +6177,8 @@ void Heap::WriteBarrierForCodeSlow(Code code) { void Heap::GenerationalBarrierSlow(HeapObject object, Address slot, HeapObject value) { - Heap* heap = Heap::FromWritableHeapObject(object); - heap->store_buffer()->InsertEntry(slot); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(object); + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::NON_ATOMIC>(chunk, slot); } void Heap::RecordEphemeronKeyWrite(EphemeronHashTable table, Address slot) { @@ -6207,7 +6220,6 @@ void Heap::WriteBarrierForRangeImpl(MemoryChunk* source_page, HeapObject object, STATIC_ASSERT(!(kModeMask & kDoEvacuationSlotRecording) || (kModeMask & kDoMarking)); - StoreBuffer* store_buffer = this->store_buffer(); IncrementalMarking* incremental_marking = this->incremental_marking(); MarkCompactCollector* collector = this->mark_compact_collector(); @@ -6218,7 +6230,8 @@ void Heap::WriteBarrierForRangeImpl(MemoryChunk* source_page, HeapObject object, if ((kModeMask & kDoGenerational) && Heap::InYoungGeneration(value_heap_object)) { - store_buffer->InsertEntry(slot.address()); + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::NON_ATOMIC>(source_page, + slot.address()); } if ((kModeMask & kDoMarking) && diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 2b8b963a798b2f..182096f29c78d2 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -7,6 +7,7 @@ #include <cmath> #include <map> +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> @@ -45,7 +46,11 @@ class TestMemoryAllocatorScope; } // namespace heap class IncrementalMarking; +class BackingStore; class JSArrayBuffer; +class JSPromise; +class NativeContext; + using v8::MemoryPressureLevel; class AllocationObserver; @@ -62,6 +67,7 @@ class Isolate; class JSFinalizationGroup; class LocalEmbedderHeapTracer; class MemoryAllocator; +class MemoryMeasurement; class MemoryReducer; class MinorMarkCompactCollector; class ObjectIterator; @@ -74,7 +80,6 @@ class ScavengeJob; class Scavenger; class ScavengerCollector; class Space; -class StoreBuffer; class StressScavengeObserver; class TimedHistogram; class WeakObjectRetainer; @@ -86,6 +91,8 @@ enum ArrayStorageAllocationMode { enum class ClearRecordedSlots { kYes, kNo }; +enum class InvalidateRecordedSlots { kYes, kNo }; + enum class ClearFreedMemoryMode { kClearFreedMemory, kDontClearFreedMemory }; enum ExternalBackingStoreType { kArrayBuffer, kExternalString, kNumTypes }; @@ -560,6 +567,9 @@ class Heap { void RecordStats(HeapStats* stats, bool take_snapshot = false); + Handle<JSPromise> MeasureMemory(Handle<NativeContext> context, + v8::MeasureMemoryMode mode); + // Check new space expansion criteria and expand semispaces if it was hit. void CheckNewSpaceExpansionCriteria(); @@ -839,12 +849,13 @@ class Heap { void SetIsMarkingFlag(uint8_t flag) { is_marking_flag_ = flag; } - Address* store_buffer_top_address(); + V8_EXPORT_PRIVATE Address* store_buffer_top_address(); static intptr_t store_buffer_mask_constant(); static Address store_buffer_overflow_function_address(); void ClearRecordedSlot(HeapObject object, ObjectSlot slot); void ClearRecordedSlotRange(Address start, Address end); + static int InsertIntoRememberedSetFromCode(MemoryChunk* chunk, Address slot); #ifdef DEBUG void VerifyClearedSlot(HeapObject object, ObjectSlot slot); @@ -896,8 +907,13 @@ class Heap { // The runtime uses this function to notify potentially unsafe object layout // changes that require special synchronization with the concurrent marker. // The old size is the size of the object before layout change. - void NotifyObjectLayoutChange(HeapObject object, int old_size, - const DisallowHeapAllocation&); + // By default recorded slots in the object are invalidated. Pass + // InvalidateRecordedSlots::kNo if this is not necessary or to perform this + // manually. + void NotifyObjectLayoutChange( + HeapObject object, const DisallowHeapAllocation&, + InvalidateRecordedSlots invalidate_recorded_slots = + InvalidateRecordedSlots::kYes); #ifdef VERIFY_HEAP // This function checks that either @@ -1214,16 +1230,24 @@ class Heap { AlignWithFiller(HeapObject object, int object_size, int allocation_size, AllocationAlignment alignment); + // Allocate an external backing store with the given allocation callback. + // If the callback fails (indicated by a nullptr result) then this function + // will re-try the allocation after performing GCs. This is useful for + // external backing stores that may be retained by (unreachable) V8 objects + // such as ArrayBuffers, ExternalStrings, etc. + // + // The function may also proactively trigger GCs even if the allocation + // callback does not fail to keep the memory usage low. + V8_EXPORT_PRIVATE void* AllocateExternalBackingStore( + const std::function<void*(size_t)>& allocate, size_t byte_length); + // =========================================================================== // ArrayBuffer tracking. ===================================================== // =========================================================================== - - // TODO(gc): API usability: encapsulate mutation of JSArrayBuffer::is_external - // in the registration/unregistration APIs. Consider dropping the "New" from - // "RegisterNewArrayBuffer" because one can re-register a previously - // unregistered buffer, too, and the name is confusing. - void RegisterNewArrayBuffer(JSArrayBuffer buffer); - void UnregisterArrayBuffer(JSArrayBuffer buffer); + void RegisterBackingStore(JSArrayBuffer buffer, + std::shared_ptr<BackingStore> backing_store); + std::shared_ptr<BackingStore> UnregisterBackingStore(JSArrayBuffer buffer); + std::shared_ptr<BackingStore> LookupBackingStore(JSArrayBuffer buffer); // =========================================================================== // Allocation site tracking. ================================================= @@ -1332,9 +1356,7 @@ class Heap { // per call to mmap(). The page is only reclaimed when the process is // killed. Confine the hint to a 32-bit section of the virtual address // space. See crbug.com/700928. - uintptr_t offset = - reinterpret_cast<uintptr_t>(v8::internal::GetRandomMmapAddr()) & - kMmapRegionMask; + uintptr_t offset = reinterpret_cast<uintptr_t>(result) & kMmapRegionMask; result = reinterpret_cast<void*>(mmap_region_base_ + offset); #endif // V8_OS_MACOSX #endif // V8_TARGET_ARCH_X64 @@ -1348,8 +1370,6 @@ class Heap { inline int MaxNumberToStringCacheSize() const; private: - class SkipStoreBufferScope; - using ExternalStringTableUpdaterCallback = String (*)(Heap* heap, FullObjectSlot pointer); @@ -1462,11 +1482,7 @@ class Heap { ROOT_LIST(ROOT_ACCESSOR) #undef ROOT_ACCESSOR - StoreBuffer* store_buffer() { return store_buffer_.get(); } - - void set_current_gc_flags(int flags) { - current_gc_flags_ = flags; - } + void set_current_gc_flags(int flags) { current_gc_flags_ = flags; } inline bool ShouldReduceMemory() const { return (current_gc_flags_ & kReduceMemoryFootprintMask) != 0; @@ -1732,20 +1748,23 @@ class Heap { AllocationOrigin origin = AllocationOrigin::kRuntime, AllocationAlignment alignment = kWordAligned); + // This method will try to allocate objects quickly (AllocationType::kYoung) + // otherwise it falls back to a slower path indicated by the mode. + enum AllocationRetryMode { kLightRetry, kRetryOrFail }; + template <AllocationRetryMode mode> + V8_WARN_UNUSED_RESULT inline HeapObject AllocateRawWith( + int size, AllocationType allocation, + AllocationOrigin origin = AllocationOrigin::kRuntime, + AllocationAlignment alignment = kWordAligned); + // This method will try to perform an allocation of a given size of a given // AllocationType. If the allocation fails, a regular full garbage collection // is triggered and the allocation is retried. This is performed multiple // times. If after that retry procedure the allocation still fails nullptr is // returned. - HeapObject AllocateRawWithLightRetry( + V8_WARN_UNUSED_RESULT HeapObject AllocateRawWithLightRetrySlowPath( int size, AllocationType allocation, AllocationOrigin origin, AllocationAlignment alignment = kWordAligned); - HeapObject AllocateRawWithLightRetry( - int size, AllocationType allocation, - AllocationAlignment alignment = kWordAligned) { - return AllocateRawWithLightRetry(size, allocation, - AllocationOrigin::kRuntime, alignment); - } // This method will try to perform an allocation of a given size of a given // AllocationType. If the allocation fails, a regular full garbage collection @@ -1753,17 +1772,11 @@ class Heap { // times. If after that retry procedure the allocation still fails a "hammer" // garbage collection is triggered which tries to significantly reduce memory. // If the allocation still fails after that a fatal error is thrown. - HeapObject AllocateRawWithRetryOrFail( + V8_WARN_UNUSED_RESULT HeapObject AllocateRawWithRetryOrFailSlowPath( int size, AllocationType allocation, AllocationOrigin origin, AllocationAlignment alignment = kWordAligned); - HeapObject AllocateRawWithRetryOrFail( - int size, AllocationType allocation, - AllocationAlignment alignment = kWordAligned) { - return AllocateRawWithRetryOrFail(size, allocation, - AllocationOrigin::kRuntime, alignment); - } - HeapObject AllocateRawCodeInLargeObjectSpace(int size); + V8_WARN_UNUSED_RESULT HeapObject AllocateRawCodeInLargeObjectSpace(int size); // Allocates a heap object based on the map. V8_WARN_UNUSED_RESULT AllocationResult Allocate(Map map, @@ -1980,10 +1993,10 @@ class Heap { std::unique_ptr<ScavengerCollector> scavenger_collector_; std::unique_ptr<ArrayBufferCollector> array_buffer_collector_; std::unique_ptr<MemoryAllocator> memory_allocator_; - std::unique_ptr<StoreBuffer> store_buffer_; std::unique_ptr<IncrementalMarking> incremental_marking_; std::unique_ptr<ConcurrentMarking> concurrent_marking_; std::unique_ptr<GCIdleTimeHandler> gc_idle_time_handler_; + std::unique_ptr<MemoryMeasurement> memory_measurement_; std::unique_ptr<MemoryReducer> memory_reducer_; std::unique_ptr<ObjectStats> live_object_stats_; std::unique_ptr<ObjectStats> dead_object_stats_; @@ -2101,7 +2114,6 @@ class Heap { friend class Scavenger; friend class ScavengerCollector; friend class Space; - friend class StoreBuffer; friend class Sweeper; friend class heap::TestMemoryAllocatorScope; @@ -2152,7 +2164,6 @@ class HeapStats { intptr_t* end_marker; // 27 }; - class AlwaysAllocateScope { public: explicit inline AlwaysAllocateScope(Heap* heap); @@ -2232,7 +2243,6 @@ class VerifyPointersVisitor : public ObjectVisitor, public RootVisitor { Heap* heap_; }; - // Verify that all objects are Smis. class VerifySmisVisitor : public RootVisitor { public: @@ -2263,7 +2273,7 @@ class V8_EXPORT_PRIVATE SpaceIterator : public Malloced { private: Heap* heap_; - int current_space_; // from enum AllocationSpace. + int current_space_; // from enum AllocationSpace. }; // A HeapObjectIterator provides iteration over the entire non-read-only heap. diff --git a/deps/v8/src/heap/incremental-marking-job.cc b/deps/v8/src/heap/incremental-marking-job.cc index c6e607c3eade7a..1f924ff1391563 100644 --- a/deps/v8/src/heap/incremental-marking-job.cc +++ b/deps/v8/src/heap/incremental-marking-job.cc @@ -54,24 +54,24 @@ void IncrementalMarkingJob::ScheduleTask(Heap* heap, TaskType task_type) { V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate); if (task_type == TaskType::kNormal) { if (taskrunner->NonNestableTasksEnabled()) { - taskrunner->PostNonNestableTask(base::make_unique<Task>( + taskrunner->PostNonNestableTask(std::make_unique<Task>( heap->isolate(), this, EmbedderHeapTracer::EmbedderStackState::kEmpty, task_type)); } else { - taskrunner->PostTask(base::make_unique<Task>( + taskrunner->PostTask(std::make_unique<Task>( heap->isolate(), this, EmbedderHeapTracer::EmbedderStackState::kUnknown, task_type)); } } else { if (taskrunner->NonNestableDelayedTasksEnabled()) { taskrunner->PostNonNestableDelayedTask( - base::make_unique<Task>( + std::make_unique<Task>( heap->isolate(), this, EmbedderHeapTracer::EmbedderStackState::kEmpty, task_type), kDelayInSeconds); } else { taskrunner->PostDelayedTask( - base::make_unique<Task>( + std::make_unique<Task>( heap->isolate(), this, EmbedderHeapTracer::EmbedderStackState::kUnknown, task_type), kDelayInSeconds); diff --git a/deps/v8/src/heap/invalidated-slots-inl.h b/deps/v8/src/heap/invalidated-slots-inl.h index 35a08108f63e93..546667b2b254ed 100644 --- a/deps/v8/src/heap/invalidated-slots-inl.h +++ b/deps/v8/src/heap/invalidated-slots-inl.h @@ -24,42 +24,40 @@ bool InvalidatedSlotsFilter::IsValid(Address slot) { DCHECK_LE(last_slot_, slot); last_slot_ = slot; #endif - while (slot >= invalidated_end_) { - ++iterator_; - if (iterator_ != iterator_end_) { - // Invalidated ranges must not overlap. - DCHECK_LE(invalidated_end_, iterator_->first.address()); - invalidated_start_ = iterator_->first.address(); - invalidated_end_ = invalidated_start_ + iterator_->second; - invalidated_object_ = HeapObject(); - invalidated_object_size_ = 0; - } else { - invalidated_start_ = sentinel_; - invalidated_end_ = sentinel_; - } - } - // Now the invalidated region ends after the slot. if (slot < invalidated_start_) { - // The invalidated region starts after the slot. return true; } - // The invalidated region includes the slot. - // Ask the object if the slot is valid. - if (invalidated_object_.is_null()) { - invalidated_object_ = HeapObject::FromAddress(invalidated_start_); - DCHECK(!invalidated_object_.IsFiller()); - invalidated_object_size_ = - invalidated_object_.SizeFromMap(invalidated_object_.map()); + + while (slot >= next_invalidated_start_) { + NextInvalidatedObject(); + } + + HeapObject invalidated_object = HeapObject::FromAddress(invalidated_start_); + + if (invalidated_size_ == 0) { + DCHECK(invalidated_object.map().IsMap()); + invalidated_size_ = invalidated_object.Size(); } + int offset = static_cast<int>(slot - invalidated_start_); DCHECK_GT(offset, 0); - DCHECK_LE(invalidated_object_size_, - static_cast<int>(invalidated_end_ - invalidated_start_)); + if (offset < invalidated_size_) + return invalidated_object.IsValidSlot(invalidated_object.map(), offset); + + NextInvalidatedObject(); + return true; +} + +void InvalidatedSlotsFilter::NextInvalidatedObject() { + invalidated_start_ = next_invalidated_start_; + invalidated_size_ = 0; - if (offset >= invalidated_object_size_) { - return slots_in_free_space_are_valid_; + if (iterator_ == iterator_end_) { + next_invalidated_start_ = sentinel_; + } else { + next_invalidated_start_ = iterator_->address(); + iterator_++; } - return invalidated_object_.IsValidSlot(invalidated_object_.map(), offset); } void InvalidatedSlotsCleanup::Free(Address free_start, Address free_end) { @@ -72,35 +70,25 @@ void InvalidatedSlotsCleanup::Free(Address free_start, Address free_end) { if (iterator_ == iterator_end_) return; - // Ignore invalidated objects before free region - while (free_start >= invalidated_end_) { + // Ignore invalidated objects that start before free region + while (invalidated_start_ < free_start) { ++iterator_; NextInvalidatedObject(); } - // Loop here: Free region might contain multiple invalidated objects - while (free_end > invalidated_start_) { - // Case: Free region starts before current invalidated object - if (free_start <= invalidated_start_) { - iterator_ = invalidated_slots_->erase(iterator_); - - } else { - // Case: Free region starts within current invalidated object - // (Can happen for right-trimmed objects) - iterator_++; - } - + // Remove all invalidated objects that start within + // free region. + while (invalidated_start_ < free_end) { + iterator_ = invalidated_slots_->erase(iterator_); NextInvalidatedObject(); } } void InvalidatedSlotsCleanup::NextInvalidatedObject() { if (iterator_ != iterator_end_) { - invalidated_start_ = iterator_->first.address(); - invalidated_end_ = invalidated_start_ + iterator_->second; + invalidated_start_ = iterator_->address(); } else { invalidated_start_ = sentinel_; - invalidated_end_ = sentinel_; } } diff --git a/deps/v8/src/heap/invalidated-slots.cc b/deps/v8/src/heap/invalidated-slots.cc index 8fa1518d683895..9f29af218bca26 100644 --- a/deps/v8/src/heap/invalidated-slots.cc +++ b/deps/v8/src/heap/invalidated-slots.cc @@ -3,52 +3,35 @@ // found in the LICENSE file. #include "src/heap/invalidated-slots.h" +#include "src/heap/invalidated-slots-inl.h" #include "src/heap/spaces.h" +#include "src/objects/objects-inl.h" namespace v8 { namespace internal { InvalidatedSlotsFilter InvalidatedSlotsFilter::OldToOld(MemoryChunk* chunk) { - // The sweeper removes invalid slots and makes free space available for - // allocation. Slots for new objects can be recorded in the free space. - // Note that we cannot simply check for SweepingDone because pages in large - // object space are not swept but have SweepingDone() == true. - bool slots_in_free_space_are_valid = - chunk->SweepingDone() && chunk->InOldSpace(); - return InvalidatedSlotsFilter(chunk, chunk->invalidated_slots<OLD_TO_OLD>(), - slots_in_free_space_are_valid); + return InvalidatedSlotsFilter(chunk, chunk->invalidated_slots<OLD_TO_OLD>()); } InvalidatedSlotsFilter InvalidatedSlotsFilter::OldToNew(MemoryChunk* chunk) { - // Always treat these slots as valid for old-to-new for now. Invalid - // old-to-new slots are always cleared. - bool slots_in_free_space_are_valid = true; - return InvalidatedSlotsFilter(chunk, chunk->invalidated_slots<OLD_TO_NEW>(), - slots_in_free_space_are_valid); + return InvalidatedSlotsFilter(chunk, chunk->invalidated_slots<OLD_TO_NEW>()); } InvalidatedSlotsFilter::InvalidatedSlotsFilter( - MemoryChunk* chunk, InvalidatedSlots* invalidated_slots, - bool slots_in_free_space_are_valid) { - // Adjust slots_in_free_space_are_valid_ if more spaces are added. - DCHECK_IMPLIES(invalidated_slots != nullptr, - chunk->InOldSpace() || chunk->InLargeObjectSpace()); - - slots_in_free_space_are_valid_ = slots_in_free_space_are_valid; + MemoryChunk* chunk, InvalidatedSlots* invalidated_slots) { invalidated_slots = invalidated_slots ? invalidated_slots : &empty_; iterator_ = invalidated_slots->begin(); iterator_end_ = invalidated_slots->end(); sentinel_ = chunk->area_end(); - if (iterator_ != iterator_end_) { - invalidated_start_ = iterator_->first.address(); - invalidated_end_ = invalidated_start_ + iterator_->second; - } else { - invalidated_start_ = sentinel_; - invalidated_end_ = sentinel_; - } - // These values will be lazily set when needed. - invalidated_object_size_ = 0; + + // Invoke NextInvalidatedObject twice, to initialize + // invalidated_start_ to the first invalidated object and + // next_invalidated_object_ to the second one. + NextInvalidatedObject(); + NextInvalidatedObject(); + #ifdef DEBUG last_slot_ = chunk->area_start(); #endif @@ -69,13 +52,7 @@ InvalidatedSlotsCleanup::InvalidatedSlotsCleanup( iterator_end_ = invalidated_slots_->end(); sentinel_ = chunk->area_end(); - if (iterator_ != iterator_end_) { - invalidated_start_ = iterator_->first.address(); - invalidated_end_ = invalidated_start_ + iterator_->second; - } else { - invalidated_start_ = sentinel_; - invalidated_end_ = sentinel_; - } + NextInvalidatedObject(); #ifdef DEBUG last_free_ = chunk->area_start(); diff --git a/deps/v8/src/heap/invalidated-slots.h b/deps/v8/src/heap/invalidated-slots.h index 4a722719106fb8..15be3ce44cd8f0 100644 --- a/deps/v8/src/heap/invalidated-slots.h +++ b/deps/v8/src/heap/invalidated-slots.h @@ -5,7 +5,7 @@ #ifndef V8_HEAP_INVALIDATED_SLOTS_H_ #define V8_HEAP_INVALIDATED_SLOTS_H_ -#include <map> +#include <set> #include <stack> #include "src/base/atomic-utils.h" @@ -20,7 +20,7 @@ namespace internal { // that potentially invalidates slots recorded concurrently. The second part // of each element is the size of the corresponding object before the layout // change. -using InvalidatedSlots = std::map<HeapObject, int, Object::Comparer>; +using InvalidatedSlots = std::set<HeapObject, Object::Comparer>; // This class provides IsValid predicate that takes into account the set // of invalidated objects in the given memory chunk. @@ -34,8 +34,7 @@ class V8_EXPORT_PRIVATE InvalidatedSlotsFilter { static InvalidatedSlotsFilter OldToNew(MemoryChunk* chunk); explicit InvalidatedSlotsFilter(MemoryChunk* chunk, - InvalidatedSlots* invalidated_slots, - bool slots_in_free_space_are_valid); + InvalidatedSlots* invalidated_slots); inline bool IsValid(Address slot); private: @@ -43,14 +42,15 @@ class V8_EXPORT_PRIVATE InvalidatedSlotsFilter { InvalidatedSlots::const_iterator iterator_end_; Address sentinel_; Address invalidated_start_; - Address invalidated_end_; - HeapObject invalidated_object_; - int invalidated_object_size_; - bool slots_in_free_space_are_valid_; + Address next_invalidated_start_; + int invalidated_size_; InvalidatedSlots empty_; #ifdef DEBUG Address last_slot_; #endif + + private: + inline void NextInvalidatedObject(); }; class V8_EXPORT_PRIVATE InvalidatedSlotsCleanup { @@ -71,7 +71,6 @@ class V8_EXPORT_PRIVATE InvalidatedSlotsCleanup { Address sentinel_; Address invalidated_start_; - Address invalidated_end_; inline void NextInvalidatedObject(); #ifdef DEBUG diff --git a/deps/v8/src/heap/mark-compact-inl.h b/deps/v8/src/heap/mark-compact-inl.h index cf6d96cef813e0..ed7e251f44f291 100644 --- a/deps/v8/src/heap/mark-compact-inl.h +++ b/deps/v8/src/heap/mark-compact-inl.h @@ -485,7 +485,8 @@ void MarkCompactCollector::RecordSlot(HeapObject object, HeapObjectSlot slot, MemoryChunk* source_page = MemoryChunk::FromHeapObject(object); if (target_page->IsEvacuationCandidate<AccessMode::ATOMIC>() && !source_page->ShouldSkipEvacuationSlotRecording<AccessMode::ATOMIC>()) { - RememberedSet<OLD_TO_OLD>::Insert(source_page, slot.address()); + RememberedSet<OLD_TO_OLD>::Insert<AccessMode::ATOMIC>(source_page, + slot.address()); } } @@ -493,7 +494,8 @@ void MarkCompactCollector::RecordSlot(MemoryChunk* source_page, HeapObjectSlot slot, HeapObject target) { MemoryChunk* target_page = MemoryChunk::FromHeapObject(target); if (target_page->IsEvacuationCandidate<AccessMode::ATOMIC>()) { - RememberedSet<OLD_TO_OLD>::Insert(source_page, slot.address()); + RememberedSet<OLD_TO_OLD>::Insert<AccessMode::ATOMIC>(source_page, + slot.address()); } } diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc index f7067a60ea225d..c18b2652d7a3ed 100644 --- a/deps/v8/src/heap/mark-compact.cc +++ b/deps/v8/src/heap/mark-compact.cc @@ -2080,12 +2080,13 @@ void MarkCompactCollector::FlushBytecodeFromSFI( MemoryChunk* chunk = MemoryChunk::FromAddress(compiled_data_start); // Clear any recorded slots for the compiled data as being invalid. + DCHECK_NULL(chunk->sweeping_slot_set()); RememberedSet<OLD_TO_NEW>::RemoveRange( chunk, compiled_data_start, compiled_data_start + compiled_data_size, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_OLD>::RemoveRange( chunk, compiled_data_start, compiled_data_start + compiled_data_size, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); // Swap the map, using set_map_after_allocation to avoid verify heap checks // which are not necessary since we are doing this during the GC atomic pause. @@ -2233,12 +2234,12 @@ void MarkCompactCollector::RightTrimDescriptorArray(DescriptorArray array, DCHECK_LE(0, new_nof_all_descriptors); Address start = array.GetDescriptorSlot(new_nof_all_descriptors).address(); Address end = array.GetDescriptorSlot(old_nof_all_descriptors).address(); - RememberedSet<OLD_TO_NEW>::RemoveRange(MemoryChunk::FromHeapObject(array), - start, end, - SlotSet::PREFREE_EMPTY_BUCKETS); - RememberedSet<OLD_TO_OLD>::RemoveRange(MemoryChunk::FromHeapObject(array), - start, end, - SlotSet::PREFREE_EMPTY_BUCKETS); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(array); + DCHECK_NULL(chunk->sweeping_slot_set()); + RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, end, + SlotSet::FREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_OLD>::RemoveRange(chunk, start, end, + SlotSet::FREE_EMPTY_BUCKETS); heap()->CreateFillerObjectAt(start, static_cast<int>(end - start), ClearRecordedSlots::kNo); array.set_number_of_all_descriptors(new_nof_all_descriptors); @@ -3411,15 +3412,32 @@ class RememberedSetUpdatingItem : public UpdatingItem { void UpdateUntypedPointers() { if (chunk_->slot_set<OLD_TO_NEW, AccessMode::NON_ATOMIC>() != nullptr) { + InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew(chunk_); RememberedSet<OLD_TO_NEW>::Iterate( chunk_, - [this](MaybeObjectSlot slot) { + [this, &filter](MaybeObjectSlot slot) { + if (!filter.IsValid(slot.address())) return REMOVE_SLOT; return CheckAndUpdateOldToNewSlot(slot); }, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); } - DCHECK_NULL(chunk_->invalidated_slots<OLD_TO_NEW>()); + if (chunk_->sweeping_slot_set<AccessMode::NON_ATOMIC>()) { + InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew(chunk_); + RememberedSetSweeping::Iterate( + chunk_, + [this, &filter](MaybeObjectSlot slot) { + if (!filter.IsValid(slot.address())) return REMOVE_SLOT; + return CheckAndUpdateOldToNewSlot(slot); + }, + SlotSet::FREE_EMPTY_BUCKETS); + } + + if (chunk_->invalidated_slots<OLD_TO_NEW>() != nullptr) { + // The invalidated slots are not needed after old-to-new slots were + // processed. + chunk_->ReleaseInvalidatedSlots<OLD_TO_NEW>(); + } if ((updating_mode_ == RememberedSetUpdatingMode::ALL) && (chunk_->slot_set<OLD_TO_OLD, AccessMode::NON_ATOMIC>() != nullptr)) { @@ -3430,17 +3448,11 @@ class RememberedSetUpdatingItem : public UpdatingItem { if (!filter.IsValid(slot.address())) return REMOVE_SLOT; return UpdateSlot<AccessMode::NON_ATOMIC>(slot); }, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); + chunk_->ReleaseSlotSet<OLD_TO_OLD>(); } if ((updating_mode_ == RememberedSetUpdatingMode::ALL) && chunk_->invalidated_slots<OLD_TO_OLD>() != nullptr) { -#ifdef DEBUG - for (auto object_size : *chunk_->invalidated_slots<OLD_TO_OLD>()) { - HeapObject object = object_size.first; - int size = object_size.second; - DCHECK_LE(object.SizeFromMap(object.map()), size); - } -#endif // The invalidated slots are not needed after old-to-old slots were // processsed. chunk_->ReleaseInvalidatedSlots<OLD_TO_OLD>(); @@ -3557,15 +3569,18 @@ int MarkCompactCollectorBase::CollectRememberedSetUpdatingItems( const bool contains_old_to_new_slots = chunk->slot_set<OLD_TO_NEW>() != nullptr || chunk->typed_slot_set<OLD_TO_NEW>() != nullptr; + const bool contains_old_to_new_sweeping_slots = + chunk->sweeping_slot_set() != nullptr; const bool contains_old_to_old_invalidated_slots = chunk->invalidated_slots<OLD_TO_OLD>() != nullptr; const bool contains_old_to_new_invalidated_slots = chunk->invalidated_slots<OLD_TO_NEW>() != nullptr; - if (!contains_old_to_new_slots && !contains_old_to_old_slots && - !contains_old_to_old_invalidated_slots && + if (!contains_old_to_new_slots && !contains_old_to_new_sweeping_slots && + !contains_old_to_old_slots && !contains_old_to_old_invalidated_slots && !contains_old_to_new_invalidated_slots) continue; if (mode == RememberedSetUpdatingMode::ALL || contains_old_to_new_slots || + contains_old_to_new_sweeping_slots || contains_old_to_old_invalidated_slots || contains_old_to_new_invalidated_slots) { job->AddItem(CreateRememberedSetUpdatingItem(chunk, mode)); @@ -3773,11 +3788,22 @@ void MarkCompactCollector::PostProcessEvacuationCandidates() { // might not have recorded them in first place. // Remove outdated slots. + RememberedSetSweeping::RemoveRange(page, page->address(), + failed_object.address(), + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(page, page->address(), failed_object.address(), - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRangeTyped(page, page->address(), failed_object.address()); + + // Remove invalidated slots. + if (failed_object.address() > page->area_start()) { + InvalidatedSlotsCleanup old_to_new_cleanup = + InvalidatedSlotsCleanup::OldToNew(page); + old_to_new_cleanup.Free(page->area_start(), failed_object.address()); + } + // Recompute live bytes. LiveObjectVisitor::RecomputeLiveBytes(page, non_atomic_marking_state()); // Re-record slots. @@ -4350,11 +4376,7 @@ void MinorMarkCompactCollector::CollectGarbage() { RememberedSet<OLD_TO_NEW>::IterateMemoryChunks( heap(), [](MemoryChunk* chunk) { - if (chunk->SweepingDone()) { - RememberedSet<OLD_TO_NEW>::FreeEmptyBuckets(chunk); - } else { - RememberedSet<OLD_TO_NEW>::PreFreeEmptyBuckets(chunk); - } + RememberedSet<OLD_TO_NEW>::FreeEmptyBuckets(chunk); }); heap()->account_external_memory_concurrently_freed(); @@ -4651,7 +4673,15 @@ class PageMarkingItem : public MarkingItem { if (!filter.IsValid(slot.address())) return REMOVE_SLOT; return CheckAndMarkObject(task, slot); }, - SlotSet::PREFREE_EMPTY_BUCKETS); + SlotSet::FREE_EMPTY_BUCKETS); + filter = InvalidatedSlotsFilter::OldToNew(chunk_); + RememberedSetSweeping::Iterate( + chunk_, + [this, task, &filter](MaybeObjectSlot slot) { + if (!filter.IsValid(slot.address())) return REMOVE_SLOT; + return CheckAndMarkObject(task, slot); + }, + SlotSet::FREE_EMPTY_BUCKETS); } void MarkTypedPointers(YoungGenerationMarkingTask* task) { diff --git a/deps/v8/src/heap/memory-measurement.cc b/deps/v8/src/heap/memory-measurement.cc new file mode 100644 index 00000000000000..62cd5dadb94ca0 --- /dev/null +++ b/deps/v8/src/heap/memory-measurement.cc @@ -0,0 +1,80 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/heap/memory-measurement.h" + +#include "src/execution/isolate-inl.h" +#include "src/execution/isolate.h" +#include "src/heap/factory-inl.h" +#include "src/heap/factory.h" +#include "src/objects/js-promise.h" + +namespace v8 { +namespace internal { + +MemoryMeasurement::MemoryMeasurement(Isolate* isolate) : isolate_(isolate) {} + +namespace { + +class MemoryMeasurementResultBuilder { + public: + MemoryMeasurementResultBuilder(Isolate* isolate, Factory* factory) + : isolate_(isolate), factory_(factory) { + result_ = NewJSObject(); + } + + void AddTotals(size_t estimate, size_t lower_bound, size_t upper_bound) { + Handle<JSObject> total = NewJSObject(); + Handle<Object> estimate_obj = NewNumber(estimate); + AddProperty(total, factory_->jsMemoryEstimate_string(), estimate_obj); + Handle<Object> range = NewRange(lower_bound, upper_bound); + AddProperty(total, factory_->jsMemoryRange_string(), range); + AddProperty(result_, factory_->total_string(), total); + } + + Handle<JSObject> Build() { return result_; } + + private: + Handle<Object> NewNumber(size_t value) { + return factory_->NewNumberFromSize(value); + } + + Handle<JSObject> NewJSObject() { + return factory_->NewJSObject(isolate_->object_function()); + } + + Handle<JSArray> NewRange(size_t lower_bound, size_t upper_bound) { + Handle<Object> lower = NewNumber(lower_bound); + Handle<Object> upper = NewNumber(upper_bound); + Handle<FixedArray> elements = factory_->NewFixedArray(2); + elements->set(0, *lower); + elements->set(1, *upper); + return factory_->NewJSArrayWithElements(elements); + } + + void AddProperty(Handle<JSObject> object, Handle<String> name, + Handle<Object> value) { + JSObject::AddProperty(isolate_, object, name, value, NONE); + } + + Isolate* isolate_; + Factory* factory_; + Handle<JSObject> result_; +}; + +} // anonymous namespace + +Handle<JSPromise> MemoryMeasurement::EnqueueRequest( + Handle<NativeContext> context, v8::MeasureMemoryMode mode) { + Handle<JSPromise> promise = isolate_->factory()->NewJSPromise(); + MemoryMeasurementResultBuilder result_builder(isolate_, isolate_->factory()); + result_builder.AddTotals(isolate_->heap()->SizeOfObjects(), 0, + isolate_->heap()->SizeOfObjects()); + Handle<JSObject> result = result_builder.Build(); + JSPromise::Resolve(promise, result).ToHandleChecked(); + return promise; +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/heap/memory-measurement.h b/deps/v8/src/heap/memory-measurement.h new file mode 100644 index 00000000000000..6de7c8c970c99a --- /dev/null +++ b/deps/v8/src/heap/memory-measurement.h @@ -0,0 +1,29 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_HEAP_MEMORY_MEASUREMENT_H_ +#define V8_HEAP_MEMORY_MEASUREMENT_H_ + +#include "src/common/globals.h" +#include "src/objects/objects.h" + +namespace v8 { +namespace internal { + +class Heap; + +class V8_EXPORT_PRIVATE MemoryMeasurement { + public: + explicit MemoryMeasurement(Isolate* isolate); + Handle<JSPromise> EnqueueRequest(Handle<NativeContext> context, + v8::MeasureMemoryMode mode); + + private: + Isolate* isolate_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_HEAP_MEMORY_MEASUREMENT_H_ diff --git a/deps/v8/src/heap/memory-reducer.cc b/deps/v8/src/heap/memory-reducer.cc index 704e6567962166..37dca5b99c45d4 100644 --- a/deps/v8/src/heap/memory-reducer.cc +++ b/deps/v8/src/heap/memory-reducer.cc @@ -214,9 +214,8 @@ void MemoryReducer::ScheduleTimer(double delay_ms) { if (heap()->IsTearingDown()) return; // Leave some room for precision error in task scheduler. const double kSlackMs = 100; - taskrunner_->PostDelayedTask( - base::make_unique<MemoryReducer::TimerTask>(this), - (delay_ms + kSlackMs) / 1000.0); + taskrunner_->PostDelayedTask(std::make_unique<MemoryReducer::TimerTask>(this), + (delay_ms + kSlackMs) / 1000.0); } void MemoryReducer::TearDown() { state_ = State(kDone, 0, 0, 0.0, 0); } diff --git a/deps/v8/src/heap/object-stats.cc b/deps/v8/src/heap/object-stats.cc index 2ee88361c965f3..44798a392826ff 100644 --- a/deps/v8/src/heap/object-stats.cc +++ b/deps/v8/src/heap/object-stats.cc @@ -150,9 +150,8 @@ FieldStatsCollector::GetInobjectFieldStats(Map map) { JSObjectFieldStats stats; stats.embedded_fields_count_ = JSObject::GetEmbedderFieldCount(map); if (!map.is_dictionary_map()) { - int nof = map.NumberOfOwnDescriptors(); DescriptorArray descriptors = map.instance_descriptors(); - for (int descriptor = 0; descriptor < nof; descriptor++) { + for (InternalIndex descriptor : map.IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(descriptor); if (details.location() == kField) { FieldIndex index = FieldIndex::ForDescriptor(map, descriptor); @@ -658,8 +657,7 @@ static ObjectStats::VirtualInstanceType GetFeedbackSlotType( Object obj = maybe_obj->GetHeapObjectOrSmi(); switch (kind) { case FeedbackSlotKind::kCall: - if (obj == *isolate->factory()->uninitialized_symbol() || - obj == *isolate->factory()->premonomorphic_symbol()) { + if (obj == *isolate->factory()->uninitialized_symbol()) { return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE; } return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_TYPE; @@ -669,8 +667,7 @@ static ObjectStats::VirtualInstanceType GetFeedbackSlotType( case FeedbackSlotKind::kLoadGlobalNotInsideTypeof: case FeedbackSlotKind::kLoadKeyed: case FeedbackSlotKind::kHasKeyed: - if (obj == *isolate->factory()->uninitialized_symbol() || - obj == *isolate->factory()->premonomorphic_symbol()) { + if (obj == *isolate->factory()->uninitialized_symbol()) { return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE; } return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_TYPE; @@ -682,8 +679,7 @@ static ObjectStats::VirtualInstanceType GetFeedbackSlotType( case FeedbackSlotKind::kStoreGlobalStrict: case FeedbackSlotKind::kStoreKeyedSloppy: case FeedbackSlotKind::kStoreKeyedStrict: - if (obj == *isolate->factory()->uninitialized_symbol() || - obj == *isolate->factory()->premonomorphic_symbol()) { + if (obj == *isolate->factory()->uninitialized_symbol()) { return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE; } return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_TYPE; @@ -829,10 +825,6 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() { ObjectStats::RETAINED_MAPS_TYPE); // WeakArrayList. - RecordSimpleVirtualObjectStats( - HeapObject(), - WeakArrayList::cast(heap_->noscript_shared_function_infos()), - ObjectStats::NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE); RecordSimpleVirtualObjectStats(HeapObject(), WeakArrayList::cast(heap_->script_list()), ObjectStats::SCRIPT_LIST_TYPE); diff --git a/deps/v8/src/heap/object-stats.h b/deps/v8/src/heap/object-stats.h index 2a9b9675ef2145..28ef967c5ca011 100644 --- a/deps/v8/src/heap/object-stats.h +++ b/deps/v8/src/heap/object-stats.h @@ -54,7 +54,6 @@ V(MAP_PROTOTYPE_DICTIONARY_TYPE) \ V(MAP_PROTOTYPE_TYPE) \ V(MAP_STABLE_TYPE) \ - V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \ V(NUMBER_STRING_CACHE_TYPE) \ V(OBJECT_DICTIONARY_ELEMENTS_TYPE) \ V(OBJECT_ELEMENTS_TYPE) \ diff --git a/deps/v8/src/heap/objects-visiting-inl.h b/deps/v8/src/heap/objects-visiting-inl.h index ba0bfa2415befb..d4d6d9375cd150 100644 --- a/deps/v8/src/heap/objects-visiting-inl.h +++ b/deps/v8/src/heap/objects-visiting-inl.h @@ -38,7 +38,7 @@ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map map, HeapObject object) { ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); switch (map.visitor_id()) { -#define CASE(TypeName, Type) \ +#define CASE(TypeName) \ case kVisit##TypeName: \ return visitor->Visit##TypeName( \ map, ConcreteVisitor::template Cast<TypeName>(object)); @@ -77,10 +77,10 @@ void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer( static_cast<ConcreteVisitor*>(this)->VisitPointer(host, host.map_slot()); } -#define VISIT(TypeName, Type) \ +#define VISIT(TypeName) \ template <typename ResultType, typename ConcreteVisitor> \ ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##TypeName( \ - Map map, Type object) { \ + Map map, TypeName object) { \ ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \ if (!visitor->ShouldVisit(object)) return ResultType(); \ if (!visitor->AllowDefaultJSObjectVisit()) { \ diff --git a/deps/v8/src/heap/objects-visiting.h b/deps/v8/src/heap/objects-visiting.h index a5c291458f5758..0f972737d25e4b 100644 --- a/deps/v8/src/heap/objects-visiting.h +++ b/deps/v8/src/heap/objects-visiting.h @@ -13,59 +13,58 @@ namespace v8 { namespace internal { -// TODO(jkummerow): Drop the duplication: V(x, x) -> V(x). -#define TYPED_VISITOR_ID_LIST(V) \ - V(AllocationSite, AllocationSite) \ - V(BigInt, BigInt) \ - V(ByteArray, ByteArray) \ - V(BytecodeArray, BytecodeArray) \ - V(Cell, Cell) \ - V(Code, Code) \ - V(CodeDataContainer, CodeDataContainer) \ - V(ConsString, ConsString) \ - V(Context, Context) \ - V(DataHandler, DataHandler) \ - V(DescriptorArray, DescriptorArray) \ - V(EmbedderDataArray, EmbedderDataArray) \ - V(EphemeronHashTable, EphemeronHashTable) \ - V(FeedbackCell, FeedbackCell) \ - V(FeedbackVector, FeedbackVector) \ - V(FixedArray, FixedArray) \ - V(FixedDoubleArray, FixedDoubleArray) \ - V(JSArrayBuffer, JSArrayBuffer) \ - V(JSDataView, JSDataView) \ - V(JSFunction, JSFunction) \ - V(JSObject, JSObject) \ - V(JSTypedArray, JSTypedArray) \ - V(WeakCell, WeakCell) \ - V(JSWeakCollection, JSWeakCollection) \ - V(JSWeakRef, JSWeakRef) \ - V(Map, Map) \ - V(NativeContext, NativeContext) \ - V(Oddball, Oddball) \ - V(PreparseData, PreparseData) \ - V(PropertyArray, PropertyArray) \ - V(PropertyCell, PropertyCell) \ - V(PrototypeInfo, PrototypeInfo) \ - V(SeqOneByteString, SeqOneByteString) \ - V(SeqTwoByteString, SeqTwoByteString) \ - V(SharedFunctionInfo, SharedFunctionInfo) \ - V(SlicedString, SlicedString) \ - V(SmallOrderedHashMap, SmallOrderedHashMap) \ - V(SmallOrderedHashSet, SmallOrderedHashSet) \ - V(SmallOrderedNameDictionary, SmallOrderedNameDictionary) \ - V(SourceTextModule, SourceTextModule) \ - V(Symbol, Symbol) \ - V(SyntheticModule, SyntheticModule) \ - V(ThinString, ThinString) \ - V(TransitionArray, TransitionArray) \ - V(UncompiledDataWithoutPreparseData, UncompiledDataWithoutPreparseData) \ - V(UncompiledDataWithPreparseData, UncompiledDataWithPreparseData) \ - V(WasmCapiFunctionData, WasmCapiFunctionData) \ - V(WasmIndirectFunctionTable, WasmIndirectFunctionTable) \ - V(WasmInstanceObject, WasmInstanceObject) - -#define FORWARD_DECLARE(TypeName, Type) class Type; +#define TYPED_VISITOR_ID_LIST(V) \ + V(AllocationSite) \ + V(BigInt) \ + V(ByteArray) \ + V(BytecodeArray) \ + V(Cell) \ + V(Code) \ + V(CodeDataContainer) \ + V(ConsString) \ + V(Context) \ + V(DataHandler) \ + V(DescriptorArray) \ + V(EmbedderDataArray) \ + V(EphemeronHashTable) \ + V(FeedbackCell) \ + V(FeedbackVector) \ + V(FixedArray) \ + V(FixedDoubleArray) \ + V(JSArrayBuffer) \ + V(JSDataView) \ + V(JSFunction) \ + V(JSObject) \ + V(JSTypedArray) \ + V(WeakCell) \ + V(JSWeakCollection) \ + V(JSWeakRef) \ + V(Map) \ + V(NativeContext) \ + V(Oddball) \ + V(PreparseData) \ + V(PropertyArray) \ + V(PropertyCell) \ + V(PrototypeInfo) \ + V(SeqOneByteString) \ + V(SeqTwoByteString) \ + V(SharedFunctionInfo) \ + V(SlicedString) \ + V(SmallOrderedHashMap) \ + V(SmallOrderedHashSet) \ + V(SmallOrderedNameDictionary) \ + V(SourceTextModule) \ + V(Symbol) \ + V(SyntheticModule) \ + V(ThinString) \ + V(TransitionArray) \ + V(UncompiledDataWithoutPreparseData) \ + V(UncompiledDataWithPreparseData) \ + V(WasmCapiFunctionData) \ + V(WasmIndirectFunctionTable) \ + V(WasmInstanceObject) + +#define FORWARD_DECLARE(TypeName) class TypeName; TYPED_VISITOR_ID_LIST(FORWARD_DECLARE) #undef FORWARD_DECLARE @@ -99,8 +98,8 @@ class HeapVisitor : public ObjectVisitor { // in default Visit implemention for subclasses of JSObject. V8_INLINE bool AllowDefaultJSObjectVisit() { return true; } -#define VISIT(TypeName, Type) \ - V8_INLINE ResultType Visit##TypeName(Map map, Type object); +#define VISIT(TypeName) \ + V8_INLINE ResultType Visit##TypeName(Map map, TypeName object); TYPED_VISITOR_ID_LIST(VISIT) #undef VISIT V8_INLINE ResultType VisitShortcutCandidate(Map map, ConsString object); diff --git a/deps/v8/src/heap/remembered-set.h b/deps/v8/src/heap/remembered-set.h index eefc565e0083dc..3c8984c83a6052 100644 --- a/deps/v8/src/heap/remembered-set.h +++ b/deps/v8/src/heap/remembered-set.h @@ -5,6 +5,8 @@ #ifndef V8_HEAP_REMEMBERED_SET_H_ #define V8_HEAP_REMEMBERED_SET_H_ +#include <memory> + #include "src/base/memory.h" #include "src/codegen/reloc-info.h" #include "src/heap/heap.h" @@ -16,54 +18,39 @@ namespace internal { enum RememberedSetIterationMode { SYNCHRONIZED, NON_SYNCHRONIZED }; -// TODO(ulan): Investigate performance of de-templatizing this class. -template <RememberedSetType type> -class RememberedSet : public AllStatic { +class RememberedSetOperations { public: // Given a page and a slot in that page, this function adds the slot to the // remembered set. - template <AccessMode access_mode = AccessMode::ATOMIC> - static void Insert(MemoryChunk* chunk, Address slot_addr) { + template <AccessMode access_mode> + static void Insert(SlotSet* slot_set, MemoryChunk* chunk, Address slot_addr) { DCHECK(chunk->Contains(slot_addr)); - SlotSet* slot_set = chunk->slot_set<type, access_mode>(); - if (slot_set == nullptr) { - slot_set = chunk->AllocateSlotSet<type>(); - } uintptr_t offset = slot_addr - chunk->address(); slot_set[offset / Page::kPageSize].Insert<access_mode>(offset % Page::kPageSize); } - // Given a page and a slot in that page, this function returns true if - // the remembered set contains the slot. - static bool Contains(MemoryChunk* chunk, Address slot_addr) { - DCHECK(chunk->Contains(slot_addr)); - SlotSet* slot_set = chunk->slot_set<type>(); - if (slot_set == nullptr) { - return false; + template <typename Callback> + static void Iterate(SlotSet* slots, MemoryChunk* chunk, Callback callback, + SlotSet::EmptyBucketMode mode) { + if (slots != nullptr) { + size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; + for (size_t page = 0; page < pages; page++) { + slots[page].Iterate(chunk->address() + page * Page::kPageSize, callback, + mode); + } } - uintptr_t offset = slot_addr - chunk->address(); - return slot_set[offset / Page::kPageSize].Contains(offset % - Page::kPageSize); } - // Given a page and a slot in that page, this function removes the slot from - // the remembered set. - // If the slot was never added, then the function does nothing. - static void Remove(MemoryChunk* chunk, Address slot_addr) { - DCHECK(chunk->Contains(slot_addr)); - SlotSet* slot_set = chunk->slot_set<type>(); + static void Remove(SlotSet* slot_set, MemoryChunk* chunk, Address slot_addr) { if (slot_set != nullptr) { uintptr_t offset = slot_addr - chunk->address(); slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize); } } - // Given a page and a range of slots in that page, this function removes the - // slots from the remembered set. - static void RemoveRange(MemoryChunk* chunk, Address start, Address end, - SlotSet::EmptyBucketMode mode) { - SlotSet* slot_set = chunk->slot_set<type>(); + static void RemoveRange(SlotSet* slot_set, MemoryChunk* chunk, Address start, + Address end, SlotSet::EmptyBucketMode mode) { if (slot_set != nullptr) { uintptr_t start_offset = start - chunk->address(); uintptr_t end_offset = end - chunk->address(); @@ -99,6 +86,53 @@ class RememberedSet : public AllStatic { } } } +}; + +// TODO(ulan): Investigate performance of de-templatizing this class. +template <RememberedSetType type> +class RememberedSet : public AllStatic { + public: + // Given a page and a slot in that page, this function adds the slot to the + // remembered set. + template <AccessMode access_mode> + static void Insert(MemoryChunk* chunk, Address slot_addr) { + DCHECK(chunk->Contains(slot_addr)); + SlotSet* slot_set = chunk->slot_set<type, access_mode>(); + if (slot_set == nullptr) { + slot_set = chunk->AllocateSlotSet<type>(); + } + RememberedSetOperations::Insert<access_mode>(slot_set, chunk, slot_addr); + } + + // Given a page and a slot in that page, this function returns true if + // the remembered set contains the slot. + static bool Contains(MemoryChunk* chunk, Address slot_addr) { + DCHECK(chunk->Contains(slot_addr)); + SlotSet* slot_set = chunk->slot_set<type>(); + if (slot_set == nullptr) { + return false; + } + uintptr_t offset = slot_addr - chunk->address(); + return slot_set[offset / Page::kPageSize].Contains(offset % + Page::kPageSize); + } + + // Given a page and a slot in that page, this function removes the slot from + // the remembered set. + // If the slot was never added, then the function does nothing. + static void Remove(MemoryChunk* chunk, Address slot_addr) { + DCHECK(chunk->Contains(slot_addr)); + SlotSet* slot_set = chunk->slot_set<type>(); + RememberedSetOperations::Remove(slot_set, chunk, slot_addr); + } + + // Given a page and a range of slots in that page, this function removes the + // slots from the remembered set. + static void RemoveRange(MemoryChunk* chunk, Address start, Address end, + SlotSet::EmptyBucketMode mode) { + SlotSet* slot_set = chunk->slot_set<type>(); + RememberedSetOperations::RemoveRange(slot_set, chunk, start, end, mode); + } // Iterates and filters the remembered set with the given callback. // The callback should take (Address slot) and return SlotCallbackResult. @@ -120,8 +154,11 @@ class RememberedSet : public AllStatic { MemoryChunk* chunk; while ((chunk = it.next()) != nullptr) { SlotSet* slots = chunk->slot_set<type>(); + SlotSet* sweeping_slots = + type == OLD_TO_NEW ? chunk->sweeping_slot_set() : nullptr; TypedSlotSet* typed_slots = chunk->typed_slot_set<type>(); - if (slots != nullptr || typed_slots != nullptr || + if (slots != nullptr || sweeping_slots != nullptr || + typed_slots != nullptr || chunk->invalidated_slots<type>() != nullptr) { callback(chunk); } @@ -138,42 +175,7 @@ class RememberedSet : public AllStatic { static void Iterate(MemoryChunk* chunk, Callback callback, SlotSet::EmptyBucketMode mode) { SlotSet* slots = chunk->slot_set<type>(); - if (slots != nullptr) { - size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; - int new_count = 0; - for (size_t page = 0; page < pages; page++) { - new_count += slots[page].Iterate(callback, mode); - } - // Only old-to-old slot sets are released eagerly. Old-new-slot sets are - // released by the sweeper threads. - if (type == OLD_TO_OLD && new_count == 0) { - chunk->ReleaseSlotSet<OLD_TO_OLD>(); - } - } - } - - static int NumberOfPreFreedEmptyBuckets(MemoryChunk* chunk) { - DCHECK(type == OLD_TO_NEW); - int result = 0; - SlotSet* slots = chunk->slot_set<type>(); - if (slots != nullptr) { - size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; - for (size_t page = 0; page < pages; page++) { - result += slots[page].NumberOfPreFreedEmptyBuckets(); - } - } - return result; - } - - static void PreFreeEmptyBuckets(MemoryChunk* chunk) { - DCHECK(type == OLD_TO_NEW); - SlotSet* slots = chunk->slot_set<type>(); - if (slots != nullptr) { - size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; - for (size_t page = 0; page < pages; page++) { - slots[page].PreFreeEmptyBuckets(); - } - } + RememberedSetOperations::Iterate(slots, chunk, callback, mode); } static void FreeEmptyBuckets(MemoryChunk* chunk) { @@ -183,7 +185,6 @@ class RememberedSet : public AllStatic { size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; for (size_t page = 0; page < pages; page++) { slots[page].FreeEmptyBuckets(); - slots[page].FreeToBeFreedBuckets(); } } } @@ -217,7 +218,7 @@ class RememberedSet : public AllStatic { return start <= slot_addr && slot_addr < end ? REMOVE_SLOT : KEEP_SLOT; }, - TypedSlotSet::PREFREE_EMPTY_CHUNKS); + TypedSlotSet::FREE_EMPTY_CHUNKS); } } @@ -234,9 +235,9 @@ class RememberedSet : public AllStatic { }); } - // Iterates and filters typed old to old pointers in the given memory chunk - // with the given callback. The callback should take (SlotType slot_type, - // Address addr) and return SlotCallbackResult. + // Iterates and filters typed pointers in the given memory chunk with the + // given callback. The callback should take (SlotType slot_type, Address addr) + // and return SlotCallbackResult. template <typename Callback> static void IterateTyped(MemoryChunk* chunk, Callback callback) { TypedSlotSet* slots = chunk->typed_slot_set<type>(); @@ -259,9 +260,6 @@ class RememberedSet : public AllStatic { chunk->ReleaseInvalidatedSlots<OLD_TO_OLD>(); } } - - private: - static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, ObjectSlot slot); }; class UpdateTypedSlotHelper { @@ -347,6 +345,46 @@ class UpdateTypedSlotHelper { } }; +class RememberedSetSweeping { + public: + template <AccessMode access_mode> + static void Insert(MemoryChunk* chunk, Address slot_addr) { + DCHECK(chunk->Contains(slot_addr)); + SlotSet* slot_set = chunk->sweeping_slot_set<access_mode>(); + if (slot_set == nullptr) { + slot_set = chunk->AllocateSweepingSlotSet(); + } + RememberedSetOperations::Insert<access_mode>(slot_set, chunk, slot_addr); + } + + static void Remove(MemoryChunk* chunk, Address slot_addr) { + DCHECK(chunk->Contains(slot_addr)); + SlotSet* slot_set = chunk->sweeping_slot_set<AccessMode::ATOMIC>(); + RememberedSetOperations::Remove(slot_set, chunk, slot_addr); + } + + // Given a page and a range of slots in that page, this function removes the + // slots from the remembered set. + static void RemoveRange(MemoryChunk* chunk, Address start, Address end, + SlotSet::EmptyBucketMode mode) { + SlotSet* slot_set = chunk->sweeping_slot_set(); + RememberedSetOperations::RemoveRange(slot_set, chunk, start, end, mode); + } + + // Iterates and filters the remembered set in the given memory chunk with + // the given callback. The callback should take (Address slot) and return + // SlotCallbackResult. + // + // Notice that |mode| can only be of FREE* or PREFREE* if there are no other + // threads concurrently inserting slots. + template <typename Callback> + static void Iterate(MemoryChunk* chunk, Callback callback, + SlotSet::EmptyBucketMode mode) { + SlotSet* slots = chunk->sweeping_slot_set(); + RememberedSetOperations::Iterate(slots, chunk, callback, mode); + } +}; + inline SlotType SlotTypeForRelocInfoMode(RelocInfo::Mode rmode) { if (RelocInfo::IsCodeTargetMode(rmode)) { return CODE_TARGET_SLOT; diff --git a/deps/v8/src/heap/scavenge-job.cc b/deps/v8/src/heap/scavenge-job.cc index 273866d5e4dca7..3730bfeecb6d34 100644 --- a/deps/v8/src/heap/scavenge-job.cc +++ b/deps/v8/src/heap/scavenge-job.cc @@ -108,7 +108,7 @@ void ScavengeJob::ScheduleIdleTask(Heap* heap) { v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap->isolate()); if (V8::GetCurrentPlatform()->IdleTasksEnabled(isolate)) { idle_task_pending_ = true; - auto task = base::make_unique<IdleTask>(heap->isolate(), this); + auto task = std::make_unique<IdleTask>(heap->isolate(), this); V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate)->PostIdleTask( std::move(task)); } diff --git a/deps/v8/src/heap/scavenger.cc b/deps/v8/src/heap/scavenger.cc index 7d56882953e6f5..47c19d4fcc1de5 100644 --- a/deps/v8/src/heap/scavenger.cc +++ b/deps/v8/src/heap/scavenger.cc @@ -153,8 +153,17 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor { if (result == KEEP_SLOT) { SLOW_DCHECK(target.IsHeapObject()); - RememberedSet<OLD_TO_NEW>::Insert(MemoryChunk::FromHeapObject(host), - slot.address()); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(host); + + // Sweeper is stopped during scavenge, so we can directly + // insert into its remembered set here. + if (chunk->sweeping_slot_set()) { + RememberedSetSweeping::Insert<AccessMode::ATOMIC>(chunk, + slot.address()); + } else { + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(chunk, + slot.address()); + } } SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate( HeapObject::cast(target))); @@ -165,8 +174,8 @@ class IterateAndScavengePromotedObjectsVisitor final : public ObjectVisitor { // We cannot call MarkCompactCollector::RecordSlot because that checks // that the host page is not in young generation, which does not hold // for pending large pages. - RememberedSet<OLD_TO_OLD>::Insert(MemoryChunk::FromHeapObject(host), - slot.address()); + RememberedSet<OLD_TO_OLD>::Insert<AccessMode::ATOMIC>( + MemoryChunk::FromHeapObject(host), slot.address()); } } @@ -239,8 +248,10 @@ void ScavengerCollector::CollectGarbage() { // access to the slots of a page and can completely avoid any locks on // the page itself. Sweeper::FilterSweepingPagesScope filter_scope(sweeper, pause_scope); - filter_scope.FilterOldSpaceSweepingPages( - [](Page* page) { return !page->ContainsSlots<OLD_TO_NEW>(); }); + filter_scope.FilterOldSpaceSweepingPages([](Page* page) { + return !page->ContainsSlots<OLD_TO_NEW>() && !page->sweeping_slot_set(); + }); + RememberedSet<OLD_TO_NEW>::IterateMemoryChunks( heap_, [&job](MemoryChunk* chunk) { job.AddItem(new PageScavengingItem(chunk)); @@ -335,11 +346,7 @@ void ScavengerCollector::CollectGarbage() { heap_->new_lo_space()->FreeDeadObjects([](HeapObject) { return true; }); RememberedSet<OLD_TO_NEW>::IterateMemoryChunks(heap_, [](MemoryChunk* chunk) { - if (chunk->SweepingDone()) { - RememberedSet<OLD_TO_NEW>::FreeEmptyBuckets(chunk); - } else { - RememberedSet<OLD_TO_NEW>::PreFreeEmptyBuckets(chunk); - } + RememberedSet<OLD_TO_NEW>::FreeEmptyBuckets(chunk); }); // Update how much has survived scavenge. @@ -430,16 +437,45 @@ void Scavenger::AddPageToSweeperIfNecessary(MemoryChunk* page) { } } +// Remove this crashkey after chromium:1010312 is fixed. +class ScopedFullHeapCrashKey { + public: + explicit ScopedFullHeapCrashKey(Isolate* isolate) : isolate_(isolate) { + isolate_->AddCrashKey(v8::CrashKeyId::kDumpType, "heap"); + } + ~ScopedFullHeapCrashKey() { + isolate_->AddCrashKey(v8::CrashKeyId::kDumpType, ""); + } + + private: + Isolate* isolate_ = nullptr; +}; + void Scavenger::ScavengePage(MemoryChunk* page) { + ScopedFullHeapCrashKey collect_full_heap_dump_if_crash(heap_->isolate()); CodePageMemoryModificationScope memory_modification_scope(page); + InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToNew(page); RememberedSet<OLD_TO_NEW>::Iterate( page, - [this](MaybeObjectSlot addr) { - return CheckAndScavengeObject(heap_, addr); + [this, &filter](MaybeObjectSlot slot) { + if (!filter.IsValid(slot.address())) return REMOVE_SLOT; + return CheckAndScavengeObject(heap_, slot); + }, + SlotSet::KEEP_EMPTY_BUCKETS); + filter = InvalidatedSlotsFilter::OldToNew(page); + RememberedSetSweeping::Iterate( + page, + [this, &filter](MaybeObjectSlot slot) { + if (!filter.IsValid(slot.address())) return REMOVE_SLOT; + return CheckAndScavengeObject(heap_, slot); }, SlotSet::KEEP_EMPTY_BUCKETS); - DCHECK_NULL(page->invalidated_slots<OLD_TO_NEW>()); + if (page->invalidated_slots<OLD_TO_NEW>() != nullptr) { + // The invalidated slots are not needed after old-to-new slots were + // processed. + page->ReleaseInvalidatedSlots<OLD_TO_NEW>(); + } RememberedSet<OLD_TO_NEW>::IterateTyped( page, [=](SlotType type, Address addr) { diff --git a/deps/v8/src/heap/setup-heap-internal.cc b/deps/v8/src/heap/setup-heap-internal.cc index 15ca6d7930383a..9f94029af374ab 100644 --- a/deps/v8/src/heap/setup-heap-internal.cc +++ b/deps/v8/src/heap/setup-heap-internal.cc @@ -7,6 +7,7 @@ #include "src/builtins/accessors.h" #include "src/codegen/compilation-cache.h" #include "src/execution/isolate.h" +#include "src/execution/protectors.h" #include "src/heap/factory.h" #include "src/heap/heap-inl.h" #include "src/ic/handler-configuration.h" @@ -616,17 +617,17 @@ void Heap::CreateInitialObjects() { // The -0 value must be set before NewNumber works. set_minus_zero_value( - *factory->NewHeapNumber(-0.0, AllocationType::kReadOnly)); + *factory->NewHeapNumber<AllocationType::kReadOnly>(-0.0)); DCHECK(std::signbit(roots.minus_zero_value().Number())); - set_nan_value(*factory->NewHeapNumber( - std::numeric_limits<double>::quiet_NaN(), AllocationType::kReadOnly)); - set_hole_nan_value(*factory->NewHeapNumberFromBits( - kHoleNanInt64, AllocationType::kReadOnly)); + set_nan_value(*factory->NewHeapNumber<AllocationType::kReadOnly>( + std::numeric_limits<double>::quiet_NaN())); + set_hole_nan_value(*factory->NewHeapNumberFromBits<AllocationType::kReadOnly>( + kHoleNanInt64)); set_infinity_value( - *factory->NewHeapNumber(V8_INFINITY, AllocationType::kReadOnly)); + *factory->NewHeapNumber<AllocationType::kReadOnly>(V8_INFINITY)); set_minus_infinity_value( - *factory->NewHeapNumber(-V8_INFINITY, AllocationType::kReadOnly)); + *factory->NewHeapNumber<AllocationType::kReadOnly>(-V8_INFINITY)); set_hash_seed(*factory->NewByteArray(kInt64Size, AllocationType::kReadOnly)); InitializeHashSeed(); @@ -704,8 +705,7 @@ void Heap::CreateInitialObjects() { Oddball::kStaleRegister)); // Initialize the self-reference marker. - set_self_reference_marker( - *factory->NewSelfReferenceMarker(AllocationType::kReadOnly)); + set_self_reference_marker(*factory->NewSelfReferenceMarker()); set_interpreter_entry_trampoline_for_profiling(roots.undefined_value()); @@ -781,13 +781,13 @@ void Heap::CreateInitialObjects() { set_feedback_vectors_for_profiling_tools(roots.undefined_value()); set_pending_optimize_for_test_bytecode(roots.undefined_value()); + set_shared_wasm_memories(roots.empty_weak_array_list()); set_script_list(roots.empty_weak_array_list()); Handle<NumberDictionary> slow_element_dictionary = NumberDictionary::New( isolate(), 1, AllocationType::kReadOnly, USE_CUSTOM_MINIMUM_CAPACITY); DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1)); - slow_element_dictionary->set_requires_slow_elements(); set_empty_slow_element_dictionary(*slow_element_dictionary); set_materialized_objects(*factory->NewFixedArray(0, AllocationType::kOld)); @@ -839,76 +839,122 @@ void Heap::CreateInitialObjects() { script->set_origin_options(ScriptOriginOptions(true, false)); set_empty_script(*script); - Handle<Cell> array_constructor_cell = factory->NewCell( - handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); - set_array_constructor_protector(*array_constructor_cell); + { + Handle<PropertyCell> cell = factory->NewPropertyCell( + factory->empty_string(), AllocationType::kReadOnly); + cell->set_value(roots.the_hole_value()); + set_empty_property_cell(*cell); + } - Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_no_elements_protector(*cell); + // Protectors + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_array_constructor_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string(), - AllocationType::kReadOnly); - cell->set_value(roots.the_hole_value()); - set_empty_property_cell(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_no_elements_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_array_iterator_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_array_iterator_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_map_iterator_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_map_iterator_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_set_iterator_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_set_iterator_protector(*cell); + } - Handle<Cell> is_concat_spreadable_cell = factory->NewCell( - handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); - set_is_concat_spreadable_protector(*is_concat_spreadable_cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_is_concat_spreadable_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_array_species_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_array_species_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_typed_array_species_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_typed_array_species_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_promise_species_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_promise_species_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_string_iterator_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_string_iterator_protector(*cell); + } - Handle<Cell> string_length_overflow_cell = factory->NewCell( - handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); - set_string_length_protector(*string_length_overflow_cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_string_length_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_array_buffer_detaching_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_array_buffer_detaching_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_promise_hook_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_promise_hook_protector(*cell); + } - Handle<Cell> promise_resolve_cell = factory->NewCell( - handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); - set_promise_resolve_protector(*promise_resolve_cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_promise_resolve_protector(*cell); + } - cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); - set_promise_then_protector(*cell); + { + Handle<PropertyCell> cell = + factory->NewPropertyCell(factory->empty_string()); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); + set_promise_then_protector(*cell); + } set_serialized_objects(roots.empty_fixed_array()); set_serialized_global_proxy_sizes(roots.empty_fixed_array()); - set_noscript_shared_function_infos(roots.empty_weak_array_list()); - /* Canonical off-heap trampoline data */ set_off_heap_trampoline_relocation_info( *Builtins::GenerateOffHeapTrampolineRelocInfo(isolate_)); diff --git a/deps/v8/src/heap/slot-set.cc b/deps/v8/src/heap/slot-set.cc index 12cf6bab5afd7f..92540574a0b1d0 100644 --- a/deps/v8/src/heap/slot-set.cc +++ b/deps/v8/src/heap/slot-set.cc @@ -11,7 +11,6 @@ TypedSlots::~TypedSlots() { Chunk* chunk = head_; while (chunk != nullptr) { Chunk* next = chunk->next; - delete[] chunk->buffer; delete chunk; chunk = next; } @@ -22,9 +21,8 @@ TypedSlots::~TypedSlots() { void TypedSlots::Insert(SlotType type, uint32_t offset) { TypedSlot slot = {TypeField::encode(type) | OffsetField::encode(offset)}; Chunk* chunk = EnsureChunk(); - DCHECK_LT(chunk->count, chunk->capacity); - chunk->buffer[chunk->count] = slot; - ++chunk->count; + DCHECK_LT(chunk->buffer.size(), chunk->buffer.capacity()); + chunk->buffer.push_back(slot); } void TypedSlots::Merge(TypedSlots* other) { @@ -46,37 +44,25 @@ TypedSlots::Chunk* TypedSlots::EnsureChunk() { if (!head_) { head_ = tail_ = NewChunk(nullptr, kInitialBufferSize); } - if (head_->count == head_->capacity) { - head_ = NewChunk(head_, NextCapacity(head_->capacity)); + if (head_->buffer.size() == head_->buffer.capacity()) { + head_ = NewChunk(head_, NextCapacity(head_->buffer.capacity())); } return head_; } -TypedSlots::Chunk* TypedSlots::NewChunk(Chunk* next, int capacity) { +TypedSlots::Chunk* TypedSlots::NewChunk(Chunk* next, size_t capacity) { Chunk* chunk = new Chunk; chunk->next = next; - chunk->buffer = new TypedSlot[capacity]; - chunk->capacity = capacity; - chunk->count = 0; + chunk->buffer.reserve(capacity); + DCHECK_EQ(chunk->buffer.capacity(), capacity); return chunk; } -TypedSlotSet::~TypedSlotSet() { FreeToBeFreedChunks(); } - -void TypedSlotSet::FreeToBeFreedChunks() { - base::MutexGuard guard(&to_be_freed_chunks_mutex_); - std::stack<std::unique_ptr<Chunk>> empty; - to_be_freed_chunks_.swap(empty); -} - void TypedSlotSet::ClearInvalidSlots( const std::map<uint32_t, uint32_t>& invalid_ranges) { Chunk* chunk = LoadHead(); while (chunk != nullptr) { - TypedSlot* buffer = chunk->buffer; - int count = chunk->count; - for (int i = 0; i < count; i++) { - TypedSlot slot = LoadTypedSlot(buffer + i); + for (TypedSlot& slot : chunk->buffer) { SlotType type = TypeField::decode(slot.type_and_offset); if (type == CLEARED_SLOT) continue; uint32_t offset = OffsetField::decode(slot.type_and_offset); @@ -88,7 +74,7 @@ void TypedSlotSet::ClearInvalidSlots( upper_bound--; DCHECK_LE(upper_bound->first, offset); if (upper_bound->second > offset) { - ClearTypedSlot(buffer + i); + slot = ClearedTypedSlot(); } } chunk = LoadNext(chunk); diff --git a/deps/v8/src/heap/slot-set.h b/deps/v8/src/heap/slot-set.h index c71192bfdceec1..b1321b6fcaafe5 100644 --- a/deps/v8/src/heap/slot-set.h +++ b/deps/v8/src/heap/slot-set.h @@ -6,6 +6,7 @@ #define V8_HEAP_SLOT_SET_H_ #include <map> +#include <memory> #include <stack> #include "src/base/atomic-utils.h" @@ -21,19 +22,15 @@ namespace internal { enum SlotCallbackResult { KEEP_SLOT, REMOVE_SLOT }; // Data structure for maintaining a set of slots in a standard (non-large) -// page. The base address of the page must be set with SetPageStart before any -// operation. +// page. // The data structure assumes that the slots are pointer size aligned and // splits the valid slot offset range into kBuckets buckets. // Each bucket is a bitmap with a bit corresponding to a single slot offset. class SlotSet : public Malloced { public: enum EmptyBucketMode { - FREE_EMPTY_BUCKETS, // An empty bucket will be deallocated immediately. - PREFREE_EMPTY_BUCKETS, // An empty bucket will be unlinked from the slot - // set, but deallocated on demand by a sweeper - // thread. - KEEP_EMPTY_BUCKETS // An empty bucket will be kept. + FREE_EMPTY_BUCKETS, // An empty bucket will be deallocated immediately. + KEEP_EMPTY_BUCKETS // An empty bucket will be kept. }; SlotSet() { @@ -46,15 +43,12 @@ class SlotSet : public Malloced { for (int i = 0; i < kBuckets; i++) { ReleaseBucket(i); } - FreeToBeFreedBuckets(); } - void SetPageStart(Address page_start) { page_start_ = page_start; } - // The slot offset specifies a slot at address page_start_ + slot_offset. // AccessMode defines whether there can be concurrent access on the buckets // or not. - template <AccessMode access_mode = AccessMode::ATOMIC> + template <AccessMode access_mode> void Insert(int slot_offset) { int bucket_index, cell_index, bit_index; SlotToIndices(slot_offset, &bucket_index, &cell_index, &bit_index); @@ -138,9 +132,7 @@ class SlotSet : public Malloced { DCHECK(current_bucket == end_bucket || (current_bucket < end_bucket && current_cell == 0)); while (current_bucket < end_bucket) { - if (mode == PREFREE_EMPTY_BUCKETS) { - PreFreeEmptyBucket(current_bucket); - } else if (mode == FREE_EMPTY_BUCKETS) { + if (mode == FREE_EMPTY_BUCKETS) { ReleaseBucket(current_bucket); } else { DCHECK(mode == KEEP_EMPTY_BUCKETS); @@ -152,11 +144,11 @@ class SlotSet : public Malloced { current_bucket++; } // All buckets between start_bucket and end_bucket are cleared. + DCHECK(current_bucket == end_bucket); + if (current_bucket == kBuckets) return; bucket = LoadBucket(&buckets_[current_bucket]); - DCHECK(current_bucket == end_bucket && current_cell <= end_cell); - if (current_bucket == kBuckets || bucket == nullptr) { - return; - } + DCHECK(current_cell <= end_cell); + if (bucket == nullptr) return; while (current_cell < end_cell) { StoreCell(&bucket[current_cell], 0); current_cell++; @@ -189,7 +181,7 @@ class SlotSet : public Malloced { // else return REMOVE_SLOT; // }); template <typename Callback> - int Iterate(Callback callback, EmptyBucketMode mode) { + int Iterate(Address page_start, Callback callback, EmptyBucketMode mode) { int new_count = 0; for (int bucket_index = 0; bucket_index < kBuckets; bucket_index++) { Bucket bucket = LoadBucket(&buckets_[bucket_index]); @@ -205,7 +197,7 @@ class SlotSet : public Malloced { int bit_offset = base::bits::CountTrailingZeros(cell); uint32_t bit_mask = 1u << bit_offset; uint32_t slot = (cell_offset + bit_offset) << kTaggedSizeLog2; - if (callback(MaybeObjectSlot(page_start_ + slot)) == KEEP_SLOT) { + if (callback(MaybeObjectSlot(page_start + slot)) == KEEP_SLOT) { ++in_bucket_count; } else { mask |= bit_mask; @@ -218,31 +210,12 @@ class SlotSet : public Malloced { } } } - if (mode == PREFREE_EMPTY_BUCKETS && in_bucket_count == 0) { - PreFreeEmptyBucket(bucket_index); - } new_count += in_bucket_count; } } return new_count; } - int NumberOfPreFreedEmptyBuckets() { - base::MutexGuard guard(&to_be_freed_buckets_mutex_); - return static_cast<int>(to_be_freed_buckets_.size()); - } - - void PreFreeEmptyBuckets() { - for (int bucket_index = 0; bucket_index < kBuckets; bucket_index++) { - Bucket bucket = LoadBucket(&buckets_[bucket_index]); - if (bucket != nullptr) { - if (IsEmptyBucket(bucket)) { - PreFreeEmptyBucket(bucket_index); - } - } - } - } - void FreeEmptyBuckets() { for (int bucket_index = 0; bucket_index < kBuckets; bucket_index++) { Bucket bucket = LoadBucket(&buckets_[bucket_index]); @@ -254,27 +227,22 @@ class SlotSet : public Malloced { } } - void FreeToBeFreedBuckets() { - base::MutexGuard guard(&to_be_freed_buckets_mutex_); - while (!to_be_freed_buckets_.empty()) { - Bucket top = to_be_freed_buckets_.top(); - to_be_freed_buckets_.pop(); - DeleteArray<uint32_t>(top); - } - DCHECK_EQ(0u, to_be_freed_buckets_.size()); - } - - private: - using Bucket = uint32_t*; static const int kMaxSlots = (1 << kPageSizeBits) / kTaggedSize; static const int kCellsPerBucket = 32; static const int kCellsPerBucketLog2 = 5; + static const int kCellSizeBytesLog2 = 2; + static const int kCellSizeBytes = 1 << kCellSizeBytesLog2; static const int kBitsPerCell = 32; static const int kBitsPerCellLog2 = 5; static const int kBitsPerBucket = kCellsPerBucket * kBitsPerCell; static const int kBitsPerBucketLog2 = kCellsPerBucketLog2 + kBitsPerCellLog2; static const int kBuckets = kMaxSlots / kCellsPerBucket / kBitsPerCell; + static const int kSize = kBuckets * kSystemPointerSize; + + using Bucket = uint32_t*; + + private: Bucket AllocateBucket() { Bucket result = NewArray<uint32_t>(kCellsPerBucket); for (int i = 0; i < kCellsPerBucket; i++) { @@ -293,15 +261,6 @@ class SlotSet : public Malloced { } } - void PreFreeEmptyBucket(int bucket_index) { - Bucket bucket = LoadBucket(&buckets_[bucket_index]); - if (bucket != nullptr) { - base::MutexGuard guard(&to_be_freed_buckets_mutex_); - to_be_freed_buckets_.push(bucket); - StoreBucket(&buckets_[bucket_index], nullptr); - } - } - void ReleaseBucket(int bucket_index) { Bucket bucket = LoadBucket(&buckets_[bucket_index]); StoreBucket(&buckets_[bucket_index], nullptr); @@ -381,11 +340,11 @@ class SlotSet : public Malloced { } Bucket buckets_[kBuckets]; - Address page_start_; - base::Mutex to_be_freed_buckets_mutex_; - std::stack<uint32_t*> to_be_freed_buckets_; }; +STATIC_ASSERT(std::is_standard_layout<SlotSet>::value); +STATIC_ASSERT(sizeof(SlotSet) == SlotSet::kSize); + enum SlotType { FULL_EMBEDDED_OBJECT_SLOT, COMPRESSED_EMBEDDED_OBJECT_SLOT, @@ -396,9 +355,9 @@ enum SlotType { }; // Data structure for maintaining a list of typed slots in a page. -// Typed slots can only appear in Code and JSFunction objects, so +// Typed slots can only appear in Code objects, so // the maximum possible offset is limited by the LargePage::kMaxCodePageSize. -// The implementation is a chain of chunks, where each chunks is an array of +// The implementation is a chain of chunks, where each chunk is an array of // encoded (slot type, slot offset) pairs. // There is no duplicate detection and we do not expect many duplicates because // typed slots contain V8 internal pointers that are not directly exposed to JS. @@ -418,17 +377,15 @@ class V8_EXPORT_PRIVATE TypedSlots { }; struct Chunk { Chunk* next; - TypedSlot* buffer; - int32_t capacity; - int32_t count; + std::vector<TypedSlot> buffer; }; - static const int kInitialBufferSize = 100; - static const int kMaxBufferSize = 16 * KB; - static int NextCapacity(int capacity) { + static const size_t kInitialBufferSize = 100; + static const size_t kMaxBufferSize = 16 * KB; + static size_t NextCapacity(size_t capacity) { return Min(kMaxBufferSize, capacity * 2); } Chunk* EnsureChunk(); - Chunk* NewChunk(Chunk* next, int capacity); + Chunk* NewChunk(Chunk* next, size_t capacity); Chunk* head_ = nullptr; Chunk* tail_ = nullptr; }; @@ -437,15 +394,10 @@ class V8_EXPORT_PRIVATE TypedSlots { // clearing of invalid slots. class V8_EXPORT_PRIVATE TypedSlotSet : public TypedSlots { public: - // The PREFREE_EMPTY_CHUNKS indicates that chunks detected as empty - // during the iteration are queued in to_be_freed_chunks_, which are - // then freed in FreeToBeFreedChunks. - enum IterationMode { PREFREE_EMPTY_CHUNKS, KEEP_EMPTY_CHUNKS }; + enum IterationMode { FREE_EMPTY_CHUNKS, KEEP_EMPTY_CHUNKS }; explicit TypedSlotSet(Address page_start) : page_start_(page_start) {} - ~TypedSlotSet() override; - // Iterate over all slots in the set and for each slot invoke the callback. // If the callback returns REMOVE_SLOT then the slot is removed from the set. // Returns the new number of slots. @@ -463,11 +415,8 @@ class V8_EXPORT_PRIVATE TypedSlotSet : public TypedSlots { Chunk* previous = nullptr; int new_count = 0; while (chunk != nullptr) { - TypedSlot* buffer = chunk->buffer; - int count = chunk->count; bool empty = true; - for (int i = 0; i < count; i++) { - TypedSlot slot = LoadTypedSlot(buffer + i); + for (TypedSlot& slot : chunk->buffer) { SlotType type = TypeField::decode(slot.type_and_offset); if (type != CLEARED_SLOT) { uint32_t offset = OffsetField::decode(slot.type_and_offset); @@ -476,12 +425,12 @@ class V8_EXPORT_PRIVATE TypedSlotSet : public TypedSlots { new_count++; empty = false; } else { - ClearTypedSlot(buffer + i); + slot = ClearedTypedSlot(); } } } Chunk* next = chunk->next; - if (mode == PREFREE_EMPTY_CHUNKS && empty) { + if (mode == FREE_EMPTY_CHUNKS && empty) { // We remove the chunk from the list but let it still point its next // chunk to allow concurrent iteration. if (previous) { @@ -489,8 +438,8 @@ class V8_EXPORT_PRIVATE TypedSlotSet : public TypedSlots { } else { StoreHead(next); } - base::MutexGuard guard(&to_be_freed_chunks_mutex_); - to_be_freed_chunks_.push(std::unique_ptr<Chunk>(chunk)); + + delete chunk; } else { previous = chunk; } @@ -518,19 +467,11 @@ class V8_EXPORT_PRIVATE TypedSlotSet : public TypedSlots { void StoreHead(Chunk* chunk) { base::AsAtomicPointer::Relaxed_Store(&head_, chunk); } - TypedSlot LoadTypedSlot(TypedSlot* slot) { - return TypedSlot{base::AsAtomic32::Relaxed_Load(&slot->type_and_offset)}; - } - void ClearTypedSlot(TypedSlot* slot) { - // Order is important here and should match that of LoadTypedSlot. - base::AsAtomic32::Relaxed_Store( - &slot->type_and_offset, - TypeField::encode(CLEARED_SLOT) | OffsetField::encode(0)); + static TypedSlot ClearedTypedSlot() { + return TypedSlot{TypeField::encode(CLEARED_SLOT) | OffsetField::encode(0)}; } Address page_start_; - base::Mutex to_be_freed_chunks_mutex_; - std::stack<std::unique_ptr<Chunk>> to_be_freed_chunks_; }; } // namespace internal diff --git a/deps/v8/src/heap/spaces.cc b/deps/v8/src/heap/spaces.cc index dd8ba301018c5b..2c5d5c298da3f8 100644 --- a/deps/v8/src/heap/spaces.cc +++ b/deps/v8/src/heap/spaces.cc @@ -11,14 +11,14 @@ #include "src/base/lsan.h" #include "src/base/macros.h" #include "src/base/platform/semaphore.h" -#include "src/base/template-utils.h" #include "src/execution/vm-state-inl.h" -#include "src/heap/array-buffer-tracker.h" +#include "src/heap/array-buffer-tracker-inl.h" #include "src/heap/combined-heap.h" #include "src/heap/concurrent-marking.h" #include "src/heap/gc-tracer.h" #include "src/heap/heap-controller.h" #include "src/heap/incremental-marking-inl.h" +#include "src/heap/invalidated-slots-inl.h" #include "src/heap/mark-compact.h" #include "src/heap/read-only-heap.h" #include "src/heap/remembered-set.h" @@ -220,7 +220,7 @@ void MemoryAllocator::InitializeCodePageAllocator( requested)); heap_reservation_ = std::move(reservation); - code_page_allocator_instance_ = base::make_unique<base::BoundedPageAllocator>( + code_page_allocator_instance_ = std::make_unique<base::BoundedPageAllocator>( page_allocator, aligned_base, size, static_cast<size_t>(MemoryChunk::kAlignment)); code_page_allocator_ = code_page_allocator_instance_.get(); @@ -286,7 +286,7 @@ void MemoryAllocator::Unmapper::FreeQueuedChunks() { } return; } - auto task = base::make_unique<UnmapFreeMemoryTask>(heap_->isolate(), this); + auto task = std::make_unique<UnmapFreeMemoryTask>(heap_->isolate(), this); if (FLAG_trace_unmapper) { PrintIsolate(heap_->isolate(), "Unmapper::FreeQueuedChunks: new task id=%" PRIu64 "\n", @@ -699,6 +699,7 @@ MemoryChunk* MemoryChunk::Initialize(Heap* heap, Address base, size_t size, chunk->InitializeReservedMemory(); base::AsAtomicPointer::Release_Store(&chunk->slot_set_[OLD_TO_NEW], nullptr); base::AsAtomicPointer::Release_Store(&chunk->slot_set_[OLD_TO_OLD], nullptr); + base::AsAtomicPointer::Release_Store(&chunk->sweeping_slot_set_, nullptr); base::AsAtomicPointer::Release_Store(&chunk->typed_slot_set_[OLD_TO_NEW], nullptr); base::AsAtomicPointer::Release_Store(&chunk->typed_slot_set_[OLD_TO_OLD], @@ -856,6 +857,33 @@ Page* Page::ConvertNewToOld(Page* old_page) { return new_page; } +void Page::MoveOldToNewRememberedSetForSweeping() { + CHECK_NULL(sweeping_slot_set_); + sweeping_slot_set_ = slot_set_[OLD_TO_NEW]; + slot_set_[OLD_TO_NEW] = nullptr; +} + +void Page::MergeOldToNewRememberedSets() { + if (sweeping_slot_set_ == nullptr) return; + + RememberedSet<OLD_TO_NEW>::Iterate( + this, + [this](MaybeObjectSlot slot) { + Address address = slot.address(); + RememberedSetSweeping::Insert<AccessMode::NON_ATOMIC>(this, address); + return KEEP_SLOT; + }, + SlotSet::KEEP_EMPTY_BUCKETS); + + if (slot_set_[OLD_TO_NEW]) { + ReleaseSlotSet<OLD_TO_NEW>(); + } + + CHECK_NULL(slot_set_[OLD_TO_NEW]); + slot_set_[OLD_TO_NEW] = sweeping_slot_set_; + sweeping_slot_set_ = nullptr; +} + size_t MemoryChunk::CommittedPhysicalMemory() { if (!base::OS::HasLazyCommits() || owner_identity() == LO_SPACE) return size(); @@ -1376,6 +1404,7 @@ void MemoryChunk::ReleaseAllocatedMemoryNeededForWritableChunk() { } ReleaseSlotSet<OLD_TO_NEW>(); + ReleaseSlotSet(&sweeping_slot_set_); ReleaseSlotSet<OLD_TO_OLD>(); ReleaseTypedSlotSet<OLD_TO_NEW>(); ReleaseTypedSlotSet<OLD_TO_OLD>(); @@ -1399,11 +1428,7 @@ void MemoryChunk::ReleaseAllAllocatedMemory() { static SlotSet* AllocateAndInitializeSlotSet(size_t size, Address page_start) { size_t pages = (size + Page::kPageSize - 1) / Page::kPageSize; DCHECK_LT(0, pages); - SlotSet* slot_set = new SlotSet[pages]; - for (size_t i = 0; i < pages; i++) { - slot_set[i].SetPageStart(page_start + i * Page::kPageSize); - } - return slot_set; + return new SlotSet[pages]; } template V8_EXPORT_PRIVATE SlotSet* MemoryChunk::AllocateSlotSet<OLD_TO_NEW>(); @@ -1411,15 +1436,23 @@ template V8_EXPORT_PRIVATE SlotSet* MemoryChunk::AllocateSlotSet<OLD_TO_OLD>(); template <RememberedSetType type> SlotSet* MemoryChunk::AllocateSlotSet() { - SlotSet* slot_set = AllocateAndInitializeSlotSet(size(), address()); + return AllocateSlotSet(&slot_set_[type]); +} + +SlotSet* MemoryChunk::AllocateSweepingSlotSet() { + return AllocateSlotSet(&sweeping_slot_set_); +} + +SlotSet* MemoryChunk::AllocateSlotSet(SlotSet** slot_set) { + SlotSet* new_slot_set = AllocateAndInitializeSlotSet(size(), address()); SlotSet* old_slot_set = base::AsAtomicPointer::Release_CompareAndSwap( - &slot_set_[type], nullptr, slot_set); + slot_set, nullptr, new_slot_set); if (old_slot_set != nullptr) { - delete[] slot_set; - slot_set = old_slot_set; + delete[] new_slot_set; + new_slot_set = old_slot_set; } - DCHECK(slot_set); - return slot_set; + DCHECK(new_slot_set); + return new_slot_set; } template void MemoryChunk::ReleaseSlotSet<OLD_TO_NEW>(); @@ -1427,10 +1460,13 @@ template void MemoryChunk::ReleaseSlotSet<OLD_TO_OLD>(); template <RememberedSetType type> void MemoryChunk::ReleaseSlotSet() { - SlotSet* slot_set = slot_set_[type]; - if (slot_set) { - slot_set_[type] = nullptr; - delete[] slot_set; + ReleaseSlotSet(&slot_set_[type]); +} + +void MemoryChunk::ReleaseSlotSet(SlotSet** slot_set) { + if (*slot_set) { + delete[] * slot_set; + *slot_set = nullptr; } } @@ -1484,15 +1520,12 @@ void MemoryChunk::ReleaseInvalidatedSlots() { } template V8_EXPORT_PRIVATE void -MemoryChunk::RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(HeapObject object, - int size); +MemoryChunk::RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(HeapObject object); template V8_EXPORT_PRIVATE void -MemoryChunk::RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(HeapObject object, - int size); +MemoryChunk::RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(HeapObject object); template <RememberedSetType type> -void MemoryChunk::RegisterObjectWithInvalidatedSlots(HeapObject object, - int size) { +void MemoryChunk::RegisterObjectWithInvalidatedSlots(HeapObject object) { bool skip_slot_recording; if (type == OLD_TO_NEW) { @@ -1509,27 +1542,17 @@ void MemoryChunk::RegisterObjectWithInvalidatedSlots(HeapObject object, AllocateInvalidatedSlots<type>(); } - InvalidatedSlots* invalidated_slots = this->invalidated_slots<type>(); - InvalidatedSlots::iterator it = invalidated_slots->lower_bound(object); + invalidated_slots<type>()->insert(object); +} - if (it != invalidated_slots->end() && it->first == object) { - // object was already inserted - CHECK_LE(size, it->second); - return; +void MemoryChunk::InvalidateRecordedSlots(HeapObject object) { + if (heap()->incremental_marking()->IsCompacting()) { + // We cannot check slot_set_[OLD_TO_OLD] here, since the + // concurrent markers might insert slots concurrently. + RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(object); } - it = invalidated_slots->insert(it, std::make_pair(object, size)); - - // prevent overlapping invalidated objects for old-to-new. - if (type == OLD_TO_NEW && it != invalidated_slots->begin()) { - HeapObject pred = (--it)->first; - int pred_size = it->second; - DCHECK_LT(pred.address(), object.address()); - - if (pred.address() + pred_size > object.address()) { - it->second = static_cast<int>(object.address() - pred.address()); - } - } + RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(object); } template bool MemoryChunk::RegisteredObjectWithInvalidatedSlots<OLD_TO_NEW>( @@ -1546,27 +1569,6 @@ bool MemoryChunk::RegisteredObjectWithInvalidatedSlots(HeapObject object) { invalidated_slots<type>()->end(); } -template void MemoryChunk::MoveObjectWithInvalidatedSlots<OLD_TO_OLD>( - HeapObject old_start, HeapObject new_start); - -template <RememberedSetType type> -void MemoryChunk::MoveObjectWithInvalidatedSlots(HeapObject old_start, - HeapObject new_start) { - DCHECK_LT(old_start, new_start); - DCHECK_EQ(MemoryChunk::FromHeapObject(old_start), - MemoryChunk::FromHeapObject(new_start)); - static_assert(type == OLD_TO_OLD, "only use this for old-to-old slots"); - if (!ShouldSkipEvacuationSlotRecording() && invalidated_slots<type>()) { - auto it = invalidated_slots<type>()->find(old_start); - if (it != invalidated_slots<type>()->end()) { - int old_size = it->second; - int delta = static_cast<int>(new_start.address() - old_start.address()); - invalidated_slots<type>()->erase(it); - (*invalidated_slots<type>())[new_start] = old_size - delta; - } - } -} - void MemoryChunk::ReleaseLocalTracker() { DCHECK_NOT_NULL(local_tracker_); delete local_tracker_; @@ -1657,6 +1659,7 @@ void PagedSpace::RefillFreeList() { DCHECK(!IsDetached()); MarkCompactCollector* collector = heap()->mark_compact_collector(); size_t added = 0; + { Page* p = nullptr; while ((p = collector->sweeper()->GetSweptPageSafe(this)) != nullptr) { @@ -1667,6 +1670,15 @@ void PagedSpace::RefillFreeList() { category->Reset(free_list()); }); } + + // Also merge old-to-new remembered sets outside of collections. + // Do not do this during GC, because of races during scavenges. + // One thread might iterate remembered set, while another thread merges + // them. + if (!is_local()) { + p->MergeOldToNewRememberedSets(); + } + // Only during compaction pages can actually change ownership. This is // safe because there exists no other competing action on the page links // during compaction. @@ -1709,6 +1721,9 @@ void PagedSpace::MergeCompactionSpace(CompactionSpace* other) { // Move over pages. for (auto it = other->begin(); it != other->end();) { Page* p = *(it++); + + p->MergeOldToNewRememberedSets(); + // Relinking requires the category to be unlinked. other->RemovePage(p); AddPage(p); @@ -1883,19 +1898,8 @@ Address SpaceWithLinearArea::ComputeLimit(Address start, Address end, // Generated code may allocate inline from the linear allocation area for. // To make sure we can observe these allocations, we use a lower limit. size_t step = GetNextInlineAllocationStepSize(); - - // TODO(ofrobots): there is subtle difference between old space and new - // space here. Any way to avoid it? `step - 1` makes more sense as we would - // like to sample the object that straddles the `start + step` boundary. - // Rounding down further would introduce a small statistical error in - // sampling. However, presently PagedSpace requires limit to be aligned. - size_t rounded_step; - if (identity() == NEW_SPACE) { - DCHECK_GE(step, 1); - rounded_step = step - 1; - } else { - rounded_step = RoundSizeDownToObjectAlignment(static_cast<int>(step)); - } + size_t rounded_step = + RoundSizeDownToObjectAlignment(static_cast<int>(step - 1)); return Min(static_cast<Address>(start + min_size + rounded_step), end); } else { // The entire node can be used as the linear allocation area. @@ -2139,7 +2143,7 @@ void PagedSpace::Verify(Isolate* isolate, ObjectVisitor* visitor) { } else if (object.IsJSArrayBuffer()) { JSArrayBuffer array_buffer = JSArrayBuffer::cast(object); if (ArrayBufferTracker::IsTracked(array_buffer)) { - size_t size = array_buffer.byte_length(); + size_t size = PerIsolateAccountingLength(array_buffer); external_page_bytes[ExternalBackingStoreType::kArrayBuffer] += size; } } @@ -2628,7 +2632,7 @@ void NewSpace::Verify(Isolate* isolate) { } else if (object.IsJSArrayBuffer()) { JSArrayBuffer array_buffer = JSArrayBuffer::cast(object); if (ArrayBufferTracker::IsTracked(array_buffer)) { - size_t size = array_buffer.byte_length(); + size_t size = PerIsolateAccountingLength(array_buffer); external_space_bytes[ExternalBackingStoreType::kArrayBuffer] += size; } } @@ -3942,6 +3946,7 @@ Address LargePage::GetAddressToShrink(Address object_address, } void LargePage::ClearOutOfLiveRangeSlots(Address free_start) { + DCHECK_NULL(this->sweeping_slot_set()); RememberedSet<OLD_TO_NEW>::RemoveRange(this, free_start, area_end(), SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_OLD>::RemoveRange(this, free_start, area_end(), diff --git a/deps/v8/src/heap/spaces.h b/deps/v8/src/heap/spaces.h index ebb6876cbe1781..5652042d20c131 100644 --- a/deps/v8/src/heap/spaces.h +++ b/deps/v8/src/heap/spaces.h @@ -130,12 +130,6 @@ enum FreeMode { kLinkCategory, kDoNotLinkCategory }; enum class SpaceAccountingMode { kSpaceAccounted, kSpaceUnaccounted }; -enum RememberedSetType { - OLD_TO_NEW, - OLD_TO_OLD, - NUMBER_OF_REMEMBERED_SET_TYPES = OLD_TO_OLD + 1 -}; - // A free list category maintains a linked list of free memory blocks. class FreeListCategory { public: @@ -606,7 +600,7 @@ class MemoryChunk : public BasicMemoryChunk { + kSystemPointerSize // Address owner_ + kSizetSize // size_t progress_bar_ + kIntptrSize // intptr_t live_byte_count_ - + kSystemPointerSize * NUMBER_OF_REMEMBERED_SET_TYPES // SlotSet* array + + kSystemPointerSize // SlotSet* sweeping_slot_set_ + kSystemPointerSize * NUMBER_OF_REMEMBERED_SET_TYPES // TypedSlotSet* array + kSystemPointerSize * @@ -706,6 +700,13 @@ class MemoryChunk : public BasicMemoryChunk { return slot_set_[type]; } + template <AccessMode access_mode = AccessMode::ATOMIC> + SlotSet* sweeping_slot_set() { + if (access_mode == AccessMode::ATOMIC) + return base::AsAtomicPointer::Acquire_Load(&sweeping_slot_set_); + return sweeping_slot_set_; + } + template <RememberedSetType type, AccessMode access_mode = AccessMode::ATOMIC> TypedSlotSet* typed_slot_set() { if (access_mode == AccessMode::ATOMIC) @@ -715,9 +716,13 @@ class MemoryChunk : public BasicMemoryChunk { template <RememberedSetType type> V8_EXPORT_PRIVATE SlotSet* AllocateSlotSet(); + SlotSet* AllocateSweepingSlotSet(); + SlotSet* AllocateSlotSet(SlotSet** slot_set); + // Not safe to be called concurrently. template <RememberedSetType type> void ReleaseSlotSet(); + void ReleaseSlotSet(SlotSet** slot_set); template <RememberedSetType type> TypedSlotSet* AllocateTypedSlotSet(); // Not safe to be called concurrently. @@ -729,12 +734,8 @@ class MemoryChunk : public BasicMemoryChunk { template <RememberedSetType type> void ReleaseInvalidatedSlots(); template <RememberedSetType type> - V8_EXPORT_PRIVATE void RegisterObjectWithInvalidatedSlots(HeapObject object, - int size); - // Updates invalidated_slots after array left-trimming. - template <RememberedSetType type> - void MoveObjectWithInvalidatedSlots(HeapObject old_start, - HeapObject new_start); + V8_EXPORT_PRIVATE void RegisterObjectWithInvalidatedSlots(HeapObject object); + void InvalidateRecordedSlots(HeapObject object); template <RememberedSetType type> bool RegisteredObjectWithInvalidatedSlots(HeapObject object); template <RememberedSetType type> @@ -914,7 +915,7 @@ class MemoryChunk : public BasicMemoryChunk { // A single slot set for small pages (of size kPageSize) or an array of slot // set for large pages. In the latter case the number of entries in the array // is ceil(size() / kPageSize). - SlotSet* slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]; + SlotSet* sweeping_slot_set_; TypedSlotSet* typed_slot_set_[NUMBER_OF_REMEMBERED_SET_TYPES]; InvalidatedSlots* invalidated_slots_[NUMBER_OF_REMEMBERED_SET_TYPES]; @@ -1097,6 +1098,9 @@ class Page : public MemoryChunk { void AllocateFreeListCategories(); void ReleaseFreeListCategories(); + void MoveOldToNewRememberedSetForSweeping(); + void MergeOldToNewRememberedSets(); + #ifdef DEBUG void Print(); #endif // DEBUG diff --git a/deps/v8/src/heap/store-buffer-inl.h b/deps/v8/src/heap/store-buffer-inl.h deleted file mode 100644 index b43098bf57d350..00000000000000 --- a/deps/v8/src/heap/store-buffer-inl.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_HEAP_STORE_BUFFER_INL_H_ -#define V8_HEAP_STORE_BUFFER_INL_H_ - -#include "src/heap/store-buffer.h" - -#include "src/heap/heap-inl.h" - -namespace v8 { -namespace internal { - -void StoreBuffer::InsertIntoStoreBuffer(Address slot) { - if (top_ + sizeof(Address) > limit_[current_]) { - StoreBufferOverflow(heap_->isolate()); - } - *top_ = slot; - top_++; -} - -} // namespace internal -} // namespace v8 - -#endif // V8_HEAP_STORE_BUFFER_INL_H_ diff --git a/deps/v8/src/heap/store-buffer.cc b/deps/v8/src/heap/store-buffer.cc deleted file mode 100644 index 349e7877409c80..00000000000000 --- a/deps/v8/src/heap/store-buffer.cc +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/heap/store-buffer.h" - -#include <algorithm> - -#include "src/base/bits.h" -#include "src/base/macros.h" -#include "src/base/template-utils.h" -#include "src/execution/isolate.h" -#include "src/heap/incremental-marking.h" -#include "src/heap/store-buffer-inl.h" -#include "src/init/v8.h" -#include "src/logging/counters.h" -#include "src/objects/objects-inl.h" - -namespace v8 { -namespace internal { - -StoreBuffer::StoreBuffer(Heap* heap) - : heap_(heap), top_(nullptr), current_(0), mode_(NOT_IN_GC) { - for (int i = 0; i < kStoreBuffers; i++) { - start_[i] = nullptr; - limit_[i] = nullptr; - lazy_top_[i] = nullptr; - } - task_running_ = false; - insertion_callback = &InsertDuringRuntime; -} - -void StoreBuffer::SetUp() { - v8::PageAllocator* page_allocator = GetPlatformPageAllocator(); - // Round up the requested size in order to fulfill the VirtualMemory's - // requrements on the requested size alignment. This may cause a bit of - // memory wastage if the actual CommitPageSize() will be bigger than the - // kMinExpectedOSPageSize value but this is a trade-off for keeping the - // store buffer overflow check in write barriers cheap. - const size_t requested_size = RoundUp(kStoreBufferSize * kStoreBuffers, - page_allocator->CommitPageSize()); - // Allocate buffer memory aligned at least to kStoreBufferSize. This lets us - // use a bit test to detect the ends of the buffers. - STATIC_ASSERT(base::bits::IsPowerOfTwo(kStoreBufferSize)); - const size_t alignment = - std::max<size_t>(kStoreBufferSize, page_allocator->AllocatePageSize()); - void* hint = AlignedAddress(heap_->GetRandomMmapAddr(), alignment); - VirtualMemory reservation(page_allocator, requested_size, hint, alignment); - if (!reservation.IsReserved()) { - heap_->FatalProcessOutOfMemory("StoreBuffer::SetUp"); - } - - Address start = reservation.address(); - const size_t allocated_size = reservation.size(); - - start_[0] = reinterpret_cast<Address*>(start); - limit_[0] = start_[0] + (kStoreBufferSize / kSystemPointerSize); - start_[1] = limit_[0]; - limit_[1] = start_[1] + (kStoreBufferSize / kSystemPointerSize); - - // Sanity check the buffers. - Address* vm_limit = reinterpret_cast<Address*>(start + allocated_size); - USE(vm_limit); - for (int i = 0; i < kStoreBuffers; i++) { - DCHECK(reinterpret_cast<Address>(start_[i]) >= reservation.address()); - DCHECK(reinterpret_cast<Address>(limit_[i]) >= reservation.address()); - DCHECK(start_[i] <= vm_limit); - DCHECK(limit_[i] <= vm_limit); - DCHECK_EQ(0, reinterpret_cast<Address>(limit_[i]) & kStoreBufferMask); - } - - // Set RW permissions only on the pages we use. - const size_t used_size = RoundUp(requested_size, CommitPageSize()); - if (!reservation.SetPermissions(start, used_size, - PageAllocator::kReadWrite)) { - heap_->FatalProcessOutOfMemory("StoreBuffer::SetUp"); - } - current_ = 0; - top_ = start_[current_]; - virtual_memory_ = std::move(reservation); -} - -void StoreBuffer::TearDown() { - if (virtual_memory_.IsReserved()) virtual_memory_.Free(); - top_ = nullptr; - for (int i = 0; i < kStoreBuffers; i++) { - start_[i] = nullptr; - limit_[i] = nullptr; - lazy_top_[i] = nullptr; - } -} - -void StoreBuffer::InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) { - DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC); - store_buffer->InsertIntoStoreBuffer(slot); -} - -void StoreBuffer::InsertDuringGarbageCollection(StoreBuffer* store_buffer, - Address slot) { - DCHECK(store_buffer->mode() != StoreBuffer::NOT_IN_GC); - RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); -} - -void StoreBuffer::SetMode(StoreBufferMode mode) { - mode_ = mode; - if (mode == NOT_IN_GC) { - insertion_callback = &InsertDuringRuntime; - } else { - insertion_callback = &InsertDuringGarbageCollection; - } -} - -int StoreBuffer::StoreBufferOverflow(Isolate* isolate) { - isolate->heap()->store_buffer()->FlipStoreBuffers(); - isolate->counters()->store_buffer_overflows()->Increment(); - // Called by RecordWriteCodeStubAssembler, which doesnt accept void type - return 0; -} - -void StoreBuffer::FlipStoreBuffers() { - base::MutexGuard guard(&mutex_); - int other = (current_ + 1) % kStoreBuffers; - MoveEntriesToRememberedSet(other); - lazy_top_[current_] = top_; - current_ = other; - top_ = start_[current_]; - - if (!task_running_ && FLAG_concurrent_store_buffer) { - task_running_ = true; - V8::GetCurrentPlatform()->CallOnWorkerThread( - base::make_unique<Task>(heap_->isolate(), this)); - } -} - -void StoreBuffer::MoveEntriesToRememberedSet(int index) { - if (!lazy_top_[index]) return; - DCHECK_GE(index, 0); - DCHECK_LT(index, kStoreBuffers); - Address last_inserted_addr = kNullAddress; - MemoryChunk* chunk = nullptr; - - for (Address* current = start_[index]; current < lazy_top_[index]; - current++) { - Address addr = *current; - if (chunk == nullptr || - MemoryChunk::BaseAddress(addr) != chunk->address()) { - chunk = MemoryChunk::FromAnyPointerAddress(addr); - } - if (addr != last_inserted_addr) { - RememberedSet<OLD_TO_NEW>::Insert(chunk, addr); - last_inserted_addr = addr; - } - } - lazy_top_[index] = nullptr; -} - -void StoreBuffer::MoveAllEntriesToRememberedSet() { - base::MutexGuard guard(&mutex_); - int other = (current_ + 1) % kStoreBuffers; - MoveEntriesToRememberedSet(other); - lazy_top_[current_] = top_; - MoveEntriesToRememberedSet(current_); - top_ = start_[current_]; -} - -void StoreBuffer::ConcurrentlyProcessStoreBuffer() { - base::MutexGuard guard(&mutex_); - int other = (current_ + 1) % kStoreBuffers; - MoveEntriesToRememberedSet(other); - task_running_ = false; -} - -} // namespace internal -} // namespace v8 diff --git a/deps/v8/src/heap/store-buffer.h b/deps/v8/src/heap/store-buffer.h deleted file mode 100644 index 025bb6a060b272..00000000000000 --- a/deps/v8/src/heap/store-buffer.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2011 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_HEAP_STORE_BUFFER_H_ -#define V8_HEAP_STORE_BUFFER_H_ - -#include "src/base/logging.h" -#include "src/base/platform/platform.h" -#include "src/common/globals.h" -#include "src/heap/gc-tracer.h" -#include "src/heap/remembered-set.h" -#include "src/heap/slot-set.h" -#include "src/tasks/cancelable-task.h" -#include "src/utils/allocation.h" - -namespace v8 { -namespace internal { - -// Intermediate buffer that accumulates old-to-new stores from the generated -// code. Moreover, it stores invalid old-to-new slots with two entries. -// The first is a tagged address of the start of the invalid range, the second -// one is the end address of the invalid range or null if there is just one slot -// that needs to be removed from the remembered set. On buffer overflow the -// slots are moved to the remembered set. -// Store buffer entries are always full pointers. -class StoreBuffer { - public: - enum StoreBufferMode { IN_GC, NOT_IN_GC }; - - static const int kStoreBuffers = 2; - static const int kStoreBufferSize = - Max(static_cast<int>(kMinExpectedOSPageSize / kStoreBuffers), - 1 << (11 + kSystemPointerSizeLog2)); - static const int kStoreBufferMask = kStoreBufferSize - 1; - - V8_EXPORT_PRIVATE static int StoreBufferOverflow(Isolate* isolate); - - static void InsertDuringGarbageCollection(StoreBuffer* store_buffer, - Address slot); - static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot); - - explicit StoreBuffer(Heap* heap); - void SetUp(); - void TearDown(); - - // Used to add entries from generated code. - inline Address* top_address() { return reinterpret_cast<Address*>(&top_); } - - // Moves entries from a specific store buffer to the remembered set. This - // method takes a lock. - void MoveEntriesToRememberedSet(int index); - - // This method ensures that all used store buffer entries are transferred to - // the remembered set. - void MoveAllEntriesToRememberedSet(); - - inline void InsertIntoStoreBuffer(Address slot); - - void InsertEntry(Address slot) { - // Insertions coming from the GC are directly inserted into the remembered - // set. Insertions coming from the runtime are added to the store buffer to - // allow concurrent processing. - insertion_callback(this, slot); - } - - void SetMode(StoreBufferMode mode); - - // Used by the concurrent processing thread to transfer entries from the - // store buffer to the remembered set. - void ConcurrentlyProcessStoreBuffer(); - - bool Empty() { - for (int i = 0; i < kStoreBuffers; i++) { - if (lazy_top_[i]) { - return false; - } - } - return top_ == start_[current_]; - } - - Heap* heap() { return heap_; } - - private: - // There are two store buffers. If one store buffer fills up, the main thread - // publishes the top pointer of the store buffer that needs processing in its - // global lazy_top_ field. After that it start the concurrent processing - // thread. The concurrent processing thread uses the pointer in lazy_top_. - // It will grab the given mutex and transfer its entries to the remembered - // set. If the concurrent thread does not make progress, the main thread will - // perform the work. - // Important: there is an ordering constrained. The store buffer with the - // older entries has to be processed first. - class Task : public CancelableTask { - public: - Task(Isolate* isolate, StoreBuffer* store_buffer) - : CancelableTask(isolate), - store_buffer_(store_buffer), - tracer_(isolate->heap()->tracer()) {} - ~Task() override = default; - - private: - void RunInternal() override { - TRACE_BACKGROUND_GC(tracer_, - GCTracer::BackgroundScope::BACKGROUND_STORE_BUFFER); - store_buffer_->ConcurrentlyProcessStoreBuffer(); - } - StoreBuffer* store_buffer_; - GCTracer* tracer_; - DISALLOW_COPY_AND_ASSIGN(Task); - }; - - StoreBufferMode mode() const { return mode_; } - - void FlipStoreBuffers(); - - Heap* heap_; - - Address* top_; - - // The start and the limit of the buffer that contains store slots - // added from the generated code. We have two chunks of store buffers. - // Whenever one fills up, we notify a concurrent processing thread and - // use the other empty one in the meantime. - Address* start_[kStoreBuffers]; - Address* limit_[kStoreBuffers]; - - // At most one lazy_top_ pointer is set at any time. - Address* lazy_top_[kStoreBuffers]; - base::Mutex mutex_; - - // We only want to have at most one concurrent processing tas running. - bool task_running_; - - // Points to the current buffer in use. - int current_; - - // During GC, entries are directly added to the remembered set without - // going through the store buffer. This is signaled by a special - // IN_GC mode. - StoreBufferMode mode_; - - VirtualMemory virtual_memory_; - - // Callbacks are more efficient than reading out the gc state for every - // store buffer operation. - void (*insertion_callback)(StoreBuffer*, Address); -}; - -} // namespace internal -} // namespace v8 - -#endif // V8_HEAP_STORE_BUFFER_H_ diff --git a/deps/v8/src/heap/sweeper.cc b/deps/v8/src/heap/sweeper.cc index c3c6b58835ca5e..11be77548567b7 100644 --- a/deps/v8/src/heap/sweeper.cc +++ b/deps/v8/src/heap/sweeper.cc @@ -4,7 +4,6 @@ #include "src/heap/sweeper.h" -#include "src/base/template-utils.h" #include "src/execution/vm-state-inl.h" #include "src/heap/array-buffer-tracker-inl.h" #include "src/heap/gc-tracer.h" @@ -181,7 +180,7 @@ void Sweeper::StartSweeperTasks() { ForAllSweepingSpaces([this](AllocationSpace space) { DCHECK(IsValidSweepingSpace(space)); num_sweeping_tasks_++; - auto task = base::make_unique<SweeperTask>( + auto task = std::make_unique<SweeperTask>( heap_->isolate(), this, &pending_sweeper_tasks_semaphore_, &num_sweeping_tasks_, space); DCHECK_LT(num_tasks_, kMaxSweeperTasks); @@ -321,8 +320,8 @@ int Sweeper::RawSweep( ClearFreedMemoryMode::kClearFreedMemory); } if (should_reduce_memory_) p->DiscardUnusedMemory(free_start, size); - RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, free_end, - SlotSet::KEEP_EMPTY_BUCKETS); + RememberedSetSweeping::RemoveRange(p, free_start, free_end, + SlotSet::KEEP_EMPTY_BUCKETS); RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, free_end, SlotSet::KEEP_EMPTY_BUCKETS); if (non_empty_typed_slots) { @@ -355,8 +354,8 @@ int Sweeper::RawSweep( ClearFreedMemoryMode::kClearFreedMemory); } if (should_reduce_memory_) p->DiscardUnusedMemory(free_start, size); - RememberedSet<OLD_TO_NEW>::RemoveRange(p, free_start, p->area_end(), - SlotSet::KEEP_EMPTY_BUCKETS); + RememberedSetSweeping::RemoveRange(p, free_start, p->area_end(), + SlotSet::KEEP_EMPTY_BUCKETS); RememberedSet<OLD_TO_OLD>::RemoveRange(p, free_start, p->area_end(), SlotSet::KEEP_EMPTY_BUCKETS); if (non_empty_typed_slots) { @@ -404,6 +403,10 @@ void Sweeper::SweepSpaceFromTask(AllocationSpace identity) { Page* page = nullptr; while (!stop_sweeper_tasks_ && ((page = GetSweepingPageSafe(identity)) != nullptr)) { + // Typed slot sets are only recorded on code pages. Code pages + // are not swept concurrently to the application to ensure W^X. + DCHECK(!page->typed_slot_set<OLD_TO_NEW>() && + !page->typed_slot_set<OLD_TO_OLD>()); ParallelSweepPage(page, identity); } } @@ -462,16 +465,6 @@ int Sweeper::ParallelSweepPage( max_freed = RawSweep(page, REBUILD_FREE_LIST, free_space_mode, invalidated_slots_in_free_space); DCHECK(page->SweepingDone()); - - // After finishing sweeping of a page we clean up its remembered set. - TypedSlotSet* typed_slot_set = page->typed_slot_set<OLD_TO_NEW>(); - if (typed_slot_set) { - typed_slot_set->FreeToBeFreedChunks(); - } - SlotSet* slot_set = page->slot_set<OLD_TO_NEW>(); - if (slot_set) { - slot_set->FreeToBeFreedBuckets(); - } } { @@ -488,7 +481,7 @@ void Sweeper::ScheduleIncrementalSweepingTask() { auto taskrunner = V8::GetCurrentPlatform()->GetForegroundTaskRunner(isolate); taskrunner->PostTask( - base::make_unique<IncrementalSweeperTask>(heap_->isolate(), this)); + std::make_unique<IncrementalSweeperTask>(heap_->isolate(), this)); } } @@ -517,6 +510,7 @@ void Sweeper::PrepareToBeSweptPage(AllocationSpace space, Page* page) { DCHECK(!category->is_linked(page->owner()->free_list())); }); #endif // DEBUG + page->MoveOldToNewRememberedSetForSweeping(); page->set_concurrent_sweeping_state(Page::kSweepingPending); heap_->paged_space(space)->IncreaseAllocatedBytes( marking_state_->live_bytes(page), page); @@ -596,8 +590,8 @@ void Sweeper::StartIterabilityTasks() { DCHECK(!iterability_task_started_); if (FLAG_concurrent_sweeping && !iterability_list_.empty()) { - auto task = base::make_unique<IterabilityTask>( - heap_->isolate(), this, &iterability_task_semaphore_); + auto task = std::make_unique<IterabilityTask>(heap_->isolate(), this, + &iterability_task_semaphore_); iterability_task_id_ = task->id(); iterability_task_started_ = true; V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task)); diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc index f9efcba05f72aa..99cbd3c3c892b1 100644 --- a/deps/v8/src/ic/accessor-assembler.cc +++ b/deps/v8/src/ic/accessor-assembler.cc @@ -5,6 +5,7 @@ #include "src/ic/accessor-assembler.h" #include "src/ast/ast.h" +#include "src/base/optional.h" #include "src/codegen/code-factory.h" #include "src/ic/handler-configuration.h" #include "src/ic/ic.h" @@ -16,6 +17,7 @@ #include "src/objects/heap-number.h" #include "src/objects/module.h" #include "src/objects/objects-inl.h" +#include "src/objects/property-details.h" #include "src/objects/smi.h" namespace v8 { @@ -23,10 +25,6 @@ namespace internal { using compiler::CodeAssemblerState; using compiler::Node; -template <typename T> -using TNode = compiler::TNode<T>; -template <typename T> -using SloppyTNode = compiler::SloppyTNode<T>; //////////////////// Private helpers. @@ -66,27 +64,25 @@ TNode<MaybeObject> AccessorAssembler::LoadHandlerDataField( } TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase( - Node* slot, Node* vector, Node* receiver_map, Label* if_handler, - TVariable<MaybeObject>* var_handler, Label* if_miss) { + TNode<Smi> slot, TNode<FeedbackVector> vector, TNode<Map> receiver_map, + Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss) { Comment("TryMonomorphicCase"); DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); // TODO(ishell): add helper class that hides offset computations for a series // of loads. - CSA_ASSERT(this, IsFeedbackVector(vector), vector); int32_t header_size = FeedbackVector::kFeedbackSlotsOffset - kHeapObjectTag; // Adding |header_size| with a separate IntPtrAdd rather than passing it // into ElementOffsetFromIndex() allows it to be folded into a single // [base, index, offset] indirect memory access on x64. - TNode<IntPtrT> offset = - ElementOffsetFromIndex(slot, HOLEY_ELEMENTS, SMI_PARAMETERS); + TNode<IntPtrT> offset = ElementOffsetFromIndex(slot, HOLEY_ELEMENTS); TNode<MaybeObject> feedback = ReinterpretCast<MaybeObject>( Load(MachineType::AnyTagged(), vector, IntPtrAdd(offset, IntPtrConstant(header_size)))); // Try to quickly handle the monomorphic case without knowing for sure // if we have a weak reference in feedback. - GotoIf(IsNotWeakReferenceTo(feedback, CAST(receiver_map)), if_miss); + GotoIfNot(IsWeakReferenceTo(feedback, receiver_map), if_miss); TNode<MaybeObject> handler = UncheckedCast<MaybeObject>( Load(MachineType::AnyTagged(), vector, @@ -98,7 +94,7 @@ TNode<MaybeObject> AccessorAssembler::TryMonomorphicCase( } void AccessorAssembler::HandlePolymorphicCase( - Node* receiver_map, TNode<WeakFixedArray> feedback, Label* if_handler, + TNode<Map> receiver_map, TNode<WeakFixedArray> feedback, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss) { Comment("HandlePolymorphicCase"); DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep()); @@ -121,8 +117,7 @@ void AccessorAssembler::HandlePolymorphicCase( TNode<MaybeObject> maybe_cached_map = LoadWeakFixedArrayElement(feedback, var_index.value()); CSA_ASSERT(this, IsWeakOrCleared(maybe_cached_map)); - GotoIf(IsNotWeakReferenceTo(maybe_cached_map, CAST(receiver_map)), - &loop_next); + GotoIfNot(IsWeakReferenceTo(maybe_cached_map, receiver_map), &loop_next); // Found, now call handler. TNode<MaybeObject> handler = @@ -157,7 +152,7 @@ void AccessorAssembler::HandleLoadICHandlerCase( BIND(&try_proto_handler); { GotoIf(IsCodeMap(LoadMap(CAST(handler))), &call_handler); - HandleLoadICProtoHandler(p, handler, &var_holder, &var_smi_handler, + HandleLoadICProtoHandler(p, CAST(handler), &var_holder, &var_smi_handler, &if_smi_handler, miss, exit_point, ic_mode, access_mode); } @@ -167,8 +162,8 @@ void AccessorAssembler::HandleLoadICHandlerCase( BIND(&if_smi_handler); { HandleLoadICSmiHandlerCase(p, var_holder.value(), var_smi_handler.value(), - handler, miss, exit_point, on_nonexistent, - support_elements, access_mode); + handler, miss, exit_point, ic_mode, + on_nonexistent, support_elements, access_mode); } BIND(&call_handler); @@ -237,9 +232,10 @@ void AccessorAssembler::HandleLoadAccessor( api_holder.value(), p->receiver())); } -void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, +void AccessorAssembler::HandleLoadField(SloppyTNode<JSObject> holder, + TNode<WordT> handler_word, Variable* var_double_value, - Label* rebox_double, + Label* rebox_double, Label* miss, ExitPoint* exit_point) { Comment("field_load"); TNode<IntPtrT> index = @@ -261,8 +257,13 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, var_double_value->Bind( LoadObjectField(holder, offset, MachineType::Float64())); } else { - TNode<HeapNumber> heap_number = CAST(LoadObjectField(holder, offset)); - var_double_value->Bind(LoadHeapNumberValue(heap_number)); + TNode<Object> heap_number = LoadObjectField(holder, offset); + // This is not an "old" Smi value from before a Smi->Double transition. + // Rather, it's possible that since the last update of this IC, the Double + // field transitioned to a Tagged field, and was then assigned a Smi. + GotoIf(TaggedIsSmi(heap_number), miss); + GotoIfNot(IsHeapNumber(CAST(heap_number)), miss); + var_double_value->Bind(LoadHeapNumberValue(CAST(heap_number))); } Goto(rebox_double); } @@ -276,6 +277,13 @@ void AccessorAssembler::HandleLoadField(Node* holder, Node* handler_word, exit_point->Return(value); BIND(&is_double); + if (!FLAG_unbox_double_fields) { + // This is not an "old" Smi value from before a Smi->Double transition. + // Rather, it's possible that since the last update of this IC, the Double + // field transitioned to a Tagged field, and was then assigned a Smi. + GotoIf(TaggedIsSmi(value), miss); + GotoIfNot(IsHeapNumber(CAST(value)), miss); + } var_double_value->Bind(LoadHeapNumberValue(CAST(value))); Goto(rebox_double); } @@ -293,10 +301,10 @@ TNode<MaybeObject> AccessorAssembler::LoadDescriptorValueOrFieldType( } void AccessorAssembler::HandleLoadICSmiHandlerCase( - const LazyLoadICParameters* p, Node* holder, SloppyTNode<Smi> smi_handler, - SloppyTNode<Object> handler, Label* miss, ExitPoint* exit_point, - OnNonExistent on_nonexistent, ElementSupport support_elements, - LoadAccessMode access_mode) { + const LazyLoadICParameters* p, SloppyTNode<HeapObject> holder, + SloppyTNode<Smi> smi_handler, SloppyTNode<Object> handler, Label* miss, + ExitPoint* exit_point, ICMode ic_mode, OnNonExistent on_nonexistent, + ElementSupport support_elements, LoadAccessMode access_mode) { VARIABLE(var_double_value, MachineRepresentation::kFloat64); Label rebox_double(this, &var_double_value); @@ -388,10 +396,11 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( Label if_oob(this, Label::kDeferred); Comment("indexed string"); + TNode<String> string_holder = CAST(holder); TNode<IntPtrT> intptr_index = TryToIntptr(p->name(), miss); - TNode<IntPtrT> length = LoadStringLengthAsWord(holder); + TNode<IntPtrT> length = LoadStringLengthAsWord(string_holder); GotoIf(UintPtrGreaterThanOrEqual(intptr_index, length), &if_oob); - TNode<Int32T> code = StringCharCodeAt(holder, intptr_index); + TNode<Int32T> code = StringCharCodeAt(string_holder, intptr_index); TNode<String> result = StringFromSingleCharCode(code); Return(result); @@ -410,23 +419,25 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( if (access_mode == LoadAccessMode::kHas) { HandleLoadICSmiHandlerHasNamedCase(p, holder, handler_kind, miss, - exit_point); + exit_point, ic_mode); } else { HandleLoadICSmiHandlerLoadNamedCase( p, holder, handler_kind, handler_word, &rebox_double, &var_double_value, - handler, miss, exit_point, on_nonexistent, support_elements); + handler, miss, exit_point, ic_mode, on_nonexistent, support_elements); } } void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( - const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, - TNode<WordT> handler_word, Label* rebox_double, Variable* var_double_value, - SloppyTNode<Object> handler, Label* miss, ExitPoint* exit_point, - OnNonExistent on_nonexistent, ElementSupport support_elements) { + const LazyLoadICParameters* p, TNode<HeapObject> holder, + TNode<IntPtrT> handler_kind, TNode<WordT> handler_word, Label* rebox_double, + Variable* var_double_value, SloppyTNode<Object> handler, Label* miss, + ExitPoint* exit_point, ICMode ic_mode, OnNonExistent on_nonexistent, + ElementSupport support_elements) { Label constant(this), field(this), normal(this, Label::kDeferred), - interceptor(this, Label::kDeferred), nonexistent(this), - accessor(this, Label::kDeferred), global(this, Label::kDeferred), - module_export(this, Label::kDeferred), proxy(this, Label::kDeferred), + slow(this, Label::kDeferred), interceptor(this, Label::kDeferred), + nonexistent(this), accessor(this, Label::kDeferred), + global(this, Label::kDeferred), module_export(this, Label::kDeferred), + proxy(this, Label::kDeferred), native_data_property(this, Label::kDeferred), api_getter(this, Label::kDeferred); @@ -459,14 +470,16 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kGlobal)), &global); + GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kSlow)), &slow); + GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kProxy)), &proxy); Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kModuleExport)), &module_export, &interceptor); BIND(&field); - HandleLoadField(holder, handler_word, var_double_value, rebox_double, - exit_point); + HandleLoadField(CAST(holder), handler_word, var_double_value, rebox_double, + miss, exit_point); BIND(&nonexistent); // This is a handler for a load of a non-existent value. @@ -487,7 +500,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&normal); { Comment("load_normal"); - TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder)); + TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(holder))); TVARIABLE(IntPtrT, var_name_index); Label found(this, &var_name_index); NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), &found, @@ -529,8 +542,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( BIND(&proxy); { - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); Label if_index(this), if_unique_name(this), to_name_failed(this, Label::kDeferred); @@ -586,20 +599,31 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( p->context(), p->name(), p->receiver(), holder, p->slot(), p->vector()); } + BIND(&slow); + { + Comment("load_slow"); + if (ic_mode == ICMode::kGlobalIC) { + exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Slow, p->context(), + p->name(), p->slot(), p->vector()); + + } else { + exit_point->ReturnCallRuntime(Runtime::kGetProperty, p->context(), + p->receiver(), p->name()); + } + } BIND(&module_export); { Comment("module export"); TNode<UintPtrT> index = DecodeWord<LoadHandler::ExportsIndexBits>(handler_word); - Node* module = - LoadObjectField(p->receiver(), JSModuleNamespace::kModuleOffset, - MachineType::TaggedPointer()); - TNode<ObjectHashTable> exports = CAST(LoadObjectField( - module, Module::kExportsOffset, MachineType::TaggedPointer())); + TNode<Module> module = + CAST(LoadObjectField(p->receiver(), JSModuleNamespace::kModuleOffset)); + TNode<ObjectHashTable> exports = + LoadObjectField<ObjectHashTable>(module, Module::kExportsOffset); TNode<Cell> cell = CAST(LoadFixedArrayElement(exports, index)); // The handler is only installed for exports that exist. - Node* value = LoadCellValue(cell); + TNode<Object> value = LoadCellValue(cell); Label is_the_hole(this, Label::kDeferred); GotoIf(IsTheHole(value), &is_the_hole); exit_point->Return(value); @@ -617,10 +641,11 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( } void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( - const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, - Label* miss, ExitPoint* exit_point) { + const LazyLoadICParameters* p, TNode<HeapObject> holder, + TNode<IntPtrT> handler_kind, Label* miss, ExitPoint* exit_point, + ICMode ic_mode) { Label return_true(this), return_false(this), return_lookup(this), - normal(this), global(this); + normal(this), global(this), slow(this); GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kField)), &return_true); @@ -649,6 +674,8 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( IntPtrConstant(LoadHandler::kApiGetterHolderIsPrototype)), &return_true); + GotoIf(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kSlow)), &slow); + Branch(WordEqual(handler_kind, IntPtrConstant(LoadHandler::kGlobal)), &global, &return_lookup); @@ -676,7 +703,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( BIND(&normal); { Comment("has_normal"); - TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder)); + TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(holder))); TVARIABLE(IntPtrT, var_name_index); Label found(this); NameDictionaryLookup<NameDictionary>(properties, CAST(p->name()), &found, @@ -695,6 +722,18 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( exit_point->Return(TrueConstant()); } + + BIND(&slow); + { + Comment("load_slow"); + if (ic_mode == ICMode::kGlobalIC) { + exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Slow, p->context(), + p->name(), p->slot(), p->vector()); + } else { + exit_point->ReturnCallRuntime(Runtime::kHasProperty, p->context(), + p->receiver(), p->name()); + } + } } // Performs actions common to both load and store handlers: @@ -715,8 +754,9 @@ void AccessorAssembler::HandleLoadICSmiHandlerHasNamedCase( // TODO(ishell): Remove templatezation once we move common bits from // Load/StoreHandler to the base class. template <typename ICHandler, typename ICParameters> -Node* AccessorAssembler::HandleProtoHandler( - const ICParameters* p, Node* handler, const OnCodeHandler& on_code_handler, +TNode<Object> AccessorAssembler::HandleProtoHandler( + const ICParameters* p, TNode<DataHandler> handler, + const OnCodeHandler& on_code_handler, const OnFoundOnReceiver& on_found_on_receiver, Label* miss, ICMode ic_mode) { // @@ -738,8 +778,7 @@ Node* AccessorAssembler::HandleProtoHandler( Label if_smi_handler(this); GotoIf(TaggedIsSmi(smi_or_code_handler), &if_smi_handler); - CSA_ASSERT(this, IsCodeMap(LoadMap(CAST(smi_or_code_handler)))); - on_code_handler(smi_or_code_handler); + on_code_handler(CAST(smi_or_code_handler)); BIND(&if_smi_handler); } @@ -771,8 +810,8 @@ Node* AccessorAssembler::HandleProtoHandler( CSA_ASSERT(this, IsWeakOrCleared(data2)); TNode<Context> expected_native_context = CAST(GetHeapObjectAssumeWeak(data2, miss)); - EmitAccessCheck(expected_native_context, p->context(), p->receiver(), - &done, miss); + EmitAccessCheck(expected_native_context, p->context(), + CAST(p->receiver()), &done, miss); } // Dictionary lookup on receiver is not necessary for Load/StoreGlobalIC @@ -807,18 +846,19 @@ Node* AccessorAssembler::HandleProtoHandler( } void AccessorAssembler::HandleLoadICProtoHandler( - const LazyLoadICParameters* p, Node* handler, Variable* var_holder, - Variable* var_smi_handler, Label* if_smi_handler, Label* miss, - ExitPoint* exit_point, ICMode ic_mode, LoadAccessMode access_mode) { + const LazyLoadICParameters* p, TNode<DataHandler> handler, + Variable* var_holder, Variable* var_smi_handler, Label* if_smi_handler, + Label* miss, ExitPoint* exit_point, ICMode ic_mode, + LoadAccessMode access_mode) { DCHECK_EQ(MachineRepresentation::kTagged, var_holder->rep()); DCHECK_EQ(MachineRepresentation::kTagged, var_smi_handler->rep()); - Node* smi_handler = HandleProtoHandler<LoadHandler>( + TNode<Smi> smi_handler = CAST(HandleProtoHandler<LoadHandler>( p, handler, // Code sub-handlers are not expected in LoadICs, so no |on_code_handler|. nullptr, // on_found_on_receiver - [=](Node* properties, Node* name_index) { + [=](TNode<NameDictionary> properties, TNode<IntPtrT> name_index) { if (access_mode == LoadAccessMode::kHas) { exit_point->Return(TrueConstant()); } else { @@ -832,7 +872,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( exit_point->Return(value); } }, - miss, ic_mode); + miss, ic_mode)); TNode<MaybeObject> maybe_holder_or_constant = LoadHandlerDataField(handler, 1); @@ -840,7 +880,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( Label load_from_cached_holder(this), is_smi(this), done(this); GotoIf(TaggedIsSmi(maybe_holder_or_constant), &is_smi); - Branch(IsStrongReferenceTo(maybe_holder_or_constant, NullConstant()), &done, + Branch(TaggedEqual(maybe_holder_or_constant, NullConstant()), &done, &load_from_cached_holder); BIND(&is_smi); @@ -878,14 +918,15 @@ void AccessorAssembler::HandleLoadICProtoHandler( } void AccessorAssembler::EmitAccessCheck(TNode<Context> expected_native_context, - TNode<Context> context, Node* receiver, + TNode<Context> context, + TNode<Object> receiver, Label* can_access, Label* miss) { CSA_ASSERT(this, IsNativeContext(expected_native_context)); - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); GotoIf(TaggedEqual(expected_native_context, native_context), can_access); // If the receiver is not a JSGlobalProxy then we miss. - GotoIfNot(IsJSGlobalProxy(receiver), miss); + GotoIfNot(IsJSGlobalProxy(CAST(receiver)), miss); // For JSGlobalProxy receiver try to compare security tokens of current // and expected native contexts. TNode<Object> expected_token = LoadContextElement( @@ -895,8 +936,8 @@ void AccessorAssembler::EmitAccessCheck(TNode<Context> expected_native_context, Branch(TaggedEqual(expected_token, current_token), can_access, miss); } -void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable, - Label* readonly) { +void AccessorAssembler::JumpIfDataProperty(TNode<Uint32T> details, + Label* writable, Label* readonly) { if (readonly) { // Accessor properties never have the READ_ONLY attribute set. GotoIf(IsSetWord32(details, PropertyDetails::kAttributesReadOnlyMask), @@ -911,10 +952,11 @@ void AccessorAssembler::JumpIfDataProperty(Node* details, Label* writable, } void AccessorAssembler::HandleStoreICNativeDataProperty( - const StoreICParameters* p, Node* holder, Node* handler_word) { + const StoreICParameters* p, SloppyTNode<HeapObject> holder, + TNode<Word32T> handler_word) { Comment("native_data_property_store"); TNode<IntPtrT> descriptor = - Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word)); + Signed(DecodeWordFromWord32<StoreHandler::DescriptorBits>(handler_word)); TNode<AccessorInfo> accessor_info = CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); @@ -936,23 +978,30 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_smi_handler); { Node* holder = p->receiver(); - TNode<IntPtrT> handler_word = SmiUntag(CAST(handler)); + TNode<Int32T> handler_word = SmiToInt32(CAST(handler)); - Label if_fast_smi(this), if_proxy(this); + Label if_fast_smi(this), if_proxy(this), if_interceptor(this), + if_slow(this); STATIC_ASSERT(StoreHandler::kGlobalProxy + 1 == StoreHandler::kNormal); - STATIC_ASSERT(StoreHandler::kNormal + 1 == StoreHandler::kProxy); + STATIC_ASSERT(StoreHandler::kNormal + 1 == StoreHandler::kInterceptor); + STATIC_ASSERT(StoreHandler::kInterceptor + 1 == StoreHandler::kSlow); + STATIC_ASSERT(StoreHandler::kSlow + 1 == StoreHandler::kProxy); STATIC_ASSERT(StoreHandler::kProxy + 1 == StoreHandler::kKindsNumber); - TNode<UintPtrT> handler_kind = - DecodeWord<StoreHandler::KindBits>(handler_word); - GotoIf(IntPtrLessThan(handler_kind, - IntPtrConstant(StoreHandler::kGlobalProxy)), - &if_fast_smi); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kProxy)), + TNode<Uint32T> handler_kind = + DecodeWord32<StoreHandler::KindBits>(handler_word); + GotoIf( + Int32LessThan(handler_kind, Int32Constant(StoreHandler::kGlobalProxy)), + &if_fast_smi); + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kProxy)), &if_proxy); + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kInterceptor)), + &if_interceptor); + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kSlow)), + &if_slow); CSA_ASSERT(this, - WordEqual(handler_kind, IntPtrConstant(StoreHandler::kNormal))); + Word32Equal(handler_kind, Int32Constant(StoreHandler::kNormal))); TNode<NameDictionary> properties = CAST(LoadSlowProperties(holder)); TVARIABLE(IntPtrT, var_name_index); @@ -976,14 +1025,14 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_fast_smi); { - TNode<UintPtrT> handler_kind = - DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<Uint32T> handler_kind = + DecodeWord32<StoreHandler::KindBits>(handler_word); Label data(this), accessor(this), native_data_property(this); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kAccessor)), + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kAccessor)), &accessor); - Branch(WordEqual(handler_kind, - IntPtrConstant(StoreHandler::kNativeDataProperty)), + Branch(Word32Equal(handler_kind, + Int32Constant(StoreHandler::kNativeDataProperty)), &native_data_property, &data); BIND(&accessor); @@ -999,6 +1048,29 @@ void AccessorAssembler::HandleStoreICHandlerCase( BIND(&if_proxy); HandleStoreToProxy(p, holder, miss, support_elements); + + BIND(&if_interceptor); + { + Comment("store_interceptor"); + TailCallRuntime(Runtime::kStorePropertyWithInterceptor, p->context(), + p->value(), p->slot(), p->vector(), p->receiver(), + p->name()); + } + + BIND(&if_slow); + { + Comment("store_slow"); + // The slow case calls into the runtime to complete the store without + // causing an IC miss that would otherwise cause a transition to the + // generic stub. + if (ic_mode == ICMode::kGlobalIC) { + TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(), + p->slot(), p->vector(), p->receiver(), p->name()); + } else { + TailCallRuntime(Runtime::kKeyedStoreIC_Slow, p->context(), p->value(), + p->receiver(), p->name()); + } + } } BIND(&if_nonsmi_handler); @@ -1111,7 +1183,7 @@ void AccessorAssembler::HandleStoreICTransitionMapHandlerCase( } void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, - Node* name_index, + TNode<IntPtrT> name_index, TNode<Word32T> representation, Node* value, Label* bailout) { Label r_smi(this), r_double(this), r_heapobject(this), all_fine(this); @@ -1143,20 +1215,20 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, BIND(&r_heapobject); { GotoIf(TaggedIsSmi(value), bailout); - TNode<MaybeObject> field_type = LoadFieldTypeByKeyIndex( - descriptors, UncheckedCast<IntPtrT>(name_index)); + TNode<MaybeObject> field_type = + LoadFieldTypeByKeyIndex(descriptors, name_index); const Address kNoneType = FieldType::None().ptr(); const Address kAnyType = FieldType::Any().ptr(); DCHECK_NE(static_cast<uint32_t>(kNoneType), kClearedWeakHeapObjectLower32); DCHECK_NE(static_cast<uint32_t>(kAnyType), kClearedWeakHeapObjectLower32); // FieldType::None can't hold any value. - GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), - IntPtrConstant(kNoneType)), - bailout); + GotoIf( + TaggedEqual(field_type, BitcastWordToTagged(IntPtrConstant(kNoneType))), + bailout); // FieldType::Any can hold any value. - GotoIf(WordEqual(BitcastMaybeObjectToWord(field_type), - IntPtrConstant(kAnyType)), - &all_fine); + GotoIf( + TaggedEqual(field_type, BitcastWordToTagged(IntPtrConstant(kAnyType))), + &all_fine); // Cleared weak references count as FieldType::None, which can't hold any // value. TNode<Map> field_type_map = @@ -1168,15 +1240,16 @@ void AccessorAssembler::CheckFieldType(TNode<DescriptorArray> descriptors, BIND(&all_fine); } -TNode<BoolT> AccessorAssembler::IsPropertyDetailsConst(Node* details) { +TNode<BoolT> AccessorAssembler::IsPropertyDetailsConst(TNode<Uint32T> details) { return Word32Equal(DecodeWord32<PropertyDetails::ConstnessField>(details), Int32Constant(static_cast<int32_t>(VariableMode::kConst))); } void AccessorAssembler::OverwriteExistingFastDataProperty( - Node* object, Node* object_map, Node* descriptors, - Node* descriptor_name_index, Node* details, TNode<Object> value, - Label* slow, bool do_transitioning_store) { + SloppyTNode<HeapObject> object, TNode<Map> object_map, + TNode<DescriptorArray> descriptors, TNode<IntPtrT> descriptor_name_index, + TNode<Uint32T> details, TNode<Object> value, Label* slow, + bool do_transitioning_store) { Label done(this), if_field(this), if_descriptor(this); CSA_ASSERT(this, @@ -1192,8 +1265,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( TNode<Uint32T> representation = DecodeWord32<PropertyDetails::RepresentationField>(details); - CheckFieldType(CAST(descriptors), descriptor_name_index, representation, - value, slow); + CheckFieldType(descriptors, descriptor_name_index, representation, value, + slow); TNode<UintPtrT> field_index = DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details); @@ -1224,7 +1297,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( Label if_mutable(this); GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); TNode<Float64T> current_value = - LoadObjectField<Float64T>(CAST(object), field_offset); + LoadObjectField<Float64T>(object, field_offset); BranchIfSameNumberValue(current_value, double_value, &done, slow); BIND(&if_mutable); } @@ -1257,8 +1330,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( } else { Label if_mutable(this); GotoIfNot(IsPropertyDetailsConst(details), &if_mutable); - TNode<Object> current_value = - LoadObjectField(CAST(object), field_offset); + TNode<Object> current_value = LoadObjectField(object, field_offset); BranchIfSameValue(current_value, value, &done, slow, SameValueMode::kNumbersOnly); BIND(&if_mutable); @@ -1302,7 +1374,8 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( } else { Label tagged_rep(this), double_rep(this); - TNode<PropertyArray> properties = CAST(LoadFastProperties(object)); + TNode<PropertyArray> properties = + CAST(LoadFastProperties(CAST(object))); Branch( Word32Equal(representation, Int32Constant(Representation::kDouble)), &double_rep, &tagged_rep); @@ -1342,7 +1415,7 @@ void AccessorAssembler::OverwriteExistingFastDataProperty( { // Check that constant matches value. TNode<Object> constant = LoadValueByKeyIndex( - CAST(descriptors), UncheckedCast<IntPtrT>(descriptor_name_index)); + descriptors, UncheckedCast<IntPtrT>(descriptor_name_index)); GotoIf(TaggedNotEqual(value, constant), slow); if (do_transitioning_store) { @@ -1370,10 +1443,11 @@ void AccessorAssembler::CheckPrototypeValidityCell( } void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p, - Node* holder, Node* handler_word) { + SloppyTNode<HeapObject> holder, + TNode<Word32T> handler_word) { Comment("accessor_store"); TNode<IntPtrT> descriptor = - Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word)); + Signed(DecodeWordFromWord32<StoreHandler::DescriptorBits>(handler_word)); TNode<HeapObject> accessor_pair = CAST(LoadDescriptorValue(LoadMap(holder), descriptor)); CSA_ASSERT(this, IsAccessorPair(accessor_pair)); @@ -1393,7 +1467,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( OnCodeHandler on_code_handler; if (support_elements == kSupportElements) { // Code sub-handlers are expected only in KeyedStoreICs. - on_code_handler = [=](Node* code_handler) { + on_code_handler = [=](TNode<Code> code_handler) { // This is either element store or transitioning element store. Label if_element_store(this), if_transitioning_element_store(this); Branch(IsStoreHandler0Map(LoadMap(handler)), &if_element_store, @@ -1421,10 +1495,10 @@ void AccessorAssembler::HandleStoreICProtoHandler( }; } - Node* smi_handler = HandleProtoHandler<StoreHandler>( + TNode<Object> smi_handler = HandleProtoHandler<StoreHandler>( p, handler, on_code_handler, // on_found_on_receiver - [=](Node* properties, Node* name_index) { + [=](TNode<NameDictionary> properties, TNode<IntPtrT> name_index) { TNode<Uint32T> details = LoadDetailsByKeyIndex<NameDictionary>(properties, name_index); // Check that the property is a writable data property (no accessor). @@ -1434,49 +1508,80 @@ void AccessorAssembler::HandleStoreICProtoHandler( STATIC_ASSERT(kData == 0); GotoIf(IsSetWord32(details, kTypeAndReadOnlyMask), miss); - StoreValueByKeyIndex<NameDictionary>( - CAST(properties), UncheckedCast<IntPtrT>(name_index), p->value()); + StoreValueByKeyIndex<NameDictionary>(properties, name_index, + p->value()); Return(p->value()); }, miss, ic_mode); { Label if_add_normal(this), if_store_global_proxy(this), if_api_setter(this), - if_accessor(this), if_native_data_property(this); + if_accessor(this), if_native_data_property(this), if_slow(this), + if_interceptor(this); CSA_ASSERT(this, TaggedIsSmi(smi_handler)); - TNode<IntPtrT> handler_word = SmiUntag(smi_handler); + TNode<Int32T> handler_word = SmiToInt32(CAST(smi_handler)); - TNode<UintPtrT> handler_kind = - DecodeWord<StoreHandler::KindBits>(handler_word); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kNormal)), + TNode<Uint32T> handler_kind = + DecodeWord32<StoreHandler::KindBits>(handler_word); + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kNormal)), &if_add_normal); TNode<MaybeObject> maybe_holder = LoadHandlerDataField(handler, 1); CSA_ASSERT(this, IsWeakOrCleared(maybe_holder)); TNode<HeapObject> holder = GetHeapObjectAssumeWeak(maybe_holder, miss); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kGlobalProxy)), + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kGlobalProxy)), &if_store_global_proxy); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kAccessor)), + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kAccessor)), &if_accessor); - GotoIf(WordEqual(handler_kind, - IntPtrConstant(StoreHandler::kNativeDataProperty)), + GotoIf(Word32Equal(handler_kind, + Int32Constant(StoreHandler::kNativeDataProperty)), &if_native_data_property); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kApiSetter)), + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kApiSetter)), &if_api_setter); - GotoIf(WordEqual(handler_kind, - IntPtrConstant(StoreHandler::kApiSetterHolderIsPrototype)), - &if_api_setter); + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kSlow)), + &if_slow); + + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kInterceptor)), + &if_interceptor); + + GotoIf( + Word32Equal(handler_kind, + Int32Constant(StoreHandler::kApiSetterHolderIsPrototype)), + &if_api_setter); CSA_ASSERT(this, - WordEqual(handler_kind, IntPtrConstant(StoreHandler::kProxy))); + Word32Equal(handler_kind, Int32Constant(StoreHandler::kProxy))); HandleStoreToProxy(p, holder, miss, support_elements); + BIND(&if_slow); + { + Comment("store_slow"); + // The slow case calls into the runtime to complete the store without + // causing an IC miss that would otherwise cause a transition to the + // generic stub. + if (ic_mode == ICMode::kGlobalIC) { + TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(), + p->slot(), p->vector(), p->receiver(), p->name()); + } else { + TailCallRuntime(Runtime::kKeyedStoreIC_Slow, p->context(), p->value(), + p->receiver(), p->name()); + } + } + + BIND(&if_interceptor); + { + Comment("store_interceptor"); + TailCallRuntime(Runtime::kStorePropertyWithInterceptor, p->context(), + p->value(), p->slot(), p->vector(), p->receiver(), + p->name()); + } + BIND(&if_add_normal); { // This is a case of "transitioning store" to a dictionary mode object @@ -1512,7 +1617,7 @@ void AccessorAssembler::HandleStoreICProtoHandler( // Context is stored either in data2 or data3 field depending on whether // the access check is enabled for this handler or not. TNode<MaybeObject> maybe_context = Select<MaybeObject>( - IsSetWord<LoadHandler::DoAccessCheckOnReceiverBits>(handler_word), + IsSetWord32<LoadHandler::DoAccessCheckOnReceiverBits>(handler_word), [=] { return LoadHandlerDataField(handler, 3); }, [=] { return LoadHandlerDataField(handler, 2); }); @@ -1530,13 +1635,13 @@ void AccessorAssembler::HandleStoreICProtoHandler( VARIABLE(api_holder, MachineRepresentation::kTagged, p->receiver()); Label store(this); - GotoIf(WordEqual(handler_kind, IntPtrConstant(StoreHandler::kApiSetter)), + GotoIf(Word32Equal(handler_kind, Int32Constant(StoreHandler::kApiSetter)), &store); - CSA_ASSERT( - this, - WordEqual(handler_kind, - IntPtrConstant(StoreHandler::kApiSetterHolderIsPrototype))); + CSA_ASSERT(this, + Word32Equal( + handler_kind, + Int32Constant(StoreHandler::kApiSetterHolderIsPrototype))); api_holder.Bind(LoadMapPrototype(LoadMap(p->receiver()))); Goto(&store); @@ -1559,8 +1664,8 @@ void AccessorAssembler::HandleStoreICProtoHandler( void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, Node* proxy, Label* miss, ElementSupport support_elements) { - VARIABLE(var_index, MachineType::PointerRepresentation()); - VARIABLE(var_unique, MachineRepresentation::kTagged); + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); Label if_index(this), if_unique_name(this), to_name_failed(this, Label::kDeferred); @@ -1591,128 +1696,200 @@ void AccessorAssembler::HandleStoreToProxy(const StoreICParameters* p, } } -void AccessorAssembler::HandleStoreICSmiHandlerCase(Node* handler_word, - Node* holder, Node* value, - Label* miss) { +void AccessorAssembler::HandleStoreICSmiHandlerCase( + SloppyTNode<Word32T> handler_word, SloppyTNode<JSObject> holder, + SloppyTNode<Object> value, Label* miss) { Comment("field store"); #ifdef DEBUG - TNode<UintPtrT> handler_kind = - DecodeWord<StoreHandler::KindBits>(handler_word); + TNode<Uint32T> handler_kind = + DecodeWord32<StoreHandler::KindBits>(handler_word); CSA_ASSERT( this, Word32Or( - WordEqual(handler_kind, IntPtrConstant(StoreHandler::kField)), - WordEqual(handler_kind, IntPtrConstant(StoreHandler::kConstField)))); + Word32Equal(handler_kind, Int32Constant(StoreHandler::kField)), + Word32Equal(handler_kind, Int32Constant(StoreHandler::kConstField)))); #endif - TNode<UintPtrT> field_representation = - DecodeWord<StoreHandler::FieldRepresentationBits>(handler_word); + TNode<Uint32T> field_representation = + DecodeWord32<StoreHandler::RepresentationBits>(handler_word); Label if_smi_field(this), if_double_field(this), if_heap_object_field(this), if_tagged_field(this); - GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kTagged)), - &if_tagged_field); - GotoIf(WordEqual(field_representation, - IntPtrConstant(StoreHandler::kHeapObject)), - &if_heap_object_field); - GotoIf(WordEqual(field_representation, IntPtrConstant(StoreHandler::kDouble)), - &if_double_field); - CSA_ASSERT(this, WordEqual(field_representation, - IntPtrConstant(StoreHandler::kSmi))); - Goto(&if_smi_field); + int32_t case_values[] = {Representation::kTagged, Representation::kHeapObject, + Representation::kSmi}; + Label* case_labels[] = {&if_tagged_field, &if_heap_object_field, + &if_smi_field}; + + Switch(field_representation, &if_double_field, case_values, case_labels, 3); BIND(&if_tagged_field); { Comment("store tagged field"); - HandleStoreFieldAndReturn(handler_word, holder, Representation::Tagged(), - value, miss); - } - - BIND(&if_double_field); - { - Comment("store double field"); - HandleStoreFieldAndReturn(handler_word, holder, Representation::Double(), - value, miss); + HandleStoreFieldAndReturn(handler_word, holder, value, base::nullopt, + Representation::Tagged(), miss); } BIND(&if_heap_object_field); { + Comment("heap object field checks"); + CheckHeapObjectTypeMatchesDescriptor(handler_word, holder, value, miss); + Comment("store heap object field"); - HandleStoreFieldAndReturn(handler_word, holder, - Representation::HeapObject(), value, miss); + HandleStoreFieldAndReturn(handler_word, holder, value, base::nullopt, + Representation::HeapObject(), miss); } BIND(&if_smi_field); { + Comment("smi field checks"); + GotoIfNot(TaggedIsSmi(value), miss); + Comment("store smi field"); - HandleStoreFieldAndReturn(handler_word, holder, Representation::Smi(), - value, miss); + HandleStoreFieldAndReturn(handler_word, holder, value, base::nullopt, + Representation::Smi(), miss); + } + + BIND(&if_double_field); + { + CSA_ASSERT(this, Word32Equal(field_representation, + Int32Constant(Representation::kDouble))); + Comment("double field checks"); + TNode<Float64T> double_value = TryTaggedToFloat64(value, miss); + CheckDescriptorConsidersNumbersMutable(handler_word, holder, miss); + + Comment("store double field"); + HandleStoreFieldAndReturn(handler_word, holder, value, double_value, + Representation::Double(), miss); } } -void AccessorAssembler::HandleStoreFieldAndReturn(Node* handler_word, - Node* holder, - Representation representation, - Node* value, Label* miss) { - Node* prepared_value = - PrepareValueForStore(handler_word, holder, representation, value, miss); +void AccessorAssembler::CheckHeapObjectTypeMatchesDescriptor( + TNode<Word32T> handler_word, TNode<JSObject> holder, TNode<Object> value, + Label* bailout) { + GotoIf(TaggedIsSmi(value), bailout); - Label if_inobject(this), if_out_of_object(this); - Branch(IsSetWord<StoreHandler::IsInobjectBits>(handler_word), &if_inobject, - &if_out_of_object); + Label done(this); + // Skip field type check in favor of constant value check when storing + // to constant field. + GotoIf(Word32Equal(DecodeWord32<StoreHandler::KindBits>(handler_word), + Int32Constant(StoreHandler::kConstField)), + &done); + TNode<IntPtrT> descriptor = + Signed(DecodeWordFromWord32<StoreHandler::DescriptorBits>(handler_word)); + TNode<MaybeObject> maybe_field_type = + LoadDescriptorValueOrFieldType(LoadMap(holder), descriptor); - BIND(&if_inobject); + GotoIf(TaggedIsSmi(maybe_field_type), &done); + // Check that value type matches the field type. { - StoreNamedField(handler_word, holder, true, representation, prepared_value, - miss); - Return(value); + TNode<HeapObject> field_type = + GetHeapObjectAssumeWeak(maybe_field_type, bailout); + Branch(TaggedEqual(LoadMap(CAST(value)), field_type), &done, bailout); } + BIND(&done); +} - BIND(&if_out_of_object); - { - StoreNamedField(handler_word, holder, false, representation, prepared_value, - miss); - Return(value); - } +void AccessorAssembler::CheckDescriptorConsidersNumbersMutable( + TNode<Word32T> handler_word, TNode<JSObject> holder, Label* bailout) { + // We have to check that the representation is Double. Checking the value + // (either in the field or being assigned) is not enough, as we could have + // transitioned to Tagged but still be holding a HeapNumber, which would no + // longer be allowed to be mutable. + + // TODO(leszeks): We could skip the representation check in favor of a + // constant value check in HandleStoreFieldAndReturn here, but then + // HandleStoreFieldAndReturn would need an IsHeapNumber check in case both the + // representation changed and the value is no longer a HeapNumber. + TNode<IntPtrT> descriptor_entry = + Signed(DecodeWordFromWord32<StoreHandler::DescriptorBits>(handler_word)); + TNode<DescriptorArray> descriptors = LoadMapDescriptors(LoadMap(holder)); + TNode<Uint32T> details = + LoadDetailsByDescriptorEntry(descriptors, descriptor_entry); + + GotoIfNot(IsEqualInWord32<PropertyDetails::RepresentationField>( + details, Representation::kDouble), + bailout); } -Node* AccessorAssembler::PrepareValueForStore(Node* handler_word, Node* holder, - Representation representation, - Node* value, Label* bailout) { - if (representation.IsDouble()) { - value = TryTaggedToFloat64(value, bailout); +void AccessorAssembler::HandleStoreFieldAndReturn( + TNode<Word32T> handler_word, TNode<JSObject> holder, TNode<Object> value, + base::Optional<TNode<Float64T>> double_value, Representation representation, + Label* miss) { + Label done(this); - } else if (representation.IsHeapObject()) { - GotoIf(TaggedIsSmi(value), bailout); + bool store_value_as_double = representation.IsDouble(); - Label done(this); - // Skip field type check in favor of constant value check when storing - // to constant field. - GotoIf(WordEqual(DecodeWord<StoreHandler::KindBits>(handler_word), - IntPtrConstant(StoreHandler::kConstField)), - &done); - TNode<IntPtrT> descriptor = - Signed(DecodeWord<StoreHandler::DescriptorBits>(handler_word)); - TNode<MaybeObject> maybe_field_type = - LoadDescriptorValueOrFieldType(LoadMap(holder), descriptor); + TNode<BoolT> is_inobject = + IsSetWord32<StoreHandler::IsInobjectBits>(handler_word); + TNode<HeapObject> property_storage = Select<HeapObject>( + is_inobject, [&]() { return holder; }, + [&]() { return LoadFastProperties(holder); }); - GotoIf(TaggedIsSmi(maybe_field_type), &done); - // Check that value type matches the field type. - { - TNode<HeapObject> field_type = - GetHeapObjectAssumeWeak(maybe_field_type, bailout); - Branch(TaggedEqual(LoadMap(CAST(value)), field_type), &done, bailout); + TNode<UintPtrT> index = + DecodeWordFromWord32<StoreHandler::FieldIndexBits>(handler_word); + TNode<IntPtrT> offset = Signed(TimesTaggedSize(index)); + + // For Double fields, we want to mutate the current double-value + // field rather than changing it to point at a new HeapNumber. + if (store_value_as_double) { + TVARIABLE(HeapObject, actual_property_storage, property_storage); + TVARIABLE(IntPtrT, actual_offset, offset); + + Label property_and_offset_ready(this); + + // If we are unboxing double fields, and this is an in-object field, the + // property_storage and offset are already pointing to the double-valued + // field. + if (FLAG_unbox_double_fields) { + GotoIf(is_inobject, &property_and_offset_ready); } - BIND(&done); - } else if (representation.IsSmi()) { - GotoIfNot(TaggedIsSmi(value), bailout); + // Store the double value directly into the mutable HeapNumber. + TNode<Object> field = LoadObjectField(property_storage, offset); + CSA_ASSERT(this, IsHeapNumber(CAST(field))); + actual_property_storage = CAST(field); + actual_offset = IntPtrConstant(HeapNumber::kValueOffset); + Goto(&property_and_offset_ready); + + BIND(&property_and_offset_ready); + property_storage = actual_property_storage.value(); + offset = actual_offset.value(); + } + + // Do constant value check if necessary. + Label do_store(this); + GotoIfNot(Word32Equal(DecodeWord32<StoreHandler::KindBits>(handler_word), + Int32Constant(StoreHandler::kConstField)), + &do_store); + { + if (store_value_as_double) { + Label done(this); + TNode<Float64T> current_value = + LoadObjectField<Float64T>(property_storage, offset); + BranchIfSameNumberValue(current_value, *double_value, &done, miss); + BIND(&done); + Return(value); + } else { + TNode<Object> current_value = LoadObjectField(property_storage, offset); + GotoIfNot(TaggedEqual(current_value, value), miss); + Return(value); + } + } + BIND(&do_store); + // Do the store. + if (store_value_as_double) { + StoreObjectFieldNoWriteBarrier(property_storage, offset, *double_value, + MachineRepresentation::kFloat64); + } else if (representation.IsSmi()) { + TNode<Smi> value_smi = CAST(value); + StoreObjectFieldNoWriteBarrier(property_storage, offset, value_smi); } else { - DCHECK(representation.IsTagged()); + StoreObjectField(property_storage, offset, value); } - return value; + + Return(value); } Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, @@ -1737,7 +1914,7 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, BIND(&if_smi_hash); { TNode<Int32T> hash = SmiToInt32(CAST(properties)); - TNode<Word32T> encoded_hash = + TNode<Int32T> encoded_hash = Word32Shl(hash, Int32Constant(PropertyArray::HashField::kShift)); var_encoded_hash.Bind(encoded_hash); var_length.Bind(IntPtrOrSmiConstant(0, mode)); @@ -1813,59 +1990,6 @@ Node* AccessorAssembler::ExtendPropertiesBackingStore(Node* object, } } -void AccessorAssembler::StoreNamedField(Node* handler_word, Node* object, - bool is_inobject, - Representation representation, - Node* value, Label* bailout) { - bool store_value_as_double = representation.IsDouble(); - Node* property_storage = object; - if (!is_inobject) { - property_storage = LoadFastProperties(object); - } - - TNode<UintPtrT> index = - DecodeWord<StoreHandler::FieldIndexBits>(handler_word); - TNode<IntPtrT> offset = Signed(TimesTaggedSize(index)); - if (representation.IsDouble()) { - if (!FLAG_unbox_double_fields || !is_inobject) { - // Load the mutable heap number. - property_storage = LoadObjectField(property_storage, offset); - // Store the double value into it. - offset = IntPtrConstant(HeapNumber::kValueOffset); - } - } - - // Do constant value check if necessary. - Label const_checked(this); - GotoIfNot(WordEqual(DecodeWord<StoreHandler::KindBits>(handler_word), - IntPtrConstant(StoreHandler::kConstField)), - &const_checked); - { - if (store_value_as_double) { - TNode<Float64T> current_value = - LoadObjectField<Float64T>(CAST(property_storage), offset); - BranchIfSameNumberValue(current_value, UncheckedCast<Float64T>(value), - &const_checked, bailout); - } else { - TNode<Object> current_value = LoadObjectField(property_storage, offset); - Branch(TaggedEqual(current_value, UncheckedCast<Object>(value)), - &const_checked, bailout); - } - } - - BIND(&const_checked); - // Do the store. - if (store_value_as_double) { - StoreObjectFieldNoWriteBarrier(property_storage, offset, value, - MachineRepresentation::kFloat64); - } else if (representation.IsSmi()) { - TNode<Smi> value_smi = CAST(value); - StoreObjectFieldNoWriteBarrier(property_storage, offset, value_smi); - } else { - StoreObjectField(property_storage, offset, value); - } -} - void AccessorAssembler::EmitFastElementsBoundsCheck(Node* object, Node* elements, Node* intptr_index, @@ -2012,8 +2136,7 @@ void AccessorAssembler::EmitElementLoad( if (access_mode == LoadAccessMode::kHas) { exit_point->Return(TrueConstant()); } else { - TNode<RawPtrT> backing_store = - LoadJSTypedArrayBackingStore(CAST(object)); + TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(object)); Label uint8_elements(this), int8_elements(this), uint16_elements(this), int16_elements(this), uint32_elements(this), int32_elements(this), @@ -2039,50 +2162,48 @@ void AccessorAssembler::EmitElementLoad( BIND(&uint8_elements); { Comment("UINT8_ELEMENTS"); // Handles UINT8_CLAMPED_ELEMENTS too. - Node* element = - Load(MachineType::Uint8(), backing_store, intptr_index); + Node* element = Load(MachineType::Uint8(), data_ptr, intptr_index); exit_point->Return(SmiFromInt32(element)); } BIND(&int8_elements); { Comment("INT8_ELEMENTS"); - Node* element = - Load(MachineType::Int8(), backing_store, intptr_index); + Node* element = Load(MachineType::Int8(), data_ptr, intptr_index); exit_point->Return(SmiFromInt32(element)); } BIND(&uint16_elements); { Comment("UINT16_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(1)); - Node* element = Load(MachineType::Uint16(), backing_store, index); + Node* element = Load(MachineType::Uint16(), data_ptr, index); exit_point->Return(SmiFromInt32(element)); } BIND(&int16_elements); { Comment("INT16_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(1)); - Node* element = Load(MachineType::Int16(), backing_store, index); + Node* element = Load(MachineType::Int16(), data_ptr, index); exit_point->Return(SmiFromInt32(element)); } BIND(&uint32_elements); { Comment("UINT32_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); - Node* element = Load(MachineType::Uint32(), backing_store, index); + Node* element = Load(MachineType::Uint32(), data_ptr, index); exit_point->Return(ChangeUint32ToTagged(element)); } BIND(&int32_elements); { Comment("INT32_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); - Node* element = Load(MachineType::Int32(), backing_store, index); + Node* element = Load(MachineType::Int32(), data_ptr, index); exit_point->Return(ChangeInt32ToTagged(element)); } BIND(&float32_elements); { Comment("FLOAT32_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(2)); - Node* element = Load(MachineType::Float32(), backing_store, index); + Node* element = Load(MachineType::Float32(), data_ptr, index); var_double_value->Bind(ChangeFloat32ToFloat64(element)); Goto(rebox_double); } @@ -2090,7 +2211,7 @@ void AccessorAssembler::EmitElementLoad( { Comment("FLOAT64_ELEMENTS"); TNode<IntPtrT> index = WordShl(intptr_index, IntPtrConstant(3)); - Node* element = Load(MachineType::Float64(), backing_store, index); + Node* element = Load(MachineType::Float64(), data_ptr, index); var_double_value->Bind(element); Goto(rebox_double); } @@ -2098,15 +2219,13 @@ void AccessorAssembler::EmitElementLoad( { Comment("BIGINT64_ELEMENTS"); exit_point->Return(LoadFixedTypedArrayElementAsTagged( - backing_store, intptr_index, BIGINT64_ELEMENTS, - INTPTR_PARAMETERS)); + data_ptr, intptr_index, BIGINT64_ELEMENTS, INTPTR_PARAMETERS)); } BIND(&biguint64_elements); { Comment("BIGUINT64_ELEMENTS"); exit_point->Return(LoadFixedTypedArrayElementAsTagged( - backing_store, intptr_index, BIGUINT64_ELEMENTS, - INTPTR_PARAMETERS)); + data_ptr, intptr_index, BIGUINT64_ELEMENTS, INTPTR_PARAMETERS)); } } } @@ -2152,7 +2271,8 @@ void AccessorAssembler::InvalidateValidityCellIfPrototype(Node* map, BIND(&cont); } -void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, +void AccessorAssembler::GenericElementLoad(Node* receiver, + TNode<Map> receiver_map, SloppyTNode<Int32T> instance_type, Node* index, Label* slow) { Comment("integer index"); @@ -2213,11 +2333,9 @@ void AccessorAssembler::GenericElementLoad(Node* receiver, Node* receiver_map, } } -void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, - SloppyTNode<Int32T> instance_type, - const LoadICParameters* p, - Label* slow, - UseStubCache use_stub_cache) { +void AccessorAssembler::GenericPropertyLoad( + Node* receiver, TNode<Map> receiver_map, SloppyTNode<Int32T> instance_type, + const LoadICParameters* p, Label* slow, UseStubCache use_stub_cache) { ExitPoint direct_exit(this); Comment("key is unique name"); @@ -2317,13 +2435,13 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, BIND(&lookup_prototype_chain); { - VARIABLE(var_holder_map, MachineRepresentation::kTagged); + TVARIABLE(Map, var_holder_map); VARIABLE(var_holder_instance_type, MachineRepresentation::kWord32); Label return_undefined(this), is_private_symbol(this); Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; Label loop(this, arraysize(merged_variables), merged_variables); - var_holder_map.Bind(receiver_map); + var_holder_map = receiver_map; var_holder_instance_type.Bind(instance_type); GotoIf(IsPrivateSymbol(name), &is_private_symbol); @@ -2338,7 +2456,7 @@ void AccessorAssembler::GenericPropertyLoad(Node* receiver, Node* receiver_map, GotoIf(TaggedEqual(proto, NullConstant()), &return_undefined); TNode<Map> proto_map = LoadMap(proto); TNode<Uint16T> proto_instance_type = LoadMapInstanceType(proto_map); - var_holder_map.Bind(proto_map); + var_holder_map = proto_map; var_holder_instance_type.Bind(proto_instance_type); Label next_proto(this), return_value(this, &var_value), goto_slow(this); TryGetOwnProperty(p->context(), receiver, proto, proto_map, @@ -2394,8 +2512,6 @@ enum AccessorAssembler::StubCacheTable : int { }; Node* AccessorAssembler::StubCachePrimaryOffset(Node* name, Node* map) { - // See v8::internal::StubCache::PrimaryOffset(). - STATIC_ASSERT(StubCache::kCacheIndexShift == Name::kHashShift); // Compute the hash of the name (use entire hash field). TNode<Uint32T> hash_field = LoadNameHashField(name); CSA_ASSERT(this, @@ -2422,7 +2538,7 @@ Node* AccessorAssembler::StubCacheSecondaryOffset(Node* name, Node* seed) { // Use the seed from the primary cache in the secondary cache. TNode<Int32T> name32 = TruncateIntPtrToInt32(BitcastTaggedToWord(name)); - TNode<Word32T> hash = Int32Sub(TruncateIntPtrToInt32(seed), name32); + TNode<Int32T> hash = Int32Sub(TruncateIntPtrToInt32(seed), name32); hash = Int32Add(hash, Int32Constant(StubCache::kSecondaryMagic)); int32_t mask = (StubCache::kSecondaryTableSize - 1) << StubCache::kCacheIndexShift; @@ -2436,7 +2552,8 @@ void AccessorAssembler::TryProbeStubCacheTable( StubCache::Table table = static_cast<StubCache::Table>(table_id); // The {table_offset} holds the entry offset times four (due to masking // and shifting optimizations). - const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; + const int kMultiplier = + sizeof(StubCache::Entry) >> StubCache::kCacheIndexShift; entry_offset = IntPtrMul(entry_offset, IntPtrConstant(kMultiplier)); TNode<ExternalReference> key_base = ExternalConstant( @@ -2527,7 +2644,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p, Label try_polymorphic(this), if_handler(this, &var_handler); TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), recv_map, &if_handler, + TryMonomorphicCase(p->slot(), CAST(p->vector()), recv_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); @@ -2589,8 +2706,8 @@ void AccessorAssembler::LoadIC(const LoadICParameters* p) { // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, - &var_handler, &try_polymorphic); + TryMonomorphicCase(p->slot(), CAST(p->vector()), receiver_map, + &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { LazyLoadICParameters lazy_p(p); @@ -2673,21 +2790,25 @@ void AccessorAssembler::LoadIC_NoFeedback(const LoadICParameters* p) { } } -void AccessorAssembler::LoadGlobalIC(Node* vector, Node* slot, +void AccessorAssembler::LoadGlobalIC(TNode<HeapObject> maybe_feedback_vector, + const LazyNode<Smi>& lazy_smi_slot, + const LazyNode<UintPtrT>& lazy_slot, const LazyNode<Context>& lazy_context, const LazyNode<Name>& lazy_name, TypeofMode typeof_mode, - ExitPoint* exit_point, - ParameterMode slot_mode) { + ExitPoint* exit_point) { Label try_handler(this, Label::kDeferred), miss(this, Label::kDeferred); - GotoIf(IsUndefined(vector), &miss); - - LoadGlobalIC_TryPropertyCellCase(CAST(vector), slot, lazy_context, exit_point, - &try_handler, &miss, slot_mode); + GotoIf(IsUndefined(maybe_feedback_vector), &miss); + { + TNode<FeedbackVector> vector = CAST(maybe_feedback_vector); + TNode<UintPtrT> slot = lazy_slot(); + LoadGlobalIC_TryPropertyCellCase(vector, slot, lazy_context, exit_point, + &try_handler, &miss); - BIND(&try_handler); - LoadGlobalIC_TryHandlerCase(CAST(vector), slot, lazy_context, lazy_name, - typeof_mode, exit_point, &miss, slot_mode); + BIND(&try_handler); + LoadGlobalIC_TryHandlerCase(vector, slot, lazy_smi_slot, lazy_context, + lazy_name, typeof_mode, exit_point, &miss); + } BIND(&miss); { @@ -2695,20 +2816,19 @@ void AccessorAssembler::LoadGlobalIC(Node* vector, Node* slot, TNode<Context> context = lazy_context(); TNode<Name> name = lazy_name(); exit_point->ReturnCallRuntime(Runtime::kLoadGlobalIC_Miss, context, name, - ParameterToTagged(slot, slot_mode), vector, + lazy_smi_slot(), maybe_feedback_vector, SmiConstant(typeof_mode)); } } void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( - TNode<FeedbackVector> vector, Node* slot, + TNode<FeedbackVector> vector, TNode<UintPtrT> slot, const LazyNode<Context>& lazy_context, ExitPoint* exit_point, - Label* try_handler, Label* miss, ParameterMode slot_mode) { + Label* try_handler, Label* miss) { Comment("LoadGlobalIC_TryPropertyCellCase"); Label if_lexical_var(this), if_property_cell(this); - TNode<MaybeObject> maybe_weak_ref = - LoadFeedbackVectorSlot(vector, slot, 0, slot_mode); + TNode<MaybeObject> maybe_weak_ref = LoadFeedbackVectorSlot(vector, slot); Branch(TaggedIsSmi(maybe_weak_ref), &if_lexical_var, &if_property_cell); BIND(&if_property_cell); @@ -2739,16 +2859,16 @@ void AccessorAssembler::LoadGlobalIC_TryPropertyCellCase( } void AccessorAssembler::LoadGlobalIC_TryHandlerCase( - TNode<FeedbackVector> vector, Node* slot, - const LazyNode<Context>& lazy_context, const LazyNode<Name>& lazy_name, - TypeofMode typeof_mode, ExitPoint* exit_point, Label* miss, - ParameterMode slot_mode) { + TNode<FeedbackVector> vector, TNode<UintPtrT> slot, + const LazyNode<Smi>& lazy_smi_slot, const LazyNode<Context>& lazy_context, + const LazyNode<Name>& lazy_name, TypeofMode typeof_mode, + ExitPoint* exit_point, Label* miss) { Comment("LoadGlobalIC_TryHandlerCase"); Label call_handler(this), non_smi(this); TNode<MaybeObject> feedback_element = - LoadFeedbackVectorSlot(vector, slot, kTaggedSize, slot_mode); + LoadFeedbackVectorSlot(vector, slot, kTaggedSize); TNode<Object> handler = CAST(feedback_element); GotoIf(TaggedEqual(handler, UninitializedSymbolConstant()), miss); @@ -2757,14 +2877,14 @@ void AccessorAssembler::LoadGlobalIC_TryHandlerCase( : OnNonExistent::kReturnUndefined; TNode<Context> context = lazy_context(); - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSGlobalProxy> receiver = CAST(LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX)); TNode<Object> holder = LoadContextElement(native_context, Context::EXTENSION_INDEX); LazyLoadICParameters p([=] { return context; }, receiver, lazy_name, - ParameterToTagged(slot, slot_mode), vector, holder); + lazy_smi_slot, vector, holder); HandleLoadICHandlerCase(&p, handler, miss, exit_point, ICMode::kGlobalIC, on_nonexistent); @@ -2788,8 +2908,8 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, - &var_handler, &try_polymorphic); + TryMonomorphicCase(p->slot(), CAST(p->vector()), receiver_map, + &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { LazyLoadICParameters lazy_p(p); @@ -2840,13 +2960,13 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, // We might have a name in feedback, and a weak fixed array in the next // slot. Comment("KeyedLoadIC_try_polymorphic_name"); - TVARIABLE(Object, var_name, p->name()); + TVARIABLE(Name, var_name); TVARIABLE(IntPtrT, var_index); - Label if_polymorphic_name(this, &var_name), if_internalized(this), - if_notinternalized(this, Label::kDeferred); + Label if_polymorphic_name(this), feedback_matches(this), + if_internalized(this), if_notinternalized(this, Label::kDeferred); // Fast-case: The recorded {feedback} matches the {name}. - GotoIf(TaggedEqual(strong_feedback, p->name()), &if_polymorphic_name); + GotoIf(TaggedEqual(strong_feedback, p->name()), &feedback_matches); // Try to internalize the {name} if it isn't already. TryToName(p->name(), &miss, &var_index, &if_internalized, &var_name, &miss, @@ -2861,16 +2981,15 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, BIND(&if_notinternalized); { - // Try to internalize the {name}. - TNode<ExternalReference> function = ExternalConstant( - ExternalReference::try_internalize_string_function()); - TNode<ExternalReference> const isolate_ptr = - ExternalConstant(ExternalReference::isolate_address(isolate())); - var_name = CAST( - CallCFunction(function, MachineType::AnyTagged(), - std::make_pair(MachineType::Pointer(), isolate_ptr), - std::make_pair(MachineType::AnyTagged(), p->name()))); - Goto(&if_internalized); + TVARIABLE(IntPtrT, var_index); + TryInternalizeString(CAST(p->name()), &miss, &var_index, &if_internalized, + &var_name, &miss, &miss); + } + + BIND(&feedback_matches); + { + var_name = CAST(p->name()); + Goto(&if_polymorphic_name); } BIND(&if_polymorphic_name); @@ -2896,71 +3015,74 @@ void AccessorAssembler::KeyedLoadIC(const LoadICParameters* p, } void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { - TVARIABLE(IntPtrT, var_index); - TVARIABLE(Object, var_unique, p->name()); - Label if_index(this), if_unique_name(this), if_notunique(this), - if_other(this, Label::kDeferred), if_runtime(this, Label::kDeferred); + TVARIABLE(Object, var_name, p->name()); + Label if_runtime(this, Label::kDeferred); Node* receiver = p->receiver(); GotoIf(TaggedIsSmi(receiver), &if_runtime); GotoIf(IsNullOrUndefined(receiver), &if_runtime); - TryToName(p->name(), &if_index, &var_index, &if_unique_name, &var_unique, - &if_other, &if_notunique); - - BIND(&if_other); { - TNode<Name> name = - CAST(CallBuiltin(Builtins::kToName, p->context(), p->name())); - var_unique = name; - TryToName(name, &if_index, &var_index, &if_unique_name, &var_unique, - &if_runtime, &if_notunique); - } + TVARIABLE(IntPtrT, var_index); + TVARIABLE(Name, var_unique); + Label if_index(this), if_unique_name(this, &var_name), if_notunique(this), + if_other(this, Label::kDeferred); - BIND(&if_index); - { - TNode<Map> receiver_map = LoadMap(receiver); - TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); - GenericElementLoad(receiver, receiver_map, instance_type, var_index.value(), - &if_runtime); - } + TryToName(var_name.value(), &if_index, &var_index, &if_unique_name, + &var_unique, &if_other, &if_notunique); - BIND(&if_unique_name); - { - LoadICParameters pp(p, var_unique.value()); - TNode<Map> receiver_map = LoadMap(receiver); - TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); - GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, - &if_runtime); - } + BIND(&if_unique_name); + { + LoadICParameters pp(p, var_unique.value()); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); + GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, + &if_runtime); + } - BIND(&if_notunique); - { - if (FLAG_internalize_on_the_fly) { - // Ideally we could return undefined directly here if the name is not - // found in the string table, i.e. it was never internalized, but that - // invariant doesn't hold with named property interceptors (at this - // point), so we take the {if_runtime} path instead. - Label if_in_string_table(this); - TryInternalizeString(var_unique.value(), &if_index, &var_index, - &if_in_string_table, &var_unique, &if_runtime, - &if_runtime); + BIND(&if_other); + { + var_name = CallBuiltin(Builtins::kToName, p->context(), var_name.value()); + TryToName(var_name.value(), &if_index, &var_index, &if_unique_name, + &var_unique, &if_runtime, &if_notunique); + } - BIND(&if_in_string_table); - { - // TODO(bmeurer): We currently use a version of GenericPropertyLoad - // here, where we don't try to probe the megamorphic stub cache after - // successfully internalizing the incoming string. Past experiments - // with this have shown that it causes too much traffic on the stub - // cache. We may want to re-evaluate that in the future. - LoadICParameters pp(p, var_unique.value()); - TNode<Map> receiver_map = LoadMap(receiver); - TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); - GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, - &if_runtime, kDontUseStubCache); + BIND(&if_notunique); + { + if (FLAG_internalize_on_the_fly) { + // Ideally we could return undefined directly here if the name is not + // found in the string table, i.e. it was never internalized, but that + // invariant doesn't hold with named property interceptors (at this + // point), so we take the {if_runtime} path instead. + Label if_in_string_table(this); + TryInternalizeString(CAST(var_name.value()), &if_index, &var_index, + &if_in_string_table, &var_unique, &if_runtime, + &if_runtime); + + BIND(&if_in_string_table); + { + // TODO(bmeurer): We currently use a version of GenericPropertyLoad + // here, where we don't try to probe the megamorphic stub cache + // after successfully internalizing the incoming string. Past + // experiments with this have shown that it causes too much traffic + // on the stub cache. We may want to re-evaluate that in the future. + LoadICParameters pp(p, var_unique.value()); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); + GenericPropertyLoad(receiver, receiver_map, instance_type, &pp, + &if_runtime, kDontUseStubCache); + } + } else { + Goto(&if_runtime); } - } else { - Goto(&if_runtime); + } + + BIND(&if_index); + { + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); + GenericElementLoad(receiver, receiver_map, instance_type, + var_index.value(), &if_runtime); } } @@ -2970,7 +3092,7 @@ void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); // TODO(jkummerow): Should we use the GetProperty TF stub instead? TailCallRuntime(Runtime::kGetProperty, p->context(), p->receiver(), - var_unique.value()); + var_name.value()); } } @@ -2982,22 +3104,20 @@ void AccessorAssembler::KeyedLoadICPolymorphicName(const LoadICParameters* p, Node* receiver = p->receiver(); TNode<Map> receiver_map = LoadReceiverMap(receiver); TNode<Name> name = CAST(p->name()); - Node* vector = p->vector(); - Node* slot = p->slot(); + TNode<FeedbackVector> vector = CAST(p->vector()); + TNode<Smi> slot = p->slot(); TNode<Context> context = p->context(); // When we get here, we know that the {name} matches the recorded // feedback name in the {vector} and can safely be used for the // LoadIC handler logic below. CSA_ASSERT(this, Word32BinaryNot(IsDeprecatedMap(receiver_map))); - CSA_ASSERT(this, - TaggedEqual( - name, LoadFeedbackVectorSlot(vector, slot, 0, SMI_PARAMETERS)), + CSA_ASSERT(this, TaggedEqual(name, LoadFeedbackVectorSlot(vector, slot)), name, vector); // Check if we have a matching handler for the {receiver_map}. TNode<MaybeObject> feedback_element = - LoadFeedbackVectorSlot(vector, slot, kTaggedSize, SMI_PARAMETERS); + LoadFeedbackVectorSlot(vector, slot, kTaggedSize); TNode<WeakFixedArray> array = CAST(feedback_element); HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss); @@ -3038,8 +3158,8 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, - &var_handler, &try_polymorphic); + TryMonomorphicCase(p->slot(), CAST(p->vector()), receiver_map, + &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { Comment("StoreIC_if_handler"); @@ -3082,17 +3202,12 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) { void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { Label if_lexical_var(this), if_heapobject(this); TNode<MaybeObject> maybe_weak_ref = - LoadFeedbackVectorSlot(pp->vector(), pp->slot(), 0, SMI_PARAMETERS); + LoadFeedbackVectorSlot(CAST(pp->vector()), pp->slot()); Branch(TaggedIsSmi(maybe_weak_ref), &if_lexical_var, &if_heapobject); BIND(&if_heapobject); { Label try_handler(this), miss(this, Label::kDeferred); - // We use pre-monomorphic state for global stores that run into - // interceptors because the property doesn't exist yet. Using - // pre-monomorphic state gives it a chance to find more information the - // second time. - GotoIf(TaggedEqual(maybe_weak_ref, PremonomorphicSymbolConstant()), &miss); CSA_ASSERT(this, IsWeakOrCleared(maybe_weak_ref)); TNode<PropertyCell> property_cell = @@ -3105,13 +3220,13 @@ void AccessorAssembler::StoreGlobalIC(const StoreICParameters* pp) { BIND(&try_handler); { Comment("StoreGlobalIC_try_handler"); - TNode<MaybeObject> handler = LoadFeedbackVectorSlot( - pp->vector(), pp->slot(), kTaggedSize, SMI_PARAMETERS); + TNode<MaybeObject> handler = + LoadFeedbackVectorSlot(CAST(pp->vector()), pp->slot(), kTaggedSize); GotoIf(TaggedEqual(handler, UninitializedSymbolConstant()), &miss); DCHECK_NULL(pp->receiver()); - TNode<Context> native_context = LoadNativeContext(pp->context()); + TNode<NativeContext> native_context = LoadNativeContext(pp->context()); StoreICParameters p( pp->context(), LoadContextElement(native_context, Context::GLOBAL_PROXY_INDEX), @@ -3225,8 +3340,8 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { // Check monomorphic case. TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), receiver_map, &if_handler, - &var_handler, &try_polymorphic); + TryMonomorphicCase(p->slot(), CAST(p->vector()), receiver_map, + &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { Comment("KeyedStoreIC_if_handler"); @@ -3266,8 +3381,8 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) { GotoIfNot(TaggedEqual(strong_feedback, p->name()), &miss); // If the name comparison succeeded, we know we have a feedback vector // with at least one map/handler pair. - TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot( - p->vector(), p->slot(), kTaggedSize, SMI_PARAMETERS); + TNode<MaybeObject> feedback_element = + LoadFeedbackVectorSlot(CAST(p->vector()), p->slot(), kTaggedSize); TNode<WeakFixedArray> array = CAST(feedback_element); HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss); @@ -3296,16 +3411,20 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { GotoIf(IsUndefined(p->vector()), &miss); TNode<MaybeObject> feedback = - TryMonomorphicCase(p->slot(), p->vector(), array_map, &if_handler, + TryMonomorphicCase(p->slot(), CAST(p->vector()), array_map, &if_handler, &var_handler, &try_polymorphic); BIND(&if_handler); { Comment("StoreInArrayLiteralIC_if_handler"); // This is a stripped-down version of HandleStoreICHandlerCase. + Label if_transitioning_element_store(this), if_smi_handler(this); + + // Check used to identify the Slow case. + // Currently only the Slow case uses a Smi handler. + GotoIf(TaggedIsSmi(var_handler.value()), &if_smi_handler); TNode<HeapObject> handler = CAST(var_handler.value()); - Label if_transitioning_element_store(this); GotoIfNot(IsCode(handler), &if_transitioning_element_store); TailCallStub(StoreWithVectorDescriptor{}, CAST(handler), p->context(), p->receiver(), p->name(), p->value(), p->slot(), @@ -3324,6 +3443,22 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { p->receiver(), p->name(), transition_map, p->value(), p->slot(), p->vector()); } + + BIND(&if_smi_handler); + { +#ifdef DEBUG + // A check to ensure that no other Smi handler uses this path. + TNode<Int32T> handler_word = SmiToInt32(CAST(var_handler.value())); + TNode<Uint32T> handler_kind = + DecodeWord32<StoreHandler::KindBits>(handler_word); + CSA_ASSERT(this, Word32Equal(handler_kind, + Int32Constant(StoreHandler::kSlow))); +#endif + + Comment("StoreInArrayLiteralIC_Slow"); + TailCallRuntime(Runtime::kStoreInArrayLiteralIC_Slow, p->context(), + p->value(), p->receiver(), p->name()); + } } BIND(&try_polymorphic); @@ -3366,7 +3501,7 @@ void AccessorAssembler::GenerateLoadIC() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3379,7 +3514,7 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3392,7 +3527,7 @@ void AccessorAssembler::GenerateLoadIC_Megamorphic() { BIND(&if_handler); LazyLoadICParameters p([=] { return context; }, receiver, - [=] { return name; }, slot, vector); + [=] { return name; }, [=] { return slot; }, vector); HandleLoadICHandlerCase(&p, CAST(var_handler.value()), &miss, &direct_exit); BIND(&miss); @@ -3405,8 +3540,8 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); + TNode<FeedbackVector> vector = CAST(Parameter(Descriptor::kVector)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ExitPoint direct_exit(this); @@ -3414,8 +3549,7 @@ void AccessorAssembler::GenerateLoadIC_Noninlined() { Label if_handler(this, &var_handler), miss(this, Label::kDeferred); TNode<Map> receiver_map = LoadReceiverMap(receiver); - TNode<MaybeObject> feedback_element = - LoadFeedbackVectorSlot(vector, slot, 0, SMI_PARAMETERS); + TNode<MaybeObject> feedback_element = LoadFeedbackVectorSlot(vector, slot); TNode<HeapObject> feedback = CAST(feedback_element); LoadICParameters p(context, receiver, name, slot, vector); @@ -3439,7 +3573,7 @@ void AccessorAssembler::GenerateLoadIC_NoFeedback() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); LoadICParameters p(context, receiver, name, slot, UndefinedConstant()); @@ -3475,13 +3609,17 @@ void AccessorAssembler::GenerateLoadGlobalIC(TypeofMode typeof_mode) { using Descriptor = LoadGlobalWithVectorDescriptor; TNode<Name> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); - Node* vector = Parameter(Descriptor::kVector); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); + TNode<HeapObject> vector = CAST(Parameter(Descriptor::kVector)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); ExitPoint direct_exit(this); LoadGlobalIC( - vector, slot, + vector, + // lazy_smi_slot + [=] { return slot; }, + // lazy_slot + [=] { return Unsigned(SmiUntag(slot)); }, // lazy_context [=] { return context; }, // lazy_name @@ -3506,7 +3644,7 @@ void AccessorAssembler::GenerateKeyedLoadIC() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3519,7 +3657,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3532,7 +3670,7 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); @@ -3545,7 +3683,7 @@ void AccessorAssembler::GenerateKeyedLoadICTrampoline_Megamorphic() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); @@ -3558,7 +3696,7 @@ void AccessorAssembler::GenerateKeyedLoadIC_PolymorphicName() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3571,7 +3709,7 @@ void AccessorAssembler::GenerateStoreGlobalIC() { TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3584,7 +3722,7 @@ void AccessorAssembler::GenerateStoreGlobalICTrampoline() { TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); @@ -3597,7 +3735,7 @@ void AccessorAssembler::GenerateStoreIC() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3611,7 +3749,7 @@ void AccessorAssembler::GenerateStoreICTrampoline() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); @@ -3625,7 +3763,7 @@ void AccessorAssembler::GenerateKeyedStoreIC() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3639,7 +3777,7 @@ void AccessorAssembler::GenerateKeyedStoreICTrampoline() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<FeedbackVector> vector = LoadFeedbackVectorForStub(); @@ -3653,7 +3791,7 @@ void AccessorAssembler::GenerateStoreInArrayLiteralIC() { Node* array = Parameter(Descriptor::kReceiver); TNode<Object> index = CAST(Parameter(Descriptor::kName)); Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3671,7 +3809,7 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() { // can be tail called from it. However, the feedback slot and vector are not // used. - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); TNode<JSFunction> object_fn = CAST(LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX)); TNode<Map> initial_map = CAST( @@ -3724,7 +3862,7 @@ void AccessorAssembler::GenerateCloneObjectIC() { TNode<Object> source = CAST(Parameter(Descriptor::kSource)); TNode<Smi> flags = CAST(Parameter(Descriptor::kFlags)); TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); - TNode<HeapObject> vector = CAST(Parameter(Descriptor::kVector)); + TNode<HeapObject> maybe_vector = CAST(Parameter(Descriptor::kVector)); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TVARIABLE(MaybeObject, var_handler); Label if_handler(this, &var_handler), miss(this, Label::kDeferred), @@ -3734,10 +3872,11 @@ void AccessorAssembler::GenerateCloneObjectIC() { TNode<Map> source_map = LoadReceiverMap(source); GotoIf(IsDeprecatedMap(source_map), &miss); - GotoIf(IsUndefined(vector), &slow); + GotoIf(IsUndefined(maybe_vector), &slow); - TNode<MaybeObject> feedback = TryMonomorphicCase( - slot, vector, source_map, &if_handler, &var_handler, &try_polymorphic); + TNode<MaybeObject> feedback = + TryMonomorphicCase(slot, CAST(maybe_vector), source_map, &if_handler, + &var_handler, &try_polymorphic); BIND(&if_handler); { @@ -3801,30 +3940,28 @@ void AccessorAssembler::GenerateCloneObjectIC() { // Just copy the fields as raw data (pretending that there are no mutable // HeapNumbers). This doesn't need write barriers. - BuildFastLoop( + BuildFastLoop<IntPtrT>( source_start, source_size, - [=](Node* field_index) { - TNode<IntPtrT> field_offset = - TimesTaggedSize(UncheckedCast<IntPtrT>(field_index)); + [=](TNode<IntPtrT> field_index) { + TNode<IntPtrT> field_offset = TimesTaggedSize(field_index); TNode<TaggedT> field = LoadObjectField<TaggedT>(CAST(source), field_offset); TNode<IntPtrT> result_offset = IntPtrAdd(field_offset, field_offset_difference); StoreObjectFieldNoWriteBarrier(object, result_offset, field); }, - 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + 1, IndexAdvanceMode::kPost); // If mutable HeapNumbers can occur, we need to go through the {object} // again here and properly clone them. We use a second loop here to // ensure that the GC (and heap verifier) always sees properly initialized // objects, i.e. never hits undefined values in double fields. if (!FLAG_unbox_double_fields) { - BuildFastLoop( + BuildFastLoop<IntPtrT>( source_start, source_size, - [=](Node* field_index) { - TNode<IntPtrT> result_offset = - IntPtrAdd(TimesTaggedSize(UncheckedCast<IntPtrT>(field_index)), - field_offset_difference); + [=](TNode<IntPtrT> field_index) { + TNode<IntPtrT> result_offset = IntPtrAdd( + TimesTaggedSize(field_index), field_offset_difference); TNode<Object> field = LoadObjectField(object, result_offset); Label if_done(this), if_mutableheapnumber(this, Label::kDeferred); GotoIf(TaggedIsSmi(field), &if_done); @@ -3838,7 +3975,7 @@ void AccessorAssembler::GenerateCloneObjectIC() { } BIND(&if_done); }, - 1, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); + 1, IndexAdvanceMode::kPost); } Return(object); @@ -3867,14 +4004,15 @@ void AccessorAssembler::GenerateCloneObjectIC() { BIND(&slow); { TailCallBuiltin(Builtins::kCloneObjectIC_Slow, context, source, flags, slot, - vector); + maybe_vector); } BIND(&miss); { Comment("CloneObjectIC_miss"); - TNode<HeapObject> map_or_result = CAST(CallRuntime( - Runtime::kCloneObjectIC_Miss, context, source, flags, slot, vector)); + TNode<HeapObject> map_or_result = + CAST(CallRuntime(Runtime::kCloneObjectIC_Miss, context, source, flags, + slot, maybe_vector)); var_handler = UncheckedCast<MaybeObject>(map_or_result); GotoIf(IsMap(map_or_result), &if_handler); CSA_ASSERT(this, IsJSObject(map_or_result)); @@ -3887,7 +4025,7 @@ void AccessorAssembler::GenerateKeyedHasIC() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3911,7 +4049,7 @@ void AccessorAssembler::GenerateKeyedHasIC_PolymorphicName() { Node* receiver = Parameter(Descriptor::kReceiver); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* slot = Parameter(Descriptor::kSlot); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); Node* vector = Parameter(Descriptor::kVector); TNode<Context> context = CAST(Parameter(Descriptor::kContext)); @@ -3919,5 +4057,54 @@ void AccessorAssembler::GenerateKeyedHasIC_PolymorphicName() { KeyedLoadICPolymorphicName(&p, LoadAccessMode::kHas); } +void AccessorAssembler::BranchIfPrototypesHaveNoElements( + TNode<Map> receiver_map, Label* definitely_no_elements, + Label* possibly_elements) { + TVARIABLE(Map, var_map, receiver_map); + Label loop_body(this, &var_map); + TNode<FixedArray> empty_fixed_array = EmptyFixedArrayConstant(); + TNode<NumberDictionary> empty_slow_element_dictionary = + EmptySlowElementDictionaryConstant(); + Goto(&loop_body); + + BIND(&loop_body); + { + TNode<Map> map = var_map.value(); + TNode<HeapObject> prototype = LoadMapPrototype(map); + GotoIf(IsNull(prototype), definitely_no_elements); + TNode<Map> prototype_map = LoadMap(prototype); + TNode<Uint16T> prototype_instance_type = LoadMapInstanceType(prototype_map); + + // Pessimistically assume elements if a Proxy, Special API Object, + // or JSPrimitiveWrapper wrapper is found on the prototype chain. After this + // instance type check, it's not necessary to check for interceptors or + // access checks. + Label if_custom(this, Label::kDeferred), if_notcustom(this); + Branch(IsCustomElementsReceiverInstanceType(prototype_instance_type), + &if_custom, &if_notcustom); + + BIND(&if_custom); + { + // For string JSPrimitiveWrapper wrappers we still support the checks as + // long as they wrap the empty string. + GotoIfNot( + InstanceTypeEqual(prototype_instance_type, JS_PRIMITIVE_WRAPPER_TYPE), + possibly_elements); + TNode<Object> prototype_value = + LoadJSPrimitiveWrapperValue(CAST(prototype)); + Branch(IsEmptyString(prototype_value), &if_notcustom, possibly_elements); + } + + BIND(&if_notcustom); + { + TNode<FixedArrayBase> prototype_elements = LoadElements(CAST(prototype)); + var_map = prototype_map; + GotoIf(TaggedEqual(prototype_elements, empty_fixed_array), &loop_body); + Branch(TaggedEqual(prototype_elements, empty_slow_element_dictionary), + &loop_body, possibly_elements); + } + } +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/ic/accessor-assembler.h b/deps/v8/src/ic/accessor-assembler.h index 0de2292fd6d4a2..ccc2de9323a167 100644 --- a/deps/v8/src/ic/accessor-assembler.h +++ b/deps/v8/src/ic/accessor-assembler.h @@ -5,6 +5,7 @@ #ifndef V8_IC_ACCESSOR_ASSEMBLER_H_ #define V8_IC_ACCESSOR_ASSEMBLER_H_ +#include "src/base/optional.h" #include "src/codegen/code-stub-assembler.h" namespace v8 { @@ -19,10 +20,6 @@ class ExitPoint; class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { public: using Node = compiler::Node; - template <class T> - using TNode = compiler::TNode<T>; - template <class T> - using SloppyTNode = compiler::SloppyTNode<T>; explicit AccessorAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} @@ -69,7 +66,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { struct LoadICParameters { LoadICParameters(TNode<Context> context, Node* receiver, TNode<Object> name, - Node* slot, Node* vector, Node* holder = nullptr) + TNode<Smi> slot, Node* vector, Node* holder = nullptr) : context_(context), receiver_(receiver), name_(name), @@ -88,7 +85,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<Context> context() const { return context_; } Node* receiver() const { return receiver_; } TNode<Object> name() const { return name_; } - Node* slot() const { return slot_; } + TNode<Smi> slot() const { return slot_; } Node* vector() const { return vector_; } Node* holder() const { return holder_; } @@ -96,15 +93,15 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<Context> context_; Node* receiver_; TNode<Object> name_; - Node* slot_; + TNode<Smi> slot_; Node* vector_; Node* holder_; }; struct LazyLoadICParameters { LazyLoadICParameters(LazyNode<Context> context, Node* receiver, - LazyNode<Object> name, Node* slot, Node* vector, - Node* holder = nullptr) + LazyNode<Object> name, LazyNode<Smi> slot, + Node* vector, Node* holder = nullptr) : context_(context), receiver_(receiver), name_(name), @@ -114,19 +111,17 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { explicit LazyLoadICParameters(const LoadICParameters* p) : receiver_(p->receiver()), - slot_(p->slot()), vector_(p->vector()), holder_(p->holder()) { - TNode<Context> p_context = p->context(); - context_ = [=] { return p_context; }; - TNode<Object> p_name = p->name(); - name_ = [=] { return p_name; }; + slot_ = [=] { return p->slot(); }; + context_ = [=] { return p->context(); }; + name_ = [=] { return p->name(); }; } TNode<Context> context() const { return context_(); } Node* receiver() const { return receiver_; } TNode<Object> name() const { return name_(); } - Node* slot() const { return slot_; } + TNode<Smi> slot() const { return slot_(); } Node* vector() const { return vector_; } Node* holder() const { return holder_; } @@ -134,16 +129,17 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { LazyNode<Context> context_; Node* receiver_; LazyNode<Object> name_; - Node* slot_; + LazyNode<Smi> slot_; Node* vector_; Node* holder_; }; - void LoadGlobalIC(Node* vector, Node* slot, + void LoadGlobalIC(TNode<HeapObject> maybe_feedback_vector, + const LazyNode<Smi>& lazy_smi_slot, + const LazyNode<UintPtrT>& lazy_slot, const LazyNode<Context>& lazy_context, const LazyNode<Name>& lazy_name, TypeofMode typeof_mode, - ExitPoint* exit_point, - ParameterMode slot_mode = SMI_PARAMETERS); + ExitPoint* exit_point); // Specialized LoadIC for inlined bytecode handler, hand-tuned to omit frame // construction on common paths. @@ -157,8 +153,8 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { protected: struct StoreICParameters : public LoadICParameters { StoreICParameters(TNode<Context> context, Node* receiver, - TNode<Object> name, SloppyTNode<Object> value, Node* slot, - Node* vector) + TNode<Object> name, SloppyTNode<Object> value, + TNode<Smi> slot, Node* vector) : LoadICParameters(context, receiver, name, slot, vector), value_(value) {} @@ -185,20 +181,22 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { Label* miss, StoreTransitionMapFlags flags); - void JumpIfDataProperty(Node* details, Label* writable, Label* readonly); + void JumpIfDataProperty(TNode<Uint32T> details, Label* writable, + Label* readonly); void InvalidateValidityCellIfPrototype(Node* map, Node* bitfield3 = nullptr); - void OverwriteExistingFastDataProperty(Node* object, Node* object_map, - Node* descriptors, - Node* descriptor_name_index, - Node* details, TNode<Object> value, - Label* slow, + void OverwriteExistingFastDataProperty(SloppyTNode<HeapObject> object, + TNode<Map> object_map, + TNode<DescriptorArray> descriptors, + TNode<IntPtrT> descriptor_name_index, + TNode<Uint32T> details, + TNode<Object> value, Label* slow, bool do_transitioning_store); - void CheckFieldType(TNode<DescriptorArray> descriptors, Node* name_index, - TNode<Word32T> representation, Node* value, - Label* bailout); + void CheckFieldType(TNode<DescriptorArray> descriptors, + TNode<IntPtrT> name_index, TNode<Word32T> representation, + Node* value, Label* bailout); private: // Stub generation entry points. @@ -232,12 +230,11 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { // IC dispatcher behavior. // Checks monomorphic case. Returns {feedback} entry of the vector. - TNode<MaybeObject> TryMonomorphicCase(Node* slot, Node* vector, - Node* receiver_map, Label* if_handler, - TVariable<MaybeObject>* var_handler, - Label* if_miss); - void HandlePolymorphicCase(Node* receiver_map, TNode<WeakFixedArray> feedback, - Label* if_handler, + TNode<MaybeObject> TryMonomorphicCase( + TNode<Smi> slot, TNode<FeedbackVector> vector, TNode<Map> receiver_map, + Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss); + void HandlePolymorphicCase(TNode<Map> receiver_map, + TNode<WeakFixedArray> feedback, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss); @@ -249,15 +246,14 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { ElementSupport support_elements = kOnlyProperties, LoadAccessMode access_mode = LoadAccessMode::kLoad); - void HandleLoadICSmiHandlerCase(const LazyLoadICParameters* p, Node* holder, - SloppyTNode<Smi> smi_handler, - SloppyTNode<Object> handler, Label* miss, - ExitPoint* exit_point, - OnNonExistent on_nonexistent, - ElementSupport support_elements, - LoadAccessMode access_mode); + void HandleLoadICSmiHandlerCase( + const LazyLoadICParameters* p, SloppyTNode<HeapObject> holder, + SloppyTNode<Smi> smi_handler, SloppyTNode<Object> handler, Label* miss, + ExitPoint* exit_point, ICMode ic_mode, OnNonExistent on_nonexistent, + ElementSupport support_elements, LoadAccessMode access_mode); - void HandleLoadICProtoHandler(const LazyLoadICParameters* p, Node* handler, + void HandleLoadICProtoHandler(const LazyLoadICParameters* p, + TNode<DataHandler> handler, Variable* var_holder, Variable* var_smi_handler, Label* if_smi_handler, Label* miss, ExitPoint* exit_point, ICMode ic_mode, @@ -273,40 +269,43 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<WordT> handler_word, TNode<DataHandler> handler, TNode<IntPtrT> handler_kind, ExitPoint* exit_point); - void HandleLoadField(Node* holder, Node* handler_word, + void HandleLoadField(SloppyTNode<JSObject> holder, TNode<WordT> handler_word, Variable* var_double_value, Label* rebox_double, - ExitPoint* exit_point); + Label* miss, ExitPoint* exit_point); void EmitAccessCheck(TNode<Context> expected_native_context, - TNode<Context> context, Node* receiver, + TNode<Context> context, TNode<Object> receiver, Label* can_access, Label* miss); void HandleLoadICSmiHandlerLoadNamedCase( - const LazyLoadICParameters* p, Node* holder, TNode<IntPtrT> handler_kind, - TNode<WordT> handler_word, Label* rebox_double, - Variable* var_double_value, SloppyTNode<Object> handler, Label* miss, - ExitPoint* exit_point, OnNonExistent on_nonexistent, + const LazyLoadICParameters* p, TNode<HeapObject> holder, + TNode<IntPtrT> handler_kind, TNode<WordT> handler_word, + Label* rebox_double, Variable* var_double_value, + SloppyTNode<Object> handler, Label* miss, ExitPoint* exit_point, + ICMode ic_mode, OnNonExistent on_nonexistent, ElementSupport support_elements); void HandleLoadICSmiHandlerHasNamedCase(const LazyLoadICParameters* p, - Node* holder, + TNode<HeapObject> holder, TNode<IntPtrT> handler_kind, - Label* miss, ExitPoint* exit_point); + Label* miss, ExitPoint* exit_point, + ICMode ic_mode); // LoadGlobalIC implementation. - void LoadGlobalIC_TryPropertyCellCase( - TNode<FeedbackVector> vector, Node* slot, - const LazyNode<Context>& lazy_context, ExitPoint* exit_point, - Label* try_handler, Label* miss, - ParameterMode slot_mode = SMI_PARAMETERS); + void LoadGlobalIC_TryPropertyCellCase(TNode<FeedbackVector> vector, + TNode<UintPtrT> slot, + const LazyNode<Context>& lazy_context, + ExitPoint* exit_point, + Label* try_handler, Label* miss); - void LoadGlobalIC_TryHandlerCase(TNode<FeedbackVector> vector, Node* slot, + void LoadGlobalIC_TryHandlerCase(TNode<FeedbackVector> vector, + TNode<UintPtrT> slot, + const LazyNode<Smi>& lazy_smi_slot, const LazyNode<Context>& lazy_context, const LazyNode<Name>& lazy_name, TypeofMode typeof_mode, - ExitPoint* exit_point, Label* miss, - ParameterMode slot_mode); + ExitPoint* exit_point, Label* miss); // StoreIC implementation. @@ -314,59 +313,66 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<StoreHandler> handler, Label* miss, ICMode ic_mode, ElementSupport support_elements); - void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder, - Node* value, Label* miss); - void HandleStoreFieldAndReturn(Node* handler_word, Node* holder, - Representation representation, Node* value, - Label* miss); + void HandleStoreICSmiHandlerCase(SloppyTNode<Word32T> handler_word, + SloppyTNode<JSObject> holder, + SloppyTNode<Object> value, Label* miss); + void HandleStoreFieldAndReturn(TNode<Word32T> handler_word, + TNode<JSObject> holder, TNode<Object> value, + base::Optional<TNode<Float64T>> double_value, + Representation representation, Label* miss); void CheckPrototypeValidityCell(TNode<Object> maybe_validity_cell, Label* miss); - void HandleStoreICNativeDataProperty(const StoreICParameters* p, Node* holder, - Node* handler_word); + void HandleStoreICNativeDataProperty(const StoreICParameters* p, + SloppyTNode<HeapObject> holder, + TNode<Word32T> handler_word); void HandleStoreToProxy(const StoreICParameters* p, Node* proxy, Label* miss, ElementSupport support_elements); - void HandleStoreAccessor(const StoreICParameters* p, Node* holder, - Node* handler_word); + void HandleStoreAccessor(const StoreICParameters* p, + SloppyTNode<HeapObject> holder, + TNode<Word32T> handler_word); // KeyedLoadIC_Generic implementation. - void GenericElementLoad(Node* receiver, Node* receiver_map, + void GenericElementLoad(Node* receiver, TNode<Map> receiver_map, SloppyTNode<Int32T> instance_type, Node* index, Label* slow); enum UseStubCache { kUseStubCache, kDontUseStubCache }; - void GenericPropertyLoad(Node* receiver, Node* receiver_map, + void GenericPropertyLoad(Node* receiver, TNode<Map> receiver_map, SloppyTNode<Int32T> instance_type, const LoadICParameters* p, Label* slow, UseStubCache use_stub_cache = kUseStubCache); // Low-level helpers. - using OnCodeHandler = std::function<void(Node* code_handler)>; - using OnFoundOnReceiver = - std::function<void(Node* properties, Node* name_index)>; + using OnCodeHandler = std::function<void(TNode<Code> code_handler)>; + using OnFoundOnReceiver = std::function<void(TNode<NameDictionary> properties, + TNode<IntPtrT> name_index)>; template <typename ICHandler, typename ICParameters> - Node* HandleProtoHandler(const ICParameters* p, Node* handler, - const OnCodeHandler& on_code_handler, - const OnFoundOnReceiver& on_found_on_receiver, - Label* miss, ICMode ic_mode); - - Node* PrepareValueForStore(Node* handler_word, Node* holder, - Representation representation, Node* value, - Label* bailout); + TNode<Object> HandleProtoHandler( + const ICParameters* p, TNode<DataHandler> handler, + const OnCodeHandler& on_code_handler, + const OnFoundOnReceiver& on_found_on_receiver, Label* miss, + ICMode ic_mode); + + void CheckHeapObjectTypeMatchesDescriptor(TNode<Word32T> handler_word, + TNode<JSObject> holder, + TNode<Object> value, + Label* bailout); + // Double fields store double values in a mutable box, where stores are + // writes into this box rather than HeapNumber assignment. + void CheckDescriptorConsidersNumbersMutable(TNode<Word32T> handler_word, + TNode<JSObject> holder, + Label* bailout); // Extends properties backing store by JSObject::kFieldsAdded elements, // returns updated properties backing store. Node* ExtendPropertiesBackingStore(Node* object, Node* index); - void StoreNamedField(Node* handler_word, Node* object, bool is_inobject, - Representation representation, Node* value, - Label* bailout); - void EmitFastElementsBoundsCheck(Node* object, Node* elements, Node* intptr_index, Node* is_jsarray_condition, Label* miss); @@ -379,7 +385,7 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { LoadAccessMode access_mode = LoadAccessMode::kLoad); void NameDictionaryNegativeLookup(Node* object, SloppyTNode<Name> name, Label* miss); - TNode<BoolT> IsPropertyDetailsConst(Node* details); + TNode<BoolT> IsPropertyDetailsConst(TNode<Uint32T> details); // Stub cache access helpers. @@ -395,6 +401,10 @@ class V8_EXPORT_PRIVATE AccessorAssembler : public CodeStubAssembler { TNode<Map> map, Label* if_handler, TVariable<MaybeObject>* var_handler, Label* if_miss); + + void BranchIfPrototypesHaveNoElements(TNode<Map> receiver_map, + Label* definitely_no_elements, + Label* possibly_elements); }; // Abstraction over direct and indirect exit points. Direct exits correspond to diff --git a/deps/v8/src/ic/binary-op-assembler.cc b/deps/v8/src/ic/binary-op-assembler.cc index f6bec6eab9fa0b..ee488100e9eb5e 100644 --- a/deps/v8/src/ic/binary-op-assembler.cc +++ b/deps/v8/src/ic/binary-op-assembler.cc @@ -9,21 +9,19 @@ namespace v8 { namespace internal { -using compiler::Node; - -Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, - Node* rhs, Node* slot_id, - Node* feedback_vector, - bool rhs_is_smi) { +TNode<Object> BinaryOpAssembler::Generate_AddWithFeedback( + TNode<Context> context, TNode<Object> lhs, TNode<Object> rhs, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { // Shared entry for floating point addition. Label do_fadd(this), if_lhsisnotnumber(this, Label::kDeferred), check_rhsisoddball(this, Label::kDeferred), call_with_oddball_feedback(this), call_with_any_feedback(this), call_add_stub(this), end(this), bigint(this, Label::kDeferred); - VARIABLE(var_fadd_lhs, MachineRepresentation::kFloat64); - VARIABLE(var_fadd_rhs, MachineRepresentation::kFloat64); - VARIABLE(var_type_feedback, MachineRepresentation::kTaggedSigned); - VARIABLE(var_result, MachineRepresentation::kTagged); + TVARIABLE(Float64T, var_fadd_lhs); + TVARIABLE(Float64T, var_fadd_rhs); + TVARIABLE(Smi, var_type_feedback); + TVARIABLE(Object, var_result); // Check if the {lhs} is a Smi or a HeapObject. Label if_lhsissmi(this); @@ -32,13 +30,14 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, // both Smi and Number operations, so this path should not be marked as // Deferred. Label if_lhsisnotsmi(this, - rhs_is_smi ? Label::kDeferred : Label::kNonDeferred); + rhs_known_smi ? Label::kDeferred : Label::kNonDeferred); Branch(TaggedIsNotSmi(lhs), &if_lhsisnotsmi, &if_lhsissmi); BIND(&if_lhsissmi); { Comment("lhs is Smi"); - if (!rhs_is_smi) { + TNode<Smi> lhs_smi = CAST(lhs); + if (!rhs_known_smi) { // Check if the {rhs} is also a Smi. Label if_rhsissmi(this), if_rhsisnotsmi(this); Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); @@ -46,10 +45,11 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, BIND(&if_rhsisnotsmi); { // Check if the {rhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball); + TNode<HeapObject> rhs_heap_object = CAST(rhs); + GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball); - var_fadd_lhs.Bind(SmiToFloat64(lhs)); - var_fadd_rhs.Bind(LoadHeapNumberValue(rhs)); + var_fadd_lhs = SmiToFloat64(lhs_smi); + var_fadd_rhs = LoadHeapNumberValue(rhs_heap_object); Goto(&do_fadd); } @@ -62,21 +62,21 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, // is for AddSmi operation. For the normal Add operation, we want to fast // path both Smi and Number operations, so this path should not be marked // as Deferred. + TNode<Smi> rhs_smi = CAST(rhs); Label if_overflow(this, - rhs_is_smi ? Label::kDeferred : Label::kNonDeferred); - TNode<Smi> smi_result = TrySmiAdd(CAST(lhs), CAST(rhs), &if_overflow); + rhs_known_smi ? Label::kDeferred : Label::kNonDeferred); + TNode<Smi> smi_result = TrySmiAdd(lhs_smi, rhs_smi, &if_overflow); // Not overflowed. { - var_type_feedback.Bind( - SmiConstant(BinaryOperationFeedback::kSignedSmall)); - var_result.Bind(smi_result); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall); + var_result = smi_result; Goto(&end); } BIND(&if_overflow); { - var_fadd_lhs.Bind(SmiToFloat64(lhs)); - var_fadd_rhs.Bind(SmiToFloat64(rhs)); + var_fadd_lhs = SmiToFloat64(lhs_smi); + var_fadd_rhs = SmiToFloat64(rhs_smi); Goto(&do_fadd); } } @@ -85,9 +85,10 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, BIND(&if_lhsisnotsmi); { // Check if {lhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(lhs), &if_lhsisnotnumber); + TNode<HeapObject> lhs_heap_object = CAST(lhs); + GotoIfNot(IsHeapNumber(lhs_heap_object), &if_lhsisnotnumber); - if (!rhs_is_smi) { + if (!rhs_known_smi) { // Check if the {rhs} is Smi. Label if_rhsissmi(this), if_rhsisnotsmi(this); Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); @@ -95,29 +96,30 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, BIND(&if_rhsisnotsmi); { // Check if the {rhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball); + TNode<HeapObject> rhs_heap_object = CAST(rhs); + GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball); - var_fadd_lhs.Bind(LoadHeapNumberValue(lhs)); - var_fadd_rhs.Bind(LoadHeapNumberValue(rhs)); + var_fadd_lhs = LoadHeapNumberValue(lhs_heap_object); + var_fadd_rhs = LoadHeapNumberValue(rhs_heap_object); Goto(&do_fadd); } BIND(&if_rhsissmi); } { - var_fadd_lhs.Bind(LoadHeapNumberValue(lhs)); - var_fadd_rhs.Bind(SmiToFloat64(rhs)); + var_fadd_lhs = LoadHeapNumberValue(lhs_heap_object); + var_fadd_rhs = SmiToFloat64(CAST(rhs)); Goto(&do_fadd); } } BIND(&do_fadd); { - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); TNode<Float64T> value = Float64Add(var_fadd_lhs.value(), var_fadd_rhs.value()); TNode<HeapNumber> result = AllocateHeapNumberWithValue(value); - var_result.Bind(result); + var_result = result; Goto(&end); } @@ -125,7 +127,7 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, { // No checks on rhs are done yet. We just know lhs is not a number or Smi. Label if_lhsisoddball(this), if_lhsisnotoddball(this); - TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs); + TNode<Uint16T> lhs_instance_type = LoadInstanceType(CAST(lhs)); TNode<BoolT> lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); Branch(lhs_is_oddball, &if_lhsisoddball, &if_lhsisnotoddball); @@ -135,39 +137,40 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, GotoIf(TaggedIsSmi(rhs), &call_with_oddball_feedback); // Check if {rhs} is a HeapNumber. - Branch(IsHeapNumber(rhs), &call_with_oddball_feedback, + Branch(IsHeapNumber(CAST(rhs)), &call_with_oddball_feedback, &check_rhsisoddball); } BIND(&if_lhsisnotoddball); { + // Check if the {rhs} is a smi, and exit the string and bigint check early + // if it is. + GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback); + TNode<HeapObject> rhs_heap_object = CAST(rhs); + Label lhs_is_string(this), lhs_is_bigint(this); GotoIf(IsStringInstanceType(lhs_instance_type), &lhs_is_string); GotoIf(IsBigIntInstanceType(lhs_instance_type), &lhs_is_bigint); Goto(&call_with_any_feedback); BIND(&lhs_is_bigint); - { - GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback); - Branch(IsBigInt(rhs), &bigint, &call_with_any_feedback); - } + Branch(IsBigInt(rhs_heap_object), &bigint, &call_with_any_feedback); BIND(&lhs_is_string); - // Check if the {rhs} is a smi, and exit the string check early if it is. - GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback); - - TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); + { + TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs_heap_object); - // Exit unless {rhs} is a string. Since {lhs} is a string we no longer - // need an Oddball check. - GotoIfNot(IsStringInstanceType(rhs_instance_type), - &call_with_any_feedback); + // Exit unless {rhs} is a string. Since {lhs} is a string we no longer + // need an Oddball check. + GotoIfNot(IsStringInstanceType(rhs_instance_type), + &call_with_any_feedback); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kString)); - var_result.Bind( - CallBuiltin(Builtins::kStringAdd_CheckNone, context, lhs, rhs)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kString); + var_result = + CallBuiltin(Builtins::kStringAdd_CheckNone, context, lhs, rhs); - Goto(&end); + Goto(&end); + } } } @@ -175,7 +178,7 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, { // Check if rhs is an oddball. At this point we know lhs is either a // Smi or number or oddball and rhs is not a number or Smi. - TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); + TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs)); TNode<BoolT> rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); GotoIf(rhs_is_oddball, &call_with_oddball_feedback); @@ -186,59 +189,58 @@ Node* BinaryOpAssembler::Generate_AddWithFeedback(Node* context, Node* lhs, { // Both {lhs} and {rhs} are of BigInt type. Label bigint_too_big(this); - var_result.Bind( - CallBuiltin(Builtins::kBigIntAddNoThrow, context, lhs, rhs)); + var_result = CallBuiltin(Builtins::kBigIntAddNoThrow, context, lhs, rhs); // Check for sentinel that signals BigIntTooBig exception. GotoIf(TaggedIsSmi(var_result.value()), &bigint_too_big); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt); Goto(&end); BIND(&bigint_too_big); { // Update feedback to prevent deopt loop. UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny), - feedback_vector, slot_id); + maybe_feedback_vector, slot_id); ThrowRangeError(context, MessageTemplate::kBigIntTooBig); } } BIND(&call_with_oddball_feedback); { - var_type_feedback.Bind( - SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumberOrOddball); Goto(&call_add_stub); } BIND(&call_with_any_feedback); { - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kAny); Goto(&call_add_stub); } BIND(&call_add_stub); { - var_result.Bind(CallBuiltin(Builtins::kAdd, context, lhs, rhs)); + var_result = CallBuiltin(Builtins::kAdd, context, lhs, rhs); Goto(&end); } BIND(&end); - UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_id); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); return var_result.value(); } -Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( - Node* context, Node* lhs, Node* rhs, Node* slot_id, Node* feedback_vector, +TNode<Object> BinaryOpAssembler::Generate_BinaryOperationWithFeedback( + TNode<Context> context, TNode<Object> lhs, TNode<Object> rhs, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, const SmiOperation& smiOperation, const FloatOperation& floatOperation, - Operation op, bool rhs_is_smi) { + Operation op, bool rhs_known_smi) { Label do_float_operation(this), end(this), call_stub(this), check_rhsisoddball(this, Label::kDeferred), call_with_any_feedback(this), if_lhsisnotnumber(this, Label::kDeferred), if_bigint(this, Label::kDeferred); - VARIABLE(var_float_lhs, MachineRepresentation::kFloat64); - VARIABLE(var_float_rhs, MachineRepresentation::kFloat64); - VARIABLE(var_type_feedback, MachineRepresentation::kTaggedSigned); - VARIABLE(var_result, MachineRepresentation::kTagged); + TVARIABLE(Float64T, var_float_lhs); + TVARIABLE(Float64T, var_float_rhs); + TVARIABLE(Smi, var_type_feedback); + TVARIABLE(Object, var_result); Label if_lhsissmi(this); // If rhs is known to be an Smi (in the SubSmi, MulSmi, DivSmi, ModSmi @@ -246,25 +248,28 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( // operation, we want to fast path both Smi and Number operations, so this // path should not be marked as Deferred. Label if_lhsisnotsmi(this, - rhs_is_smi ? Label::kDeferred : Label::kNonDeferred); + rhs_known_smi ? Label::kDeferred : Label::kNonDeferred); Branch(TaggedIsNotSmi(lhs), &if_lhsisnotsmi, &if_lhsissmi); // Check if the {lhs} is a Smi or a HeapObject. BIND(&if_lhsissmi); { Comment("lhs is Smi"); - if (!rhs_is_smi) { + TNode<Smi> lhs_smi = CAST(lhs); + if (!rhs_known_smi) { // Check if the {rhs} is also a Smi. Label if_rhsissmi(this), if_rhsisnotsmi(this); Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); + BIND(&if_rhsisnotsmi); { // Check if {rhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball); + TNode<HeapObject> rhs_heap_object = CAST(rhs); + GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball); // Perform a floating point operation. - var_float_lhs.Bind(SmiToFloat64(lhs)); - var_float_rhs.Bind(LoadHeapNumberValue(rhs)); + var_float_lhs = SmiToFloat64(lhs_smi); + var_float_rhs = LoadHeapNumberValue(rhs_heap_object); Goto(&do_float_operation); } @@ -273,7 +278,7 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { Comment("perform smi operation"); - var_result.Bind(smiOperation(lhs, rhs, &var_type_feedback)); + var_result = smiOperation(lhs_smi, CAST(rhs), &var_type_feedback); Goto(&end); } } @@ -282,9 +287,10 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { Comment("lhs is not Smi"); // Check if the {lhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(lhs), &if_lhsisnotnumber); + TNode<HeapObject> lhs_heap_object = CAST(lhs); + GotoIfNot(IsHeapNumber(lhs_heap_object), &if_lhsisnotnumber); - if (!rhs_is_smi) { + if (!rhs_known_smi) { // Check if the {rhs} is a Smi. Label if_rhsissmi(this), if_rhsisnotsmi(this); Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi); @@ -292,11 +298,12 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&if_rhsisnotsmi); { // Check if the {rhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball); + TNode<HeapObject> rhs_heap_object = CAST(rhs); + GotoIfNot(IsHeapNumber(rhs_heap_object), &check_rhsisoddball); // Perform a floating point operation. - var_float_lhs.Bind(LoadHeapNumberValue(lhs)); - var_float_rhs.Bind(LoadHeapNumberValue(rhs)); + var_float_lhs = LoadHeapNumberValue(lhs_heap_object); + var_float_rhs = LoadHeapNumberValue(rhs_heap_object); Goto(&do_float_operation); } @@ -305,19 +312,19 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { // Perform floating point operation. - var_float_lhs.Bind(LoadHeapNumberValue(lhs)); - var_float_rhs.Bind(SmiToFloat64(rhs)); + var_float_lhs = LoadHeapNumberValue(lhs_heap_object); + var_float_rhs = SmiToFloat64(CAST(rhs)); Goto(&do_float_operation); } } BIND(&do_float_operation); { - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); - Node* lhs_value = var_float_lhs.value(); - Node* rhs_value = var_float_rhs.value(); - Node* value = floatOperation(lhs_value, rhs_value); - var_result.Bind(AllocateHeapNumberWithValue(value)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); + TNode<Float64T> lhs_value = var_float_lhs.value(); + TNode<Float64T> rhs_value = var_float_rhs.value(); + TNode<Float64T> value = floatOperation(lhs_value, rhs_value); + var_result = AllocateHeapNumberWithValue(value); Goto(&end); } @@ -325,7 +332,7 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { // No checks on rhs are done yet. We just know lhs is not a number or Smi. Label if_left_bigint(this), if_left_oddball(this); - TNode<Uint16T> lhs_instance_type = LoadInstanceType(lhs); + TNode<Uint16T> lhs_instance_type = LoadInstanceType(CAST(lhs)); GotoIf(IsBigIntInstanceType(lhs_instance_type), &if_left_bigint); TNode<BoolT> lhs_is_oddball = InstanceTypeEqual(lhs_instance_type, ODDBALL_TYPE); @@ -338,18 +345,18 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&if_rhsissmi); { - var_type_feedback.Bind( - SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); + var_type_feedback = + SmiConstant(BinaryOperationFeedback::kNumberOrOddball); Goto(&call_stub); } BIND(&if_rhsisnotsmi); { // Check if {rhs} is a HeapNumber. - GotoIfNot(IsHeapNumber(rhs), &check_rhsisoddball); + GotoIfNot(IsHeapNumber(CAST(rhs)), &check_rhsisoddball); - var_type_feedback.Bind( - SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); + var_type_feedback = + SmiConstant(BinaryOperationFeedback::kNumberOrOddball); Goto(&call_stub); } } @@ -357,7 +364,7 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( BIND(&if_left_bigint); { GotoIf(TaggedIsSmi(rhs), &call_with_any_feedback); - Branch(IsBigInt(rhs), &if_bigint, &call_with_any_feedback); + Branch(IsBigInt(CAST(rhs)), &if_bigint, &call_with_any_feedback); } } @@ -365,39 +372,38 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( { // Check if rhs is an oddball. At this point we know lhs is either a // Smi or number or oddball and rhs is not a number or Smi. - TNode<Uint16T> rhs_instance_type = LoadInstanceType(rhs); + TNode<Uint16T> rhs_instance_type = LoadInstanceType(CAST(rhs)); GotoIf(IsBigIntInstanceType(rhs_instance_type), &if_bigint); TNode<BoolT> rhs_is_oddball = InstanceTypeEqual(rhs_instance_type, ODDBALL_TYPE); GotoIfNot(rhs_is_oddball, &call_with_any_feedback); - var_type_feedback.Bind( - SmiConstant(BinaryOperationFeedback::kNumberOrOddball)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumberOrOddball); Goto(&call_stub); } // This handles the case where at least one input is a BigInt. BIND(&if_bigint); { - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt); if (op == Operation::kAdd) { - var_result.Bind(CallBuiltin(Builtins::kBigIntAdd, context, lhs, rhs)); + var_result = CallBuiltin(Builtins::kBigIntAdd, context, lhs, rhs); } else { - var_result.Bind(CallRuntime(Runtime::kBigIntBinaryOp, context, lhs, rhs, - SmiConstant(op))); + var_result = CallRuntime(Runtime::kBigIntBinaryOp, context, lhs, rhs, + SmiConstant(op)); } Goto(&end); } BIND(&call_with_any_feedback); { - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kAny); Goto(&call_stub); } BIND(&call_stub); { - Node* result; + TNode<Object> result; switch (op) { case Operation::kSubtract: result = CallBuiltin(Builtins::kSubtract, context, lhs, rhs); @@ -414,34 +420,35 @@ Node* BinaryOpAssembler::Generate_BinaryOperationWithFeedback( default: UNREACHABLE(); } - var_result.Bind(result); + var_result = result; Goto(&end); } BIND(&end); - UpdateFeedback(var_type_feedback.value(), feedback_vector, slot_id); + UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_id); return var_result.value(); } -Node* BinaryOpAssembler::Generate_SubtractWithFeedback(Node* context, Node* lhs, - Node* rhs, Node* slot_id, - Node* feedback_vector, - bool rhs_is_smi) { - auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) { +TNode<Object> BinaryOpAssembler::Generate_SubtractWithFeedback( + TNode<Context> context, TNode<Object> lhs, TNode<Object> rhs, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { + auto smiFunction = [=](TNode<Smi> lhs, TNode<Smi> rhs, + TVariable<Smi>* var_type_feedback) { Label end(this); TVARIABLE(Number, var_result); // If rhs is known to be an Smi (for SubSmi) we want to fast path Smi // operation. For the normal Sub operation, we want to fast path both // Smi and Number operations, so this path should not be marked as Deferred. Label if_overflow(this, - rhs_is_smi ? Label::kDeferred : Label::kNonDeferred); - var_result = TrySmiSub(CAST(lhs), CAST(rhs), &if_overflow); - var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall)); + rhs_known_smi ? Label::kDeferred : Label::kNonDeferred); + var_result = TrySmiSub(lhs, rhs, &if_overflow); + *var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall); Goto(&end); BIND(&if_overflow); { - var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kNumber)); + *var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); TNode<Float64T> value = Float64Sub(SmiToFloat64(lhs), SmiToFloat64(rhs)); var_result = AllocateHeapNumberWithValue(value); Goto(&end); @@ -450,91 +457,97 @@ Node* BinaryOpAssembler::Generate_SubtractWithFeedback(Node* context, Node* lhs, BIND(&end); return var_result.value(); }; - auto floatFunction = [=](Node* lhs, Node* rhs) { + auto floatFunction = [=](TNode<Float64T> lhs, TNode<Float64T> rhs) { return Float64Sub(lhs, rhs); }; return Generate_BinaryOperationWithFeedback( - context, lhs, rhs, slot_id, feedback_vector, smiFunction, floatFunction, - Operation::kSubtract, rhs_is_smi); + context, lhs, rhs, slot_id, maybe_feedback_vector, smiFunction, + floatFunction, Operation::kSubtract, rhs_known_smi); } -Node* BinaryOpAssembler::Generate_MultiplyWithFeedback(Node* context, Node* lhs, - Node* rhs, Node* slot_id, - Node* feedback_vector, - bool rhs_is_smi) { - auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) { - TNode<Number> result = SmiMul(CAST(lhs), CAST(rhs)); - var_type_feedback->Bind(SelectSmiConstant( +TNode<Object> BinaryOpAssembler::Generate_MultiplyWithFeedback( + TNode<Context> context, TNode<Object> lhs, TNode<Object> rhs, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { + auto smiFunction = [=](TNode<Smi> lhs, TNode<Smi> rhs, + TVariable<Smi>* var_type_feedback) { + TNode<Number> result = SmiMul(lhs, rhs); + *var_type_feedback = SelectSmiConstant( TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, - BinaryOperationFeedback::kNumber)); + BinaryOperationFeedback::kNumber); return result; }; - auto floatFunction = [=](Node* lhs, Node* rhs) { + auto floatFunction = [=](TNode<Float64T> lhs, TNode<Float64T> rhs) { return Float64Mul(lhs, rhs); }; return Generate_BinaryOperationWithFeedback( - context, lhs, rhs, slot_id, feedback_vector, smiFunction, floatFunction, - Operation::kMultiply, rhs_is_smi); + context, lhs, rhs, slot_id, maybe_feedback_vector, smiFunction, + floatFunction, Operation::kMultiply, rhs_known_smi); } -Node* BinaryOpAssembler::Generate_DivideWithFeedback( - Node* context, Node* dividend, Node* divisor, Node* slot_id, - Node* feedback_vector, bool rhs_is_smi) { - auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) { - VARIABLE(var_result, MachineRepresentation::kTagged); +TNode<Object> BinaryOpAssembler::Generate_DivideWithFeedback( + TNode<Context> context, TNode<Object> dividend, TNode<Object> divisor, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { + auto smiFunction = [=](TNode<Smi> lhs, TNode<Smi> rhs, + TVariable<Smi>* var_type_feedback) { + TVARIABLE(Object, var_result); // If rhs is known to be an Smi (for DivSmi) we want to fast path Smi // operation. For the normal Div operation, we want to fast path both // Smi and Number operations, so this path should not be marked as Deferred. - Label bailout(this, rhs_is_smi ? Label::kDeferred : Label::kNonDeferred), + Label bailout(this, rhs_known_smi ? Label::kDeferred : Label::kNonDeferred), end(this); - var_result.Bind(TrySmiDiv(CAST(lhs), CAST(rhs), &bailout)); - var_type_feedback->Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall)); + var_result = TrySmiDiv(lhs, rhs, &bailout); + *var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall); Goto(&end); BIND(&bailout); { - var_type_feedback->Bind( - SmiConstant(BinaryOperationFeedback::kSignedSmallInputs)); + *var_type_feedback = + SmiConstant(BinaryOperationFeedback::kSignedSmallInputs); TNode<Float64T> value = Float64Div(SmiToFloat64(lhs), SmiToFloat64(rhs)); - var_result.Bind(AllocateHeapNumberWithValue(value)); + var_result = AllocateHeapNumberWithValue(value); Goto(&end); } BIND(&end); return var_result.value(); }; - auto floatFunction = [=](Node* lhs, Node* rhs) { + auto floatFunction = [=](TNode<Float64T> lhs, TNode<Float64T> rhs) { return Float64Div(lhs, rhs); }; return Generate_BinaryOperationWithFeedback( - context, dividend, divisor, slot_id, feedback_vector, smiFunction, - floatFunction, Operation::kDivide, rhs_is_smi); + context, dividend, divisor, slot_id, maybe_feedback_vector, smiFunction, + floatFunction, Operation::kDivide, rhs_known_smi); } -Node* BinaryOpAssembler::Generate_ModulusWithFeedback( - Node* context, Node* dividend, Node* divisor, Node* slot_id, - Node* feedback_vector, bool rhs_is_smi) { - auto smiFunction = [=](Node* lhs, Node* rhs, Variable* var_type_feedback) { - TNode<Number> result = SmiMod(CAST(lhs), CAST(rhs)); - var_type_feedback->Bind(SelectSmiConstant( +TNode<Object> BinaryOpAssembler::Generate_ModulusWithFeedback( + TNode<Context> context, TNode<Object> dividend, TNode<Object> divisor, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { + auto smiFunction = [=](TNode<Smi> lhs, TNode<Smi> rhs, + TVariable<Smi>* var_type_feedback) { + TNode<Number> result = SmiMod(lhs, rhs); + *var_type_feedback = SelectSmiConstant( TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall, - BinaryOperationFeedback::kNumber)); + BinaryOperationFeedback::kNumber); return result; }; - auto floatFunction = [=](Node* lhs, Node* rhs) { + auto floatFunction = [=](TNode<Float64T> lhs, TNode<Float64T> rhs) { return Float64Mod(lhs, rhs); }; return Generate_BinaryOperationWithFeedback( - context, dividend, divisor, slot_id, feedback_vector, smiFunction, - floatFunction, Operation::kModulus, rhs_is_smi); + context, dividend, divisor, slot_id, maybe_feedback_vector, smiFunction, + floatFunction, Operation::kModulus, rhs_known_smi); } -Node* BinaryOpAssembler::Generate_ExponentiateWithFeedback( - Node* context, Node* base, Node* exponent, Node* slot_id, - Node* feedback_vector, bool rhs_is_smi) { +TNode<Object> BinaryOpAssembler::Generate_ExponentiateWithFeedback( + TNode<Context> context, TNode<Object> base, TNode<Object> exponent, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi) { // We currently don't optimize exponentiation based on feedback. TNode<Smi> dummy_feedback = SmiConstant(BinaryOperationFeedback::kAny); - UpdateFeedback(dummy_feedback, feedback_vector, slot_id); + UpdateFeedback(dummy_feedback, maybe_feedback_vector, slot_id); return CallBuiltin(Builtins::kExponentiate, context, base, exponent); } diff --git a/deps/v8/src/ic/binary-op-assembler.h b/deps/v8/src/ic/binary-op-assembler.h index 26324660c859e1..37484909d42955 100644 --- a/deps/v8/src/ic/binary-op-assembler.h +++ b/deps/v8/src/ic/binary-op-assembler.h @@ -17,44 +17,50 @@ class CodeAssemblerState; class BinaryOpAssembler : public CodeStubAssembler { public: - using Node = compiler::Node; - explicit BinaryOpAssembler(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) {} - Node* Generate_AddWithFeedback(Node* context, Node* lhs, Node* rhs, - Node* slot_id, Node* feedback_vector, - bool rhs_is_smi); + TNode<Object> Generate_AddWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); - Node* Generate_SubtractWithFeedback(Node* context, Node* lhs, Node* rhs, - Node* slot_id, Node* feedback_vector, - bool rhs_is_smi); + TNode<Object> Generate_SubtractWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); - Node* Generate_MultiplyWithFeedback(Node* context, Node* lhs, Node* rhs, - Node* slot_id, Node* feedback_vector, - bool rhs_is_smi); + TNode<Object> Generate_MultiplyWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); - Node* Generate_DivideWithFeedback(Node* context, Node* dividend, - Node* divisor, Node* slot_id, - Node* feedback_vector, bool rhs_is_smi); + TNode<Object> Generate_DivideWithFeedback( + TNode<Context> context, TNode<Object> dividend, TNode<Object> divisor, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); - Node* Generate_ModulusWithFeedback(Node* context, Node* dividend, - Node* divisor, Node* slot_id, - Node* feedback_vector, bool rhs_is_smi); + TNode<Object> Generate_ModulusWithFeedback( + TNode<Context> context, TNode<Object> dividend, TNode<Object> divisor, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); - Node* Generate_ExponentiateWithFeedback(Node* context, Node* dividend, - Node* divisor, Node* slot_id, - Node* feedback_vector, - bool rhs_is_smi); + TNode<Object> Generate_ExponentiateWithFeedback( + TNode<Context> context, TNode<Object> base, TNode<Object> exponent, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); private: - using SmiOperation = std::function<Node*(Node*, Node*, Variable*)>; - using FloatOperation = std::function<Node*(Node*, Node*)>; - - Node* Generate_BinaryOperationWithFeedback( - Node* context, Node* lhs, Node* rhs, Node* slot_id, Node* feedback_vector, + using SmiOperation = + std::function<TNode<Object>(TNode<Smi>, TNode<Smi>, TVariable<Smi>*)>; + using FloatOperation = + std::function<TNode<Float64T>(TNode<Float64T>, TNode<Float64T>)>; + + TNode<Object> Generate_BinaryOperationWithFeedback( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, const SmiOperation& smiOperation, const FloatOperation& floatOperation, - Operation op, bool rhs_is_smi); + Operation op, bool rhs_known_smi); }; } // namespace internal diff --git a/deps/v8/src/ic/handler-configuration-inl.h b/deps/v8/src/ic/handler-configuration-inl.h index c0ff8a4c9b111e..95ef3532778777 100644 --- a/deps/v8/src/ic/handler-configuration-inl.h +++ b/deps/v8/src/ic/handler-configuration-inl.h @@ -43,6 +43,11 @@ Handle<Smi> LoadHandler::LoadInterceptor(Isolate* isolate) { return handle(Smi::FromInt(config), isolate); } +Handle<Smi> LoadHandler::LoadSlow(Isolate* isolate) { + int config = KindBits::encode(kSlow); + return handle(Smi::FromInt(config), isolate); +} + Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) { int config = KindBits::encode(kField) | IsInobjectBits::encode(field_index.is_inobject()) | @@ -127,6 +132,16 @@ Handle<Smi> StoreHandler::StoreNormal(Isolate* isolate) { return handle(Smi::FromInt(config), isolate); } +Handle<Smi> StoreHandler::StoreInterceptor(Isolate* isolate) { + int config = KindBits::encode(kInterceptor); + return handle(Smi::FromInt(config), isolate); +} + +Handle<Smi> StoreHandler::StoreSlow(Isolate* isolate) { + int config = KindBits::encode(kSlow); + return handle(Smi::FromInt(config), isolate); +} + Handle<Smi> StoreHandler::StoreProxy(Isolate* isolate) { int config = KindBits::encode(kProxy); return handle(Smi::FromInt(config), isolate); @@ -135,29 +150,12 @@ Handle<Smi> StoreHandler::StoreProxy(Isolate* isolate) { Handle<Smi> StoreHandler::StoreField(Isolate* isolate, Kind kind, int descriptor, FieldIndex field_index, Representation representation) { - FieldRepresentation field_rep; - switch (representation.kind()) { - case Representation::kSmi: - field_rep = kSmi; - break; - case Representation::kDouble: - field_rep = kDouble; - break; - case Representation::kHeapObject: - field_rep = kHeapObject; - break; - case Representation::kTagged: - field_rep = kTagged; - break; - default: - UNREACHABLE(); - } - + DCHECK(!representation.IsNone()); DCHECK(kind == kField || kind == kConstField); int config = KindBits::encode(kind) | IsInobjectBits::encode(field_index.is_inobject()) | - FieldRepresentationBits::encode(field_rep) | + RepresentationBits::encode(representation.kind()) | DescriptorBits::encode(descriptor) | FieldIndexBits::encode(field_index.index()); return handle(Smi::FromInt(config), isolate); diff --git a/deps/v8/src/ic/handler-configuration.cc b/deps/v8/src/ic/handler-configuration.cc index 814935c6ebe996..3af5fe495377dc 100644 --- a/deps/v8/src/ic/handler-configuration.cc +++ b/deps/v8/src/ic/handler-configuration.cc @@ -196,7 +196,7 @@ MaybeObjectHandle StoreHandler::StoreTransition(Isolate* isolate, bool is_dictionary_map = transition_map->is_dictionary_map(); #ifdef DEBUG if (!is_dictionary_map) { - int descriptor = transition_map->LastAdded(); + InternalIndex descriptor = transition_map->LastAdded(); Handle<DescriptorArray> descriptors(transition_map->instance_descriptors(), isolate); PropertyDetails details = descriptors->GetDetails(descriptor); diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h index 80d19d73ecfd5e..fd0cee2920602e 100644 --- a/deps/v8/src/ic/handler-configuration.h +++ b/deps/v8/src/ic/handler-configuration.h @@ -43,6 +43,7 @@ class LoadHandler final : public DataHandler { kApiGetter, kApiGetterHolderIsPrototype, kInterceptor, + kSlow, kProxy, kNonExistent, kModuleExport @@ -113,6 +114,9 @@ class LoadHandler final : public DataHandler { // interceptor. static inline Handle<Smi> LoadInterceptor(Isolate* isolate); + // Creates a Smi-handler for loading a property from a object. + static inline Handle<Smi> LoadSlow(Isolate* isolate); + // Creates a Smi-handler for loading a field from fast object. static inline Handle<Smi> LoadField(Isolate* isolate, FieldIndex field_index); @@ -197,13 +201,13 @@ class StoreHandler final : public DataHandler { kApiSetterHolderIsPrototype, kGlobalProxy, kNormal, + kInterceptor, + kSlow, kProxy, kKindsNumber // Keep last }; using KindBits = BitField<Kind, 0, 4>; - enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; - // Applicable to kGlobalProxy, kProxy kinds. // Defines whether access rights check should be done on receiver object. @@ -231,10 +235,10 @@ class StoreHandler final : public DataHandler { // Encoding when KindBits contains kField or kTransitionToField. // using IsInobjectBits = DescriptorBits::Next<bool, 1>; - using FieldRepresentationBits = IsInobjectBits::Next<FieldRepresentation, 2>; + using RepresentationBits = IsInobjectBits::Next<Representation::Kind, 3>; // +1 here is to cover all possible JSObject header sizes. using FieldIndexBits = - FieldRepresentationBits::Next<unsigned, kDescriptorIndexBitCount + 1>; + RepresentationBits::Next<unsigned, kDescriptorIndexBitCount + 1>; // Make sure we don't overflow the smi. STATIC_ASSERT(FieldIndexBits::kLastUsedBit < kSmiValueSize); @@ -283,6 +287,12 @@ class StoreHandler final : public DataHandler { // Creates a Smi-handler for storing a property to a slow object. static inline Handle<Smi> StoreNormal(Isolate* isolate); + // Creates a Smi-handler for storing a property to an interceptor. + static inline Handle<Smi> StoreInterceptor(Isolate* isolate); + + // Creates a Smi-handler for storing a property. + static inline Handle<Smi> StoreSlow(Isolate* isolate); + // Creates a Smi-handler for storing a property on a proxy. static inline Handle<Smi> StoreProxy(Isolate* isolate); diff --git a/deps/v8/src/ic/ic-stats.cc b/deps/v8/src/ic/ic-stats.cc index f387239aeee031..54d485663103cc 100644 --- a/deps/v8/src/ic/ic-stats.cc +++ b/deps/v8/src/ic/ic-stats.cc @@ -94,6 +94,7 @@ ICInfo::ICInfo() script_offset(0), script_name(nullptr), line_num(-1), + column_num(-1), is_constructor(false), is_optimized(false), map(nullptr), @@ -106,6 +107,7 @@ void ICInfo::Reset() { script_offset = 0; script_name = nullptr; line_num = -1; + column_num = -1; is_constructor = false; is_optimized = false; state.clear(); @@ -127,6 +129,7 @@ void ICInfo::AppendToTracedValue(v8::tracing::TracedValue* value) const { if (script_offset) value->SetInteger("offset", script_offset); if (script_name) value->SetString("scriptName", script_name); if (line_num != -1) value->SetInteger("lineNum", line_num); + if (column_num != -1) value->SetInteger("columnNum", column_num); if (is_constructor) value->SetInteger("constructor", is_constructor); if (!state.empty()) value->SetString("state", state); if (map) { diff --git a/deps/v8/src/ic/ic-stats.h b/deps/v8/src/ic/ic-stats.h index 76c65c3862c7ea..44b968c6c0e093 100644 --- a/deps/v8/src/ic/ic-stats.h +++ b/deps/v8/src/ic/ic-stats.h @@ -34,6 +34,7 @@ struct ICInfo { int script_offset; const char* script_name; int line_num; + int column_num; bool is_constructor; bool is_optimized; std::string state; diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc index 54f4be7a221ee7..4ac5fd7abefaa7 100644 --- a/deps/v8/src/ic/ic.cc +++ b/deps/v8/src/ic/ic.cc @@ -15,6 +15,7 @@ #include "src/execution/execution.h" #include "src/execution/frames-inl.h" #include "src/execution/isolate-inl.h" +#include "src/execution/protectors-inl.h" #include "src/execution/runtime-profiler.h" #include "src/handles/handles-inl.h" #include "src/ic/call-optimization.h" @@ -47,8 +48,6 @@ char IC::TransitionMarkFromState(IC::State state) { return 'X'; case UNINITIALIZED: return '0'; - case PREMONOMORPHIC: - return '.'; case MONOMORPHIC: return '1'; case RECOMPUTE_HANDLER: @@ -343,11 +342,6 @@ bool IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) { return changed; } -void IC::ConfigureVectorState(Handle<Map> map) { - nexus()->ConfigurePremonomorphic(map); - OnFeedbackChanged("Premonomorphic"); -} - void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, Handle<Object> handler) { ConfigureVectorState(name, map, MaybeObjectHandle(handler)); @@ -383,11 +377,11 @@ MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { // of its properties; throw a TypeError in that case. if (IsAnyHas() ? !object->IsJSReceiver() : object->IsNullOrUndefined(isolate())) { - if (use_ic && state() != PREMONOMORPHIC) { + if (use_ic) { // Ensure the IC state progresses. TRACE_HANDLER_STATS(isolate(), LoadIC_NonReceiver); update_receiver_map(object); - PatchCache(name, slow_stub()); + SetCache(name, LoadHandler::LoadSlow(isolate())); TraceIC("LoadIC", name); } @@ -490,7 +484,7 @@ MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) { } else { // Given combination of indices can't be encoded, so use slow stub. TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_SlowStub); - PatchCache(name, slow_stub()); + SetCache(name, LoadHandler::LoadSlow(isolate())); } TraceIC("LoadGlobalIC", name); } @@ -613,11 +607,11 @@ bool IC::IsTransitionOfMonomorphicTarget(Map source_map, Map target_map) { return transitioned_map == target_map; } -void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { - PatchCache(name, MaybeObjectHandle(handler)); +void IC::SetCache(Handle<Name> name, Handle<Object> handler) { + SetCache(name, MaybeObjectHandle(handler)); } -void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) { +void IC::SetCache(Handle<Name> name, const MaybeObjectHandle& handler) { DCHECK(IsHandler(*handler)); // Currently only load and store ICs support non-code handlers. DCHECK(IsAnyLoad() || IsAnyStore() || IsAnyHas()); @@ -625,7 +619,6 @@ void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) { case NO_FEEDBACK: UNREACHABLE(); case UNINITIALIZED: - case PREMONOMORPHIC: UpdateMonomorphicIC(handler, name); break; case RECOMPUTE_HANDLER: @@ -659,7 +652,7 @@ __attribute__((__aligned__(32))) void LoadIC::UpdateCaches(LookupIterator* lookup) { Handle<Object> code; if (lookup->state() == LookupIterator::ACCESS_CHECK) { - code = slow_stub(); + code = LoadHandler::LoadSlow(isolate()); } else if (!lookup->IsFound()) { TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH); Handle<Smi> smi_handler = LoadHandler::LoadNonExistent(isolate()); @@ -683,7 +676,7 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { code = ComputeHandler(lookup); } - PatchCache(lookup->name(), code); + SetCache(lookup->name(), code); TraceIC("LoadIC", lookup->name()); } @@ -798,7 +791,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { isolate()); if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) { TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); - return slow_stub(); + return LoadHandler::LoadSlow(isolate()); } if ((getter->IsFunctionTemplateInfo() && @@ -807,7 +800,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { JSFunction::cast(*getter).shared().BreakAtEntry())) { // Do not install an IC if the api function has a breakpoint. TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); - return slow_stub(); + return LoadHandler::LoadSlow(isolate()); } Handle<Smi> smi_handler; @@ -817,7 +810,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { if (!call_optimization.IsCompatibleReceiverMap(map, holder) || !holder->HasFastProperties()) { TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); - return slow_stub(); + return LoadHandler::LoadSlow(isolate()); } CallOptimization::HolderLookup holder_lookup; @@ -868,7 +861,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) { !holder->HasFastProperties() || (info->is_sloppy() && !receiver->IsJSReceiver())) { TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); - return slow_stub(); + return LoadHandler::LoadSlow(isolate()); } Handle<Smi> smi_handler = LoadHandler::LoadNativeDataProperty( @@ -1076,7 +1069,7 @@ bool AllowConvertHoleElementToUndefined(Isolate* isolate, } // For other {receiver}s we need to check the "no elements" protector. - if (isolate->IsNoElementsProtectorIntact()) { + if (Protectors::IsNoElementsIntact(isolate)) { if (receiver_map->IsStringMap()) { return true; } @@ -1315,12 +1308,11 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, case LookupIterator::INTERCEPTOR: { Handle<JSObject> holder = it->GetHolder<JSObject>(); InterceptorInfo info = holder->GetNamedInterceptor(); - if (it->HolderIsReceiverOrHiddenPrototype()) { - return !info.non_masking() && receiver.is_identical_to(holder) && - !info.setter().IsUndefined(isolate()); - } else if (!info.getter().IsUndefined(isolate()) || - !info.query().IsUndefined(isolate())) { - return false; + if ((it->HolderIsReceiverOrHiddenPrototype() && + !info.non_masking()) || + !info.getter().IsUndefined(isolate()) || + !info.query().IsUndefined(isolate())) { + return true; } break; } @@ -1403,7 +1395,7 @@ MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name, } else { // Given combination of indices can't be encoded, so use slow stub. TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_SlowStub); - PatchCache(name, slow_stub()); + SetCache(name, StoreHandler::StoreSlow(isolate())); } TraceIC("StoreGlobalIC", name); } @@ -1432,11 +1424,11 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, // If the object is undefined or null it's illegal to try to set any // properties on it; throw a TypeError in that case. if (object->IsNullOrUndefined(isolate())) { - if (use_ic && state() != PREMONOMORPHIC) { + if (use_ic) { // Ensure the IC state progresses. TRACE_HANDLER_STATS(isolate(), StoreIC_NonReceiver); update_receiver_map(object); - PatchCache(name, slow_stub()); + SetCache(name, StoreHandler::StoreSlow(isolate())); TraceIC("StoreIC", name); } return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name); @@ -1481,30 +1473,11 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, } handler = ComputeHandler(lookup); } else { - if (state() == UNINITIALIZED && IsStoreGlobalIC() && - lookup->state() == LookupIterator::INTERCEPTOR) { - InterceptorInfo info = - lookup->GetHolder<JSObject>()->GetNamedInterceptor(); - if (!lookup->HolderIsReceiverOrHiddenPrototype() && - !info.getter().IsUndefined(isolate())) { - // Utilize premonomorphic state for global store ics that run into - // an interceptor because the property doesn't exist yet. - // After we actually set the property, we'll have more information. - // Premonomorphism gives us a chance to find more information the - // second time. - TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_Premonomorphic); - ConfigureVectorState(receiver_map()); - TraceIC("StoreGlobalIC", lookup->name()); - return; - } - } - set_slow_stub_reason("LookupForWrite said 'false'"); - // TODO(marja): change slow_stub to return MaybeObjectHandle. - handler = MaybeObjectHandle(slow_stub()); + handler = MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } - PatchCache(lookup->name(), handler); + SetCache(lookup->name(), handler); TraceIC("StoreIC", lookup->name()); } @@ -1542,12 +1515,27 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { case LookupIterator::INTERCEPTOR: { Handle<JSObject> holder = lookup->GetHolder<JSObject>(); - USE(holder); + InterceptorInfo info = holder->GetNamedInterceptor(); + + // If the interceptor is on the receiver + if (lookup->HolderIsReceiverOrHiddenPrototype() && !info.non_masking()) { + // return a store interceptor smi handler if there is one, + if (!info.setter().IsUndefined(isolate())) { + return MaybeObjectHandle(StoreHandler::StoreInterceptor(isolate())); + } + // otherwise return a slow-case smi handler. + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); + } - DCHECK(!holder->GetNamedInterceptor().setter().IsUndefined(isolate())); - // TODO(jgruber): Update counter name. - TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); - return MaybeObjectHandle(BUILTIN_CODE(isolate(), StoreInterceptorIC)); + // If the interceptor is a getter/query interceptor on the prototype + // chain, return an invalidatable slow handler so it can turn fast if the + // interceptor is masked by a regular property later. + DCHECK(!info.getter().IsUndefined(isolate()) || + !info.query().IsUndefined(isolate())); + Handle<Object> handler = StoreHandler::StoreThroughPrototype( + isolate(), receiver_map(), holder, + StoreHandler::StoreSlow(isolate())); + return MaybeObjectHandle(handler); } case LookupIterator::ACCESSOR: { @@ -1559,7 +1547,9 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { if (!holder->HasFastProperties()) { set_slow_stub_reason("accessor on slow map"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + MaybeObjectHandle handler = + MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); + return handler; } Handle<Object> accessors = lookup->GetAccessors(); if (accessors->IsAccessorInfo()) { @@ -1567,18 +1557,18 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { if (v8::ToCData<Address>(info->setter()) == kNullAddress) { set_slow_stub_reason("setter == kNullAddress"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } if (AccessorInfo::cast(*accessors).is_special_data_property() && !lookup->HolderIsReceiverOrHiddenPrototype()) { set_slow_stub_reason("special data property in prototype chain"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } if (!AccessorInfo::IsCompatibleReceiverMap(info, receiver_map())) { set_slow_stub_reason("incompatible receiver type"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } Handle<Smi> smi_handler = StoreHandler::StoreNativeDataProperty( @@ -1598,7 +1588,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) { set_slow_stub_reason("setter not a function"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } if ((setter->IsFunctionTemplateInfo() && @@ -1607,7 +1597,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { JSFunction::cast(*setter).shared().BreakAtEntry())) { // Do not install an IC if the api function has a breakpoint. TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } CallOptimization call_optimization(isolate(), setter); @@ -1631,11 +1621,11 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { } set_slow_stub_reason("incompatible receiver"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } else if (setter->IsFunctionTemplateInfo()) { set_slow_stub_reason("setter non-simple template"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } Handle<Smi> smi_handler = @@ -1651,7 +1641,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { isolate(), receiver_map(), holder, smi_handler)); } TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } case LookupIterator::DATA: { @@ -1694,7 +1684,7 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { DCHECK_EQ(kDescriptor, lookup->property_details().location()); set_slow_stub_reason("constant property"); TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); - return MaybeObjectHandle(slow_stub()); + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } case LookupIterator::JSPROXY: { Handle<JSReceiver> receiver = @@ -1905,7 +1895,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers( // TODO(mvstanton): Consider embedding store_mode in the state of the slow // keyed store ic for uniformity. TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub); - handler = slow_stub(); + handler = StoreHandler::StoreSlow(isolate()); } else { { @@ -2532,7 +2522,7 @@ static bool CanFastCloneObject(Handle<Map> map) { } DescriptorArray descriptors = map->instance_descriptors(); - for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(i); Name key = descriptors.GetKey(i); if (details.kind() != kData || !details.IsEnumerable() || diff --git a/deps/v8/src/ic/ic.h b/deps/v8/src/ic/ic.h index 29f3b4a60a25ae..a3c68f4fbf991f 100644 --- a/deps/v8/src/ic/ic.h +++ b/deps/v8/src/ic/ic.h @@ -74,8 +74,6 @@ class IC { // Configure for most states. bool ConfigureVectorState(IC::State new_state, Handle<Object> key); - // Configure the vector for PREMONOMORPHIC. - void ConfigureVectorState(Handle<Map> map); // Configure the vector for MONOMORPHIC. void ConfigureVectorState(Handle<Name> name, Handle<Map> map, Handle<Object> handler); @@ -103,8 +101,8 @@ class IC { void CopyICToMegamorphicCache(Handle<Name> name); bool IsTransitionOfMonomorphicTarget(Map source_map, Map target_map); - void PatchCache(Handle<Name> name, Handle<Object> handler); - void PatchCache(Handle<Name> name, const MaybeObjectHandle& handler); + void SetCache(Handle<Name> name, Handle<Object> handler); + void SetCache(Handle<Name> name, const MaybeObjectHandle& handler); FeedbackSlotKind kind() const { return kind_; } bool IsGlobalIC() const { return IsLoadGlobalIC() || IsStoreGlobalIC(); } bool IsLoadIC() const { return IsLoadICKind(kind_); } @@ -188,11 +186,6 @@ class LoadIC : public IC { Handle<Name> name); protected: - virtual Handle<Code> slow_stub() const { - return IsAnyHas() ? BUILTIN_CODE(isolate(), HasIC_Slow) - : BUILTIN_CODE(isolate(), LoadIC_Slow); - } - // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupIterator* lookup); @@ -211,11 +204,6 @@ class LoadGlobalIC : public LoadIC { : LoadIC(isolate, vector, slot, kind) {} V8_WARN_UNUSED_RESULT MaybeHandle<Object> Load(Handle<Name> name); - - protected: - Handle<Code> slow_stub() const override { - return BUILTIN_CODE(isolate(), LoadGlobalIC_Slow); - } }; class KeyedLoadIC : public LoadIC { @@ -268,11 +256,6 @@ class StoreIC : public IC { protected: // Stub accessors. - virtual Handle<Code> slow_stub() const { - // All StoreICs share the same slow stub. - return BUILTIN_CODE(isolate(), KeyedStoreIC_Slow); - } - // Update the inline cache and the global stub cache based on the // lookup result. void UpdateCaches(LookupIterator* lookup, Handle<Object> value, @@ -292,11 +275,6 @@ class StoreGlobalIC : public StoreIC { V8_WARN_UNUSED_RESULT MaybeHandle<Object> Store(Handle<Name> name, Handle<Object> value); - - protected: - Handle<Code> slow_stub() const override { - return BUILTIN_CODE(isolate(), StoreGlobalIC_Slow); - } }; enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; @@ -328,10 +306,6 @@ class KeyedStoreIC : public StoreIC { KeyedAccessStoreMode store_mode, Handle<Map> new_receiver_map); - Handle<Code> slow_stub() const override { - return BUILTIN_CODE(isolate(), KeyedStoreIC_Slow); - } - private: Handle<Map> ComputeTransitionedMap(Handle<Map> map, TransitionMode transition_mode); @@ -356,11 +330,6 @@ class StoreInArrayLiteralIC : public KeyedStoreIC { } void Store(Handle<JSArray> array, Handle<Object> index, Handle<Object> value); - - private: - Handle<Code> slow_stub() const override { - return BUILTIN_CODE(isolate(), StoreInArrayLiteralIC_Slow); - } }; } // namespace internal diff --git a/deps/v8/src/ic/keyed-store-generic.cc b/deps/v8/src/ic/keyed-store-generic.cc index bb4e6cb4278972..ff830a022e5b34 100644 --- a/deps/v8/src/ic/keyed-store-generic.cc +++ b/deps/v8/src/ic/keyed-store-generic.cc @@ -16,10 +16,6 @@ namespace v8 { namespace internal { -using Node = compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; - enum class StoreMode { kOrdinary, kInLiteral }; class KeyedStoreGenericAssembler : public AccessorAssembler { @@ -62,9 +58,11 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { TNode<Object> key, TNode<Object> value, Maybe<LanguageMode> language_mode); - void EmitGenericElementStore(Node* receiver, TNode<Map> receiver_map, - Node* instance_type, TNode<IntPtrT> index, - Node* value, Node* context, Label* slow); + void EmitGenericElementStore(TNode<JSObject> receiver, + TNode<Map> receiver_map, + TNode<Uint16T> instance_type, + TNode<IntPtrT> index, TNode<Object> value, + TNode<Context> context, Label* slow); // If language mode is not provided it is deduced from the feedback slot's // kind. @@ -86,38 +84,46 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { Label* non_fast_elements, Label* only_fast_elements); - void TryRewriteElements(Node* receiver, TNode<Map> receiver_map, - Node* elements, Node* native_context, + void TryRewriteElements(TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<FixedArrayBase> elements, + TNode<NativeContext> native_context, ElementsKind from_kind, ElementsKind to_kind, Label* bailout); - void StoreElementWithCapacity(Node* receiver, TNode<Map> receiver_map, + void StoreElementWithCapacity(TNode<JSObject> receiver, + TNode<Map> receiver_map, SloppyTNode<FixedArrayBase> elements, TNode<Word32T> elements_kind, - TNode<IntPtrT> index, Node* value, - Node* context, Label* slow, + TNode<IntPtrT> index, SloppyTNode<Object> value, + TNode<Context> context, Label* slow, UpdateLength update_length); - void MaybeUpdateLengthAndReturn(Node* receiver, Node* index, Node* value, + void MaybeUpdateLengthAndReturn(TNode<JSObject> receiver, + TNode<IntPtrT> index, TNode<Object> value, UpdateLength update_length); - void TryChangeToHoleyMapHelper(Node* receiver, TNode<Map> receiver_map, - Node* native_context, ElementsKind packed_kind, + void TryChangeToHoleyMapHelper(TNode<JSObject> receiver, + TNode<Map> receiver_map, + TNode<NativeContext> native_context, + ElementsKind packed_kind, ElementsKind holey_kind, Label* done, Label* map_mismatch, Label* bailout); - void TryChangeToHoleyMap(Node* receiver, TNode<Map> receiver_map, - TNode<Word32T> current_elements_kind, Node* context, - ElementsKind packed_kind, Label* bailout); - void TryChangeToHoleyMapMulti(Node* receiver, TNode<Map> receiver_map, + void TryChangeToHoleyMap(TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, + TNode<Context> context, ElementsKind packed_kind, + Label* bailout); + void TryChangeToHoleyMapMulti(TNode<JSObject> receiver, + TNode<Map> receiver_map, TNode<Word32T> current_elements_kind, - Node* context, ElementsKind packed_kind, + TNode<Context> context, + ElementsKind packed_kind, ElementsKind packed_kind_2, Label* bailout); - void LookupPropertyOnPrototypeChain(TNode<Map> receiver_map, Node* name, - Label* accessor, - Variable* var_accessor_pair, - Variable* var_accessor_holder, - Label* readonly, Label* bailout); + void LookupPropertyOnPrototypeChain( + TNode<Map> receiver_map, TNode<Name> name, Label* accessor, + TVariable<Object>* var_accessor_pair, + TVariable<HeapObject>* var_accessor_holder, Label* readonly, + Label* bailout); TNode<Map> FindCandidateStoreICTransitionMapHandler(TNode<Map> map, TNode<Name> name, @@ -173,18 +179,18 @@ void KeyedStoreGenericGenerator::SetPropertyInLiteral( void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( TNode<Map> receiver_map, Label* non_fast_elements, Label* only_fast_elements) { - VARIABLE(var_map, MachineRepresentation::kTagged); - var_map.Bind(receiver_map); + TVARIABLE(Map, var_map); + var_map = receiver_map; Label loop_body(this, &var_map); Goto(&loop_body); BIND(&loop_body); { - Node* map = var_map.value(); + TNode<Map> map = var_map.value(); TNode<HeapObject> prototype = LoadMapPrototype(map); GotoIf(IsNull(prototype), only_fast_elements); TNode<Map> prototype_map = LoadMap(prototype); - var_map.Bind(prototype_map); + var_map = prototype_map; TNode<Uint16T> instance_type = LoadMapInstanceType(prototype_map); GotoIf(IsCustomElementsReceiverInstanceType(instance_type), non_fast_elements); @@ -196,9 +202,9 @@ void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( } void KeyedStoreGenericAssembler::TryRewriteElements( - Node* receiver, TNode<Map> receiver_map, Node* elements, - Node* native_context, ElementsKind from_kind, ElementsKind to_kind, - Label* bailout) { + TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<FixedArrayBase> elements, TNode<NativeContext> native_context, + ElementsKind from_kind, ElementsKind to_kind, Label* bailout) { DCHECK(IsFastPackedElementsKind(from_kind)); ElementsKind holey_from_kind = GetHoleyElementsKind(from_kind); ElementsKind holey_to_kind = GetHoleyElementsKind(to_kind); @@ -206,12 +212,12 @@ void KeyedStoreGenericAssembler::TryRewriteElements( TrapAllocationMemento(receiver, bailout); } Label perform_transition(this), check_holey_map(this); - VARIABLE(var_target_map, MachineRepresentation::kTagged); + TVARIABLE(Map, var_target_map); // Check if the receiver has the default |from_kind| map. { TNode<Map> packed_map = LoadJSArrayElementsMap(from_kind, native_context); GotoIf(TaggedNotEqual(receiver_map, packed_map), &check_holey_map); - var_target_map.Bind( + var_target_map = CAST( LoadContextElement(native_context, Context::ArrayMapIndex(to_kind))); Goto(&perform_transition); } @@ -222,7 +228,7 @@ void KeyedStoreGenericAssembler::TryRewriteElements( TNode<Object> holey_map = LoadContextElement( native_context, Context::ArrayMapIndex(holey_from_kind)); GotoIf(TaggedNotEqual(receiver_map, holey_map), bailout); - var_target_map.Bind(LoadContextElement( + var_target_map = CAST(LoadContextElement( native_context, Context::ArrayMapIndex(holey_to_kind))); Goto(&perform_transition); } @@ -240,9 +246,9 @@ void KeyedStoreGenericAssembler::TryRewriteElements( } void KeyedStoreGenericAssembler::TryChangeToHoleyMapHelper( - Node* receiver, TNode<Map> receiver_map, Node* native_context, - ElementsKind packed_kind, ElementsKind holey_kind, Label* done, - Label* map_mismatch, Label* bailout) { + TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<NativeContext> native_context, ElementsKind packed_kind, + ElementsKind holey_kind, Label* done, Label* map_mismatch, Label* bailout) { TNode<Map> packed_map = LoadJSArrayElementsMap(packed_kind, native_context); GotoIf(TaggedNotEqual(receiver_map, packed_map), map_mismatch); if (AllocationSite::ShouldTrack(packed_kind, holey_kind)) { @@ -255,23 +261,23 @@ void KeyedStoreGenericAssembler::TryChangeToHoleyMapHelper( } void KeyedStoreGenericAssembler::TryChangeToHoleyMap( - Node* receiver, TNode<Map> receiver_map, - TNode<Word32T> current_elements_kind, Node* context, + TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, TNode<Context> context, ElementsKind packed_kind, Label* bailout) { ElementsKind holey_kind = GetHoleyElementsKind(packed_kind); Label already_holey(this); GotoIf(Word32Equal(current_elements_kind, Int32Constant(holey_kind)), &already_holey); - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); TryChangeToHoleyMapHelper(receiver, receiver_map, native_context, packed_kind, holey_kind, &already_holey, bailout, bailout); BIND(&already_holey); } void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( - Node* receiver, TNode<Map> receiver_map, - TNode<Word32T> current_elements_kind, Node* context, + TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<Word32T> current_elements_kind, TNode<Context> context, ElementsKind packed_kind, ElementsKind packed_kind_2, Label* bailout) { ElementsKind holey_kind = GetHoleyElementsKind(packed_kind); ElementsKind holey_kind_2 = GetHoleyElementsKind(packed_kind_2); @@ -282,7 +288,7 @@ void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( GotoIf(Word32Equal(current_elements_kind, Int32Constant(holey_kind_2)), &already_holey); - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); TryChangeToHoleyMapHelper(receiver, receiver_map, native_context, packed_kind, holey_kind, &already_holey, &check_other_kind, bailout); @@ -294,7 +300,8 @@ void KeyedStoreGenericAssembler::TryChangeToHoleyMapMulti( } void KeyedStoreGenericAssembler::MaybeUpdateLengthAndReturn( - Node* receiver, Node* index, Node* value, UpdateLength update_length) { + TNode<JSObject> receiver, TNode<IntPtrT> index, TNode<Object> value, + UpdateLength update_length) { if (update_length != kDontChangeLength) { TNode<Smi> new_length = SmiTag(Signed(IntPtrAdd(index, IntPtrConstant(1)))); StoreObjectFieldNoWriteBarrier(receiver, JSArray::kLengthOffset, new_length, @@ -304,10 +311,10 @@ void KeyedStoreGenericAssembler::MaybeUpdateLengthAndReturn( } void KeyedStoreGenericAssembler::StoreElementWithCapacity( - Node* receiver, TNode<Map> receiver_map, + TNode<JSObject> receiver, TNode<Map> receiver_map, SloppyTNode<FixedArrayBase> elements, TNode<Word32T> elements_kind, - TNode<IntPtrT> index, Node* value, Node* context, Label* slow, - UpdateLength update_length) { + TNode<IntPtrT> index, SloppyTNode<Object> value, TNode<Context> context, + Label* slow, UpdateLength update_length) { if (update_length != kDontChangeLength) { CSA_ASSERT(this, InstanceTypeEqual(LoadMapInstanceType(receiver_map), JS_ARRAY_TYPE)); @@ -331,8 +338,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // FixedArray backing store -> Smi or object elements. { - TNode<IntPtrT> offset = ElementOffsetFromIndex( - index, PACKED_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> offset = + ElementOffsetFromIndex(index, PACKED_ELEMENTS, kHeaderSize); // Check if we're about to overwrite the hole. We can safely do that // only if there can be no setters on the prototype chain. // If we know that we're storing beyond the previous array length, we @@ -387,8 +394,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // Transition to the required ElementsKind. { Label transition_to_double(this), transition_to_object(this); - TNode<Context> native_context = LoadNativeContext(context); - Branch(TaggedEqual(LoadMap(value), HeapNumberMapConstant()), + TNode<NativeContext> native_context = LoadNativeContext(context); + Branch(TaggedEqual(LoadMap(CAST(value)), HeapNumberMapConstant()), &transition_to_double, &transition_to_object); BIND(&transition_to_double); { @@ -401,11 +408,11 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( PACKED_SMI_ELEMENTS, target_kind, slow); // Reload migrated elements. TNode<FixedArrayBase> double_elements = LoadElements(receiver); - TNode<IntPtrT> double_offset = ElementOffsetFromIndex( - index, PACKED_DOUBLE_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> double_offset = + ElementOffsetFromIndex(index, PACKED_DOUBLE_ELEMENTS, kHeaderSize); // Make sure we do not store signalling NaNs into double arrays. TNode<Float64T> double_value = - Float64SilenceNaN(LoadHeapNumberValue(value)); + Float64SilenceNaN(LoadHeapNumberValue(CAST(value))); StoreNoWriteBarrier(MachineRepresentation::kFloat64, double_elements, double_offset, double_value); MaybeUpdateLengthAndReturn(receiver, index, value, update_length); @@ -434,8 +441,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( &check_cow_elements); // FixedDoubleArray backing store -> double elements. { - TNode<IntPtrT> offset = ElementOffsetFromIndex( - index, PACKED_DOUBLE_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> offset = + ElementOffsetFromIndex(index, PACKED_DOUBLE_ELEMENTS, kHeaderSize); // Check if we're about to overwrite the hole. We can safely do that // only if there can be no setters on the prototype chain. { @@ -457,7 +464,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // Try to store the value as a double. { Label non_number_value(this); - Node* double_value = TryTaggedToFloat64(value, &non_number_value); + TNode<Float64T> double_value = + TryTaggedToFloat64(value, &non_number_value); // Make sure we do not store signalling NaNs into double arrays. double_value = Float64SilenceNaN(double_value); @@ -475,7 +483,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( // Transition to object elements. { - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); ElementsKind target_kind = update_length == kBumpLengthWithGap ? HOLEY_ELEMENTS : PACKED_ELEMENTS; @@ -483,8 +491,8 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( PACKED_DOUBLE_ELEMENTS, target_kind, slow); // Reload migrated elements. TNode<FixedArrayBase> fast_elements = LoadElements(receiver); - TNode<IntPtrT> fast_offset = ElementOffsetFromIndex( - index, PACKED_ELEMENTS, INTPTR_PARAMETERS, kHeaderSize); + TNode<IntPtrT> fast_offset = + ElementOffsetFromIndex(index, PACKED_ELEMENTS, kHeaderSize); Store(fast_elements, fast_offset, value); MaybeUpdateLengthAndReturn(receiver, index, value, update_length); } @@ -498,8 +506,9 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( } void KeyedStoreGenericAssembler::EmitGenericElementStore( - Node* receiver, TNode<Map> receiver_map, Node* instance_type, - TNode<IntPtrT> index, Node* value, Node* context, Label* slow) { + TNode<JSObject> receiver, TNode<Map> receiver_map, + TNode<Uint16T> instance_type, TNode<IntPtrT> index, TNode<Object> value, + TNode<Context> context, Label* slow) { Label if_fast(this), if_in_bounds(this), if_out_of_bounds(this), if_increment_length_by_one(this), if_bump_length_with_gap(this), if_grow(this), if_nonfast(this), if_typed_array(this), @@ -517,7 +526,7 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( } BIND(&if_array); { - TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(receiver)); + TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(CAST(receiver))); GotoIf(UintPtrLessThan(index, length), &if_in_bounds); TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); GotoIf(UintPtrGreaterThanOrEqual(index, capacity), &if_grow); @@ -595,32 +604,32 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore( } void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( - TNode<Map> receiver_map, Node* name, Label* accessor, - Variable* var_accessor_pair, Variable* var_accessor_holder, Label* readonly, + TNode<Map> receiver_map, TNode<Name> name, Label* accessor, + TVariable<Object>* var_accessor_pair, + TVariable<HeapObject>* var_accessor_holder, Label* readonly, Label* bailout) { Label ok_to_write(this); - VARIABLE(var_holder, MachineRepresentation::kTagged); - var_holder.Bind(LoadMapPrototype(receiver_map)); - VARIABLE(var_holder_map, MachineRepresentation::kTagged); - var_holder_map.Bind(LoadMap(var_holder.value())); + TVARIABLE(HeapObject, var_holder); + TVARIABLE(Map, var_holder_map); + var_holder = LoadMapPrototype(receiver_map); + var_holder_map = LoadMap(var_holder.value()); - Variable* merged_variables[] = {&var_holder, &var_holder_map}; - Label loop(this, arraysize(merged_variables), merged_variables); + Label loop(this, {&var_holder, &var_holder_map}); Goto(&loop); BIND(&loop); { - Node* holder = var_holder.value(); + TNode<HeapObject> holder = var_holder.value(); GotoIf(IsNull(holder), &ok_to_write); - Node* holder_map = var_holder_map.value(); + TNode<Map> holder_map = var_holder_map.value(); TNode<Uint16T> instance_type = LoadMapInstanceType(holder_map); Label next_proto(this); { Label found(this), found_fast(this), found_dict(this), found_global(this); TVARIABLE(HeapObject, var_meta_storage); TVARIABLE(IntPtrT, var_entry); - TryLookupProperty(holder, holder_map, instance_type, name, &found_fast, - &found_dict, &found_global, &var_meta_storage, - &var_entry, &next_proto, bailout); + TryLookupProperty(CAST(holder), holder_map, instance_type, name, + &found_fast, &found_dict, &found_global, + &var_meta_storage, &var_entry, &next_proto, bailout); BIND(&found_fast); { TNode<DescriptorArray> descriptors = CAST(var_meta_storage.value()); @@ -631,10 +640,10 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( // Accessor case. // TODO(jkummerow): Implement a trimmed-down // LoadAccessorFromFastObject. - VARIABLE(var_details, MachineRepresentation::kWord32); + TVARIABLE(Uint32T, var_details); LoadPropertyFromFastObject(holder, holder_map, descriptors, name_index, &var_details, var_accessor_pair); - var_accessor_holder->Bind(holder); + *var_accessor_holder = holder; Goto(accessor); } @@ -648,9 +657,9 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( if (accessor != nullptr) { // Accessor case. - var_accessor_pair->Bind( - LoadValueByKeyIndex<NameDictionary>(dictionary, entry)); - var_accessor_holder->Bind(holder); + *var_accessor_pair = + LoadValueByKeyIndex<NameDictionary>(dictionary, entry); + *var_accessor_holder = holder; Goto(accessor); } else { Goto(&ok_to_write); @@ -666,14 +675,14 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( TNode<Object> value = LoadObjectField(property_cell, PropertyCell::kValueOffset); GotoIf(TaggedEqual(value, TheHoleConstant()), &next_proto); - TNode<Int32T> details = LoadAndUntagToWord32ObjectField( - property_cell, PropertyCell::kPropertyDetailsRawOffset); + TNode<Uint32T> details = Unsigned(LoadAndUntagToWord32ObjectField( + property_cell, PropertyCell::kPropertyDetailsRawOffset)); JumpIfDataProperty(details, &ok_to_write, readonly); if (accessor != nullptr) { // Accessor case. - var_accessor_pair->Bind(value); - var_accessor_holder->Bind(holder); + *var_accessor_pair = value; + *var_accessor_holder = holder; Goto(accessor); } else { Goto(&ok_to_write); @@ -686,8 +695,8 @@ void KeyedStoreGenericAssembler::LookupPropertyOnPrototypeChain( GotoIf(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE), bailout); TNode<HeapObject> proto = LoadMapPrototype(holder_map); GotoIf(IsNull(proto), &ok_to_write); - var_holder.Bind(proto); - var_holder_map.Bind(LoadMap(proto)); + var_holder = proto; + var_holder_map = LoadMap(proto); Goto(&loop); } BIND(&ok_to_write); @@ -763,8 +772,10 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( const StoreICParameters* p, ExitPoint* exit_point, Label* slow, Maybe<LanguageMode> maybe_language_mode) { CSA_ASSERT(this, IsSimpleObjectMap(receiver_map)); - VARIABLE(var_accessor_pair, MachineRepresentation::kTagged); - VARIABLE(var_accessor_holder, MachineRepresentation::kTagged); + // TODO(rmcilroy) Type as Struct once we use a trimmed down + // LoadAccessorFromFastObject instead of LoadPropertyFromFastObject. + TVARIABLE(Object, var_accessor_pair); + TVARIABLE(HeapObject, var_accessor_holder); Label fast_properties(this), dictionary_properties(this), accessor(this), readonly(this); TNode<Uint32T> bitfield3 = LoadMapBitField3(receiver_map); @@ -792,11 +803,11 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( if (ShouldCallSetter()) { // Accessor case. // TODO(jkummerow): Implement a trimmed-down LoadAccessorFromFastObject. - VARIABLE(var_details, MachineRepresentation::kWord32); + TVARIABLE(Uint32T, var_details); LoadPropertyFromFastObject(receiver, receiver_map, descriptors, name_index, &var_details, &var_accessor_pair); - var_accessor_holder.Bind(receiver); + var_accessor_holder = receiver; Goto(&accessor); } else { // Handle accessor to data property reconfiguration in runtime. @@ -836,7 +847,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( TVARIABLE(IntPtrT, var_name_index); Label dictionary_found(this, &var_name_index), not_found(this); - TNode<NameDictionary> properties = CAST(LoadSlowProperties(CAST(receiver))); + TNode<NameDictionary> properties = CAST(LoadSlowProperties(receiver)); NameDictionaryLookup<NameDictionary>(properties, name, &dictionary_found, &var_name_index, ¬_found); BIND(&dictionary_found); @@ -849,9 +860,9 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( if (ShouldCallSetter()) { // Accessor case. - var_accessor_pair.Bind(LoadValueByKeyIndex<NameDictionary>( - properties, var_name_index.value())); - var_accessor_holder.Bind(receiver); + var_accessor_pair = LoadValueByKeyIndex<NameDictionary>( + properties, var_name_index.value()); + var_accessor_holder = receiver; Goto(&accessor); } else { // We must reconfigure an accessor property to a data property @@ -870,6 +881,11 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(¬_found); { + // TODO(jkummerow): Also add support to correctly handle integer exotic + // cases for typed arrays and remove this check here. + GotoIf(InstanceTypeEqual(LoadMapInstanceType(receiver_map), + JS_TYPED_ARRAY_TYPE), + slow); CheckForAssociatedProtector(name, slow); Label extensible(this), is_private_symbol(this); TNode<Uint32T> bitfield3 = LoadMapBitField3(receiver_map); @@ -909,7 +925,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( BIND(&accessor); { Label not_callable(this); - Node* accessor_pair = var_accessor_pair.value(); + TNode<Struct> accessor_pair = CAST(var_accessor_pair.value()); GotoIf(IsAccessorInfoMap(LoadMap(accessor_pair)), slow); CSA_ASSERT(this, HasInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE)); TNode<HeapObject> setter = @@ -951,7 +967,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( LanguageMode language_mode; if (maybe_language_mode.To(&language_mode)) { if (language_mode == LanguageMode::kStrict) { - Node* type = Typeof(p->receiver()); + TNode<String> type = Typeof(p->receiver()); ThrowTypeError(p->context(), MessageTemplate::kStrictReadOnlyProperty, name, type, p->receiver()); } else { @@ -969,15 +985,16 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( // Helper that is used by the public KeyedStoreGeneric and by SetProperty. void KeyedStoreGenericAssembler::KeyedStoreGeneric( - TNode<Context> context, TNode<Object> receiver, TNode<Object> key, + TNode<Context> context, TNode<Object> receiver_maybe_smi, TNode<Object> key, TNode<Object> value, Maybe<LanguageMode> language_mode) { TVARIABLE(IntPtrT, var_index); - TVARIABLE(Object, var_unique, key); + TVARIABLE(Name, var_unique); Label if_index(this), if_unique_name(this), not_internalized(this), slow(this); - GotoIf(TaggedIsSmi(receiver), &slow); - TNode<Map> receiver_map = LoadMap(CAST(receiver)); + GotoIf(TaggedIsSmi(receiver_maybe_smi), &slow); + TNode<HeapObject> receiver = CAST(receiver_maybe_smi); + TNode<Map> receiver_map = LoadMap(receiver); TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); // Receivers requiring non-standard element accesses (interceptors, access // checks, strings and string wrappers, proxies) are handled in the runtime. @@ -989,14 +1006,14 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric( BIND(&if_index); { Comment("integer index"); - EmitGenericElementStore(receiver, receiver_map, instance_type, + EmitGenericElementStore(CAST(receiver), receiver_map, instance_type, var_index.value(), value, context, &slow); } BIND(&if_unique_name); { Comment("key is unique name"); - StoreICParameters p(context, receiver, var_unique.value(), value, nullptr, + StoreICParameters p(context, receiver, var_unique.value(), value, {}, nullptr); ExitPoint direct_exit(this); EmitGenericPropertyStore(CAST(receiver), receiver_map, &p, &direct_exit, @@ -1006,7 +1023,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric( BIND(¬_internalized); { if (FLAG_internalize_on_the_fly) { - TryInternalizeString(key, &if_index, &var_index, &if_unique_name, + TryInternalizeString(CAST(key), &if_index, &var_index, &if_unique_name, &var_unique, &slow, &slow); } else { Goto(&slow); @@ -1049,30 +1066,34 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, void KeyedStoreGenericAssembler::StoreIC_NoFeedback() { using Descriptor = StoreDescriptor; - Node* receiver = Parameter(Descriptor::kReceiver); + TNode<Object> receiver_maybe_smi = CAST(Parameter(Descriptor::kReceiver)); TNode<Object> name = CAST(Parameter(Descriptor::kName)); - Node* value = Parameter(Descriptor::kValue); - Node* slot = Parameter(Descriptor::kSlot); - Node* context = Parameter(Descriptor::kContext); + TNode<Object> value = CAST(Parameter(Descriptor::kValue)); + TNode<Smi> slot = CAST(Parameter(Descriptor::kSlot)); + TNode<Context> context = CAST(Parameter(Descriptor::kContext)); Label miss(this, Label::kDeferred), store_property(this); - GotoIf(TaggedIsSmi(receiver), &miss); - TNode<Map> receiver_map = LoadMap(receiver); - TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); - // Receivers requiring non-standard element accesses (interceptors, access - // checks, strings and string wrappers, proxies) are handled in the runtime. - GotoIf(IsSpecialReceiverInstanceType(instance_type), &miss); + GotoIf(TaggedIsSmi(receiver_maybe_smi), &miss); + { - StoreICParameters p(CAST(context), receiver, name, value, slot, - UndefinedConstant()); - EmitGenericPropertyStore(receiver, receiver_map, &p, &miss); + TNode<HeapObject> receiver = CAST(receiver_maybe_smi); + TNode<Map> receiver_map = LoadMap(receiver); + TNode<Uint16T> instance_type = LoadMapInstanceType(receiver_map); + // Receivers requiring non-standard element accesses (interceptors, access + // checks, strings and string wrappers, proxies) are handled in the runtime. + GotoIf(IsSpecialReceiverInstanceType(instance_type), &miss); + { + StoreICParameters p(context, receiver, name, value, slot, + UndefinedConstant()); + EmitGenericPropertyStore(CAST(receiver), receiver_map, &p, &miss); + } } BIND(&miss); { TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, - UndefinedConstant(), receiver, name); + UndefinedConstant(), receiver_maybe_smi, name); } } @@ -1082,7 +1103,7 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, TNode<Name> unique_name, TNode<Object> value, LanguageMode language_mode) { - StoreICParameters p(context, receiver, unique_name, value, nullptr, nullptr); + StoreICParameters p(context, receiver, unique_name, value, {}, nullptr); Label done(this), slow(this, Label::kDeferred); ExitPoint exit_point(this, [&](Node* result) { Goto(&done); }); diff --git a/deps/v8/src/ic/keyed-store-generic.h b/deps/v8/src/ic/keyed-store-generic.h index efee0da80e6c62..8047fe649345b2 100644 --- a/deps/v8/src/ic/keyed-store-generic.h +++ b/deps/v8/src/ic/keyed-store-generic.h @@ -13,9 +13,6 @@ namespace internal { class KeyedStoreGenericGenerator { public: - template <class T> - using TNode = compiler::TNode<T>; - static void Generate(compiler::CodeAssemblerState* state); // Building block for fast path of Object.assign implementation. diff --git a/deps/v8/src/ic/stub-cache.cc b/deps/v8/src/ic/stub-cache.cc index 04381bf693cb4a..c1d9aea3748d37 100644 --- a/deps/v8/src/ic/stub-cache.cc +++ b/deps/v8/src/ic/stub-cache.cc @@ -26,11 +26,10 @@ void StubCache::Initialize() { Clear(); } -// Hash algorithm for the primary table. This algorithm is replicated in -// assembler for every architecture. Returns an index into the table that +// Hash algorithm for the primary table. This algorithm is replicated in +// the AccessorAssembler. Returns an index into the table that // is scaled by 1 << kCacheIndexShift. int StubCache::PrimaryOffset(Name name, Map map) { - STATIC_ASSERT(kCacheIndexShift == Name::kHashShift); // Compute the hash of the name (use entire hash field). DCHECK(name.HasHashCode()); uint32_t field = name.hash_field(); diff --git a/deps/v8/src/ic/stub-cache.h b/deps/v8/src/ic/stub-cache.h index 87acc0e007e193..dc3317588dbd23 100644 --- a/deps/v8/src/ic/stub-cache.h +++ b/deps/v8/src/ic/stub-cache.h @@ -78,10 +78,15 @@ class V8_EXPORT_PRIVATE StubCache { Isolate* isolate() { return isolate_; } - // Setting the entry size such that the index is shifted by Name::kHashShift - // is convenient; shifting down the length field (to extract the hash code) - // automatically discards the hash bit field. - static const int kCacheIndexShift = Name::kHashShift; + // Ideally we would set kCacheIndexShift to Name::kHashShift, such that + // the bit field inside the hash field gets shifted out implicitly. However, + // sizeof(Entry) needs to be a multiple of 1 << kCacheIndexShift, and it + // isn't clear whether letting one bit of the bit field leak into the index + // computation is bad enough to warrant an additional shift to get rid of it. + static const int kCacheIndexShift = 2; + // The purpose of the static assert is to make us reconsider this choice + // if the bit field ever grows even more. + STATIC_ASSERT(kCacheIndexShift == Name::kHashShift - 1); static const int kPrimaryTableBits = 11; static const int kPrimaryTableSize = (1 << kPrimaryTableBits); @@ -125,7 +130,10 @@ class V8_EXPORT_PRIVATE StubCache { // of sizeof(Entry). This makes it easier to avoid making mistakes // in the hashed offset computations. static Entry* entry(Entry* table, int offset) { - const int multiplier = sizeof(*table) >> Name::kHashShift; + // The size of {Entry} must be a multiple of 1 << kCacheIndexShift. + STATIC_ASSERT((sizeof(*table) >> kCacheIndexShift) << kCacheIndexShift == + sizeof(*table)); + const int multiplier = sizeof(*table) >> kCacheIndexShift; return reinterpret_cast<Entry*>(reinterpret_cast<Address>(table) + offset * multiplier); } diff --git a/deps/v8/src/init/bootstrapper.cc b/deps/v8/src/init/bootstrapper.cc index f7e25ca0bbc99c..148c60d89d39d6 100644 --- a/deps/v8/src/init/bootstrapper.cc +++ b/deps/v8/src/init/bootstrapper.cc @@ -12,6 +12,7 @@ #include "src/debug/debug.h" #include "src/execution/isolate-inl.h" #include "src/execution/microtask-queue.h" +#include "src/execution/protectors.h" #include "src/extensions/cputracemark-extension.h" #include "src/extensions/externalize-string-extension.h" #include "src/extensions/free-buffer-extension.h" @@ -130,15 +131,15 @@ static bool isValidCpuTraceMarkFunctionName() { } void Bootstrapper::InitializeOncePerProcess() { - v8::RegisterExtension(v8::base::make_unique<FreeBufferExtension>()); - v8::RegisterExtension(v8::base::make_unique<GCExtension>(GCFunctionName())); - v8::RegisterExtension(v8::base::make_unique<ExternalizeStringExtension>()); - v8::RegisterExtension(v8::base::make_unique<StatisticsExtension>()); - v8::RegisterExtension(v8::base::make_unique<TriggerFailureExtension>()); - v8::RegisterExtension(v8::base::make_unique<IgnitionStatisticsExtension>()); + v8::RegisterExtension(std::make_unique<FreeBufferExtension>()); + v8::RegisterExtension(std::make_unique<GCExtension>(GCFunctionName())); + v8::RegisterExtension(std::make_unique<ExternalizeStringExtension>()); + v8::RegisterExtension(std::make_unique<StatisticsExtension>()); + v8::RegisterExtension(std::make_unique<TriggerFailureExtension>()); + v8::RegisterExtension(std::make_unique<IgnitionStatisticsExtension>()); if (isValidCpuTraceMarkFunctionName()) { - v8::RegisterExtension(v8::base::make_unique<CpuTraceMarkExtension>( - FLAG_expose_cputracemark_as)); + v8::RegisterExtension( + std::make_unique<CpuTraceMarkExtension>(FLAG_expose_cputracemark_as)); } } @@ -284,6 +285,9 @@ class Genesis { void TransferNamedProperties(Handle<JSObject> from, Handle<JSObject> to); void TransferIndexedProperties(Handle<JSObject> from, Handle<JSObject> to); + Handle<Map> CreateInitialMapForArraySubclass(int size, + int inobject_properties); + static bool CompileExtension(Isolate* isolate, v8::Extension* extension); Isolate* isolate_; @@ -867,6 +871,29 @@ void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) { generator_next_internal->shared().set_native(false); native_context()->set_generator_next_internal(*generator_next_internal); + // Internal version of async module functions, flagged as non-native such + // that they don't show up in Error traces. + { + Handle<JSFunction> async_module_evaluate_internal = + SimpleCreateFunction(isolate(), factory()->next_string(), + Builtins::kAsyncModuleEvaluate, 1, false); + async_module_evaluate_internal->shared().set_native(false); + native_context()->set_async_module_evaluate_internal( + *async_module_evaluate_internal); + + Handle<JSFunction> call_async_module_fulfilled = + SimpleCreateFunction(isolate(), factory()->empty_string(), + Builtins::kCallAsyncModuleFulfilled, 1, false); + native_context()->set_call_async_module_fulfilled( + *call_async_module_fulfilled); + + Handle<JSFunction> call_async_module_rejected = + SimpleCreateFunction(isolate(), factory()->empty_string(), + Builtins::kCallAsyncModuleRejected, 1, false); + native_context()->set_call_async_module_rejected( + *call_async_module_rejected); + } + // Create maps for generator functions and their prototypes. Store those // maps in the native context. The "prototype" property descriptor is // writable, non-enumerable, and non-configurable (as per ES6 draft @@ -1098,9 +1125,9 @@ void ReplaceAccessors(Isolate* isolate, Handle<Map> map, Handle<String> name, PropertyAttributes attributes, Handle<AccessorPair> accessor_pair) { DescriptorArray descriptors = map->instance_descriptors(); - int idx = descriptors.SearchWithCache(isolate, *name, *map); + InternalIndex entry = descriptors.SearchWithCache(isolate, *name, *map); Descriptor d = Descriptor::AccessorConstant(name, accessor_pair, attributes); - descriptors.Replace(idx, &d); + descriptors.Replace(entry, &d); } } // namespace @@ -1274,8 +1301,8 @@ Handle<JSGlobalObject> Genesis::CreateNewGlobals( DCHECK(native_context() ->get(Context::GLOBAL_PROXY_INDEX) .IsUndefined(isolate()) || - native_context()->global_proxy() == *global_proxy); - native_context()->set_global_proxy(*global_proxy); + native_context()->global_proxy_object() == *global_proxy); + native_context()->set_global_proxy_object(*global_proxy); return global_object; } @@ -2432,7 +2459,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { // -- R e g E x p // Builtin functions for RegExp.prototype. Handle<JSFunction> regexp_fun = InstallFunction( - isolate_, global, "RegExp", JS_REGEXP_TYPE, + isolate_, global, "RegExp", JS_REG_EXP_TYPE, JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kTaggedSize, JSRegExp::kInObjectFieldCount, factory->the_hole_value(), Builtins::kRegExpConstructor); @@ -2455,7 +2482,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kRegExpPrototypeExec, 1, true); native_context()->set_regexp_exec_function(*fun); DCHECK_EQ(JSRegExp::kExecFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } SimpleInstallGetter(isolate_, prototype, factory->dotAll_string(), @@ -2488,7 +2515,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kRegExpPrototypeMatch, 1, true); native_context()->set_regexp_match_function(*fun); DCHECK_EQ(JSRegExp::kSymbolMatchFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } { @@ -2497,7 +2524,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, "[Symbol.matchAll]", Builtins::kRegExpPrototypeMatchAll, 1, true); native_context()->set_regexp_match_all_function(*fun); DCHECK_EQ(JSRegExp::kSymbolMatchAllFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } { @@ -2506,7 +2533,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kRegExpPrototypeReplace, 2, false); native_context()->set_regexp_replace_function(*fun); DCHECK_EQ(JSRegExp::kSymbolReplaceFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } { @@ -2515,7 +2542,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kRegExpPrototypeSearch, 1, true); native_context()->set_regexp_search_function(*fun); DCHECK_EQ(JSRegExp::kSymbolSearchFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } { @@ -2524,7 +2551,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kRegExpPrototypeSplit, 2, false); native_context()->set_regexp_split_function(*fun); DCHECK_EQ(JSRegExp::kSymbolSplitFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); } Handle<Map> prototype_map(prototype->map(), isolate()); @@ -2616,7 +2643,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string()); - cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); + cell->set_value(Smi::FromInt(Protectors::kProtectorValid)); native_context()->set_regexp_species_protector(*cell); } @@ -2647,7 +2674,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, true); Handle<JSFunction> regexp_string_iterator_function = CreateFunction( - isolate(), "RegExpStringIterator", JS_REGEXP_STRING_ITERATOR_TYPE, + isolate(), "RegExpStringIterator", JS_REG_EXP_STRING_ITERATOR_TYPE, JSRegExpStringIterator::kSize, 0, regexp_string_iterator_prototype, Builtins::kIllegal); regexp_string_iterator_function->shared().set_native(false); @@ -2886,7 +2913,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { // -- D a t e T i m e F o r m a t Handle<JSFunction> date_time_format_constructor = InstallFunction( - isolate_, intl, "DateTimeFormat", JS_INTL_DATE_TIME_FORMAT_TYPE, + isolate_, intl, "DateTimeFormat", JS_DATE_TIME_FORMAT_TYPE, JSDateTimeFormat::kSize, 0, factory->the_hole_value(), Builtins::kDateTimeFormatConstructor); date_time_format_constructor->shared().set_length(0); @@ -2914,13 +2941,20 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, SimpleInstallGetter(isolate_, prototype, factory->format_string(), Builtins::kDateTimeFormatPrototypeFormat, false); + + SimpleInstallFunction(isolate_, prototype, "formatRange", + Builtins::kDateTimeFormatPrototypeFormatRange, 2, + false); + SimpleInstallFunction( + isolate_, prototype, "formatRangeToParts", + Builtins::kDateTimeFormatPrototypeFormatRangeToParts, 2, false); } { // -- N u m b e r F o r m a t - Handle<JSFunction> number_format_constructor = InstallFunction( - isolate_, intl, "NumberFormat", JS_INTL_NUMBER_FORMAT_TYPE, - JSNumberFormat::kSize, 0, factory->the_hole_value(), - Builtins::kNumberFormatConstructor); + Handle<JSFunction> number_format_constructor = + InstallFunction(isolate_, intl, "NumberFormat", JS_NUMBER_FORMAT_TYPE, + JSNumberFormat::kSize, 0, factory->the_hole_value(), + Builtins::kNumberFormatConstructor); number_format_constructor->shared().set_length(0); number_format_constructor->shared().DontAdaptArguments(); InstallWithIntrinsicDefaultProto( @@ -2949,8 +2983,8 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { // -- C o l l a t o r Handle<JSFunction> collator_constructor = InstallFunction( - isolate_, intl, "Collator", JS_INTL_COLLATOR_TYPE, JSCollator::kSize, - 0, factory->the_hole_value(), Builtins::kCollatorConstructor); + isolate_, intl, "Collator", JS_COLLATOR_TYPE, JSCollator::kSize, 0, + factory->the_hole_value(), Builtins::kCollatorConstructor); collator_constructor->shared().DontAdaptArguments(); InstallWithIntrinsicDefaultProto(isolate_, collator_constructor, Context::INTL_COLLATOR_FUNCTION_INDEX); @@ -2974,7 +3008,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { // -- V 8 B r e a k I t e r a t o r Handle<JSFunction> v8_break_iterator_constructor = InstallFunction( - isolate_, intl, "v8BreakIterator", JS_INTL_V8_BREAK_ITERATOR_TYPE, + isolate_, intl, "v8BreakIterator", JS_V8_BREAK_ITERATOR_TYPE, JSV8BreakIterator::kSize, 0, factory->the_hole_value(), Builtins::kV8BreakIteratorConstructor); v8_break_iterator_constructor->shared().DontAdaptArguments(); @@ -3009,11 +3043,14 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, } { // -- P l u r a l R u l e s - Handle<JSFunction> plural_rules_constructor = InstallFunction( - isolate_, intl, "PluralRules", JS_INTL_PLURAL_RULES_TYPE, - JSPluralRules::kSize, 0, factory->the_hole_value(), - Builtins::kPluralRulesConstructor); + Handle<JSFunction> plural_rules_constructor = + InstallFunction(isolate_, intl, "PluralRules", JS_PLURAL_RULES_TYPE, + JSPluralRules::kSize, 0, factory->the_hole_value(), + Builtins::kPluralRulesConstructor); plural_rules_constructor->shared().DontAdaptArguments(); + InstallWithIntrinsicDefaultProto( + isolate_, plural_rules_constructor, + Context::INTL_PLURAL_RULES_FUNCTION_INDEX); SimpleInstallFunction(isolate(), plural_rules_constructor, "supportedLocalesOf", @@ -3032,13 +3069,16 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Builtins::kPluralRulesPrototypeSelect, 1, false); } - { // -- R e l a t i v e T i m e F o r m a t e + { // -- R e l a t i v e T i m e F o r m a t Handle<JSFunction> relative_time_format_fun = InstallFunction( - isolate(), intl, "RelativeTimeFormat", - JS_INTL_RELATIVE_TIME_FORMAT_TYPE, JSRelativeTimeFormat::kSize, 0, - factory->the_hole_value(), Builtins::kRelativeTimeFormatConstructor); + isolate(), intl, "RelativeTimeFormat", JS_RELATIVE_TIME_FORMAT_TYPE, + JSRelativeTimeFormat::kSize, 0, factory->the_hole_value(), + Builtins::kRelativeTimeFormatConstructor); relative_time_format_fun->shared().set_length(0); relative_time_format_fun->shared().DontAdaptArguments(); + InstallWithIntrinsicDefaultProto( + isolate_, relative_time_format_fun, + Context::INTL_RELATIVE_TIME_FORMAT_FUNCTION_INDEX); SimpleInstallFunction( isolate(), relative_time_format_fun, "supportedLocalesOf", @@ -3063,12 +3103,14 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, } { // -- L i s t F o r m a t - Handle<JSFunction> list_format_fun = InstallFunction( - isolate(), intl, "ListFormat", JS_INTL_LIST_FORMAT_TYPE, - JSListFormat::kSize, 0, factory->the_hole_value(), - Builtins::kListFormatConstructor); + Handle<JSFunction> list_format_fun = + InstallFunction(isolate(), intl, "ListFormat", JS_LIST_FORMAT_TYPE, + JSListFormat::kSize, 0, factory->the_hole_value(), + Builtins::kListFormatConstructor); list_format_fun->shared().set_length(0); list_format_fun->shared().DontAdaptArguments(); + InstallWithIntrinsicDefaultProto( + isolate_, list_format_fun, Context::INTL_LIST_FORMAT_FUNCTION_INDEX); SimpleInstallFunction(isolate(), list_format_fun, "supportedLocalesOf", Builtins::kListFormatSupportedLocalesOf, 1, false); @@ -3091,7 +3133,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, { // -- L o c a l e Handle<JSFunction> locale_fun = InstallFunction( - isolate(), intl, "Locale", JS_INTL_LOCALE_TYPE, JSLocale::kSize, 0, + isolate(), intl, "Locale", JS_LOCALE_TYPE, JSLocale::kSize, 0, factory->the_hole_value(), Builtins::kLocaleConstructor); InstallWithIntrinsicDefaultProto(isolate(), locale_fun, Context::INTL_LOCALE_FUNCTION_INDEX); @@ -3394,7 +3436,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, isolate_, prototype, "set", Builtins::kMapPrototypeSet, 2, true); // Check that index of "set" function in JSCollection is correct. DCHECK_EQ(JSCollection::kAddFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); native_context()->set_map_set(*map_set); Handle<JSFunction> map_has = SimpleInstallFunction( @@ -3490,7 +3532,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, isolate_, prototype, "add", Builtins::kSetPrototypeAdd, 1, true); // Check that index of "add" function in JSCollection is correct. DCHECK_EQ(JSCollection::kAddFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); native_context()->set_set_add(*set_add); Handle<JSFunction> set_delete = SimpleInstallFunction( @@ -3523,6 +3565,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Handle<Map> map = factory->NewMap( JS_MODULE_NAMESPACE_TYPE, JSModuleNamespace::kSize, TERMINAL_FAST_ELEMENTS_KIND, JSModuleNamespace::kInObjectFieldCount); + map->SetConstructor(native_context()->object_function()); Map::SetPrototype(isolate(), map, isolate_->factory()->null_value()); Map::EnsureDescriptorSlack(isolate_, map, 1); native_context()->set_js_module_namespace_map(*map); @@ -3593,7 +3636,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, isolate_, prototype, "set", Builtins::kWeakMapPrototypeSet, 2, true); // Check that index of "set" function in JSWeakCollection is correct. DCHECK_EQ(JSWeakCollection::kAddFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); native_context()->set_weakmap_set(*weakmap_set); SimpleInstallFunction(isolate_, prototype, "has", @@ -3628,7 +3671,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, isolate_, prototype, "add", Builtins::kWeakSetPrototypeAdd, 1, true); // Check that index of "add" function in JSWeakCollection is correct. DCHECK_EQ(JSWeakCollection::kAddFunctionDescriptorIndex, - prototype->map().LastAdded()); + prototype->map().LastAdded().as_int()); native_context()->set_weakset_add(*weakset_add); @@ -3748,7 +3791,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, Handle<String> arguments_string = factory->Arguments_string(); NewFunctionArgs args = NewFunctionArgs::ForBuiltinWithPrototype( arguments_string, isolate_->initial_object_prototype(), - JS_ARGUMENTS_TYPE, JSSloppyArgumentsObject::kSize, 2, + JS_ARGUMENTS_OBJECT_TYPE, JSSloppyArgumentsObject::kSize, 2, Builtins::kIllegal, MUTABLE); Handle<JSFunction> function = factory->NewFunction(args); Handle<Map> map(function->initial_map(), isolate()); @@ -3805,8 +3848,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, callee->set_setter(*poison); // Create the map. Allocate one in-object field for length. - Handle<Map> map = factory->NewMap( - JS_ARGUMENTS_TYPE, JSStrictArgumentsObject::kSize, PACKED_ELEMENTS, 1); + Handle<Map> map = + factory->NewMap(JS_ARGUMENTS_OBJECT_TYPE, + JSStrictArgumentsObject::kSize, PACKED_ELEMENTS, 1); // Create the descriptor array for the arguments object. Map::EnsureDescriptorSlack(isolate_, map, 2); @@ -4265,16 +4309,14 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_meta) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_regexp_sequence) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_optional_chaining) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_nullish) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_top_level_await) #ifdef V8_INTL_SUPPORT EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_add_calendar_numbering_system) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_bigint) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_dateformat_day_period) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE( harmony_intl_dateformat_fractional_second_digits) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_dateformat_quarter) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_datetime_style) -EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_numberformat_unified) +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_other_calendars) #endif // V8_INTL_SUPPORT #undef EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE @@ -4419,34 +4461,20 @@ void Genesis::InitializeGlobal_harmony_promise_all_settled() { } } -#ifdef V8_INTL_SUPPORT - -void Genesis::InitializeGlobal_harmony_intl_date_format_range() { - if (!FLAG_harmony_intl_date_format_range) return; - - Handle<JSObject> intl = Handle<JSObject>::cast( - JSReceiver::GetProperty( - isolate(), - Handle<JSReceiver>(native_context()->global_object(), isolate()), - factory()->InternalizeUtf8String("Intl")) - .ToHandleChecked()); - - Handle<JSFunction> date_time_format_constructor = Handle<JSFunction>::cast( - JSReceiver::GetProperty( - isolate(), intl, factory()->InternalizeUtf8String("DateTimeFormat")) - .ToHandleChecked()); +void Genesis::InitializeGlobal_harmony_regexp_match_indices() { + if (!FLAG_harmony_regexp_match_indices) return; - Handle<JSObject> prototype( - JSObject::cast(date_time_format_constructor->prototype()), isolate_); - - SimpleInstallFunction(isolate_, prototype, "formatRange", - Builtins::kDateTimeFormatPrototypeFormatRange, 2, - false); - SimpleInstallFunction(isolate_, prototype, "formatRangeToParts", - Builtins::kDateTimeFormatPrototypeFormatRangeToParts, 2, - false); + // Add indices accessor to JSRegExpResult's initial map. + Handle<Map> initial_map(native_context()->regexp_result_map(), isolate()); + Descriptor d = Descriptor::AccessorConstant( + factory()->indices_string(), factory()->regexp_result_indices_accessor(), + NONE); + Map::EnsureDescriptorSlack(isolate(), initial_map, 1); + initial_map->AppendDescriptor(isolate(), &d); } +#ifdef V8_INTL_SUPPORT + void Genesis::InitializeGlobal_harmony_intl_segmenter() { if (!FLAG_harmony_intl_segmenter) return; Handle<JSObject> intl = Handle<JSObject>::cast( @@ -4457,10 +4485,12 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() { .ToHandleChecked()); Handle<JSFunction> segmenter_fun = InstallFunction( - isolate(), intl, "Segmenter", JS_INTL_SEGMENTER_TYPE, JSSegmenter::kSize, - 0, factory()->the_hole_value(), Builtins::kSegmenterConstructor); + isolate(), intl, "Segmenter", JS_SEGMENTER_TYPE, JSSegmenter::kSize, 0, + factory()->the_hole_value(), Builtins::kSegmenterConstructor); segmenter_fun->shared().set_length(0); segmenter_fun->shared().DontAdaptArguments(); + InstallWithIntrinsicDefaultProto(isolate_, segmenter_fun, + Context::INTL_SEGMENTER_FUNCTION_INDEX); SimpleInstallFunction(isolate(), segmenter_fun, "supportedLocalesOf", Builtins::kSegmenterSupportedLocalesOf, 1, false); @@ -4515,7 +4545,7 @@ void Genesis::InitializeGlobal_harmony_intl_segmenter() { isolate()->factory()->SegmentIterator_string()) .ToHandleChecked(); Handle<JSFunction> segment_iterator_fun = CreateFunction( - isolate(), name_string, JS_INTL_SEGMENT_ITERATOR_TYPE, + isolate(), name_string, JS_SEGMENT_ITERATOR_TYPE, JSSegmentIterator::kSize, 0, prototype, Builtins::kIllegal); segment_iterator_fun->shared().set_native(false); @@ -4900,42 +4930,10 @@ bool Genesis::InstallNatives() { // predefines the properties index, input, and groups). { // JSRegExpResult initial map. - - // Find global.Array.prototype to inherit from. - Handle<JSFunction> array_constructor(native_context()->array_function(), - isolate()); - Handle<JSObject> array_prototype( - JSObject::cast(array_constructor->instance_prototype()), isolate()); - - // Add initial map. - Handle<Map> initial_map = factory()->NewMap( - JS_ARRAY_TYPE, JSRegExpResult::kSize, TERMINAL_FAST_ELEMENTS_KIND, - JSRegExpResult::kInObjectPropertyCount); - initial_map->SetConstructor(*array_constructor); - - // Set prototype on map. - initial_map->set_has_non_instance_prototype(false); - Map::SetPrototype(isolate(), initial_map, array_prototype); - - // Update map with length accessor from Array and add "index", "input" and - // "groups". - Map::EnsureDescriptorSlack(isolate(), initial_map, - JSRegExpResult::kInObjectPropertyCount + 1); - - // length descriptor. - { - JSFunction array_function = native_context()->array_function(); - Handle<DescriptorArray> array_descriptors( - array_function.initial_map().instance_descriptors(), isolate()); - Handle<String> length = factory()->length_string(); - int old = array_descriptors->SearchWithCache( - isolate(), *length, array_function.initial_map()); - DCHECK_NE(old, DescriptorArray::kNotFound); - Descriptor d = Descriptor::AccessorConstant( - length, handle(array_descriptors->GetStrongValue(old), isolate()), - array_descriptors->GetDetails(old).attributes()); - initial_map->AppendDescriptor(isolate(), &d); - } + // Add additional slack to the initial map in case regexp_match_indices + // are enabled to account for the additional descriptor. + Handle<Map> initial_map = CreateInitialMapForArraySubclass( + JSRegExpResult::kSize, JSRegExpResult::kInObjectPropertyCount); // index descriptor. { @@ -4961,9 +4959,53 @@ bool Genesis::InstallNatives() { initial_map->AppendDescriptor(isolate(), &d); } + // Private internal only fields. All of the remaining fields have special + // symbols to prevent their use in Javascript. + // cached_indices_or_match_info descriptor. + { + PropertyAttributes attribs = DONT_ENUM; + { + Descriptor d = Descriptor::DataField( + isolate(), + factory()->regexp_result_cached_indices_or_match_info_symbol(), + JSRegExpResult::kCachedIndicesOrMatchInfoIndex, attribs, + Representation::Tagged()); + initial_map->AppendDescriptor(isolate(), &d); + } + + // names descriptor. + { + Descriptor d = Descriptor::DataField( + isolate(), factory()->regexp_result_names_symbol(), + JSRegExpResult::kNamesIndex, attribs, Representation::Tagged()); + initial_map->AppendDescriptor(isolate(), &d); + } + } + native_context()->set_regexp_result_map(*initial_map); } + // Create a constructor for JSRegExpResultIndices (a variant of Array that + // predefines the groups property). + { + // JSRegExpResultIndices initial map. + Handle<Map> initial_map = CreateInitialMapForArraySubclass( + JSRegExpResultIndices::kSize, + JSRegExpResultIndices::kInObjectPropertyCount); + + // groups descriptor. + { + Descriptor d = Descriptor::DataField( + isolate(), factory()->groups_string(), + JSRegExpResultIndices::kGroupsIndex, NONE, Representation::Tagged()); + initial_map->AppendDescriptor(isolate(), &d); + DCHECK_EQ(initial_map->LastAdded().as_int(), + JSRegExpResultIndices::kGroupsDescriptorIndex); + } + + native_context()->set_regexp_result_indices_map(*initial_map); + } + // Add @@iterator method to the arguments object maps. { PropertyAttributes attribs = DONT_ENUM; @@ -5263,7 +5305,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from, if (from->HasFastProperties()) { Handle<DescriptorArray> descs = Handle<DescriptorArray>(from->map().instance_descriptors(), isolate()); - for (int i = 0; i < from->map().NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : from->map().IterateOwnDescriptors()) { PropertyDetails details = descs->GetDetails(i); if (details.location() == kField) { if (details.kind() == kData) { @@ -5365,6 +5407,45 @@ void Genesis::TransferObject(Handle<JSObject> from, Handle<JSObject> to) { JSObject::ForceSetPrototype(to, proto); } +Handle<Map> Genesis::CreateInitialMapForArraySubclass(int size, + int inobject_properties) { + // Find global.Array.prototype to inherit from. + Handle<JSFunction> array_constructor(native_context()->array_function(), + isolate()); + Handle<JSObject> array_prototype(native_context()->initial_array_prototype(), + isolate()); + + // Add initial map. + Handle<Map> initial_map = factory()->NewMap( + JS_ARRAY_TYPE, size, TERMINAL_FAST_ELEMENTS_KIND, inobject_properties); + initial_map->SetConstructor(*array_constructor); + + // Set prototype on map. + initial_map->set_has_non_instance_prototype(false); + Map::SetPrototype(isolate(), initial_map, array_prototype); + + // Update map with length accessor from Array. + static constexpr int kTheLengthAccessor = 1; + Map::EnsureDescriptorSlack(isolate(), initial_map, + inobject_properties + kTheLengthAccessor); + + // length descriptor. + { + JSFunction array_function = native_context()->array_function(); + Handle<DescriptorArray> array_descriptors( + array_function.initial_map().instance_descriptors(), isolate()); + Handle<String> length = factory()->length_string(); + InternalIndex old = array_descriptors->SearchWithCache( + isolate(), *length, array_function.initial_map()); + DCHECK(old.is_found()); + Descriptor d = Descriptor::AccessorConstant( + length, handle(array_descriptors->GetStrongValue(old), isolate()), + array_descriptors->GetDetails(old).attributes()); + initial_map->AppendDescriptor(isolate(), &d); + } + return initial_map; +} + Genesis::Genesis( Isolate* isolate, MaybeHandle<JSGlobalProxy> maybe_global_proxy, v8::Local<v8::ObjectTemplate> global_proxy_template, diff --git a/deps/v8/src/init/heap-symbols.h b/deps/v8/src/init/heap-symbols.h index ce5a4f1a8b2d1b..9d630f547bd1b8 100644 --- a/deps/v8/src/init/heap-symbols.h +++ b/deps/v8/src/init/heap-symbols.h @@ -82,6 +82,7 @@ V(_, plusSign_string, "plusSign") \ V(_, quarter_string, "quarter") \ V(_, region_string, "region") \ + V(_, relatedYear_string, "relatedYear") \ V(_, scientific_string, "scientific") \ V(_, second_string, "second") \ V(_, segment_string, "segment") \ @@ -107,7 +108,8 @@ V(_, unit_string, "unit") \ V(_, unitDisplay_string, "unitDisplay") \ V(_, weekday_string, "weekday") \ - V(_, year_string, "year") + V(_, year_string, "year") \ + V(_, yearName_string, "yearName") #else // V8_INTL_SUPPORT #define INTERNALIZED_STRING_LIST_GENERATOR_INTL(V, _) #endif // V8_INTL_SUPPORT @@ -202,6 +204,7 @@ V(_, illegal_access_string, "illegal access") \ V(_, illegal_argument_string, "illegal argument") \ V(_, index_string, "index") \ + V(_, indices_string, "indices") \ V(_, Infinity_string, "Infinity") \ V(_, infinity_string, "infinity") \ V(_, input_string, "input") \ @@ -209,6 +212,8 @@ V(_, Int32Array_string, "Int32Array") \ V(_, Int8Array_string, "Int8Array") \ V(_, isExtensible_string, "isExtensible") \ + V(_, jsMemoryEstimate_string, "jsMemoryEstimate") \ + V(_, jsMemoryRange_string, "jsMemoryRange") \ V(_, keys_string, "keys") \ V(_, lastIndex_string, "lastIndex") \ V(_, length_string, "length") \ @@ -299,6 +304,7 @@ V(_, toJSON_string, "toJSON") \ V(_, toString_string, "toString") \ V(_, true_string, "true") \ + V(_, total_string, "total") \ V(_, TypeError_string, "TypeError") \ V(_, Uint16Array_string, "Uint16Array") \ V(_, Uint32Array_string, "Uint32Array") \ @@ -318,35 +324,36 @@ V(_, writable_string, "writable") \ V(_, zero_string, "0") -#define PRIVATE_SYMBOL_LIST_GENERATOR(V, _) \ - V(_, call_site_frame_array_symbol) \ - V(_, call_site_frame_index_symbol) \ - V(_, console_context_id_symbol) \ - V(_, console_context_name_symbol) \ - V(_, class_fields_symbol) \ - V(_, class_positions_symbol) \ - V(_, detailed_stack_trace_symbol) \ - V(_, elements_transition_symbol) \ - V(_, error_end_pos_symbol) \ - V(_, error_script_symbol) \ - V(_, error_start_pos_symbol) \ - V(_, frozen_symbol) \ - V(_, generic_symbol) \ - V(_, home_object_symbol) \ - V(_, interpreter_trampoline_symbol) \ - V(_, megamorphic_symbol) \ - V(_, native_context_index_symbol) \ - V(_, nonextensible_symbol) \ - V(_, not_mapped_symbol) \ - V(_, premonomorphic_symbol) \ - V(_, promise_debug_marker_symbol) \ - V(_, promise_forwarding_handler_symbol) \ - V(_, promise_handled_by_symbol) \ - V(_, sealed_symbol) \ - V(_, stack_trace_symbol) \ - V(_, strict_function_transition_symbol) \ - V(_, wasm_exception_tag_symbol) \ - V(_, wasm_exception_values_symbol) \ +#define PRIVATE_SYMBOL_LIST_GENERATOR(V, _) \ + V(_, call_site_frame_array_symbol) \ + V(_, call_site_frame_index_symbol) \ + V(_, console_context_id_symbol) \ + V(_, console_context_name_symbol) \ + V(_, class_fields_symbol) \ + V(_, class_positions_symbol) \ + V(_, detailed_stack_trace_symbol) \ + V(_, elements_transition_symbol) \ + V(_, error_end_pos_symbol) \ + V(_, error_script_symbol) \ + V(_, error_start_pos_symbol) \ + V(_, frozen_symbol) \ + V(_, generic_symbol) \ + V(_, home_object_symbol) \ + V(_, interpreter_trampoline_symbol) \ + V(_, megamorphic_symbol) \ + V(_, native_context_index_symbol) \ + V(_, nonextensible_symbol) \ + V(_, not_mapped_symbol) \ + V(_, promise_debug_marker_symbol) \ + V(_, promise_forwarding_handler_symbol) \ + V(_, promise_handled_by_symbol) \ + V(_, regexp_result_cached_indices_or_match_info_symbol) \ + V(_, regexp_result_names_symbol) \ + V(_, sealed_symbol) \ + V(_, stack_trace_symbol) \ + V(_, strict_function_transition_symbol) \ + V(_, wasm_exception_tag_symbol) \ + V(_, wasm_exception_values_symbol) \ V(_, uninitialized_symbol) #define PUBLIC_SYMBOL_LIST_GENERATOR(V, _) \ diff --git a/deps/v8/src/init/icu_util.cc b/deps/v8/src/init/icu_util.cc index 81c66e6a20f2d2..22ea3837cdee7f 100644 --- a/deps/v8/src/init/icu_util.cc +++ b/deps/v8/src/init/icu_util.cc @@ -40,26 +40,23 @@ bool InitializeICUDefaultLocation(const char* exec_path, const char* icu_data_file) { #if !defined(V8_INTL_SUPPORT) return true; -#else -#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE +#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE if (icu_data_file) { return InitializeICU(icu_data_file); } - char* icu_data_file_default; #if defined(V8_TARGET_LITTLE_ENDIAN) - base::RelativePath(&icu_data_file_default, exec_path, "icudtl.dat"); + std::unique_ptr<char[]> icu_data_file_default = + base::RelativePath(exec_path, "icudtl.dat"); #elif defined(V8_TARGET_BIG_ENDIAN) - base::RelativePath(&icu_data_file_default, exec_path, "icudtb.dat"); + std::unique_ptr<char[]> icu_data_file_default = + base::RelativePath(exec_path, "icudtb.dat"); #else #error Unknown byte ordering #endif - bool result = InitializeICU(icu_data_file_default); - free(icu_data_file_default); - return result; + return InitializeICU(icu_data_file_default.get()); #else return InitializeICU(nullptr); #endif -#endif } bool InitializeICU(const char* icu_data_file) { diff --git a/deps/v8/src/init/isolate-allocator.cc b/deps/v8/src/init/isolate-allocator.cc index 6a9b4c33cdad0f..b9ec6c3f43b6ef 100644 --- a/deps/v8/src/init/isolate-allocator.cc +++ b/deps/v8/src/init/isolate-allocator.cc @@ -6,6 +6,7 @@ #include "src/base/bounded-page-allocator.h" #include "src/common/ptr-compr.h" #include "src/execution/isolate.h" +#include "src/utils/memcopy.h" #include "src/utils/utils.h" namespace v8 { @@ -38,21 +39,39 @@ IsolateAllocator::~IsolateAllocator() { } #if V8_TARGET_ARCH_64_BIT + +namespace { + +// "IsolateRootBiasPage" is an optional region before the 4Gb aligned +// reservation. This "IsolateRootBiasPage" page is supposed to be used for +// storing part of the Isolate object when Isolate::isolate_root_bias() is +// not zero. +inline size_t GetIsolateRootBiasPageSize( + v8::PageAllocator* platform_page_allocator) { + return RoundUp(Isolate::isolate_root_bias(), + platform_page_allocator->AllocatePageSize()); +} + +} // namespace + Address IsolateAllocator::InitReservation() { v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator(); - // Reserve a 4Gb region so that the middle is 4Gb aligned. - // The VirtualMemory API does not support such an constraint so we have to - // implement it manually here. - size_t reservation_size = kPtrComprHeapReservationSize; - size_t base_alignment = kPtrComprIsolateRootAlignment; + const size_t kIsolateRootBiasPageSize = + GetIsolateRootBiasPageSize(platform_page_allocator); + + // Reserve a |4Gb + kIsolateRootBiasPageSize| region such as that the + // resevation address plus |kIsolateRootBiasPageSize| is 4Gb aligned. + const size_t reservation_size = + kPtrComprHeapReservationSize + kIsolateRootBiasPageSize; + const size_t base_alignment = kPtrComprIsolateRootAlignment; const int kMaxAttempts = 4; for (int attempt = 0; attempt < kMaxAttempts; ++attempt) { Address hint = RoundDown(reinterpret_cast<Address>( platform_page_allocator->GetRandomMmapAddr()), - base_alignment) + - kPtrComprIsolateRootBias; + base_alignment) - + kIsolateRootBiasPageSize; // Within this reservation there will be a sub-region with proper alignment. VirtualMemory padded_reservation(platform_page_allocator, @@ -60,12 +79,11 @@ Address IsolateAllocator::InitReservation() { reinterpret_cast<void*>(hint)); if (!padded_reservation.IsReserved()) break; - // Find such a sub-region inside the reservation that it's middle is - // |base_alignment|-aligned. + // Find properly aligned sub-region inside the reservation. Address address = - RoundUp(padded_reservation.address() + kPtrComprIsolateRootBias, + RoundUp(padded_reservation.address() + kIsolateRootBiasPageSize, base_alignment) - - kPtrComprIsolateRootBias; + kIsolateRootBiasPageSize; CHECK(padded_reservation.InVM(address, reservation_size)); #if defined(V8_OS_FUCHSIA) @@ -98,16 +116,16 @@ Address IsolateAllocator::InitReservation() { if (!reservation.IsReserved()) break; // The reservation could still be somewhere else but we can accept it - // if the reservation has the required alignment. - Address aligned_address = - RoundUp(reservation.address() + kPtrComprIsolateRootBias, + // if it has the required alignment. + Address address = + RoundUp(reservation.address() + kIsolateRootBiasPageSize, base_alignment) - - kPtrComprIsolateRootBias; + kIsolateRootBiasPageSize; - if (reservation.address() == aligned_address) { + if (reservation.address() == address) { reservation_ = std::move(reservation); CHECK_EQ(reservation_.size(), reservation_size); - return aligned_address; + return address; } } } @@ -116,21 +134,26 @@ Address IsolateAllocator::InitReservation() { return kNullAddress; } -void IsolateAllocator::CommitPagesForIsolate(Address heap_address) { - CHECK(reservation_.InVM(heap_address, kPtrComprHeapReservationSize)); +void IsolateAllocator::CommitPagesForIsolate(Address heap_reservation_address) { + v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator(); + + const size_t kIsolateRootBiasPageSize = + GetIsolateRootBiasPageSize(platform_page_allocator); - Address isolate_root = heap_address + kPtrComprIsolateRootBias; + Address isolate_root = heap_reservation_address + kIsolateRootBiasPageSize; CHECK(IsAligned(isolate_root, kPtrComprIsolateRootAlignment)); - v8::PageAllocator* platform_page_allocator = GetPlatformPageAllocator(); + CHECK(reservation_.InVM( + heap_reservation_address, + kPtrComprHeapReservationSize + kIsolateRootBiasPageSize)); // Simplify BoundedPageAllocator's life by configuring it to use same page // size as the Heap will use (MemoryChunk::kPageSize). size_t page_size = RoundUp(size_t{1} << kPageSizeBits, platform_page_allocator->AllocatePageSize()); - page_allocator_instance_ = base::make_unique<base::BoundedPageAllocator>( - platform_page_allocator, heap_address, kPtrComprHeapReservationSize, + page_allocator_instance_ = std::make_unique<base::BoundedPageAllocator>( + platform_page_allocator, isolate_root, kPtrComprHeapReservationSize, page_size); page_allocator_ = page_allocator_instance_.get(); @@ -139,7 +162,7 @@ void IsolateAllocator::CommitPagesForIsolate(Address heap_address) { // Inform the bounded page allocator about reserved pages. { - Address reserved_region_address = RoundDown(isolate_address, page_size); + Address reserved_region_address = isolate_root; size_t reserved_region_size = RoundUp(isolate_end, page_size) - reserved_region_address; @@ -163,10 +186,8 @@ void IsolateAllocator::CommitPagesForIsolate(Address heap_address) { PageAllocator::kReadWrite)); if (Heap::ShouldZapGarbage()) { - for (Address address = committed_region_address; - address < committed_region_size; address += kSystemPointerSize) { - base::Memory<Address>(address) = static_cast<Address>(kZapValue); - } + MemsetPointer(reinterpret_cast<Address*>(committed_region_address), + kZapValue, committed_region_size / kSystemPointerSize); } } isolate_memory_ = reinterpret_cast<void*>(isolate_address); diff --git a/deps/v8/src/init/isolate-allocator.h b/deps/v8/src/init/isolate-allocator.h index cd0e102d40a2c1..5f8b48ef3a325b 100644 --- a/deps/v8/src/init/isolate-allocator.h +++ b/deps/v8/src/init/isolate-allocator.h @@ -5,6 +5,8 @@ #ifndef V8_INIT_ISOLATE_ALLOCATOR_H_ #define V8_INIT_ISOLATE_ALLOCATOR_H_ +#include <memory> + #include "src/base/bounded-page-allocator.h" #include "src/base/page-allocator.h" #include "src/common/globals.h" @@ -46,7 +48,7 @@ class V8_EXPORT_PRIVATE IsolateAllocator final { private: Address InitReservation(); - void CommitPagesForIsolate(Address heap_address); + void CommitPagesForIsolate(Address heap_reservation_address); // The allocated memory for Isolate instance. void* isolate_memory_ = nullptr; diff --git a/deps/v8/src/init/setup-isolate-deserialize.cc b/deps/v8/src/init/setup-isolate-deserialize.cc index 8a73ff0c8ac9d5..ff0268d3c84f91 100644 --- a/deps/v8/src/init/setup-isolate-deserialize.cc +++ b/deps/v8/src/init/setup-isolate-deserialize.cc @@ -7,7 +7,6 @@ #include "src/base/logging.h" #include "src/execution/isolate.h" #include "src/interpreter/interpreter.h" -#include "src/objects/objects-inl.h" #include "src/utils/ostreams.h" namespace v8 { diff --git a/deps/v8/src/init/startup-data-util.cc b/deps/v8/src/init/startup-data-util.cc index 54d697c591d553..d234c152f884d7 100644 --- a/deps/v8/src/init/startup-data-util.cc +++ b/deps/v8/src/init/startup-data-util.cc @@ -38,6 +38,10 @@ void FreeStartupData() { DeleteStartupData(&g_snapshot); } +// TODO(jgruber): Rename to FreeStartupData once natives support has been +// removed (https://crbug.com/v8/7624). +void FreeStartupDataSnapshotOnly() { DeleteStartupData(&g_snapshot); } + void Load(const char* blob_file, v8::StartupData* startup_data, void (*setter_fn)(v8::StartupData*)) { ClearStartupData(startup_data); @@ -67,7 +71,7 @@ void Load(const char* blob_file, v8::StartupData* startup_data, } void LoadFromFiles(const char* natives_blob, const char* snapshot_blob) { - Load(natives_blob, &g_natives, v8::V8::SetNativesDataBlob); + Load(natives_blob, &g_natives, i::V8::SetNativesBlob); Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob); atexit(&FreeStartupData); @@ -78,19 +82,17 @@ void LoadFromFiles(const char* natives_blob, const char* snapshot_blob) { void InitializeExternalStartupData(const char* directory_path) { #ifdef V8_USE_EXTERNAL_STARTUP_DATA - char* natives; - char* snapshot; const char* snapshot_name = "snapshot_blob.bin"; #ifdef V8_MULTI_SNAPSHOTS if (!FLAG_untrusted_code_mitigations) { snapshot_name = "snapshot_blob_trusted.bin"; } #endif - LoadFromFiles( - base::RelativePath(&natives, directory_path, "natives_blob.bin"), - base::RelativePath(&snapshot, directory_path, snapshot_name)); - free(natives); - free(snapshot); + std::unique_ptr<char[]> natives = + base::RelativePath(directory_path, "natives_blob.bin"); + std::unique_ptr<char[]> snapshot = + base::RelativePath(directory_path, snapshot_name); + LoadFromFiles(natives.get(), snapshot.get()); #endif // V8_USE_EXTERNAL_STARTUP_DATA } @@ -101,5 +103,12 @@ void InitializeExternalStartupData(const char* natives_blob, #endif // V8_USE_EXTERNAL_STARTUP_DATA } +void InitializeExternalStartupDataFromFile(const char* snapshot_blob) { +#ifdef V8_USE_EXTERNAL_STARTUP_DATA + Load(snapshot_blob, &g_snapshot, v8::V8::SetSnapshotDataBlob); + atexit(&FreeStartupDataSnapshotOnly); +#endif // V8_USE_EXTERNAL_STARTUP_DATA +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/init/startup-data-util.h b/deps/v8/src/init/startup-data-util.h index dfa26510abd55a..e4d1e540f7627f 100644 --- a/deps/v8/src/init/startup-data-util.h +++ b/deps/v8/src/init/startup-data-util.h @@ -21,6 +21,7 @@ void InitializeExternalStartupData(const char* directory_path); void InitializeExternalStartupData(const char* natives_blob, const char* snapshot_blob); +void InitializeExternalStartupDataFromFile(const char* snapshot_blob); } // namespace internal } // namespace v8 diff --git a/deps/v8/src/init/v8.cc b/deps/v8/src/init/v8.cc index 15eb929332a85e..fd26c60848e7dd 100644 --- a/deps/v8/src/init/v8.cc +++ b/deps/v8/src/init/v8.cc @@ -90,6 +90,12 @@ void V8::InitializeOncePerProcessImpl() { FLAG_expose_wasm = false; } + if (FLAG_regexp_interpret_all && FLAG_regexp_tier_up) { + // Turning off the tier-up strategy, because the --regexp-interpret-all and + // --regexp-tier-up flags are incompatible. + FLAG_regexp_tier_up = false; + } + // The --jitless and --interpreted-frames-native-stack flags are incompatible // since the latter requires code generation while the former prohibits code // generation. diff --git a/deps/v8/src/inspector/custom-preview.h b/deps/v8/src/inspector/custom-preview.h index 1e8c74a154c499..d7b24adcce3370 100644 --- a/deps/v8/src/inspector/custom-preview.h +++ b/deps/v8/src/inspector/custom-preview.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_CUSTOM_PREVIEW_H_ #define V8_INSPECTOR_CUSTOM_PREVIEW_H_ +#include <memory> + #include "src/inspector/protocol/Protocol.h" #include "src/inspector/protocol/Runtime.h" diff --git a/deps/v8/src/inspector/injected-script.cc b/deps/v8/src/inspector/injected-script.cc index 18a10285dd031a..6afc6486e42ff7 100644 --- a/deps/v8/src/inspector/injected-script.cc +++ b/deps/v8/src/inspector/injected-script.cc @@ -289,7 +289,7 @@ Response InjectedScript::getProperties( int sessionId = m_sessionId; v8::TryCatch tryCatch(isolate); - *properties = v8::base::make_unique<Array<PropertyDescriptor>>(); + *properties = std::make_unique<Array<PropertyDescriptor>>(); std::vector<PropertyMirror> mirrors; PropertyAccumulator accumulator(&mirrors); if (!ValueMirror::getProperties(context, object, ownProperties, @@ -366,10 +366,8 @@ Response InjectedScript::getInternalAndPrivateProperties( internalProperties, std::unique_ptr<protocol::Array<PrivatePropertyDescriptor>>* privateProperties) { - *internalProperties = - v8::base::make_unique<Array<InternalPropertyDescriptor>>(); - *privateProperties = - v8::base::make_unique<Array<PrivatePropertyDescriptor>>(); + *internalProperties = std::make_unique<Array<InternalPropertyDescriptor>>(); + *privateProperties = std::make_unique<Array<PrivatePropertyDescriptor>>(); if (!value->IsObject()) return Response::OK(); @@ -521,7 +519,7 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( if (columnSet.find(property->getName()) == columnSet.end()) continue; columnMap[property->getName()] = property.get(); } - auto filtered = v8::base::make_unique<Array<PropertyPreview>>(); + auto filtered = std::make_unique<Array<PropertyPreview>>(); for (const String16& column : selectedColumns) { if (columnMap.find(column) == columnMap.end()) continue; filtered->push_back(columnMap[column]->clone()); diff --git a/deps/v8/src/inspector/injected-script.h b/deps/v8/src/inspector/injected-script.h index d007e9121ece3b..080769f7121981 100644 --- a/deps/v8/src/inspector/injected-script.h +++ b/deps/v8/src/inspector/injected-script.h @@ -31,6 +31,7 @@ #ifndef V8_INSPECTOR_INJECTED_SCRIPT_H_ #define V8_INSPECTOR_INJECTED_SCRIPT_H_ +#include <memory> #include <unordered_map> #include <unordered_set> diff --git a/deps/v8/src/inspector/inspected-context.cc b/deps/v8/src/inspector/inspected-context.cc index 8098aa5caccdfc..03a799cb5b4874 100644 --- a/deps/v8/src/inspector/inspected-context.cc +++ b/deps/v8/src/inspector/inspected-context.cc @@ -112,7 +112,7 @@ InjectedScript* InspectedContext::getInjectedScript(int sessionId) { InjectedScript* InspectedContext::createInjectedScript(int sessionId) { std::unique_ptr<InjectedScript> injectedScript = - v8::base::make_unique<InjectedScript>(this, sessionId); + std::make_unique<InjectedScript>(this, sessionId); CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end()); m_injectedScripts[sessionId] = std::move(injectedScript); return getInjectedScript(sessionId); diff --git a/deps/v8/src/inspector/inspected-context.h b/deps/v8/src/inspector/inspected-context.h index 4ec52dc1e4f437..68b865de672f8d 100644 --- a/deps/v8/src/inspector/inspected-context.h +++ b/deps/v8/src/inspector/inspected-context.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_INSPECTED_CONTEXT_H_ #define V8_INSPECTOR_INSPECTED_CONTEXT_H_ +#include <memory> #include <unordered_map> #include <unordered_set> diff --git a/deps/v8/src/inspector/remote-object-id.h b/deps/v8/src/inspector/remote-object-id.h index b199032359e88c..5a35c13e58fb9c 100644 --- a/deps/v8/src/inspector/remote-object-id.h +++ b/deps/v8/src/inspector/remote-object-id.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_REMOTE_OBJECT_ID_H_ #define V8_INSPECTOR_REMOTE_OBJECT_ID_H_ +#include <memory> + #include "src/inspector/protocol/Forward.h" namespace v8_inspector { diff --git a/deps/v8/src/inspector/search-util.h b/deps/v8/src/inspector/search-util.h index 3c8a9fe31ca352..5958a404f04ed6 100644 --- a/deps/v8/src/inspector/search-util.h +++ b/deps/v8/src/inspector/search-util.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_SEARCH_UTIL_H_ #define V8_INSPECTOR_SEARCH_UTIL_H_ +#include <memory> + #include "src/inspector/protocol/Debugger.h" #include "src/inspector/string-util.h" diff --git a/deps/v8/src/inspector/string-16.cc b/deps/v8/src/inspector/string-16.cc index 3a91169ac8e962..3adffeddf1c887 100644 --- a/deps/v8/src/inspector/string-16.cc +++ b/deps/v8/src/inspector/string-16.cc @@ -83,6 +83,13 @@ String16 String16::fromInteger(size_t number) { return String16(buffer); } +// static +String16 String16::fromInteger64(int64_t number) { + char buffer[50]; + v8::base::OS::SNPrintF(buffer, arraysize(buffer), "%" PRId64 "", number); + return String16(buffer); +} + // static String16 String16::fromDouble(double number) { char arr[50]; diff --git a/deps/v8/src/inspector/string-16.h b/deps/v8/src/inspector/string-16.h index c1dd5cb92913b4..910a2e49c63c92 100644 --- a/deps/v8/src/inspector/string-16.h +++ b/deps/v8/src/inspector/string-16.h @@ -37,6 +37,7 @@ class String16 { static String16 fromInteger(int); static String16 fromInteger(size_t); + static String16 fromInteger64(int64_t); static String16 fromDouble(double); static String16 fromDouble(double, int precision); diff --git a/deps/v8/src/inspector/string-util.cc b/deps/v8/src/inspector/string-util.cc index 20c8951e2a8c3a..bae5dd91a901d5 100644 --- a/deps/v8/src/inspector/string-util.cc +++ b/deps/v8/src/inspector/string-util.cc @@ -169,15 +169,6 @@ StringBufferImpl::StringBufferImpl(String16& string) { m_string = toStringView(m_owner); } -String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId) { - const size_t kBufferSize = 35; - - char buffer[kBufferSize]; - v8::base::OS::SNPrintF(buffer, kBufferSize, "(%08" PRIX64 "%08" PRIX64 ")", - debuggerId.first, debuggerId.second); - return String16(buffer); -} - String16 stackTraceIdToString(uintptr_t id) { String16Builder builder; builder.appendNumber(static_cast<size_t>(id)); diff --git a/deps/v8/src/inspector/string-util.h b/deps/v8/src/inspector/string-util.h index 513f436136ee79..9b6a8bdd5d76ce 100644 --- a/deps/v8/src/inspector/string-util.h +++ b/deps/v8/src/inspector/string-util.h @@ -101,13 +101,23 @@ class StringUtil { // therefore it's unnecessary to provide an implementation here. class Binary { public: - const uint8_t* data() const { UNIMPLEMENTED(); } - size_t size() const { UNIMPLEMENTED(); } + Binary() = default; + + const uint8_t* data() const { return bytes_->data(); } + size_t size() const { return bytes_->size(); } String toBase64() const { UNIMPLEMENTED(); } static Binary fromBase64(const String& base64, bool* success) { UNIMPLEMENTED(); } - static Binary fromSpan(const uint8_t* data, size_t size) { UNIMPLEMENTED(); } + static Binary fromSpan(const uint8_t* data, size_t size) { + return Binary(std::make_shared<std::vector<uint8_t>>(data, data + size)); + } + + private: + std::shared_ptr<std::vector<uint8_t>> bytes_; + + explicit Binary(std::shared_ptr<std::vector<uint8_t>> bytes) + : bytes_(bytes) {} }; } // namespace protocol @@ -149,7 +159,6 @@ class BinaryStringBuffer : public StringBuffer { DISALLOW_COPY_AND_ASSIGN(BinaryStringBuffer); }; -String16 debuggerIdToString(const std::pair<int64_t, int64_t>& debuggerId); String16 stackTraceIdToString(uintptr_t id); } // namespace v8_inspector diff --git a/deps/v8/src/inspector/v8-console-message.cc b/deps/v8/src/inspector/v8-console-message.cc index 458e4d402795b9..e4c678a272958a 100644 --- a/deps/v8/src/inspector/v8-console-message.cc +++ b/deps/v8/src/inspector/v8-console-message.cc @@ -258,7 +258,7 @@ V8ConsoleMessage::wrapArguments(V8InspectorSessionImpl* session, v8::Local<v8::Context> context = inspectedContext->context(); auto args = - v8::base::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); + std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); v8::Local<v8::Value> value = m_arguments[0]->Get(isolate); if (value->IsObject() && m_type == ConsoleAPIType::kTable && @@ -341,8 +341,8 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, arguments = wrapArguments(session, generatePreview); if (!inspector->hasConsoleMessageStorage(contextGroupId)) return; if (!arguments) { - arguments = v8::base::make_unique< - protocol::Array<protocol::Runtime::RemoteObject>>(); + arguments = + std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>(); if (!m_message.isEmpty()) { std::unique_ptr<protocol::Runtime::RemoteObject> messageArg = protocol::Runtime::RemoteObject::create() diff --git a/deps/v8/src/inspector/v8-console-message.h b/deps/v8/src/inspector/v8-console-message.h index cca5b47265f10b..04bd10ff73fa7c 100644 --- a/deps/v8/src/inspector/v8-console-message.h +++ b/deps/v8/src/inspector/v8-console-message.h @@ -7,7 +7,9 @@ #include <deque> #include <map> +#include <memory> #include <set> + #include "include/v8.h" #include "src/inspector/protocol/Console.h" #include "src/inspector/protocol/Forward.h" diff --git a/deps/v8/src/inspector/v8-console.cc b/deps/v8/src/inspector/v8-console.cc index 0f476f23161b2c..f4d0ffa0550a94 100644 --- a/deps/v8/src/inspector/v8-console.cc +++ b/deps/v8/src/inspector/v8-console.cc @@ -691,7 +691,7 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI( v8::Local<v8::ArrayBuffer> data = v8::ArrayBuffer::New(isolate, sizeof(CommandLineAPIData)); - *static_cast<CommandLineAPIData*>(data->GetContents().Data()) = + *static_cast<CommandLineAPIData*>(data->GetBackingStore()->Data()) = CommandLineAPIData(this, sessionId); createBoundFunctionProperty(context, commandLineAPI, data, "dir", &V8Console::call<&V8Console::Dir>, diff --git a/deps/v8/src/inspector/v8-console.h b/deps/v8/src/inspector/v8-console.h index 03d89ced109155..4d38c51a2a28d6 100644 --- a/deps/v8/src/inspector/v8-console.h +++ b/deps/v8/src/inspector/v8-console.h @@ -106,14 +106,14 @@ class V8Console : public v8::debug::ConsoleDelegate { int)> static void call(const v8::FunctionCallbackInfo<v8::Value>& info) { CommandLineAPIData* data = static_cast<CommandLineAPIData*>( - info.Data().As<v8::ArrayBuffer>()->GetContents().Data()); + info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data()); (data->first->*func)(info, data->second); } template <void (V8Console::*func)(const v8::debug::ConsoleCallArguments&, const v8::debug::ConsoleContext&)> static void call(const v8::FunctionCallbackInfo<v8::Value>& info) { CommandLineAPIData* data = static_cast<CommandLineAPIData*>( - info.Data().As<v8::ArrayBuffer>()->GetContents().Data()); + info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data()); v8::debug::ConsoleCallArguments args(info); (data->first->*func)(args, v8::debug::ConsoleContext()); } diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc index e5458823ea7657..18bf43fbbc80f5 100644 --- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc +++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc @@ -262,7 +262,7 @@ String16 scopeType(v8::debug::ScopeIterator::ScopeType type) { Response buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator, InjectedScript* injectedScript, std::unique_ptr<Array<Scope>>* scopes) { - *scopes = v8::base::make_unique<Array<Scope>>(); + *scopes = std::make_unique<Array<Scope>>(); if (!injectedScript) return Response::OK(); if (iterator->Done()) return Response::OK(); @@ -353,8 +353,8 @@ Response V8DebuggerAgentImpl::enable(Maybe<double> maxScriptsCacheSize, String16* outDebuggerId) { m_maxScriptCacheSize = v8::base::saturated_cast<size_t>( maxScriptsCacheSize.fromMaybe(std::numeric_limits<double>::max())); - *outDebuggerId = debuggerIdToString( - m_debugger->debuggerIdFor(m_session->contextGroupId())); + *outDebuggerId = + m_debugger->debuggerIdFor(m_session->contextGroupId()).toString(); if (enabled()) return Response::OK(); if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) @@ -472,7 +472,7 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl( Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition, String16* outBreakpointId, std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { - *locations = v8::base::make_unique<Array<protocol::Debugger::Location>>(); + *locations = std::make_unique<Array<protocol::Debugger::Location>>(); int specified = (optionalURL.isJust() ? 1 : 0) + (optionalURLRegex.isJust() ? 1 : 0) + @@ -708,8 +708,8 @@ Response V8DebuggerAgentImpl::getPossibleBreakpoints( v8Start, v8End, restrictToFunction.fromMaybe(false), &v8Locations); } - *locations = v8::base::make_unique< - protocol::Array<protocol::Debugger::BreakLocation>>(); + *locations = + std::make_unique<protocol::Array<protocol::Debugger::BreakLocation>>(); for (size_t i = 0; i < v8Locations.size(); ++i) { std::unique_ptr<protocol::Debugger::BreakLocation> breakLocation = protocol::Debugger::BreakLocation::create() @@ -752,17 +752,19 @@ Response V8DebuggerAgentImpl::getStackTrace( std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) { bool isOk = false; int64_t id = inStackTraceId->getId().toInteger64(&isOk); - std::pair<int64_t, int64_t> debuggerId; + if (!isOk) return Response::Error("Invalid stack trace id"); + + V8DebuggerId debuggerId; if (inStackTraceId->hasDebuggerId()) { - debuggerId = - m_debugger->debuggerIdFor(inStackTraceId->getDebuggerId(String16())); + debuggerId = V8DebuggerId(inStackTraceId->getDebuggerId(String16())); } else { debuggerId = m_debugger->debuggerIdFor(m_session->contextGroupId()); } - V8StackTraceId v8StackTraceId(id, debuggerId); - if (!isOk || v8StackTraceId.IsInvalid()) { + if (!debuggerId.isValid()) return Response::Error("Invalid stack trace id"); + + V8StackTraceId v8StackTraceId(id, debuggerId.pair()); + if (v8StackTraceId.IsInvalid()) return Response::Error("Invalid stack trace id"); - } auto stack = m_debugger->stackTraceFor(m_session->contextGroupId(), v8StackTraceId); if (!stack) { @@ -872,11 +874,10 @@ Response V8DebuggerAgentImpl::searchInContent( if (it == m_scripts.end()) return Response::Error("No script for id: " + scriptId); - *results = - v8::base::make_unique<protocol::Array<protocol::Debugger::SearchMatch>>( - searchInTextByLinesImpl(m_session, it->second->source(0), query, - optionalCaseSensitive.fromMaybe(false), - optionalIsRegex.fromMaybe(false))); + *results = std::make_unique<protocol::Array<protocol::Debugger::SearchMatch>>( + searchInTextByLinesImpl(m_session, it->second->source(0), query, + optionalCaseSensitive.fromMaybe(false), + optionalIsRegex.fromMaybe(false))); return Response::OK(); } @@ -961,6 +962,20 @@ Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, return Response::OK(); } +Response V8DebuggerAgentImpl::getWasmBytecode(const String16& scriptId, + protocol::Binary* bytecode) { + if (!enabled()) return Response::Error(kDebuggerNotEnabled); + ScriptsMap::iterator it = m_scripts.find(scriptId); + if (it == m_scripts.end()) + return Response::Error("No script for id: " + scriptId); + v8::MemorySpan<const uint8_t> span; + if (!it->second->wasmBytecode().To(&span)) + return Response::Error("Script with id " + scriptId + + " is not WebAssembly"); + *bytecode = protocol::Binary::fromSpan(span.data(), span.size()); + return Response::OK(); +} + void V8DebuggerAgentImpl::pushBreakDetails( const String16& breakReason, std::unique_ptr<protocol::DictionaryValue> breakAuxData) { @@ -1040,13 +1055,7 @@ Response V8DebuggerAgentImpl::stepOut() { Response V8DebuggerAgentImpl::pauseOnAsyncCall( std::unique_ptr<protocol::Runtime::StackTraceId> inParentStackTraceId) { - bool isOk = false; - int64_t stackTraceId = inParentStackTraceId->getId().toInteger64(&isOk); - if (!isOk) { - return Response::Error("Invalid stack trace id"); - } - m_debugger->pauseOnAsyncCall(m_session->contextGroupId(), stackTraceId, - inParentStackTraceId->getDebuggerId(String16())); + // Deprecated, just return OK. return Response::OK(); } @@ -1270,11 +1279,11 @@ Response V8DebuggerAgentImpl::setBlackboxedRanges( Response V8DebuggerAgentImpl::currentCallFrames( std::unique_ptr<Array<CallFrame>>* result) { if (!isPaused()) { - *result = v8::base::make_unique<Array<CallFrame>>(); + *result = std::make_unique<Array<CallFrame>>(); return Response::OK(); } v8::HandleScope handles(m_isolate); - *result = v8::base::make_unique<Array<CallFrame>>(); + *result = std::make_unique<Array<CallFrame>>(); auto iterator = v8::debug::StackTraceIterator::Create(m_isolate); int frameOrdinal = 0; for (; !iterator->Done(); iterator->Advance(), frameOrdinal++) { @@ -1373,28 +1382,10 @@ V8DebuggerAgentImpl::currentExternalStackTrace() { if (externalParent.IsInvalid()) return nullptr; return protocol::Runtime::StackTraceId::create() .setId(stackTraceIdToString(externalParent.id)) - .setDebuggerId(debuggerIdToString(externalParent.debugger_id)) + .setDebuggerId(V8DebuggerId(externalParent.debugger_id).toString()) .build(); } -std::unique_ptr<protocol::Runtime::StackTraceId> -V8DebuggerAgentImpl::currentScheduledAsyncCall() { - v8_inspector::V8StackTraceId scheduledAsyncCall = - m_debugger->scheduledAsyncCall(); - if (scheduledAsyncCall.IsInvalid()) return nullptr; - std::unique_ptr<protocol::Runtime::StackTraceId> asyncCallStackTrace = - protocol::Runtime::StackTraceId::create() - .setId(stackTraceIdToString(scheduledAsyncCall.id)) - .build(); - // TODO(kozyatinskiy): extract this check to IsLocal function. - if (scheduledAsyncCall.debugger_id.first || - scheduledAsyncCall.debugger_id.second) { - asyncCallStackTrace->setDebuggerId( - debuggerIdToString(scheduledAsyncCall.debugger_id)); - } - return asyncCallStackTrace; -} - bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPausedInContextGroup(m_session->contextGroupId()); } @@ -1602,7 +1593,7 @@ void V8DebuggerAgentImpl::didPause( } } - auto hitBreakpointIds = v8::base::make_unique<Array<String16>>(); + auto hitBreakpointIds = std::make_unique<Array<String16>>(); for (const auto& id : hitBreakpoints) { auto it = m_breakpointsOnScriptRun.find(id); @@ -1655,12 +1646,11 @@ void V8DebuggerAgentImpl::didPause( std::unique_ptr<Array<CallFrame>> protocolCallFrames; Response response = currentCallFrames(&protocolCallFrames); if (!response.isSuccess()) - protocolCallFrames = v8::base::make_unique<Array<CallFrame>>(); + protocolCallFrames = std::make_unique<Array<CallFrame>>(); m_frontend.paused(std::move(protocolCallFrames), breakReason, std::move(breakAuxData), std::move(hitBreakpointIds), - currentAsyncStackTrace(), currentExternalStackTrace(), - currentScheduledAsyncCall()); + currentAsyncStackTrace(), currentExternalStackTrace()); } void V8DebuggerAgentImpl::didContinue() { diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.h b/deps/v8/src/inspector/v8-debugger-agent-impl.h index 0a5a169907c145..e6b35b845a90bf 100644 --- a/deps/v8/src/inspector/v8-debugger-agent-impl.h +++ b/deps/v8/src/inspector/v8-debugger-agent-impl.h @@ -6,6 +6,7 @@ #define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_ #include <deque> +#include <memory> #include <unordered_map> #include <vector> @@ -94,6 +95,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) override; Response getScriptSource(const String16& scriptId, String16* scriptSource) override; + Response getWasmBytecode(const String16& scriptId, + protocol::Binary* bytecode) override; Response pause() override; Response resume() override; Response stepOver() override; @@ -165,7 +168,6 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*); std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace(); std::unique_ptr<protocol::Runtime::StackTraceId> currentExternalStackTrace(); - std::unique_ptr<protocol::Runtime::StackTraceId> currentScheduledAsyncCall(); void setPauseOnExceptionsImpl(int); diff --git a/deps/v8/src/inspector/v8-debugger-script.cc b/deps/v8/src/inspector/v8-debugger-script.cc index b83eafc96a9ec9..99511fc144e8bc 100644 --- a/deps/v8/src/inspector/v8-debugger-script.cc +++ b/deps/v8/src/inspector/v8-debugger-script.cc @@ -141,6 +141,12 @@ class ActualScript : public V8DebuggerScript { static_cast<int>(pos), static_cast<int>(substringLength)); return String16(buffer.get(), substringLength); } + v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const override { + v8::HandleScope scope(m_isolate); + auto script = this->script(); + if (!script->IsWasm()) return v8::Nothing<v8::MemorySpan<const uint8_t>>(); + return v8::Just(v8::debug::WasmScript::Cast(*script)->Bytecode()); + } int startLine() const override { return m_startLine; } int startColumn() const override { return m_startColumn; } int endLine() const override { return m_endLine; } @@ -281,9 +287,8 @@ class ActualScript : public V8DebuggerScript { m_startLine = script->LineOffset(); m_startColumn = script->ColumnOffset(); std::vector<int> lineEnds = script->LineEnds(); - CHECK(lineEnds.size()); - int source_length = lineEnds[lineEnds.size() - 1]; if (lineEnds.size()) { + int source_length = lineEnds[lineEnds.size() - 1]; m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1; if (lineEnds.size() > 1) { m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; @@ -356,6 +361,9 @@ class WasmVirtualScript : public V8DebuggerScript { return m_wasmTranslation->GetSource(m_id, m_functionIndex) .substring(pos, len); } + v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const override { + return v8::Nothing<v8::MemorySpan<const uint8_t>>(); + } int startLine() const override { return m_wasmTranslation->GetStartLine(m_id, m_functionIndex); } @@ -462,17 +470,17 @@ class WasmVirtualScript : public V8DebuggerScript { std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj, bool isLiveEdit, V8DebuggerAgentImpl* agent, V8InspectorClient* client) { - return v8::base::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit, - agent, client); + return std::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit, agent, + client); } std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( v8::Isolate* isolate, WasmTranslation* wasmTranslation, v8::Local<v8::debug::WasmScript> underlyingScript, String16 id, String16 url, int functionIndex) { - return v8::base::make_unique<WasmVirtualScript>( - isolate, wasmTranslation, underlyingScript, std::move(id), std::move(url), - functionIndex); + return std::make_unique<WasmVirtualScript>(isolate, wasmTranslation, + underlyingScript, std::move(id), + std::move(url), functionIndex); } V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, diff --git a/deps/v8/src/inspector/v8-debugger-script.h b/deps/v8/src/inspector/v8-debugger-script.h index 547bb0a2ccb5ce..b53d2c15aa80ab 100644 --- a/deps/v8/src/inspector/v8-debugger-script.h +++ b/deps/v8/src/inspector/v8-debugger-script.h @@ -30,6 +30,8 @@ #ifndef V8_INSPECTOR_V8_DEBUGGER_SCRIPT_H_ #define V8_INSPECTOR_V8_DEBUGGER_SCRIPT_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/string-16.h" #include "src/inspector/string-util.h" @@ -61,6 +63,7 @@ class V8DebuggerScript { virtual const String16& sourceMappingURL() const = 0; virtual String16 source(size_t pos, size_t len = UINT_MAX) const = 0; + virtual v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const = 0; virtual const String16& hash() const = 0; virtual int startLine() const = 0; virtual int startColumn() const = 0; diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc index 5ddc375a80c6be..bd127b2c1ce818 100644 --- a/deps/v8/src/inspector/v8-debugger.cc +++ b/deps/v8/src/inspector/v8-debugger.cc @@ -64,6 +64,42 @@ class MatchPrototypePredicate : public v8::debug::QueryObjectPredicate { } // namespace +V8DebuggerId::V8DebuggerId(std::pair<int64_t, int64_t> pair) + : m_first(pair.first), m_second(pair.second) {} + +// static +V8DebuggerId V8DebuggerId::generate(v8::Isolate* isolate) { + V8DebuggerId debuggerId; + debuggerId.m_first = v8::debug::GetNextRandomInt64(isolate); + debuggerId.m_second = v8::debug::GetNextRandomInt64(isolate); + if (!debuggerId.m_first && !debuggerId.m_second) ++debuggerId.m_first; + return debuggerId; +} + +V8DebuggerId::V8DebuggerId(const String16& debuggerId) { + const UChar dot = '.'; + size_t pos = debuggerId.find(dot); + if (pos == String16::kNotFound) return; + bool ok = false; + int64_t first = debuggerId.substring(0, pos).toInteger64(&ok); + if (!ok) return; + int64_t second = debuggerId.substring(pos + 1).toInteger64(&ok); + if (!ok) return; + m_first = first; + m_second = second; +} + +String16 V8DebuggerId::toString() const { + return String16::fromInteger64(m_first) + "." + + String16::fromInteger64(m_second); +} + +bool V8DebuggerId::isValid() const { return m_first || m_second; } + +std::pair<int64_t, int64_t> V8DebuggerId::pair() const { + return std::make_pair(m_first, m_second); +} + V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) : m_isolate(isolate), m_inspector(inspector), @@ -107,7 +143,9 @@ void V8Debugger::disable() { if (--m_enableCount) return; clearContinueToLocation(); m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_wasmTranslation.Clear(); v8::debug::SetDebugDelegate(m_isolate, nullptr); @@ -171,12 +209,19 @@ void V8Debugger::setPauseOnNextCall(bool pause, int targetContextGroupId) { m_targetContextGroupId != targetContextGroupId) { return; } - m_targetContextGroupId = targetContextGroupId; - m_breakRequested = pause; - if (pause) - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - else - v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + if (pause) { + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_pauseOnNextCallRequested = true; + if (!didHaveBreak) { + m_targetContextGroupId = targetContextGroupId; + v8::debug::SetBreakOnNextFunctionCall(m_isolate); + } + } else { + m_pauseOnNextCallRequested = false; + if (!hasScheduledBreakOnNextFunctionCall()) { + v8::debug::ClearBreakOnNextFunctionCall(m_isolate); + } + } } bool V8Debugger::canBreakProgram() { @@ -275,21 +320,12 @@ bool V8Debugger::asyncStepOutOfFunction(int targetContextGroupId, void* parentTask = std::shared_ptr<AsyncStackTrace>(parent)->suspendedTaskId(); if (!parentTask) return false; - pauseOnAsyncCall(targetContextGroupId, - reinterpret_cast<uintptr_t>(parentTask), String16()); + m_targetContextGroupId = targetContextGroupId; + m_taskWithScheduledBreak = parentTask; continueProgram(targetContextGroupId); return true; } -void V8Debugger::pauseOnAsyncCall(int targetContextGroupId, uintptr_t task, - const String16& debuggerId) { - DCHECK(targetContextGroupId); - m_targetContextGroupId = targetContextGroupId; - - m_taskWithScheduledBreak = reinterpret_cast<void*>(task); - m_taskWithScheduledBreakDebuggerId = debuggerId; -} - void V8Debugger::terminateExecution( std::unique_ptr<TerminateExecutionCallback> callback) { if (m_terminateExecutionCallback) { @@ -390,10 +426,11 @@ void V8Debugger::handleProgramBreak( return; } m_targetContextGroupId = 0; - m_breakRequested = false; + m_pauseOnNextCallRequested = false; m_pauseOnAsyncCall = false; m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); + m_externalAsyncTaskPauseRequested = false; + m_taskWithScheduledBreakPauseRequested = false; bool scheduledOOMBreak = m_scheduledOOMBreak; bool scheduledAssertBreak = m_scheduledAssertBreak; @@ -470,31 +507,30 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit, void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited, bool has_compile_error) { + if (m_ignoreScriptParsedEventsCounter != 0) return; + int contextId; if (!script->ContextId().To(&contextId)) return; - if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { - WasmTranslation* wasmTranslation = &m_wasmTranslation; - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&script, &wasmTranslation](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - wasmTranslation->AddScript(script.As<v8::debug::WasmScript>(), - session->debuggerAgent()); - }); - } else if (m_ignoreScriptParsedEventsCounter == 0) { - v8::Isolate* isolate = m_isolate; - V8InspectorClient* client = m_inspector->client(); - m_inspector->forEachSession( - m_inspector->contextGroupId(contextId), - [&isolate, &script, &has_compile_error, &is_live_edited, - &client](V8InspectorSessionImpl* session) { - if (!session->debuggerAgent()->enabled()) return; - session->debuggerAgent()->didParseSource( - V8DebuggerScript::Create(isolate, script, is_live_edited, - session->debuggerAgent(), client), + + v8::Isolate* isolate = m_isolate; + V8InspectorClient* client = m_inspector->client(); + WasmTranslation& wasmTranslation = m_wasmTranslation; + + m_inspector->forEachSession( + m_inspector->contextGroupId(contextId), + [isolate, &script, has_compile_error, is_live_edited, client, + &wasmTranslation](V8InspectorSessionImpl* session) { + auto agent = session->debuggerAgent(); + if (!agent->enabled()) return; + if (script->IsWasm() && script->SourceMappingURL().IsEmpty()) { + wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); + } else { + agent->didParseSource( + V8DebuggerScript::Create(isolate, script, is_live_edited, agent, + client), !has_compile_error); - }); - } + } + }); } void V8Debugger::BreakProgramRequested( @@ -540,15 +576,15 @@ void V8Debugger::AsyncEventOccurred(v8::debug::DebugAsyncActionType type, switch (type) { case v8::debug::kDebugPromiseThen: asyncTaskScheduledForStack("Promise.then", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseCatch: asyncTaskScheduledForStack("Promise.catch", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugPromiseFinally: asyncTaskScheduledForStack("Promise.finally", task, false); - if (!isBlackboxed) asyncTaskCandidateForStepping(task, true); + if (!isBlackboxed) asyncTaskCandidateForStepping(task); break; case v8::debug::kDebugWillHandle: asyncTaskStartedForStack(task); @@ -786,7 +822,7 @@ void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { std::shared_ptr<AsyncStackTrace> V8Debugger::stackTraceFor( int contextGroupId, const V8StackTraceId& id) { - if (debuggerIdFor(contextGroupId) != id.debugger_id) return nullptr; + if (debuggerIdFor(contextGroupId).pair() != id.debugger_id) return nullptr; auto it = m_storedStackTraces.find(id.id); if (it == m_storedStackTraces.end()) return nullptr; return it->second.lock(); @@ -811,9 +847,13 @@ V8StackTraceId V8Debugger::storeCurrentStackTrace( ++m_asyncStacksCount; collectOldAsyncStacksIfNeeded(); - asyncTaskCandidateForStepping(reinterpret_cast<void*>(id), false); - - return V8StackTraceId(id, debuggerIdFor(contextGroupId)); + bool shouldPause = + m_pauseOnAsyncCall && contextGroupId == m_targetContextGroupId; + if (shouldPause) { + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. + } + return V8StackTraceId(id, debuggerIdFor(contextGroupId).pair(), shouldPause); } uintptr_t V8Debugger::storeStackTrace( @@ -829,13 +869,12 @@ void V8Debugger::externalAsyncTaskStarted(const V8StackTraceId& parent) { m_currentAsyncParent.emplace_back(); m_currentTasks.push_back(reinterpret_cast<void*>(parent.id)); - if (m_breakRequested) return; - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() && - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) == parent.id && - m_taskWithScheduledBreakDebuggerId == - debuggerIdToString(parent.debugger_id)) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (!parent.should_pause) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_externalAsyncTaskPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { @@ -845,22 +884,16 @@ void V8Debugger::externalAsyncTaskFinished(const V8StackTraceId& parent) { DCHECK(m_currentTasks.back() == reinterpret_cast<void*>(parent.id)); m_currentTasks.pop_back(); - if (m_taskWithScheduledBreakDebuggerId.isEmpty() || - reinterpret_cast<uintptr_t>(m_taskWithScheduledBreak) != parent.id || - m_taskWithScheduledBreakDebuggerId != - debuggerIdToString(parent.debugger_id)) { - return; - } - m_taskWithScheduledBreak = nullptr; - m_taskWithScheduledBreakDebuggerId = String16(); - if (m_breakRequested) return; + if (!parent.should_pause) return; + m_externalAsyncTaskPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, bool recurring) { asyncTaskScheduledForStack(toString16(taskName), task, recurring); - asyncTaskCandidateForStepping(task, true); + asyncTaskCandidateForStepping(task); } void V8Debugger::asyncTaskCanceled(void* task) { @@ -936,46 +969,36 @@ void V8Debugger::asyncTaskFinishedForStack(void* task) { } } -void V8Debugger::asyncTaskCandidateForStepping(void* task, bool isLocal) { +void V8Debugger::asyncTaskCandidateForStepping(void* task) { if (!m_pauseOnAsyncCall) return; int contextGroupId = currentContextGroupId(); if (contextGroupId != m_targetContextGroupId) return; - if (isLocal) { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), std::make_pair(0, 0)); - } else { - m_scheduledAsyncCall = v8_inspector::V8StackTraceId( - reinterpret_cast<uintptr_t>(task), debuggerIdFor(contextGroupId)); - } - breakProgram(m_targetContextGroupId); - m_scheduledAsyncCall = v8_inspector::V8StackTraceId(); + m_taskWithScheduledBreak = task; + m_pauseOnAsyncCall = false; + v8::debug::ClearStepping(m_isolate); // Cancel step into. } void V8Debugger::asyncTaskStartedForStepping(void* task) { - if (m_breakRequested) return; // TODO(kozyatinskiy): we should search task in async chain to support // blackboxing. - if (m_taskWithScheduledBreakDebuggerId.isEmpty() && - task == m_taskWithScheduledBreak) { - v8::debug::SetBreakOnNextFunctionCall(m_isolate); - } + if (task != m_taskWithScheduledBreak) return; + bool didHaveBreak = hasScheduledBreakOnNextFunctionCall(); + m_taskWithScheduledBreakPauseRequested = true; + if (didHaveBreak) return; + m_targetContextGroupId = currentContextGroupId(); + v8::debug::SetBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskFinishedForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) { - return; - } + if (task != m_taskWithScheduledBreak) return; m_taskWithScheduledBreak = nullptr; - if (m_breakRequested) return; + m_taskWithScheduledBreakPauseRequested = false; + if (hasScheduledBreakOnNextFunctionCall()) return; v8::debug::ClearBreakOnNextFunctionCall(m_isolate); } void V8Debugger::asyncTaskCanceledForStepping(void* task) { - if (!m_taskWithScheduledBreakDebuggerId.isEmpty() || - task != m_taskWithScheduledBreak) - return; - m_taskWithScheduledBreak = nullptr; + asyncTaskFinishedForStepping(task); } void V8Debugger::allAsyncTasksCanceled() { @@ -1058,7 +1081,7 @@ std::shared_ptr<StackFrame> V8Debugger::symbolize( return std::shared_ptr<StackFrame>(it->second); } std::shared_ptr<StackFrame> frame(new StackFrame(isolate(), v8Frame)); - // TODO(clemensh): Figure out a way to do this translation only right before + // TODO(clemensb): Figure out a way to do this translation only right before // sending the stack trace over wire. if (v8Frame->IsWasm()) frame->translate(&m_wasmTranslation); if (m_maxAsyncCallStackDepth) { @@ -1073,27 +1096,15 @@ void V8Debugger::setMaxAsyncTaskStacksForTest(int limit) { m_maxAsyncCallStacks = limit; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor(int contextGroupId) { +V8DebuggerId V8Debugger::debuggerIdFor(int contextGroupId) { auto it = m_contextGroupIdToDebuggerId.find(contextGroupId); if (it != m_contextGroupIdToDebuggerId.end()) return it->second; - std::pair<int64_t, int64_t> debuggerId( - v8::debug::GetNextRandomInt64(m_isolate), - v8::debug::GetNextRandomInt64(m_isolate)); - if (!debuggerId.first && !debuggerId.second) ++debuggerId.first; + V8DebuggerId debuggerId = V8DebuggerId::generate(m_isolate); m_contextGroupIdToDebuggerId.insert( it, std::make_pair(contextGroupId, debuggerId)); - m_serializedDebuggerIdToDebuggerId.insert( - std::make_pair(debuggerIdToString(debuggerId), debuggerId)); return debuggerId; } -std::pair<int64_t, int64_t> V8Debugger::debuggerIdFor( - const String16& serializedDebuggerId) { - auto it = m_serializedDebuggerIdToDebuggerId.find(serializedDebuggerId); - if (it != m_serializedDebuggerIdToDebuggerId.end()) return it->second; - return std::make_pair(0, 0); -} - bool V8Debugger::addInternalObject(v8::Local<v8::Context> context, v8::Local<v8::Object> object, V8InternalValueType type) { @@ -1110,4 +1121,9 @@ void V8Debugger::dumpAsyncTaskStacksStateForTest() { fprintf(stdout, "\n"); } +bool V8Debugger::hasScheduledBreakOnNextFunctionCall() const { + return m_pauseOnNextCallRequested || m_taskWithScheduledBreakPauseRequested || + m_externalAsyncTaskPauseRequested; +} + } // namespace v8_inspector diff --git a/deps/v8/src/inspector/v8-debugger.h b/deps/v8/src/inspector/v8-debugger.h index ba64c4c0326593..a078d14f3d2113 100644 --- a/deps/v8/src/inspector/v8-debugger.h +++ b/deps/v8/src/inspector/v8-debugger.h @@ -6,6 +6,7 @@ #define V8_INSPECTOR_V8_DEBUGGER_H_ #include <list> +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> @@ -36,6 +37,31 @@ using protocol::Response; using TerminateExecutionCallback = protocol::Runtime::Backend::TerminateExecutionCallback; +// This debugger id tries to be unique by generating two random +// numbers, which should most likely avoid collisions. +// Debugger id has a 1:1 mapping to context group. It is used to +// attribute stack traces to a particular debugging, when doing any +// cross-debugger operations (e.g. async step in). +// See also Runtime.UniqueDebuggerId in the protocol. +class V8DebuggerId { + public: + V8DebuggerId() = default; + explicit V8DebuggerId(std::pair<int64_t, int64_t>); + explicit V8DebuggerId(const String16&); + V8DebuggerId(const V8DebuggerId&) V8_NOEXCEPT = default; + ~V8DebuggerId() = default; + + static V8DebuggerId generate(v8::Isolate*); + + String16 toString() const; + bool isValid() const; + std::pair<int64_t, int64_t> pair() const; + + private: + int64_t m_first = 0; + int64_t m_second = 0; +}; + class V8Debugger : public v8::debug::DebugDelegate, public v8::debug::AsyncEventDelegate { public: @@ -59,8 +85,6 @@ class V8Debugger : public v8::debug::DebugDelegate, void stepIntoStatement(int targetContextGroupId, bool breakOnAsyncCall); void stepOverStatement(int targetContextGroupId); void stepOutOfFunction(int targetContextGroupId); - void pauseOnAsyncCall(int targetContextGroupId, uintptr_t task, - const String16& debuggerId); void terminateExecution(std::unique_ptr<TerminateExecutionCallback> callback); @@ -121,13 +145,7 @@ class V8Debugger : public v8::debug::DebugDelegate, void setMaxAsyncTaskStacksForTest(int limit); void dumpAsyncTaskStacksStateForTest(); - v8_inspector::V8StackTraceId scheduledAsyncCall() { - return m_scheduledAsyncCall; - } - - std::pair<int64_t, int64_t> debuggerIdFor(int contextGroupId); - std::pair<int64_t, int64_t> debuggerIdFor( - const String16& serializedDebuggerId); + V8DebuggerId debuggerIdFor(int contextGroupId); std::shared_ptr<AsyncStackTrace> stackTraceFor(int contextGroupId, const V8StackTraceId& id); @@ -173,7 +191,7 @@ class V8Debugger : public v8::debug::DebugDelegate, void asyncTaskStartedForStack(void* task); void asyncTaskFinishedForStack(void* task); - void asyncTaskCandidateForStepping(void* task, bool isLocal); + void asyncTaskCandidateForStepping(void* task); void asyncTaskStartedForStepping(void* task); void asyncTaskFinishedForStepping(void* task); void asyncTaskCanceledForStepping(void* task); @@ -197,6 +215,8 @@ class V8Debugger : public v8::debug::DebugDelegate, int currentContextGroupId(); bool asyncStepOutOfFunction(int targetContextGroupId, bool onlyAtReturn); + bool hasScheduledBreakOnNextFunctionCall() const; + v8::Isolate* m_isolate; V8InspectorImpl* m_inspector; int m_enableCount; @@ -233,23 +253,24 @@ class V8Debugger : public v8::debug::DebugDelegate, std::unordered_map<V8DebuggerAgentImpl*, int> m_maxAsyncCallStackDepthMap; void* m_taskWithScheduledBreak = nullptr; - String16 m_taskWithScheduledBreakDebuggerId; - bool m_breakRequested = false; + // If any of the following three is true, we schedule pause on next JS + // execution using SetBreakOnNextFunctionCall. + bool m_externalAsyncTaskPauseRequested = false; // External async task. + bool m_taskWithScheduledBreakPauseRequested = false; // Local async task. + bool m_pauseOnNextCallRequested = false; // setPauseOnNextCall API call. v8::debug::ExceptionBreakState m_pauseOnExceptionsState; + // Whether we should pause on async call execution (if any) while stepping in. + // See Debugger.stepInto for details. bool m_pauseOnAsyncCall = false; - v8_inspector::V8StackTraceId m_scheduledAsyncCall; using StackTraceIdToStackTrace = std::unordered_map<uintptr_t, std::weak_ptr<AsyncStackTrace>>; StackTraceIdToStackTrace m_storedStackTraces; uintptr_t m_lastStackTraceId = 0; - std::unordered_map<int, std::pair<int64_t, int64_t>> - m_contextGroupIdToDebuggerId; - std::unordered_map<String16, std::pair<int64_t, int64_t>> - m_serializedDebuggerIdToDebuggerId; + std::unordered_map<int, V8DebuggerId> m_contextGroupIdToDebuggerId; std::unique_ptr<TerminateExecutionCallback> m_terminateExecutionCallback; diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc index fcee8a6ef3d652..02aa1ad9feb929 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc @@ -4,7 +4,6 @@ #include "src/inspector/v8-heap-profiler-agent-impl.h" -#include "src/base/template-utils.h" #include "src/inspector/injected-script.h" #include "src/inspector/inspected-context.h" #include "src/inspector/protocol/Protocol.h" @@ -128,7 +127,7 @@ class HeapStatsStream final : public v8::OutputStream { WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* updateData, int count) override { DCHECK_GT(count, 0); - auto statsDiff = v8::base::make_unique<protocol::Array<int>>(); + auto statsDiff = std::make_unique<protocol::Array<int>>(); for (int i = 0; i < count; ++i) { statsDiff->emplace_back(updateData[i].index); statsDiff->emplace_back(updateData[i].count); @@ -337,7 +336,7 @@ namespace { std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfileNode> buildSampingHeapProfileNode(v8::Isolate* isolate, const v8::AllocationProfile::Node* node) { - auto children = v8::base::make_unique< + auto children = std::make_unique< protocol::Array<protocol::HeapProfiler::SamplingHeapProfileNode>>(); for (const auto* child : node->children) children->emplace_back(buildSampingHeapProfileNode(isolate, child)); @@ -384,7 +383,7 @@ Response V8HeapProfilerAgentImpl::getSamplingProfile( if (!v8Profile) return Response::Error("V8 sampling heap profiler was not started."); v8::AllocationProfile::Node* root = v8Profile->GetRootNode(); - auto samples = v8::base::make_unique< + auto samples = std::make_unique< protocol::Array<protocol::HeapProfiler::SamplingHeapProfileSample>>(); for (const auto& sample : v8Profile->GetSamples()) { samples->emplace_back( diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h index 5c2107d57398b5..665e30be945368 100644 --- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h +++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_V8_HEAP_PROFILER_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_HEAP_PROFILER_AGENT_IMPL_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/HeapProfiler.h" diff --git a/deps/v8/src/inspector/v8-inspector-impl.cc b/deps/v8/src/inspector/v8-inspector-impl.cc index b76411807969ed..e91dd7f7f46b1e 100644 --- a/deps/v8/src/inspector/v8-inspector-impl.cc +++ b/deps/v8/src/inspector/v8-inspector-impl.cc @@ -439,7 +439,7 @@ protocol::Response V8InspectorImpl::EvaluateScope::setTimeout(double timeout) { } m_cancelToken.reset(new CancelToken()); v8::debug::GetCurrentPlatform()->CallDelayedOnWorkerThread( - v8::base::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout); + std::make_unique<TerminateTask>(m_isolate, m_cancelToken), timeout); return protocol::Response::OK(); } diff --git a/deps/v8/src/inspector/v8-inspector-impl.h b/deps/v8/src/inspector/v8-inspector-impl.h index 5b89cb092092ad..6276d6d7f6fe96 100644 --- a/deps/v8/src/inspector/v8-inspector-impl.h +++ b/deps/v8/src/inspector/v8-inspector-impl.h @@ -33,6 +33,7 @@ #include <functional> #include <map> +#include <memory> #include <unordered_map> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.h b/deps/v8/src/inspector/v8-inspector-session-impl.h index 7a976bcd40daeb..786dc2a048b512 100644 --- a/deps/v8/src/inspector/v8-inspector-session-impl.h +++ b/deps/v8/src/inspector/v8-inspector-session-impl.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_V8_INSPECTOR_SESSION_IMPL_H_ #define V8_INSPECTOR_V8_INSPECTOR_SESSION_IMPL_H_ +#include <memory> #include <vector> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-profiler-agent-impl.cc index 3b02f7faa1575a..286a18a673cf1d 100644 --- a/deps/v8/src/inspector/v8-profiler-agent-impl.cc +++ b/deps/v8/src/inspector/v8-profiler-agent-impl.cc @@ -44,8 +44,8 @@ std::unique_ptr<protocol::Array<protocol::Profiler::PositionTickInfo>> buildInspectorObjectForPositionTicks(const v8::CpuProfileNode* node) { unsigned lineCount = node->GetHitLineCount(); if (!lineCount) return nullptr; - auto array = v8::base::make_unique< - protocol::Array<protocol::Profiler::PositionTickInfo>>(); + auto array = + std::make_unique<protocol::Array<protocol::Profiler::PositionTickInfo>>(); std::vector<v8::CpuProfileNode::LineTick> entries(lineCount); if (node->GetLineTicks(&entries[0], lineCount)) { for (unsigned i = 0; i < lineCount; i++) { @@ -80,7 +80,7 @@ std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor( const int childrenCount = node->GetChildrenCount(); if (childrenCount) { - auto children = v8::base::make_unique<protocol::Array<int>>(); + auto children = std::make_unique<protocol::Array<int>>(); for (int i = 0; i < childrenCount; i++) children->emplace_back(node->GetChild(i)->GetNodeId()); result->setChildren(std::move(children)); @@ -98,7 +98,7 @@ std::unique_ptr<protocol::Profiler::ProfileNode> buildInspectorObjectFor( std::unique_ptr<protocol::Array<int>> buildInspectorObjectForSamples( v8::CpuProfile* v8profile) { - auto array = v8::base::make_unique<protocol::Array<int>>(); + auto array = std::make_unique<protocol::Array<int>>(); int count = v8profile->GetSamplesCount(); for (int i = 0; i < count; i++) array->emplace_back(v8profile->GetSample(i)->GetNodeId()); @@ -107,7 +107,7 @@ std::unique_ptr<protocol::Array<int>> buildInspectorObjectForSamples( std::unique_ptr<protocol::Array<int>> buildInspectorObjectForTimestamps( v8::CpuProfile* v8profile) { - auto array = v8::base::make_unique<protocol::Array<int>>(); + auto array = std::make_unique<protocol::Array<int>>(); int count = v8profile->GetSamplesCount(); uint64_t lastTime = v8profile->GetStartTime(); for (int i = 0; i < count; i++) { @@ -130,7 +130,7 @@ void flattenNodesTree(V8InspectorImpl* inspector, std::unique_ptr<protocol::Profiler::Profile> createCPUProfile( V8InspectorImpl* inspector, v8::CpuProfile* v8profile) { auto nodes = - v8::base::make_unique<protocol::Array<protocol::Profiler::ProfileNode>>(); + std::make_unique<protocol::Array<protocol::Profiler::ProfileNode>>(); flattenNodesTree(inspector, v8profile->GetTopDownRoot(), nodes.get()); return protocol::Profiler::Profile::create() .setNodes(std::move(nodes)) @@ -338,18 +338,18 @@ Response coverageToProtocol( V8InspectorImpl* inspector, const v8::debug::Coverage& coverage, std::unique_ptr<protocol::Array<protocol::Profiler::ScriptCoverage>>* out_result) { - auto result = v8::base::make_unique< - protocol::Array<protocol::Profiler::ScriptCoverage>>(); + auto result = + std::make_unique<protocol::Array<protocol::Profiler::ScriptCoverage>>(); v8::Isolate* isolate = inspector->isolate(); for (size_t i = 0; i < coverage.ScriptCount(); i++) { v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); v8::Local<v8::debug::Script> script = script_data.GetScript(); - auto functions = v8::base::make_unique< + auto functions = std::make_unique< protocol::Array<protocol::Profiler::FunctionCoverage>>(); for (size_t j = 0; j < script_data.FunctionCount(); j++) { v8::debug::Coverage::FunctionData function_data = script_data.GetFunctionData(j); - auto ranges = v8::base::make_unique< + auto ranges = std::make_unique< protocol::Array<protocol::Profiler::CoverageRange>>(); // Add function range. @@ -418,19 +418,19 @@ namespace { std::unique_ptr<protocol::Array<protocol::Profiler::ScriptTypeProfile>> typeProfileToProtocol(V8InspectorImpl* inspector, const v8::debug::TypeProfile& type_profile) { - auto result = v8::base::make_unique< + auto result = std::make_unique< protocol::Array<protocol::Profiler::ScriptTypeProfile>>(); v8::Isolate* isolate = inspector->isolate(); for (size_t i = 0; i < type_profile.ScriptCount(); i++) { v8::debug::TypeProfile::ScriptData script_data = type_profile.GetScriptData(i); v8::Local<v8::debug::Script> script = script_data.GetScript(); - auto entries = v8::base::make_unique< + auto entries = std::make_unique< protocol::Array<protocol::Profiler::TypeProfileEntry>>(); for (const auto& entry : script_data.Entries()) { - auto types = v8::base::make_unique< - protocol::Array<protocol::Profiler::TypeObject>>(); + auto types = + std::make_unique<protocol::Array<protocol::Profiler::TypeObject>>(); for (const auto& type : entry.Types()) { types->emplace_back( protocol::Profiler::TypeObject::create() diff --git a/deps/v8/src/inspector/v8-profiler-agent-impl.h b/deps/v8/src/inspector/v8-profiler-agent-impl.h index 5370d39eb480ef..832d2ce139f1e7 100644 --- a/deps/v8/src/inspector/v8-profiler-agent-impl.h +++ b/deps/v8/src/inspector/v8-profiler-agent-impl.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_V8_PROFILER_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_PROFILER_AGENT_IMPL_H_ +#include <memory> #include <vector> #include "src/base/macros.h" diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.cc b/deps/v8/src/inspector/v8-runtime-agent-impl.cc index a8aee0b7f36a68..4dfc210edc4432 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.cc +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.cc @@ -235,7 +235,8 @@ void V8RuntimeAgentImpl::evaluate( Maybe<int> executionContextId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture, Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect, - Maybe<double> timeout, std::unique_ptr<EvaluateCallback> callback) { + Maybe<double> timeout, Maybe<bool> disableBreaks, + std::unique_ptr<EvaluateCallback> callback) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript"); int contextId = 0; @@ -272,9 +273,16 @@ void V8RuntimeAgentImpl::evaluate( } v8::MicrotasksScope microtasksScope(m_inspector->isolate(), v8::MicrotasksScope::kRunMicrotasks); + v8::debug::EvaluateGlobalMode mode = + v8::debug::EvaluateGlobalMode::kDefault; + if (throwOnSideEffect.fromMaybe(false)) { + mode = v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect; + } else if (disableBreaks.fromMaybe(false)) { + mode = v8::debug::EvaluateGlobalMode::kDisableBreaks; + } maybeResultValue = v8::debug::EvaluateGlobal( m_inspector->isolate(), toV8String(m_inspector->isolate(), expression), - throwOnSideEffect.fromMaybe(false)); + mode); } // Run microtasks before returning result. // Re-initialize after running client's code, as it could have destroyed @@ -613,7 +621,7 @@ Response V8RuntimeAgentImpl::globalLexicalScopeNames( v8::PersistentValueVector<v8::String> names(m_inspector->isolate()); v8::debug::GlobalLexicalScopeNames(scope.context(), &names); - *outNames = v8::base::make_unique<protocol::Array<String16>>(); + *outNames = std::make_unique<protocol::Array<String16>>(); for (size_t i = 0; i < names.Size(); ++i) { (*outNames)->emplace_back( toProtocolString(m_inspector->isolate(), names.Get(i))); diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.h b/deps/v8/src/inspector/v8-runtime-agent-impl.h index a2002e36609645..7ecbafd611663e 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.h +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.h @@ -31,6 +31,7 @@ #ifndef V8_INSPECTOR_V8_RUNTIME_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_RUNTIME_AGENT_IMPL_H_ +#include <memory> #include <unordered_map> #include "src/base/macros.h" @@ -66,7 +67,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { Maybe<int> executionContextId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture, Maybe<bool> awaitPromise, Maybe<bool> throwOnSideEffect, - Maybe<double> timeout, + Maybe<double> timeout, Maybe<bool> disableBreaks, std::unique_ptr<EvaluateCallback>) override; void awaitPromise(const String16& promiseObjectId, Maybe<bool> returnByValue, Maybe<bool> generatePreview, diff --git a/deps/v8/src/inspector/v8-schema-agent-impl.cc b/deps/v8/src/inspector/v8-schema-agent-impl.cc index 808f59b0bfbc15..ae19416d1f24dd 100644 --- a/deps/v8/src/inspector/v8-schema-agent-impl.cc +++ b/deps/v8/src/inspector/v8-schema-agent-impl.cc @@ -4,7 +4,6 @@ #include "src/inspector/v8-schema-agent-impl.h" -#include "src/base/template-utils.h" #include "src/inspector/protocol/Protocol.h" #include "src/inspector/v8-inspector-session-impl.h" @@ -19,9 +18,9 @@ V8SchemaAgentImpl::~V8SchemaAgentImpl() = default; Response V8SchemaAgentImpl::getDomains( std::unique_ptr<protocol::Array<protocol::Schema::Domain>>* result) { - *result = v8::base::make_unique< - std::vector<std::unique_ptr<protocol::Schema::Domain>>>( - m_session->supportedDomainsImpl()); + *result = + std::make_unique<std::vector<std::unique_ptr<protocol::Schema::Domain>>>( + m_session->supportedDomainsImpl()); return Response::OK(); } diff --git a/deps/v8/src/inspector/v8-schema-agent-impl.h b/deps/v8/src/inspector/v8-schema-agent-impl.h index b96cce1401332d..1251e98bc52814 100644 --- a/deps/v8/src/inspector/v8-schema-agent-impl.h +++ b/deps/v8/src/inspector/v8-schema-agent-impl.h @@ -5,6 +5,8 @@ #ifndef V8_INSPECTOR_V8_SCHEMA_AGENT_IMPL_H_ #define V8_INSPECTOR_V8_SCHEMA_AGENT_IMPL_H_ +#include <memory> + #include "src/base/macros.h" #include "src/inspector/protocol/Forward.h" #include "src/inspector/protocol/Schema.h" diff --git a/deps/v8/src/inspector/v8-stack-trace-impl.cc b/deps/v8/src/inspector/v8-stack-trace-impl.cc index e2be8110696e52..04feca284c57c1 100644 --- a/deps/v8/src/inspector/v8-stack-trace-impl.cc +++ b/deps/v8/src/inspector/v8-stack-trace-impl.cc @@ -6,7 +6,6 @@ #include <algorithm> -#include "src/base/template-utils.h" #include "src/inspector/v8-debugger.h" #include "src/inspector/v8-inspector-impl.h" #include "src/inspector/wasm-translation.h" @@ -17,6 +16,10 @@ int V8StackTraceImpl::maxCallStackSizeToCapture = 200; namespace { +static const char kId[] = "id"; +static const char kDebuggerId[] = "debuggerId"; +static const char kShouldPause[] = "shouldPause"; + static const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast<v8::StackTrace::StackTraceOptions>( v8::StackTrace::kDetailed | @@ -74,7 +77,7 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( } auto inspectorFrames = - v8::base::make_unique<protocol::Array<protocol::Runtime::CallFrame>>(); + std::make_unique<protocol::Array<protocol::Runtime::CallFrame>>(); for (const std::shared_ptr<StackFrame>& frame : frames) { V8InspectorClient* client = nullptr; if (debugger && debugger->inspector()) @@ -102,7 +105,7 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( stackTrace->setParentId( protocol::Runtime::StackTraceId::create() .setId(stackTraceIdToString(externalParent.id)) - .setDebuggerId(debuggerIdToString(externalParent.debugger_id)) + .setDebuggerId(V8DebuggerId(externalParent.debugger_id).toString()) .build()); } return stackTrace; @@ -110,14 +113,47 @@ std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( } // namespace -V8StackTraceId::V8StackTraceId() : id(0), debugger_id(std::make_pair(0, 0)) {} +V8StackTraceId::V8StackTraceId() : id(0), debugger_id(V8DebuggerId().pair()) {} V8StackTraceId::V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id) : id(id), debugger_id(debugger_id) {} +V8StackTraceId::V8StackTraceId(uintptr_t id, + const std::pair<int64_t, int64_t> debugger_id, + bool should_pause) + : id(id), debugger_id(debugger_id), should_pause(should_pause) {} + +V8StackTraceId::V8StackTraceId(const StringView& json) + : id(0), debugger_id(V8DebuggerId().pair()) { + auto dict = + protocol::DictionaryValue::cast(protocol::StringUtil::parseJSON(json)); + if (!dict) return; + String16 s; + if (!dict->getString(kId, &s)) return; + bool isOk = false; + int64_t parsedId = s.toInteger64(&isOk); + if (!isOk || !parsedId) return; + if (!dict->getString(kDebuggerId, &s)) return; + V8DebuggerId debuggerId(s); + if (!debuggerId.isValid()) return; + if (!dict->getBoolean(kShouldPause, &should_pause)) return; + id = parsedId; + debugger_id = debuggerId.pair(); +} + bool V8StackTraceId::IsInvalid() const { return !id; } +std::unique_ptr<StringBuffer> V8StackTraceId::ToString() { + if (IsInvalid()) return nullptr; + auto dict = protocol::DictionaryValue::create(); + dict->setString(kId, String16::fromInteger64(id)); + dict->setString(kDebuggerId, V8DebuggerId(debugger_id).toString()); + dict->setBoolean(kShouldPause, should_pause); + String16 json = dict->toJSONString(); + return StringBufferImpl::adopt(json); +} + StackFrame::StackFrame(v8::Isolate* isolate, v8::Local<v8::StackFrame> v8Frame) : m_functionName(toProtocolString(isolate, v8Frame->GetFunctionName())), m_scriptId(String16::fromInteger(v8Frame->GetScriptId())), diff --git a/deps/v8/src/inspector/value-mirror.cc b/deps/v8/src/inspector/value-mirror.cc index 9edfbc1a212a46..903a5c6b020521 100644 --- a/deps/v8/src/inspector/value-mirror.cc +++ b/deps/v8/src/inspector/value-mirror.cc @@ -372,8 +372,7 @@ class PrimitiveValueMirror final : public ValueMirror { .setType(m_type) .setDescription(descriptionForPrimitiveType(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); if (m_value->IsNull()) (*preview)->setSubtype(RemoteObject::SubtypeEnum::Null); @@ -438,8 +437,7 @@ class NumberMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Number) .setDescription(description(&unserializable)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -496,8 +494,7 @@ class BigIntMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Bigint) .setDescription(descriptionForBigInt(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -656,8 +653,7 @@ class FunctionMirror final : public ValueMirror { .setType(RemoteObject::TypeEnum::Function) .setDescription(descriptionForFunction(context, m_value)) .setOverflow(false) - .setProperties( - v8::base::make_unique<protocol::Array<PropertyPreview>>()) + .setProperties(std::make_unique<protocol::Array<PropertyPreview>>()) .build(); } @@ -939,7 +935,7 @@ class ObjectMirror final : public ValueMirror { v8::Local<v8::Context> context, bool forEntry, bool generatePreviewForTable, int* nameLimit, int* indexLimit, std::unique_ptr<ObjectPreview>* result) const { - auto properties = v8::base::make_unique<protocol::Array<PropertyPreview>>(); + auto properties = std::make_unique<protocol::Array<PropertyPreview>>(); std::unique_ptr<protocol::Array<EntryPreview>> entriesPreview; bool overflow = false; @@ -996,8 +992,7 @@ class ObjectMirror final : public ValueMirror { if (forEntry) { overflow = true; } else { - entriesPreview = - v8::base::make_unique<protocol::Array<EntryPreview>>(); + entriesPreview = std::make_unique<protocol::Array<EntryPreview>>(); for (const auto& entry : entries) { std::unique_ptr<ObjectPreview> valuePreview; entry.value->buildEntryPreview(context, nameLimit, indexLimit, @@ -1545,11 +1540,11 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, const String16& subtype) { // TODO(alph): description and length retrieval should move to embedder. if (subtype == "node") { - return v8::base::make_unique<ObjectMirror>( - value, subtype, descriptionForNode(context, value)); + return std::make_unique<ObjectMirror>(value, subtype, + descriptionForNode(context, value)); } if (subtype == "error") { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Error, descriptionForError(context, value.As<v8::Object>(), ErrorType::kClient)); @@ -1562,14 +1557,14 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, if (object->Get(context, toV8String(isolate, "length")) .ToLocal(&lengthValue)) { if (lengthValue->IsInt32()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Array, descriptionForCollection(isolate, object, lengthValue.As<v8::Int32>()->Value())); } } } - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, descriptionForObject(context->GetIsolate(), value.As<v8::Object>())); } @@ -1577,26 +1572,26 @@ std::unique_ptr<ValueMirror> clientMirror(v8::Local<v8::Context> context, std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, v8::Local<v8::Value> value) { if (value->IsNull()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Object); } if (value->IsBoolean()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Boolean); } if (value->IsNumber()) { - return v8::base::make_unique<NumberMirror>(value.As<v8::Number>()); + return std::make_unique<NumberMirror>(value.As<v8::Number>()); } v8::Isolate* isolate = context->GetIsolate(); if (value->IsString()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::String); } if (value->IsBigInt()) { - return v8::base::make_unique<BigIntMirror>(value.As<v8::BigInt>()); + return std::make_unique<BigIntMirror>(value.As<v8::BigInt>()); } if (value->IsSymbol()) { - return v8::base::make_unique<SymbolMirror>(value.As<v8::Symbol>()); + return std::make_unique<SymbolMirror>(value.As<v8::Symbol>()); } auto clientSubtype = (value->IsUndefined() || value->IsObject()) ? clientFor(context)->valueSubtype(value) @@ -1606,121 +1601,121 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, return clientMirror(context, value, subtype); } if (value->IsUndefined()) { - return v8::base::make_unique<PrimitiveValueMirror>( + return std::make_unique<PrimitiveValueMirror>( value, RemoteObject::TypeEnum::Undefined); } if (value->IsRegExp()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Regexp, descriptionForRegExp(isolate, value.As<v8::RegExp>())); } if (value->IsProxy()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Proxy, "Proxy"); } if (value->IsFunction()) { - return v8::base::make_unique<FunctionMirror>(value); + return std::make_unique<FunctionMirror>(value); } if (value->IsDate()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Date, descriptionForDate(context, value.As<v8::Date>())); } if (value->IsPromise()) { v8::Local<v8::Promise> promise = value.As<v8::Promise>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( promise, RemoteObject::SubtypeEnum::Promise, descriptionForObject(isolate, promise)); } if (value->IsNativeError()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Error, descriptionForError(context, value.As<v8::Object>(), ErrorType::kNative)); } if (value->IsMap()) { v8::Local<v8::Map> map = value.As<v8::Map>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Map, descriptionForCollection(isolate, map, map->Size())); } if (value->IsSet()) { v8::Local<v8::Set> set = value.As<v8::Set>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Set, descriptionForCollection(isolate, set, set->Size())); } if (value->IsWeakMap()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Weakmap, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsWeakSet()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Weakset, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsMapIterator() || value->IsSetIterator()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Iterator, descriptionForObject(isolate, value.As<v8::Object>())); } if (value->IsGeneratorObject()) { v8::Local<v8::Object> object = value.As<v8::Object>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( object, RemoteObject::SubtypeEnum::Generator, descriptionForObject(isolate, object)); } if (value->IsTypedArray()) { v8::Local<v8::TypedArray> array = value.As<v8::TypedArray>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Typedarray, descriptionForCollection(isolate, array, array->Length())); } if (value->IsArrayBuffer()) { v8::Local<v8::ArrayBuffer> buffer = value.As<v8::ArrayBuffer>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Arraybuffer, descriptionForCollection(isolate, buffer, buffer->ByteLength())); } if (value->IsSharedArrayBuffer()) { v8::Local<v8::SharedArrayBuffer> buffer = value.As<v8::SharedArrayBuffer>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Arraybuffer, descriptionForCollection(isolate, buffer, buffer->ByteLength())); } if (value->IsDataView()) { v8::Local<v8::DataView> view = value.As<v8::DataView>(); - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Dataview, descriptionForCollection(isolate, view, view->ByteLength())); } V8InternalValueType internalType = v8InternalValueTypeFrom(context, v8::Local<v8::Object>::Cast(value)); if (value->IsArray() && internalType == V8InternalValueType::kScopeList) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#scopeList", descriptionForScopeList(value.As<v8::Array>())); } if (value->IsObject() && internalType == V8InternalValueType::kEntry) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#entry", descriptionForEntry(context, value.As<v8::Object>())); } if (value->IsObject() && internalType == V8InternalValueType::kScope) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, "internal#scope", descriptionForScope(context, value.As<v8::Object>())); } size_t length = 0; if (value->IsArray() || isArrayLike(context, value, &length)) { length = value->IsArray() ? value.As<v8::Array>()->Length() : length; - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Array, descriptionForCollection(isolate, value.As<v8::Object>(), length)); } if (value->IsObject()) { - return v8::base::make_unique<ObjectMirror>( + return std::make_unique<ObjectMirror>( value, descriptionForObject(isolate, value.As<v8::Object>())); } return nullptr; diff --git a/deps/v8/src/inspector/wasm-translation.cc b/deps/v8/src/inspector/wasm-translation.cc index 4836a6bc4a3d80..5a1526d142b14e 100644 --- a/deps/v8/src/inspector/wasm-translation.cc +++ b/deps/v8/src/inspector/wasm-translation.cc @@ -67,15 +67,20 @@ class WasmTranslation::TranslatorImpl { column(column) {} }; - TranslatorImpl(v8::Isolate* isolate, v8::Local<v8::debug::WasmScript> script) + TranslatorImpl(v8::Isolate* isolate, WasmTranslation* translation, + v8::Local<v8::debug::WasmScript> script) : script_(isolate, script) { script_.AnnotateStrongRetainer(kGlobalScriptHandleLabel); + + ForEachFunction(script, [this, translation](String16& script_id, + int func_idx) { + translation->AddFakeScript(GetFakeScriptId(script_id, func_idx), this); + }); } - void Init(v8::Isolate* isolate, WasmTranslation* translation, - V8DebuggerAgentImpl* agent) { - // Register fake scripts for each function in this wasm module/script. - v8::Local<v8::debug::WasmScript> script = script_.Get(isolate); + template <typename Callback> + void ForEachFunction(v8::Local<v8::debug::WasmScript> script, + Callback callback) { int num_functions = script->NumFunctions(); int num_imported_functions = script->NumImportedFunctions(); DCHECK_LE(0, num_imported_functions); @@ -84,10 +89,18 @@ class WasmTranslation::TranslatorImpl { String16 script_id = String16::fromInteger(script->Id()); for (int func_idx = num_imported_functions; func_idx < num_functions; ++func_idx) { - AddFakeScript(isolate, script_id, func_idx, translation, agent); + callback(script_id, func_idx); } } + void ReportFakeScripts(v8::Isolate* isolate, WasmTranslation* translation, + V8DebuggerAgentImpl* agent) { + ForEachFunction( + script_.Get(isolate), [=](String16& script_id, int func_idx) { + ReportFakeScript(isolate, script_id, func_idx, translation, agent); + }); + } + void Translate(TransLocation* loc) { const OffsetTable& offset_table = GetOffsetTable(loc); DCHECK(!offset_table.empty()); @@ -212,9 +225,10 @@ class WasmTranslation::TranslatorImpl { return GetFakeScriptId(loc->script_id, loc->line); } - void AddFakeScript(v8::Isolate* isolate, const String16& underlyingScriptId, - int func_idx, WasmTranslation* translation, - V8DebuggerAgentImpl* agent) { + void ReportFakeScript(v8::Isolate* isolate, + const String16& underlyingScriptId, int func_idx, + WasmTranslation* translation, + V8DebuggerAgentImpl* agent) { String16 fake_script_id = GetFakeScriptId(underlyingScriptId, func_idx); String16 fake_script_url = GetFakeScriptUrl(isolate, func_idx); @@ -223,7 +237,6 @@ class WasmTranslation::TranslatorImpl { fake_script_id, std::move(fake_script_url), func_idx); - translation->AddFakeScript(fake_script->scriptId(), this); agent->didParseSource(std::move(fake_script), true); } @@ -254,6 +267,9 @@ class WasmTranslation::TranslatorImpl { // We assume to only disassemble a subset of the functions, so store them in a // map instead of an array. std::unordered_map<int, WasmSourceInformation> source_informations_; + + // Disallow copies, because our pointer is registered in translation. + DISALLOW_COPY_AND_ASSIGN(TranslatorImpl); }; constexpr char WasmTranslation::TranslatorImpl::kGlobalScriptHandleLabel[]; @@ -264,15 +280,11 @@ WasmTranslation::~WasmTranslation() { Clear(); } void WasmTranslation::AddScript(v8::Local<v8::debug::WasmScript> script, V8DebuggerAgentImpl* agent) { - std::unique_ptr<TranslatorImpl> impl; - impl.reset(new TranslatorImpl(isolate_, script)); - DCHECK(impl); - auto inserted = - wasm_translators_.insert(std::make_pair(script->Id(), std::move(impl))); - // Check that no mapping for this script id existed before. - DCHECK(inserted.second); - // impl has been moved, use the returned iterator to call Init. - inserted.first->second->Init(isolate_, this, agent); + auto& impl = wasm_translators_[script->Id()]; + if (impl == nullptr) { + impl = std::make_unique<TranslatorImpl>(isolate_, this, script); + } + impl->ReportFakeScripts(isolate_, this, agent); } void WasmTranslation::Clear() { diff --git a/deps/v8/src/inspector/wasm-translation.h b/deps/v8/src/inspector/wasm-translation.h index 2d41822e59a420..a19aa852051c4d 100644 --- a/deps/v8/src/inspector/wasm-translation.h +++ b/deps/v8/src/inspector/wasm-translation.h @@ -5,6 +5,7 @@ #ifndef V8_INSPECTOR_WASM_TRANSLATION_H_ #define V8_INSPECTOR_WASM_TRANSLATION_H_ +#include <memory> #include <unordered_map> #include "include/v8.h" diff --git a/deps/v8/src/interpreter/bytecode-array-accessor.cc b/deps/v8/src/interpreter/bytecode-array-accessor.cc index d460c1a45f7391..0690e16aa9ad01 100644 --- a/deps/v8/src/interpreter/bytecode-array-accessor.cc +++ b/deps/v8/src/interpreter/bytecode-array-accessor.cc @@ -66,7 +66,7 @@ BytecodeArrayAccessor::BytecodeArrayAccessor( BytecodeArrayAccessor::BytecodeArrayAccessor( Handle<BytecodeArray> bytecode_array, int initial_offset) : BytecodeArrayAccessor( - base::make_unique<OnHeapBytecodeArray>(bytecode_array), + std::make_unique<OnHeapBytecodeArray>(bytecode_array), initial_offset) {} void BytecodeArrayAccessor::SetOffset(int offset) { diff --git a/deps/v8/src/interpreter/bytecode-array-accessor.h b/deps/v8/src/interpreter/bytecode-array-accessor.h index 97278af7bd0e05..92d0da66071d4b 100644 --- a/deps/v8/src/interpreter/bytecode-array-accessor.h +++ b/deps/v8/src/interpreter/bytecode-array-accessor.h @@ -5,6 +5,8 @@ #ifndef V8_INTERPRETER_BYTECODE_ARRAY_ACCESSOR_H_ #define V8_INTERPRETER_BYTECODE_ARRAY_ACCESSOR_H_ +#include <memory> + #include "src/base/optional.h" #include "src/common/globals.h" #include "src/handles/handles.h" diff --git a/deps/v8/src/interpreter/bytecode-array-builder.cc b/deps/v8/src/interpreter/bytecode-array-builder.cc index cfc3eb36c15d8e..1c61776cdfa4d3 100644 --- a/deps/v8/src/interpreter/bytecode-array-builder.cc +++ b/deps/v8/src/interpreter/bytecode-array-builder.cc @@ -824,9 +824,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty( return *this; } -BytecodeArrayBuilder& BytecodeArrayBuilder::GetIterator(Register object, - int feedback_slot) { - OutputGetIterator(object, feedback_slot); +BytecodeArrayBuilder& BytecodeArrayBuilder::LoadIteratorProperty( + Register object, int feedback_slot) { + size_t name_index = IteratorSymbolConstantPoolEntry(); + OutputLdaNamedProperty(object, name_index, feedback_slot); + return *this; +} + +BytecodeArrayBuilder& BytecodeArrayBuilder::GetIterator( + Register object, int load_feedback_slot, int call_feedback_slot) { + OutputGetIterator(object, load_feedback_slot, call_feedback_slot); return *this; } diff --git a/deps/v8/src/interpreter/bytecode-array-builder.h b/deps/v8/src/interpreter/bytecode-array-builder.h index 06230f9270d3b8..39cd4fa6f609c8 100644 --- a/deps/v8/src/interpreter/bytecode-array-builder.h +++ b/deps/v8/src/interpreter/bytecode-array-builder.h @@ -135,7 +135,12 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final { BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot); // Named load property of the @@iterator symbol. - BytecodeArrayBuilder& GetIterator(Register object, int feedback_slot); + BytecodeArrayBuilder& LoadIteratorProperty(Register object, + int feedback_slot); + + // Load and call property of the @@iterator symbol + BytecodeArrayBuilder& GetIterator(Register object, int load_feedback_slot, + int call_feedback_slot); // Named load property of the @@asyncIterator symbol. BytecodeArrayBuilder& LoadAsyncIteratorProperty(Register object, diff --git a/deps/v8/src/interpreter/bytecode-array-iterator.h b/deps/v8/src/interpreter/bytecode-array-iterator.h index e6b58deadc4ccf..b992ffc0374487 100644 --- a/deps/v8/src/interpreter/bytecode-array-iterator.h +++ b/deps/v8/src/interpreter/bytecode-array-iterator.h @@ -5,6 +5,8 @@ #ifndef V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_ #define V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_ +#include <memory> + #include "src/interpreter/bytecode-array-accessor.h" namespace v8 { diff --git a/deps/v8/src/interpreter/bytecode-array-random-iterator.h b/deps/v8/src/interpreter/bytecode-array-random-iterator.h index a3b69b7015894a..68905a146cc000 100644 --- a/deps/v8/src/interpreter/bytecode-array-random-iterator.h +++ b/deps/v8/src/interpreter/bytecode-array-random-iterator.h @@ -5,6 +5,8 @@ #ifndef V8_INTERPRETER_BYTECODE_ARRAY_RANDOM_ITERATOR_H_ #define V8_INTERPRETER_BYTECODE_ARRAY_RANDOM_ITERATOR_H_ +#include <memory> + #include "src/interpreter/bytecode-array-accessor.h" #include "src/zone/zone-containers.h" #include "src/zone/zone.h" diff --git a/deps/v8/src/interpreter/bytecode-generator.cc b/deps/v8/src/interpreter/bytecode-generator.cc index 29065d6a55ac2b..92ae15127e4e87 100644 --- a/deps/v8/src/interpreter/bytecode-generator.cc +++ b/deps/v8/src/interpreter/bytecode-generator.cc @@ -2042,7 +2042,71 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) { VisitDeclarations(expr->scope()->declarations()); Register class_constructor = register_allocator()->NewRegister(); + // Create the class brand symbol and store it on the context during class + // evaluation. This will be stored in the instance later in the constructor. + // We do this early so that invalid access to private methods or accessors + // in computed property keys throw. + if (expr->scope()->brand() != nullptr) { + Register brand = register_allocator()->NewRegister(); + const AstRawString* class_name = + expr->scope()->class_variable() != nullptr + ? expr->scope()->class_variable()->raw_name() + : ast_string_constants()->empty_string(); + builder() + ->LoadLiteral(class_name) + .StoreAccumulatorInRegister(brand) + .CallRuntime(Runtime::kCreatePrivateNameSymbol, brand); + BuildVariableAssignment(expr->scope()->brand(), Token::INIT, + HoleCheckMode::kElided); + } + AccessorTable<ClassLiteral::Property> private_accessors(zone()); + for (int i = 0; i < expr->private_members()->length(); i++) { + ClassLiteral::Property* property = expr->private_members()->at(i); + DCHECK(property->is_private()); + switch (property->kind()) { + case ClassLiteral::Property::FIELD: { + // Initialize the private field variables early. + // Create the private name symbols for fields during class + // evaluation and store them on the context. These will be + // used as keys later during instance or static initialization. + RegisterAllocationScope private_name_register_scope(this); + Register private_name = register_allocator()->NewRegister(); + VisitForRegisterValue(property->key(), private_name); + builder() + ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName()) + .StoreAccumulatorInRegister(private_name) + .CallRuntime(Runtime::kCreatePrivateNameSymbol, private_name); + DCHECK_NOT_NULL(property->private_name_var()); + BuildVariableAssignment(property->private_name_var(), Token::INIT, + HoleCheckMode::kElided); + break; + } + case ClassLiteral::Property::METHOD: { + // We can initialize the private methods and accessors later so that the + // home objects can be assigned right after the creation of the + // closures, and those are guarded by the brand checks. + break; + } + // Collect private accessors into a table to merge the creation of + // those closures later. + case ClassLiteral::Property::GETTER: { + Literal* key = property->key()->AsLiteral(); + DCHECK_NULL(private_accessors.LookupOrInsert(key)->getter); + private_accessors.LookupOrInsert(key)->getter = property; + break; + } + case ClassLiteral::Property::SETTER: { + Literal* key = property->key()->AsLiteral(); + DCHECK_NULL(private_accessors.LookupOrInsert(key)->setter); + private_accessors.LookupOrInsert(key)->setter = property; + break; + } + default: + UNREACHABLE(); + } + } + { RegisterAllocationScope register_scope(this); RegisterList args = register_allocator()->NewGrowableRegisterList(); @@ -2065,8 +2129,8 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) { .StoreAccumulatorInRegister(class_boilerplate); // Create computed names and method values nodes to store into the literal. - for (int i = 0; i < expr->properties()->length(); i++) { - ClassLiteral::Property* property = expr->properties()->at(i); + for (int i = 0; i < expr->public_members()->length(); i++) { + ClassLiteral::Property* property = expr->public_members()->at(i); if (property->is_computed_name()) { Register key = register_allocator()->GrowRegisterList(&args); @@ -2099,50 +2163,7 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) { } } - if (property->is_private()) { - // Assign private class member's name variables. - switch (property->kind()) { - case ClassLiteral::Property::FIELD: { - // Create the private name symbols for fields during class - // evaluation and store them on the context. These will be - // used as keys later during instance or static initialization. - RegisterAllocationScope private_name_register_scope(this); - Register private_name = register_allocator()->NewRegister(); - VisitForRegisterValue(property->key(), private_name); - builder() - ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName()) - .StoreAccumulatorInRegister(private_name) - .CallRuntime(Runtime::kCreatePrivateNameSymbol, private_name); - DCHECK_NOT_NULL(property->private_name_var()); - BuildVariableAssignment(property->private_name_var(), Token::INIT, - HoleCheckMode::kElided); - break; - } - case ClassLiteral::Property::METHOD: { - // Create the closures for private methods. - VisitForAccumulatorValue(property->value()); - BuildVariableAssignment(property->private_name_var(), Token::INIT, - HoleCheckMode::kElided); - break; - } - case ClassLiteral::Property::GETTER: { - Literal* key = property->key()->AsLiteral(); - DCHECK_NULL(private_accessors.LookupOrInsert(key)->getter); - private_accessors.LookupOrInsert(key)->getter = property; - break; - } - case ClassLiteral::Property::SETTER: { - Literal* key = property->key()->AsLiteral(); - DCHECK_NULL(private_accessors.LookupOrInsert(key)->setter); - private_accessors.LookupOrInsert(key)->setter = property; - break; - } - } - // The private fields are initialized in the initializer function and - // the private brand for the private methods are initialized in the - // constructor instead. - continue; - } + DCHECK(!property->is_private()); if (property->kind() == ClassLiteral::Property::FIELD) { // We don't compute field's value here, but instead do it in the @@ -2160,60 +2181,55 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr, Register name) { builder()->StoreAccumulatorInRegister(prototype); // Assign to class variable. - if (expr->class_variable() != nullptr) { - DCHECK(expr->class_variable()->IsStackLocal() || - expr->class_variable()->IsContextSlot()); + Variable* class_variable = expr->scope()->class_variable(); + if (class_variable != nullptr && class_variable->is_used()) { + DCHECK(class_variable->IsStackLocal() || class_variable->IsContextSlot()); builder()->LoadAccumulatorWithRegister(class_constructor); - BuildVariableAssignment(expr->class_variable(), Token::INIT, + BuildVariableAssignment(class_variable, Token::INIT, HoleCheckMode::kElided); } - // Create the class brand symbol and store it on the context - // during class evaluation. This will be stored in the - // receiver later in the constructor. - if (expr->scope()->brand() != nullptr) { - Register brand = register_allocator()->NewRegister(); - const AstRawString* class_name = - expr->class_variable() != nullptr - ? expr->class_variable()->raw_name() - : ast_string_constants()->empty_string(); - builder() - ->LoadLiteral(class_name) - .StoreAccumulatorInRegister(brand) - .CallRuntime(Runtime::kCreatePrivateNameSymbol, brand); - BuildVariableAssignment(expr->scope()->brand(), Token::INIT, - HoleCheckMode::kElided); - - // Store the home object for any private methods that need - // them. We do this here once the prototype and brand symbol has - // been created. Private accessors have their home object set later - // when they are defined. - for (int i = 0; i < expr->properties()->length(); i++) { + // Create the closures of private methods, and store the home object for + // any private methods that need them. + if (expr->has_private_methods()) { + for (int i = 0; i < expr->private_members()->length(); i++) { + ClassLiteral::Property* property = expr->private_members()->at(i); + if (property->kind() != ClassLiteral::Property::METHOD) { + continue; + } RegisterAllocationScope register_scope(this); - ClassLiteral::Property* property = expr->properties()->at(i); + VisitForAccumulatorValue(property->value()); + BuildVariableAssignment(property->private_name_var(), Token::INIT, + HoleCheckMode::kElided); + Register home_object = property->private_name_var()->is_static() + ? class_constructor + : prototype; if (property->NeedsHomeObjectOnClassPrototype()) { Register func = register_allocator()->NewRegister(); - BuildVariableLoad(property->private_name_var(), HoleCheckMode::kElided); builder()->StoreAccumulatorInRegister(func); - VisitSetHomeObject(func, prototype, property); + VisitSetHomeObject(func, home_object, property); } } + } - // Define accessors, using only a single call to the runtime for each pair - // of corresponding getters and setters. - for (auto accessors : private_accessors.ordered_accessors()) { - RegisterAllocationScope inner_register_scope(this); - RegisterList accessors_reg = register_allocator()->NewRegisterList(2); - ClassLiteral::Property* getter = accessors.second->getter; - ClassLiteral::Property* setter = accessors.second->setter; - VisitLiteralAccessor(prototype, getter, accessors_reg[0]); - VisitLiteralAccessor(prototype, setter, accessors_reg[1]); - builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg); - Variable* var = getter != nullptr ? getter->private_name_var() - : setter->private_name_var(); - DCHECK_NOT_NULL(var); - BuildVariableAssignment(var, Token::INIT, HoleCheckMode::kElided); - } + // Define private accessors, using only a single call to the runtime for + // each pair of corresponding getters and setters, in the order the first + // component is declared. Store the home objects if necessary. + for (auto accessors : private_accessors.ordered_accessors()) { + RegisterAllocationScope inner_register_scope(this); + RegisterList accessors_reg = register_allocator()->NewRegisterList(2); + ClassLiteral::Property* getter = accessors.second->getter; + ClassLiteral::Property* setter = accessors.second->setter; + bool is_static = + getter != nullptr ? getter->is_static() : setter->is_static(); + Register home_object = is_static ? class_constructor : prototype; + VisitLiteralAccessor(home_object, getter, accessors_reg[0]); + VisitLiteralAccessor(home_object, setter, accessors_reg[1]); + builder()->CallRuntime(Runtime::kCreatePrivateAccessors, accessors_reg); + Variable* var = getter != nullptr ? getter->private_name_var() + : setter->private_name_var(); + DCHECK_NOT_NULL(var); + BuildVariableAssignment(var, Token::INIT, HoleCheckMode::kElided); } if (expr->instance_members_initializer_function() != nullptr) { @@ -3086,7 +3102,8 @@ void BytecodeGenerator::BuildAsyncReturn(int source_position) { .StoreAccumulatorInRegister(args[2]) // done .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args); } else { - DCHECK(IsAsyncFunction(info()->literal()->kind())); + DCHECK(IsAsyncFunction(info()->literal()->kind()) || + IsAsyncModule(info()->literal()->kind())); RegisterList args = register_allocator()->NewRegisterList(3); builder() ->MoveRegister(generator_object(), args[0]) // generator @@ -3921,7 +3938,8 @@ void BytecodeGenerator::BuildAssignment( Property* property = lhs_data.expr()->AsProperty(); Register object = VisitForRegisterValue(property->obj()); Register key = VisitForRegisterValue(property->key()); - BuildPrivateBrandCheck(property, object); + BuildPrivateBrandCheck(property, object, + MessageTemplate::kInvalidPrivateMemberWrite); BuildPrivateSetterAccess(object, key, value); if (!execution_result()->IsEffect()) { builder()->LoadAccumulatorWithRegister(value); @@ -4004,6 +4022,12 @@ void BytecodeGenerator::VisitCompoundAssignment(CompoundAssignment* expr) { // in the accumulator. When the generator is resumed, the sent value is loaded // in the accumulator. void BytecodeGenerator::BuildSuspendPoint(int position) { + // Because we eliminate jump targets in dead code, we also eliminate resumes + // when the suspend is not emitted because otherwise the below call to Bind + // would start a new basic block and the code would be considered alive. + if (builder()->RemainderOfBlockIsDead()) { + return; + } const int suspend_id = suspend_count_++; RegisterList registers = register_allocator()->AllLiveRegisters(); @@ -4454,12 +4478,14 @@ void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) { case PRIVATE_GETTER_ONLY: case PRIVATE_GETTER_AND_SETTER: { Register key = VisitForRegisterValue(property->key()); - BuildPrivateBrandCheck(property, obj); + BuildPrivateBrandCheck(property, obj, + MessageTemplate::kInvalidPrivateMemberRead); BuildPrivateGetterAccess(obj, key); break; } case PRIVATE_METHOD: { - BuildPrivateBrandCheck(property, obj); + BuildPrivateBrandCheck(property, obj, + MessageTemplate::kInvalidPrivateMemberRead); // In the case of private methods, property->key() is the function to be // loaded (stored in a context slot), so load this directly. VisitForAccumulatorValue(property->key()); @@ -4499,15 +4525,29 @@ void BytecodeGenerator::BuildPrivateSetterAccess(Register object, } void BytecodeGenerator::BuildPrivateBrandCheck(Property* property, - Register object) { + Register object, + MessageTemplate tmpl) { Variable* private_name = property->key()->AsVariableProxy()->var(); - DCHECK(private_name->requires_brand_check()); + DCHECK(IsPrivateMethodOrAccessorVariableMode(private_name->mode())); ClassScope* scope = private_name->scope()->AsClassScope(); - Variable* brand = scope->brand(); - BuildVariableLoadForAccumulatorValue(brand, HoleCheckMode::kElided); - builder()->SetExpressionPosition(property); - builder()->LoadKeyedProperty( - object, feedback_index(feedback_spec()->AddKeyedLoadICSlot())); + if (private_name->is_static()) { + DCHECK_NOT_NULL(scope->class_variable()); + // For static private methods, the only valid receiver is the class. + // Load the class constructor. + BuildVariableLoadForAccumulatorValue(scope->class_variable(), + HoleCheckMode::kElided); + BytecodeLabel return_check; + builder()->CompareReference(object).JumpIfTrue( + ToBooleanMode::kAlreadyBoolean, &return_check); + BuildInvalidPropertyAccess(tmpl, property); + builder()->Bind(&return_check); + } else { + BuildVariableLoadForAccumulatorValue(scope->brand(), + HoleCheckMode::kElided); + builder()->SetExpressionPosition(property); + builder()->LoadKeyedProperty( + object, feedback_index(feedback_spec()->AddKeyedLoadICSlot())); + } } void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj, @@ -5113,7 +5153,8 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { case PRIVATE_GETTER_AND_SETTER: { object = VisitForRegisterValue(property->obj()); key = VisitForRegisterValue(property->key()); - BuildPrivateBrandCheck(property, object); + BuildPrivateBrandCheck(property, object, + MessageTemplate::kInvalidPrivateMemberRead); BuildPrivateGetterAccess(object, key); break; } @@ -5407,7 +5448,8 @@ void BytecodeGenerator::BuildGetIterator(IteratorType hint) { // If method is undefined, // Let syncMethod be GetMethod(obj, @@iterator) builder() - ->GetIterator(obj, feedback_index(feedback_spec()->AddLoadICSlot())) + ->LoadIteratorProperty(obj, + feedback_index(feedback_spec()->AddLoadICSlot())) .StoreAccumulatorInRegister(method); // Let syncIterator be Call(syncMethod, obj) @@ -5426,24 +5468,17 @@ void BytecodeGenerator::BuildGetIterator(IteratorType hint) { RegisterAllocationScope scope(this); Register obj = register_allocator()->NewRegister(); - Register method = register_allocator()->NewRegister(); - - // Let method be GetMethod(obj, @@iterator). - builder() - ->StoreAccumulatorInRegister(obj) - .GetIterator(obj, feedback_index(feedback_spec()->AddLoadICSlot())) - .StoreAccumulatorInRegister(method); + int load_feedback_index = + feedback_index(feedback_spec()->AddLoadICSlot()); + int call_feedback_index = + feedback_index(feedback_spec()->AddCallICSlot()); - // Let iterator be Call(method, obj). - builder()->CallProperty(method, RegisterList(obj), - feedback_index(feedback_spec()->AddCallICSlot())); + // Let method be GetMethod(obj, @@iterator) and + // iterator be Call(method, obj). If Type(iterator) is not Object, + // throw a SymbolIteratorInvalid exception. + builder()->StoreAccumulatorInRegister(obj).GetIterator( + obj, load_feedback_index, call_feedback_index); } - - // If Type(iterator) is not Object, throw a TypeError exception. - BytecodeLabel no_type_error; - builder()->JumpIfJSReceiver(&no_type_error); - builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); - builder()->Bind(&no_type_error); } } @@ -6102,8 +6137,9 @@ void BytecodeGenerator::BuildGeneratorObjectVariableInitialization() { RegisterAllocationScope register_scope(this); RegisterList args = register_allocator()->NewRegisterList(2); Runtime::FunctionId function_id = - (IsAsyncFunction(info()->literal()->kind()) && - !IsAsyncGeneratorFunction(info()->literal()->kind())) + ((IsAsyncFunction(info()->literal()->kind()) && + !IsAsyncGeneratorFunction(info()->literal()->kind())) || + IsAsyncModule(info()->literal()->kind())) ? Runtime::kInlineAsyncFunctionEnter : Runtime::kInlineCreateJSGeneratorObject; builder() diff --git a/deps/v8/src/interpreter/bytecode-generator.h b/deps/v8/src/interpreter/bytecode-generator.h index 134b1b463ab11e..ecfe50ba5a486c 100644 --- a/deps/v8/src/interpreter/bytecode-generator.h +++ b/deps/v8/src/interpreter/bytecode-generator.h @@ -250,12 +250,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op); void BuildThrowIfHole(Variable* variable); - // Build jump to targets[value], where - // start_index <= value < start_index + size. - void BuildIndexedJump( - Register value, size_t start_index, size_t size, - ZoneVector<BytecodeLabel>& targets); // NOLINT(runtime/references) - void BuildNewLocalActivationContext(); void BuildLocalActivationContextInitialization(); void BuildNewLocalBlockContext(Scope* scope); @@ -307,10 +301,13 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { void VisitRestArgumentsArray(Variable* rest); void VisitCallSuper(Call* call); void BuildInvalidPropertyAccess(MessageTemplate tmpl, Property* property); - void BuildPrivateBrandCheck(Property* property, Register object); + void BuildPrivateBrandCheck(Property* property, Register object, + MessageTemplate tmpl); void BuildPrivateGetterAccess(Register obj, Register access_pair); void BuildPrivateSetterAccess(Register obj, Register access_pair, Register value); + void BuildPrivateMethods(ClassLiteral* expr, bool is_static, + Register home_object); void BuildClassLiteral(ClassLiteral* expr, Register name); void VisitClassLiteral(ClassLiteral* expr, Register name); void VisitNewTargetVariable(Variable* variable); diff --git a/deps/v8/src/interpreter/bytecodes.cc b/deps/v8/src/interpreter/bytecodes.cc index 60f30ee1d98d46..88e80b961359c0 100644 --- a/deps/v8/src/interpreter/bytecodes.cc +++ b/deps/v8/src/interpreter/bytecodes.cc @@ -217,6 +217,7 @@ bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) { case Bytecode::kCreateBlockContext: case Bytecode::kCreateCatchContext: case Bytecode::kCreateRegExpLiteral: + case Bytecode::kGetIterator: return true; default: return false; diff --git a/deps/v8/src/interpreter/bytecodes.h b/deps/v8/src/interpreter/bytecodes.h index 6802d53c955fbd..80f9e4d311228d 100644 --- a/deps/v8/src/interpreter/bytecodes.h +++ b/deps/v8/src/interpreter/bytecodes.h @@ -356,7 +356,8 @@ namespace interpreter { OperandType::kRegOutList, OperandType::kRegCount) \ \ /* Iterator protocol operations */ \ - V(GetIterator, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kIdx) \ + V(GetIterator, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kIdx, \ + OperandType::kIdx) \ \ /* Debugger */ \ V(Debugger, AccumulatorUse::kNone) \ diff --git a/deps/v8/src/interpreter/constant-array-builder.cc b/deps/v8/src/interpreter/constant-array-builder.cc index 167b0ee7e244ad..0a4bdd62f76497 100644 --- a/deps/v8/src/interpreter/constant-array-builder.cc +++ b/deps/v8/src/interpreter/constant-array-builder.cc @@ -378,7 +378,7 @@ Handle<Object> ConstantArrayBuilder::Entry::ToHandle(Isolate* isolate) const { case Tag::kRawString: return raw_string_->string(); case Tag::kHeapNumber: - return isolate->factory()->NewNumber(heap_number_, AllocationType::kOld); + return isolate->factory()->NewNumber<AllocationType::kOld>(heap_number_); case Tag::kBigInt: // This should never fail: the parser will never create a BigInt // literal that cannot be allocated. diff --git a/deps/v8/src/interpreter/interpreter-assembler.cc b/deps/v8/src/interpreter/interpreter-assembler.cc index f01821b5651f4b..a55e074b3ae214 100644 --- a/deps/v8/src/interpreter/interpreter-assembler.cc +++ b/deps/v8/src/interpreter/interpreter-assembler.cc @@ -22,8 +22,6 @@ namespace interpreter { using compiler::CodeAssemblerState; using compiler::Node; -template <class T> -using TNode = compiler::TNode<T>; InterpreterAssembler::InterpreterAssembler(CodeAssemblerState* state, Bytecode bytecode, @@ -32,19 +30,19 @@ InterpreterAssembler::InterpreterAssembler(CodeAssemblerState* state, bytecode_(bytecode), operand_scale_(operand_scale), TVARIABLE_CONSTRUCTOR(interpreted_frame_pointer_), - VARIABLE_CONSTRUCTOR( - bytecode_array_, MachineRepresentation::kTagged, - Parameter(InterpreterDispatchDescriptor::kBytecodeArray)), + TVARIABLE_CONSTRUCTOR( + bytecode_array_, + CAST(Parameter(InterpreterDispatchDescriptor::kBytecodeArray))), TVARIABLE_CONSTRUCTOR( bytecode_offset_, UncheckedCast<IntPtrT>( Parameter(InterpreterDispatchDescriptor::kBytecodeOffset))), - VARIABLE_CONSTRUCTOR( - dispatch_table_, MachineType::PointerRepresentation(), - Parameter(InterpreterDispatchDescriptor::kDispatchTable)), - VARIABLE_CONSTRUCTOR( - accumulator_, MachineRepresentation::kTagged, - Parameter(InterpreterDispatchDescriptor::kAccumulator)), + TVARIABLE_CONSTRUCTOR( + dispatch_table_, UncheckedCast<ExternalReference>(Parameter( + InterpreterDispatchDescriptor::kDispatchTable))), + TVARIABLE_CONSTRUCTOR( + accumulator_, + CAST(Parameter(InterpreterDispatchDescriptor::kAccumulator))), accumulator_use_(AccumulatorUse::kNone), made_call_(false), reloaded_frame_ptr_(false), @@ -129,27 +127,27 @@ void InterpreterAssembler::SaveBytecodeOffset() { } } -Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { +TNode<BytecodeArray> InterpreterAssembler::BytecodeArrayTaggedPointer() { // Force a re-load of the bytecode array after every call in case the debugger // has been activated. if (!bytecode_array_valid_) { - bytecode_array_.Bind(LoadRegister(Register::bytecode_array())); + bytecode_array_ = CAST(LoadRegister(Register::bytecode_array())); bytecode_array_valid_ = true; } return bytecode_array_.value(); } -Node* InterpreterAssembler::DispatchTableRawPointer() { +TNode<ExternalReference> InterpreterAssembler::DispatchTablePointer() { if (Bytecodes::MakesCallAlongCriticalPath(bytecode_) && made_call_ && (dispatch_table_.value() == Parameter(InterpreterDispatchDescriptor::kDispatchTable))) { - dispatch_table_.Bind(ExternalConstant( - ExternalReference::interpreter_dispatch_table_address(isolate()))); + dispatch_table_ = ExternalConstant( + ExternalReference::interpreter_dispatch_table_address(isolate())); } return dispatch_table_.value(); } -Node* InterpreterAssembler::GetAccumulatorUnchecked() { +TNode<Object> InterpreterAssembler::GetAccumulatorUnchecked() { return accumulator_.value(); } @@ -159,10 +157,11 @@ TNode<Object> InterpreterAssembler::GetAccumulator() { return TaggedPoisonOnSpeculation(GetAccumulatorUnchecked()); } -void InterpreterAssembler::SetAccumulator(Node* value) { +// TODO(v8:6949): Remove sloppy-ness from SetAccumulator's value argument. +void InterpreterAssembler::SetAccumulator(SloppyTNode<Object> value) { DCHECK(Bytecodes::WritesAccumulator(bytecode_)); accumulator_use_ = accumulator_use_ | AccumulatorUse::kWrite; - accumulator_.Bind(value); + accumulator_ = value; } TNode<Context> InterpreterAssembler::GetContext() { @@ -173,15 +172,14 @@ void InterpreterAssembler::SetContext(TNode<Context> value) { StoreRegister(value, Register::current_context()); } -Node* InterpreterAssembler::GetContextAtDepth(TNode<Context> context, - TNode<Uint32T> depth) { +TNode<Context> InterpreterAssembler::GetContextAtDepth(TNode<Context> context, + TNode<Uint32T> depth) { TVARIABLE(Context, cur_context, context); TVARIABLE(Uint32T, cur_depth, depth); Label context_found(this); - Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; - Label context_search(this, 2, context_search_loop_variables); + Label context_search(this, {&cur_depth, &cur_context}); // Fast path if the depth is 0. Branch(Word32Equal(depth, Int32Constant(0)), &context_found, &context_search); @@ -206,33 +204,38 @@ void InterpreterAssembler::GotoIfHasContextExtensionUpToDepth( TVARIABLE(Context, cur_context, context); TVARIABLE(Uint32T, cur_depth, depth); - Variable* context_search_loop_variables[2] = {&cur_depth, &cur_context}; - Label context_search(this, 2, context_search_loop_variables); + Label context_search(this, {&cur_depth, &cur_context}); + Label no_extension(this); // Loop until the depth is 0. Goto(&context_search); BIND(&context_search); { - // TODO(leszeks): We only need to do this check if the context had a sloppy - // eval, we could pass in a context chain bitmask to figure out which - // contexts actually need to be checked. + // Check if context has an extension slot + TNode<BoolT> has_extension = + LoadContextHasExtensionField(cur_context.value()); + GotoIfNot(has_extension, &no_extension); + // Jump to the target if the extension slot is not a hole. TNode<Object> extension_slot = LoadContextElement(cur_context.value(), Context::EXTENSION_INDEX); + Branch(TaggedNotEqual(extension_slot, TheHoleConstant()), target, + &no_extension); - // Jump to the target if the extension slot is not a hole. - GotoIf(TaggedNotEqual(extension_slot, TheHoleConstant()), target); - - cur_depth = Unsigned(Int32Sub(cur_depth.value(), Int32Constant(1))); - cur_context = - CAST(LoadContextElement(cur_context.value(), Context::PREVIOUS_INDEX)); + BIND(&no_extension); + { + cur_depth = Unsigned(Int32Sub(cur_depth.value(), Int32Constant(1))); + cur_context = CAST( + LoadContextElement(cur_context.value(), Context::PREVIOUS_INDEX)); - GotoIf(Word32NotEqual(cur_depth.value(), Int32Constant(0)), - &context_search); + GotoIf(Word32NotEqual(cur_depth.value(), Int32Constant(0)), + &context_search); + } } } -TNode<IntPtrT> InterpreterAssembler::RegisterLocation(Node* reg_index) { +TNode<IntPtrT> InterpreterAssembler::RegisterLocation( + TNode<IntPtrT> reg_index) { return Signed(WordPoisonOnSpeculation( IntPtrAdd(GetInterpretedFramePointer(), RegisterFrameOffset(reg_index)))); } @@ -241,11 +244,11 @@ TNode<IntPtrT> InterpreterAssembler::RegisterLocation(Register reg) { return RegisterLocation(IntPtrConstant(reg.ToOperand())); } -TNode<IntPtrT> InterpreterAssembler::RegisterFrameOffset(Node* index) { - return Signed(TimesSystemPointerSize(index)); +TNode<IntPtrT> InterpreterAssembler::RegisterFrameOffset(TNode<IntPtrT> index) { + return TimesSystemPointerSize(index); } -TNode<Object> InterpreterAssembler::LoadRegister(Node* reg_index) { +TNode<Object> InterpreterAssembler::LoadRegister(TNode<IntPtrT> reg_index) { return LoadFullTagged(GetInterpretedFramePointer(), RegisterFrameOffset(reg_index), LoadSensitivity::kCritical); @@ -281,7 +284,7 @@ std::pair<TNode<Object>, TNode<Object>> InterpreterAssembler::LoadRegisterPairAtOperandIndex(int operand_index) { DCHECK_EQ(OperandType::kRegPair, Bytecodes::GetOperandType(bytecode_, operand_index)); - Node* first_reg_index = + TNode<IntPtrT> first_reg_index = BytecodeOperandReg(operand_index, LoadSensitivity::kSafe); TNode<IntPtrT> second_reg_index = NextRegister(first_reg_index); return std::make_pair(LoadRegister(first_reg_index), @@ -300,7 +303,7 @@ InterpreterAssembler::GetRegisterListAtOperandIndex(int operand_index) { return RegListNodePair(base_reg, reg_count); } -Node* InterpreterAssembler::LoadRegisterFromRegisterList( +TNode<Object> InterpreterAssembler::LoadRegisterFromRegisterList( const RegListNodePair& reg_list, int index) { TNode<IntPtrT> location = RegisterLocationInRegisterList(reg_list, index); // Location is already poisoned on speculation, so no need to poison here. @@ -317,29 +320,30 @@ TNode<IntPtrT> InterpreterAssembler::RegisterLocationInRegisterList( return Signed(IntPtrSub(reg_list.base_reg_location(), offset)); } -void InterpreterAssembler::StoreRegister(Node* value, Register reg) { +void InterpreterAssembler::StoreRegister(TNode<Object> value, Register reg) { StoreFullTaggedNoWriteBarrier( GetInterpretedFramePointer(), IntPtrConstant(reg.ToOperand() * kSystemPointerSize), value); } -void InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { +void InterpreterAssembler::StoreRegister(TNode<Object> value, + TNode<IntPtrT> reg_index) { StoreFullTaggedNoWriteBarrier(GetInterpretedFramePointer(), RegisterFrameOffset(reg_index), value); } -void InterpreterAssembler::StoreRegisterAtOperandIndex(Node* value, +void InterpreterAssembler::StoreRegisterAtOperandIndex(TNode<Object> value, int operand_index) { StoreRegister(value, BytecodeOperandReg(operand_index, LoadSensitivity::kSafe)); } -void InterpreterAssembler::StoreRegisterPairAtOperandIndex(Node* value1, - Node* value2, +void InterpreterAssembler::StoreRegisterPairAtOperandIndex(TNode<Object> value1, + TNode<Object> value2, int operand_index) { DCHECK_EQ(OperandType::kRegOutPair, Bytecodes::GetOperandType(bytecode_, operand_index)); - Node* first_reg_index = + TNode<IntPtrT> first_reg_index = BytecodeOperandReg(operand_index, LoadSensitivity::kSafe); StoreRegister(value1, first_reg_index); TNode<IntPtrT> second_reg_index = NextRegister(first_reg_index); @@ -347,10 +351,11 @@ void InterpreterAssembler::StoreRegisterPairAtOperandIndex(Node* value1, } void InterpreterAssembler::StoreRegisterTripleAtOperandIndex( - Node* value1, Node* value2, Node* value3, int operand_index) { + TNode<Object> value1, TNode<Object> value2, TNode<Object> value3, + int operand_index) { DCHECK_EQ(OperandType::kRegOutTriple, Bytecodes::GetOperandType(bytecode_, operand_index)); - Node* first_reg_index = + TNode<IntPtrT> first_reg_index = BytecodeOperandReg(operand_index, LoadSensitivity::kSafe); StoreRegister(value1, first_reg_index); TNode<IntPtrT> second_reg_index = NextRegister(first_reg_index); @@ -359,12 +364,12 @@ void InterpreterAssembler::StoreRegisterTripleAtOperandIndex( StoreRegister(value3, third_reg_index); } -TNode<IntPtrT> InterpreterAssembler::NextRegister(Node* reg_index) { +TNode<IntPtrT> InterpreterAssembler::NextRegister(TNode<IntPtrT> reg_index) { // Register indexes are negative, so the next index is minus one. return Signed(IntPtrAdd(reg_index, IntPtrConstant(-1))); } -Node* InterpreterAssembler::OperandOffset(int operand_index) { +TNode<IntPtrT> InterpreterAssembler::OperandOffset(int operand_index) { return IntPtrConstant( Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale())); } @@ -374,7 +379,7 @@ TNode<Uint8T> InterpreterAssembler::BytecodeOperandUnsignedByte( DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( bytecode_, operand_index, operand_scale())); - Node* operand_offset = OperandOffset(operand_index); + TNode<IntPtrT> operand_offset = OperandOffset(operand_index); return Load<Uint8T>(BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), operand_offset), needs_poisoning); @@ -385,7 +390,7 @@ TNode<Int8T> InterpreterAssembler::BytecodeOperandSignedByte( DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_)); DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize( bytecode_, operand_index, operand_scale())); - Node* operand_offset = OperandOffset(operand_index); + TNode<IntPtrT> operand_offset = OperandOffset(operand_index); return Load<Int8T>(BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), operand_offset), needs_poisoning); @@ -429,7 +434,7 @@ TNode<Word32T> InterpreterAssembler::BytecodeOperandReadUnaligned( MachineType machine_type = (i == 0) ? msb_type : MachineType::Uint8(); TNode<IntPtrT> offset = IntPtrConstant(relative_offset + msb_offset + i * kStep); - TNode<WordT> array_offset = IntPtrAdd(BytecodeOffset(), offset); + TNode<IntPtrT> array_offset = IntPtrAdd(BytecodeOffset(), offset); bytes[i] = UncheckedCast<Word32T>(Load(machine_type, BytecodeArrayTaggedPointer(), array_offset, needs_poisoning)); @@ -561,7 +566,7 @@ TNode<Uint32T> InterpreterAssembler::BytecodeOperandCount(int operand_index) { return BytecodeUnsignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::BytecodeOperandFlag(int operand_index) { +TNode<Uint32T> InterpreterAssembler::BytecodeOperandFlag(int operand_index) { DCHECK_EQ(OperandType::kFlag8, Bytecodes::GetOperandType(bytecode_, operand_index)); OperandSize operand_size = @@ -578,15 +583,16 @@ TNode<Uint32T> InterpreterAssembler::BytecodeOperandUImm(int operand_index) { return BytecodeUnsignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::BytecodeOperandUImmWord(int operand_index) { +TNode<UintPtrT> InterpreterAssembler::BytecodeOperandUImmWord( + int operand_index) { return ChangeUint32ToWord(BytecodeOperandUImm(operand_index)); } -Node* InterpreterAssembler::BytecodeOperandUImmSmi(int operand_index) { - return SmiFromInt32(Signed(BytecodeOperandUImm(operand_index))); +TNode<Smi> InterpreterAssembler::BytecodeOperandUImmSmi(int operand_index) { + return SmiFromUint32(BytecodeOperandUImm(operand_index)); } -Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { +TNode<Int32T> InterpreterAssembler::BytecodeOperandImm(int operand_index) { DCHECK_EQ(OperandType::kImm, Bytecodes::GetOperandType(bytecode_, operand_index)); OperandSize operand_size = @@ -594,15 +600,17 @@ Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) { return BytecodeSignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::BytecodeOperandImmIntPtr(int operand_index) { +TNode<IntPtrT> InterpreterAssembler::BytecodeOperandImmIntPtr( + int operand_index) { return ChangeInt32ToIntPtr(BytecodeOperandImm(operand_index)); } -Node* InterpreterAssembler::BytecodeOperandImmSmi(int operand_index) { +TNode<Smi> InterpreterAssembler::BytecodeOperandImmSmi(int operand_index) { return SmiFromInt32(BytecodeOperandImm(operand_index)); } -Node* InterpreterAssembler::BytecodeOperandIdxInt32(int operand_index) { +TNode<Uint32T> InterpreterAssembler::BytecodeOperandIdxInt32( + int operand_index) { DCHECK_EQ(OperandType::kIdx, Bytecodes::GetOperandType(bytecode_, operand_index)); OperandSize operand_size = @@ -610,15 +618,15 @@ Node* InterpreterAssembler::BytecodeOperandIdxInt32(int operand_index) { return BytecodeUnsignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { +TNode<UintPtrT> InterpreterAssembler::BytecodeOperandIdx(int operand_index) { return ChangeUint32ToWord(BytecodeOperandIdxInt32(operand_index)); } -Node* InterpreterAssembler::BytecodeOperandIdxSmi(int operand_index) { - return SmiTag(BytecodeOperandIdx(operand_index)); +TNode<Smi> InterpreterAssembler::BytecodeOperandIdxSmi(int operand_index) { + return SmiTag(Signed(BytecodeOperandIdx(operand_index))); } -Node* InterpreterAssembler::BytecodeOperandConstantPoolIdx( +TNode<UintPtrT> InterpreterAssembler::BytecodeOperandConstantPoolIdx( int operand_index, LoadSensitivity needs_poisoning) { DCHECK_EQ(OperandType::kIdx, Bytecodes::GetOperandType(bytecode_, operand_index)); @@ -628,7 +636,7 @@ Node* InterpreterAssembler::BytecodeOperandConstantPoolIdx( BytecodeUnsignedOperand(operand_index, operand_size, needs_poisoning)); } -Node* InterpreterAssembler::BytecodeOperandReg( +TNode<IntPtrT> InterpreterAssembler::BytecodeOperandReg( int operand_index, LoadSensitivity needs_poisoning) { DCHECK(Bytecodes::IsRegisterOperandType( Bytecodes::GetOperandType(bytecode_, operand_index))); @@ -638,7 +646,8 @@ Node* InterpreterAssembler::BytecodeOperandReg( BytecodeSignedOperand(operand_index, operand_size, needs_poisoning)); } -Node* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) { +TNode<Uint32T> InterpreterAssembler::BytecodeOperandRuntimeId( + int operand_index) { DCHECK_EQ(OperandType::kRuntimeId, Bytecodes::GetOperandType(bytecode_, operand_index)); OperandSize operand_size = @@ -647,7 +656,7 @@ Node* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) { return BytecodeUnsignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::BytecodeOperandNativeContextIndex( +TNode<UintPtrT> InterpreterAssembler::BytecodeOperandNativeContextIndex( int operand_index) { DCHECK_EQ(OperandType::kNativeContextIndex, Bytecodes::GetOperandType(bytecode_, operand_index)); @@ -657,7 +666,8 @@ Node* InterpreterAssembler::BytecodeOperandNativeContextIndex( BytecodeUnsignedOperand(operand_index, operand_size)); } -Node* InterpreterAssembler::BytecodeOperandIntrinsicId(int operand_index) { +TNode<Uint32T> InterpreterAssembler::BytecodeOperandIntrinsicId( + int operand_index) { DCHECK_EQ(OperandType::kIntrinsicId, Bytecodes::GetOperandType(bytecode_, operand_index)); OperandSize operand_size = @@ -666,7 +676,7 @@ Node* InterpreterAssembler::BytecodeOperandIntrinsicId(int operand_index) { return BytecodeUnsignedOperand(operand_index, operand_size); } -Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { +TNode<Object> InterpreterAssembler::LoadConstantPoolEntry(TNode<WordT> index) { TNode<FixedArray> constant_pool = CAST(LoadObjectField( BytecodeArrayTaggedPointer(), BytecodeArray::kConstantPoolOffset)); return UnsafeLoadFixedArrayElement( @@ -674,13 +684,13 @@ Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { } TNode<IntPtrT> InterpreterAssembler::LoadAndUntagConstantPoolEntry( - Node* index) { - return SmiUntag(LoadConstantPoolEntry(index)); + TNode<WordT> index) { + return SmiUntag(CAST(LoadConstantPoolEntry(index))); } -Node* InterpreterAssembler::LoadConstantPoolEntryAtOperandIndex( +TNode<Object> InterpreterAssembler::LoadConstantPoolEntryAtOperandIndex( int operand_index) { - Node* index = + TNode<UintPtrT> index = BytecodeOperandConstantPoolIdx(operand_index, LoadSensitivity::kSafe); return LoadConstantPoolEntry(index); } @@ -688,7 +698,7 @@ Node* InterpreterAssembler::LoadConstantPoolEntryAtOperandIndex( TNode<IntPtrT> InterpreterAssembler::LoadAndUntagConstantPoolEntryAtOperandIndex( int operand_index) { - return SmiUntag(LoadConstantPoolEntryAtOperandIndex(operand_index)); + return SmiUntag(CAST(LoadConstantPoolEntryAtOperandIndex(operand_index))); } TNode<HeapObject> InterpreterAssembler::LoadFeedbackVector() { @@ -713,151 +723,15 @@ void InterpreterAssembler::CallPrologue() { void InterpreterAssembler::CallEpilogue() { } -void InterpreterAssembler::IncrementCallCount(Node* feedback_vector, - Node* slot_id) { - Comment("increment call count"); - TNode<Smi> call_count = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot_id, kTaggedSize)); - // The lowest {FeedbackNexus::CallCountField::kShift} bits of the call - // count are used as flags. To increment the call count by 1 we hence - // have to increment by 1 << {FeedbackNexus::CallCountField::kShift}. - TNode<Smi> new_count = SmiAdd( - call_count, SmiConstant(1 << FeedbackNexus::CallCountField::kShift)); - // Count is Smi, so we don't need a write barrier. - StoreFeedbackVectorSlot(feedback_vector, slot_id, new_count, - SKIP_WRITE_BARRIER, kTaggedSize); -} - -void InterpreterAssembler::CollectCallableFeedback(Node* target, Node* context, - Node* feedback_vector, - Node* slot_id) { - Label extra_checks(this, Label::kDeferred), done(this); - - // Check if we have monomorphic {target} feedback already. - TNode<MaybeObject> feedback = - LoadFeedbackVectorSlot(feedback_vector, slot_id); - Comment("check if monomorphic"); - TNode<BoolT> is_monomorphic = IsWeakReferenceTo(feedback, CAST(target)); - GotoIf(is_monomorphic, &done); - - // Check if it is a megamorphic {target}. - Comment("check if megamorphic"); - TNode<BoolT> is_megamorphic = TaggedEqual( - feedback, HeapConstant(FeedbackVector::MegamorphicSentinel(isolate()))); - Branch(is_megamorphic, &done, &extra_checks); - - BIND(&extra_checks); - { - Label initialize(this), mark_megamorphic(this); - - Comment("check if weak reference"); - TNode<BoolT> is_uninitialized = TaggedEqual( - feedback, - HeapConstant(FeedbackVector::UninitializedSentinel(isolate()))); - GotoIf(is_uninitialized, &initialize); - CSA_ASSERT(this, IsWeakOrCleared(feedback)); - - // If the weak reference is cleared, we have a new chance to become - // monomorphic. - Comment("check if weak reference is cleared"); - Branch(IsCleared(feedback), &initialize, &mark_megamorphic); - - BIND(&initialize); - { - // Check if {target} is a JSFunction in the current native context. - Comment("check if function in same native context"); - GotoIf(TaggedIsSmi(target), &mark_megamorphic); - // Check if the {target} is a JSFunction or JSBoundFunction - // in the current native context. - VARIABLE(var_current, MachineRepresentation::kTagged, target); - Label loop(this, &var_current), done_loop(this); - Goto(&loop); - BIND(&loop); - { - Label if_boundfunction(this), if_function(this); - Node* current = var_current.value(); - CSA_ASSERT(this, TaggedIsNotSmi(current)); - TNode<Uint16T> current_instance_type = LoadInstanceType(current); - GotoIf(InstanceTypeEqual(current_instance_type, JS_BOUND_FUNCTION_TYPE), - &if_boundfunction); - Branch(InstanceTypeEqual(current_instance_type, JS_FUNCTION_TYPE), - &if_function, &mark_megamorphic); - - BIND(&if_function); - { - // Check that the JSFunction {current} is in the current native - // context. - TNode<Context> current_context = - CAST(LoadObjectField(current, JSFunction::kContextOffset)); - TNode<Context> current_native_context = - LoadNativeContext(current_context); - Branch( - TaggedEqual(LoadNativeContext(context), current_native_context), - &done_loop, &mark_megamorphic); - } - - BIND(&if_boundfunction); - { - // Continue with the [[BoundTargetFunction]] of {target}. - var_current.Bind(LoadObjectField( - current, JSBoundFunction::kBoundTargetFunctionOffset)); - Goto(&loop); - } - } - BIND(&done_loop); - StoreWeakReferenceInFeedbackVector(feedback_vector, slot_id, - CAST(target)); - ReportFeedbackUpdate(feedback_vector, slot_id, "Call:Initialize"); - Goto(&done); - } - - BIND(&mark_megamorphic); - { - // MegamorphicSentinel is an immortal immovable object so - // write-barrier is not needed. - Comment("transition to megamorphic"); - DCHECK(RootsTable::IsImmortalImmovable(RootIndex::kmegamorphic_symbol)); - StoreFeedbackVectorSlot( - feedback_vector, slot_id, - HeapConstant(FeedbackVector::MegamorphicSentinel(isolate())), - SKIP_WRITE_BARRIER); - ReportFeedbackUpdate(feedback_vector, slot_id, - "Call:TransitionMegamorphic"); - Goto(&done); - } - } - - BIND(&done); -} - -void InterpreterAssembler::CollectCallFeedback(Node* target, Node* context, - Node* maybe_feedback_vector, - Node* slot_id) { - Label feedback_done(this); - // If feedback_vector is not valid, then nothing to do. - GotoIf(IsUndefined(maybe_feedback_vector), &feedback_done); - - CSA_SLOW_ASSERT(this, IsFeedbackVector(maybe_feedback_vector)); - - // Increment the call count. - IncrementCallCount(maybe_feedback_vector, slot_id); - - // Collect the callable {target} feedback. - CollectCallableFeedback(target, context, maybe_feedback_vector, slot_id); - Goto(&feedback_done); - - BIND(&feedback_done); -} - void InterpreterAssembler::CallJSAndDispatch( - Node* function, Node* context, const RegListNodePair& args, + TNode<Object> function, TNode<Context> context, const RegListNodePair& args, ConvertReceiverMode receiver_mode) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); DCHECK(Bytecodes::IsCallOrConstruct(bytecode_) || bytecode_ == Bytecode::kInvokeIntrinsic); DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), receiver_mode); - Node* args_count; + TNode<Word32T> args_count; if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { // The receiver is implied, so it is not in the argument list. args_count = args.reg_count(); @@ -879,8 +753,9 @@ void InterpreterAssembler::CallJSAndDispatch( } template <class... TArgs> -void InterpreterAssembler::CallJSAndDispatch(Node* function, Node* context, - Node* arg_count, +void InterpreterAssembler::CallJSAndDispatch(TNode<Object> function, + TNode<Context> context, + TNode<Word32T> arg_count, ConvertReceiverMode receiver_mode, TArgs... args) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); @@ -892,9 +767,9 @@ void InterpreterAssembler::CallJSAndDispatch(Node* function, Node* context, if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) { // The first argument parameter (the receiver) is implied to be undefined. - TailCallStubThenBytecodeDispatch( - callable.descriptor(), code_target, context, function, arg_count, - static_cast<Node*>(UndefinedConstant()), args...); + TailCallStubThenBytecodeDispatch(callable.descriptor(), code_target, + context, function, arg_count, + UndefinedConstant(), args...); } else { TailCallStubThenBytecodeDispatch(callable.descriptor(), code_target, context, function, arg_count, args...); @@ -906,21 +781,22 @@ void InterpreterAssembler::CallJSAndDispatch(Node* function, Node* context, // Instantiate CallJSAndDispatch() for argument counts used by interpreter // generator. template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch( - Node* function, Node* context, Node* arg_count, + TNode<Object> function, TNode<Context> context, TNode<Word32T> arg_count, ConvertReceiverMode receiver_mode); template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch( - Node* function, Node* context, Node* arg_count, - ConvertReceiverMode receiver_mode, Node*); + TNode<Object> function, TNode<Context> context, TNode<Word32T> arg_count, + ConvertReceiverMode receiver_mode, TNode<Object>); template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch( - Node* function, Node* context, Node* arg_count, - ConvertReceiverMode receiver_mode, Node*, Node*); + TNode<Object> function, TNode<Context> context, TNode<Word32T> arg_count, + ConvertReceiverMode receiver_mode, TNode<Object>, TNode<Object>); template V8_EXPORT_PRIVATE void InterpreterAssembler::CallJSAndDispatch( - Node* function, Node* context, Node* arg_count, - ConvertReceiverMode receiver_mode, Node*, Node*, Node*); + TNode<Object> function, TNode<Context> context, TNode<Word32T> arg_count, + ConvertReceiverMode receiver_mode, TNode<Object>, TNode<Object>, + TNode<Object>); void InterpreterAssembler::CallJSWithSpreadAndDispatch( - Node* function, Node* context, const RegListNodePair& args, Node* slot_id, - Node* maybe_feedback_vector) { + TNode<Object> function, TNode<Context> context, const RegListNodePair& args, + TNode<UintPtrT> slot_id, TNode<HeapObject> maybe_feedback_vector) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); DCHECK_EQ(Bytecodes::GetReceiverMode(bytecode_), ConvertReceiverMode::kAny); CollectCallFeedback(function, context, maybe_feedback_vector, slot_id); @@ -939,16 +815,18 @@ void InterpreterAssembler::CallJSWithSpreadAndDispatch( accumulator_use_ = accumulator_use_ | AccumulatorUse::kWrite; } -Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, - SloppyTNode<Object> new_target, - const RegListNodePair& args, - Node* slot_id, Node* feedback_vector) { +TNode<Object> InterpreterAssembler::Construct( + TNode<Object> target, TNode<Context> context, TNode<Object> new_target, + const RegListNodePair& args, TNode<UintPtrT> slot_id, + TNode<HeapObject> maybe_feedback_vector) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); - VARIABLE(var_result, MachineRepresentation::kTagged); - VARIABLE(var_site, MachineRepresentation::kTagged); + TVARIABLE(Object, var_result); + TVARIABLE(AllocationSite, var_site); Label extra_checks(this, Label::kDeferred), return_result(this, &var_result), construct(this), construct_array(this, &var_site); - GotoIf(IsUndefined(feedback_vector), &construct); + GotoIf(IsUndefined(maybe_feedback_vector), &construct); + + TNode<FeedbackVector> feedback_vector = CAST(maybe_feedback_vector); // Increment the call count. IncrementCallCount(feedback_vector, slot_id); @@ -956,7 +834,8 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, // Check if we have monomorphic {new_target} feedback already. TNode<MaybeObject> feedback = LoadFeedbackVectorSlot(feedback_vector, slot_id); - Branch(IsWeakReferenceTo(feedback, new_target), &construct, &extra_checks); + Branch(IsWeakReferenceToObject(feedback, new_target), &construct, + &extra_checks); BIND(&extra_checks); { @@ -989,7 +868,7 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, LoadNativeContext(context), Context::ARRAY_FUNCTION_INDEX); GotoIfNot(TaggedEqual(target, array_function), &mark_megamorphic); GotoIfNot(TaggedEqual(new_target, array_function), &mark_megamorphic); - var_site.Bind(strong_feedback); + var_site = CAST(strong_feedback); Goto(&construct_array); } @@ -1008,14 +887,13 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, GotoIf(TaggedIsSmi(new_target), &mark_megamorphic); // Check if the {new_target} is a JSFunction or JSBoundFunction // in the current native context. - VARIABLE(var_current, MachineRepresentation::kTagged, new_target); + TVARIABLE(HeapObject, var_current, CAST(new_target)); Label loop(this, &var_current), done_loop(this); Goto(&loop); BIND(&loop); { Label if_boundfunction(this), if_function(this); - Node* current = var_current.value(); - CSA_ASSERT(this, TaggedIsNotSmi(current)); + TNode<HeapObject> current = var_current.value(); TNode<Uint16T> current_instance_type = LoadInstanceType(current); GotoIf(InstanceTypeEqual(current_instance_type, JS_BOUND_FUNCTION_TYPE), &if_boundfunction); @@ -1028,7 +906,7 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, // context. TNode<Context> current_context = CAST(LoadObjectField(current, JSFunction::kContextOffset)); - TNode<Context> current_native_context = + TNode<NativeContext> current_native_context = LoadNativeContext(current_context); Branch( TaggedEqual(LoadNativeContext(context), current_native_context), @@ -1038,8 +916,8 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, BIND(&if_boundfunction); { // Continue with the [[BoundTargetFunction]] of {current}. - var_current.Bind(LoadObjectField( - current, JSBoundFunction::kBoundTargetFunctionOffset)); + var_current = LoadObjectField<HeapObject>( + current, JSBoundFunction::kBoundTargetFunctionOffset); Goto(&loop); } } @@ -1056,8 +934,8 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, BIND(&create_allocation_site); { - var_site.Bind(CreateAllocationSiteInFeedbackVector(feedback_vector, - SmiTag(slot_id))); + var_site = + CreateAllocationSiteInFeedbackVector(feedback_vector, slot_id); ReportFeedbackUpdate(feedback_vector, slot_id, "Construct:CreateAllocationSite"); Goto(&construct_array); @@ -1097,9 +975,9 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, Callable callable = CodeFactory::InterpreterPushArgsThenConstruct( isolate(), InterpreterPushArgsMode::kArrayFunction); TNode<Code> code_target = HeapConstant(callable.code()); - var_result.Bind(CallStub(callable.descriptor(), code_target, context, - args.reg_count(), args.base_reg_location(), target, - new_target, var_site.value())); + var_result = CallStub(callable.descriptor(), code_target, context, + args.reg_count(), args.base_reg_location(), target, + new_target, var_site.value()); Goto(&return_result); } @@ -1110,9 +988,9 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, Callable callable = CodeFactory::InterpreterPushArgsThenConstruct( isolate(), InterpreterPushArgsMode::kOther); TNode<Code> code_target = HeapConstant(callable.code()); - var_result.Bind(CallStub(callable.descriptor(), code_target, context, - args.reg_count(), args.base_reg_location(), target, - new_target, UndefinedConstant())); + var_result = CallStub(callable.descriptor(), code_target, context, + args.reg_count(), args.base_reg_location(), target, + new_target, UndefinedConstant()); Goto(&return_result); } @@ -1120,17 +998,18 @@ Node* InterpreterAssembler::Construct(SloppyTNode<Object> target, Node* context, return var_result.value(); } -Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, - Node* new_target, - const RegListNodePair& args, - Node* slot_id, - Node* feedback_vector) { +TNode<Object> InterpreterAssembler::ConstructWithSpread( + TNode<Object> target, TNode<Context> context, TNode<Object> new_target, + const RegListNodePair& args, TNode<UintPtrT> slot_id, + TNode<HeapObject> maybe_feedback_vector) { // TODO(bmeurer): Unify this with the Construct bytecode feedback // above once we have a way to pass the AllocationSite to the Array // constructor _and_ spread the last argument at the same time. DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); Label extra_checks(this, Label::kDeferred), construct(this); - GotoIf(IsUndefined(feedback_vector), &construct); + GotoIf(IsUndefined(maybe_feedback_vector), &construct); + + TNode<FeedbackVector> feedback_vector = CAST(maybe_feedback_vector); // Increment the call count. IncrementCallCount(feedback_vector, slot_id); @@ -1138,7 +1017,7 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, // Check if we have monomorphic {new_target} feedback already. TNode<MaybeObject> feedback = LoadFeedbackVectorSlot(feedback_vector, slot_id); - Branch(IsWeakReferenceTo(feedback, CAST(new_target)), &construct, + Branch(IsWeakReferenceToObject(feedback, new_target), &construct, &extra_checks); BIND(&extra_checks); @@ -1174,14 +1053,13 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, GotoIf(TaggedIsSmi(new_target), &mark_megamorphic); // Check if the {new_target} is a JSFunction or JSBoundFunction // in the current native context. - VARIABLE(var_current, MachineRepresentation::kTagged, new_target); + TVARIABLE(HeapObject, var_current, CAST(new_target)); Label loop(this, &var_current), done_loop(this); Goto(&loop); BIND(&loop); { Label if_boundfunction(this), if_function(this); - Node* current = var_current.value(); - CSA_ASSERT(this, TaggedIsNotSmi(current)); + TNode<HeapObject> current = var_current.value(); TNode<Uint16T> current_instance_type = LoadInstanceType(current); GotoIf(InstanceTypeEqual(current_instance_type, JS_BOUND_FUNCTION_TYPE), &if_boundfunction); @@ -1194,7 +1072,7 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, // context. TNode<Context> current_context = CAST(LoadObjectField(current, JSFunction::kContextOffset)); - TNode<Context> current_native_context = + TNode<NativeContext> current_native_context = LoadNativeContext(current_context); Branch( TaggedEqual(LoadNativeContext(context), current_native_context), @@ -1204,8 +1082,8 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, BIND(&if_boundfunction); { // Continue with the [[BoundTargetFunction]] of {current}. - var_current.Bind(LoadObjectField( - current, JSBoundFunction::kBoundTargetFunctionOffset)); + var_current = LoadObjectField<HeapObject>( + current, JSBoundFunction::kBoundTargetFunctionOffset); Goto(&loop); } } @@ -1243,7 +1121,8 @@ Node* InterpreterAssembler::ConstructWithSpread(Node* target, Node* context, UndefinedConstant()); } -Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context, +Node* InterpreterAssembler::CallRuntimeN(TNode<Uint32T> function_id, + TNode<Context> context, const RegListNodePair& args, int result_size) { DCHECK(Bytecodes::MakesCallAlongCriticalPath(bytecode_)); @@ -1252,22 +1131,22 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context, TNode<Code> code_target = HeapConstant(callable.code()); // Get the function entry from the function id. - Node* function_table = ExternalConstant( - ExternalReference::runtime_function_table_address(isolate())); + TNode<RawPtrT> function_table = ReinterpretCast<RawPtrT>(ExternalConstant( + ExternalReference::runtime_function_table_address(isolate()))); TNode<Word32T> function_offset = Int32Mul(function_id, Int32Constant(sizeof(Runtime::Function))); TNode<WordT> function = IntPtrAdd(function_table, ChangeUint32ToWord(function_offset)); - Node* function_entry = - Load(MachineType::Pointer(), function, - IntPtrConstant(offsetof(Runtime::Function, entry))); + TNode<RawPtrT> function_entry = Load<RawPtrT>( + function, IntPtrConstant(offsetof(Runtime::Function, entry))); return CallStubR(StubCallMode::kCallCodeObject, callable.descriptor(), result_size, code_target, context, args.reg_count(), args.base_reg_location(), function_entry); } -void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) { +void InterpreterAssembler::UpdateInterruptBudget(TNode<Int32T> weight, + bool backward) { Comment("[ UpdateInterruptBudget"); // Assert that the weight is positive (negative weights should be implemented @@ -1289,7 +1168,7 @@ void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) { TVARIABLE(Int32T, new_budget); if (backward) { // Update budget by |weight| and check if it reaches zero. - new_budget = Signed(Int32Sub(budget_after_bytecode, weight)); + new_budget = Int32Sub(budget_after_bytecode, weight); TNode<BoolT> condition = Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0)); Label ok(this), interrupt_check(this, Label::kDeferred); @@ -1303,7 +1182,7 @@ void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) { } else { // For a forward jump, we know we only increase the interrupt budget, so // no need to check if it's below zero. - new_budget = Signed(Int32Add(budget_after_bytecode, weight)); + new_budget = Int32Add(budget_after_bytecode, weight); } // Update budget. @@ -1323,7 +1202,7 @@ TNode<IntPtrT> InterpreterAssembler::Advance(int delta) { return Advance(IntPtrConstant(delta)); } -TNode<IntPtrT> InterpreterAssembler::Advance(SloppyTNode<IntPtrT> delta, +TNode<IntPtrT> InterpreterAssembler::Advance(TNode<IntPtrT> delta, bool backward) { #ifdef V8_TRACE_IGNITION TraceBytecode(Runtime::kInterpreterTraceBytecodeExit); @@ -1334,45 +1213,51 @@ TNode<IntPtrT> InterpreterAssembler::Advance(SloppyTNode<IntPtrT> delta, return next_offset; } -Node* InterpreterAssembler::Jump(Node* delta, bool backward) { +void InterpreterAssembler::Jump(TNode<IntPtrT> jump_offset, bool backward) { DCHECK(!Bytecodes::IsStarLookahead(bytecode_, operand_scale_)); - UpdateInterruptBudget(TruncateIntPtrToInt32(delta), backward); - Node* new_bytecode_offset = Advance(delta, backward); - TNode<WordT> target_bytecode = LoadBytecode(new_bytecode_offset); - return DispatchToBytecode(target_bytecode, new_bytecode_offset); + UpdateInterruptBudget(TruncateIntPtrToInt32(jump_offset), backward); + TNode<IntPtrT> new_bytecode_offset = Advance(jump_offset, backward); + TNode<RawPtrT> target_bytecode = + UncheckedCast<RawPtrT>(LoadBytecode(new_bytecode_offset)); + DispatchToBytecode(target_bytecode, new_bytecode_offset); } -Node* InterpreterAssembler::Jump(Node* delta) { return Jump(delta, false); } +void InterpreterAssembler::Jump(TNode<IntPtrT> jump_offset) { + Jump(jump_offset, false); +} -Node* InterpreterAssembler::JumpBackward(Node* delta) { - return Jump(delta, true); +void InterpreterAssembler::JumpBackward(TNode<IntPtrT> jump_offset) { + Jump(jump_offset, true); } -void InterpreterAssembler::JumpConditional(Node* condition, Node* delta) { +void InterpreterAssembler::JumpConditional(TNode<BoolT> condition, + TNode<IntPtrT> jump_offset) { Label match(this), no_match(this); Branch(condition, &match, &no_match); BIND(&match); - Jump(delta); + Jump(jump_offset); BIND(&no_match); Dispatch(); } void InterpreterAssembler::JumpIfTaggedEqual(TNode<Object> lhs, - TNode<Object> rhs, Node* delta) { - JumpConditional(TaggedEqual(lhs, rhs), delta); + TNode<Object> rhs, + TNode<IntPtrT> jump_offset) { + JumpConditional(TaggedEqual(lhs, rhs), jump_offset); } void InterpreterAssembler::JumpIfTaggedNotEqual(TNode<Object> lhs, TNode<Object> rhs, - Node* delta) { - JumpConditional(TaggedNotEqual(lhs, rhs), delta); + TNode<IntPtrT> jump_offset) { + JumpConditional(TaggedNotEqual(lhs, rhs), jump_offset); } -TNode<WordT> InterpreterAssembler::LoadBytecode(Node* bytecode_offset) { - Node* bytecode = - Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), bytecode_offset); +TNode<WordT> InterpreterAssembler::LoadBytecode( + TNode<IntPtrT> bytecode_offset) { + TNode<Uint8T> bytecode = + Load<Uint8T>(BytecodeArrayTaggedPointer(), bytecode_offset); return ChangeUint32ToWord(bytecode); } @@ -1418,51 +1303,39 @@ void InterpreterAssembler::InlineStar() { accumulator_use_ = previous_acc_use; } -Node* InterpreterAssembler::Dispatch() { +void InterpreterAssembler::Dispatch() { Comment("========= Dispatch"); DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_); - Node* target_offset = Advance(); + TNode<IntPtrT> target_offset = Advance(); TNode<WordT> target_bytecode = LoadBytecode(target_offset); if (Bytecodes::IsStarLookahead(bytecode_, operand_scale_)) { target_bytecode = StarDispatchLookahead(target_bytecode); } - return DispatchToBytecode(target_bytecode, BytecodeOffset()); + DispatchToBytecode(target_bytecode, BytecodeOffset()); } -Node* InterpreterAssembler::DispatchToBytecode(Node* target_bytecode, - Node* new_bytecode_offset) { +void InterpreterAssembler::DispatchToBytecode( + TNode<WordT> target_bytecode, TNode<IntPtrT> new_bytecode_offset) { if (FLAG_trace_ignition_dispatches) { TraceBytecodeDispatch(target_bytecode); } - Node* target_code_entry = - Load(MachineType::Pointer(), DispatchTableRawPointer(), - TimesSystemPointerSize(target_bytecode)); - - return DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset, - target_bytecode); -} + TNode<RawPtrT> target_code_entry = Load<RawPtrT>( + DispatchTablePointer(), TimesSystemPointerSize(target_bytecode)); -Node* InterpreterAssembler::DispatchToBytecodeHandler(Node* handler, - Node* bytecode_offset, - Node* target_bytecode) { - // TODO(ishell): Add CSA::CodeEntryPoint(code). - TNode<IntPtrT> handler_entry = - IntPtrAdd(BitcastTaggedToWord(handler), - IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); - return DispatchToBytecodeHandlerEntry(handler_entry, bytecode_offset, - target_bytecode); + DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset); } -Node* InterpreterAssembler::DispatchToBytecodeHandlerEntry( - Node* handler_entry, Node* bytecode_offset, Node* target_bytecode) { +void InterpreterAssembler::DispatchToBytecodeHandlerEntry( + TNode<RawPtrT> handler_entry, TNode<IntPtrT> bytecode_offset) { // Propagate speculation poisoning. - TNode<WordT> poisoned_handler_entry = WordPoisonOnSpeculation(handler_entry); - return TailCallBytecodeDispatch( - InterpreterDispatchDescriptor{}, poisoned_handler_entry, - GetAccumulatorUnchecked(), bytecode_offset, BytecodeArrayTaggedPointer(), - DispatchTableRawPointer()); + TNode<RawPtrT> poisoned_handler_entry = + UncheckedCast<RawPtrT>(WordPoisonOnSpeculation(handler_entry)); + TailCallBytecodeDispatch(InterpreterDispatchDescriptor{}, + poisoned_handler_entry, GetAccumulatorUnchecked(), + bytecode_offset, BytecodeArrayTaggedPointer(), + DispatchTablePointer()); } void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { @@ -1474,14 +1347,14 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { // Indices 256-511 correspond to bytecodes with operand_scale == 1 // Indices 512-767 correspond to bytecodes with operand_scale == 2 DCHECK_IMPLIES(Bytecodes::MakesCallAlongCriticalPath(bytecode_), made_call_); - Node* next_bytecode_offset = Advance(1); + TNode<IntPtrT> next_bytecode_offset = Advance(1); TNode<WordT> next_bytecode = LoadBytecode(next_bytecode_offset); if (FLAG_trace_ignition_dispatches) { TraceBytecodeDispatch(next_bytecode); } - Node* base_index; + TNode<IntPtrT> base_index; switch (operand_scale) { case OperandScale::kDouble: base_index = IntPtrConstant(1 << kBitsPerByte); @@ -1493,12 +1366,10 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { UNREACHABLE(); } TNode<WordT> target_index = IntPtrAdd(base_index, next_bytecode); - Node* target_code_entry = - Load(MachineType::Pointer(), DispatchTableRawPointer(), - TimesSystemPointerSize(target_index)); + TNode<RawPtrT> target_code_entry = Load<RawPtrT>( + DispatchTablePointer(), TimesSystemPointerSize(target_index)); - DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset, - next_bytecode); + DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset); } void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { @@ -1527,10 +1398,9 @@ void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { UpdateInterruptBudget(profiling_weight, true); } -Node* InterpreterAssembler::LoadOsrNestingLevel() { - return LoadObjectField(BytecodeArrayTaggedPointer(), - BytecodeArray::kOsrNestingLevelOffset, - MachineType::Int8()); +TNode<Int8T> InterpreterAssembler::LoadOsrNestingLevel() { + return LoadObjectField<Int8T>(BytecodeArrayTaggedPointer(), + BytecodeArray::kOsrNestingLevelOffset); } void InterpreterAssembler::Abort(AbortReason abort_reason) { @@ -1551,7 +1421,7 @@ void InterpreterAssembler::AbortIfWordNotEqual(TNode<WordT> lhs, BIND(&ok); } -void InterpreterAssembler::MaybeDropFrames(Node* context) { +void InterpreterAssembler::MaybeDropFrames(TNode<Context> context) { TNode<ExternalReference> restart_fp_address = ExternalConstant(ExternalReference::debug_restart_fp_address(isolate())); @@ -1576,7 +1446,7 @@ void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) { SmiTag(BytecodeOffset()), GetAccumulatorUnchecked()); } -void InterpreterAssembler::TraceBytecodeDispatch(Node* target_bytecode) { +void InterpreterAssembler::TraceBytecodeDispatch(TNode<WordT> target_bytecode) { TNode<ExternalReference> counters_table = ExternalConstant( ExternalReference::interpreter_dispatch_counters(isolate())); TNode<IntPtrT> source_bytecode_table_index = IntPtrConstant( @@ -1616,8 +1486,8 @@ bool InterpreterAssembler::TargetSupportsUnalignedAccess() { } void InterpreterAssembler::AbortIfRegisterCountInvalid( - Node* parameters_and_registers, Node* formal_parameter_count, - Node* register_count) { + TNode<FixedArrayBase> parameters_and_registers, + TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count) { TNode<IntPtrT> array_size = LoadAndUntagFixedArrayBaseLength(parameters_and_registers); @@ -1633,13 +1503,13 @@ void InterpreterAssembler::AbortIfRegisterCountInvalid( BIND(&ok); } -Node* InterpreterAssembler::ExportParametersAndRegisterFile( +TNode<FixedArray> InterpreterAssembler::ExportParametersAndRegisterFile( TNode<FixedArray> array, const RegListNodePair& registers, TNode<Int32T> formal_parameter_count) { // Store the formal parameters (without receiver) followed by the // registers into the generator's internal parameters_and_registers field. TNode<IntPtrT> formal_parameter_count_intptr = - ChangeInt32ToIntPtr(formal_parameter_count); + Signed(ChangeUint32ToWord(formal_parameter_count)); TNode<UintPtrT> register_count = ChangeUint32ToWord(registers.reg_count()); if (FLAG_debug_code) { CSA_ASSERT(this, IntPtrEqual(registers.base_reg_location(), @@ -1649,8 +1519,8 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile( } { - Variable var_index(this, MachineType::PointerRepresentation()); - var_index.Bind(IntPtrConstant(0)); + TVARIABLE(IntPtrT, var_index); + var_index = IntPtrConstant(0); // Iterate over parameters and write them into the array. Label loop(this, &var_index), done_loop(this); @@ -1662,16 +1532,16 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile( Goto(&loop); BIND(&loop); { - Node* index = var_index.value(); + TNode<IntPtrT> index = var_index.value(); GotoIfNot(UintPtrLessThan(index, formal_parameter_count_intptr), &done_loop); - TNode<WordT> reg_index = IntPtrSub(reg_base, index); + TNode<IntPtrT> reg_index = IntPtrSub(reg_base, index); TNode<Object> value = LoadRegister(reg_index); StoreFixedArrayElement(array, index, value); - var_index.Bind(IntPtrAdd(index, IntPtrConstant(1))); + var_index = IntPtrAdd(index, IntPtrConstant(1)); Goto(&loop); } BIND(&done_loop); @@ -1681,25 +1551,25 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile( // Iterate over register file and write values into array. // The mapping of register to array index must match that used in // BytecodeGraphBuilder::VisitResumeGenerator. - Variable var_index(this, MachineType::PointerRepresentation()); - var_index.Bind(IntPtrConstant(0)); + TVARIABLE(IntPtrT, var_index); + var_index = IntPtrConstant(0); Label loop(this, &var_index), done_loop(this); Goto(&loop); BIND(&loop); { - Node* index = var_index.value(); + TNode<IntPtrT> index = var_index.value(); GotoIfNot(UintPtrLessThan(index, register_count), &done_loop); - TNode<WordT> reg_index = + TNode<IntPtrT> reg_index = IntPtrSub(IntPtrConstant(Register(0).ToOperand()), index); TNode<Object> value = LoadRegister(reg_index); - TNode<WordT> array_index = + TNode<IntPtrT> array_index = IntPtrAdd(formal_parameter_count_intptr, index); StoreFixedArrayElement(array, array_index, value); - var_index.Bind(IntPtrAdd(index, IntPtrConstant(1))); + var_index = IntPtrAdd(index, IntPtrConstant(1)); Goto(&loop); } BIND(&done_loop); @@ -1708,11 +1578,11 @@ Node* InterpreterAssembler::ExportParametersAndRegisterFile( return array; } -Node* InterpreterAssembler::ImportRegisterFile( +TNode<FixedArray> InterpreterAssembler::ImportRegisterFile( TNode<FixedArray> array, const RegListNodePair& registers, TNode<Int32T> formal_parameter_count) { TNode<IntPtrT> formal_parameter_count_intptr = - ChangeInt32ToIntPtr(formal_parameter_count); + Signed(ChangeUint32ToWord(formal_parameter_count)); TNode<UintPtrT> register_count = ChangeUint32ToWord(registers.reg_count()); if (FLAG_debug_code) { CSA_ASSERT(this, IntPtrEqual(registers.base_reg_location(), @@ -1758,8 +1628,8 @@ void InterpreterAssembler::ToNumberOrNumeric(Object::Conversion mode) { TNode<Object> object = GetAccumulator(); TNode<Context> context = GetContext(); - Variable var_type_feedback(this, MachineRepresentation::kTaggedSigned); - Variable var_result(this, MachineRepresentation::kTagged); + TVARIABLE(Smi, var_type_feedback); + TVARIABLE(Numeric, var_result); Label if_done(this), if_objectissmi(this), if_objectisheapnumber(this), if_objectisother(this, Label::kDeferred); @@ -1768,15 +1638,15 @@ void InterpreterAssembler::ToNumberOrNumeric(Object::Conversion mode) { BIND(&if_objectissmi); { - var_result.Bind(object); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall)); + var_result = CAST(object); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kSignedSmall); Goto(&if_done); } BIND(&if_objectisheapnumber); { - var_result.Bind(object); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber)); + var_result = CAST(object); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kNumber); Goto(&if_done); } @@ -1789,23 +1659,23 @@ void InterpreterAssembler::ToNumberOrNumeric(Object::Conversion mode) { Label not_bigint(this); GotoIfNot(IsBigInt(CAST(object)), ¬_bigint); { - var_result.Bind(object); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kBigInt)); + var_result = CAST(object); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kBigInt); Goto(&if_done); } BIND(¬_bigint); } // Convert {object} by calling out to the appropriate builtin. - var_result.Bind(CallBuiltin(builtin, context, object)); - var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kAny)); + var_result = CAST(CallBuiltin(builtin, context, object)); + var_type_feedback = SmiConstant(BinaryOperationFeedback::kAny); Goto(&if_done); } BIND(&if_done); // Record the type feedback collected for {object}. - Node* slot_index = BytecodeOperandIdx(0); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(0); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_index); diff --git a/deps/v8/src/interpreter/interpreter-assembler.h b/deps/v8/src/interpreter/interpreter-assembler.h index 33fa987595daee..4a1882b82ca071 100644 --- a/deps/v8/src/interpreter/interpreter-assembler.h +++ b/deps/v8/src/interpreter/interpreter-assembler.h @@ -25,64 +25,62 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { // Returns the 32-bit unsigned count immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::TNode<Uint32T> BytecodeOperandCount(int operand_index); + TNode<Uint32T> BytecodeOperandCount(int operand_index); // Returns the 32-bit unsigned flag for bytecode operand |operand_index| // in the current bytecode. - compiler::Node* BytecodeOperandFlag(int operand_index); + TNode<Uint32T> BytecodeOperandFlag(int operand_index); // Returns the 32-bit zero-extended index immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandIdxInt32(int operand_index); + TNode<Uint32T> BytecodeOperandIdxInt32(int operand_index); // Returns the word zero-extended index immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandIdx(int operand_index); + TNode<UintPtrT> BytecodeOperandIdx(int operand_index); // Returns the smi index immediate for bytecode operand |operand_index| // in the current bytecode. - compiler::Node* BytecodeOperandIdxSmi(int operand_index); + TNode<Smi> BytecodeOperandIdxSmi(int operand_index); // Returns the 32-bit unsigned immediate for bytecode operand |operand_index| // in the current bytecode. - compiler::TNode<Uint32T> BytecodeOperandUImm(int operand_index); + TNode<Uint32T> BytecodeOperandUImm(int operand_index); // Returns the word-size unsigned immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandUImmWord(int operand_index); + TNode<UintPtrT> BytecodeOperandUImmWord(int operand_index); // Returns the unsigned smi immediate for bytecode operand |operand_index| in // the current bytecode. - compiler::Node* BytecodeOperandUImmSmi(int operand_index); + TNode<Smi> BytecodeOperandUImmSmi(int operand_index); // Returns the 32-bit signed immediate for bytecode operand |operand_index| // in the current bytecode. - compiler::Node* BytecodeOperandImm(int operand_index); + TNode<Int32T> BytecodeOperandImm(int operand_index); // Returns the word-size signed immediate for bytecode operand |operand_index| // in the current bytecode. - compiler::Node* BytecodeOperandImmIntPtr(int operand_index); + TNode<IntPtrT> BytecodeOperandImmIntPtr(int operand_index); // Returns the smi immediate for bytecode operand |operand_index| in the // current bytecode. - compiler::Node* BytecodeOperandImmSmi(int operand_index); + TNode<Smi> BytecodeOperandImmSmi(int operand_index); // Returns the 32-bit unsigned runtime id immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandRuntimeId(int operand_index); - // Returns the 32-bit unsigned native context index immediate for bytecode + TNode<Uint32T> BytecodeOperandRuntimeId(int operand_index); + // Returns the word zero-extended native context index immediate for bytecode // operand |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandNativeContextIndex(int operand_index); + TNode<UintPtrT> BytecodeOperandNativeContextIndex(int operand_index); // Returns the 32-bit unsigned intrinsic id immediate for bytecode operand // |operand_index| in the current bytecode. - compiler::Node* BytecodeOperandIntrinsicId(int operand_index); - + TNode<Uint32T> BytecodeOperandIntrinsicId(int operand_index); // Accumulator. - compiler::TNode<Object> GetAccumulator(); - void SetAccumulator(compiler::Node* value); + TNode<Object> GetAccumulator(); + void SetAccumulator(SloppyTNode<Object> value); // Context. - compiler::TNode<Context> GetContext(); - void SetContext(compiler::TNode<Context> value); + TNode<Context> GetContext(); + void SetContext(TNode<Context> value); // Context at |depth| in the context chain starting at |context|. - compiler::Node* GetContextAtDepth(compiler::TNode<Context> context, - compiler::TNode<Uint32T> depth); + TNode<Context> GetContextAtDepth(TNode<Context> context, + TNode<Uint32T> depth); // Goto the given |target| if the context chain starting at |context| has any // extensions up to the given |depth|. - void GotoIfHasContextExtensionUpToDepth(compiler::TNode<Context> context, - compiler::TNode<Uint32T> depth, - Label* target); + void GotoIfHasContextExtensionUpToDepth(TNode<Context> context, + TNode<Uint32T> depth, Label* target); // A RegListNodePair provides an abstraction over lists of registers. class RegListNodePair { @@ -90,14 +88,12 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { RegListNodePair(TNode<IntPtrT> base_reg_location, TNode<Word32T> reg_count) : base_reg_location_(base_reg_location), reg_count_(reg_count) {} - compiler::TNode<Word32T> reg_count() const { return reg_count_; } - compiler::TNode<IntPtrT> base_reg_location() const { - return base_reg_location_; - } + TNode<Word32T> reg_count() const { return reg_count_; } + TNode<IntPtrT> base_reg_location() const { return base_reg_location_; } private: - compiler::TNode<IntPtrT> base_reg_location_; - compiler::TNode<Word32T> reg_count_; + TNode<IntPtrT> base_reg_location_; + TNode<Word32T> reg_count_; }; // Backup/restore register file to/from a fixed array of the correct length. @@ -105,72 +101,53 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { // - Suspend copies arguments and registers to the generator. // - Resume copies only the registers from the generator, the arguments // are copied by the ResumeGenerator trampoline. - compiler::Node* ExportParametersAndRegisterFile( + TNode<FixedArray> ExportParametersAndRegisterFile( TNode<FixedArray> array, const RegListNodePair& registers, TNode<Int32T> formal_parameter_count); - compiler::Node* ImportRegisterFile(TNode<FixedArray> array, - const RegListNodePair& registers, - TNode<Int32T> formal_parameter_count); + TNode<FixedArray> ImportRegisterFile(TNode<FixedArray> array, + const RegListNodePair& registers, + TNode<Int32T> formal_parameter_count); // Loads from and stores to the interpreter register file. - compiler::TNode<Object> LoadRegister(Register reg); - compiler::TNode<IntPtrT> LoadAndUntagRegister(Register reg); - compiler::TNode<Object> LoadRegisterAtOperandIndex(int operand_index); - std::pair<compiler::TNode<Object>, compiler::TNode<Object>> - LoadRegisterPairAtOperandIndex(int operand_index); - void StoreRegister(compiler::Node* value, Register reg); - void StoreRegisterAtOperandIndex(compiler::Node* value, int operand_index); - void StoreRegisterPairAtOperandIndex(compiler::Node* value1, - compiler::Node* value2, - int operand_index); - void StoreRegisterTripleAtOperandIndex(compiler::Node* value1, - compiler::Node* value2, - compiler::Node* value3, + TNode<Object> LoadRegister(Register reg); + TNode<IntPtrT> LoadAndUntagRegister(Register reg); + TNode<Object> LoadRegisterAtOperandIndex(int operand_index); + std::pair<TNode<Object>, TNode<Object>> LoadRegisterPairAtOperandIndex( + int operand_index); + void StoreRegister(TNode<Object> value, Register reg); + void StoreRegisterAtOperandIndex(TNode<Object> value, int operand_index); + void StoreRegisterPairAtOperandIndex(TNode<Object> value1, + TNode<Object> value2, int operand_index); + void StoreRegisterTripleAtOperandIndex(TNode<Object> value1, + TNode<Object> value2, + TNode<Object> value3, int operand_index); RegListNodePair GetRegisterListAtOperandIndex(int operand_index); - Node* LoadRegisterFromRegisterList(const RegListNodePair& reg_list, - int index); + TNode<Object> LoadRegisterFromRegisterList(const RegListNodePair& reg_list, + int index); TNode<IntPtrT> RegisterLocationInRegisterList(const RegListNodePair& reg_list, int index); // Load constant at the index specified in operand |operand_index| from the // constant pool. - compiler::Node* LoadConstantPoolEntryAtOperandIndex(int operand_index); + TNode<Object> LoadConstantPoolEntryAtOperandIndex(int operand_index); // Load and untag constant at the index specified in operand |operand_index| // from the constant pool. TNode<IntPtrT> LoadAndUntagConstantPoolEntryAtOperandIndex(int operand_index); // Load constant at |index| in the constant pool. - compiler::Node* LoadConstantPoolEntry(compiler::Node* index); + TNode<Object> LoadConstantPoolEntry(TNode<WordT> index); // Load and untag constant at |index| in the constant pool. - TNode<IntPtrT> LoadAndUntagConstantPoolEntry(compiler::Node* index); + TNode<IntPtrT> LoadAndUntagConstantPoolEntry(TNode<WordT> index); // Load the FeedbackVector for the current function. The retuned node could be // undefined. - compiler::TNode<HeapObject> LoadFeedbackVector(); - - // Increment the call count for a CALL_IC or construct call. - // The call count is located at feedback_vector[slot_id + 1]. - void IncrementCallCount(compiler::Node* feedback_vector, - compiler::Node* slot_id); - - // Collect the callable |target| feedback for either a CALL_IC or - // an INSTANCEOF_IC in the |feedback_vector| at |slot_id|. - void CollectCallableFeedback(compiler::Node* target, compiler::Node* context, - compiler::Node* feedback_vector, - compiler::Node* slot_id); - - // Collect CALL_IC feedback for |target| function in the - // |feedback_vector| at |slot_id|, and the call counts in - // the |feedback_vector| at |slot_id+1|. - void CollectCallFeedback(compiler::Node* target, compiler::Node* context, - compiler::Node* maybe_feedback_vector, - compiler::Node* slot_id); + TNode<HeapObject> LoadFeedbackVector(); // Call JSFunction or Callable |function| with |args| arguments, possibly // including the receiver depending on |receiver_mode|. After the call returns // directly dispatches to the next bytecode. - void CallJSAndDispatch(compiler::Node* function, compiler::Node* context, + void CallJSAndDispatch(TNode<Object> function, TNode<Context> context, const RegListNodePair& args, ConvertReceiverMode receiver_mode); @@ -179,93 +156,89 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { // depending on |receiver_mode|. After the call returns directly dispatches to // the next bytecode. template <class... TArgs> - void CallJSAndDispatch(Node* function, Node* context, Node* arg_count, + void CallJSAndDispatch(TNode<Object> function, TNode<Context> context, + TNode<Word32T> arg_count, ConvertReceiverMode receiver_mode, TArgs... args); // Call JSFunction or Callable |function| with |args| // arguments (not including receiver), and the final argument being spread. // After the call returns directly dispatches to the next bytecode. - void CallJSWithSpreadAndDispatch(compiler::Node* function, - compiler::Node* context, + void CallJSWithSpreadAndDispatch(TNode<Object> function, + TNode<Context> context, const RegListNodePair& args, - compiler::Node* slot_id, - compiler::Node* feedback_vector); + TNode<UintPtrT> slot_id, + TNode<HeapObject> maybe_feedback_vector); // Call constructor |target| with |args| arguments (not including receiver). // The |new_target| is the same as the |target| for the new keyword, but // differs for the super keyword. - compiler::Node* Construct(compiler::SloppyTNode<Object> target, - compiler::Node* context, - compiler::SloppyTNode<Object> new_target, - const RegListNodePair& args, - compiler::Node* slot_id, - compiler::Node* feedback_vector); + TNode<Object> Construct(TNode<Object> target, TNode<Context> context, + TNode<Object> new_target, const RegListNodePair& args, + TNode<UintPtrT> slot_id, + TNode<HeapObject> maybe_feedback_vector); // Call constructor |target| with |args| arguments (not including // receiver). The last argument is always a spread. The |new_target| is the // same as the |target| for the new keyword, but differs for the super // keyword. - compiler::Node* ConstructWithSpread(compiler::Node* target, - compiler::Node* context, - compiler::Node* new_target, - const RegListNodePair& args, - compiler::Node* slot_id, - compiler::Node* feedback_vector); + TNode<Object> ConstructWithSpread(TNode<Object> target, + TNode<Context> context, + TNode<Object> new_target, + const RegListNodePair& args, + TNode<UintPtrT> slot_id, + TNode<HeapObject> maybe_feedback_vector); // Call runtime function with |args| arguments which will return |return_size| // number of values. - compiler::Node* CallRuntimeN(compiler::Node* function_id, - compiler::Node* context, + compiler::Node* CallRuntimeN(TNode<Uint32T> function_id, + TNode<Context> context, const RegListNodePair& args, int return_size = 1); // Jump forward relative to the current bytecode by the |jump_offset|. - compiler::Node* Jump(compiler::Node* jump_offset); + void Jump(TNode<IntPtrT> jump_offset); // Jump backward relative to the current bytecode by the |jump_offset|. - compiler::Node* JumpBackward(compiler::Node* jump_offset); + void JumpBackward(TNode<IntPtrT> jump_offset); // Jump forward relative to the current bytecode by |jump_offset| if the // word values |lhs| and |rhs| are equal. - void JumpIfTaggedEqual(compiler::TNode<Object> lhs, - compiler::TNode<Object> rhs, - compiler::Node* jump_offset); + void JumpIfTaggedEqual(TNode<Object> lhs, TNode<Object> rhs, + TNode<IntPtrT> jump_offset); // Jump forward relative to the current bytecode by |jump_offset| if the // word values |lhs| and |rhs| are not equal. - void JumpIfTaggedNotEqual(compiler::TNode<Object> lhs, - compiler::TNode<Object> rhs, - compiler::Node* jump_offset); + void JumpIfTaggedNotEqual(TNode<Object> lhs, TNode<Object> rhs, + TNode<IntPtrT> jump_offset); // Updates the profiler interrupt budget for a return. void UpdateInterruptBudgetOnReturn(); // Returns the OSR nesting level from the bytecode header. - compiler::Node* LoadOsrNestingLevel(); + TNode<Int8T> LoadOsrNestingLevel(); // Dispatch to the bytecode. - compiler::Node* Dispatch(); + void Dispatch(); // Dispatch bytecode as wide operand variant. void DispatchWide(OperandScale operand_scale); // Dispatch to |target_bytecode| at |new_bytecode_offset|. // |target_bytecode| should be equivalent to loading from the offset. - compiler::Node* DispatchToBytecode(compiler::Node* target_bytecode, - compiler::Node* new_bytecode_offset); + void DispatchToBytecode(TNode<WordT> target_bytecode, + TNode<IntPtrT> new_bytecode_offset); // Abort with the given abort reason. void Abort(AbortReason abort_reason); - void AbortIfWordNotEqual(compiler::TNode<WordT> lhs, - compiler::TNode<WordT> rhs, + void AbortIfWordNotEqual(TNode<WordT> lhs, TNode<WordT> rhs, AbortReason abort_reason); // Abort if |register_count| is invalid for given register file array. - void AbortIfRegisterCountInvalid(compiler::Node* parameters_and_registers, - compiler::Node* formal_parameter_count, - compiler::Node* register_count); + void AbortIfRegisterCountInvalid( + TNode<FixedArrayBase> parameters_and_registers, + TNode<IntPtrT> formal_parameter_count, TNode<UintPtrT> register_count); // Dispatch to frame dropper trampoline if necessary. - void MaybeDropFrames(compiler::Node* context); + void MaybeDropFrames(TNode<Context> context); // Returns the offset from the BytecodeArrayPointer of the current bytecode. TNode<IntPtrT> BytecodeOffset(); @@ -277,27 +250,27 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { void ToNumberOrNumeric(Object::Conversion mode); private: - // Returns a tagged pointer to the current function's BytecodeArray object. - compiler::Node* BytecodeArrayTaggedPointer(); + // Returns a pointer to the current function's BytecodeArray object. + TNode<BytecodeArray> BytecodeArrayTaggedPointer(); - // Returns a raw pointer to first entry in the interpreter dispatch table. - compiler::Node* DispatchTableRawPointer(); + // Returns a pointer to first entry in the interpreter dispatch table. + TNode<ExternalReference> DispatchTablePointer(); // Returns the accumulator value without checking whether bytecode // uses it. This is intended to be used only in dispatch and in // tracing as these need to bypass accumulator use validity checks. - compiler::Node* GetAccumulatorUnchecked(); + TNode<Object> GetAccumulatorUnchecked(); // Returns the frame pointer for the interpreted frame of the function being // interpreted. TNode<RawPtrT> GetInterpretedFramePointer(); // Operations on registers. - compiler::TNode<IntPtrT> RegisterLocation(Register reg); - compiler::TNode<IntPtrT> RegisterLocation(compiler::Node* reg_index); - compiler::TNode<IntPtrT> NextRegister(compiler::Node* reg_index); - compiler::TNode<Object> LoadRegister(Node* reg_index); - void StoreRegister(compiler::Node* value, compiler::Node* reg_index); + TNode<IntPtrT> RegisterLocation(Register reg); + TNode<IntPtrT> RegisterLocation(TNode<IntPtrT> reg_index); + TNode<IntPtrT> NextRegister(TNode<IntPtrT> reg_index); + TNode<Object> LoadRegister(TNode<IntPtrT> reg_index); + void StoreRegister(TNode<Object> value, TNode<IntPtrT> reg_index); // Saves and restores interpreter bytecode offset to the interpreter stack // frame when performing a call. @@ -305,7 +278,7 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { void CallEpilogue(); // Increment the dispatch counter for the (current, next) bytecode pair. - void TraceBytecodeDispatch(compiler::Node* target_index); + void TraceBytecodeDispatch(TNode<WordT> target_bytecode); // Traces the current bytecode by calling |function_id|. void TraceBytecode(Runtime::FunctionId function_id); @@ -313,74 +286,74 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { // Updates the bytecode array's interrupt budget by a 32-bit unsigned |weight| // and calls Runtime::kInterrupt if counter reaches zero. If |backward|, then // the interrupt budget is decremented, otherwise it is incremented. - void UpdateInterruptBudget(compiler::Node* weight, bool backward); + void UpdateInterruptBudget(TNode<Int32T> weight, bool backward); // Returns the offset of register |index| relative to RegisterFilePointer(). - compiler::TNode<IntPtrT> RegisterFrameOffset(compiler::Node* index); + TNode<IntPtrT> RegisterFrameOffset(TNode<IntPtrT> index); // Returns the offset of an operand relative to the current bytecode offset. - compiler::Node* OperandOffset(int operand_index); + TNode<IntPtrT> OperandOffset(int operand_index); // Returns a value built from an sequence of bytes in the bytecode // array starting at |relative_offset| from the current bytecode. // The |result_type| determines the size and signedness. of the // value read. This method should only be used on architectures that // do not support unaligned memory accesses. - compiler::TNode<Word32T> BytecodeOperandReadUnaligned( + TNode<Word32T> BytecodeOperandReadUnaligned( int relative_offset, MachineType result_type, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); // Returns zero- or sign-extended to word32 value of the operand. - compiler::TNode<Uint8T> BytecodeOperandUnsignedByte( + TNode<Uint8T> BytecodeOperandUnsignedByte( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Int8T> BytecodeOperandSignedByte( + TNode<Int8T> BytecodeOperandSignedByte( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Uint16T> BytecodeOperandUnsignedShort( + TNode<Uint16T> BytecodeOperandUnsignedShort( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Int16T> BytecodeOperandSignedShort( + TNode<Int16T> BytecodeOperandSignedShort( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Uint32T> BytecodeOperandUnsignedQuad( + TNode<Uint32T> BytecodeOperandUnsignedQuad( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Int32T> BytecodeOperandSignedQuad( + TNode<Int32T> BytecodeOperandSignedQuad( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); // Returns zero- or sign-extended to word32 value of the operand of // given size. - compiler::TNode<Int32T> BytecodeSignedOperand( + TNode<Int32T> BytecodeSignedOperand( int operand_index, OperandSize operand_size, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); - compiler::TNode<Uint32T> BytecodeUnsignedOperand( + TNode<Uint32T> BytecodeUnsignedOperand( int operand_index, OperandSize operand_size, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); // Returns the word-size sign-extended register index for bytecode operand // |operand_index| in the current bytecode. Value is not poisoned on // speculation since the value loaded from the register is poisoned instead. - compiler::Node* BytecodeOperandReg( + TNode<IntPtrT> BytecodeOperandReg( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); // Returns the word zero-extended index immediate for bytecode operand // |operand_index| in the current bytecode for use when loading a . - compiler::Node* BytecodeOperandConstantPoolIdx( + TNode<UintPtrT> BytecodeOperandConstantPoolIdx( int operand_index, LoadSensitivity needs_poisoning = LoadSensitivity::kCritical); // Jump relative to the current bytecode by the |jump_offset|. If |backward|, // then jump backward (subtract the offset), otherwise jump forward (add the // offset). Helper function for Jump and JumpBackward. - compiler::Node* Jump(compiler::Node* jump_offset, bool backward); + void Jump(TNode<IntPtrT> jump_offset, bool backward); // Jump forward relative to the current bytecode by |jump_offset| if the // |condition| is true. Helper function for JumpIfTaggedEqual and // JumpIfTaggedNotEqual. - void JumpConditional(compiler::Node* condition, compiler::Node* jump_offset); + void JumpConditional(TNode<BoolT> condition, TNode<IntPtrT> jump_offset); // Save the bytecode offset to the interpreter frame. void SaveBytecodeOffset(); @@ -394,29 +367,22 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { // Updates and returns BytecodeOffset() advanced by delta bytecodes. // Traces the exit of the current bytecode. TNode<IntPtrT> Advance(int delta); - TNode<IntPtrT> Advance(SloppyTNode<IntPtrT> delta, bool backward = false); + TNode<IntPtrT> Advance(TNode<IntPtrT> delta, bool backward = false); // Load the bytecode at |bytecode_offset|. - compiler::TNode<WordT> LoadBytecode(compiler::Node* bytecode_offset); + TNode<WordT> LoadBytecode(TNode<IntPtrT> bytecode_offset); // Look ahead for Star and inline it in a branch. Returns a new target // bytecode node for dispatch. - compiler::TNode<WordT> StarDispatchLookahead( - compiler::TNode<WordT> target_bytecode); + TNode<WordT> StarDispatchLookahead(TNode<WordT> target_bytecode); // Build code for Star at the current BytecodeOffset() and Advance() to the // next dispatch offset. void InlineStar(); - // Dispatch to the bytecode handler with code offset |handler|. - compiler::Node* DispatchToBytecodeHandler(compiler::Node* handler, - compiler::Node* bytecode_offset, - compiler::Node* target_bytecode); - // Dispatch to the bytecode handler with code entry point |handler_entry|. - compiler::Node* DispatchToBytecodeHandlerEntry( - compiler::Node* handler_entry, compiler::Node* bytecode_offset, - compiler::Node* target_bytecode); + void DispatchToBytecodeHandlerEntry(TNode<RawPtrT> handler_entry, + TNode<IntPtrT> bytecode_offset); int CurrentBytecodeSize() const; @@ -424,11 +390,11 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler { Bytecode bytecode_; OperandScale operand_scale_; - TVariable<RawPtrT> interpreted_frame_pointer_; - CodeStubAssembler::Variable bytecode_array_; - TVariable<IntPtrT> bytecode_offset_; - CodeStubAssembler::Variable dispatch_table_; - CodeStubAssembler::Variable accumulator_; + CodeStubAssembler::TVariable<RawPtrT> interpreted_frame_pointer_; + CodeStubAssembler::TVariable<BytecodeArray> bytecode_array_; + CodeStubAssembler::TVariable<IntPtrT> bytecode_offset_; + CodeStubAssembler::TVariable<ExternalReference> dispatch_table_; + CodeStubAssembler::TVariable<Object> accumulator_; AccumulatorUse accumulator_use_; bool made_call_; bool reloaded_frame_ptr_; diff --git a/deps/v8/src/interpreter/interpreter-generator.cc b/deps/v8/src/interpreter/interpreter-generator.cc index e8569ecd55b0a7..5f686f86b88c4b 100644 --- a/deps/v8/src/interpreter/interpreter-generator.cc +++ b/deps/v8/src/interpreter/interpreter-generator.cc @@ -35,7 +35,6 @@ namespace { using compiler::Node; using Label = CodeStubAssembler::Label; -using Variable = CodeStubAssembler::Variable; #define IGNITION_HANDLER(Name, BaseAssembler) \ class Name##Assembler : public BaseAssembler { \ @@ -71,7 +70,7 @@ IGNITION_HANDLER(LdaZero, InterpreterAssembler) { // // Load an integer literal into the accumulator as a Smi. IGNITION_HANDLER(LdaSmi, InterpreterAssembler) { - Node* smi_int = BytecodeOperandImmSmi(0); + TNode<Smi> smi_int = BytecodeOperandImmSmi(0); SetAccumulator(smi_int); Dispatch(); } @@ -80,7 +79,7 @@ IGNITION_HANDLER(LdaSmi, InterpreterAssembler) { // // Load constant literal at |idx| in the constant pool into the accumulator. IGNITION_HANDLER(LdaConstant, InterpreterAssembler) { - Node* constant = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Object> constant = LoadConstantPoolEntryAtOperandIndex(0); SetAccumulator(constant); Dispatch(); } @@ -161,7 +160,6 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler { void LdaGlobal(int slot_operand_index, int name_operand_index, TypeofMode typeof_mode) { TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); - Node* feedback_slot = BytecodeOperandIdx(slot_operand_index); AccessorAssembler accessor_asm(state()); ExitPoint exit_point(this, [=](Node* result) { @@ -169,17 +167,25 @@ class InterpreterLoadGlobalAssembler : public InterpreterAssembler { Dispatch(); }); + LazyNode<Smi> lazy_smi_slot = [=] { + return SmiTag(Signed(BytecodeOperandIdx(slot_operand_index))); + }; + + LazyNode<UintPtrT> lazy_slot = [=] { + return BytecodeOperandIdx(slot_operand_index); + }; + LazyNode<Context> lazy_context = [=] { return GetContext(); }; LazyNode<Name> lazy_name = [=] { - Node* name = LoadConstantPoolEntryAtOperandIndex(name_operand_index); - return CAST(name); + TNode<Name> name = + CAST(LoadConstantPoolEntryAtOperandIndex(name_operand_index)); + return name; }; - ParameterMode slot_mode = CodeStubAssembler::INTPTR_PARAMETERS; - accessor_asm.LoadGlobalIC(maybe_feedback_vector, feedback_slot, - lazy_context, lazy_name, typeof_mode, &exit_point, - slot_mode); + accessor_asm.LoadGlobalIC(maybe_feedback_vector, lazy_smi_slot, lazy_slot, + lazy_context, lazy_name, typeof_mode, + &exit_point); } }; @@ -213,9 +219,9 @@ IGNITION_HANDLER(StaGlobal, InterpreterAssembler) { TNode<Context> context = GetContext(); // Store the global via the StoreGlobalIC. - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Object> value = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(1); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(1)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> maybe_vector = LoadFeedbackVector(); @@ -240,9 +246,9 @@ IGNITION_HANDLER(StaGlobal, InterpreterAssembler) { // chain starting at |context| into the accumulator. IGNITION_HANDLER(LdaContextSlot, InterpreterAssembler) { TNode<Context> context = CAST(LoadRegisterAtOperandIndex(0)); - Node* slot_index = BytecodeOperandIdx(1); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(1)); TNode<Uint32T> depth = BytecodeOperandUImm(2); - Node* slot_context = GetContextAtDepth(context, depth); + TNode<Context> slot_context = GetContextAtDepth(context, depth); TNode<Object> result = LoadContextElement(slot_context, slot_index); SetAccumulator(result); Dispatch(); @@ -254,9 +260,9 @@ IGNITION_HANDLER(LdaContextSlot, InterpreterAssembler) { // chain starting at |context| into the accumulator. IGNITION_HANDLER(LdaImmutableContextSlot, InterpreterAssembler) { TNode<Context> context = CAST(LoadRegisterAtOperandIndex(0)); - Node* slot_index = BytecodeOperandIdx(1); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(1)); TNode<Uint32T> depth = BytecodeOperandUImm(2); - Node* slot_context = GetContextAtDepth(context, depth); + TNode<Context> slot_context = GetContextAtDepth(context, depth); TNode<Object> result = LoadContextElement(slot_context, slot_index); SetAccumulator(result); Dispatch(); @@ -266,7 +272,7 @@ IGNITION_HANDLER(LdaImmutableContextSlot, InterpreterAssembler) { // // Load the object in |slot_index| of the current context into the accumulator. IGNITION_HANDLER(LdaCurrentContextSlot, InterpreterAssembler) { - Node* slot_index = BytecodeOperandIdx(0); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(0)); TNode<Context> slot_context = GetContext(); TNode<Object> result = LoadContextElement(slot_context, slot_index); SetAccumulator(result); @@ -277,7 +283,7 @@ IGNITION_HANDLER(LdaCurrentContextSlot, InterpreterAssembler) { // // Load the object in |slot_index| of the current context into the accumulator. IGNITION_HANDLER(LdaImmutableCurrentContextSlot, InterpreterAssembler) { - Node* slot_index = BytecodeOperandIdx(0); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(0)); TNode<Context> slot_context = GetContext(); TNode<Object> result = LoadContextElement(slot_context, slot_index); SetAccumulator(result); @@ -291,9 +297,9 @@ IGNITION_HANDLER(LdaImmutableCurrentContextSlot, InterpreterAssembler) { IGNITION_HANDLER(StaContextSlot, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); TNode<Context> context = CAST(LoadRegisterAtOperandIndex(0)); - Node* slot_index = BytecodeOperandIdx(1); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(1)); TNode<Uint32T> depth = BytecodeOperandUImm(2); - Node* slot_context = GetContextAtDepth(context, depth); + TNode<Context> slot_context = GetContextAtDepth(context, depth); StoreContextElement(slot_context, slot_index, value); Dispatch(); } @@ -304,7 +310,7 @@ IGNITION_HANDLER(StaContextSlot, InterpreterAssembler) { // context. IGNITION_HANDLER(StaCurrentContextSlot, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* slot_index = BytecodeOperandIdx(0); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(0)); TNode<Context> slot_context = GetContext(); StoreContextElement(slot_context, slot_index, value); Dispatch(); @@ -315,7 +321,7 @@ IGNITION_HANDLER(StaCurrentContextSlot, InterpreterAssembler) { // Lookup the object with the name in constant pool entry |name_index| // dynamically. IGNITION_HANDLER(LdaLookupSlot, InterpreterAssembler) { - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Context> context = GetContext(); TNode<Object> result = CallRuntime(Runtime::kLoadLookupSlot, context, name); SetAccumulator(result); @@ -327,7 +333,7 @@ IGNITION_HANDLER(LdaLookupSlot, InterpreterAssembler) { // Lookup the object with the name in constant pool entry |name_index| // dynamically without causing a NoReferenceError. IGNITION_HANDLER(LdaLookupSlotInsideTypeof, InterpreterAssembler) { - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Context> context = GetContext(); TNode<Object> result = CallRuntime(Runtime::kLoadLookupSlotInsideTypeof, context, name); @@ -344,7 +350,7 @@ class InterpreterLookupContextSlotAssembler : public InterpreterAssembler { void LookupContextSlot(Runtime::FunctionId function_id) { TNode<Context> context = GetContext(); - Node* slot_index = BytecodeOperandIdx(1); + TNode<IntPtrT> slot_index = Signed(BytecodeOperandIdx(1)); TNode<Uint32T> depth = BytecodeOperandUImm(2); Label slowpath(this, Label::kDeferred); @@ -354,7 +360,7 @@ class InterpreterLookupContextSlotAssembler : public InterpreterAssembler { // Fast path does a normal load context. { - Node* slot_context = GetContextAtDepth(context, depth); + TNode<Context> slot_context = GetContextAtDepth(context, depth); TNode<Object> result = LoadContextElement(slot_context, slot_index); SetAccumulator(result); Dispatch(); @@ -363,7 +369,7 @@ class InterpreterLookupContextSlotAssembler : public InterpreterAssembler { // Slow path when we have to call out to the runtime. BIND(&slowpath); { - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Object> result = CallRuntime(function_id, context, name); SetAccumulator(result); Dispatch(); @@ -419,7 +425,7 @@ class InterpreterLookupGlobalAssembler : public InterpreterLoadGlobalAssembler { // Slow path when we have to call out to the runtime BIND(&slowpath); { - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Object> result = CallRuntime(function_id, context, name); SetAccumulator(result); Dispatch(); @@ -450,10 +456,10 @@ IGNITION_HANDLER(LdaLookupGlobalSlotInsideTypeof, // pool entry |name_index|. IGNITION_HANDLER(StaLookupSlot, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* name = LoadConstantPoolEntryAtOperandIndex(0); - Node* bytecode_flags = BytecodeOperandFlag(1); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); + TNode<Uint32T> bytecode_flags = BytecodeOperandFlag(1); TNode<Context> context = GetContext(); - Variable var_result(this, MachineRepresentation::kTagged); + TVARIABLE(Object, var_result); Label sloppy(this), strict(this), end(this); DCHECK_EQ(0, LanguageMode::kSloppy); @@ -467,8 +473,8 @@ IGNITION_HANDLER(StaLookupSlot, InterpreterAssembler) { { CSA_ASSERT(this, IsClearWord32<StoreLookupSlotFlags::LookupHoistingModeBit>( bytecode_flags)); - var_result.Bind( - CallRuntime(Runtime::kStoreLookupSlot_Strict, context, name, value)); + var_result = + CallRuntime(Runtime::kStoreLookupSlot_Strict, context, name, value); Goto(&end); } @@ -481,15 +487,15 @@ IGNITION_HANDLER(StaLookupSlot, InterpreterAssembler) { BIND(&hoisting); { - var_result.Bind(CallRuntime(Runtime::kStoreLookupSlot_SloppyHoisting, - context, name, value)); + var_result = CallRuntime(Runtime::kStoreLookupSlot_SloppyHoisting, + context, name, value); Goto(&end); } BIND(&ordinary); { - var_result.Bind( - CallRuntime(Runtime::kStoreLookupSlot_Sloppy, context, name, value)); + var_result = + CallRuntime(Runtime::kStoreLookupSlot_Sloppy, context, name, value); Goto(&end); } } @@ -507,24 +513,24 @@ IGNITION_HANDLER(StaLookupSlot, InterpreterAssembler) { // constant pool entry <name_index>. IGNITION_HANDLER(LdaNamedProperty, InterpreterAssembler) { TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* feedback_slot = BytecodeOperandIdx(2); - TNode<Smi> smi_slot = SmiTag(feedback_slot); + TNode<UintPtrT> feedback_slot = BytecodeOperandIdx(2); // Load receiver. TNode<Object> recv = LoadRegisterAtOperandIndex(0); // Load the name and context lazily. - LazyNode<Name> name = [=] { + LazyNode<Smi> lazy_smi_slot = [=] { return SmiTag(Signed(feedback_slot)); }; + LazyNode<Name> lazy_name = [=] { return CAST(LoadConstantPoolEntryAtOperandIndex(1)); }; - LazyNode<Context> context = [=] { return GetContext(); }; + LazyNode<Context> lazy_context = [=] { return GetContext(); }; Label done(this); - Variable var_result(this, MachineRepresentation::kTagged); + TVARIABLE(Object, var_result); ExitPoint exit_point(this, &done, &var_result); - AccessorAssembler::LazyLoadICParameters params(context, recv, name, smi_slot, - feedback_vector); + AccessorAssembler::LazyLoadICParameters params( + lazy_context, recv, lazy_name, lazy_smi_slot, feedback_vector); AccessorAssembler accessor_asm(state()); accessor_asm.LoadIC_BytecodeHandler(¶ms, &exit_point); @@ -540,7 +546,7 @@ IGNITION_HANDLER(LdaNamedProperty, InterpreterAssembler) { // Calls the GetProperty builtin for <object> and the key in the accumulator. IGNITION_HANDLER(LdaNamedPropertyNoFeedback, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); - Node* name = LoadConstantPoolEntryAtOperandIndex(1); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(1)); TNode<Context> context = GetContext(); TNode<Object> result = CallBuiltin(Builtins::kGetProperty, context, object, name); @@ -555,14 +561,14 @@ IGNITION_HANDLER(LdaNamedPropertyNoFeedback, InterpreterAssembler) { IGNITION_HANDLER(LdaKeyedProperty, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); TNode<Object> name = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(1); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(1)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_result, MachineRepresentation::kTagged); - var_result.Bind(CallBuiltin(Builtins::kKeyedLoadIC, context, object, name, - smi_slot, feedback_vector)); + TVARIABLE(Object, var_result); + var_result = CallBuiltin(Builtins::kKeyedLoadIC, context, object, name, + smi_slot, feedback_vector); SetAccumulator(var_result.value()); Dispatch(); } @@ -577,16 +583,16 @@ class InterpreterStoreNamedPropertyAssembler : public InterpreterAssembler { void StaNamedProperty(Callable ic, NamedPropertyType property_type) { TNode<Code> code_target = HeapConstant(ic.code()); TNode<Object> object = LoadRegisterAtOperandIndex(0); - Node* name = LoadConstantPoolEntryAtOperandIndex(1); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(1)); TNode<Object> value = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(2); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(2)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> maybe_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_result, MachineRepresentation::kTagged); - var_result.Bind(CallStub(ic.descriptor(), code_target, context, object, - name, value, smi_slot, maybe_vector)); + TVARIABLE(Object, var_result); + var_result = CallStub(ic.descriptor(), code_target, context, object, name, + value, smi_slot, maybe_vector); // To avoid special logic in the deoptimizer to re-materialize the value in // the accumulator, we overwrite the accumulator after the IC call. It // doesn't really matter what we write to the accumulator here, since we @@ -624,7 +630,7 @@ IGNITION_HANDLER(StaNamedOwnProperty, InterpreterStoreNamedPropertyAssembler) { IGNITION_HANDLER(StaNamedPropertyNoFeedback, InterpreterStoreNamedPropertyAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); - Node* name = LoadConstantPoolEntryAtOperandIndex(1); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(1)); TNode<Object> value = GetAccumulator(); TNode<Context> context = GetContext(); @@ -642,14 +648,14 @@ IGNITION_HANDLER(StaKeyedProperty, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); TNode<Object> name = LoadRegisterAtOperandIndex(1); TNode<Object> value = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(2); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(2)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> maybe_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_result, MachineRepresentation::kTagged); - var_result.Bind(CallBuiltin(Builtins::kKeyedStoreIC, context, object, name, - value, smi_slot, maybe_vector)); + TVARIABLE(Object, var_result); + var_result = CallBuiltin(Builtins::kKeyedStoreIC, context, object, name, + value, smi_slot, maybe_vector); // To avoid special logic in the deoptimizer to re-materialize the value in // the accumulator, we overwrite the accumulator after the IC call. It // doesn't really matter what we write to the accumulator here, since we @@ -667,14 +673,14 @@ IGNITION_HANDLER(StaInArrayLiteral, InterpreterAssembler) { TNode<Object> array = LoadRegisterAtOperandIndex(0); TNode<Object> index = LoadRegisterAtOperandIndex(1); TNode<Object> value = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(2); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(2)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_result, MachineRepresentation::kTagged); - var_result.Bind(CallBuiltin(Builtins::kStoreInArrayLiteralIC, context, array, - index, value, smi_slot, feedback_vector)); + TVARIABLE(Object, var_result); + var_result = CallBuiltin(Builtins::kStoreInArrayLiteralIC, context, array, + index, value, smi_slot, feedback_vector); // To avoid special logic in the deoptimizer to re-materialize the value in // the accumulator, we overwrite the accumulator after the IC call. It // doesn't really matter what we write to the accumulator here, since we @@ -696,8 +702,9 @@ IGNITION_HANDLER(StaDataPropertyInLiteral, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); TNode<Object> name = LoadRegisterAtOperandIndex(1); TNode<Object> value = GetAccumulator(); - TNode<Smi> flags = SmiFromInt32(BytecodeOperandFlag(2)); - TNode<Smi> vector_index = SmiTag(BytecodeOperandIdx(3)); + TNode<Smi> flags = + SmiFromInt32(UncheckedCast<Int32T>(BytecodeOperandFlag(2))); + TNode<Smi> vector_index = BytecodeOperandIdxSmi(3); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); @@ -708,7 +715,7 @@ IGNITION_HANDLER(StaDataPropertyInLiteral, InterpreterAssembler) { } IGNITION_HANDLER(CollectTypeProfile, InterpreterAssembler) { - Node* position = BytecodeOperandImmSmi(0); + TNode<Smi> position = BytecodeOperandImmSmi(0); TNode<Object> value = GetAccumulator(); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); @@ -725,10 +732,10 @@ IGNITION_HANDLER(CollectTypeProfile, InterpreterAssembler) { // identified by <cell_index>. <depth> is the depth of the current context // relative to the module context. IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) { - Node* cell_index = BytecodeOperandImmIntPtr(0); + TNode<IntPtrT> cell_index = BytecodeOperandImmIntPtr(0); TNode<Uint32T> depth = BytecodeOperandUImm(1); - Node* module_context = GetContextAtDepth(GetContext(), depth); + TNode<Context> module_context = GetContextAtDepth(GetContext(), depth); TNode<SourceTextModule> module = CAST(LoadContextElement(module_context, Context::EXTENSION_INDEX)); @@ -741,7 +748,7 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) { TNode<FixedArray> regular_exports = LoadObjectField<FixedArray>( module, SourceTextModule::kRegularExportsOffset); // The actual array index is (cell_index - 1). - TNode<WordT> export_index = IntPtrSub(cell_index, IntPtrConstant(1)); + TNode<IntPtrT> export_index = IntPtrSub(cell_index, IntPtrConstant(1)); TNode<Cell> cell = CAST(LoadFixedArrayElement(regular_exports, export_index)); SetAccumulator(LoadObjectField(cell, Cell::kValueOffset)); @@ -753,7 +760,7 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) { TNode<FixedArray> regular_imports = LoadObjectField<FixedArray>( module, SourceTextModule::kRegularImportsOffset); // The actual array index is (-cell_index - 1). - TNode<WordT> import_index = IntPtrSub(IntPtrConstant(-1), cell_index); + TNode<IntPtrT> import_index = IntPtrSub(IntPtrConstant(-1), cell_index); TNode<Cell> cell = CAST(LoadFixedArrayElement(regular_imports, import_index)); SetAccumulator(LoadObjectField(cell, Cell::kValueOffset)); @@ -770,10 +777,10 @@ IGNITION_HANDLER(LdaModuleVariable, InterpreterAssembler) { // <depth> is the depth of the current context relative to the module context. IGNITION_HANDLER(StaModuleVariable, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* cell_index = BytecodeOperandImmIntPtr(0); + TNode<IntPtrT> cell_index = BytecodeOperandImmIntPtr(0); TNode<Uint32T> depth = BytecodeOperandUImm(1); - Node* module_context = GetContextAtDepth(GetContext(), depth); + TNode<Context> module_context = GetContextAtDepth(GetContext(), depth); TNode<SourceTextModule> module = CAST(LoadContextElement(module_context, Context::EXTENSION_INDEX)); @@ -786,7 +793,7 @@ IGNITION_HANDLER(StaModuleVariable, InterpreterAssembler) { TNode<FixedArray> regular_exports = LoadObjectField<FixedArray>( module, SourceTextModule::kRegularExportsOffset); // The actual array index is (cell_index - 1). - TNode<WordT> export_index = IntPtrSub(cell_index, IntPtrConstant(1)); + TNode<IntPtrT> export_index = IntPtrSub(cell_index, IntPtrConstant(1)); TNode<Object> cell = LoadFixedArrayElement(regular_exports, export_index); StoreObjectField(cell, Cell::kValueOffset, value); Goto(&end); @@ -830,34 +837,35 @@ class InterpreterBinaryOpAssembler : public InterpreterAssembler { OperandScale operand_scale) : InterpreterAssembler(state, bytecode, operand_scale) {} - using BinaryOpGenerator = - Node* (BinaryOpAssembler::*)(Node* context, Node* left, Node* right, - Node* slot, Node* vector, bool lhs_is_smi); + using BinaryOpGenerator = TNode<Object> (BinaryOpAssembler::*)( + TNode<Context> context, TNode<Object> left, TNode<Object> right, + TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector, + bool rhs_known_smi); void BinaryOpWithFeedback(BinaryOpGenerator generator) { TNode<Object> lhs = LoadRegisterAtOperandIndex(0); TNode<Object> rhs = GetAccumulator(); TNode<Context> context = GetContext(); - Node* slot_index = BytecodeOperandIdx(1); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); BinaryOpAssembler binop_asm(state()); - Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index, - maybe_feedback_vector, false); + TNode<Object> result = (binop_asm.*generator)(context, lhs, rhs, slot_index, + maybe_feedback_vector, false); SetAccumulator(result); Dispatch(); } void BinaryOpSmiWithFeedback(BinaryOpGenerator generator) { TNode<Object> lhs = GetAccumulator(); - Node* rhs = BytecodeOperandImmSmi(0); + TNode<Smi> rhs = BytecodeOperandImmSmi(0); TNode<Context> context = GetContext(); - Node* slot_index = BytecodeOperandIdx(1); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); BinaryOpAssembler binop_asm(state()); - Node* result = (binop_asm.*generator)(context, lhs, rhs, slot_index, - maybe_feedback_vector, true); + TNode<Object> result = (binop_asm.*generator)(context, lhs, rhs, slot_index, + maybe_feedback_vector, true); SetAccumulator(result); Dispatch(); } @@ -959,15 +967,15 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { TNode<Object> left = LoadRegisterAtOperandIndex(0); TNode<Object> right = GetAccumulator(); TNode<Context> context = GetContext(); - Node* slot_index = BytecodeOperandIdx(1); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TVARIABLE(Smi, var_left_feedback); TVARIABLE(Smi, var_right_feedback); - VARIABLE(var_left_word32, MachineRepresentation::kWord32); - VARIABLE(var_right_word32, MachineRepresentation::kWord32); - VARIABLE(var_left_bigint, MachineRepresentation::kTagged, left); - VARIABLE(var_right_bigint, MachineRepresentation::kTagged); + TVARIABLE(Word32T, var_left_word32); + TVARIABLE(Word32T, var_right_word32); + TVARIABLE(Object, var_left_bigint, left); + TVARIABLE(Object, var_right_bigint); Label if_left_number(this), do_number_op(this); Label if_left_bigint(this), do_bigint_op(this); @@ -1007,14 +1015,16 @@ class InterpreterBitwiseBinaryOpAssembler : public InterpreterAssembler { void BitwiseBinaryOpWithSmi(Operation bitwise_op) { TNode<Object> left = GetAccumulator(); - Node* right = BytecodeOperandImmSmi(0); - Node* slot_index = BytecodeOperandIdx(1); + TNode<Smi> right = BytecodeOperandImmSmi(0); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); TVARIABLE(Smi, var_left_feedback); - VARIABLE(var_left_word32, MachineRepresentation::kWord32); - VARIABLE(var_left_bigint, MachineRepresentation::kTagged); + TVARIABLE(Word32T, var_left_word32); + // TODO(v8:6949): var_left_bigint should be BigInt, but before that we need + // to clean up TaggedToWord32OrBigIntWithFeedback and related methods. + TVARIABLE(Object, var_left_bigint); Label do_smi_op(this), if_bigint_mix(this); TaggedToWord32OrBigIntWithFeedback(context, left, &do_smi_op, @@ -1115,13 +1125,15 @@ IGNITION_HANDLER(BitwiseAndSmi, InterpreterBitwiseBinaryOpAssembler) { // Perform bitwise-not on the accumulator. IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) { TNode<Object> operand = GetAccumulator(); - Node* slot_index = BytecodeOperandIdx(0); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(0); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_word32, MachineRepresentation::kWord32); + TVARIABLE(Word32T, var_word32); TVARIABLE(Smi, var_feedback); - VARIABLE(var_bigint, MachineRepresentation::kTagged); + // TODO(v8:6949): var_bigint should be BigInt, but before that we need to + // clean up TaggedToWord32OrBigIntWithFeedback and related methods. + TVARIABLE(Object, var_bigint); Label if_number(this), if_bigint(this); TaggedToWord32OrBigIntWithFeedback(context, operand, &if_number, &var_word32, &if_bigint, &var_bigint, &var_feedback); @@ -1184,20 +1196,20 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { virtual ~UnaryNumericOpAssembler() = default; // Must return a tagged value. - virtual TNode<Number> SmiOp(TNode<Smi> smi_value, Variable* var_feedback, - Label* do_float_op, Variable* var_float) = 0; + virtual TNode<Number> SmiOp(TNode<Smi> smi_value, + TVariable<Smi>* var_feedback, Label* do_float_op, + TVariable<Float64T>* var_float) = 0; // Must return a Float64 value. - virtual Node* FloatOp(Node* float_value) = 0; + virtual TNode<Float64T> FloatOp(TNode<Float64T> float_value) = 0; // Must return a tagged value. - virtual Node* BigIntOp(Node* bigint_value) = 0; + virtual TNode<HeapObject> BigIntOp(TNode<HeapObject> bigint_value) = 0; void UnaryOpWithFeedback() { - VARIABLE(var_value, MachineRepresentation::kTagged, GetAccumulator()); - VARIABLE(var_result, MachineRepresentation::kTagged); - VARIABLE(var_float_value, MachineRepresentation::kFloat64); + TVARIABLE(Object, var_value, GetAccumulator()); + TVARIABLE(Object, var_result); + TVARIABLE(Float64T, var_float_value); TVARIABLE(Smi, var_feedback, SmiConstant(BinaryOperationFeedback::kNone)); - Variable* loop_vars[] = {&var_value, &var_feedback}; - Label start(this, arraysize(loop_vars), loop_vars), end(this); + Label start(this, {&var_value, &var_feedback}), end(this); Label do_float_op(this, &var_float_value); Goto(&start); // We might have to try again after ToNumeric conversion. @@ -1206,9 +1218,11 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { Label if_smi(this), if_heapnumber(this), if_oddball(this); Label if_bigint(this, Label::kDeferred); Label if_other(this, Label::kDeferred); - Node* value = var_value.value(); + TNode<Object> value = var_value.value(); GotoIf(TaggedIsSmi(value), &if_smi); - TNode<Map> map = LoadMap(value); + + TNode<HeapObject> value_heap_object = CAST(value); + TNode<Map> map = LoadMap(value_heap_object); GotoIf(IsHeapNumberMap(map), &if_heapnumber); TNode<Uint16T> instance_type = LoadMapInstanceType(map); GotoIf(IsBigIntInstanceType(instance_type), &if_bigint); @@ -1217,20 +1231,20 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { BIND(&if_smi); { - var_result.Bind( - SmiOp(CAST(value), &var_feedback, &do_float_op, &var_float_value)); + var_result = + SmiOp(CAST(value), &var_feedback, &do_float_op, &var_float_value); Goto(&end); } BIND(&if_heapnumber); { - var_float_value.Bind(LoadHeapNumberValue(value)); + var_float_value = LoadHeapNumberValue(value_heap_object); Goto(&do_float_op); } BIND(&if_bigint); { - var_result.Bind(BigIntOp(value)); + var_result = BigIntOp(value_heap_object); CombineFeedback(&var_feedback, BinaryOperationFeedback::kBigInt); Goto(&end); } @@ -1244,7 +1258,8 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { SmiConstant(BinaryOperationFeedback::kNone))); OverwriteFeedback(&var_feedback, BinaryOperationFeedback::kNumberOrOddball); - var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset)); + var_value = + LoadObjectField(value_heap_object, Oddball::kToNumberOffset); Goto(&start); } @@ -1256,8 +1271,8 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { CSA_ASSERT(this, SmiEqual(var_feedback.value(), SmiConstant(BinaryOperationFeedback::kNone))); OverwriteFeedback(&var_feedback, BinaryOperationFeedback::kAny); - var_value.Bind( - CallBuiltin(Builtins::kNonNumberToNumeric, GetContext(), value)); + var_value = CallBuiltin(Builtins::kNonNumberToNumeric, GetContext(), + value_heap_object); Goto(&start); } } @@ -1265,13 +1280,13 @@ class UnaryNumericOpAssembler : public InterpreterAssembler { BIND(&do_float_op); { CombineFeedback(&var_feedback, BinaryOperationFeedback::kNumber); - var_result.Bind( - AllocateHeapNumberWithValue(FloatOp(var_float_value.value()))); + var_result = + AllocateHeapNumberWithValue(FloatOp(var_float_value.value())); Goto(&end); } BIND(&end); - Node* slot_index = BytecodeOperandIdx(0); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(0); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); UpdateFeedback(var_feedback.value(), maybe_feedback_vector, slot_index); SetAccumulator(var_result.value()); @@ -1285,8 +1300,9 @@ class NegateAssemblerImpl : public UnaryNumericOpAssembler { OperandScale operand_scale) : UnaryNumericOpAssembler(state, bytecode, operand_scale) {} - TNode<Number> SmiOp(TNode<Smi> smi_value, Variable* var_feedback, - Label* do_float_op, Variable* var_float) override { + TNode<Number> SmiOp(TNode<Smi> smi_value, TVariable<Smi>* var_feedback, + Label* do_float_op, + TVariable<Float64T>* var_float) override { TVARIABLE(Number, var_result); Label if_zero(this), if_min_smi(this), end(this); // Return -0 if operand is 0. @@ -1306,18 +1322,20 @@ class NegateAssemblerImpl : public UnaryNumericOpAssembler { Goto(&end); BIND(&if_min_smi); - var_float->Bind(SmiToFloat64(smi_value)); + *var_float = SmiToFloat64(smi_value); Goto(do_float_op); BIND(&end); return var_result.value(); } - Node* FloatOp(Node* float_value) override { return Float64Neg(float_value); } + TNode<Float64T> FloatOp(TNode<Float64T> float_value) override { + return Float64Neg(float_value); + } - Node* BigIntOp(Node* bigint_value) override { - return CallRuntime(Runtime::kBigIntUnaryOp, GetContext(), bigint_value, - SmiConstant(Operation::kNegate)); + TNode<HeapObject> BigIntOp(TNode<HeapObject> bigint_value) override { + return CAST(CallRuntime(Runtime::kBigIntUnaryOp, GetContext(), bigint_value, + SmiConstant(Operation::kNegate))); } }; @@ -1381,8 +1399,9 @@ class IncDecAssembler : public UnaryNumericOpAssembler { return op_; } - TNode<Number> SmiOp(TNode<Smi> value, Variable* var_feedback, - Label* do_float_op, Variable* var_float) override { + TNode<Number> SmiOp(TNode<Smi> value, TVariable<Smi>* var_feedback, + Label* do_float_op, + TVariable<Float64T>* var_float) override { TNode<Smi> one = SmiConstant(1); Label if_overflow(this), if_notoverflow(this); TNode<Smi> result = op() == Operation::kIncrement @@ -1392,7 +1411,7 @@ class IncDecAssembler : public UnaryNumericOpAssembler { BIND(&if_overflow); { - var_float->Bind(SmiToFloat64(value)); + *var_float = SmiToFloat64(value); Goto(do_float_op); } @@ -1401,15 +1420,15 @@ class IncDecAssembler : public UnaryNumericOpAssembler { return result; } - Node* FloatOp(Node* float_value) override { + TNode<Float64T> FloatOp(TNode<Float64T> float_value) override { return op() == Operation::kIncrement ? Float64Add(float_value, Float64Constant(1.0)) : Float64Sub(float_value, Float64Constant(1.0)); } - Node* BigIntOp(Node* bigint_value) override { - return CallRuntime(Runtime::kBigIntUnaryOp, GetContext(), bigint_value, - SmiConstant(op())); + TNode<HeapObject> BigIntOp(TNode<HeapObject> bigint_value) override { + return CAST(CallRuntime(Runtime::kBigIntUnaryOp, GetContext(), bigint_value, + SmiConstant(op()))); } void IncWithFeedback() { @@ -1442,17 +1461,17 @@ IGNITION_HANDLER(Dec, IncDecAssembler) { DecWithFeedback(); } // accumulator to a boolean value if required. IGNITION_HANDLER(ToBooleanLogicalNot, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Variable result(this, MachineRepresentation::kTagged); + TVARIABLE(Oddball, result); Label if_true(this), if_false(this), end(this); BranchIfToBooleanIsTrue(value, &if_true, &if_false); BIND(&if_true); { - result.Bind(FalseConstant()); + result = FalseConstant(); Goto(&end); } BIND(&if_false); { - result.Bind(TrueConstant()); + result = TrueConstant(); Goto(&end); } BIND(&end); @@ -1466,20 +1485,20 @@ IGNITION_HANDLER(ToBooleanLogicalNot, InterpreterAssembler) { // value. IGNITION_HANDLER(LogicalNot, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Variable result(this, MachineRepresentation::kTagged); + TVARIABLE(Oddball, result); Label if_true(this), if_false(this), end(this); TNode<Oddball> true_value = TrueConstant(); TNode<Oddball> false_value = FalseConstant(); Branch(TaggedEqual(value, true_value), &if_true, &if_false); BIND(&if_true); { - result.Bind(false_value); + result = false_value; Goto(&end); } BIND(&if_false); { CSA_ASSERT(this, TaggedEqual(value, false_value)); - result.Bind(true_value); + result = true_value; Goto(&end); } BIND(&end); @@ -1493,7 +1512,7 @@ IGNITION_HANDLER(LogicalNot, InterpreterAssembler) { // object in the accumulator. IGNITION_HANDLER(TypeOf, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* result = Typeof(value); + TNode<String> result = Typeof(value); SetAccumulator(result); Dispatch(); } @@ -1550,7 +1569,7 @@ class InterpreterJSCallAssembler : public InterpreterAssembler { void JSCall(ConvertReceiverMode receiver_mode) { TNode<Object> function = LoadRegisterAtOperandIndex(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); - Node* slot_id = BytecodeOperandIdx(3); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(3); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); @@ -1583,7 +1602,7 @@ class InterpreterJSCallAssembler : public InterpreterAssembler { kFirstArgumentOperandIndex + kRecieverAndArgOperandCount; TNode<Object> function = LoadRegisterAtOperandIndex(0); - Node* slot_id = BytecodeOperandIdx(kSlotOperandIndex); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(kSlotOperandIndex); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); @@ -1598,26 +1617,20 @@ class InterpreterJSCallAssembler : public InterpreterAssembler { case 1: CallJSAndDispatch( function, context, Int32Constant(arg_count), receiver_mode, - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex))); + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex)); break; case 2: CallJSAndDispatch( function, context, Int32Constant(arg_count), receiver_mode, - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex)), - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 1))); + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex), + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 1)); break; case 3: CallJSAndDispatch( function, context, Int32Constant(arg_count), receiver_mode, - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex)), - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 1)), - static_cast<Node*>( - LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 2))); + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex), + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 1), + LoadRegisterAtOperandIndex(kFirstArgumentOperandIndex + 2)); break; default: UNREACHABLE(); @@ -1676,7 +1689,7 @@ IGNITION_HANDLER(CallNoFeedback, InterpreterJSCallAssembler) { // register |first_arg| and |arg_count| arguments in subsequent // registers. IGNITION_HANDLER(CallRuntime, InterpreterAssembler) { - Node* function_id = BytecodeOperandRuntimeId(0); + TNode<Uint32T> function_id = BytecodeOperandRuntimeId(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); TNode<Context> context = GetContext(); Node* result = CallRuntimeN(function_id, context, args); @@ -1690,10 +1703,11 @@ IGNITION_HANDLER(CallRuntime, InterpreterAssembler) { // |function_id| with the first argument in |first_arg| and |arg_count| // arguments in subsequent registers. IGNITION_HANDLER(InvokeIntrinsic, InterpreterAssembler) { - Node* function_id = BytecodeOperandIntrinsicId(0); + TNode<Uint32T> function_id = BytecodeOperandIntrinsicId(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); TNode<Context> context = GetContext(); - Node* result = GenerateInvokeIntrinsic(this, function_id, context, args); + TNode<Object> result = + GenerateInvokeIntrinsic(this, function_id, context, args); SetAccumulator(result); Dispatch(); } @@ -1706,13 +1720,13 @@ IGNITION_HANDLER(InvokeIntrinsic, InterpreterAssembler) { // <first_return + 1> IGNITION_HANDLER(CallRuntimeForPair, InterpreterAssembler) { // Call the runtime function. - Node* function_id = BytecodeOperandRuntimeId(0); + TNode<Uint32T> function_id = BytecodeOperandRuntimeId(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); TNode<Context> context = GetContext(); Node* result_pair = CallRuntimeN(function_id, context, args, 2); // Store the results in <first_return> and <first_return + 1> - Node* result0 = Projection(0, result_pair); - Node* result1 = Projection(1, result_pair); + TNode<Object> result0 = CAST(Projection(0, result_pair)); + TNode<Object> result1 = CAST(Projection(1, result_pair)); StoreRegisterPairAtOperandIndex(result0, result1, 3); Dispatch(); } @@ -1722,12 +1736,12 @@ IGNITION_HANDLER(CallRuntimeForPair, InterpreterAssembler) { // Call the JS runtime function that has the |context_index| with the receiver // in register |receiver| and |arg_count| arguments in subsequent registers. IGNITION_HANDLER(CallJSRuntime, InterpreterAssembler) { - Node* context_index = BytecodeOperandNativeContextIndex(0); + TNode<IntPtrT> context_index = Signed(BytecodeOperandNativeContextIndex(0)); RegListNodePair args = GetRegisterListAtOperandIndex(1); // Get the function to call from the native context. TNode<Context> context = GetContext(); - TNode<Context> native_context = LoadNativeContext(context); + TNode<NativeContext> native_context = LoadNativeContext(context); TNode<Object> function = LoadContextElement(native_context, context_index); // Call the function. @@ -1744,7 +1758,7 @@ IGNITION_HANDLER(CallJSRuntime, InterpreterAssembler) { IGNITION_HANDLER(CallWithSpread, InterpreterAssembler) { TNode<Object> callable = LoadRegisterAtOperandIndex(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); - Node* slot_id = BytecodeOperandIdx(3); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(3); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); @@ -1763,11 +1777,11 @@ IGNITION_HANDLER(ConstructWithSpread, InterpreterAssembler) { TNode<Object> new_target = GetAccumulator(); TNode<Object> constructor = LoadRegisterAtOperandIndex(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); - Node* slot_id = BytecodeOperandIdx(3); - TNode<HeapObject> feedback_vector = LoadFeedbackVector(); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(3); + TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - Node* result = ConstructWithSpread(constructor, context, new_target, args, - slot_id, feedback_vector); + TNode<Object> result = ConstructWithSpread( + constructor, context, new_target, args, slot_id, maybe_feedback_vector); SetAccumulator(result); Dispatch(); } @@ -1782,11 +1796,11 @@ IGNITION_HANDLER(Construct, InterpreterAssembler) { TNode<Object> new_target = GetAccumulator(); TNode<Object> constructor = LoadRegisterAtOperandIndex(0); RegListNodePair args = GetRegisterListAtOperandIndex(1); - Node* slot_id = BytecodeOperandIdx(3); - TNode<HeapObject> feedback_vector = LoadFeedbackVector(); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(3); + TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - Node* result = Construct(constructor, context, new_target, args, slot_id, - feedback_vector); + TNode<Object> result = Construct(constructor, context, new_target, args, + slot_id, maybe_feedback_vector); SetAccumulator(result); Dispatch(); } @@ -1802,8 +1816,8 @@ class InterpreterCompareOpAssembler : public InterpreterAssembler { TNode<Object> rhs = GetAccumulator(); TNode<Context> context = GetContext(); - Variable var_type_feedback(this, MachineRepresentation::kTagged); - Node* result; + TVARIABLE(Smi, var_type_feedback); + TNode<Oddball> result; switch (compare_op) { case Operation::kEqual: result = Equal(lhs, rhs, context, &var_type_feedback); @@ -1822,7 +1836,7 @@ class InterpreterCompareOpAssembler : public InterpreterAssembler { UNREACHABLE(); } - Node* slot_index = BytecodeOperandIdx(1); + TNode<UintPtrT> slot_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot_index); @@ -1894,14 +1908,14 @@ IGNITION_HANDLER(TestReferenceEqual, InterpreterAssembler) { IGNITION_HANDLER(TestIn, InterpreterAssembler) { TNode<Object> name = LoadRegisterAtOperandIndex(0); TNode<Object> object = GetAccumulator(); - Node* raw_slot = BytecodeOperandIdx(1); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(1)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - VARIABLE(var_result, MachineRepresentation::kTagged); - var_result.Bind(CallBuiltin(Builtins::kKeyedHasIC, context, object, name, - smi_slot, feedback_vector)); + TVARIABLE(Object, var_result); + var_result = CallBuiltin(Builtins::kKeyedHasIC, context, object, name, + smi_slot, feedback_vector); SetAccumulator(var_result.value()); Dispatch(); } @@ -1913,15 +1927,16 @@ IGNITION_HANDLER(TestIn, InterpreterAssembler) { IGNITION_HANDLER(TestInstanceOf, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); TNode<Object> callable = GetAccumulator(); - Node* slot_id = BytecodeOperandIdx(1); - TNode<HeapObject> feedback_vector = LoadFeedbackVector(); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(1); + TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); Label feedback_done(this); - GotoIf(IsUndefined(feedback_vector), &feedback_done); + GotoIf(IsUndefined(maybe_feedback_vector), &feedback_done); // Record feedback for the {callable} in the {feedback_vector}. - CollectCallableFeedback(callable, context, feedback_vector, slot_id); + CollectCallableFeedback(callable, context, CAST(maybe_feedback_vector), + slot_id); Goto(&feedback_done); BIND(&feedback_done); @@ -1980,7 +1995,7 @@ IGNITION_HANDLER(TestUndefined, InterpreterAssembler) { // by |literal_flag|. IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) { TNode<Object> object = GetAccumulator(); - Node* literal_flag = BytecodeOperandFlag(0); + TNode<Uint32T> literal_flag = BytecodeOperandFlag(0); #define MAKE_LABEL(name, lower_case) Label if_##lower_case(this); TYPEOF_LITERAL_LIST(MAKE_LABEL) @@ -2097,7 +2112,7 @@ IGNITION_HANDLER(TestTypeOf, InterpreterAssembler) { // // Jump by the number of bytes represented by the immediate operand |imm|. IGNITION_HANDLER(Jump, InterpreterAssembler) { - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); Jump(relative_jump); } @@ -2117,7 +2132,7 @@ IGNITION_HANDLER(JumpConstant, InterpreterAssembler) { // will misbehave if passed arbitrary input values. IGNITION_HANDLER(JumpIfTrue, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); CSA_ASSERT(this, IsBoolean(CAST(accumulator))); JumpIfTaggedEqual(accumulator, TrueConstant(), relative_jump); } @@ -2141,7 +2156,7 @@ IGNITION_HANDLER(JumpIfTrueConstant, InterpreterAssembler) { // will misbehave if passed arbitrary input values. IGNITION_HANDLER(JumpIfFalse, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); CSA_ASSERT(this, IsBoolean(CAST(accumulator))); JumpIfTaggedEqual(accumulator, FalseConstant(), relative_jump); } @@ -2164,7 +2179,7 @@ IGNITION_HANDLER(JumpIfFalseConstant, InterpreterAssembler) { // referenced by the accumulator is true when the object is cast to boolean. IGNITION_HANDLER(JumpIfToBooleanTrue, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); Label if_true(this), if_false(this); BranchIfToBooleanIsTrue(value, &if_true, &if_false); BIND(&if_true); @@ -2195,7 +2210,7 @@ IGNITION_HANDLER(JumpIfToBooleanTrueConstant, InterpreterAssembler) { // referenced by the accumulator is false when the object is cast to boolean. IGNITION_HANDLER(JumpIfToBooleanFalse, InterpreterAssembler) { TNode<Object> value = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); Label if_true(this), if_false(this); BranchIfToBooleanIsTrue(value, &if_true, &if_false); BIND(&if_true); @@ -2226,7 +2241,7 @@ IGNITION_HANDLER(JumpIfToBooleanFalseConstant, InterpreterAssembler) { // referenced by the accumulator is the null constant. IGNITION_HANDLER(JumpIfNull, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); JumpIfTaggedEqual(accumulator, NullConstant(), relative_jump); } @@ -2246,7 +2261,7 @@ IGNITION_HANDLER(JumpIfNullConstant, InterpreterAssembler) { // referenced by the accumulator is not the null constant. IGNITION_HANDLER(JumpIfNotNull, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); JumpIfTaggedNotEqual(accumulator, NullConstant(), relative_jump); } @@ -2266,7 +2281,7 @@ IGNITION_HANDLER(JumpIfNotNullConstant, InterpreterAssembler) { // referenced by the accumulator is the undefined constant. IGNITION_HANDLER(JumpIfUndefined, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); JumpIfTaggedEqual(accumulator, UndefinedConstant(), relative_jump); } @@ -2286,7 +2301,7 @@ IGNITION_HANDLER(JumpIfUndefinedConstant, InterpreterAssembler) { // referenced by the accumulator is not the undefined constant. IGNITION_HANDLER(JumpIfNotUndefined, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); JumpIfTaggedNotEqual(accumulator, UndefinedConstant(), relative_jump); } @@ -2314,7 +2329,7 @@ IGNITION_HANDLER(JumpIfUndefinedOrNull, InterpreterAssembler) { Dispatch(); BIND(&do_jump); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); Jump(relative_jump); } @@ -2342,7 +2357,7 @@ IGNITION_HANDLER(JumpIfUndefinedOrNullConstant, InterpreterAssembler) { // referenced by the accumulator is a JSReceiver. IGNITION_HANDLER(JumpIfJSReceiver, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); - Node* relative_jump = BytecodeOperandUImmWord(0); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); Label if_object(this), if_notobject(this, Label::kDeferred), if_notsmi(this); Branch(TaggedIsSmi(accumulator), &if_notobject, &if_notsmi); @@ -2383,9 +2398,9 @@ IGNITION_HANDLER(JumpIfJSReceiverConstant, InterpreterAssembler) { // performs a loop nesting check and potentially triggers OSR in case the // current OSR level matches (or exceeds) the specified |loop_depth|. IGNITION_HANDLER(JumpLoop, InterpreterAssembler) { - Node* relative_jump = BytecodeOperandUImmWord(0); - Node* loop_depth = BytecodeOperandImm(1); - Node* osr_level = LoadOsrNestingLevel(); + TNode<IntPtrT> relative_jump = Signed(BytecodeOperandUImmWord(0)); + TNode<Int32T> loop_depth = BytecodeOperandImm(1); + TNode<Int8T> osr_level = LoadOsrNestingLevel(); // Check if OSR points at the given {loop_depth} are armed by comparing it to // the current {osr_level} loaded from the header of the BytecodeArray. @@ -2415,9 +2430,9 @@ IGNITION_HANDLER(JumpLoop, InterpreterAssembler) { // next bytecode. IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { TNode<Object> acc = GetAccumulator(); - Node* table_start = BytecodeOperandIdx(0); - Node* table_length = BytecodeOperandUImmWord(1); - Node* case_value_base = BytecodeOperandImmIntPtr(2); + TNode<UintPtrT> table_start = BytecodeOperandIdx(0); + TNode<UintPtrT> table_length = BytecodeOperandUImmWord(1); + TNode<IntPtrT> case_value_base = BytecodeOperandImmIntPtr(2); Label fall_through(this); @@ -2426,7 +2441,7 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { // accumulator values. CSA_ASSERT(this, TaggedIsSmi(acc)); - TNode<WordT> case_value = IntPtrSub(SmiUntag(CAST(acc)), case_value_base); + TNode<IntPtrT> case_value = IntPtrSub(SmiUntag(CAST(acc)), case_value_base); GotoIf(IntPtrLessThan(case_value, IntPtrConstant(0)), &fall_through); GotoIf(IntPtrGreaterThanOrEqual(case_value, table_length), &fall_through); TNode<WordT> entry = IntPtrAdd(table_start, case_value); @@ -2442,17 +2457,18 @@ IGNITION_HANDLER(SwitchOnSmiNoFeedback, InterpreterAssembler) { // Creates a regular expression literal for literal index <literal_idx> with // <flags> and the pattern in <pattern_idx>. IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) { - Node* pattern = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Object> pattern = LoadConstantPoolEntryAtOperandIndex(0); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* slot_id = BytecodeOperandIdx(1); - TNode<Smi> flags = SmiFromInt32(BytecodeOperandFlag(2)); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(1); + TNode<Smi> flags = + SmiFromInt32(UncheckedCast<Int32T>(BytecodeOperandFlag(2))); TNode<Context> context = GetContext(); - VARIABLE(result, MachineRepresentation::kTagged); + TVARIABLE(JSRegExp, result); ConstructorBuiltinsAssembler constructor_assembler(state()); - result.Bind(constructor_assembler.EmitCreateRegExpLiteral( - feedback_vector, slot_id, pattern, flags, context)); + result = constructor_assembler.EmitCreateRegExpLiteral( + feedback_vector, slot_id, pattern, flags, context); SetAccumulator(result.value()); Dispatch(); } @@ -2463,9 +2479,9 @@ IGNITION_HANDLER(CreateRegExpLiteral, InterpreterAssembler) { // CreateArrayLiteral flags <flags> and constant elements in <element_idx>. IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* slot_id = BytecodeOperandIdx(1); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(1); TNode<Context> context = GetContext(); - Node* bytecode_flags = BytecodeOperandFlag(2); + TNode<Uint32T> bytecode_flags = BytecodeOperandFlag(2); Label fast_shallow_clone(this), call_runtime(this, Label::kDeferred); // No feedback, so handle it as a slow case. @@ -2478,8 +2494,8 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { BIND(&fast_shallow_clone); { ConstructorBuiltinsAssembler constructor_assembler(state()); - Node* result = constructor_assembler.EmitCreateShallowArrayLiteral( - feedback_vector, slot_id, context, &call_runtime, + TNode<JSArray> result = constructor_assembler.EmitCreateShallowArrayLiteral( + CAST(feedback_vector), slot_id, context, &call_runtime, TRACK_ALLOCATION_SITE); SetAccumulator(result); Dispatch(); @@ -2487,14 +2503,14 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { BIND(&call_runtime); { - TNode<WordT> flags_raw = + TNode<UintPtrT> flags_raw = DecodeWordFromWord32<CreateArrayLiteralFlags::FlagsBits>( bytecode_flags); TNode<Smi> flags = SmiTag(Signed(flags_raw)); - Node* constant_elements = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Object> constant_elements = LoadConstantPoolEntryAtOperandIndex(0); TNode<Object> result = CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector, - SmiTag(slot_id), constant_elements, flags); + SmiTag(Signed(slot_id)), constant_elements, flags); SetAccumulator(result); Dispatch(); } @@ -2504,26 +2520,26 @@ IGNITION_HANDLER(CreateArrayLiteral, InterpreterAssembler) { // // Creates an empty JSArray literal for literal index <literal_idx>. IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) { - TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* slot_id = BytecodeOperandIdx(0); + TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(0); TNode<Context> context = GetContext(); Label no_feedback(this, Label::kDeferred), end(this); - VARIABLE(result, MachineRepresentation::kTagged); - GotoIf(IsUndefined(feedback_vector), &no_feedback); + TVARIABLE(JSArray, result); + GotoIf(IsUndefined(maybe_feedback_vector), &no_feedback); ConstructorBuiltinsAssembler constructor_assembler(state()); - result.Bind(constructor_assembler.EmitCreateEmptyArrayLiteral( - feedback_vector, slot_id, context)); + result = constructor_assembler.EmitCreateEmptyArrayLiteral( + CAST(maybe_feedback_vector), slot_id, context); Goto(&end); BIND(&no_feedback); { TNode<Map> array_map = LoadJSArrayElementsMap(GetInitialFastElementsKind(), LoadNativeContext(context)); - result.Bind(AllocateJSArray(GetInitialFastElementsKind(), array_map, - SmiConstant(0), SmiConstant(0), nullptr, - ParameterMode::SMI_PARAMETERS)); + result = + AllocateJSArray(GetInitialFastElementsKind(), array_map, SmiConstant(0), + SmiConstant(0), {}, ParameterMode::SMI_PARAMETERS); Goto(&end); } @@ -2551,8 +2567,8 @@ IGNITION_HANDLER(CreateArrayFromIterable, InterpreterAssembler) { // CreateObjectLiteralFlags <flags> and constant elements in <element_idx>. IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* slot_id = BytecodeOperandIdx(1); - Node* bytecode_flags = BytecodeOperandFlag(2); + TNode<UintPtrT> slot_id = BytecodeOperandIdx(1); + TNode<Uint32T> bytecode_flags = BytecodeOperandFlag(2); Label if_fast_clone(this), if_not_fast_clone(this, Label::kDeferred); // No feedback, so handle it as a slow case. @@ -2567,8 +2583,9 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { { // If we can do a fast clone do the fast-path in CreateShallowObjectLiteral. ConstructorBuiltinsAssembler constructor_assembler(state()); - Node* result = constructor_assembler.EmitCreateShallowObjectLiteral( - feedback_vector, slot_id, &if_not_fast_clone); + TNode<HeapObject> result = + constructor_assembler.EmitCreateShallowObjectLiteral( + CAST(feedback_vector), slot_id, &if_not_fast_clone); SetAccumulator(result); Dispatch(); } @@ -2576,18 +2593,18 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { BIND(&if_not_fast_clone); { // If we can't do a fast clone, call into the runtime. - Node* object_boilerplate_description = - LoadConstantPoolEntryAtOperandIndex(0); + TNode<ObjectBoilerplateDescription> object_boilerplate_description = + CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Context> context = GetContext(); - TNode<WordT> flags_raw = + TNode<UintPtrT> flags_raw = DecodeWordFromWord32<CreateObjectLiteralFlags::FlagsBits>( bytecode_flags); TNode<Smi> flags = SmiTag(Signed(flags_raw)); - TNode<Object> result = - CallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector, - SmiTag(slot_id), object_boilerplate_description, flags); + TNode<Object> result = CallRuntime(Runtime::kCreateObjectLiteral, context, + feedback_vector, SmiTag(Signed(slot_id)), + object_boilerplate_description, flags); SetAccumulator(result); // TODO(klaasb) build a single dispatch once the call is inlined Dispatch(); @@ -2600,7 +2617,8 @@ IGNITION_HANDLER(CreateObjectLiteral, InterpreterAssembler) { IGNITION_HANDLER(CreateEmptyObjectLiteral, InterpreterAssembler) { TNode<Context> context = GetContext(); ConstructorBuiltinsAssembler constructor_assembler(state()); - Node* result = constructor_assembler.EmitCreateEmptyObjectLiteral(context); + TNode<JSObject> result = + constructor_assembler.EmitCreateEmptyObjectLiteral(context); SetAccumulator(result); Dispatch(); } @@ -2611,18 +2629,18 @@ IGNITION_HANDLER(CreateEmptyObjectLiteral, InterpreterAssembler) { // {source}, converting getters into data properties. IGNITION_HANDLER(CloneObject, InterpreterAssembler) { TNode<Object> source = LoadRegisterAtOperandIndex(0); - Node* bytecode_flags = BytecodeOperandFlag(1); - TNode<WordT> raw_flags = + TNode<Uint32T> bytecode_flags = BytecodeOperandFlag(1); + TNode<UintPtrT> raw_flags = DecodeWordFromWord32<CreateObjectLiteralFlags::FlagsBits>(bytecode_flags); TNode<Smi> smi_flags = SmiTag(Signed(raw_flags)); - Node* raw_slot = BytecodeOperandIdx(2); + TNode<IntPtrT> raw_slot = Signed(BytecodeOperandIdx(2)); TNode<Smi> smi_slot = SmiTag(raw_slot); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); TNode<Context> context = GetContext(); - Variable var_result(this, MachineRepresentation::kTagged); - var_result.Bind(CallBuiltin(Builtins::kCloneObjectIC, context, source, - smi_flags, smi_slot, maybe_feedback_vector)); + TVARIABLE(Object, var_result); + var_result = CallBuiltin(Builtins::kCloneObjectIC, context, source, smi_flags, + smi_slot, maybe_feedback_vector); SetAccumulator(var_result.value()); Dispatch(); } @@ -2633,14 +2651,14 @@ IGNITION_HANDLER(CloneObject, InterpreterAssembler) { // accumulator, creating and caching the site object on-demand as per the // specification. IGNITION_HANDLER(GetTemplateObject, InterpreterAssembler) { - TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* slot = BytecodeOperandIdx(1); + TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); + TNode<UintPtrT> slot = BytecodeOperandIdx(1); Label call_runtime(this, Label::kDeferred); - GotoIf(IsUndefined(feedback_vector), &call_runtime); + GotoIf(IsUndefined(maybe_feedback_vector), &call_runtime); TNode<Object> cached_value = - CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS)); + CAST(LoadFeedbackVectorSlot(CAST(maybe_feedback_vector), slot)); GotoIf(TaggedEqual(cached_value, SmiConstant(0)), &call_runtime); @@ -2649,8 +2667,8 @@ IGNITION_HANDLER(GetTemplateObject, InterpreterAssembler) { BIND(&call_runtime); { - Node* description = LoadConstantPoolEntryAtOperandIndex(0); - TNode<Smi> slot_smi = SmiTag(slot); + TNode<Object> description = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Smi> slot_smi = SmiTag(Signed(slot)); TNode<JSFunction> closure = CAST(LoadRegister(Register::function_closure())); TNode<SharedFunctionInfo> shared_info = LoadObjectField<SharedFunctionInfo>( @@ -2660,8 +2678,8 @@ IGNITION_HANDLER(GetTemplateObject, InterpreterAssembler) { description, shared_info, slot_smi); Label end(this); - GotoIf(IsUndefined(feedback_vector), &end); - StoreFeedbackVectorSlot(feedback_vector, slot, result); + GotoIf(IsUndefined(maybe_feedback_vector), &end); + StoreFeedbackVectorSlot(CAST(maybe_feedback_vector), slot, result); Goto(&end); Bind(&end); @@ -2675,10 +2693,10 @@ IGNITION_HANDLER(GetTemplateObject, InterpreterAssembler) { // Creates a new closure for SharedFunctionInfo at position |index| in the // constant pool and with pretenuring controlled by |flags|. IGNITION_HANDLER(CreateClosure, InterpreterAssembler) { - Node* shared = LoadConstantPoolEntryAtOperandIndex(0); - Node* flags = BytecodeOperandFlag(2); + TNode<Object> shared = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Uint32T> flags = BytecodeOperandFlag(2); TNode<Context> context = GetContext(); - Node* slot = BytecodeOperandIdx(1); + TNode<UintPtrT> slot = BytecodeOperandIdx(1); Label if_undefined(this); TNode<ClosureFeedbackCellArray> feedback_cell_array = @@ -2727,7 +2745,7 @@ IGNITION_HANDLER(CreateClosure, InterpreterAssembler) { // // Creates a new block context with the scope info constant at |index|. IGNITION_HANDLER(CreateBlockContext, InterpreterAssembler) { - Node* scope_info = LoadConstantPoolEntryAtOperandIndex(0); + TNode<ScopeInfo> scope_info = CAST(LoadConstantPoolEntryAtOperandIndex(0)); TNode<Context> context = GetContext(); SetAccumulator(CallRuntime(Runtime::kPushBlockContext, context, scope_info)); Dispatch(); @@ -2739,7 +2757,7 @@ IGNITION_HANDLER(CreateBlockContext, InterpreterAssembler) { // and the ScopeInfo at |scope_info_idx|. IGNITION_HANDLER(CreateCatchContext, InterpreterAssembler) { TNode<Object> exception = LoadRegisterAtOperandIndex(0); - Node* scope_info = LoadConstantPoolEntryAtOperandIndex(1); + TNode<ScopeInfo> scope_info = CAST(LoadConstantPoolEntryAtOperandIndex(1)); TNode<Context> context = GetContext(); SetAccumulator( CallRuntime(Runtime::kPushCatchContext, context, exception, scope_info)); @@ -2750,8 +2768,8 @@ IGNITION_HANDLER(CreateCatchContext, InterpreterAssembler) { // // Creates a new context with number of |slots| for the function closure. IGNITION_HANDLER(CreateFunctionContext, InterpreterAssembler) { - Node* scope_info_idx = BytecodeOperandIdx(0); - Node* scope_info = LoadConstantPoolEntry(scope_info_idx); + TNode<UintPtrT> scope_info_idx = BytecodeOperandIdx(0); + TNode<ScopeInfo> scope_info = CAST(LoadConstantPoolEntry(scope_info_idx)); TNode<Uint32T> slots = BytecodeOperandUImm(1); TNode<Context> context = GetContext(); ConstructorBuiltinsAssembler constructor_assembler(state()); @@ -2764,8 +2782,8 @@ IGNITION_HANDLER(CreateFunctionContext, InterpreterAssembler) { // // Creates a new context with number of |slots| for an eval closure. IGNITION_HANDLER(CreateEvalContext, InterpreterAssembler) { - Node* scope_info_idx = BytecodeOperandIdx(0); - Node* scope_info = LoadConstantPoolEntry(scope_info_idx); + TNode<UintPtrT> scope_info_idx = BytecodeOperandIdx(0); + TNode<ScopeInfo> scope_info = CAST(LoadConstantPoolEntry(scope_info_idx)); TNode<Uint32T> slots = BytecodeOperandUImm(1); TNode<Context> context = GetContext(); ConstructorBuiltinsAssembler constructor_assembler(state()); @@ -2780,7 +2798,7 @@ IGNITION_HANDLER(CreateEvalContext, InterpreterAssembler) { // with-statement with the object in |register|. IGNITION_HANDLER(CreateWithContext, InterpreterAssembler) { TNode<Object> object = LoadRegisterAtOperandIndex(0); - Node* scope_info = LoadConstantPoolEntryAtOperandIndex(1); + TNode<ScopeInfo> scope_info = CAST(LoadConstantPoolEntryAtOperandIndex(1)); TNode<Context> context = GetContext(); SetAccumulator( CallRuntime(Runtime::kPushWithContext, context, object, scope_info)); @@ -2802,8 +2820,8 @@ IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) { // duplicate parameters. TNode<SharedFunctionInfo> shared_info = LoadObjectField<SharedFunctionInfo>( closure, JSFunction::kSharedFunctionInfoOffset); - Node* flags = LoadObjectField(shared_info, SharedFunctionInfo::kFlagsOffset, - MachineType::Uint32()); + TNode<Uint32T> flags = + LoadObjectField<Uint32T>(shared_info, SharedFunctionInfo::kFlagsOffset); TNode<BoolT> has_duplicate_parameters = IsSetWord32<SharedFunctionInfo::HasDuplicateParametersBit>(flags); Branch(has_duplicate_parameters, &if_duplicate_parameters, @@ -2812,7 +2830,7 @@ IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) { BIND(&if_not_duplicate_parameters); { ArgumentsBuiltinsAssembler constructor_assembler(state()); - Node* result = + TNode<JSObject> result = constructor_assembler.EmitFastNewSloppyArguments(context, closure); SetAccumulator(result); Dispatch(); @@ -2832,9 +2850,9 @@ IGNITION_HANDLER(CreateMappedArguments, InterpreterAssembler) { // Creates a new unmapped arguments object. IGNITION_HANDLER(CreateUnmappedArguments, InterpreterAssembler) { TNode<Context> context = GetContext(); - TNode<Object> closure = LoadRegister(Register::function_closure()); + TNode<JSFunction> closure = CAST(LoadRegister(Register::function_closure())); ArgumentsBuiltinsAssembler builtins_assembler(state()); - Node* result = + TNode<JSObject> result = builtins_assembler.EmitFastNewStrictArguments(context, closure); SetAccumulator(result); Dispatch(); @@ -2844,10 +2862,11 @@ IGNITION_HANDLER(CreateUnmappedArguments, InterpreterAssembler) { // // Creates a new rest parameter array. IGNITION_HANDLER(CreateRestParameter, InterpreterAssembler) { - TNode<Object> closure = LoadRegister(Register::function_closure()); + TNode<JSFunction> closure = CAST(LoadRegister(Register::function_closure())); TNode<Context> context = GetContext(); ArgumentsBuiltinsAssembler builtins_assembler(state()); - Node* result = builtins_assembler.EmitFastNewRestParameter(context, closure); + TNode<JSObject> result = + builtins_assembler.EmitFastNewRestParameter(context, closure); SetAccumulator(result); Dispatch(); } @@ -2868,7 +2887,7 @@ IGNITION_HANDLER(StackCheck, InterpreterAssembler) { IGNITION_HANDLER(SetPendingMessage, InterpreterAssembler) { TNode<ExternalReference> pending_message = ExternalConstant( ExternalReference::address_of_pending_message_obj(isolate())); - Node* previous_message = Load(MachineType::TaggedPointer(), pending_message); + TNode<HeapObject> previous_message = Load<HeapObject>(pending_message); TNode<Object> new_message = GetAccumulator(); StoreFullTaggedNoWriteBarrier(pending_message, new_message); SetAccumulator(previous_message); @@ -2903,8 +2922,8 @@ IGNITION_HANDLER(ReThrow, InterpreterAssembler) { // // Aborts execution (via a call to the runtime function). IGNITION_HANDLER(Abort, InterpreterAssembler) { - Node* reason = BytecodeOperandIdx(0); - CallRuntime(Runtime::kAbort, NoContextConstant(), SmiTag(reason)); + TNode<UintPtrT> reason = BytecodeOperandIdx(0); + CallRuntime(Runtime::kAbort, NoContextConstant(), SmiTag(Signed(reason))); Unreachable(); } @@ -2929,7 +2948,7 @@ IGNITION_HANDLER(ThrowReferenceErrorIfHole, InterpreterAssembler) { BIND(&throw_error); { - Node* name = LoadConstantPoolEntryAtOperandIndex(0); + TNode<Name> name = CAST(LoadConstantPoolEntryAtOperandIndex(0)); CallRuntime(Runtime::kThrowAccessedUninitializedVariable, GetContext(), name); // We shouldn't ever return from a throw. @@ -2995,7 +3014,7 @@ IGNITION_HANDLER(Debugger, InterpreterAssembler) { TNode<Object> accumulator = GetAccumulator(); \ TNode<Object> result_pair = \ CallRuntime(Runtime::kDebugBreakOnBytecode, context, accumulator); \ - Node* return_value = Projection(0, result_pair); \ + TNode<Object> return_value = CAST(Projection(0, result_pair)); \ TNode<IntPtrT> original_bytecode = SmiUntag(Projection(1, result_pair)); \ MaybeDropFrames(context); \ SetAccumulator(return_value); \ @@ -3010,7 +3029,7 @@ DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK) // coverage. IGNITION_HANDLER(IncBlockCounter, InterpreterAssembler) { TNode<Object> closure = LoadRegister(Register::function_closure()); - Node* coverage_array_slot = BytecodeOperandIdxSmi(0); + TNode<Smi> coverage_array_slot = BytecodeOperandIdxSmi(0); TNode<Context> context = GetContext(); CallBuiltin(Builtins::kIncBlockCounter, context, closure, @@ -3025,11 +3044,11 @@ IGNITION_HANDLER(IncBlockCounter, InterpreterAssembler) { // map of the |receiver| if it has a usable enum cache or a fixed array // with the keys to enumerate in the accumulator. IGNITION_HANDLER(ForInEnumerate, InterpreterAssembler) { - TNode<Object> receiver = LoadRegisterAtOperandIndex(0); + TNode<HeapObject> receiver = CAST(LoadRegisterAtOperandIndex(0)); TNode<Context> context = GetContext(); Label if_empty(this), if_runtime(this, Label::kDeferred); - Node* receiver_map = CheckEnumCache(receiver, &if_empty, &if_runtime); + TNode<Map> receiver_map = CheckEnumCache(receiver, &if_empty, &if_runtime); SetAccumulator(receiver_map); Dispatch(); @@ -3060,7 +3079,7 @@ IGNITION_HANDLER(ForInEnumerate, InterpreterAssembler) { IGNITION_HANDLER(ForInPrepare, InterpreterAssembler) { // The {enumerator} is either a Map or a FixedArray. TNode<HeapObject> enumerator = CAST(GetAccumulator()); - Node* vector_index = BytecodeOperandIdx(1); + TNode<UintPtrT> vector_index = BytecodeOperandIdx(1); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); // Check if we're using an enum cache. @@ -3091,8 +3110,8 @@ IGNITION_HANDLER(ForInPrepare, InterpreterAssembler) { UpdateFeedback(feedback, maybe_feedback_vector, vector_index); // Construct the cache info triple. - Node* cache_type = enumerator; - Node* cache_array = enum_keys; + TNode<Map> cache_type = map_enumerator; + TNode<FixedArray> cache_array = enum_keys; TNode<Smi> cache_length = SmiTag(Signed(enum_length)); StoreRegisterTripleAtOperandIndex(cache_type, cache_array, cache_length, 0); Dispatch(); @@ -3108,8 +3127,8 @@ IGNITION_HANDLER(ForInPrepare, InterpreterAssembler) { vector_index); // Construct the cache info triple. - Node* cache_type = array_enumerator; - Node* cache_array = array_enumerator; + TNode<FixedArray> cache_type = array_enumerator; + TNode<FixedArray> cache_array = array_enumerator; TNode<Smi> cache_length = LoadFixedArrayBaseLength(array_enumerator); StoreRegisterTripleAtOperandIndex(cache_type, cache_array, cache_length, 0); Dispatch(); @@ -3125,7 +3144,7 @@ IGNITION_HANDLER(ForInNext, InterpreterAssembler) { TNode<Object> cache_type; TNode<Object> cache_array; std::tie(cache_type, cache_array) = LoadRegisterPairAtOperandIndex(2); - Node* vector_index = BytecodeOperandIdx(3); + TNode<UintPtrT> vector_index = BytecodeOperandIdx(3); TNode<HeapObject> maybe_feedback_vector = LoadFeedbackVector(); // Load the next key from the enumeration array. @@ -3195,21 +3214,22 @@ IGNITION_HANDLER(ForInStep, InterpreterAssembler) { // GetIterator <object> // -// Retrieves the object[Symbol.iterator] method and stores the result -// in the accumulator -// TODO(swapnilgaikwad): Extend the functionality of the bytecode to call -// iterator method for an object +// Retrieves the object[Symbol.iterator] method, calls it and stores +// the result in the accumulator. If the result is not a JSReceiver, throws +// SymbolIteratorInvalid runtime exception. IGNITION_HANDLER(GetIterator, InterpreterAssembler) { TNode<Object> receiver = LoadRegisterAtOperandIndex(0); TNode<Context> context = GetContext(); TNode<HeapObject> feedback_vector = LoadFeedbackVector(); - Node* feedback_slot = BytecodeOperandIdx(1); - TNode<Smi> smi_slot = SmiTag(feedback_slot); + TNode<IntPtrT> load_feedback_slot = Signed(BytecodeOperandIdx(1)); + TNode<IntPtrT> call_feedback_slot = Signed(BytecodeOperandIdx(2)); + TNode<Smi> load_slot_smi = SmiTag(load_feedback_slot); + TNode<Smi> call_slot_smi = SmiTag(call_feedback_slot); - TNode<Object> result = + TNode<Object> iterator = CallBuiltin(Builtins::kGetIteratorWithFeedback, context, receiver, - smi_slot, feedback_vector); - SetAccumulator(result); + load_slot_smi, call_slot_smi, feedback_vector); + SetAccumulator(iterator); Dispatch(); } @@ -3249,7 +3269,7 @@ IGNITION_HANDLER(SuspendGenerator, InterpreterAssembler) { TNode<JSFunction> closure = CAST(LoadRegister(Register::function_closure())); TNode<Context> context = GetContext(); RegListNodePair registers = GetRegisterListAtOperandIndex(1); - Node* suspend_id = BytecodeOperandUImmSmi(3); + TNode<Smi> suspend_id = BytecodeOperandUImmSmi(3); TNode<SharedFunctionInfo> shared = CAST(LoadObjectField(closure, JSFunction::kSharedFunctionInfoOffset)); @@ -3297,10 +3317,10 @@ IGNITION_HANDLER(SwitchOnGeneratorState, InterpreterAssembler) { CAST(LoadObjectField(generator, JSGeneratorObject::kContextOffset)); SetContext(context); - Node* table_start = BytecodeOperandIdx(1); + TNode<UintPtrT> table_start = BytecodeOperandIdx(1); // TODO(leszeks): table_length is only used for a CSA_ASSERT, we don't // actually need it otherwise. - Node* table_length = BytecodeOperandUImmWord(2); + TNode<UintPtrT> table_length = BytecodeOperandUImmWord(2); // The state must be a Smi. CSA_ASSERT(this, TaggedIsSmi(state)); @@ -3350,14 +3370,15 @@ IGNITION_HANDLER(ResumeGenerator, InterpreterAssembler) { } // namespace -Handle<Code> GenerateBytecodeHandler(Isolate* isolate, Bytecode bytecode, +Handle<Code> GenerateBytecodeHandler(Isolate* isolate, const char* debug_name, + Bytecode bytecode, OperandScale operand_scale, int builtin_index, const AssemblerOptions& options) { Zone zone(isolate->allocator(), ZONE_NAME); compiler::CodeAssemblerState state( isolate, &zone, InterpreterDispatchDescriptor{}, Code::BYTECODE_HANDLER, - Bytecodes::ToString(bytecode), + debug_name, FLAG_untrusted_code_mitigations ? PoisoningMitigationLevel::kPoisonCriticalOnly : PoisoningMitigationLevel::kDontPoison, @@ -3377,7 +3398,7 @@ Handle<Code> GenerateBytecodeHandler(Isolate* isolate, Bytecode bytecode, #ifdef ENABLE_DISASSEMBLER if (FLAG_trace_ignition_codegen) { StdoutStream os; - code->Disassemble(Bytecodes::ToString(bytecode), os); + code->Disassemble(Bytecodes::ToString(bytecode), os, isolate); os << std::flush; } #endif // ENABLE_DISASSEMBLER diff --git a/deps/v8/src/interpreter/interpreter-generator.h b/deps/v8/src/interpreter/interpreter-generator.h index a41e89f250d094..263f02ba39ef3d 100644 --- a/deps/v8/src/interpreter/interpreter-generator.h +++ b/deps/v8/src/interpreter/interpreter-generator.h @@ -15,7 +15,9 @@ struct AssemblerOptions; namespace interpreter { -extern Handle<Code> GenerateBytecodeHandler(Isolate* isolate, Bytecode bytecode, +extern Handle<Code> GenerateBytecodeHandler(Isolate* isolate, + const char* debug_name, + Bytecode bytecode, OperandScale operand_scale, int builtin_index, const AssemblerOptions& options); diff --git a/deps/v8/src/interpreter/interpreter-intrinsics-generator.cc b/deps/v8/src/interpreter/interpreter-intrinsics-generator.cc index a329e7189f4c64..f5307762f78848 100644 --- a/deps/v8/src/interpreter/interpreter-intrinsics-generator.cc +++ b/deps/v8/src/interpreter/interpreter-intrinsics-generator.cc @@ -21,8 +21,6 @@ namespace internal { namespace interpreter { using compiler::Node; -template <typename T> -using TNode = compiler::TNode<T>; class IntrinsicsGenerator { public: @@ -31,8 +29,9 @@ class IntrinsicsGenerator { zone_(assembler->zone()), assembler_(assembler) {} - Node* InvokeIntrinsic(Node* function_id, Node* context, - const InterpreterAssembler::RegListNodePair& args); + TNode<Object> InvokeIntrinsic( + TNode<Uint32T> function_id, TNode<Context> context, + const InterpreterAssembler::RegListNodePair& args); private: enum InstanceTypeCompareMode { @@ -40,17 +39,20 @@ class IntrinsicsGenerator { kInstanceTypeGreaterThanOrEqual }; - Node* IsInstanceType(Node* input, int type); - Node* CompareInstanceType(Node* map, int type, InstanceTypeCompareMode mode); - Node* IntrinsicAsStubCall(const InterpreterAssembler::RegListNodePair& args, - Node* context, Callable const& callable); - Node* IntrinsicAsBuiltinCall( - const InterpreterAssembler::RegListNodePair& args, Node* context, + TNode<Oddball> IsInstanceType(TNode<Object> input, int type); + TNode<BoolT> CompareInstanceType(TNode<HeapObject> map, int type, + InstanceTypeCompareMode mode); + TNode<Object> IntrinsicAsStubCall( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context, + Callable const& callable); + TNode<Object> IntrinsicAsBuiltinCall( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context, Builtins::Name name); - void AbortIfArgCountMismatch(int expected, compiler::TNode<Word32T> actual); + void AbortIfArgCountMismatch(int expected, TNode<Word32T> actual); -#define DECLARE_INTRINSIC_HELPER(name, lower_case, count) \ - Node* name(const InterpreterAssembler::RegListNodePair& args, Node* context); +#define DECLARE_INTRINSIC_HELPER(name, lower_case, count) \ + TNode<Object> name(const InterpreterAssembler::RegListNodePair& args, \ + TNode<Context> context); INTRINSICS_LIST(DECLARE_INTRINSIC_HELPER) #undef DECLARE_INTRINSIC_HELPER @@ -65,21 +67,20 @@ class IntrinsicsGenerator { DISALLOW_COPY_AND_ASSIGN(IntrinsicsGenerator); }; -Node* GenerateInvokeIntrinsic( - InterpreterAssembler* assembler, Node* function_id, Node* context, - const InterpreterAssembler::RegListNodePair& args) { +TNode<Object> GenerateInvokeIntrinsic( + InterpreterAssembler* assembler, TNode<Uint32T> function_id, + TNode<Context> context, const InterpreterAssembler::RegListNodePair& args) { IntrinsicsGenerator generator(assembler); return generator.InvokeIntrinsic(function_id, context, args); } #define __ assembler_-> -Node* IntrinsicsGenerator::InvokeIntrinsic( - Node* function_id, Node* context, +TNode<Object> IntrinsicsGenerator::InvokeIntrinsic( + TNode<Uint32T> function_id, TNode<Context> context, const InterpreterAssembler::RegListNodePair& args) { InterpreterAssembler::Label abort(assembler_), end(assembler_); - InterpreterAssembler::Variable result(assembler_, - MachineRepresentation::kTagged); + InterpreterAssembler::TVariable<Object> result(assembler_); #define MAKE_LABEL(name, lower_case, count) \ InterpreterAssembler::Label lower_case(assembler_); @@ -102,9 +103,9 @@ Node* IntrinsicsGenerator::InvokeIntrinsic( if (FLAG_debug_code && expected_arg_count >= 0) { \ AbortIfArgCountMismatch(expected_arg_count, args.reg_count()); \ } \ - Node* value = name(args, context); \ + TNode<Object> value = name(args, context); \ if (value) { \ - result.Bind(value); \ + result = value; \ __ Goto(&end); \ } \ } @@ -114,7 +115,7 @@ Node* IntrinsicsGenerator::InvokeIntrinsic( __ BIND(&abort); { __ Abort(AbortReason::kUnexpectedFunctionIDForInvokeIntrinsic); - result.Bind(__ UndefinedConstant()); + result = __ UndefinedConstant(); __ Goto(&end); } @@ -122,8 +123,8 @@ Node* IntrinsicsGenerator::InvokeIntrinsic( return result.value(); } -Node* IntrinsicsGenerator::CompareInstanceType(Node* object, int type, - InstanceTypeCompareMode mode) { +TNode<BoolT> IntrinsicsGenerator::CompareInstanceType( + TNode<HeapObject> object, int type, InstanceTypeCompareMode mode) { TNode<Uint16T> instance_type = __ LoadInstanceType(object); if (mode == kInstanceTypeEqual) { @@ -134,39 +135,42 @@ Node* IntrinsicsGenerator::CompareInstanceType(Node* object, int type, } } -Node* IntrinsicsGenerator::IsInstanceType(Node* input, int type) { +TNode<Oddball> IntrinsicsGenerator::IsInstanceType(TNode<Object> input, + int type) { TNode<Oddball> result = __ Select<Oddball>( __ TaggedIsSmi(input), [=] { return __ FalseConstant(); }, [=] { return __ SelectBooleanConstant( - CompareInstanceType(input, type, kInstanceTypeEqual)); + CompareInstanceType(__ CAST(input), type, kInstanceTypeEqual)); }); return result; } -Node* IntrinsicsGenerator::IsJSReceiver( - const InterpreterAssembler::RegListNodePair& args, Node* context) { - Node* input = __ LoadRegisterFromRegisterList(args, 0); +TNode<Object> IntrinsicsGenerator::IsJSReceiver( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { + TNode<Object> input = __ LoadRegisterFromRegisterList(args, 0); TNode<Oddball> result = __ Select<Oddball>( __ TaggedIsSmi(input), [=] { return __ FalseConstant(); }, - [=] { return __ SelectBooleanConstant(__ IsJSReceiver(input)); }); + [=] { + return __ SelectBooleanConstant(__ IsJSReceiver(__ CAST(input))); + }); return result; } -Node* IntrinsicsGenerator::IsArray( - const InterpreterAssembler::RegListNodePair& args, Node* context) { - Node* input = __ LoadRegisterFromRegisterList(args, 0); +TNode<Object> IntrinsicsGenerator::IsArray( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { + TNode<Object> input = __ LoadRegisterFromRegisterList(args, 0); return IsInstanceType(input, JS_ARRAY_TYPE); } -Node* IntrinsicsGenerator::IsSmi( - const InterpreterAssembler::RegListNodePair& args, Node* context) { - Node* input = __ LoadRegisterFromRegisterList(args, 0); +TNode<Object> IntrinsicsGenerator::IsSmi( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { + TNode<Object> input = __ LoadRegisterFromRegisterList(args, 0); return __ SelectBooleanConstant(__ TaggedIsSmi(input)); } -Node* IntrinsicsGenerator::IntrinsicAsStubCall( - const InterpreterAssembler::RegListNodePair& args, Node* context, +TNode<Object> IntrinsicsGenerator::IntrinsicAsStubCall( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context, Callable const& callable) { int param_count = callable.descriptor().GetParameterCount(); int input_count = param_count + 2; // +2 for target and context @@ -177,59 +181,60 @@ Node* IntrinsicsGenerator::IntrinsicAsStubCall( stub_args[index++] = __ LoadRegisterFromRegisterList(args, i); } stub_args[index++] = context; - return __ CallStubN(StubCallMode::kCallCodeObject, callable.descriptor(), 1, - input_count, stub_args); + return __ CAST(__ CallStubN(StubCallMode::kCallCodeObject, + callable.descriptor(), 1, input_count, + stub_args)); } -Node* IntrinsicsGenerator::IntrinsicAsBuiltinCall( - const InterpreterAssembler::RegListNodePair& args, Node* context, +TNode<Object> IntrinsicsGenerator::IntrinsicAsBuiltinCall( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context, Builtins::Name name) { Callable callable = Builtins::CallableFor(isolate_, name); return IntrinsicAsStubCall(args, context, callable); } -Node* IntrinsicsGenerator::CopyDataProperties( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::CopyDataProperties( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kCopyDataProperties)); } -Node* IntrinsicsGenerator::CreateIterResultObject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::CreateIterResultObject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kCreateIterResultObject)); } -Node* IntrinsicsGenerator::HasProperty( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::HasProperty( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kHasProperty)); } -Node* IntrinsicsGenerator::ToStringRT( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::ToStringRT( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kToString)); } -Node* IntrinsicsGenerator::ToLength( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::ToLength( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kToLength)); } -Node* IntrinsicsGenerator::ToObject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::ToObject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsStubCall( args, context, Builtins::CallableFor(isolate(), Builtins::kToObject)); } -Node* IntrinsicsGenerator::Call( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::Call( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { // First argument register contains the function target. - Node* function = __ LoadRegisterFromRegisterList(args, 0); + TNode<Object> function = __ LoadRegisterFromRegisterList(args, 0); // The arguments for the target function are from the second runtime call // argument. @@ -249,26 +254,25 @@ Node* IntrinsicsGenerator::Call( __ CallJSAndDispatch(function, context, target_args, ConvertReceiverMode::kAny); - return nullptr; // We never return from the CallJSAndDispatch above. + return TNode<Object>(); // We never return from the CallJSAndDispatch above. } -Node* IntrinsicsGenerator::CreateAsyncFromSyncIterator( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::CreateAsyncFromSyncIterator( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { InterpreterAssembler::Label not_receiver( assembler_, InterpreterAssembler::Label::kDeferred); InterpreterAssembler::Label done(assembler_); - InterpreterAssembler::Variable return_value(assembler_, - MachineRepresentation::kTagged); + InterpreterAssembler::TVariable<Object> return_value(assembler_); - Node* sync_iterator = __ LoadRegisterFromRegisterList(args, 0); + TNode<Object> sync_iterator = __ LoadRegisterFromRegisterList(args, 0); __ GotoIf(__ TaggedIsSmi(sync_iterator), ¬_receiver); - __ GotoIfNot(__ IsJSReceiver(sync_iterator), ¬_receiver); + __ GotoIfNot(__ IsJSReceiver(__ CAST(sync_iterator)), ¬_receiver); TNode<Object> const next = __ GetProperty(context, sync_iterator, factory()->next_string()); - TNode<Context> const native_context = __ LoadNativeContext(context); + TNode<NativeContext> const native_context = __ LoadNativeContext(context); TNode<Map> const map = __ CAST(__ LoadContextElement( native_context, Context::ASYNC_FROM_SYNC_ITERATOR_MAP_INDEX)); TNode<JSObject> const iterator = __ AllocateJSObjectFromMap(map); @@ -278,13 +282,13 @@ Node* IntrinsicsGenerator::CreateAsyncFromSyncIterator( __ StoreObjectFieldNoWriteBarrier(iterator, JSAsyncFromSyncIterator::kNextOffset, next); - return_value.Bind(iterator); + return_value = iterator; __ Goto(&done); __ BIND(¬_receiver); { - return_value.Bind( - __ CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context)); + return_value = + __ CallRuntime(Runtime::kThrowSymbolIteratorInvalid, context); // Unreachable due to the Throw in runtime call. __ Goto(&done); @@ -294,104 +298,105 @@ Node* IntrinsicsGenerator::CreateAsyncFromSyncIterator( return return_value.value(); } -Node* IntrinsicsGenerator::CreateJSGeneratorObject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::CreateJSGeneratorObject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kCreateGeneratorObject); } -Node* IntrinsicsGenerator::GeneratorGetResumeMode( - const InterpreterAssembler::RegListNodePair& args, Node* context) { - Node* generator = __ LoadRegisterFromRegisterList(args, 0); +TNode<Object> IntrinsicsGenerator::GeneratorGetResumeMode( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { + TNode<JSGeneratorObject> generator = + __ CAST(__ LoadRegisterFromRegisterList(args, 0)); TNode<Object> const value = __ LoadObjectField(generator, JSGeneratorObject::kResumeModeOffset); return value; } -Node* IntrinsicsGenerator::GeneratorClose( - const InterpreterAssembler::RegListNodePair& args, Node* context) { - Node* generator = __ LoadRegisterFromRegisterList(args, 0); +TNode<Object> IntrinsicsGenerator::GeneratorClose( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { + TNode<JSGeneratorObject> generator = + __ CAST(__ LoadRegisterFromRegisterList(args, 0)); __ StoreObjectFieldNoWriteBarrier( generator, JSGeneratorObject::kContinuationOffset, __ SmiConstant(JSGeneratorObject::kGeneratorClosed)); return __ UndefinedConstant(); } -Node* IntrinsicsGenerator::GetImportMetaObject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::GetImportMetaObject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { TNode<Context> const module_context = __ LoadModuleContext(context); TNode<HeapObject> const module = __ CAST(__ LoadContextElement(module_context, Context::EXTENSION_INDEX)); TNode<Object> const import_meta = __ LoadObjectField(module, SourceTextModule::kImportMetaOffset); - InterpreterAssembler::Variable return_value(assembler_, - MachineRepresentation::kTagged); - return_value.Bind(import_meta); + InterpreterAssembler::TVariable<Object> return_value(assembler_); + return_value = import_meta; InterpreterAssembler::Label end(assembler_); __ GotoIfNot(__ IsTheHole(import_meta), &end); - return_value.Bind(__ CallRuntime(Runtime::kGetImportMetaObject, context)); + return_value = __ CallRuntime(Runtime::kGetImportMetaObject, context); __ Goto(&end); __ BIND(&end); return return_value.value(); } -Node* IntrinsicsGenerator::AsyncFunctionAwaitCaught( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncFunctionAwaitCaught( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncFunctionAwaitCaught); } -Node* IntrinsicsGenerator::AsyncFunctionAwaitUncaught( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncFunctionAwaitUncaught( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncFunctionAwaitUncaught); } -Node* IntrinsicsGenerator::AsyncFunctionEnter( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncFunctionEnter( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncFunctionEnter); } -Node* IntrinsicsGenerator::AsyncFunctionReject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncFunctionReject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncFunctionReject); } -Node* IntrinsicsGenerator::AsyncFunctionResolve( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncFunctionResolve( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncFunctionResolve); } -Node* IntrinsicsGenerator::AsyncGeneratorAwaitCaught( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncGeneratorAwaitCaught( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorAwaitCaught); } -Node* IntrinsicsGenerator::AsyncGeneratorAwaitUncaught( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncGeneratorAwaitUncaught( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorAwaitUncaught); } -Node* IntrinsicsGenerator::AsyncGeneratorReject( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncGeneratorReject( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorReject); } -Node* IntrinsicsGenerator::AsyncGeneratorResolve( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncGeneratorResolve( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorResolve); } -Node* IntrinsicsGenerator::AsyncGeneratorYield( - const InterpreterAssembler::RegListNodePair& args, Node* context) { +TNode<Object> IntrinsicsGenerator::AsyncGeneratorYield( + const InterpreterAssembler::RegListNodePair& args, TNode<Context> context) { return IntrinsicAsBuiltinCall(args, context, Builtins::kAsyncGeneratorYield); } diff --git a/deps/v8/src/interpreter/interpreter-intrinsics-generator.h b/deps/v8/src/interpreter/interpreter-intrinsics-generator.h index fd4e167ed0f943..f0c22e7a592516 100644 --- a/deps/v8/src/interpreter/interpreter-intrinsics-generator.h +++ b/deps/v8/src/interpreter/interpreter-intrinsics-generator.h @@ -16,9 +16,9 @@ class Node; namespace interpreter { -extern compiler::Node* GenerateInvokeIntrinsic( - InterpreterAssembler* assembler, compiler::Node* function_id, - compiler::Node* context, const InterpreterAssembler::RegListNodePair& args); +extern TNode<Object> GenerateInvokeIntrinsic( + InterpreterAssembler* assembler, TNode<Uint32T> function_id, + TNode<Context> context, const InterpreterAssembler::RegListNodePair& args); } // namespace interpreter } // namespace internal diff --git a/deps/v8/src/interpreter/interpreter.cc b/deps/v8/src/interpreter/interpreter.cc index 482ffb7459043b..52ce4a140866bb 100644 --- a/deps/v8/src/interpreter/interpreter.cc +++ b/deps/v8/src/interpreter/interpreter.cc @@ -269,7 +269,7 @@ std::unique_ptr<UnoptimizedCompilationJob> Interpreter::NewCompilationJob( ParseInfo* parse_info, FunctionLiteral* literal, AccountingAllocator* allocator, std::vector<FunctionLiteral*>* eager_inner_literals) { - return base::make_unique<InterpreterCompilationJob>( + return std::make_unique<InterpreterCompilationJob>( parse_info, literal, allocator, eager_inner_literals); } @@ -277,8 +277,8 @@ std::unique_ptr<UnoptimizedCompilationJob> Interpreter::NewSourcePositionCollectionJob( ParseInfo* parse_info, FunctionLiteral* literal, Handle<BytecodeArray> existing_bytecode, AccountingAllocator* allocator) { - auto job = base::make_unique<InterpreterCompilationJob>(parse_info, literal, - allocator, nullptr); + auto job = std::make_unique<InterpreterCompilationJob>(parse_info, literal, + allocator, nullptr); job->compilation_info()->SetBytecodeArray(existing_bytecode); return std::unique_ptr<UnoptimizedCompilationJob> { static_cast<UnoptimizedCompilationJob*>(job.release()) }; } diff --git a/deps/v8/src/json/json-parser.cc b/deps/v8/src/json/json-parser.cc index e49775704db86c..3a790c210dcae9 100644 --- a/deps/v8/src/json/json-parser.cc +++ b/deps/v8/src/json/json-parser.cc @@ -394,7 +394,8 @@ Handle<Map> ParentOfDescriptorOwner(Isolate* isolate, Handle<Map> maybe_root, DCHECK_EQ(0, maybe_root->NumberOfOwnDescriptors()); return maybe_root; } - return handle(source->FindFieldOwner(isolate, descriptor - 1), isolate); + return handle(source->FindFieldOwner(isolate, InternalIndex(descriptor - 1)), + isolate); } } // namespace @@ -461,10 +462,11 @@ Handle<Object> JsonParser<Char>::BuildJsonObject( if (property.string.is_index()) continue; Handle<String> expected; Handle<Map> target; + InternalIndex descriptor_index(descriptor); if (descriptor < feedback_descriptors) { - expected = handle( - String::cast(feedback->instance_descriptors().GetKey(descriptor)), - isolate_); + expected = handle(String::cast(feedback->instance_descriptors().GetKey( + descriptor_index)), + isolate_); } else { DisallowHeapAllocation no_gc; TransitionsAccessor transitions(isolate(), *map, &no_gc); @@ -495,7 +497,7 @@ Handle<Object> JsonParser<Char>::BuildJsonObject( Handle<Object> value = property.value; PropertyDetails details = - target->instance_descriptors().GetDetails(descriptor); + target->instance_descriptors().GetDetails(descriptor_index); Representation expected_representation = details.representation(); if (!value->FitsRepresentation(expected_representation)) { @@ -507,23 +509,24 @@ Handle<Object> JsonParser<Char>::BuildJsonObject( } Handle<FieldType> value_type = value->OptimalType(isolate(), representation); - Map::GeneralizeField(isolate(), target, descriptor, details.constness(), - representation, value_type); + Map::GeneralizeField(isolate(), target, descriptor_index, + details.constness(), representation, value_type); } else if (expected_representation.IsHeapObject() && !target->instance_descriptors() - .GetFieldType(descriptor) + .GetFieldType(descriptor_index) .NowContains(value)) { Handle<FieldType> value_type = value->OptimalType(isolate(), expected_representation); - Map::GeneralizeField(isolate(), target, descriptor, details.constness(), - expected_representation, value_type); + Map::GeneralizeField(isolate(), target, descriptor_index, + details.constness(), expected_representation, + value_type); } else if (!FLAG_unbox_double_fields && expected_representation.IsDouble() && value->IsSmi()) { new_mutable_double++; } DCHECK(target->instance_descriptors() - .GetFieldType(descriptor) + .GetFieldType(descriptor_index) .NowContains(value)); map = target; descriptor++; @@ -560,18 +563,21 @@ Handle<Object> JsonParser<Char>::BuildJsonObject( : reinterpret_cast<Address>( mutable_double_buffer->GetDataStartAddress()); Address filler_address = mutable_double_address; - if (IsAligned(mutable_double_address, kDoubleAlignment)) { - mutable_double_address += kTaggedSize; - } else { - filler_address += HeapNumber::kSize; + if (kTaggedSize != kDoubleSize) { + if (IsAligned(mutable_double_address, kDoubleAlignment)) { + mutable_double_address += kTaggedSize; + } else { + filler_address += HeapNumber::kSize; + } } for (int j = 0; j < i; j++) { const JsonProperty& property = property_stack[start + j]; if (property.string.is_index()) continue; + InternalIndex descriptor_index(descriptor); PropertyDetails details = - map->instance_descriptors().GetDetails(descriptor); + map->instance_descriptors().GetDetails(descriptor_index); Object value = *property.value; - FieldIndex index = FieldIndex::ForDescriptor(*map, descriptor); + FieldIndex index = FieldIndex::ForDescriptor(*map, descriptor_index); descriptor++; if (details.representation().IsDouble()) { @@ -619,9 +625,13 @@ Handle<Object> JsonParser<Char>::BuildJsonObject( #ifdef DEBUG Address end = reinterpret_cast<Address>(mutable_double_buffer->GetDataEndAddress()); - DCHECK_EQ(Min(filler_address, mutable_double_address), end); - DCHECK_GE(filler_address, end); - DCHECK_GE(mutable_double_address, end); + if (kTaggedSize != kDoubleSize) { + DCHECK_EQ(Min(filler_address, mutable_double_address), end); + DCHECK_GE(filler_address, end); + DCHECK_GE(mutable_double_address, end); + } else { + DCHECK_EQ(mutable_double_address, end); + } #endif mutable_double_buffer->set_length(0); } diff --git a/deps/v8/src/json/json-stringifier.cc b/deps/v8/src/json/json-stringifier.cc index 684bcdcf545a33..47d6a0ddad281a 100644 --- a/deps/v8/src/json/json-stringifier.cc +++ b/deps/v8/src/json/json-stringifier.cc @@ -771,7 +771,7 @@ JsonStringifier::Result JsonStringifier::SerializeJSObject( builder_.AppendCharacter('{'); Indent(); bool comma = false; - for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { Handle<Name> name(map->instance_descriptors().GetKey(i), isolate_); // TODO(rossberg): Should this throw? if (!name->IsString()) continue; diff --git a/deps/v8/src/libplatform/default-foreground-task-runner.cc b/deps/v8/src/libplatform/default-foreground-task-runner.cc index 0a31024d9a545c..23942043481b38 100644 --- a/deps/v8/src/libplatform/default-foreground-task-runner.cc +++ b/deps/v8/src/libplatform/default-foreground-task-runner.cc @@ -60,6 +60,16 @@ bool DefaultForegroundTaskRunner::IdleTasksEnabled() { return idle_task_support_ == IdleTaskSupport::kEnabled; } +void DefaultForegroundTaskRunner::PostNonNestableTask( + std::unique_ptr<Task> task) { + // Default platform does not nest tasks. + PostTask(std::move(task)); +} + +bool DefaultForegroundTaskRunner::NonNestableTasksEnabled() const { + return true; +} + std::unique_ptr<Task> DefaultForegroundTaskRunner::PopTaskFromQueue( MessageLoopBehavior wait_for_work) { base::MutexGuard guard(&lock_); diff --git a/deps/v8/src/libplatform/default-foreground-task-runner.h b/deps/v8/src/libplatform/default-foreground-task-runner.h index 78c0f6b6600656..9ff30e39405001 100644 --- a/deps/v8/src/libplatform/default-foreground-task-runner.h +++ b/deps/v8/src/libplatform/default-foreground-task-runner.h @@ -5,6 +5,7 @@ #ifndef V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_ #define V8_LIBPLATFORM_DEFAULT_FOREGROUND_TASK_RUNNER_H_ +#include <memory> #include <queue> #include "include/libplatform/libplatform.h" @@ -35,14 +36,15 @@ class V8_PLATFORM_EXPORT DefaultForegroundTaskRunner // v8::TaskRunner implementation. void PostTask(std::unique_ptr<Task> task) override; - void PostDelayedTask(std::unique_ptr<Task> task, double delay_in_seconds) override; void PostIdleTask(std::unique_ptr<IdleTask> task) override; - bool IdleTasksEnabled() override; + void PostNonNestableTask(std::unique_ptr<Task> task) override; + bool NonNestableTasksEnabled() const override; + private: // The same as PostTask, but the lock is already held by the caller. The // {guard} parameter should make sure that the caller is holding the lock. diff --git a/deps/v8/src/libplatform/default-worker-threads-task-runner.cc b/deps/v8/src/libplatform/default-worker-threads-task-runner.cc index 213e98801a0b1b..8cae955fd16fe6 100644 --- a/deps/v8/src/libplatform/default-worker-threads-task-runner.cc +++ b/deps/v8/src/libplatform/default-worker-threads-task-runner.cc @@ -15,7 +15,7 @@ DefaultWorkerThreadsTaskRunner::DefaultWorkerThreadsTaskRunner( time_function_(time_function), thread_pool_size_(thread_pool_size) { for (uint32_t i = 0; i < thread_pool_size; ++i) { - thread_pool_.push_back(base::make_unique<WorkerThread>(this)); + thread_pool_.push_back(std::make_unique<WorkerThread>(this)); } } diff --git a/deps/v8/src/libplatform/default-worker-threads-task-runner.h b/deps/v8/src/libplatform/default-worker-threads-task-runner.h index 31b6c0e8174883..d761a36e1b75c8 100644 --- a/deps/v8/src/libplatform/default-worker-threads-task-runner.h +++ b/deps/v8/src/libplatform/default-worker-threads-task-runner.h @@ -5,6 +5,7 @@ #ifndef V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_ #define V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_ +#include <memory> #include <vector> #include "include/libplatform/libplatform-export.h" diff --git a/deps/v8/src/libplatform/delayed-task-queue.h b/deps/v8/src/libplatform/delayed-task-queue.h index 675e9ecb8a4ba9..9fec948b86a56e 100644 --- a/deps/v8/src/libplatform/delayed-task-queue.h +++ b/deps/v8/src/libplatform/delayed-task-queue.h @@ -6,6 +6,7 @@ #define V8_LIBPLATFORM_DELAYED_TASK_QUEUE_H_ #include <map> +#include <memory> #include <queue> #include "include/libplatform/libplatform-export.h" diff --git a/deps/v8/src/libplatform/task-queue.h b/deps/v8/src/libplatform/task-queue.h index f8c76498f2bf74..fbad3a8adf9290 100644 --- a/deps/v8/src/libplatform/task-queue.h +++ b/deps/v8/src/libplatform/task-queue.h @@ -5,6 +5,7 @@ #ifndef V8_LIBPLATFORM_TASK_QUEUE_H_ #define V8_LIBPLATFORM_TASK_QUEUE_H_ +#include <memory> #include <queue> #include "include/libplatform/libplatform-export.h" diff --git a/deps/v8/src/libplatform/tracing/DEPS b/deps/v8/src/libplatform/tracing/DEPS index 582200e094f5de..7a45bba55a1e8d 100644 --- a/deps/v8/src/libplatform/tracing/DEPS +++ b/deps/v8/src/libplatform/tracing/DEPS @@ -1,4 +1,4 @@ include_rules = [ "+perfetto", - "+third_party/perfetto/include/perfetto/base", -] \ No newline at end of file + "+protos/perfetto", +] diff --git a/deps/v8/src/libplatform/tracing/json-trace-event-listener.cc b/deps/v8/src/libplatform/tracing/json-trace-event-listener.cc index 94b74ef255ab29..60cc9a98a8bf71 100644 --- a/deps/v8/src/libplatform/tracing/json-trace-event-listener.cc +++ b/deps/v8/src/libplatform/tracing/json-trace-event-listener.cc @@ -7,9 +7,9 @@ #include <cmath> #include "base/trace_event/common/trace_event_common.h" -#include "perfetto/trace/chrome/chrome_trace_packet.pb.h" -#include "perfetto/trace/trace.pb.h" #include "perfetto/tracing.h" +#include "protos/perfetto/trace/chrome/chrome_trace_packet.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #include "src/base/logging.h" #include "src/base/macros.h" diff --git a/deps/v8/src/libplatform/tracing/trace-event-listener.cc b/deps/v8/src/libplatform/tracing/trace-event-listener.cc index 8224221228b4c1..2910d8fab23037 100644 --- a/deps/v8/src/libplatform/tracing/trace-event-listener.cc +++ b/deps/v8/src/libplatform/tracing/trace-event-listener.cc @@ -4,7 +4,7 @@ #include "src/libplatform/tracing/trace-event-listener.h" -#include "perfetto/trace/trace.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #include "src/base/logging.h" namespace v8 { diff --git a/deps/v8/src/libplatform/tracing/trace-object.cc b/deps/v8/src/libplatform/tracing/trace-object.cc index 6b6e0cf404d3fd..d16104df68a990 100644 --- a/deps/v8/src/libplatform/tracing/trace-object.cc +++ b/deps/v8/src/libplatform/tracing/trace-object.cc @@ -23,12 +23,11 @@ V8_INLINE static size_t GetAllocLength(const char* str) { // location, and then advances |*buffer| by the amount written. V8_INLINE static void CopyTraceObjectParameter(char** buffer, const char** member) { - if (*member) { - size_t length = strlen(*member) + 1; - strncpy(*buffer, *member, length); - *member = *buffer; - *buffer += length; - } + if (*member == nullptr) return; + size_t length = strlen(*member) + 1; + memcpy(*buffer, *member, length); + *member = *buffer; + *buffer += length; } void TraceObject::Initialize( diff --git a/deps/v8/src/libplatform/tracing/tracing-controller.cc b/deps/v8/src/libplatform/tracing/tracing-controller.cc index 3fb34366c2f768..d0972f93229569 100644 --- a/deps/v8/src/libplatform/tracing/tracing-controller.cc +++ b/deps/v8/src/libplatform/tracing/tracing-controller.cc @@ -14,9 +14,9 @@ #ifdef V8_USE_PERFETTO #include "base/trace_event/common/trace_event_common.h" -#include "perfetto/trace/chrome/chrome_trace_event.pbzero.h" -#include "perfetto/trace/trace_packet.pbzero.h" #include "perfetto/tracing.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" +#include "protos/perfetto/trace/trace_packet.pbzero.h" #include "src/base/platform/platform.h" #include "src/base/platform/semaphore.h" #include "src/libplatform/tracing/json-trace-event-listener.h" @@ -280,7 +280,7 @@ void TracingController::StartTracing(TraceConfig* trace_config) { #ifdef V8_USE_PERFETTO DCHECK_NOT_NULL(output_stream_); DCHECK(output_stream_->good()); - json_listener_ = base::make_unique<JSONTraceEventListener>(output_stream_); + json_listener_ = std::make_unique<JSONTraceEventListener>(output_stream_); // TODO(petermarshall): Set other the params for the config. ::perfetto::TraceConfig perfetto_trace_config; diff --git a/deps/v8/src/libsampler/sampler.cc b/deps/v8/src/libsampler/sampler.cc index e445dfc65a7087..d9f59dff74af02 100644 --- a/deps/v8/src/libsampler/sampler.cc +++ b/deps/v8/src/libsampler/sampler.cc @@ -526,7 +526,7 @@ void SignalHandler::FillRegisterState(void* context, RegisterState* state) { #endif // USE_SIGNALS Sampler::Sampler(Isolate* isolate) - : isolate_(isolate), data_(base::make_unique<PlatformData>()) {} + : isolate_(isolate), data_(std::make_unique<PlatformData>()) {} Sampler::~Sampler() { DCHECK(!IsActive()); diff --git a/deps/v8/src/libsampler/sampler.h b/deps/v8/src/libsampler/sampler.h index 997b127686097f..c606add82aadd0 100644 --- a/deps/v8/src/libsampler/sampler.h +++ b/deps/v8/src/libsampler/sampler.h @@ -6,6 +6,7 @@ #define V8_LIBSAMPLER_SAMPLER_H_ #include <atomic> +#include <memory> #include <unordered_map> #include "include/v8.h" diff --git a/deps/v8/src/logging/counters-definitions.h b/deps/v8/src/logging/counters-definitions.h index 8c808276faad5e..39317121524fb4 100644 --- a/deps/v8/src/logging/counters-definitions.h +++ b/deps/v8/src/logging/counters-definitions.h @@ -221,6 +221,8 @@ namespace internal { MICROSECOND) \ HT(compile_script_no_cache_because_cache_too_cold, \ V8.CompileScriptMicroSeconds.NoCache.CacheTooCold, 1000000, MICROSECOND) \ + HT(compile_script_streaming_finalization, \ + V8.CompileScriptMicroSeconds.StreamingFinalization, 1000000, MICROSECOND) \ HT(compile_script_on_background, \ V8.CompileScriptMicroSeconds.BackgroundThread, 1000000, MICROSECOND) \ HT(compile_function_on_background, \ diff --git a/deps/v8/src/logging/counters.cc b/deps/v8/src/logging/counters.cc index ce2b1fe9c0761e..a6a56fac833d5b 100644 --- a/deps/v8/src/logging/counters.cc +++ b/deps/v8/src/logging/counters.cc @@ -551,7 +551,7 @@ base::Thread::LocalStorageKey WorkerThreadRuntimeCallStats::GetKey() { RuntimeCallStats* WorkerThreadRuntimeCallStats::NewTable() { DCHECK(TracingFlags::is_runtime_stats_enabled()); std::unique_ptr<RuntimeCallStats> new_table = - base::make_unique<RuntimeCallStats>(); + std::make_unique<RuntimeCallStats>(); RuntimeCallStats* result = new_table.get(); base::MutexGuard lock(&mutex_); diff --git a/deps/v8/src/logging/counters.h b/deps/v8/src/logging/counters.h index 35df5ec0384565..d82515efbaa11d 100644 --- a/deps/v8/src/logging/counters.h +++ b/deps/v8/src/logging/counters.h @@ -5,6 +5,8 @@ #ifndef V8_LOGGING_COUNTERS_H_ #define V8_LOGGING_COUNTERS_H_ +#include <memory> + #include "include/v8.h" #include "src/base/atomic-utils.h" #include "src/base/optional.h" @@ -731,6 +733,7 @@ class RuntimeCallTimer final { V(ArrayBuffer_Cast) \ V(ArrayBuffer_Detach) \ V(ArrayBuffer_New) \ + V(ArrayBuffer_NewBackingStore) \ V(Array_CloneElementAt) \ V(Array_New) \ V(BigInt64Array_New) \ @@ -849,6 +852,7 @@ class RuntimeCallTimer final { V(Set_Has) \ V(Set_New) \ V(SharedArrayBuffer_New) \ + V(SharedArrayBuffer_NewBackingStore) \ V(String_Concat) \ V(String_NewExternalOneByte) \ V(String_NewExternalTwoByte) \ @@ -1018,16 +1022,13 @@ class RuntimeCallTimer final { V(LoadIC_LoadNormalDH) \ V(LoadIC_LoadNormalFromPrototypeDH) \ V(LoadIC_NonReceiver) \ - V(LoadIC_Premonomorphic) \ V(LoadIC_SlowStub) \ V(LoadIC_StringLength) \ V(LoadIC_StringWrapperLength) \ V(StoreGlobalIC_SlowStub) \ V(StoreGlobalIC_StoreScriptContextField) \ - V(StoreGlobalIC_Premonomorphic) \ V(StoreIC_HandlerCacheHit_Accessor) \ V(StoreIC_NonReceiver) \ - V(StoreIC_Premonomorphic) \ V(StoreIC_SlowStub) \ V(StoreIC_StoreAccessorDH) \ V(StoreIC_StoreAccessorOnPrototypeDH) \ diff --git a/deps/v8/src/logging/log-utils.cc b/deps/v8/src/logging/log-utils.cc index 39808824029aaf..e5c0b027faabbd 100644 --- a/deps/v8/src/logging/log-utils.cc +++ b/deps/v8/src/logging/log-utils.cc @@ -75,8 +75,7 @@ FILE* Log::Close() { } output_handle_ = nullptr; - DeleteArray(format_buffer_); - format_buffer_ = nullptr; + format_buffer_.reset(); is_stopped_ = false; return result; @@ -84,7 +83,7 @@ FILE* Log::Close() { Log::MessageBuilder::MessageBuilder(Log* log) : log_(log), lock_guard_(&log_->mutex_) { - DCHECK_NOT_NULL(log_->format_buffer_); + DCHECK_NOT_NULL(log_->format_buffer_.get()); } void Log::MessageBuilder::AppendString(String str, @@ -185,7 +184,7 @@ void Log::MessageBuilder::AppendSymbolNameDetails(String str, int Log::MessageBuilder::FormatStringIntoBuffer(const char* format, va_list args) { - Vector<char> buf(log_->format_buffer_, Log::kMessageBufferSize); + Vector<char> buf(log_->format_buffer_.get(), Log::kMessageBufferSize); int length = v8::internal::VSNPrintF(buf, format, args); // |length| is -1 if output was truncated. if (length == -1) length = Log::kMessageBufferSize; diff --git a/deps/v8/src/logging/log-utils.h b/deps/v8/src/logging/log-utils.h index bc5b09d43820b2..e89a449f3b442a 100644 --- a/deps/v8/src/logging/log-utils.h +++ b/deps/v8/src/logging/log-utils.h @@ -125,7 +125,7 @@ class Log { // Buffer used for formatting log messages. This is a singleton buffer and // mutex_ should be acquired before using it. - char* format_buffer_; + std::unique_ptr<char[]> format_buffer_; Logger* logger_; diff --git a/deps/v8/src/logging/log.cc b/deps/v8/src/logging/log.cc index 9b86a16031e84f..2befcd330abc92 100644 --- a/deps/v8/src/logging/log.cc +++ b/deps/v8/src/logging/log.cc @@ -180,9 +180,9 @@ class CodeEventLogger::NameBuffer { }; CodeEventLogger::CodeEventLogger(Isolate* isolate) - : isolate_(isolate), name_buffer_(new NameBuffer) {} + : isolate_(isolate), name_buffer_(std::make_unique<NameBuffer>()) {} -CodeEventLogger::~CodeEventLogger() { delete name_buffer_; } +CodeEventLogger::~CodeEventLogger() = default; void CodeEventLogger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode code, const char* comment) { @@ -477,6 +477,23 @@ void ExternalCodeEventListener::RegExpCodeCreateEvent(AbstractCode code, code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event)); } +void ExternalCodeEventListener::CodeMoveEvent(AbstractCode from, + AbstractCode to) { + CodeEvent code_event; + code_event.previous_code_start_address = + static_cast<uintptr_t>(from.InstructionStart()); + code_event.code_start_address = static_cast<uintptr_t>(to.InstructionStart()); + code_event.code_size = static_cast<size_t>(to.InstructionSize()); + code_event.function_name = isolate_->factory()->empty_string(); + code_event.script_name = isolate_->factory()->empty_string(); + code_event.script_line = 0; + code_event.script_column = 0; + code_event.code_type = v8::CodeEventType::kRelocationType; + code_event.comment = ""; + + code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event)); +} + // Low-level logging support. class LowLevelLogger : public CodeEventLogger { public: @@ -816,7 +833,7 @@ class Ticker : public sampler::Sampler { Ticker(Isolate* isolate, int interval_microseconds) : sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)), sampling_thread_( - base::make_unique<SamplingThread>(this, interval_microseconds)) {} + std::make_unique<SamplingThread>(this, interval_microseconds)) {} ~Ticker() override { if (IsActive()) Stop(); @@ -910,13 +927,11 @@ void Profiler::Run() { Logger::Logger(Isolate* isolate) : isolate_(isolate), - log_events_(nullptr), is_logging_(false), - log_(nullptr), is_initialized_(false), existing_code_logger_(isolate) {} -Logger::~Logger() { delete log_; } +Logger::~Logger() = default; const LogSeparator Logger::kNext = LogSeparator::kSeparator; @@ -931,7 +946,7 @@ void Logger::RemoveCodeEventListener(CodeEventListener* listener) { void Logger::ProfilerBeginEvent() { if (!log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "profiler" << kNext << "begin" << kNext << FLAG_prof_sampling_interval; msg.WriteToLogFile(); } @@ -942,7 +957,7 @@ void Logger::StringEvent(const char* name, const char* value) { void Logger::UncheckedStringEvent(const char* name, const char* value) { if (!log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << name << kNext << value; msg.WriteToLogFile(); } @@ -953,7 +968,7 @@ void Logger::IntPtrTEvent(const char* name, intptr_t value) { void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { if (!log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << name << kNext; msg.AppendFormatString("%" V8PRIdPTR, value); msg.WriteToLogFile(); @@ -961,14 +976,14 @@ void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { void Logger::HandleEvent(const char* name, Address* location) { if (!log_->IsEnabled() || !FLAG_log_handles) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << name << kNext << reinterpret_cast<void*>(location); msg.WriteToLogFile(); } void Logger::ApiSecurityCheck() { if (!log_->IsEnabled() || !FLAG_log_api) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "api" << kNext << "check-security"; msg.WriteToLogFile(); } @@ -977,7 +992,7 @@ void Logger::SharedLibraryEvent(const std::string& library_path, uintptr_t start, uintptr_t end, intptr_t aslr_slide) { if (!log_->IsEnabled() || !FLAG_prof_cpp) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "shared-library" << kNext << library_path.c_str() << kNext << reinterpret_cast<void*>(start) << kNext << reinterpret_cast<void*>(end) << kNext << aslr_slide; @@ -988,7 +1003,7 @@ void Logger::CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc, int fp_to_sp_delta) { if (!log_->IsEnabled()) return; Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(code, pc); - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "code-deopt" << kNext << timer_.Elapsed().InMicroseconds() << kNext << code.CodeSize() << kNext << reinterpret_cast<void*>(code.InstructionStart()); @@ -1014,14 +1029,14 @@ void Logger::CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc, void Logger::CurrentTimeEvent() { if (!log_->IsEnabled()) return; DCHECK(FLAG_log_internal_timer_events); - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "current-time" << kNext << timer_.Elapsed().InMicroseconds(); msg.WriteToLogFile(); } void Logger::TimerEvent(Logger::StartEnd se, const char* name) { if (!log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); switch (se) { case START: msg << "timer-event-start"; @@ -1053,7 +1068,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder, Object property_name) { DCHECK(property_name.IsName()); if (!log_->IsEnabled() || !FLAG_log_api) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "api" << kNext << tag << kNext << holder.class_name() << kNext << Name::cast(property_name); msg.WriteToLogFile(); @@ -1062,7 +1077,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder, void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder, uint32_t index) { if (!log_->IsEnabled() || !FLAG_log_api) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "api" << kNext << tag << kNext << holder.class_name() << kNext << index; msg.WriteToLogFile(); @@ -1070,21 +1085,21 @@ void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder, void Logger::ApiObjectAccess(const char* tag, JSObject object) { if (!log_->IsEnabled() || !FLAG_log_api) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "api" << kNext << tag << kNext << object.class_name(); msg.WriteToLogFile(); } void Logger::ApiEntryCall(const char* name) { if (!log_->IsEnabled() || !FLAG_log_api) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "api" << kNext << name; msg.WriteToLogFile(); } void Logger::NewEvent(const char* name, void* object, size_t size) { if (!log_->IsEnabled() || !FLAG_log) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "new" << kNext << name << kNext << object << kNext << static_cast<unsigned int>(size); msg.WriteToLogFile(); @@ -1092,7 +1107,7 @@ void Logger::NewEvent(const char* name, void* object, size_t size) { void Logger::DeleteEvent(const char* name, void* object) { if (!log_->IsEnabled() || !FLAG_log) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "delete" << kNext << name << kNext << object; msg.WriteToLogFile(); } @@ -1100,7 +1115,7 @@ void Logger::DeleteEvent(const char* name, void* object) { void Logger::CallbackEventInternal(const char* prefix, Name name, Address entry_point) { if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT] << kNext << kLogEventsNames[CodeEventListener::CALLBACK_TAG] << kNext << -2 << kNext << timer_.Elapsed().InMicroseconds() << kNext @@ -1149,7 +1164,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode code, const char* comment) { if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, tag, code, &timer_); msg << comment; msg.WriteToLogFile(); @@ -1159,7 +1174,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode code, Name name) { if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, tag, code, &timer_); msg << name; msg.WriteToLogFile(); @@ -1175,7 +1190,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, return; } - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, tag, code, &timer_); msg << name << kNext << reinterpret_cast<void*>(shared.address()) << kNext << ComputeMarker(shared, code); @@ -1186,7 +1201,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, const wasm::WasmCode* code, wasm::WasmName name) { if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, tag, AbstractCode::Kind::WASM_FUNCTION, code->instructions().begin(), code->instructions().length(), &timer_); @@ -1215,7 +1230,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; { - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, tag, code, &timer_); msg << shared.DebugName() << " " << source << ":" << line << ":" << column << kNext << reinterpret_cast<void*>(shared.address()) << kNext @@ -1250,7 +1265,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, // <function-id> is an index into the <fns> function table // <fns> is the function table encoded as a sequence of strings // S<shared-function-info-address> - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "code-source-info" << kNext << reinterpret_cast<void*>(code.InstructionStart()) << kNext << script.id() << kNext << shared.StartPosition() << kNext @@ -1307,7 +1322,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeDisableOptEvent(AbstractCode code, SharedFunctionInfo shared) { if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext << shared.DebugName() << kNext << GetBailoutReason(shared.disable_optimization_reason()); @@ -1323,7 +1338,7 @@ void Logger::CodeMovingGCEvent() { void Logger::RegExpCodeCreateEvent(AbstractCode code, String source) { if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, code, &timer_); msg << source; msg.WriteToLogFile(); @@ -1373,7 +1388,7 @@ void Logger::CodeLinePosInfoRecordEvent( void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { if (code_name == nullptr) return; // Not a code object. - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT] << kNext << pos << kNext << code_name; msg.WriteToLogFile(); @@ -1387,7 +1402,7 @@ void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { void Logger::MoveEventInternal(CodeEventListener::LogEventsAndTags event, Address from, Address to) { if (!FLAG_log_code || !log_->IsEnabled()) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << kLogEventsNames[event] << kNext << reinterpret_cast<void*>(from) << kNext << reinterpret_cast<void*>(to); msg.WriteToLogFile(); @@ -1395,7 +1410,7 @@ void Logger::MoveEventInternal(CodeEventListener::LogEventsAndTags event, void Logger::ResourceEvent(const char* name, const char* tag) { if (!log_->IsEnabled() || !FLAG_log) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << name << kNext << tag << kNext; uint32_t sec, usec; @@ -1409,7 +1424,7 @@ void Logger::ResourceEvent(const char* name, const char* tag) { void Logger::SuspectReadEvent(Name name, Object obj) { if (!log_->IsEnabled() || !FLAG_log_suspect) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); String class_name = obj.IsJSObject() ? JSObject::cast(obj).class_name() : ReadOnlyRoots(isolate_).empty_string(); msg << "suspect-read" << kNext << class_name << kNext << name; @@ -1432,7 +1447,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, int start_position, int end_position, String function_name) { if (!log_->IsEnabled() || !FLAG_log_function_events) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendFunctionMessage(msg, reason, script_id, time_delta, start_position, end_position, &timer_); if (!function_name.is_null()) msg << function_name; @@ -1444,7 +1459,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, const char* function_name, size_t function_name_length) { if (!log_->IsEnabled() || !FLAG_log_function_events) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); AppendFunctionMessage(msg, reason, script_id, time_delta, start_position, end_position, &timer_); if (function_name_length > 0) { @@ -1456,7 +1471,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, void Logger::CompilationCacheEvent(const char* action, const char* cache_type, SharedFunctionInfo sfi) { if (!log_->IsEnabled() || !FLAG_log_function_events) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); int script_id = -1; if (sfi.script().IsScript()) { script_id = Script::cast(sfi.script()).id(); @@ -1470,7 +1485,7 @@ void Logger::CompilationCacheEvent(const char* action, const char* cache_type, void Logger::ScriptEvent(ScriptEventType type, int script_id) { if (!log_->IsEnabled() || !FLAG_log_function_events) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "script" << Logger::kNext; switch (type) { case ScriptEventType::kReserveId: @@ -1497,7 +1512,7 @@ void Logger::ScriptEvent(ScriptEventType type, int script_id) { void Logger::ScriptDetails(Script script) { if (!log_->IsEnabled() || !FLAG_log_function_events) return; { - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "script-details" << Logger::kNext << script.id() << Logger::kNext; if (script.name().IsString()) { msg << String::cast(script.name()); @@ -1514,7 +1529,7 @@ void Logger::ScriptDetails(Script script) { bool Logger::EnsureLogScriptSource(Script script) { if (!log_->IsEnabled()) return false; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); // Make sure the script is written to the log file. int script_id = script.id(); if (logged_source_code_.find(script_id) != logged_source_code_.end()) { @@ -1544,7 +1559,7 @@ void Logger::RuntimeCallTimerEvent() { RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats(); RuntimeCallCounter* counter = stats->current_counter(); if (counter == nullptr) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "active-runtime-timer" << kNext << counter->name(); msg.WriteToLogFile(); } @@ -1555,7 +1570,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) { v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) { RuntimeCallTimerEvent(); } - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << kLogEventsNames[CodeEventListener::TICK_EVENT] << kNext << reinterpret_cast<void*>(sample->pc) << kNext << timer_.Elapsed().InMicroseconds(); @@ -1577,7 +1592,7 @@ void Logger::ICEvent(const char* type, bool keyed, Map map, Object key, char old_state, char new_state, const char* modifier, const char* slow_stub_reason) { if (!log_->IsEnabled() || !FLAG_trace_ic) return; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); if (keyed) msg << "Keyed"; int line; int column; @@ -1611,7 +1626,7 @@ void Logger::MapEvent(const char* type, Map from, Map to, const char* reason, if (!isolate_->bootstrapper()->IsActive()) { pc = isolate_->GetAbstractPC(&line, &column); } - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "map" << kNext << type << kNext << timer_.Elapsed().InMicroseconds() << kNext << AsHex::Address(from.ptr()) << kNext << AsHex::Address(to.ptr()) << kNext << AsHex::Address(pc) << kNext @@ -1634,7 +1649,7 @@ void Logger::MapEvent(const char* type, Map from, Map to, const char* reason, void Logger::MapCreate(Map map) { if (!log_->IsEnabled() || !FLAG_trace_maps) return; DisallowHeapAllocation no_gc; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "map-create" << kNext << timer_.Elapsed().InMicroseconds() << kNext << AsHex::Address(map.ptr()); msg.WriteToLogFile(); @@ -1643,7 +1658,7 @@ void Logger::MapCreate(Map map) { void Logger::MapDetails(Map map) { if (!log_->IsEnabled() || !FLAG_trace_maps) return; DisallowHeapAllocation no_gc; - Log::MessageBuilder msg(log_); + Log::MessageBuilder msg(log_.get()); msg << "map-details" << kNext << timer_.Elapsed().InMicroseconds() << kNext << AsHex::Address(map.ptr()) << kNext; if (FLAG_trace_maps_details) { @@ -1842,24 +1857,25 @@ bool Logger::SetUp(Isolate* isolate) { std::ostringstream log_file_name; std::ostringstream source_log_file_name; PrepareLogFileName(log_file_name, isolate, FLAG_logfile); - log_ = new Log(this, log_file_name.str().c_str()); + log_ = std::make_unique<Log>(this, log_file_name.str().c_str()); if (FLAG_perf_basic_prof) { - perf_basic_logger_.reset(new PerfBasicLogger(isolate)); + perf_basic_logger_ = std::make_unique<PerfBasicLogger>(isolate); AddCodeEventListener(perf_basic_logger_.get()); } if (FLAG_perf_prof) { - perf_jit_logger_.reset(new PerfJitLogger(isolate)); + perf_jit_logger_ = std::make_unique<PerfJitLogger>(isolate); AddCodeEventListener(perf_jit_logger_.get()); } if (FLAG_ll_prof) { - ll_logger_.reset(new LowLevelLogger(isolate, log_file_name.str().c_str())); + ll_logger_ = + std::make_unique<LowLevelLogger>(isolate, log_file_name.str().c_str()); AddCodeEventListener(ll_logger_.get()); } - ticker_.reset(new Ticker(isolate, FLAG_prof_sampling_interval)); + ticker_ = std::make_unique<Ticker>(isolate, FLAG_prof_sampling_interval); if (Log::InitLogAtStart()) { is_logging_ = true; @@ -1868,7 +1884,7 @@ bool Logger::SetUp(Isolate* isolate) { timer_.Start(); if (FLAG_prof_cpp) { - profiler_.reset(new Profiler(isolate)); + profiler_ = std::make_unique<Profiler>(isolate); is_logging_ = true; profiler_->Engage(); } @@ -1891,7 +1907,7 @@ void Logger::SetCodeEventHandler(uint32_t options, if (isolate_->wasm_engine() != nullptr) { isolate_->wasm_engine()->EnableCodeLogging(isolate_); } - jit_logger_.reset(new JitLogger(isolate_, event_handler)); + jit_logger_ = std::make_unique<JitLogger>(isolate_, event_handler); AddCodeEventListener(jit_logger_.get()); if (options & kJitCodeEventEnumExisting) { HandleScope scope(isolate_); @@ -2042,9 +2058,9 @@ void ExistingCodeLogger::LogCompiledFunctions() { const int wasm_module_objects_count = EnumerateWasmModuleObjects(heap, nullptr); - std::unique_ptr<Handle<WasmModuleObject>[]> module_objects( - new Handle<WasmModuleObject>[wasm_module_objects_count]); - EnumerateWasmModuleObjects(heap, module_objects.get()); + ScopedVector<Handle<WasmModuleObject>> module_objects( + wasm_module_objects_count); + EnumerateWasmModuleObjects(heap, module_objects.begin()); for (int i = 0; i < wasm_module_objects_count; ++i) { module_objects[i]->native_module()->LogWasmCodes(isolate_); } diff --git a/deps/v8/src/logging/log.h b/deps/v8/src/logging/log.h index 3c28222982cae6..69760c4c6cab33 100644 --- a/deps/v8/src/logging/log.h +++ b/deps/v8/src/logging/log.h @@ -5,6 +5,7 @@ #ifndef V8_LOGGING_LOG_H_ #define V8_LOGGING_LOG_H_ +#include <memory> #include <set> #include <string> @@ -115,6 +116,9 @@ class Logger : public CodeEventListener { kStreamingCompile }; + explicit Logger(Isolate* isolate); + ~Logger(); + // The separator is used to write an unescaped "," into the log. static const LogSeparator kNext; @@ -273,9 +277,6 @@ class Logger : public CodeEventListener { void LogCodeObject(Object code_object); private: - explicit Logger(Isolate* isolate); - ~Logger() override; - // Emits the profiler's first message. void ProfilerBeginEvent(); @@ -314,21 +315,11 @@ class Logger : public CodeEventListener { // of samples. std::unique_ptr<Profiler> profiler_; - // An array of log events names. - const char* const* log_events_; - - // Internal implementation classes with access to - // private members. - friend class EventLog; - friend class Isolate; - friend class TimeLog; + // Internal implementation classes with access to private members. friend class Profiler; - template <StateTag Tag> - friend class VMState; - friend class LoggerTestHelper; bool is_logging_; - Log* log_; + std::unique_ptr<Log> log_; std::unique_ptr<PerfBasicLogger> perf_basic_logger_; std::unique_ptr<PerfJitLogger> perf_jit_logger_; std::unique_ptr<LowLevelLogger> ll_logger_; @@ -419,7 +410,7 @@ class V8_EXPORT_PRIVATE CodeEventLogger : public CodeEventListener { virtual void LogRecordedBuffer(const wasm::WasmCode* code, const char* name, int length) = 0; - NameBuffer* name_buffer_; + std::unique_ptr<NameBuffer> name_buffer_; }; struct CodeEvent { @@ -432,6 +423,7 @@ struct CodeEvent { int script_column; CodeEventType code_type; const char* comment; + uintptr_t previous_code_start_address; }; class ExternalCodeEventListener : public CodeEventListener { @@ -457,7 +449,7 @@ class ExternalCodeEventListener : public CodeEventListener { void SetterCallbackEvent(Name name, Address entry_point) override {} void SharedFunctionInfoMoveEvent(Address from, Address to) override {} void NativeContextMoveEvent(Address from, Address to) override {} - void CodeMoveEvent(AbstractCode from, AbstractCode to) override {} + void CodeMoveEvent(AbstractCode from, AbstractCode to) override; void CodeDisableOptEvent(AbstractCode code, SharedFunctionInfo shared) override {} void CodeMovingGCEvent() override {} diff --git a/deps/v8/src/numbers/OWNERS b/deps/v8/src/numbers/OWNERS index df62d017308564..882d275fe861eb 100644 --- a/deps/v8/src/numbers/OWNERS +++ b/deps/v8/src/numbers/OWNERS @@ -1,4 +1,4 @@ -clemensh@chromium.org +clemensb@chromium.org jgruber@chromium.org jkummerow@chromium.org sigurds@chromium.org diff --git a/deps/v8/src/numbers/math-random.cc b/deps/v8/src/numbers/math-random.cc index dee18788a7c5dd..d45b4d0a5f113f 100644 --- a/deps/v8/src/numbers/math-random.cc +++ b/deps/v8/src/numbers/math-random.cc @@ -16,9 +16,8 @@ namespace internal { void MathRandom::InitializeContext(Isolate* isolate, Handle<Context> native_context) { - Handle<FixedDoubleArray> cache = - Handle<FixedDoubleArray>::cast(isolate->factory()->NewFixedDoubleArray( - kCacheSize, AllocationType::kOld)); + Handle<FixedDoubleArray> cache = Handle<FixedDoubleArray>::cast( + isolate->factory()->NewFixedDoubleArray(kCacheSize)); for (int i = 0; i < kCacheSize; i++) cache->set(i, 0); native_context->set_math_random_cache(*cache); Handle<PodArray<State>> pod = diff --git a/deps/v8/src/objects/arguments.h b/deps/v8/src/objects/arguments.h index a306ef592aa3e2..0a1e3e4ac98a0a 100644 --- a/deps/v8/src/objects/arguments.h +++ b/deps/v8/src/objects/arguments.h @@ -16,7 +16,7 @@ namespace v8 { namespace internal { -// Superclass for all objects with instance type {JS_ARGUMENTS_TYPE} +// Superclass for all objects with instance type {JS_ARGUMENTS_OBJECT_TYPE} class JSArgumentsObject : public TorqueGeneratedJSArgumentsObject<JSArgumentsObject, JSObject> { public: @@ -25,15 +25,16 @@ class JSArgumentsObject }; // Common superclass for JSSloppyArgumentsObject and JSStrictArgumentsObject. -// Note that the instance type {JS_ARGUMENTS_TYPE} does _not_ guarantee the -// below layout, the in-object properties might have transitioned to dictionary -// mode already. Only use the below layout with the specific initial maps. +// Note that the instance type {JS_ARGUMENTS_OBJECT_TYPE} does _not_ guarantee +// the below layout, the in-object properties might have transitioned to +// dictionary mode already. Only use the below layout with the specific initial +// maps. class JSArgumentsObjectWithLength : public JSArgumentsObject { public: // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS( JSObject::kHeaderSize, - TORQUE_GENERATED_JSARGUMENTS_OBJECT_WITH_LENGTH_FIELDS) + TORQUE_GENERATED_JS_ARGUMENTS_OBJECT_WITH_LENGTH_FIELDS) // Indices of in-object properties. static const int kLengthIndex = 0; @@ -50,7 +51,7 @@ class JSSloppyArgumentsObject : public JSArgumentsObjectWithLength { public: DEFINE_FIELD_OFFSET_CONSTANTS( JSArgumentsObjectWithLength::kSize, - TORQUE_GENERATED_JSSLOPPY_ARGUMENTS_OBJECT_FIELDS) + TORQUE_GENERATED_JS_SLOPPY_ARGUMENTS_OBJECT_FIELDS) // Indices of in-object properties. static const int kCalleeIndex = kLengthIndex + 1; diff --git a/deps/v8/src/objects/backing-store.cc b/deps/v8/src/objects/backing-store.cc new file mode 100644 index 00000000000000..cc6741765e1962 --- /dev/null +++ b/deps/v8/src/objects/backing-store.cc @@ -0,0 +1,710 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/objects/backing-store.h" +#include "src/execution/isolate.h" +#include "src/handles/global-handles.h" +#include "src/logging/counters.h" +#include "src/wasm/wasm-engine.h" +#include "src/wasm/wasm-limits.h" +#include "src/wasm/wasm-objects-inl.h" + +#define TRACE_BS(...) \ + do { \ + if (FLAG_trace_backing_store) PrintF(__VA_ARGS__); \ + } while (false) + +namespace v8 { +namespace internal { + +namespace { +#if V8_TARGET_ARCH_64_BIT +constexpr bool kUseGuardRegions = true; +#else +constexpr bool kUseGuardRegions = false; +#endif + +#if V8_TARGET_ARCH_MIPS64 +// MIPS64 has a user space of 2^40 bytes on most processors, +// address space limits needs to be smaller. +constexpr size_t kAddressSpaceLimit = 0x8000000000L; // 512 GiB +#elif V8_TARGET_ARCH_64_BIT +constexpr size_t kAddressSpaceLimit = 0x10100000000L; // 1 TiB + 4 GiB +#else +constexpr size_t kAddressSpaceLimit = 0xC0000000; // 3 GiB +#endif + +constexpr uint64_t kOneGiB = 1024 * 1024 * 1024; +constexpr uint64_t kNegativeGuardSize = 2 * kOneGiB; +constexpr uint64_t kFullGuardSize = 10 * kOneGiB; + +std::atomic<uint64_t> reserved_address_space_{0}; + +// Allocation results are reported to UMA +// +// See wasm_memory_allocation_result in counters.h +enum class AllocationStatus { + kSuccess, // Succeeded on the first try + + kSuccessAfterRetry, // Succeeded after garbage collection + + kAddressSpaceLimitReachedFailure, // Failed because Wasm is at its address + // space limit + + kOtherFailure // Failed for an unknown reason +}; + +base::AddressRegion GetGuardedRegion(void* buffer_start, size_t byte_length) { + // Guard regions always look like this: + // |xxx(2GiB)xxx|.......(4GiB)..xxxxx|xxxxxx(4GiB)xxxxxx| + // ^ buffer_start + // ^ byte_length + // ^ negative guard region ^ positive guard region + + Address start = reinterpret_cast<Address>(buffer_start); + DCHECK_EQ(8, sizeof(size_t)); // only use on 64-bit + DCHECK_EQ(0, start % AllocatePageSize()); + return base::AddressRegion(start - (2 * kOneGiB), + static_cast<size_t>(kFullGuardSize)); +} + +void RecordStatus(Isolate* isolate, AllocationStatus status) { + isolate->counters()->wasm_memory_allocation_result()->AddSample( + static_cast<int>(status)); +} + +inline void DebugCheckZero(void* start, size_t byte_length) { +#if DEBUG + // Double check memory is zero-initialized. + const byte* bytes = reinterpret_cast<const byte*>(start); + for (size_t i = 0; i < byte_length; i++) { + DCHECK_EQ(0, bytes[i]); + } +#endif +} +} // namespace + +bool BackingStore::ReserveAddressSpace(uint64_t num_bytes) { + uint64_t reservation_limit = kAddressSpaceLimit; + while (true) { + uint64_t old_count = reserved_address_space_.load(); + if (old_count > reservation_limit) return false; + if (reservation_limit - old_count < num_bytes) return false; + if (reserved_address_space_.compare_exchange_weak(old_count, + old_count + num_bytes)) { + return true; + } + } +} + +void BackingStore::ReleaseReservation(uint64_t num_bytes) { + uint64_t old_reserved = reserved_address_space_.fetch_sub(num_bytes); + USE(old_reserved); + DCHECK_LE(num_bytes, old_reserved); +} + +// The backing store for a Wasm shared memory remembers all the isolates +// with which it has been shared. +struct SharedWasmMemoryData { + std::vector<Isolate*> isolates_; +}; + +void BackingStore::Clear() { + buffer_start_ = nullptr; + byte_length_ = 0; + has_guard_regions_ = false; + if (holds_shared_ptr_to_allocator_) { + type_specific_data_.v8_api_array_buffer_allocator_shared + .std::shared_ptr<v8::ArrayBuffer::Allocator>::~shared_ptr(); + holds_shared_ptr_to_allocator_ = false; + } + type_specific_data_.v8_api_array_buffer_allocator = nullptr; +} + +BackingStore::~BackingStore() { + GlobalBackingStoreRegistry::Unregister(this); + + if (buffer_start_ == nullptr) return; // nothing to deallocate + + if (is_wasm_memory_) { + DCHECK(free_on_destruct_); + DCHECK(!custom_deleter_); + TRACE_BS("BSw:free bs=%p mem=%p (length=%zu, capacity=%zu)\n", this, + buffer_start_, byte_length(), byte_capacity_); + if (is_shared_) { + // Deallocate the list of attached memory objects. + SharedWasmMemoryData* shared_data = get_shared_wasm_memory_data(); + delete shared_data; + type_specific_data_.shared_wasm_memory_data = nullptr; + } + + // Wasm memories are always allocated through the page allocator. + auto region = + has_guard_regions_ + ? GetGuardedRegion(buffer_start_, byte_length_) + : base::AddressRegion(reinterpret_cast<Address>(buffer_start_), + byte_capacity_); + bool pages_were_freed = + region.size() == 0 /* no need to free any pages */ || + FreePages(GetPlatformPageAllocator(), + reinterpret_cast<void*>(region.begin()), region.size()); + CHECK(pages_were_freed); + BackingStore::ReleaseReservation(has_guard_regions_ ? kFullGuardSize + : byte_capacity_); + Clear(); + return; + } + if (custom_deleter_) { + DCHECK(free_on_destruct_); + TRACE_BS("BS:custome deleter bs=%p mem=%p (length=%zu, capacity=%zu)\n", + this, buffer_start_, byte_length(), byte_capacity_); + type_specific_data_.deleter.callback(buffer_start_, byte_length_, + type_specific_data_.deleter.data); + Clear(); + return; + } + if (free_on_destruct_) { + // JSArrayBuffer backing store. Deallocate through the embedder's allocator. + auto allocator = get_v8_api_array_buffer_allocator(); + TRACE_BS("BS:free bs=%p mem=%p (length=%zu, capacity=%zu)\n", this, + buffer_start_, byte_length(), byte_capacity_); + allocator->Free(buffer_start_, byte_length_); + } + Clear(); +} + +// Allocate a backing store using the array buffer allocator from the embedder. +std::unique_ptr<BackingStore> BackingStore::Allocate( + Isolate* isolate, size_t byte_length, SharedFlag shared, + InitializedFlag initialized) { + void* buffer_start = nullptr; + auto allocator = isolate->array_buffer_allocator(); + CHECK_NOT_NULL(allocator); + if (byte_length != 0) { + auto counters = isolate->counters(); + int mb_length = static_cast<int>(byte_length / MB); + if (mb_length > 0) { + counters->array_buffer_big_allocations()->AddSample(mb_length); + } + if (shared == SharedFlag::kShared) { + counters->shared_array_allocations()->AddSample(mb_length); + } + auto allocate_buffer = [allocator, initialized](size_t byte_length) { + if (initialized == InitializedFlag::kUninitialized) { + return allocator->AllocateUninitialized(byte_length); + } + void* buffer_start = allocator->Allocate(byte_length); + if (buffer_start) { + // TODO(wasm): node does not implement the zero-initialization API. + // Reenable this debug check when node does implement it properly. + constexpr bool + kDebugCheckZeroDisabledDueToNodeNotImplementingZeroInitAPI = true; + if ((!(kDebugCheckZeroDisabledDueToNodeNotImplementingZeroInitAPI)) && + !FLAG_mock_arraybuffer_allocator) { + DebugCheckZero(buffer_start, byte_length); + } + } + return buffer_start; + }; + + buffer_start = isolate->heap()->AllocateExternalBackingStore( + allocate_buffer, byte_length); + + if (buffer_start == nullptr) { + // Allocation failed. + counters->array_buffer_new_size_failures()->AddSample(mb_length); + return {}; + } + } + + auto result = new BackingStore(buffer_start, // start + byte_length, // length + byte_length, // capacity + shared, // shared + false, // is_wasm_memory + true, // free_on_destruct + false, // has_guard_regions + false); // custom_deleter + + TRACE_BS("BS:alloc bs=%p mem=%p (length=%zu)\n", result, + result->buffer_start(), byte_length); + result->SetAllocatorFromIsolate(isolate); + return std::unique_ptr<BackingStore>(result); +} + +void BackingStore::SetAllocatorFromIsolate(Isolate* isolate) { + if (auto allocator_shared = isolate->array_buffer_allocator_shared()) { + holds_shared_ptr_to_allocator_ = true; + new (&type_specific_data_.v8_api_array_buffer_allocator_shared) + std::shared_ptr<v8::ArrayBuffer::Allocator>( + std::move(allocator_shared)); + } else { + type_specific_data_.v8_api_array_buffer_allocator = + isolate->array_buffer_allocator(); + } +} + +// Allocate a backing store for a Wasm memory. Always use the page allocator +// and add guard regions. +std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory( + Isolate* isolate, size_t initial_pages, size_t maximum_pages, + SharedFlag shared) { + // Cannot reserve 0 pages on some OSes. + if (maximum_pages == 0) maximum_pages = 1; + + TRACE_BS("BSw:try %zu pages, %zu max\n", initial_pages, maximum_pages); + + bool guards = kUseGuardRegions; + + // For accounting purposes, whether a GC was necessary. + bool did_retry = false; + + // A helper to try running a function up to 3 times, executing a GC + // if the first and second attempts failed. + auto gc_retry = [&](const std::function<bool()>& fn) { + for (int i = 0; i < 3; i++) { + if (fn()) return true; + // Collect garbage and retry. + did_retry = true; + // TODO(wasm): try Heap::EagerlyFreeExternalMemory() first? + isolate->heap()->MemoryPressureNotification( + MemoryPressureLevel::kCritical, true); + } + return false; + }; + + // Compute size of reserved memory. + + size_t engine_max_pages = wasm::max_mem_pages(); + size_t byte_capacity = + std::min(engine_max_pages, maximum_pages) * wasm::kWasmPageSize; + size_t reservation_size = + guards ? static_cast<size_t>(kFullGuardSize) : byte_capacity; + + //-------------------------------------------------------------------------- + // 1. Enforce maximum address space reservation per engine. + //-------------------------------------------------------------------------- + auto reserve_memory_space = [&] { + return BackingStore::ReserveAddressSpace(reservation_size); + }; + + if (!gc_retry(reserve_memory_space)) { + // Crash on out-of-memory if the correctness fuzzer is running. + if (FLAG_correctness_fuzzer_suppressions) { + FATAL("could not allocate wasm memory backing store"); + } + RecordStatus(isolate, AllocationStatus::kAddressSpaceLimitReachedFailure); + TRACE_BS("BSw:try failed to reserve address space\n"); + return {}; + } + + //-------------------------------------------------------------------------- + // 2. Allocate pages (inaccessible by default). + //-------------------------------------------------------------------------- + void* allocation_base = nullptr; + auto allocate_pages = [&] { + allocation_base = + AllocatePages(GetPlatformPageAllocator(), nullptr, reservation_size, + wasm::kWasmPageSize, PageAllocator::kNoAccess); + return allocation_base != nullptr; + }; + if (!gc_retry(allocate_pages)) { + // Page allocator could not reserve enough pages. + BackingStore::ReleaseReservation(reservation_size); + RecordStatus(isolate, AllocationStatus::kOtherFailure); + TRACE_BS("BSw:try failed to allocate pages\n"); + return {}; + } + + // Get a pointer to the start of the buffer, skipping negative guard region + // if necessary. + byte* buffer_start = reinterpret_cast<byte*>(allocation_base) + + (guards ? kNegativeGuardSize : 0); + + //-------------------------------------------------------------------------- + // 3. Commit the initial pages (allow read/write). + //-------------------------------------------------------------------------- + size_t byte_length = initial_pages * wasm::kWasmPageSize; + auto commit_memory = [&] { + return byte_length == 0 || + SetPermissions(GetPlatformPageAllocator(), buffer_start, byte_length, + PageAllocator::kReadWrite); + }; + if (!gc_retry(commit_memory)) { + // SetPermissions put us over the process memory limit. + V8::FatalProcessOutOfMemory(nullptr, "BackingStore::AllocateWasmMemory()"); + TRACE_BS("BSw:try failed to set permissions\n"); + } + + DebugCheckZero(buffer_start, byte_length); // touch the bytes. + + RecordStatus(isolate, did_retry ? AllocationStatus::kSuccessAfterRetry + : AllocationStatus::kSuccess); + + auto result = new BackingStore(buffer_start, // start + byte_length, // length + byte_capacity, // capacity + shared, // shared + true, // is_wasm_memory + true, // free_on_destruct + guards, // has_guard_regions + false); // custom_deleter + + TRACE_BS("BSw:alloc bs=%p mem=%p (length=%zu, capacity=%zu)\n", result, + result->buffer_start(), byte_length, byte_capacity); + + // Shared Wasm memories need an anchor for the memory object list. + if (shared == SharedFlag::kShared) { + result->type_specific_data_.shared_wasm_memory_data = + new SharedWasmMemoryData(); + } + + return std::unique_ptr<BackingStore>(result); +} + +// Allocate a backing store for a Wasm memory. Always use the page allocator +// and add guard regions. +std::unique_ptr<BackingStore> BackingStore::AllocateWasmMemory( + Isolate* isolate, size_t initial_pages, size_t maximum_pages, + SharedFlag shared) { + // Wasm pages must be a multiple of the allocation page size. + DCHECK_EQ(0, wasm::kWasmPageSize % AllocatePageSize()); + + // Enforce engine limitation on the maximum number of pages. + if (initial_pages > wasm::max_mem_pages()) return nullptr; + + auto backing_store = + TryAllocateWasmMemory(isolate, initial_pages, maximum_pages, shared); + if (!backing_store && maximum_pages > initial_pages) { + // If reserving {maximum_pages} failed, try with maximum = initial. + backing_store = + TryAllocateWasmMemory(isolate, initial_pages, initial_pages, shared); + } + return backing_store; +} + +std::unique_ptr<BackingStore> BackingStore::CopyWasmMemory(Isolate* isolate, + size_t new_pages) { + DCHECK_GE(new_pages * wasm::kWasmPageSize, byte_length_); + // Note that we could allocate uninitialized to save initialization cost here, + // but since Wasm memories are allocated by the page allocator, the zeroing + // cost is already built-in. + // TODO(titzer): should we use a suitable maximum here? + auto new_backing_store = BackingStore::AllocateWasmMemory( + isolate, new_pages, new_pages, + is_shared() ? SharedFlag::kShared : SharedFlag::kNotShared); + + if (!new_backing_store || + new_backing_store->has_guard_regions() != has_guard_regions_) { + return {}; + } + + if (byte_length_ > 0) { + memcpy(new_backing_store->buffer_start(), buffer_start_, byte_length_); + } + + return new_backing_store; +} + +// Try to grow the size of a wasm memory in place, without realloc + copy. +bool BackingStore::GrowWasmMemoryInPlace(Isolate* isolate, size_t delta_pages, + size_t max_pages) { + DCHECK(is_wasm_memory_); + max_pages = std::min(max_pages, byte_capacity_ / wasm::kWasmPageSize); + + if (delta_pages == 0) return true; // degenerate grow. + if (delta_pages > max_pages) return false; // would never work. + + // Do a compare-exchange loop, because we also need to adjust page + // permissions. Note that multiple racing grows both try to set page + // permissions for the entire range (to be RW), so the operating system + // should deal with that raciness. We know we succeeded when we can + // compare/swap the old length with the new length. + size_t old_length = 0; + size_t new_length = 0; + while (true) { + old_length = byte_length_.load(std::memory_order_acquire); + size_t current_pages = old_length / wasm::kWasmPageSize; + + // Check if we have exceed the supplied maximum. + if (current_pages > (max_pages - delta_pages)) return false; + + new_length = (current_pages + delta_pages) * wasm::kWasmPageSize; + + // Try to adjust the permissions on the memory. + if (!i::SetPermissions(GetPlatformPageAllocator(), buffer_start_, + new_length, PageAllocator::kReadWrite)) { + return false; + } + if (byte_length_.compare_exchange_weak(old_length, new_length, + std::memory_order_acq_rel)) { + // Successfully updated both the length and permissions. + break; + } + } + + if (!is_shared_) { + // Only do per-isolate accounting for non-shared backing stores. + reinterpret_cast<v8::Isolate*>(isolate) + ->AdjustAmountOfExternalAllocatedMemory(new_length - old_length); + } + return true; +} + +void BackingStore::AttachSharedWasmMemoryObject( + Isolate* isolate, Handle<WasmMemoryObject> memory_object) { + DCHECK(is_wasm_memory_); + DCHECK(is_shared_); + // We need to take the global registry lock for this operation. + GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(isolate, this, + memory_object); +} + +void BackingStore::BroadcastSharedWasmMemoryGrow( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store, + size_t new_pages) { + GlobalBackingStoreRegistry::BroadcastSharedWasmMemoryGrow( + isolate, backing_store, new_pages); +} + +void BackingStore::RemoveSharedWasmMemoryObjects(Isolate* isolate) { + GlobalBackingStoreRegistry::Purge(isolate); +} + +void BackingStore::UpdateSharedWasmMemoryObjects(Isolate* isolate) { + GlobalBackingStoreRegistry::UpdateSharedWasmMemoryObjects(isolate); +} + +std::unique_ptr<BackingStore> BackingStore::WrapAllocation( + Isolate* isolate, void* allocation_base, size_t allocation_length, + SharedFlag shared, bool free_on_destruct) { + auto result = new BackingStore(allocation_base, // start + allocation_length, // length + allocation_length, // capacity + shared, // shared + false, // is_wasm_memory + free_on_destruct, // free_on_destruct + false, // has_guard_regions + false); // custom_deleter + result->SetAllocatorFromIsolate(isolate); + TRACE_BS("BS:wrap bs=%p mem=%p (length=%zu)\n", result, + result->buffer_start(), result->byte_length()); + return std::unique_ptr<BackingStore>(result); +} + +std::unique_ptr<BackingStore> BackingStore::WrapAllocation( + void* allocation_base, size_t allocation_length, + v8::BackingStoreDeleterCallback deleter, void* deleter_data, + SharedFlag shared) { + auto result = new BackingStore(allocation_base, // start + allocation_length, // length + allocation_length, // capacity + shared, // shared + false, // is_wasm_memory + true, // free_on_destruct + false, // has_guard_regions + true); // custom_deleter + result->type_specific_data_.deleter = {deleter, deleter_data}; + TRACE_BS("BS:wrap bs=%p mem=%p (length=%zu)\n", result, + result->buffer_start(), result->byte_length()); + return std::unique_ptr<BackingStore>(result); +} + +std::unique_ptr<BackingStore> BackingStore::EmptyBackingStore( + SharedFlag shared) { + auto result = new BackingStore(nullptr, // start + 0, // length + 0, // capacity + shared, // shared + false, // is_wasm_memory + false, // free_on_destruct + false, // has_guard_regions + false); // custom_deleter + + return std::unique_ptr<BackingStore>(result); +} + +v8::ArrayBuffer::Allocator* BackingStore::get_v8_api_array_buffer_allocator() { + CHECK(!is_wasm_memory_); + auto array_buffer_allocator = + holds_shared_ptr_to_allocator_ + ? type_specific_data_.v8_api_array_buffer_allocator_shared.get() + : type_specific_data_.v8_api_array_buffer_allocator; + CHECK_NOT_NULL(array_buffer_allocator); + return array_buffer_allocator; +} + +SharedWasmMemoryData* BackingStore::get_shared_wasm_memory_data() { + CHECK(is_wasm_memory_ && is_shared_); + auto shared_wasm_memory_data = type_specific_data_.shared_wasm_memory_data; + CHECK(shared_wasm_memory_data); + return shared_wasm_memory_data; +} + +namespace { +// Implementation details of GlobalBackingStoreRegistry. +struct GlobalBackingStoreRegistryImpl { + GlobalBackingStoreRegistryImpl() {} + base::Mutex mutex_; + std::unordered_map<const void*, std::weak_ptr<BackingStore>> map_; +}; +base::LazyInstance<GlobalBackingStoreRegistryImpl>::type global_registry_impl_ = + LAZY_INSTANCE_INITIALIZER; +inline GlobalBackingStoreRegistryImpl* impl() { + return global_registry_impl_.Pointer(); +} +} // namespace + +void GlobalBackingStoreRegistry::Register( + std::shared_ptr<BackingStore> backing_store) { + if (!backing_store || !backing_store->buffer_start()) return; + + if (!backing_store->free_on_destruct()) { + // If the backing store buffer is managed by the embedder, + // then we don't have to guarantee that there is single unique + // BackingStore per buffer_start() because the destructor of + // of the BackingStore will be a no-op in that case. + + // All WASM memory has to be registered. + CHECK(!backing_store->is_wasm_memory()); + return; + } + + base::MutexGuard scope_lock(&impl()->mutex_); + if (backing_store->globally_registered_) return; + TRACE_BS("BS:reg bs=%p mem=%p (length=%zu, capacity=%zu)\n", + backing_store.get(), backing_store->buffer_start(), + backing_store->byte_length(), backing_store->byte_capacity()); + std::weak_ptr<BackingStore> weak = backing_store; + auto result = impl()->map_.insert({backing_store->buffer_start(), weak}); + CHECK(result.second); + backing_store->globally_registered_ = true; +} + +void GlobalBackingStoreRegistry::Unregister(BackingStore* backing_store) { + if (!backing_store->globally_registered_) return; + + DCHECK_NOT_NULL(backing_store->buffer_start()); + + base::MutexGuard scope_lock(&impl()->mutex_); + const auto& result = impl()->map_.find(backing_store->buffer_start()); + if (result != impl()->map_.end()) { + DCHECK(!result->second.lock()); + impl()->map_.erase(result); + } + backing_store->globally_registered_ = false; +} + +std::shared_ptr<BackingStore> GlobalBackingStoreRegistry::Lookup( + void* buffer_start, size_t length) { + base::MutexGuard scope_lock(&impl()->mutex_); + TRACE_BS("BS:lookup mem=%p (%zu bytes)\n", buffer_start, length); + const auto& result = impl()->map_.find(buffer_start); + if (result == impl()->map_.end()) { + return std::shared_ptr<BackingStore>(); + } + auto backing_store = result->second.lock(); + CHECK_EQ(buffer_start, backing_store->buffer_start()); + if (backing_store->is_wasm_memory()) { + // Grow calls to shared WebAssembly threads can be triggered from different + // workers, length equality cannot be guaranteed here. + CHECK_LE(length, backing_store->byte_length()); + } else { + CHECK_EQ(length, backing_store->byte_length()); + } + return backing_store; +} + +void GlobalBackingStoreRegistry::Purge(Isolate* isolate) { + // We need to keep a reference to all backing stores that are inspected + // in the purging loop below. Otherwise, we might get a deadlock + // if the temporary backing store reference created in the loop is + // the last reference. In that case the destructor of the backing store + // may try to take the &impl()->mutex_ in order to unregister itself. + std::vector<std::shared_ptr<BackingStore>> prevent_destruction_under_lock; + base::MutexGuard scope_lock(&impl()->mutex_); + // Purge all entries in the map that refer to the given isolate. + for (auto& entry : impl()->map_) { + auto backing_store = entry.second.lock(); + prevent_destruction_under_lock.emplace_back(backing_store); + if (!backing_store) continue; // skip entries where weak ptr is null + if (!backing_store->is_wasm_memory()) continue; // skip non-wasm memory + if (!backing_store->is_shared()) continue; // skip non-shared memory + SharedWasmMemoryData* shared_data = + backing_store->get_shared_wasm_memory_data(); + // Remove this isolate from the isolates list. + auto& isolates = shared_data->isolates_; + for (size_t i = 0; i < isolates.size(); i++) { + if (isolates[i] == isolate) isolates[i] = nullptr; + } + } +} + +void GlobalBackingStoreRegistry::AddSharedWasmMemoryObject( + Isolate* isolate, BackingStore* backing_store, + Handle<WasmMemoryObject> memory_object) { + // Add to the weak array list of shared memory objects in the isolate. + isolate->AddSharedWasmMemory(memory_object); + + // Add the isolate to the list of isolates sharing this backing store. + base::MutexGuard scope_lock(&impl()->mutex_); + SharedWasmMemoryData* shared_data = + backing_store->get_shared_wasm_memory_data(); + auto& isolates = shared_data->isolates_; + int free_entry = -1; + for (size_t i = 0; i < isolates.size(); i++) { + if (isolates[i] == isolate) return; + if (isolates[i] == nullptr) free_entry = static_cast<int>(i); + } + if (free_entry >= 0) + isolates[free_entry] = isolate; + else + isolates.push_back(isolate); +} + +void GlobalBackingStoreRegistry::BroadcastSharedWasmMemoryGrow( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store, + size_t new_pages) { + { + // The global lock protects the list of isolates per backing store. + base::MutexGuard scope_lock(&impl()->mutex_); + SharedWasmMemoryData* shared_data = + backing_store->get_shared_wasm_memory_data(); + for (Isolate* other : shared_data->isolates_) { + if (other && other != isolate) { + other->stack_guard()->RequestGrowSharedMemory(); + } + } + } + // Update memory objects in this isolate. + UpdateSharedWasmMemoryObjects(isolate); +} + +void GlobalBackingStoreRegistry::UpdateSharedWasmMemoryObjects( + Isolate* isolate) { + HandleScope scope(isolate); + Handle<WeakArrayList> shared_wasm_memories = + isolate->factory()->shared_wasm_memories(); + + for (int i = 0; i < shared_wasm_memories->length(); i++) { + HeapObject obj; + if (!shared_wasm_memories->Get(i).GetHeapObject(&obj)) continue; + + Handle<WasmMemoryObject> memory_object(WasmMemoryObject::cast(obj), + isolate); + Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer(), isolate); + std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore(); + + if (old_buffer->byte_length() != backing_store->byte_length()) { + Handle<JSArrayBuffer> new_buffer = + isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store)); + memory_object->update_instances(isolate, new_buffer); + } + } +} + +} // namespace internal +} // namespace v8 + +#undef TRACE_BS diff --git a/deps/v8/src/objects/backing-store.h b/deps/v8/src/objects/backing-store.h new file mode 100644 index 00000000000000..c9bbcf4ba0b2dc --- /dev/null +++ b/deps/v8/src/objects/backing-store.h @@ -0,0 +1,232 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_BACKING_STORE_H_ +#define V8_OBJECTS_BACKING_STORE_H_ + +#include <memory> + +#include "include/v8-internal.h" +#include "include/v8.h" +#include "src/handles/handles.h" + +namespace v8 { +namespace internal { + +class Isolate; +class WasmMemoryObject; + +// Whether the backing store is shared or not. +enum class SharedFlag : uint8_t { kNotShared, kShared }; + +// Whether the backing store memory is initialied to zero or not. +enum class InitializedFlag : uint8_t { kUninitialized, kZeroInitialized }; + +// Internal information for shared wasm memories. E.g. contains +// a list of all memory objects (across all isolates) that share this +// backing store. +struct SharedWasmMemoryData; + +// The {BackingStore} data structure stores all the low-level details about the +// backing store of an array buffer or Wasm memory, including its base address +// and length, whether it is shared, provided by the embedder, has guard +// regions, etc. Instances of this classes *own* the underlying memory +// when they are created through one of the {Allocate()} methods below, +// and the destructor frees the memory (and page allocation if necessary). +// Backing stores can also *wrap* embedder-allocated memory. In this case, +// they do not own the memory, and upon destruction, they do not deallocate it. +class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase { + public: + ~BackingStore(); + + // Allocate an array buffer backing store using the default method, + // which currently is the embedder-provided array buffer allocator. + static std::unique_ptr<BackingStore> Allocate(Isolate* isolate, + size_t byte_length, + SharedFlag shared, + InitializedFlag initialized); + + // Allocate the backing store for a Wasm memory. + static std::unique_ptr<BackingStore> AllocateWasmMemory(Isolate* isolate, + size_t initial_pages, + size_t maximum_pages, + SharedFlag shared); + + // Create a backing store that wraps existing allocated memory. + // If {free_on_destruct} is {true}, the memory will be freed using the + // ArrayBufferAllocator::Free() callback when this backing store is + // destructed. Otherwise destructing the backing store will do nothing + // to the allocated memory. + static std::unique_ptr<BackingStore> WrapAllocation(Isolate* isolate, + void* allocation_base, + size_t allocation_length, + SharedFlag shared, + bool free_on_destruct); + + static std::unique_ptr<BackingStore> WrapAllocation( + void* allocation_base, size_t allocation_length, + v8::BackingStoreDeleterCallback deleter, void* deleter_data, + SharedFlag shared); + + // Create an empty backing store. + static std::unique_ptr<BackingStore> EmptyBackingStore(SharedFlag shared); + + // Accessors. + void* buffer_start() const { return buffer_start_; } + size_t byte_length() const { + return byte_length_.load(std::memory_order_relaxed); + } + size_t byte_capacity() const { return byte_capacity_; } + bool is_shared() const { return is_shared_; } + bool is_wasm_memory() const { return is_wasm_memory_; } + bool has_guard_regions() const { return has_guard_regions_; } + bool free_on_destruct() const { return free_on_destruct_; } + + // Attempt to grow this backing store in place. + bool GrowWasmMemoryInPlace(Isolate* isolate, size_t delta_pages, + size_t max_pages); + + // Allocate a new, larger, backing store for this Wasm memory and copy the + // contents of this backing store into it. + std::unique_ptr<BackingStore> CopyWasmMemory(Isolate* isolate, + size_t new_pages); + + // Attach the given memory object to this backing store. The memory object + // will be updated if this backing store is grown. + void AttachSharedWasmMemoryObject(Isolate* isolate, + Handle<WasmMemoryObject> memory_object); + + // Send asynchronous updates to attached memory objects in other isolates + // after the backing store has been grown. Memory objects in this + // isolate are updated synchronously. + static void BroadcastSharedWasmMemoryGrow(Isolate* isolate, + std::shared_ptr<BackingStore>, + size_t new_pages); + + // TODO(wasm): address space limitations should be enforced in page alloc. + // These methods enforce a limit on the total amount of address space, + // which is used for both backing stores and wasm memory. + static bool ReserveAddressSpace(uint64_t num_bytes); + static void ReleaseReservation(uint64_t num_bytes); + + // Remove all memory objects in the given isolate that refer to this + // backing store. + static void RemoveSharedWasmMemoryObjects(Isolate* isolate); + + // Update all shared memory objects in this isolate (after a grow operation). + static void UpdateSharedWasmMemoryObjects(Isolate* isolate); + + private: + friend class GlobalBackingStoreRegistry; + + BackingStore(void* buffer_start, size_t byte_length, size_t byte_capacity, + SharedFlag shared, bool is_wasm_memory, bool free_on_destruct, + bool has_guard_regions, bool custom_deleter) + : buffer_start_(buffer_start), + byte_length_(byte_length), + byte_capacity_(byte_capacity), + is_shared_(shared == SharedFlag::kShared), + is_wasm_memory_(is_wasm_memory), + holds_shared_ptr_to_allocator_(false), + free_on_destruct_(free_on_destruct), + has_guard_regions_(has_guard_regions), + globally_registered_(false), + custom_deleter_(custom_deleter) {} + void SetAllocatorFromIsolate(Isolate* isolate); + + void* buffer_start_ = nullptr; + std::atomic<size_t> byte_length_{0}; + size_t byte_capacity_ = 0; + + struct DeleterInfo { + v8::BackingStoreDeleterCallback callback; + void* data; + }; + + union TypeSpecificData { + TypeSpecificData() : v8_api_array_buffer_allocator(nullptr) {} + ~TypeSpecificData() {} + + // If this backing store was allocated through the ArrayBufferAllocator API, + // this is a direct pointer to the API object for freeing the backing + // store. + v8::ArrayBuffer::Allocator* v8_api_array_buffer_allocator; + + // Holds a shared_ptr to the ArrayBuffer::Allocator instance, if requested + // so by the embedder through setting + // Isolate::CreateParams::array_buffer_allocator_shared. + std::shared_ptr<v8::ArrayBuffer::Allocator> + v8_api_array_buffer_allocator_shared; + + // For shared Wasm memories, this is a list of all the attached memory + // objects, which is needed to grow shared backing stores. + SharedWasmMemoryData* shared_wasm_memory_data; + + // Custom deleter for the backing stores that wrap memory blocks that are + // allocated with a custom allocator. + DeleterInfo deleter; + } type_specific_data_; + + bool is_shared_ : 1; + bool is_wasm_memory_ : 1; + bool holds_shared_ptr_to_allocator_ : 1; + bool free_on_destruct_ : 1; + bool has_guard_regions_ : 1; + bool globally_registered_ : 1; + bool custom_deleter_ : 1; + + // Accessors for type-specific data. + v8::ArrayBuffer::Allocator* get_v8_api_array_buffer_allocator(); + SharedWasmMemoryData* get_shared_wasm_memory_data(); + + void Clear(); // Internally clears fields after deallocation. + static std::unique_ptr<BackingStore> TryAllocateWasmMemory( + Isolate* isolate, size_t initial_pages, size_t maximum_pages, + SharedFlag shared); + + DISALLOW_COPY_AND_ASSIGN(BackingStore); +}; + +// A global, per-process mapping from buffer addresses to backing stores. +// This is generally only used for dealing with an embedder that has not +// migrated to the new API which should use proper pointers to manage +// backing stores. +class GlobalBackingStoreRegistry { + public: + // Register a backing store in the global registry. A mapping from the + // {buffer_start} to the backing store object will be added. The backing + // store will automatically unregister itself upon destruction. + static void Register(std::shared_ptr<BackingStore> backing_store); + + // Look up a backing store based on the {buffer_start} pointer. + static std::shared_ptr<BackingStore> Lookup(void* buffer_start, + size_t length); + + private: + friend class BackingStore; + // Unregister a backing store in the global registry. + static void Unregister(BackingStore* backing_store); + + // Adds the given memory object to the backing store's weak list + // of memory objects (under the registry lock). + static void AddSharedWasmMemoryObject(Isolate* isolate, + BackingStore* backing_store, + Handle<WasmMemoryObject> memory_object); + + // Purge any shared wasm memory lists that refer to this isolate. + static void Purge(Isolate* isolate); + + // Broadcast updates to all attached memory objects. + static void BroadcastSharedWasmMemoryGrow( + Isolate* isolate, std::shared_ptr<BackingStore> backing_store, + size_t new_pages); + + // Update all shared memory objects in the given isolate. + static void UpdateSharedWasmMemoryObjects(Isolate* isolate); +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_OBJECTS_BACKING_STORE_H_ diff --git a/deps/v8/src/objects/bigint.cc b/deps/v8/src/objects/bigint.cc index 2905bb44c6f28a..6cc43a78e77f0d 100644 --- a/deps/v8/src/objects/bigint.cc +++ b/deps/v8/src/objects/bigint.cc @@ -1981,14 +1981,13 @@ void BigInt::SerializeDigits(uint8_t* storage) { // The serialization format MUST NOT CHANGE without updating the format // version in value-serializer.cc! MaybeHandle<BigInt> BigInt::FromSerializedDigits( - Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage, - AllocationType allocation) { + Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage) { int bytelength = LengthBits::decode(bitfield); DCHECK(digits_storage.length() == bytelength); bool sign = SignBits::decode(bitfield); int length = (bytelength + kDigitSize - 1) / kDigitSize; // Round up. Handle<MutableBigInt> result = - MutableBigInt::Cast(isolate->factory()->NewBigInt(length, allocation)); + MutableBigInt::Cast(isolate->factory()->NewBigInt(length)); result->initialize_bitfield(sign, length); void* digits = reinterpret_cast<void*>(result->ptr() + kDigitsOffset - kHeapObjectTag); diff --git a/deps/v8/src/objects/bigint.h b/deps/v8/src/objects/bigint.h index ca80547230fbaa..f50e3bcf04d93f 100644 --- a/deps/v8/src/objects/bigint.h +++ b/deps/v8/src/objects/bigint.h @@ -6,8 +6,8 @@ #define V8_OBJECTS_BIGINT_H_ #include "src/common/globals.h" -#include "src/objects/heap-object.h" #include "src/objects/objects.h" +#include "src/objects/primitive-heap-object.h" #include "src/utils/utils.h" // Has to be the last include (doesn't have include guards): @@ -28,7 +28,7 @@ class ValueSerializer; // BigIntBase is just the raw data object underlying a BigInt. Use with care! // Most code should be using BigInts instead. -class BigIntBase : public HeapObject { +class BigIntBase : public PrimitiveHeapObject { public: inline int length() const { int32_t bitfield = RELAXED_READ_INT32_FIELD(*this, kBitfieldOffset); @@ -69,7 +69,7 @@ class BigIntBase : public HeapObject { V(kHeaderSize, 0) \ V(kDigitsOffset, 0) - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, BIGINT_FIELDS) + DEFINE_FIELD_OFFSET_CONSTANTS(PrimitiveHeapObject::kHeaderSize, BIGINT_FIELDS) #undef BIGINT_FIELDS static constexpr bool HasOptionalPadding() { @@ -105,7 +105,7 @@ class BigIntBase : public HeapObject { // Only serves to make macros happy; other code should use IsBigInt. bool IsBigIntBase() const { return true; } - OBJECT_CONSTRUCTORS(BigIntBase, HeapObject); + OBJECT_CONSTRUCTORS(BigIntBase, PrimitiveHeapObject); }; class FreshlyAllocatedBigInt : public BigIntBase { @@ -263,8 +263,8 @@ class BigInt : public BigIntBase { // {DigitsByteLengthForBitfield(GetBitfieldForSerialization())}. void SerializeDigits(uint8_t* storage); V8_WARN_UNUSED_RESULT static MaybeHandle<BigInt> FromSerializedDigits( - Isolate* isolate, uint32_t bitfield, Vector<const uint8_t> digits_storage, - AllocationType allocation); + Isolate* isolate, uint32_t bitfield, + Vector<const uint8_t> digits_storage); OBJECT_CONSTRUCTORS(BigInt, BigIntBase); }; diff --git a/deps/v8/src/objects/code.cc b/deps/v8/src/objects/code.cc index b416df8878a413..a477a7da26fe18 100644 --- a/deps/v8/src/objects/code.cc +++ b/deps/v8/src/objects/code.cc @@ -101,7 +101,6 @@ void Code::CopyFromNoFlush(Heap* heap, const CodeDesc& desc) { // Unbox handles and relocate. Assembler* origin = desc.origin; - AllowDeferredHandleDereference embedding_raw_address; const int mode_mask = RelocInfo::PostCodegenRelocationMask(); for (RelocIterator it(*this, mode_mask); !it.done(); it.next()) { RelocInfo::Mode mode = it.rinfo()->rmode(); @@ -670,8 +669,8 @@ inline void DisassembleCodeRange(Isolate* isolate, std::ostream& os, Code code, } // namespace -void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) { - Isolate* isolate = GetIsolate(); +void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate, + Address current_pc) { os << "kind = " << Kind2String(kind()) << "\n"; if (name == nullptr) { name = GetName(isolate); @@ -683,7 +682,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) { os << "stack_slots = " << stack_slots() << "\n"; } os << "compiler = " << (is_turbofanned() ? "turbofan" : "unknown") << "\n"; - os << "address = " << static_cast<const void*>(this) << "\n\n"; + os << "address = " << reinterpret_cast<void*>(ptr()) << "\n\n"; if (is_off_heap_trampoline()) { int trampoline_size = raw_instruction_size(); @@ -991,8 +990,7 @@ Handle<DependentCode> DependentCode::EnsureSpace( int capacity = kCodesStartIndex + DependentCode::Grow(entries->count()); int grow_by = capacity - entries->length(); return Handle<DependentCode>::cast( - isolate->factory()->CopyWeakFixedArrayAndGrow(entries, grow_by, - AllocationType::kOld)); + isolate->factory()->CopyWeakFixedArrayAndGrow(entries, grow_by)); } bool DependentCode::Compact() { diff --git a/deps/v8/src/objects/code.h b/deps/v8/src/objects/code.h index 6a5ac9f31a8e5b..6f8c378093a5dc 100644 --- a/deps/v8/src/objects/code.h +++ b/deps/v8/src/objects/code.h @@ -61,6 +61,7 @@ class Code : public HeapObject { #ifdef ENABLE_DISASSEMBLER const char* GetName(Isolate* isolate) const; V8_EXPORT_PRIVATE void Disassemble(const char* name, std::ostream& os, + Isolate* isolate, Address current_pc = kNullAddress); #endif diff --git a/deps/v8/src/objects/contexts-inl.h b/deps/v8/src/objects/contexts-inl.h index 0c566dd081a669..669e98591fb8d4 100644 --- a/deps/v8/src/objects/contexts-inl.h +++ b/deps/v8/src/objects/contexts-inl.h @@ -13,6 +13,7 @@ #include "src/objects/js-objects-inl.h" #include "src/objects/map-inl.h" #include "src/objects/objects-inl.h" +#include "src/objects/osr-optimized-code-cache-inl.h" #include "src/objects/regexp-match-info.h" #include "src/objects/scope-info.h" #include "src/objects/shared-function-info.h" @@ -47,10 +48,29 @@ Context ScriptContextTable::get_context(int i) const { OBJECT_CONSTRUCTORS_IMPL(Context, HeapObject) NEVER_READ_ONLY_SPACE_IMPL(Context) CAST_ACCESSOR(Context) -SMI_ACCESSORS(Context, length, kLengthOffset) + +SMI_ACCESSORS(Context, length_and_extension_flag, kLengthOffset) +SYNCHRONIZED_SMI_ACCESSORS(Context, length_and_extension_flag, kLengthOffset) CAST_ACCESSOR(NativeContext) +int Context::length() const { + return LengthField::decode(length_and_extension_flag()); +} + +int Context::synchronized_length() const { + return LengthField::decode(synchronized_length_and_extension_flag()); +} + +void Context::initialize_length_and_extension_bit(int len, + Context::HasExtension flag) { + DCHECK(LengthField::is_valid(len)); + int value = 0; + value = LengthField::update(value, len); + value = HasExtensionField::update(value, flag == Context::HasExtension::kYes); + set_length_and_extension_flag(value); +} + Object Context::get(int index) const { Isolate* isolate = GetIsolateForPtrCompr(*this); return get(isolate, index); @@ -94,11 +114,20 @@ void Context::set_previous(Context context) { set(PREVIOUS_INDEX, context); } Object Context::next_context_link() { return get(Context::NEXT_CONTEXT_LINK); } -bool Context::has_extension() { return !extension().IsTheHole(); } +bool Context::has_extension() { + return static_cast<bool>( + HasExtensionField::decode(length_and_extension_flag())) && + !extension().IsTheHole(); +} + HeapObject Context::extension() { return HeapObject::cast(get(EXTENSION_INDEX)); } -void Context::set_extension(HeapObject object) { set(EXTENSION_INDEX, object); } +void Context::set_extension(HeapObject object) { + set(EXTENSION_INDEX, object); + synchronized_set_length_and_extension_flag( + HasExtensionField::update(length_and_extension_flag(), true)); +} NativeContext Context::native_context() const { Object result = get(NATIVE_CONTEXT_INDEX); @@ -197,7 +226,7 @@ int Context::FunctionMapIndex(LanguageMode language_mode, FunctionKind kind, base = IsAsyncFunction(kind) ? ASYNC_GENERATOR_FUNCTION_MAP_INDEX : GENERATOR_FUNCTION_MAP_INDEX; - } else if (IsAsyncFunction(kind)) { + } else if (IsAsyncFunction(kind) || IsAsyncModule(kind)) { CHECK_FOLLOWS4(ASYNC_FUNCTION_MAP_INDEX, ASYNC_FUNCTION_WITH_NAME_MAP_INDEX, ASYNC_FUNCTION_WITH_HOME_OBJECT_MAP_INDEX, ASYNC_FUNCTION_WITH_NAME_AND_HOME_OBJECT_MAP_INDEX); @@ -252,6 +281,10 @@ void NativeContext::set_microtask_queue(MicrotaskQueue* microtask_queue) { reinterpret_cast<Address>(microtask_queue)); } +OSROptimizedCodeCache NativeContext::GetOSROptimizedCodeCache() { + return OSROptimizedCodeCache::cast(osr_code_cache()); +} + OBJECT_CONSTRUCTORS_IMPL(NativeContext, Context) } // namespace internal diff --git a/deps/v8/src/objects/contexts.cc b/deps/v8/src/objects/contexts.cc index 74fb4477b18096..9dbba06a4d4c99 100644 --- a/deps/v8/src/objects/contexts.cc +++ b/deps/v8/src/objects/contexts.cc @@ -39,12 +39,14 @@ Handle<ScriptContextTable> ScriptContextTable::Extend( bool ScriptContextTable::Lookup(Isolate* isolate, ScriptContextTable table, String name, LookupResult* result) { DisallowHeapAllocation no_gc; + // Static variables cannot be in script contexts. + IsStaticFlag is_static_flag; for (int i = 0; i < table.used(); i++) { Context context = table.get_context(i); DCHECK(context.IsScriptContext()); int slot_index = ScopeInfo::ContextSlotIndex( context.scope_info(), name, &result->mode, &result->init_flag, - &result->maybe_assigned_flag); + &result->maybe_assigned_flag, &is_static_flag); if (slot_index >= 0) { result->context_index = i; @@ -129,10 +131,6 @@ JSGlobalProxy Context::global_proxy() { return native_context().global_proxy_object(); } -void Context::set_global_proxy(JSGlobalProxy object) { - native_context().set_global_proxy_object(object); -} - /** * Lookups a property in an object environment, taking the unscopables into * account. This is used For HasBinding spec algorithms for ObjectEnvironment. @@ -175,7 +173,6 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name, Isolate* isolate = context->GetIsolate(); bool follow_context_chain = (flags & FOLLOW_CONTEXT_CHAIN) != 0; - bool failed_whitelist = false; *index = kNotFound; *attributes = ABSENT; *init_flag = kCreatedInitialized; @@ -287,8 +284,10 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name, VariableMode mode; InitializationFlag flag; MaybeAssignedFlag maybe_assigned_flag; - int slot_index = ScopeInfo::ContextSlotIndex(scope_info, *name, &mode, - &flag, &maybe_assigned_flag); + IsStaticFlag is_static_flag; + int slot_index = + ScopeInfo::ContextSlotIndex(scope_info, *name, &mode, &flag, + &maybe_assigned_flag, &is_static_flag); DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); if (slot_index >= 0) { if (FLAG_trace_contexts) { @@ -357,6 +356,17 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name, return extension; } } + + // Check blacklist. Names that are listed, cannot be resolved further. + Object blacklist = context->get(BLACK_LIST_INDEX); + if (blacklist.IsStringSet() && + StringSet::cast(blacklist).Has(isolate, name)) { + if (FLAG_trace_contexts) { + PrintF(" - name is blacklisted. Aborting.\n"); + } + break; + } + // Check the original context, but do not follow its context chain. Object obj = context->get(WRAPPED_CONTEXT_INDEX); if (obj.IsContext()) { @@ -366,26 +376,12 @@ Handle<Object> Context::Lookup(Handle<Context> context, Handle<String> name, attributes, init_flag, variable_mode); if (!result.is_null()) return result; } - // Check whitelist. Names that do not pass whitelist shall only resolve - // to with, script or native contexts up the context chain. - obj = context->get(WHITE_LIST_INDEX); - if (obj.IsStringSet()) { - failed_whitelist = - failed_whitelist || !StringSet::cast(obj).Has(isolate, name); - } } // 3. Prepare to continue with the previous (next outermost) context. if (context->IsNativeContext()) break; - do { - context = Handle<Context>(context->previous(), isolate); - // If we come across a whitelist context, and the name is not - // whitelisted, then only consider with, script, module or native - // contexts. - } while (failed_whitelist && !context->IsScriptContext() && - !context->IsNativeContext() && !context->IsWithContext() && - !context->IsModuleContext()); + context = Handle<Context>(context->previous(), isolate); } while (follow_context_chain); if (FLAG_trace_contexts) { diff --git a/deps/v8/src/objects/contexts.h b/deps/v8/src/objects/contexts.h index a7b60ff7b95ae7..7fa988be07027f 100644 --- a/deps/v8/src/objects/contexts.h +++ b/deps/v8/src/objects/contexts.h @@ -7,6 +7,7 @@ #include "src/objects/fixed-array.h" #include "src/objects/function-kind.h" +#include "src/objects/osr-optimized-code-cache.h" #include "torque-generated/field-offsets-tq.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -37,21 +38,23 @@ enum ContextLookupFlags { // must always be allocated via Heap::AllocateContext() or // Factory::NewContext. -#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \ - V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \ - V(MAKE_ERROR_INDEX, JSFunction, make_error) \ - V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \ - V(MAKE_SYNTAX_ERROR_INDEX, JSFunction, make_syntax_error) \ - V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \ - V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \ - V(OBJECT_CREATE, JSFunction, object_create) \ - V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \ - V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \ - V(MATH_FLOOR_INDEX, JSFunction, math_floor) \ - V(MATH_POW_INDEX, JSFunction, math_pow) \ - V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \ - promise_internal_constructor) \ - V(IS_PROMISE_INDEX, JSFunction, is_promise) \ +#define NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \ + V(GENERATOR_NEXT_INTERNAL, JSFunction, generator_next_internal) \ + V(ASYNC_MODULE_EVALUATE_INTERNAL, JSFunction, \ + async_module_evaluate_internal) \ + V(MAKE_ERROR_INDEX, JSFunction, make_error) \ + V(MAKE_RANGE_ERROR_INDEX, JSFunction, make_range_error) \ + V(MAKE_SYNTAX_ERROR_INDEX, JSFunction, make_syntax_error) \ + V(MAKE_TYPE_ERROR_INDEX, JSFunction, make_type_error) \ + V(MAKE_URI_ERROR_INDEX, JSFunction, make_uri_error) \ + V(OBJECT_CREATE, JSFunction, object_create) \ + V(REFLECT_APPLY_INDEX, JSFunction, reflect_apply) \ + V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \ + V(MATH_FLOOR_INDEX, JSFunction, math_floor) \ + V(MATH_POW_INDEX, JSFunction, math_pow) \ + V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \ + promise_internal_constructor) \ + V(IS_PROMISE_INDEX, JSFunction, is_promise) \ V(PROMISE_THEN_INDEX, JSFunction, promise_then) #define NATIVE_CONTEXT_FIELDS(V) \ @@ -104,6 +107,8 @@ enum ContextLookupFlags { V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \ call_as_constructor_delegate) \ V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction, call_as_function_delegate) \ + V(CALL_ASYNC_MODULE_FULFILLED, JSFunction, call_async_module_fulfilled) \ + V(CALL_ASYNC_MODULE_REJECTED, JSFunction, call_async_module_rejected) \ V(CALLSITE_FUNCTION_INDEX, JSFunction, callsite_function) \ V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction, context_extension_function) \ V(DATA_PROPERTY_DESCRIPTOR_MAP_INDEX, Map, data_property_descriptor_map) \ @@ -159,6 +164,11 @@ enum ContextLookupFlags { V(INTL_NUMBER_FORMAT_FUNCTION_INDEX, JSFunction, \ intl_number_format_function) \ V(INTL_LOCALE_FUNCTION_INDEX, JSFunction, intl_locale_function) \ + V(INTL_LIST_FORMAT_FUNCTION_INDEX, JSFunction, intl_list_format_function) \ + V(INTL_PLURAL_RULES_FUNCTION_INDEX, JSFunction, intl_plural_rules_function) \ + V(INTL_RELATIVE_TIME_FORMAT_FUNCTION_INDEX, JSFunction, \ + intl_relative_time_format_function) \ + V(INTL_SEGMENTER_FUNCTION_INDEX, JSFunction, intl_segmenter_function) \ V(INTL_SEGMENT_ITERATOR_MAP_INDEX, Map, intl_segment_iterator_map) \ V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map) \ V(JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, Map, \ @@ -233,6 +243,7 @@ enum ContextLookupFlags { V(REGEXP_PROTOTYPE_MAP_INDEX, Map, regexp_prototype_map) \ V(REGEXP_REPLACE_FUNCTION_INDEX, JSFunction, regexp_replace_function) \ V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \ + V(REGEXP_RESULT_INDICES_MAP_INDEX, Map, regexp_result_indices_map) \ V(REGEXP_SEARCH_FUNCTION_INDEX, JSFunction, regexp_search_function) \ V(REGEXP_SPLIT_FUNCTION_INDEX, JSFunction, regexp_split_function) \ V(INITIAL_REGEXP_STRING_ITERATOR_PROTOTYPE_MAP_INDEX, Map, \ @@ -345,6 +356,7 @@ enum ContextLookupFlags { V(WEAKMAP_SET_INDEX, JSFunction, weakmap_set) \ V(WEAKMAP_GET_INDEX, JSFunction, weakmap_get) \ V(WEAKSET_ADD_INDEX, JSFunction, weakset_add) \ + V(OSR_CODE_CACHE_INDEX, WeakFixedArray, osr_code_cache) \ NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) // A table of all script contexts. Every loaded top-level script with top-level @@ -443,9 +455,19 @@ class Context : public HeapObject { DECL_CAST(Context) + enum class HasExtension { kYes, kNo }; + // [length]: length of the context. V8_INLINE int length() const; - V8_INLINE void set_length(int value); + V8_INLINE int synchronized_length() const; + V8_INLINE void initialize_length_and_extension_bit( + int len, HasExtension flag = HasExtension::kNo); + + // We use the 30th bit. Otherwise if we set the 31st bit, + // the number would be pottentially bigger than an SMI. + // Any DCHECK(Smi::IsValue(...)) would fail. + using LengthField = BitField<int, 0, kSmiValueSize - 2>; + using HasExtensionField = BitField<int, kSmiValueSize - 2, 1>; // Setter and getter for elements. V8_INLINE Object get(int index) const; @@ -458,18 +480,18 @@ class Context : public HeapObject { TORQUE_GENERATED_CONTEXT_FIELDS) // TODO(v8:8989): [torque] Support marker constants. /* TODO(ishell): remove this fixedArray-like header size. */ - static const int kHeaderSize = kScopeInfoOffset; + static const int kFixedArrayLikeHeaderSize = kScopeInfoOffset; static const int kStartOfTaggedFieldsOffset = kScopeInfoOffset; /* Header size. */ \ /* TODO(ishell): use this as header size once MIN_CONTEXT_SLOTS */ \ /* is removed in favour of offset-based access to common fields. */ \ - static const int kTodoHeaderSize = kSize; + static const int kTodoHeaderSize = kHeaderSize; // Garbage collection support. V8_INLINE static constexpr int SizeFor(int length) { // TODO(ishell): switch to kTodoHeaderSize based approach once we no longer // reference common Context fields via index - return kHeaderSize + length * kTaggedSize; + return kFixedArrayLikeHeaderSize + length * kTaggedSize; } // Code Generation support. @@ -517,7 +539,7 @@ class Context : public HeapObject { // These slots hold values in debug evaluate contexts. WRAPPED_CONTEXT_INDEX = MIN_CONTEXT_SLOTS, - WHITE_LIST_INDEX = MIN_CONTEXT_SLOTS + 1 + BLACK_LIST_INDEX = MIN_CONTEXT_SLOTS + 1 }; // A region of native context entries containing maps for functions created @@ -558,7 +580,6 @@ class Context : public HeapObject { // Returns a JSGlobalProxy object or null. V8_EXPORT_PRIVATE JSGlobalProxy global_proxy(); - void set_global_proxy(JSGlobalProxy global); // Get the JSGlobalObject object. V8_EXPORT_PRIVATE JSGlobalObject global_object(); @@ -652,6 +673,8 @@ class Context : public HeapObject { #endif OBJECT_CONSTRUCTORS(Context, HeapObject); + DECL_INT_ACCESSORS(length_and_extension_flag) + DECL_SYNCHRONIZED_INT_ACCESSORS(length_and_extension_flag) }; class NativeContext : public Context { @@ -696,6 +719,8 @@ class NativeContext : public Context { void SetDeoptimizedCodeListHead(Object head); Object DeoptimizedCodeListHead(); + inline OSROptimizedCodeCache GetOSROptimizedCodeCache(); + void ResetErrorsThrown(); void IncrementErrorsThrown(); int GetErrorsThrown(); diff --git a/deps/v8/src/objects/data-handler.h b/deps/v8/src/objects/data-handler.h index 667b19b3d45b85..c9c0cf4cbcfaad 100644 --- a/deps/v8/src/objects/data-handler.h +++ b/deps/v8/src/objects/data-handler.h @@ -41,7 +41,7 @@ class DataHandler : public Struct { static const int kSizeWithData0 = kData1Offset; static const int kSizeWithData1 = kData2Offset; static const int kSizeWithData2 = kData3Offset; - static const int kSizeWithData3 = kSize; + static const int kSizeWithData3 = kHeaderSize; DECL_CAST(DataHandler) diff --git a/deps/v8/src/objects/debug-objects-inl.h b/deps/v8/src/objects/debug-objects-inl.h index 273f710c3b6269..8189481394b7a6 100644 --- a/deps/v8/src/objects/debug-objects-inl.h +++ b/deps/v8/src/objects/debug-objects-inl.h @@ -21,24 +21,16 @@ namespace internal { OBJECT_CONSTRUCTORS_IMPL(BreakPoint, Tuple2) OBJECT_CONSTRUCTORS_IMPL(BreakPointInfo, Tuple2) OBJECT_CONSTRUCTORS_IMPL(CoverageInfo, FixedArray) -OBJECT_CONSTRUCTORS_IMPL(DebugInfo, Struct) +TQ_OBJECT_CONSTRUCTORS_IMPL(DebugInfo) NEVER_READ_ONLY_SPACE_IMPL(DebugInfo) CAST_ACCESSOR(BreakPointInfo) -CAST_ACCESSOR(DebugInfo) CAST_ACCESSOR(CoverageInfo) CAST_ACCESSOR(BreakPoint) -SMI_ACCESSORS(DebugInfo, flags, kFlagsOffset) -ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) -SMI_ACCESSORS(DebugInfo, debugger_hints, kDebuggerHintsOffset) -ACCESSORS(DebugInfo, script, Object, kScriptOffset) -ACCESSORS(DebugInfo, original_bytecode_array, Object, - kOriginalBytecodeArrayOffset) -ACCESSORS(DebugInfo, debug_bytecode_array, Object, kDebugBytecodeArrayOffset) -ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsOffset) -ACCESSORS(DebugInfo, coverage_info, Object, kCoverageInfoOffset) +TQ_SMI_ACCESSORS(DebugInfo, flags) +TQ_SMI_ACCESSORS(DebugInfo, debugger_hints) BIT_FIELD_ACCESSORS(DebugInfo, debugger_hints, side_effect_state, DebugInfo::SideEffectStateBits) diff --git a/deps/v8/src/objects/debug-objects.h b/deps/v8/src/objects/debug-objects.h index 243caaa526845c..39f42c11688608 100644 --- a/deps/v8/src/objects/debug-objects.h +++ b/deps/v8/src/objects/debug-objects.h @@ -5,6 +5,8 @@ #ifndef V8_OBJECTS_DEBUG_OBJECTS_H_ #define V8_OBJECTS_DEBUG_OBJECTS_H_ +#include <memory> + #include "src/objects/fixed-array.h" #include "src/objects/objects.h" #include "src/objects/struct.h" @@ -20,7 +22,7 @@ class BytecodeArray; // The DebugInfo class holds additional information for a function being // debugged. -class DebugInfo : public Struct { +class DebugInfo : public TorqueGeneratedDebugInfo<DebugInfo, Struct> { public: NEVER_READ_ONLY_SPACE enum Flag { @@ -38,15 +40,9 @@ class DebugInfo : public Struct { // A bitfield that lists uses of the current instance. DECL_INT_ACCESSORS(flags) - // The shared function info for the source being debugged. - DECL_ACCESSORS(shared, SharedFunctionInfo) - // Bit field containing various information collected for debugging. DECL_INT_ACCESSORS(debugger_hints) - // Script field from shared function info. - DECL_ACCESSORS(script, Object) - // DebugInfo can be detached from the SharedFunctionInfo iff it is empty. bool IsEmpty() const; @@ -83,17 +79,6 @@ class DebugInfo : public Struct { void ClearBreakAtEntry(); bool BreakAtEntry() const; - // The original uninstrumented bytecode array for functions with break - // points - the instrumented bytecode is held in the shared function info. - DECL_ACCESSORS(original_bytecode_array, Object) - - // The debug instrumented bytecode array for functions with break points - // - also pointed to by the shared function info. - DECL_ACCESSORS(debug_bytecode_array, Object) - - // Fixed array holding status information for each active break point. - DECL_ACCESSORS(break_points, FixedArray) - // Check if there is a break point at a source position. bool HasBreakPoint(Isolate* isolate, int source_position); // Attempt to clear a break point. Return true if successful. @@ -160,17 +145,9 @@ class DebugInfo : public Struct { // Clears all fields related to block coverage. void ClearCoverageInfo(Isolate* isolate); - DECL_ACCESSORS(coverage_info, Object) - - DECL_CAST(DebugInfo) // Dispatched behavior. DECL_PRINTER(DebugInfo) - DECL_VERIFIER(DebugInfo) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(Struct::kHeaderSize, - TORQUE_GENERATED_DEBUG_INFO_FIELDS) static const int kEstimatedNofBreakPointsInFunction = 4; @@ -178,7 +155,7 @@ class DebugInfo : public Struct { // Get the break point info object for a source position. Object GetBreakPointInfo(Isolate* isolate, int source_position); - OBJECT_CONSTRUCTORS(DebugInfo, Struct); + TQ_OBJECT_CONSTRUCTORS(DebugInfo) }; // The BreakPointInfo class holds information for break points set in a diff --git a/deps/v8/src/objects/descriptor-array-inl.h b/deps/v8/src/objects/descriptor-array-inl.h index e2805d795a03b0..5ea14c1e6003c7 100644 --- a/deps/v8/src/objects/descriptor-array-inl.h +++ b/deps/v8/src/objects/descriptor-array-inl.h @@ -58,33 +58,35 @@ void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) { set_enum_cache(array.enum_cache()); } -int DescriptorArray::Search(Name name, int valid_descriptors) { +InternalIndex DescriptorArray::Search(Name name, int valid_descriptors) { DCHECK(name.IsUniqueName()); - return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, - nullptr); + return InternalIndex( + internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, nullptr)); } -int DescriptorArray::Search(Name name, Map map) { +InternalIndex DescriptorArray::Search(Name name, Map map) { DCHECK(name.IsUniqueName()); int number_of_own_descriptors = map.NumberOfOwnDescriptors(); - if (number_of_own_descriptors == 0) return kNotFound; + if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); return Search(name, number_of_own_descriptors); } -int DescriptorArray::SearchWithCache(Isolate* isolate, Name name, Map map) { +InternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name, + Map map) { DCHECK(name.IsUniqueName()); int number_of_own_descriptors = map.NumberOfOwnDescriptors(); - if (number_of_own_descriptors == 0) return kNotFound; + if (number_of_own_descriptors == 0) return InternalIndex::NotFound(); DescriptorLookupCache* cache = isolate->descriptor_lookup_cache(); int number = cache->Lookup(map, name); if (number == DescriptorLookupCache::kAbsent) { - number = Search(name, number_of_own_descriptors); + InternalIndex result = Search(name, number_of_own_descriptors); + number = result.is_found() ? result.as_int() : DescriptorArray::kNotFound; cache->Update(map, name, number); } - - return number; + if (number == DescriptorArray::kNotFound) return InternalIndex::NotFound(); + return InternalIndex(number); } ObjectSlot DescriptorArray::GetFirstPointerSlot() { @@ -102,26 +104,27 @@ ObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) { return RawField(OffsetOfDescriptorAt(descriptor)); } -Name DescriptorArray::GetKey(int descriptor_number) const { +Name DescriptorArray::GetKey(InternalIndex descriptor_number) const { Isolate* isolate = GetIsolateForPtrCompr(*this); return GetKey(isolate, descriptor_number); } -Name DescriptorArray::GetKey(Isolate* isolate, int descriptor_number) const { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); +Name DescriptorArray::GetKey(Isolate* isolate, + InternalIndex descriptor_number) const { + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); return Name::cast(EntryKeyField::Relaxed_Load(isolate, *this, entry_offset)); } -void DescriptorArray::SetKey(int descriptor_number, Name key) { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); +void DescriptorArray::SetKey(InternalIndex descriptor_number, Name key) { + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); EntryKeyField::Relaxed_Store(*this, entry_offset, key); WRITE_BARRIER(*this, entry_offset + kEntryKeyOffset, key); } int DescriptorArray::GetSortedKeyIndex(int descriptor_number) { - return GetDetails(descriptor_number).pointer(); + return GetDetails(InternalIndex(descriptor_number)).pointer(); } Name DescriptorArray::GetSortedKey(int descriptor_number) { @@ -130,81 +133,83 @@ Name DescriptorArray::GetSortedKey(int descriptor_number) { } Name DescriptorArray::GetSortedKey(Isolate* isolate, int descriptor_number) { - return GetKey(isolate, GetSortedKeyIndex(descriptor_number)); + return GetKey(isolate, InternalIndex(GetSortedKeyIndex(descriptor_number))); } void DescriptorArray::SetSortedKey(int descriptor_number, int pointer) { - PropertyDetails details = GetDetails(descriptor_number); - SetDetails(descriptor_number, details.set_pointer(pointer)); + PropertyDetails details = GetDetails(InternalIndex(descriptor_number)); + SetDetails(InternalIndex(descriptor_number), details.set_pointer(pointer)); } -Object DescriptorArray::GetStrongValue(int descriptor_number) { +Object DescriptorArray::GetStrongValue(InternalIndex descriptor_number) { Isolate* isolate = GetIsolateForPtrCompr(*this); return GetStrongValue(isolate, descriptor_number); } Object DescriptorArray::GetStrongValue(Isolate* isolate, - int descriptor_number) { + InternalIndex descriptor_number) { return GetValue(isolate, descriptor_number).cast<Object>(); } -void DescriptorArray::SetValue(int descriptor_number, MaybeObject value) { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); +void DescriptorArray::SetValue(InternalIndex descriptor_number, + MaybeObject value) { + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); EntryValueField::Relaxed_Store(*this, entry_offset, value); WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value); } -MaybeObject DescriptorArray::GetValue(int descriptor_number) { +MaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) { Isolate* isolate = GetIsolateForPtrCompr(*this); return GetValue(isolate, descriptor_number); } -MaybeObject DescriptorArray::GetValue(Isolate* isolate, int descriptor_number) { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); +MaybeObject DescriptorArray::GetValue(Isolate* isolate, + InternalIndex descriptor_number) { + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); return EntryValueField::Relaxed_Load(isolate, *this, entry_offset); } -PropertyDetails DescriptorArray::GetDetails(int descriptor_number) { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); +PropertyDetails DescriptorArray::GetDetails(InternalIndex descriptor_number) { + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset); return PropertyDetails(details); } -void DescriptorArray::SetDetails(int descriptor_number, +void DescriptorArray::SetDetails(InternalIndex descriptor_number, PropertyDetails details) { - DCHECK_LT(descriptor_number, number_of_descriptors()); - int entry_offset = OffsetOfDescriptorAt(descriptor_number); + DCHECK_LT(descriptor_number.as_int(), number_of_descriptors()); + int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int()); EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi()); } -int DescriptorArray::GetFieldIndex(int descriptor_number) { +int DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) { DCHECK_EQ(GetDetails(descriptor_number).location(), kField); return GetDetails(descriptor_number).field_index(); } -FieldType DescriptorArray::GetFieldType(int descriptor_number) { +FieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) { Isolate* isolate = GetIsolateForPtrCompr(*this); return GetFieldType(isolate, descriptor_number); } FieldType DescriptorArray::GetFieldType(Isolate* isolate, - int descriptor_number) { + InternalIndex descriptor_number) { DCHECK_EQ(GetDetails(descriptor_number).location(), kField); MaybeObject wrapped_type = GetValue(isolate, descriptor_number); return Map::UnwrapFieldType(wrapped_type); } -void DescriptorArray::Set(int descriptor_number, Name key, MaybeObject value, - PropertyDetails details) { +void DescriptorArray::Set(InternalIndex descriptor_number, Name key, + MaybeObject value, PropertyDetails details) { SetKey(descriptor_number, key); SetDetails(descriptor_number, details); SetValue(descriptor_number, value); } -void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { +void DescriptorArray::Set(InternalIndex descriptor_number, Descriptor* desc) { Name key = *desc->GetKey(); MaybeObject value = *desc->GetValue(); Set(descriptor_number, key, value, desc->GetDetails()); @@ -215,7 +220,7 @@ void DescriptorArray::Append(Descriptor* desc) { int descriptor_number = number_of_descriptors(); DCHECK_LE(descriptor_number + 1, number_of_all_descriptors()); set_number_of_descriptors(descriptor_number + 1); - Set(descriptor_number, desc); + Set(InternalIndex(descriptor_number), desc); uint32_t hash = desc->GetKey()->Hash(); diff --git a/deps/v8/src/objects/descriptor-array.h b/deps/v8/src/objects/descriptor-array.h index 0f17cd22eac27a..73b94b7cfa2c69 100644 --- a/deps/v8/src/objects/descriptor-array.h +++ b/deps/v8/src/objects/descriptor-array.h @@ -6,6 +6,8 @@ #define V8_OBJECTS_DESCRIPTOR_ARRAY_H_ #include "src/objects/fixed-array.h" +// TODO(jkummerow): Consider forward-declaring instead. +#include "src/objects/internal-index.h" #include "src/objects/objects.h" #include "src/objects/struct.h" #include "src/utils/utils.h" @@ -62,27 +64,29 @@ class DescriptorArray : public HeapObject { Handle<FixedArray> indices); // Accessors for fetching instance descriptor at descriptor number. - inline Name GetKey(int descriptor_number) const; - inline Name GetKey(Isolate* isolate, int descriptor_number) const; - inline Object GetStrongValue(int descriptor_number); - inline Object GetStrongValue(Isolate* isolate, int descriptor_number); - inline MaybeObject GetValue(int descriptor_number); - inline MaybeObject GetValue(Isolate* isolate, int descriptor_number); - inline PropertyDetails GetDetails(int descriptor_number); - inline int GetFieldIndex(int descriptor_number); - inline FieldType GetFieldType(int descriptor_number); - inline FieldType GetFieldType(Isolate* isolate, int descriptor_number); + inline Name GetKey(InternalIndex descriptor_number) const; + inline Name GetKey(Isolate* isolate, InternalIndex descriptor_number) const; + inline Object GetStrongValue(InternalIndex descriptor_number); + inline Object GetStrongValue(Isolate* isolate, + InternalIndex descriptor_number); + inline MaybeObject GetValue(InternalIndex descriptor_number); + inline MaybeObject GetValue(Isolate* isolate, + InternalIndex descriptor_number); + inline PropertyDetails GetDetails(InternalIndex descriptor_number); + inline int GetFieldIndex(InternalIndex descriptor_number); + inline FieldType GetFieldType(InternalIndex descriptor_number); + inline FieldType GetFieldType(Isolate* isolate, + InternalIndex descriptor_number); inline Name GetSortedKey(int descriptor_number); inline Name GetSortedKey(Isolate* isolate, int descriptor_number); inline int GetSortedKeyIndex(int descriptor_number); - inline void SetSortedKey(int pointer, int descriptor_number); // Accessor for complete descriptor. - inline void Set(int descriptor_number, Descriptor* desc); - inline void Set(int descriptor_number, Name key, MaybeObject value, + inline void Set(InternalIndex descriptor_number, Descriptor* desc); + inline void Set(InternalIndex descriptor_number, Name key, MaybeObject value, PropertyDetails details); - void Replace(int descriptor_number, Descriptor* descriptor); + void Replace(InternalIndex descriptor_number, Descriptor* descriptor); // Generalizes constness, representation and field type of all field // descriptors. @@ -109,20 +113,20 @@ class DescriptorArray : public HeapObject { void Sort(); // Search the instance descriptors for given name. - V8_INLINE int Search(Name name, int number_of_own_descriptors); - V8_INLINE int Search(Name name, Map map); + V8_INLINE InternalIndex Search(Name name, int number_of_own_descriptors); + V8_INLINE InternalIndex Search(Name name, Map map); // As the above, but uses DescriptorLookupCache and updates it when // necessary. - V8_INLINE int SearchWithCache(Isolate* isolate, Name name, Map map); + V8_INLINE InternalIndex SearchWithCache(Isolate* isolate, Name name, Map map); bool IsEqualUpTo(DescriptorArray desc, int nof_descriptors); // Allocates a DescriptorArray, but returns the singleton // empty descriptor array object if number_of_descriptors is 0. - V8_EXPORT_PRIVATE static Handle<DescriptorArray> Allocate( - Isolate* isolate, int nof_descriptors, int slack, - AllocationType allocation = AllocationType::kYoung); + V8_EXPORT_PRIVATE static Handle<DescriptorArray> Allocate(Isolate* isolate, + int nof_descriptors, + int slack); void Initialize(EnumCache enum_cache, HeapObject undefined_value, int nof_descriptors, int slack); @@ -176,7 +180,7 @@ class DescriptorArray : public HeapObject { // Print all the descriptors. void PrintDescriptors(std::ostream& os); - void PrintDescriptorDetails(std::ostream& os, int descriptor, + void PrintDescriptorDetails(std::ostream& os, InternalIndex descriptor, PropertyDetails::PrintMode mode); DECL_PRINTER(DescriptorArray) @@ -210,13 +214,16 @@ class DescriptorArray : public HeapObject { private: DECL_INT16_ACCESSORS(filler16bits) - inline void SetKey(int descriptor_number, Name key); - inline void SetValue(int descriptor_number, MaybeObject value); - inline void SetDetails(int descriptor_number, PropertyDetails details); + inline void SetKey(InternalIndex descriptor_number, Name key); + inline void SetValue(InternalIndex descriptor_number, MaybeObject value); + inline void SetDetails(InternalIndex descriptor_number, + PropertyDetails details); // Transfer a complete descriptor from the src descriptor array to this // descriptor array. - void CopyFrom(int index, DescriptorArray src); + void CopyFrom(InternalIndex index, DescriptorArray src); + + inline void SetSortedKey(int pointer, int descriptor_number); // Swap first and second descriptor. inline void SwapSortedKeys(int first, int second); diff --git a/deps/v8/src/objects/dictionary-inl.h b/deps/v8/src/objects/dictionary-inl.h index 92c1d0940f5cd0..18b2ee67a4db59 100644 --- a/deps/v8/src/objects/dictionary-inl.h +++ b/deps/v8/src/objects/dictionary-inl.h @@ -7,8 +7,10 @@ #include "src/objects/dictionary.h" +#include "src/execution/isolate-utils-inl.h" #include "src/numbers/hash-seed-inl.h" #include "src/objects/hash-table-inl.h" +#include "src/objects/objects-inl.h" #include "src/objects/oddball.h" #include "src/objects/property-cell-inl.h" @@ -27,10 +29,62 @@ template <typename Derived, typename Shape> Dictionary<Derived, Shape>::Dictionary(Address ptr) : HashTable<Derived, Shape>(ptr) {} +template <typename Derived, typename Shape> +Object Dictionary<Derived, Shape>::ValueAt(int entry) { + Isolate* isolate = GetIsolateForPtrCompr(*this); + return ValueAt(isolate, entry); +} + +template <typename Derived, typename Shape> +Object Dictionary<Derived, Shape>::ValueAt(Isolate* isolate, int entry) { + return this->get(isolate, DerivedHashTable::EntryToIndex(entry) + 1); +} + +template <typename Derived, typename Shape> +void Dictionary<Derived, Shape>::ValueAtPut(int entry, Object value) { + this->set(DerivedHashTable::EntryToIndex(entry) + 1, value); +} + +template <typename Derived, typename Shape> +PropertyDetails Dictionary<Derived, Shape>::DetailsAt(int entry) { + return Shape::DetailsAt(Derived::cast(*this), entry); +} + +template <typename Derived, typename Shape> +void Dictionary<Derived, Shape>::DetailsAtPut(Isolate* isolate, int entry, + PropertyDetails value) { + Shape::DetailsAtPut(isolate, Derived::cast(*this), entry, value); +} + template <typename Derived, typename Shape> BaseNameDictionary<Derived, Shape>::BaseNameDictionary(Address ptr) : Dictionary<Derived, Shape>(ptr) {} +template <typename Derived, typename Shape> +void BaseNameDictionary<Derived, Shape>::SetNextEnumerationIndex(int index) { + DCHECK_NE(0, index); + this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); +} + +template <typename Derived, typename Shape> +int BaseNameDictionary<Derived, Shape>::NextEnumerationIndex() { + return Smi::ToInt(this->get(kNextEnumerationIndexIndex)); +} + +template <typename Derived, typename Shape> +void BaseNameDictionary<Derived, Shape>::SetHash(int hash) { + DCHECK(PropertyArray::HashField::is_valid(hash)); + this->set(kObjectHashIndex, Smi::FromInt(hash)); +} + +template <typename Derived, typename Shape> +int BaseNameDictionary<Derived, Shape>::Hash() const { + Object hash_obj = this->get(kObjectHashIndex); + int hash = Smi::ToInt(hash_obj); + DCHECK(PropertyArray::HashField::is_valid(hash)); + return hash; +} + GlobalDictionary::GlobalDictionary(Address ptr) : BaseNameDictionary<GlobalDictionary, GlobalDictionaryShape>(ptr) { SLOW_DCHECK(IsGlobalDictionary()); @@ -90,6 +144,25 @@ void Dictionary<Derived, Shape>::SetEntry(Isolate* isolate, int entry, if (Shape::kHasDetails) DetailsAtPut(isolate, entry, details); } +template <typename Key> +template <typename Dictionary> +PropertyDetails BaseDictionaryShape<Key>::DetailsAt(Dictionary dict, + int entry) { + STATIC_ASSERT(Dictionary::kEntrySize == 3); + DCHECK_GE(entry, 0); // Not found is -1, which is not caught by get(). + return PropertyDetails(Smi::cast(dict.get(Dictionary::EntryToIndex(entry) + + Dictionary::kEntryDetailsIndex))); +} + +template <typename Key> +template <typename Dictionary> +void BaseDictionaryShape<Key>::DetailsAtPut(Isolate* isolate, Dictionary dict, + int entry, PropertyDetails value) { + STATIC_ASSERT(Dictionary::kEntrySize == 3); + dict.set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex, + value.AsSmi()); + } + Object GlobalDictionaryShape::Unwrap(Object object) { return PropertyCell::cast(object).name(); } diff --git a/deps/v8/src/objects/dictionary.h b/deps/v8/src/objects/dictionary.h index 957c06d8ec74b7..35137c7d945430 100644 --- a/deps/v8/src/objects/dictionary.h +++ b/deps/v8/src/objects/dictionary.h @@ -31,28 +31,17 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) Dictionary public: using Key = typename Shape::Key; // Returns the value at entry. - Object ValueAt(int entry) { - Isolate* isolate = GetIsolateForPtrCompr(*this); - return ValueAt(isolate, entry); - } - Object ValueAt(Isolate* isolate, int entry) { - return this->get(isolate, DerivedHashTable::EntryToIndex(entry) + 1); - } + inline Object ValueAt(int entry); + inline Object ValueAt(Isolate* isolate, int entry); // Set the value for entry. - void ValueAtPut(int entry, Object value) { - this->set(DerivedHashTable::EntryToIndex(entry) + 1, value); - } + inline void ValueAtPut(int entry, Object value); // Returns the property details for the property at entry. - PropertyDetails DetailsAt(int entry) { - return Shape::DetailsAt(Derived::cast(*this), entry); - } + inline PropertyDetails DetailsAt(int entry); // Set the details for entry. - void DetailsAtPut(Isolate* isolate, int entry, PropertyDetails value) { - Shape::DetailsAtPut(isolate, Derived::cast(*this), entry, value); - } + inline void DetailsAtPut(Isolate* isolate, int entry, PropertyDetails value); // Delete a property from the dictionary. V8_WARN_UNUSED_RESULT static Handle<Derived> DeleteEntry( @@ -100,20 +89,11 @@ class BaseDictionaryShape : public BaseShape<Key> { public: static const bool kHasDetails = true; template <typename Dictionary> - static inline PropertyDetails DetailsAt(Dictionary dict, int entry) { - STATIC_ASSERT(Dictionary::kEntrySize == 3); - DCHECK_GE(entry, 0); // Not found is -1, which is not caught by get(). - return PropertyDetails(Smi::cast(dict.get(Dictionary::EntryToIndex(entry) + - Dictionary::kEntryDetailsIndex))); - } + static inline PropertyDetails DetailsAt(Dictionary dict, int entry); template <typename Dictionary> static inline void DetailsAtPut(Isolate* isolate, Dictionary dict, int entry, - PropertyDetails value) { - STATIC_ASSERT(Dictionary::kEntrySize == 3); - dict.set(Dictionary::EntryToIndex(entry) + Dictionary::kEntryDetailsIndex, - value.AsSmi()); - } + PropertyDetails value); }; class NameDictionaryShape : public BaseDictionaryShape<Handle<Name>> { @@ -141,26 +121,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary static const int kEntryValueIndex = 1; // Accessors for next enumeration index. - void SetNextEnumerationIndex(int index) { - DCHECK_NE(0, index); - this->set(kNextEnumerationIndexIndex, Smi::FromInt(index)); - } + inline void SetNextEnumerationIndex(int index); + inline int NextEnumerationIndex(); - int NextEnumerationIndex() { - return Smi::ToInt(this->get(kNextEnumerationIndexIndex)); - } - - void SetHash(int hash) { - DCHECK(PropertyArray::HashField::is_valid(hash)); - this->set(kObjectHashIndex, Smi::FromInt(hash)); - } - - int Hash() const { - Object hash_obj = this->get(kObjectHashIndex); - int hash = Smi::ToInt(hash_obj); - DCHECK(PropertyArray::HashField::is_valid(hash)); - return hash; - } + inline void SetHash(int hash); + inline int Hash() const; // Creates a new dictionary. V8_WARN_UNUSED_RESULT static Handle<Derived> New( diff --git a/deps/v8/src/objects/elements.cc b/deps/v8/src/objects/elements.cc index 6e5648d2f4d5a2..686f1a9b1aeb51 100644 --- a/deps/v8/src/objects/elements.cc +++ b/deps/v8/src/objects/elements.cc @@ -8,6 +8,7 @@ #include "src/execution/arguments.h" #include "src/execution/frames.h" #include "src/execution/isolate-inl.h" +#include "src/execution/protectors-inl.h" #include "src/heap/factory.h" #include "src/heap/heap-inl.h" // For MaxNumberToStringCacheSize. #include "src/heap/heap-write-barrier-inl.h" @@ -509,11 +510,11 @@ Maybe<int64_t> IndexOfValueSlowPath(Isolate* isolate, Handle<JSObject> receiver, // that take an entry (instead of an index) as an argument. class InternalElementsAccessor : public ElementsAccessor { public: - uint32_t GetEntryForIndex(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index) override = 0; + InternalIndex GetEntryForIndex(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index) override = 0; - PropertyDetails GetDetails(JSObject holder, uint32_t entry) override = 0; + PropertyDetails GetDetails(JSObject holder, InternalIndex entry) override = 0; }; // Base class for element handler implementations. Contains the @@ -594,16 +595,17 @@ class ElementsAccessorBase : public InternalElementsAccessor { FixedArrayBase backing_store, PropertyFilter filter = ALL_PROPERTIES) { return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index, - filter) != kMaxUInt32; + filter) + .is_found(); } - bool HasEntry(JSObject holder, uint32_t entry) final { + bool HasEntry(JSObject holder, InternalIndex entry) final { return Subclass::HasEntryImpl(holder.GetIsolate(), holder.elements(), entry); } static bool HasEntryImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { UNIMPLEMENTED(); } @@ -615,33 +617,33 @@ class ElementsAccessorBase : public InternalElementsAccessor { return false; } - Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) final { + Handle<Object> Get(Handle<JSObject> holder, InternalIndex entry) final { return Subclass::GetInternalImpl(holder, entry); } static Handle<Object> GetInternalImpl(Handle<JSObject> holder, - uint32_t entry) { + InternalIndex entry) { return Subclass::GetImpl(holder->GetIsolate(), holder->elements(), entry); } static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { uint32_t index = GetIndexForEntryImpl(backing_store, entry); return handle(BackingStore::cast(backing_store).get(index), isolate); } - void Set(Handle<JSObject> holder, uint32_t entry, Object value) final { + void Set(Handle<JSObject> holder, InternalIndex entry, Object value) final { Subclass::SetImpl(holder, entry, value); } void Reconfigure(Handle<JSObject> object, Handle<FixedArrayBase> store, - uint32_t entry, Handle<Object> value, + InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) final { Subclass::ReconfigureImpl(object, store, entry, value, attributes); } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { UNREACHABLE(); @@ -917,7 +919,7 @@ class ElementsAccessorBase : public InternalElementsAccessor { return true; } - void Delete(Handle<JSObject> obj, uint32_t entry) final { + void Delete(Handle<JSObject> obj, InternalIndex entry) final { Subclass::DeleteImpl(obj, entry); } @@ -1024,9 +1026,9 @@ class ElementsAccessorBase : public InternalElementsAccessor { if (!key->ToUint32(&index)) continue; DCHECK_EQ(object->GetElementsKind(), original_elements_kind); - uint32_t entry = Subclass::GetEntryForIndexImpl( + InternalIndex entry = Subclass::GetEntryForIndexImpl( isolate, *object, object->elements(), index, filter); - if (entry == kMaxUInt32) continue; + if (entry.is_not_found()) continue; PropertyDetails details = Subclass::GetDetailsImpl(*object, entry); Handle<Object> value; @@ -1053,9 +1055,9 @@ class ElementsAccessorBase : public InternalElementsAccessor { InternalElementsAccessor* accessor = reinterpret_cast<InternalElementsAccessor*>( object->GetElementsAccessor()); - uint32_t entry = accessor->GetEntryForIndex(isolate, *object, - object->elements(), index); - if (entry == kMaxUInt32) continue; + InternalIndex entry = accessor->GetEntryForIndex( + isolate, *object, object->elements(), index); + if (entry.is_not_found()) continue; PropertyDetails details = accessor->GetDetails(*object, entry); if (!details.IsEnumerable()) continue; } @@ -1280,43 +1282,44 @@ class ElementsAccessorBase : public InternalElementsAccessor { void Reverse(JSObject receiver) final { Subclass::ReverseImpl(receiver); } static uint32_t GetIndexForEntryImpl(FixedArrayBase backing_store, - uint32_t entry) { - return entry; + InternalIndex entry) { + return entry.as_uint32(); } - static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index, PropertyFilter filter) { + static InternalIndex GetEntryForIndexImpl(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index, + PropertyFilter filter) { DCHECK(IsFastElementsKind(kind()) || IsAnyNonextensibleElementsKind(kind())); uint32_t length = Subclass::GetMaxIndex(holder, backing_store); if (IsHoleyElementsKindForRead(kind())) { return index < length && !BackingStore::cast(backing_store) .is_the_hole(isolate, index) - ? index - : kMaxUInt32; + ? InternalIndex(index) + : InternalIndex::NotFound(); } else { - return index < length ? index : kMaxUInt32; + return index < length ? InternalIndex(index) : InternalIndex::NotFound(); } } - uint32_t GetEntryForIndex(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index) final { + InternalIndex GetEntryForIndex(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index) final { return Subclass::GetEntryForIndexImpl(isolate, holder, backing_store, index, ALL_PROPERTIES); } static PropertyDetails GetDetailsImpl(FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { return PropertyDetails(kData, NONE, PropertyCellType::kNoCell); } - static PropertyDetails GetDetailsImpl(JSObject holder, uint32_t entry) { + static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { return PropertyDetails(kData, NONE, PropertyCellType::kNoCell); } - PropertyDetails GetDetails(JSObject holder, uint32_t entry) final { + PropertyDetails GetDetails(JSObject holder, InternalIndex entry) final { return Subclass::GetDetailsImpl(holder, entry); } @@ -1419,10 +1422,11 @@ class DictionaryElementsAccessor UNREACHABLE(); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { Handle<NumberDictionary> dict(NumberDictionary::cast(obj->elements()), obj->GetIsolate()); - dict = NumberDictionary::DeleteEntry(obj->GetIsolate(), dict, entry); + dict = + NumberDictionary::DeleteEntry(obj->GetIsolate(), dict, entry.as_int()); obj->set_elements(*dict); } @@ -1441,38 +1445,38 @@ class DictionaryElementsAccessor return false; } - static Object GetRaw(FixedArrayBase store, uint32_t entry) { + static Object GetRaw(FixedArrayBase store, InternalIndex entry) { NumberDictionary backing_store = NumberDictionary::cast(store); - return backing_store.ValueAt(entry); + return backing_store.ValueAt(entry.as_int()); } static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { return handle(GetRaw(backing_store, entry), isolate); } - static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, + static inline void SetImpl(Handle<JSObject> holder, InternalIndex entry, Object value) { SetImpl(holder->elements(), entry, value); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value) { - NumberDictionary::cast(backing_store).ValueAtPut(entry, value); + NumberDictionary::cast(backing_store).ValueAtPut(entry.as_int(), value); } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { NumberDictionary dictionary = NumberDictionary::cast(*store); if (attributes != NONE) object->RequireSlowElements(dictionary); - dictionary.ValueAtPut(entry, *value); - PropertyDetails details = dictionary.DetailsAt(entry); + dictionary.ValueAtPut(entry.as_int(), *value); + PropertyDetails details = dictionary.DetailsAt(entry.as_int()); details = PropertyDetails(kData, attributes, PropertyCellType::kNoCell, details.dictionary_index()); - dictionary.DetailsAtPut(object->GetIsolate(), entry, details); + dictionary.DetailsAtPut(object->GetIsolate(), entry.as_int(), details); } static void AddImpl(Handle<JSObject> object, uint32_t index, @@ -1493,43 +1497,47 @@ class DictionaryElementsAccessor } static bool HasEntryImpl(Isolate* isolate, FixedArrayBase store, - uint32_t entry) { + InternalIndex entry) { DisallowHeapAllocation no_gc; NumberDictionary dict = NumberDictionary::cast(store); - Object index = dict.KeyAt(entry); + Object index = dict.KeyAt(entry.as_int()); return !index.IsTheHole(isolate); } - static uint32_t GetIndexForEntryImpl(FixedArrayBase store, uint32_t entry) { + static uint32_t GetIndexForEntryImpl(FixedArrayBase store, + InternalIndex entry) { DisallowHeapAllocation no_gc; NumberDictionary dict = NumberDictionary::cast(store); uint32_t result = 0; - CHECK(dict.KeyAt(entry).ToArrayIndex(&result)); + CHECK(dict.KeyAt(entry.as_int()).ToArrayIndex(&result)); return result; } - static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, - FixedArrayBase store, uint32_t index, - PropertyFilter filter) { + static InternalIndex GetEntryForIndexImpl(Isolate* isolate, JSObject holder, + FixedArrayBase store, + uint32_t index, + PropertyFilter filter) { DisallowHeapAllocation no_gc; NumberDictionary dictionary = NumberDictionary::cast(store); int entry = dictionary.FindEntry(isolate, index); - if (entry == NumberDictionary::kNotFound) return kMaxUInt32; + if (entry == NumberDictionary::kNotFound) { + return InternalIndex::NotFound(); + } if (filter != ALL_PROPERTIES) { PropertyDetails details = dictionary.DetailsAt(entry); PropertyAttributes attr = details.attributes(); - if ((attr & filter) != 0) return kMaxUInt32; + if ((attr & filter) != 0) return InternalIndex::NotFound(); } - return static_cast<uint32_t>(entry); + return InternalIndex(entry); } - static PropertyDetails GetDetailsImpl(JSObject holder, uint32_t entry) { + static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { return GetDetailsImpl(holder.elements(), entry); } static PropertyDetails GetDetailsImpl(FixedArrayBase backing_store, - uint32_t entry) { - return NumberDictionary::cast(backing_store).DetailsAt(entry); + InternalIndex entry) { + return NumberDictionary::cast(backing_store).DetailsAt(entry.as_int()); } static uint32_t FilterKey(Handle<NumberDictionary> dictionary, int entry, @@ -1688,7 +1696,8 @@ class DictionaryElementsAccessor continue; } - PropertyDetails details = GetDetailsImpl(*dictionary, entry); + PropertyDetails details = + GetDetailsImpl(*dictionary, InternalIndex(entry)); switch (details.kind()) { case kData: { Object element_k = dictionary->ValueAt(entry); @@ -1757,7 +1766,8 @@ class DictionaryElementsAccessor int entry = dictionary->FindEntry(isolate, k); if (entry == NumberDictionary::kNotFound) continue; - PropertyDetails details = GetDetailsImpl(*dictionary, entry); + PropertyDetails details = + GetDetailsImpl(*dictionary, InternalIndex(entry)); switch (details.kind()) { case kData: { Object element_k = dictionary->ValueAt(entry); @@ -1863,7 +1873,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { if (BackingStore::cast(*store).is_the_hole(isolate, i)) continue; } max_number_key = i; - Handle<Object> value = Subclass::GetImpl(isolate, *store, i); + Handle<Object> value = + Subclass::GetImpl(isolate, *store, InternalIndex(i)); dictionary = NumberDictionary::Add(isolate, dictionary, i, value, details); j++; @@ -1971,11 +1982,12 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(object); - entry = dictionary->FindEntry(object->GetIsolate(), entry); + entry = InternalIndex( + dictionary->FindEntry(object->GetIsolate(), entry.as_uint32())); DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, entry, value, attributes); } @@ -2000,10 +2012,10 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { JSObject::EnsureWritableFastElements(object); } } - Subclass::SetImpl(object, index, *value); + Subclass::SetImpl(object, InternalIndex(index), *value); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { ElementsKind kind = KindTraits::Kind; if (IsFastPackedElementsKind(kind) || kind == PACKED_NONEXTENSIBLE_ELEMENTS) { @@ -2013,12 +2025,14 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { IsNonextensibleElementsKind(kind)) { JSObject::EnsureWritableFastElements(obj); } - DeleteCommon(obj, entry, handle(obj->elements(), obj->GetIsolate())); + DeleteCommon(obj, entry.as_uint32(), + handle(obj->elements(), obj->GetIsolate())); } static bool HasEntryImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { - return !BackingStore::cast(backing_store).is_the_hole(isolate, entry); + InternalIndex entry) { + return !BackingStore::cast(backing_store) + .is_the_hole(isolate, entry.as_int()); } static uint32_t NumberOfElementsImpl(JSObject receiver, @@ -2028,7 +2042,9 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { Isolate* isolate = receiver.GetIsolate(); uint32_t count = 0; for (uint32_t i = 0; i < max_index; i++) { - if (Subclass::HasEntryImpl(isolate, backing_store, i)) count++; + if (Subclass::HasEntryImpl(isolate, backing_store, InternalIndex(i))) { + count++; + } } return count; } @@ -2041,9 +2057,9 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements); for (uint32_t i = 0; i < length; i++) { if (IsFastPackedElementsKind(KindTraits::Kind) || - HasEntryImpl(isolate, *elements, i)) { + HasEntryImpl(isolate, *elements, InternalIndex(i))) { RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey( - Subclass::GetImpl(isolate, *elements, i), convert)); + Subclass::GetImpl(isolate, *elements, InternalIndex(i)), convert)); } } return ExceptionStatus::kSuccess; @@ -2157,7 +2173,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { DCHECK_LE(end, Subclass::GetCapacityImpl(*receiver, receiver->elements())); for (uint32_t index = start; index < end; ++index) { - Subclass::SetImpl(receiver, index, *obj_value); + Subclass::SetImpl(receiver, InternalIndex(index), *obj_value); } return *receiver; } @@ -2311,9 +2327,10 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { Handle<FixedArray> result = isolate->factory()->NewFixedArray(length); Handle<FixedArrayBase> elements(object->elements(), isolate); for (uint32_t i = 0; i < length; i++) { - if (!Subclass::HasElementImpl(isolate, *object, i, *elements)) continue; + InternalIndex entry(i); + if (!Subclass::HasEntryImpl(isolate, *elements, entry)) continue; Handle<Object> value; - value = Subclass::GetImpl(isolate, *elements, i); + value = Subclass::GetImpl(isolate, *elements, entry); if (value->IsName()) { value = isolate->factory()->InternalizeName(Handle<Name>::cast(value)); } @@ -2336,7 +2353,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { int new_length = length - 1; int remove_index = remove_position == AT_START ? 0 : new_length; Handle<Object> result = - Subclass::GetImpl(isolate, *backing_store, remove_index); + Subclass::GetImpl(isolate, *backing_store, InternalIndex(remove_index)); if (remove_position == AT_START) { Subclass::MoveElements(isolate, receiver, backing_store, 0, 1, new_length, 0, 0); @@ -2396,7 +2413,8 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { for (uint32_t i = 0; i < copy_size; i++) { Object argument = (*args)[src_index + i]; DCHECK(!argument.IsTheHole()); - Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); + Subclass::SetImpl(raw_backing_store, InternalIndex(dst_index + i), + argument, mode); } } }; @@ -2405,22 +2423,22 @@ template <typename Subclass, typename KindTraits> class FastSmiOrObjectElementsAccessor : public FastElementsAccessor<Subclass, KindTraits> { public: - static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, + static inline void SetImpl(Handle<JSObject> holder, InternalIndex entry, Object value) { SetImpl(holder->elements(), entry, value); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value) { - FixedArray::cast(backing_store).set(entry, value); + FixedArray::cast(backing_store).set(entry.as_int(), value); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value, WriteBarrierMode mode) { - FixedArray::cast(backing_store).set(entry, value, mode); + FixedArray::cast(backing_store).set(entry.as_int(), value, mode); } - static Object GetRaw(FixedArray backing_store, uint32_t entry) { + static Object GetRaw(FixedArray backing_store, InternalIndex entry) { uint32_t index = Subclass::GetIndexForEntryImpl(backing_store, entry); return backing_store.get(index); } @@ -2488,8 +2506,9 @@ class FastSmiOrObjectElementsAccessor isolate); uint32_t length = elements->length(); for (uint32_t index = 0; index < length; ++index) { - if (!Subclass::HasEntryImpl(isolate, *elements, index)) continue; - Handle<Object> value = Subclass::GetImpl(isolate, *elements, index); + InternalIndex entry(index); + if (!Subclass::HasEntryImpl(isolate, *elements, entry)) continue; + Handle<Object> value = Subclass::GetImpl(isolate, *elements, entry); value = MakeEntryPair(isolate, index, value); values_or_entries->set(count++, *value); } @@ -2499,8 +2518,9 @@ class FastSmiOrObjectElementsAccessor FixedArray elements = FixedArray::cast(object->elements()); uint32_t length = elements.length(); for (uint32_t index = 0; index < length; ++index) { - if (!Subclass::HasEntryImpl(isolate, elements, index)) continue; - Object value = GetRaw(elements, index); + InternalIndex entry(index); + if (!Subclass::HasEntryImpl(isolate, elements, entry)) continue; + Object value = GetRaw(elements, entry); values_or_entries->set(count++, value); } } @@ -2641,7 +2661,7 @@ class FastSealedObjectElementsAccessor UNREACHABLE(); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { UNREACHABLE(); } @@ -2733,17 +2753,17 @@ class FastFrozenObjectElementsAccessor public: using BackingStore = typename KindTraits::BackingStore; - static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, + static inline void SetImpl(Handle<JSObject> holder, InternalIndex entry, Object value) { UNREACHABLE(); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value) { UNREACHABLE(); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value, WriteBarrierMode mode) { UNREACHABLE(); } @@ -2753,7 +2773,7 @@ class FastFrozenObjectElementsAccessor UNREACHABLE(); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { UNREACHABLE(); } @@ -2787,7 +2807,7 @@ class FastFrozenObjectElementsAccessor } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { UNREACHABLE(); @@ -2816,24 +2836,24 @@ class FastDoubleElementsAccessor : public FastElementsAccessor<Subclass, KindTraits> { public: static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { - return FixedDoubleArray::get(FixedDoubleArray::cast(backing_store), entry, - isolate); + InternalIndex entry) { + return FixedDoubleArray::get(FixedDoubleArray::cast(backing_store), + entry.as_int(), isolate); } - static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, + static inline void SetImpl(Handle<JSObject> holder, InternalIndex entry, Object value) { SetImpl(holder->elements(), entry, value); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value) { - FixedDoubleArray::cast(backing_store).set(entry, value.Number()); + FixedDoubleArray::cast(backing_store).set(entry.as_int(), value.Number()); } - static inline void SetImpl(FixedArrayBase backing_store, uint32_t entry, + static inline void SetImpl(FixedArrayBase backing_store, InternalIndex entry, Object value, WriteBarrierMode mode) { - FixedDoubleArray::cast(backing_store).set(entry, value.Number()); + FixedDoubleArray::cast(backing_store).set(entry.as_int(), value.Number()); } static void CopyElementsImpl(Isolate* isolate, FixedArrayBase from, @@ -2890,8 +2910,9 @@ class FastDoubleElementsAccessor int count = 0; uint32_t length = elements->length(); for (uint32_t index = 0; index < length; ++index) { - if (!Subclass::HasEntryImpl(isolate, *elements, index)) continue; - Handle<Object> value = Subclass::GetImpl(isolate, *elements, index); + InternalIndex entry(index); + if (!Subclass::HasEntryImpl(isolate, *elements, entry)) continue; + Handle<Object> value = Subclass::GetImpl(isolate, *elements, entry); if (get_entries) { value = MakeEntryPair(isolate, index, value); } @@ -2988,11 +3009,12 @@ class TypedElementsAccessor // Conversion of scalar value to handlified object. static Handle<Object> ToHandle(Isolate* isolate, ElementType value); - static void SetImpl(Handle<JSObject> holder, uint32_t entry, Object value) { + static void SetImpl(Handle<JSObject> holder, InternalIndex entry, + Object value) { Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(holder); - DCHECK_LE(entry, typed_array->length()); - SetImpl(static_cast<ElementType*>(typed_array->DataPtr()), entry, - FromObject(value)); + DCHECK_LE(entry.raw_value(), typed_array->length()); + SetImpl(static_cast<ElementType*>(typed_array->DataPtr()), + entry.raw_value(), FromObject(value)); } static void SetImpl(ElementType* data_ptr, size_t entry, ElementType value) { @@ -3019,18 +3041,18 @@ class TypedElementsAccessor } static Handle<Object> GetInternalImpl(Handle<JSObject> holder, - uint32_t entry) { + InternalIndex entry) { Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(holder); Isolate* isolate = typed_array->GetIsolate(); - DCHECK_LE(entry, typed_array->length()); + DCHECK_LE(entry.raw_value(), typed_array->length()); DCHECK(!typed_array->WasDetached()); - ElementType elem = - GetImpl(static_cast<ElementType*>(typed_array->DataPtr()), entry); + ElementType elem = GetImpl( + static_cast<ElementType*>(typed_array->DataPtr()), entry.raw_value()); return ToHandle(isolate, elem); } static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { UNREACHABLE(); } @@ -3059,12 +3081,12 @@ class TypedElementsAccessor return result; } - static PropertyDetails GetDetailsImpl(JSObject holder, uint32_t entry) { + static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { return PropertyDetails(kData, DONT_DELETE, PropertyCellType::kNoCell); } static PropertyDetails GetDetailsImpl(FixedArrayBase backing_store, - uint32_t entry) { + InternalIndex entry) { return PropertyDetails(kData, DONT_DELETE, PropertyCellType::kNoCell); } @@ -3085,21 +3107,22 @@ class TypedElementsAccessor UNREACHABLE(); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { UNREACHABLE(); } static uint32_t GetIndexForEntryImpl(FixedArrayBase backing_store, - uint32_t entry) { - return entry; + InternalIndex entry) { + return entry.as_uint32(); } - static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index, PropertyFilter filter) { + static InternalIndex GetEntryForIndexImpl(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index, + PropertyFilter filter) { return index < AccessorClass::GetCapacityImpl(holder, backing_store) - ? index - : kMaxUInt32; + ? InternalIndex(index) + : InternalIndex::NotFound(); } static uint32_t GetCapacityImpl(JSObject holder, @@ -3122,7 +3145,8 @@ class TypedElementsAccessor Handle<FixedArrayBase> elements(receiver->elements(), isolate); uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements); for (uint32_t i = 0; i < length; i++) { - Handle<Object> value = AccessorClass::GetInternalImpl(receiver, i); + Handle<Object> value = + AccessorClass::GetInternalImpl(receiver, InternalIndex(i)); RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(value, convert)); } return ExceptionStatus::kSuccess; @@ -3137,7 +3161,8 @@ class TypedElementsAccessor Handle<FixedArrayBase> elements(object->elements(), isolate); uint32_t length = AccessorClass::GetCapacityImpl(*object, *elements); for (uint32_t index = 0; index < length; ++index) { - Handle<Object> value = AccessorClass::GetInternalImpl(object, index); + Handle<Object> value = + AccessorClass::GetInternalImpl(object, InternalIndex(index)); if (get_entries) { value = MakeEntryPair(isolate, index, value); } @@ -3361,7 +3386,8 @@ class TypedElementsAccessor Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(object); Handle<FixedArray> result = isolate->factory()->NewFixedArray(length); for (uint32_t i = 0; i < length; i++) { - Handle<Object> value = AccessorClass::GetInternalImpl(typed_array, i); + Handle<Object> value = + AccessorClass::GetInternalImpl(typed_array, InternalIndex(i)); result->set(i, *value); } return result; @@ -3499,7 +3525,7 @@ class TypedElementsAccessor return true; } - return !isolate->IsNoElementsProtectorIntact(context); + return !Protectors::IsNoElementsIntact(isolate); } static bool TryCopyElementsFastNumber(Context context, JSArray source, @@ -3539,18 +3565,18 @@ class TypedElementsAccessor if (kind == PACKED_SMI_ELEMENTS) { FixedArray source_store = FixedArray::cast(source.elements()); - for (uint32_t i = 0; i < length; i++) { - Object elem = source_store.get(i); + for (size_t i = 0; i < length; i++) { + Object elem = source_store.get(static_cast<int>(i)); SetImpl(dest_data, i, FromScalar(Smi::ToInt(elem))); } return true; } else if (kind == HOLEY_SMI_ELEMENTS) { FixedArray source_store = FixedArray::cast(source.elements()); - for (uint32_t i = 0; i < length; i++) { - if (source_store.is_the_hole(isolate, i)) { + for (size_t i = 0; i < length; i++) { + if (source_store.is_the_hole(isolate, static_cast<int>(i))) { SetImpl(dest_data, i, FromObject(undefined)); } else { - Object elem = source_store.get(i); + Object elem = source_store.get(static_cast<int>(i)); SetImpl(dest_data, i, FromScalar(Smi::ToInt(elem))); } } @@ -3560,20 +3586,20 @@ class TypedElementsAccessor // unboxing the double here by using get_scalar. FixedDoubleArray source_store = FixedDoubleArray::cast(source.elements()); - for (uint32_t i = 0; i < length; i++) { + for (size_t i = 0; i < length; i++) { // Use the from_double conversion for this specific TypedArray type, // rather than relying on C++ to convert elem. - double elem = source_store.get_scalar(i); + double elem = source_store.get_scalar(static_cast<int>(i)); SetImpl(dest_data, i, FromScalar(elem)); } return true; } else if (kind == HOLEY_DOUBLE_ELEMENTS) { FixedDoubleArray source_store = FixedDoubleArray::cast(source.elements()); - for (uint32_t i = 0; i < length; i++) { - if (source_store.is_the_hole(i)) { + for (size_t i = 0; i < length; i++) { + if (source_store.is_the_hole(static_cast<int>(i))) { SetImpl(dest_data, i, FromObject(undefined)); } else { - double elem = source_store.get_scalar(i); + double elem = source_store.get_scalar(static_cast<int>(i)); SetImpl(dest_data, i, FromScalar(elem)); } } @@ -3588,7 +3614,8 @@ class TypedElementsAccessor Isolate* isolate = destination->GetIsolate(); for (size_t i = 0; i < length; i++) { Handle<Object> elem; - if (i <= kMaxUInt32) { + // TODO(4153): This if-branch will subsume its else-branch. + if (i <= JSArray::kMaxArrayIndex) { LookupIterator it(isolate, source, static_cast<uint32_t>(i)); ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, elem, Object::GetProperty(&it)); @@ -3619,8 +3646,7 @@ class TypedElementsAccessor } // The spec says we store the length, then get each element, so we don't // need to check changes to length. - // TODO(bmeurer, v8:4153): Remove this static_cast. - SetImpl(destination, static_cast<uint32_t>(offset + i), *elem); + SetImpl(destination, InternalIndex(offset + i), *elem); } return *isolate->factory()->undefined_value(); } @@ -3893,14 +3919,14 @@ class SloppyArgumentsElementsAccessor } static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase parameters, - uint32_t entry) { + InternalIndex entry) { Handle<SloppyArgumentsElements> elements( SloppyArgumentsElements::cast(parameters), isolate); uint32_t length = elements->parameter_map_length(); - if (entry < length) { + if (entry.as_uint32() < length) { // Read context mapped entry. DisallowHeapAllocation no_gc; - Object probe = elements->get_mapped_entry(entry); + Object probe = elements->get_mapped_entry(entry.as_uint32()); DCHECK(!probe.IsTheHole(isolate)); Context context = elements->context(); int context_entry = Smi::ToInt(probe); @@ -3909,7 +3935,7 @@ class SloppyArgumentsElementsAccessor } else { // Entry is not context mapped, defer to the arguments. Handle<Object> result = ArgumentsAccessor::GetImpl( - isolate, elements->arguments(), entry - length); + isolate, elements->arguments(), entry.adjust_down(length)); return Subclass::ConvertArgumentsStoreResult(isolate, elements, result); } } @@ -3924,19 +3950,19 @@ class SloppyArgumentsElementsAccessor UNREACHABLE(); } - static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, + static inline void SetImpl(Handle<JSObject> holder, InternalIndex entry, Object value) { SetImpl(holder->elements(), entry, value); } - static inline void SetImpl(FixedArrayBase store, uint32_t entry, + static inline void SetImpl(FixedArrayBase store, InternalIndex entry, Object value) { SloppyArgumentsElements elements = SloppyArgumentsElements::cast(store); uint32_t length = elements.parameter_map_length(); - if (entry < length) { + if (entry.as_uint32() < length) { // Store context mapped entry. DisallowHeapAllocation no_gc; - Object probe = elements.get_mapped_entry(entry); + Object probe = elements.get_mapped_entry(entry.as_uint32()); DCHECK(!probe.IsTheHole()); Context context = elements.context(); int context_entry = Smi::ToInt(probe); @@ -3945,7 +3971,8 @@ class SloppyArgumentsElementsAccessor } else { // Entry is not context mapped defer to arguments. FixedArray arguments = elements.arguments(); - Object current = ArgumentsAccessor::GetRaw(arguments, entry - length); + Object current = + ArgumentsAccessor::GetRaw(arguments, entry.adjust_down(length)); if (current.IsAliasedArgumentsEntry()) { AliasedArgumentsEntry alias = AliasedArgumentsEntry::cast(current); Context context = elements.context(); @@ -3953,7 +3980,7 @@ class SloppyArgumentsElementsAccessor DCHECK(!context.get(context_entry).IsTheHole()); context.set(context_entry, value); } else { - ArgumentsAccessor::SetImpl(arguments, entry - length, value); + ArgumentsAccessor::SetImpl(arguments, entry.adjust_down(length), value); } } } @@ -3989,8 +4016,8 @@ class SloppyArgumentsElementsAccessor FixedArrayBase arguments = elements.arguments(); uint32_t nof_elements = 0; uint32_t length = elements.parameter_map_length(); - for (uint32_t entry = 0; entry < length; entry++) { - if (HasParameterMapArg(isolate, elements, entry)) nof_elements++; + for (uint32_t index = 0; index < length; index++) { + if (HasParameterMapArg(isolate, elements, index)) nof_elements++; } return nof_elements + ArgumentsAccessor::NumberOfElementsImpl(receiver, arguments); @@ -4002,7 +4029,8 @@ class SloppyArgumentsElementsAccessor Isolate* isolate = accumulator->isolate(); Handle<FixedArrayBase> elements(receiver->elements(), isolate); uint32_t length = GetCapacityImpl(*receiver, *elements); - for (uint32_t entry = 0; entry < length; entry++) { + for (uint32_t index = 0; index < length; index++) { + InternalIndex entry(index); if (!HasEntryImpl(isolate, *elements, entry)) continue; Handle<Object> value = GetImpl(isolate, *elements, entry); RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(value, convert)); @@ -4011,15 +4039,16 @@ class SloppyArgumentsElementsAccessor } static bool HasEntryImpl(Isolate* isolate, FixedArrayBase parameters, - uint32_t entry) { + InternalIndex entry) { SloppyArgumentsElements elements = SloppyArgumentsElements::cast(parameters); uint32_t length = elements.parameter_map_length(); - if (entry < length) { - return HasParameterMapArg(isolate, elements, entry); + if (entry.as_uint32() < length) { + return HasParameterMapArg(isolate, elements, entry.as_uint32()); } FixedArrayBase arguments = elements.arguments(); - return ArgumentsAccessor::HasEntryImpl(isolate, arguments, entry - length); + return ArgumentsAccessor::HasEntryImpl(isolate, arguments, + entry.adjust_down(length)); } static bool HasAccessorsImpl(JSObject holder, FixedArrayBase backing_store) { @@ -4030,39 +4059,45 @@ class SloppyArgumentsElementsAccessor } static uint32_t GetIndexForEntryImpl(FixedArrayBase parameters, - uint32_t entry) { + InternalIndex entry) { SloppyArgumentsElements elements = SloppyArgumentsElements::cast(parameters); uint32_t length = elements.parameter_map_length(); - if (entry < length) return entry; + uint32_t index = entry.as_uint32(); + if (index < length) return index; FixedArray arguments = elements.arguments(); - return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); + return ArgumentsAccessor::GetIndexForEntryImpl(arguments, + entry.adjust_down(length)); } - static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, - FixedArrayBase parameters, - uint32_t index, PropertyFilter filter) { + static InternalIndex GetEntryForIndexImpl(Isolate* isolate, JSObject holder, + FixedArrayBase parameters, + uint32_t index, + PropertyFilter filter) { SloppyArgumentsElements elements = SloppyArgumentsElements::cast(parameters); - if (HasParameterMapArg(isolate, elements, index)) return index; + if (HasParameterMapArg(isolate, elements, index)) { + return InternalIndex(index); + } FixedArray arguments = elements.arguments(); - uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl( + InternalIndex entry = ArgumentsAccessor::GetEntryForIndexImpl( isolate, holder, arguments, index, filter); - if (entry == kMaxUInt32) return kMaxUInt32; + if (entry.is_not_found()) return entry; // Arguments entries could overlap with the dictionary entries, hence offset // them by the number of context mapped entries. - return elements.parameter_map_length() + entry; + return entry.adjust_up(elements.parameter_map_length()); } - static PropertyDetails GetDetailsImpl(JSObject holder, uint32_t entry) { + static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { SloppyArgumentsElements elements = SloppyArgumentsElements::cast(holder.elements()); uint32_t length = elements.parameter_map_length(); - if (entry < length) { + if (entry.as_uint32() < length) { return PropertyDetails(kData, NONE, PropertyCellType::kNoCell); } FixedArray arguments = elements.arguments(); - return ArgumentsAccessor::GetDetailsImpl(arguments, entry - length); + return ArgumentsAccessor::GetDetailsImpl(arguments, + entry.adjust_down(length)); } static bool HasParameterMapArg(Isolate* isolate, @@ -4073,26 +4108,26 @@ class SloppyArgumentsElementsAccessor return !elements.get_mapped_entry(index).IsTheHole(isolate); } - static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) { Handle<SloppyArgumentsElements> elements( SloppyArgumentsElements::cast(obj->elements()), obj->GetIsolate()); uint32_t length = elements->parameter_map_length(); - uint32_t delete_or_entry = entry; - if (entry < length) { - delete_or_entry = kMaxUInt32; + InternalIndex delete_or_entry = entry; + if (entry.as_uint32() < length) { + delete_or_entry = InternalIndex::NotFound(); } Subclass::SloppyDeleteImpl(obj, elements, delete_or_entry); // SloppyDeleteImpl allocates a new dictionary elements store. For making // heap verification happy we postpone clearing out the mapped entry. - if (entry < length) { - elements->set_mapped_entry(entry, + if (entry.as_uint32() < length) { + elements->set_mapped_entry(entry.as_uint32(), obj->GetReadOnlyRoots().the_hole_value()); } } static void SloppyDeleteImpl(Handle<JSObject> obj, Handle<SloppyArgumentsElements> elements, - uint32_t entry) { + InternalIndex entry) { // Implemented in subclasses. UNREACHABLE(); } @@ -4152,9 +4187,9 @@ class SloppyArgumentsElementsAccessor for (uint32_t k = start_from; k < length; ++k) { DCHECK_EQ(object->map(), *original_map); - uint32_t entry = + InternalIndex entry = GetEntryForIndexImpl(isolate, *object, *elements, k, ALL_PROPERTIES); - if (entry == kMaxUInt32) { + if (entry.is_not_found()) { if (search_for_hole) return Just(true); continue; } @@ -4193,9 +4228,9 @@ class SloppyArgumentsElementsAccessor for (uint32_t k = start_from; k < length; ++k) { DCHECK_EQ(object->map(), *original_map); - uint32_t entry = + InternalIndex entry = GetEntryForIndexImpl(isolate, *object, *elements, k, ALL_PROPERTIES); - if (entry == kMaxUInt32) { + if (entry.is_not_found()) { continue; } @@ -4246,14 +4281,15 @@ class SlowSloppyArgumentsElementsAccessor } static void SloppyDeleteImpl(Handle<JSObject> obj, Handle<SloppyArgumentsElements> elements, - uint32_t entry) { + InternalIndex entry) { // No need to delete a context mapped entry from the arguments elements. - if (entry == kMaxUInt32) return; + if (entry.is_not_found()) return; Isolate* isolate = obj->GetIsolate(); Handle<NumberDictionary> dict(NumberDictionary::cast(elements->arguments()), isolate); - int length = elements->parameter_map_length(); - dict = NumberDictionary::DeleteEntry(isolate, dict, entry - length); + uint32_t length = elements->parameter_map_length(); + dict = NumberDictionary::DeleteEntry(isolate, dict, + entry.as_uint32() - length); elements->set_arguments(*dict); } static void AddImpl(Handle<JSObject> object, uint32_t index, @@ -4278,15 +4314,15 @@ class SlowSloppyArgumentsElementsAccessor } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { Isolate* isolate = object->GetIsolate(); Handle<SloppyArgumentsElements> elements = Handle<SloppyArgumentsElements>::cast(store); uint32_t length = elements->parameter_map_length(); - if (entry < length) { - Object probe = elements->get_mapped_entry(entry); + if (entry.as_uint32() < length) { + Object probe = elements->get_mapped_entry(entry.as_uint32()); DCHECK(!probe.IsTheHole(isolate)); Context context = elements->context(); int context_entry = Smi::ToInt(probe); @@ -4294,7 +4330,7 @@ class SlowSloppyArgumentsElementsAccessor context.set(context_entry, *value); // Redefining attributes of an aliased element destroys fast aliasing. - elements->set_mapped_entry(entry, + elements->set_mapped_entry(entry.as_uint32(), ReadOnlyRoots(isolate).the_hole_value()); // For elements that are still writable we re-establish slow aliasing. if ((attributes & READ_ONLY) == 0) { @@ -4304,8 +4340,8 @@ class SlowSloppyArgumentsElementsAccessor PropertyDetails details(kData, attributes, PropertyCellType::kNoCell); Handle<NumberDictionary> arguments( NumberDictionary::cast(elements->arguments()), isolate); - arguments = - NumberDictionary::Add(isolate, arguments, entry, value, details); + arguments = NumberDictionary::Add(isolate, arguments, entry.as_uint32(), + value, details); // If the attributes were NONE, we would have called set rather than // reconfigure. DCHECK_NE(NONE, attributes); @@ -4314,7 +4350,7 @@ class SlowSloppyArgumentsElementsAccessor } else { Handle<FixedArrayBase> arguments(elements->arguments(), isolate); DictionaryElementsAccessor::ReconfigureImpl( - object, arguments, entry - length, value, attributes); + object, arguments, entry.adjust_down(length), value, attributes); } } }; @@ -4346,23 +4382,25 @@ class FastSloppyArgumentsElementsAccessor static Handle<NumberDictionary> NormalizeArgumentsElements( Handle<JSObject> object, Handle<SloppyArgumentsElements> elements, - uint32_t* entry) { + InternalIndex* entry) { Handle<NumberDictionary> dictionary = JSObject::NormalizeElements(object); elements->set_arguments(*dictionary); // kMaxUInt32 indicates that a context mapped element got deleted. In this // case we only normalize the elements (aka. migrate to SLOW_SLOPPY). - if (*entry == kMaxUInt32) return dictionary; + if (entry->is_not_found()) return dictionary; uint32_t length = elements->parameter_map_length(); - if (*entry >= length) { + if (entry->as_uint32() >= length) { *entry = - dictionary->FindEntry(object->GetIsolate(), *entry - length) + length; + InternalIndex(dictionary->FindEntry(object->GetIsolate(), + entry->as_uint32() - length) + + length); } return dictionary; } static void SloppyDeleteImpl(Handle<JSObject> obj, Handle<SloppyArgumentsElements> elements, - uint32_t entry) { + InternalIndex entry) { // Always normalize element on deleting an entry. NormalizeArgumentsElements(obj, elements, &entry); SlowSloppyArgumentsElementsAccessor::SloppyDeleteImpl(obj, elements, entry); @@ -4386,11 +4424,12 @@ class FastSloppyArgumentsElementsAccessor // index to entry explicitly since the slot still contains the hole, so the // current EntryForIndex would indicate that it is "absent" by returning // kMaxUInt32. - FastHoleyObjectElementsAccessor::SetImpl(arguments, index, *value); + FastHoleyObjectElementsAccessor::SetImpl(arguments, InternalIndex(index), + *value); } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { DCHECK_EQ(object->elements(), *store); @@ -4443,63 +4482,67 @@ class StringWrapperElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> { public: static Handle<Object> GetInternalImpl(Handle<JSObject> holder, - uint32_t entry) { + InternalIndex entry) { return GetImpl(holder, entry); } - static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) { + static Handle<Object> GetImpl(Handle<JSObject> holder, InternalIndex entry) { Isolate* isolate = holder->GetIsolate(); Handle<String> string(GetString(*holder), isolate); uint32_t length = static_cast<uint32_t>(string->length()); - if (entry < length) { + if (entry.as_uint32() < length) { return isolate->factory()->LookupSingleCharacterStringFromCode( - String::Flatten(isolate, string)->Get(entry)); + String::Flatten(isolate, string)->Get(entry.as_int())); } return BackingStoreAccessor::GetImpl(isolate, holder->elements(), - entry - length); + entry.adjust_down(length)); } static Handle<Object> GetImpl(Isolate* isolate, FixedArrayBase elements, - uint32_t entry) { + InternalIndex entry) { UNREACHABLE(); } - static PropertyDetails GetDetailsImpl(JSObject holder, uint32_t entry) { + static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) { uint32_t length = static_cast<uint32_t>(GetString(holder).length()); - if (entry < length) { + if (entry.as_uint32() < length) { PropertyAttributes attributes = static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE); return PropertyDetails(kData, attributes, PropertyCellType::kNoCell); } - return BackingStoreAccessor::GetDetailsImpl(holder, entry - length); + return BackingStoreAccessor::GetDetailsImpl(holder, + entry.adjust_down(length)); } - static uint32_t GetEntryForIndexImpl(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index, PropertyFilter filter) { + static InternalIndex GetEntryForIndexImpl(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index, + PropertyFilter filter) { uint32_t length = static_cast<uint32_t>(GetString(holder).length()); - if (index < length) return index; - uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl( - isolate, holder, backing_store, index, filter); - if (backing_store_entry == kMaxUInt32) return kMaxUInt32; - DCHECK(backing_store_entry < kMaxUInt32 - length); - return backing_store_entry + length; + if (index < length) return InternalIndex(index); + InternalIndex backing_store_entry = + BackingStoreAccessor::GetEntryForIndexImpl( + isolate, holder, backing_store, index, filter); + if (backing_store_entry.is_not_found()) return backing_store_entry; + return backing_store_entry.adjust_up(length); } - static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) { + static void DeleteImpl(Handle<JSObject> holder, InternalIndex entry) { uint32_t length = static_cast<uint32_t>(GetString(*holder).length()); - if (entry < length) { + if (entry.as_uint32() < length) { return; // String contents can't be deleted. } - BackingStoreAccessor::DeleteImpl(holder, entry - length); + BackingStoreAccessor::DeleteImpl(holder, entry.adjust_down(length)); } - static void SetImpl(Handle<JSObject> holder, uint32_t entry, Object value) { + static void SetImpl(Handle<JSObject> holder, InternalIndex entry, + Object value) { uint32_t length = static_cast<uint32_t>(GetString(*holder).length()); - if (entry < length) { + if (entry.as_uint32() < length) { return; // String contents are read-only. } - BackingStoreAccessor::SetImpl(holder->elements(), entry - length, value); + BackingStoreAccessor::SetImpl(holder->elements(), entry.adjust_down(length), + value); } static void AddImpl(Handle<JSObject> object, uint32_t index, @@ -4519,15 +4562,15 @@ class StringWrapperElementsAccessor } static void ReconfigureImpl(Handle<JSObject> object, - Handle<FixedArrayBase> store, uint32_t entry, + Handle<FixedArrayBase> store, InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) { uint32_t length = static_cast<uint32_t>(GetString(*object).length()); - if (entry < length) { + if (entry.as_uint32() < length) { return; // String contents can't be reconfigured. } - BackingStoreAccessor::ReconfigureImpl(object, store, entry - length, value, - attributes); + BackingStoreAccessor::ReconfigureImpl( + object, store, entry.adjust_down(length), value, attributes); } V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl( diff --git a/deps/v8/src/objects/elements.h b/deps/v8/src/objects/elements.h index b7fcd907a3792f..219a9ad73a0bf7 100644 --- a/deps/v8/src/objects/elements.h +++ b/deps/v8/src/objects/elements.h @@ -6,6 +6,7 @@ #define V8_OBJECTS_ELEMENTS_H_ #include "src/objects/elements-kind.h" +#include "src/objects/internal-index.h" #include "src/objects/keys.h" #include "src/objects/objects.h" @@ -50,11 +51,9 @@ class ElementsAccessor { // Note: this is currently not implemented for string wrapper and // typed array elements. - virtual bool HasEntry(JSObject holder, uint32_t entry) = 0; + virtual bool HasEntry(JSObject holder, InternalIndex entry) = 0; - // TODO(cbruni): HasEntry and Get should not be exposed publicly with the - // entry parameter. - virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) = 0; + virtual Handle<Object> Get(Handle<JSObject> holder, InternalIndex entry) = 0; virtual bool HasAccessors(JSObject holder) = 0; virtual uint32_t NumberOfElements(JSObject holder) = 0; @@ -105,7 +104,8 @@ class ElementsAccessor { static void InitializeOncePerProcess(); static void TearDown(); - virtual void Set(Handle<JSObject> holder, uint32_t entry, Object value) = 0; + virtual void Set(Handle<JSObject> holder, InternalIndex entry, + Object value) = 0; virtual void Add(Handle<JSObject> object, uint32_t index, Handle<Object> value, PropertyAttributes attributes, @@ -178,18 +178,18 @@ class ElementsAccessor { // indices are equivalent to entries. In the NumberDictionary // ElementsAccessor, entries are mapped to an index using the KeyAt method on // the NumberDictionary. - virtual uint32_t GetEntryForIndex(Isolate* isolate, JSObject holder, - FixedArrayBase backing_store, - uint32_t index) = 0; + virtual InternalIndex GetEntryForIndex(Isolate* isolate, JSObject holder, + FixedArrayBase backing_store, + uint32_t index) = 0; - virtual PropertyDetails GetDetails(JSObject holder, uint32_t entry) = 0; + virtual PropertyDetails GetDetails(JSObject holder, InternalIndex entry) = 0; virtual void Reconfigure(Handle<JSObject> object, - Handle<FixedArrayBase> backing_store, uint32_t entry, - Handle<Object> value, + Handle<FixedArrayBase> backing_store, + InternalIndex entry, Handle<Object> value, PropertyAttributes attributes) = 0; // Deletes an element in an object. - virtual void Delete(Handle<JSObject> holder, uint32_t entry) = 0; + virtual void Delete(Handle<JSObject> holder, InternalIndex entry) = 0; // NOTE: this method violates the handlified function signature convention: // raw pointer parameter |source_holder| in the function that allocates. diff --git a/deps/v8/src/objects/feedback-cell-inl.h b/deps/v8/src/objects/feedback-cell-inl.h index e06cfce7de18dc..188666d4626220 100644 --- a/deps/v8/src/objects/feedback-cell-inl.h +++ b/deps/v8/src/objects/feedback-cell-inl.h @@ -17,12 +17,7 @@ namespace v8 { namespace internal { -OBJECT_CONSTRUCTORS_IMPL(FeedbackCell, Struct) - -CAST_ACCESSOR(FeedbackCell) - -ACCESSORS(FeedbackCell, value, HeapObject, kValueOffset) -INT32_ACCESSORS(FeedbackCell, interrupt_budget, kInterruptBudgetOffset) +TQ_OBJECT_CONSTRUCTORS_IMPL(FeedbackCell) void FeedbackCell::clear_padding() { if (FeedbackCell::kAlignedSize == FeedbackCell::kUnalignedSize) return; diff --git a/deps/v8/src/objects/feedback-cell.h b/deps/v8/src/objects/feedback-cell.h index 3c085f72d9a5ae..669efaeaeca8b2 100644 --- a/deps/v8/src/objects/feedback-cell.h +++ b/deps/v8/src/objects/feedback-cell.h @@ -18,7 +18,7 @@ namespace internal { // number of closures created for a certain function per native // context. There's at most one FeedbackCell for each function in // a native context. -class FeedbackCell : public Struct { +class FeedbackCell : public TorqueGeneratedFeedbackCell<FeedbackCell, Struct> { public: static int GetInitialInterruptBudget() { if (FLAG_lazy_feedback_allocation) { @@ -27,19 +27,8 @@ class FeedbackCell : public Struct { return FLAG_interrupt_budget; } - // [value]: value of the cell. - DECL_ACCESSORS(value, HeapObject) - DECL_INT32_ACCESSORS(interrupt_budget) - - DECL_CAST(FeedbackCell) - // Dispatched behavior. DECL_PRINTER(FeedbackCell) - DECL_VERIFIER(FeedbackCell) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_FEEDBACK_CELL_FIELDS) static const int kUnalignedSize = kSize; static const int kAlignedSize = RoundUp<kObjectAlignment>(int{kSize}); @@ -50,7 +39,7 @@ class FeedbackCell : public Struct { using BodyDescriptor = FixedBodyDescriptor<kValueOffset, kInterruptBudgetOffset, kAlignedSize>; - OBJECT_CONSTRUCTORS(FeedbackCell, Struct); + TQ_OBJECT_CONSTRUCTORS(FeedbackCell) }; } // namespace internal diff --git a/deps/v8/src/objects/feedback-vector-inl.h b/deps/v8/src/objects/feedback-vector-inl.h index 9cdc03b5c24ce7..024b92165dea13 100644 --- a/deps/v8/src/objects/feedback-vector-inl.h +++ b/deps/v8/src/objects/feedback-vector-inl.h @@ -286,10 +286,6 @@ Handle<Symbol> FeedbackVector::MegamorphicSentinel(Isolate* isolate) { return isolate->factory()->megamorphic_symbol(); } -Handle<Symbol> FeedbackVector::PremonomorphicSentinel(Isolate* isolate) { - return isolate->factory()->premonomorphic_symbol(); -} - Symbol FeedbackVector::RawUninitializedSentinel(Isolate* isolate) { return ReadOnlyRoots(isolate).uninitialized_symbol(); } diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc index 2fbc48a95eded9..4fe75ab325e322 100644 --- a/deps/v8/src/objects/feedback-vector.cc +++ b/deps/v8/src/objects/feedback-vector.cc @@ -52,7 +52,6 @@ static bool IsPropertyNameFeedback(MaybeObject feedback) { Symbol symbol = Symbol::cast(heap_object); ReadOnlyRoots roots = symbol.GetReadOnlyRoots(); return symbol != roots.uninitialized_symbol() && - symbol != roots.premonomorphic_symbol() && symbol != roots.megamorphic_symbol(); } @@ -233,8 +232,8 @@ Handle<FeedbackVector> FeedbackVector::New( const int slot_count = shared->feedback_metadata().slot_count(); - Handle<FeedbackVector> vector = factory->NewFeedbackVector( - shared, closure_feedback_cell_array, AllocationType::kOld); + Handle<FeedbackVector> vector = + factory->NewFeedbackVector(shared, closure_feedback_cell_array); DCHECK_EQ(vector->length(), slot_count); @@ -524,12 +523,6 @@ bool FeedbackNexus::Clear() { return feedback_updated; } -void FeedbackNexus::ConfigurePremonomorphic(Handle<Map> receiver_map) { - SetFeedback(*FeedbackVector::PremonomorphicSentinel(GetIsolate()), - SKIP_WRITE_BARRIER); - SetFeedbackExtra(HeapObjectReference::Weak(*receiver_map)); -} - bool FeedbackNexus::ConfigureMegamorphic() { DisallowHeapAllocation no_gc; Isolate* isolate = GetIsolate(); @@ -585,13 +578,6 @@ InlineCacheState FeedbackNexus::ic_state() const { case FeedbackSlotKind::kLoadGlobalInsideTypeof: { if (feedback->IsSmi()) return MONOMORPHIC; - if (feedback == MaybeObject::FromObject( - *FeedbackVector::PremonomorphicSentinel(isolate))) { - DCHECK(kind() == FeedbackSlotKind::kStoreGlobalSloppy || - kind() == FeedbackSlotKind::kStoreGlobalStrict); - return PREMONOMORPHIC; - } - DCHECK(feedback->IsWeakOrCleared()); MaybeObject extra = GetFeedbackExtra(); if (!feedback->IsCleared() || @@ -619,10 +605,6 @@ InlineCacheState FeedbackNexus::ic_state() const { *FeedbackVector::MegamorphicSentinel(isolate))) { return MEGAMORPHIC; } - if (feedback == MaybeObject::FromObject( - *FeedbackVector::PremonomorphicSentinel(isolate))) { - return PREMONOMORPHIC; - } if (feedback->IsWeakOrCleared()) { // Don't check if the map is cleared. return MONOMORPHIC; @@ -974,14 +956,6 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const { Map map = Map::cast(heap_object); maps->push_back(handle(map, isolate)); return 1; - } else if (feedback->GetHeapObjectIfStrong(&heap_object) && - heap_object == - heap_object.GetReadOnlyRoots().premonomorphic_symbol()) { - if (GetFeedbackExtra()->GetHeapObjectIfWeak(&heap_object)) { - Map map = Map::cast(heap_object); - maps->push_back(handle(map, isolate)); - return 1; - } } return 0; @@ -1203,9 +1177,11 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const { handler = handle(Code::cast(data_handler->smi_handler()), vector().GetIsolate()); } else if (maybe_code_handler.object()->IsSmi()) { - // Skip proxy handlers. - DCHECK_EQ(*(maybe_code_handler.object()), - *StoreHandler::StoreProxy(GetIsolate())); + // Skip proxy handlers and the slow handler. + DCHECK(*(maybe_code_handler.object()) == + *StoreHandler::StoreProxy(GetIsolate()) || + *(maybe_code_handler.object()) == + *StoreHandler::StoreSlow(GetIsolate())); continue; } else { // Element store without prototype chain check. diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h index af03bb4130cdc4..1c34266dc830e3 100644 --- a/deps/v8/src/objects/feedback-vector.h +++ b/deps/v8/src/objects/feedback-vector.h @@ -305,9 +305,6 @@ class FeedbackVector : public HeapObject { // The object that indicates a megamorphic state. static inline Handle<Symbol> MegamorphicSentinel(Isolate* isolate); - // The object that indicates a premonomorphic state. - static inline Handle<Symbol> PremonomorphicSentinel(Isolate* isolate); - // A raw version of the uninitialized sentinel that's safe to read during // garbage collection (e.g., for patching the cache). static inline Symbol RawUninitializedSentinel(Isolate* isolate); @@ -567,7 +564,7 @@ class FeedbackMetadata : public HeapObject { // possibly be confused with a pointer. // NOLINTNEXTLINE(runtime/references) (false positive) STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag); -STATIC_ASSERT(Name::kEmptyHashField == 0x3); +STATIC_ASSERT(Name::kEmptyHashField == 0x7); // Verify that a set hash field will not look like a tagged object. STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag); @@ -657,13 +654,12 @@ class V8_EXPORT_PRIVATE FeedbackNexus final { bool IsCleared() const { InlineCacheState state = ic_state(); - return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC; + return !FLAG_use_ic || state == UNINITIALIZED; } // Clear() returns true if the state of the underlying vector was changed. bool Clear(); void ConfigureUninitialized(); - void ConfigurePremonomorphic(Handle<Map> receiver_map); // ConfigureMegamorphic() returns true if the state of the underlying vector // was changed. Extra feedback is cleared if the 0 parameter version is used. bool ConfigureMegamorphic(); diff --git a/deps/v8/src/objects/field-index-inl.h b/deps/v8/src/objects/field-index-inl.h index 997cd68c32be6d..93ffc59c724647 100644 --- a/deps/v8/src/objects/field-index-inl.h +++ b/deps/v8/src/objects/field-index-inl.h @@ -60,13 +60,13 @@ int FieldIndex::GetLoadByFieldIndex() const { return is_double() ? (result | 1) : result; } -FieldIndex FieldIndex::ForDescriptor(Map map, int descriptor_index) { +FieldIndex FieldIndex::ForDescriptor(Map map, InternalIndex descriptor_index) { Isolate* isolate = GetIsolateForPtrCompr(map); return ForDescriptor(isolate, map, descriptor_index); } FieldIndex FieldIndex::ForDescriptor(Isolate* isolate, Map map, - int descriptor_index) { + InternalIndex descriptor_index) { PropertyDetails details = map.instance_descriptors(isolate).GetDetails(descriptor_index); int field_index = details.field_index(); diff --git a/deps/v8/src/objects/field-index.h b/deps/v8/src/objects/field-index.h index 4fae87774d4b53..fbde0bc60918b3 100644 --- a/deps/v8/src/objects/field-index.h +++ b/deps/v8/src/objects/field-index.h @@ -5,6 +5,8 @@ #ifndef V8_OBJECTS_FIELD_INDEX_H_ #define V8_OBJECTS_FIELD_INDEX_H_ +// TODO(jkummerow): Consider forward-declaring instead. +#include "src/objects/internal-index.h" #include "src/objects/property-details.h" #include "src/utils/utils.h" @@ -27,9 +29,10 @@ class FieldIndex final { Map map, int index, Representation representation = Representation::Tagged()); static inline FieldIndex ForInObjectOffset(int offset, Encoding encoding); - static inline FieldIndex ForDescriptor(Map map, int descriptor_index); + static inline FieldIndex ForDescriptor(Map map, + InternalIndex descriptor_index); static inline FieldIndex ForDescriptor(Isolate* isolate, Map map, - int descriptor_index); + InternalIndex descriptor_index); inline int GetLoadByFieldIndex() const; diff --git a/deps/v8/src/objects/fixed-array-inl.h b/deps/v8/src/objects/fixed-array-inl.h index 79c29a6eeba224..9701f8ef095438 100644 --- a/deps/v8/src/objects/fixed-array-inl.h +++ b/deps/v8/src/objects/fixed-array-inl.h @@ -240,7 +240,7 @@ int BinarySearch(T* array, Name name, int valid_entries, for (; low <= limit; ++low) { int sort_index = array->GetSortedKeyIndex(low); - Name entry = array->GetKey(sort_index); + Name entry = array->GetKey(InternalIndex(sort_index)); uint32_t current_hash = entry.hash_field(); if (current_hash != hash) { if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) { @@ -272,7 +272,7 @@ int LinearSearch(T* array, Name name, int valid_entries, int len = array->number_of_entries(); for (int number = 0; number < len; number++) { int sorted_index = array->GetSortedKeyIndex(number); - Name entry = array->GetKey(sorted_index); + Name entry = array->GetKey(InternalIndex(sorted_index)); uint32_t current_hash = entry.hash_field(); if (current_hash > hash) { *out_insertion_index = sorted_index; @@ -286,7 +286,7 @@ int LinearSearch(T* array, Name name, int valid_entries, DCHECK_LE(valid_entries, array->number_of_entries()); DCHECK_NULL(out_insertion_index); // Not supported here. for (int number = 0; number < valid_entries; number++) { - if (array->GetKey(number) == name) return number; + if (array->GetKey(InternalIndex(number)) == name) return number; } return T::kNotFound; } diff --git a/deps/v8/src/objects/fixed-array.h b/deps/v8/src/objects/fixed-array.h index 40290797f71230..b9d644b4923bd8 100644 --- a/deps/v8/src/objects/fixed-array.h +++ b/deps/v8/src/objects/fixed-array.h @@ -86,14 +86,14 @@ class FixedArrayBase : public HeapObject { V8_EXPORT_PRIVATE bool IsCowArray() const; -// Maximal allowed size, in bytes, of a single FixedArrayBase. -// Prevents overflowing size computations, as well as extreme memory -// consumption. -#ifdef V8_HOST_ARCH_32_BIT - static const int kMaxSize = 512 * MB; -#else - static const int kMaxSize = 1024 * MB; -#endif // V8_HOST_ARCH_32_BIT + // Maximal allowed size, in bytes, of a single FixedArrayBase. + // Prevents overflowing size computations, as well as extreme memory + // consumption. It's either (512Mb - kTaggedSize) or (1024Mb - kTaggedSize). + // -kTaggedSize is here to ensure that this max size always fits into Smi + // which is necessary for being able to create a free space filler for the + // whole array of kMaxSize. + static const int kMaxSize = 128 * kTaggedSize * MB - kTaggedSize; + STATIC_ASSERT(Smi::IsValid(kMaxSize)); // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, @@ -120,7 +120,7 @@ class FixedArray : public FixedArrayBase { // Return a grown copy if the index is bigger than the array's length. V8_EXPORT_PRIVATE static Handle<FixedArray> SetAndGrow( Isolate* isolate, Handle<FixedArray> array, int index, - Handle<Object> value, AllocationType allocation = AllocationType::kYoung); + Handle<Object> value); // Setter that uses write barrier. inline void set(int index, Object value); @@ -303,7 +303,6 @@ class WeakFixedArray : public HeapObject { DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, TORQUE_GENERATED_WEAK_FIXED_ARRAY_FIELDS) - static constexpr int kHeaderSize = kSize; static const int kMaxLength = (FixedArray::kMaxSize - kHeaderSize) / kTaggedSize; @@ -339,6 +338,12 @@ class WeakArrayList : public HeapObject { Isolate* isolate, Handle<WeakArrayList> array, const MaybeObjectHandle& value); + // A version that adds to elements. This ensures that the elements are + // inserted atomically w.r.t GC. + V8_EXPORT_PRIVATE static Handle<WeakArrayList> AddToEnd( + Isolate* isolate, Handle<WeakArrayList> array, + const MaybeObjectHandle& value1, const MaybeObjectHandle& value2); + inline MaybeObject Get(int index) const; inline MaybeObject Get(Isolate* isolate, int index) const; diff --git a/deps/v8/src/objects/function-kind.h b/deps/v8/src/objects/function-kind.h index 8e9c68e426c132..9b0de76126b27d 100644 --- a/deps/v8/src/objects/function-kind.h +++ b/deps/v8/src/objects/function-kind.h @@ -14,6 +14,7 @@ enum FunctionKind : uint8_t { // BEGIN constructable functions kNormalFunction, kModule, + kAsyncModule, // BEGIN class constructors // BEGIN base constructors kBaseConstructor, @@ -61,7 +62,11 @@ inline bool IsArrowFunction(FunctionKind kind) { } inline bool IsModule(FunctionKind kind) { - return kind == FunctionKind::kModule; + return IsInRange(kind, FunctionKind::kModule, FunctionKind::kAsyncModule); +} + +inline bool IsAsyncModule(FunctionKind kind) { + return kind == FunctionKind::kAsyncModule; } inline bool IsAsyncGeneratorFunction(FunctionKind kind) { @@ -163,6 +168,8 @@ inline const char* FunctionKind2String(FunctionKind kind) { return "AsyncFunction"; case FunctionKind::kModule: return "Module"; + case FunctionKind::kAsyncModule: + return "AsyncModule"; case FunctionKind::kClassMembersInitializerFunction: return "ClassMembersInitializerFunction"; case FunctionKind::kDefaultBaseConstructor: diff --git a/deps/v8/src/objects/hash-table-inl.h b/deps/v8/src/objects/hash-table-inl.h index b807851d85fb70..d4c96f4df49ab9 100644 --- a/deps/v8/src/objects/hash-table-inl.h +++ b/deps/v8/src/objects/hash-table-inl.h @@ -7,6 +7,7 @@ #include "src/objects/hash-table.h" +#include "src/execution/isolate-utils-inl.h" #include "src/heap/heap.h" #include "src/objects/fixed-array-inl.h" #include "src/objects/heap-object-inl.h" @@ -178,6 +179,17 @@ bool HashTable<Derived, Shape>::ToKey(Isolate* isolate, int entry, return true; } +template <typename Derived, typename Shape> +Object HashTable<Derived, Shape>::KeyAt(int entry) { + Isolate* isolate = GetIsolateForPtrCompr(*this); + return KeyAt(isolate, entry); +} + +template <typename Derived, typename Shape> +Object HashTable<Derived, Shape>::KeyAt(Isolate* isolate, int entry) { + return get(isolate, EntryToIndex(entry) + kEntryKeyIndex); +} + template <typename Derived, typename Shape> void HashTable<Derived, Shape>::set_key(int index, Object value) { DCHECK(!IsEphemeronHashTable()); @@ -191,6 +203,16 @@ void HashTable<Derived, Shape>::set_key(int index, Object value, FixedArray::set(index, value, mode); } +template <typename Derived, typename Shape> +void HashTable<Derived, Shape>::SetCapacity(int capacity) { + // To scale a computed hash code to fit within the hash table, we + // use bit-wise AND with a mask, so the capacity must be positive + // and non-zero. + DCHECK_GT(capacity, 0); + DCHECK_LE(capacity, kMaxCapacity); + set(kCapacityIndex, Smi::FromInt(capacity)); +} + template <typename KeyT> bool BaseShape<KeyT>::IsKey(ReadOnlyRoots roots, Object key) { return IsLive(roots, key); diff --git a/deps/v8/src/objects/hash-table.h b/deps/v8/src/objects/hash-table.h index 54d8ce0d2ae18b..5cdeb0c0ec4f9d 100644 --- a/deps/v8/src/objects/hash-table.h +++ b/deps/v8/src/objects/hash-table.h @@ -9,6 +9,7 @@ #include "src/base/export-template.h" #include "src/base/macros.h" #include "src/common/globals.h" +#include "src/execution/isolate-utils.h" #include "src/objects/fixed-array.h" #include "src/objects/smi.h" #include "src/roots/roots.h" @@ -163,13 +164,8 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable inline bool ToKey(Isolate* isolate, int entry, Object* out_k); // Returns the key at entry. - Object KeyAt(int entry) { - Isolate* isolate = GetIsolateForPtrCompr(*this); - return KeyAt(isolate, entry); - } - Object KeyAt(Isolate* isolate, int entry) { - return get(isolate, EntryToIndex(entry) + kEntryKeyIndex); - } + inline Object KeyAt(int entry); + inline Object KeyAt(Isolate* isolate, int entry); static const int kElementsStartIndex = kPrefixStartIndex + Shape::kPrefixSize; static const int kEntrySize = Shape::kEntrySize; @@ -238,14 +234,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable kMaxRegularHeapObjectSize); // Sets the capacity of the hash table. - void SetCapacity(int capacity) { - // To scale a computed hash code to fit within the hash table, we - // use bit-wise AND with a mask, so the capacity must be positive - // and non-zero. - DCHECK_GT(capacity, 0); - DCHECK_LE(capacity, kMaxCapacity); - set(kCapacityIndex, Smi::FromInt(capacity)); - } + inline void SetCapacity(int capacity); // Returns _expected_ if one of entries given by the first _probe_ probes is // equal to _expected_. Otherwise, returns the entry given by the probe diff --git a/deps/v8/src/objects/heap-number-inl.h b/deps/v8/src/objects/heap-number-inl.h index 78e65ca2313df1..546b16e93d8ea6 100644 --- a/deps/v8/src/objects/heap-number-inl.h +++ b/deps/v8/src/objects/heap-number-inl.h @@ -7,8 +7,8 @@ #include "src/objects/heap-number.h" -#include "src/objects/heap-object-inl.h" #include "src/objects/objects-inl.h" +#include "src/objects/primitive-heap-object-inl.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -16,7 +16,7 @@ namespace v8 { namespace internal { -OBJECT_CONSTRUCTORS_IMPL(HeapNumber, HeapObject) +OBJECT_CONSTRUCTORS_IMPL(HeapNumber, PrimitiveHeapObject) CAST_ACCESSOR(HeapNumber) diff --git a/deps/v8/src/objects/heap-number.h b/deps/v8/src/objects/heap-number.h index 9063f3d22c9084..0982cc232ea0c3 100644 --- a/deps/v8/src/objects/heap-number.h +++ b/deps/v8/src/objects/heap-number.h @@ -5,7 +5,7 @@ #ifndef V8_OBJECTS_HEAP_NUMBER_H_ #define V8_OBJECTS_HEAP_NUMBER_H_ -#include "src/objects/heap-object.h" +#include "src/objects/primitive-heap-object.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -15,7 +15,7 @@ namespace internal { // The HeapNumber class describes heap allocated numbers that cannot be // represented in a Smi (small integer). -class HeapNumber : public HeapObject { +class HeapNumber : public PrimitiveHeapObject { public: // [value]: number value. inline double value() const; @@ -28,7 +28,7 @@ class HeapNumber : public HeapObject { inline int get_sign(); // Layout description. - static const int kValueOffset = HeapObject::kHeaderSize; + static const int kValueOffset = PrimitiveHeapObject::kHeaderSize; // IEEE doubles are two 32 bit words. The first is just mantissa, the second // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit // words within double numbers are endian dependent and they are set @@ -59,7 +59,7 @@ class HeapNumber : public HeapObject { DECL_CAST(HeapNumber) V8_EXPORT_PRIVATE void HeapNumberPrint(std::ostream& os); - OBJECT_CONSTRUCTORS(HeapNumber, HeapObject); + OBJECT_CONSTRUCTORS(HeapNumber, PrimitiveHeapObject); }; } // namespace internal diff --git a/deps/v8/src/objects/instance-type.h b/deps/v8/src/objects/instance-type.h index 9a855de95bcf0c..f9931972049f86 100644 --- a/deps/v8/src/objects/instance-type.h +++ b/deps/v8/src/objects/instance-type.h @@ -80,8 +80,8 @@ static inline bool IsShortcutCandidate(int type) { enum InstanceType : uint16_t { // String types. - INTERNALIZED_STRING_TYPE = kTwoByteStringTag | kSeqStringTag | - kInternalizedTag, // FIRST_PRIMITIVE_TYPE + INTERNALIZED_STRING_TYPE = + kTwoByteStringTag | kSeqStringTag | kInternalizedTag, ONE_BYTE_INTERNALIZED_STRING_TYPE = kOneByteStringTag | kSeqStringTag | kInternalizedTag, EXTERNAL_INTERNALIZED_STRING_TYPE = @@ -116,262 +116,41 @@ enum InstanceType : uint16_t { THIN_ONE_BYTE_STRING_TYPE = kOneByteStringTag | kThinStringTag | kNotInternalizedTag, - // Non-string names - SYMBOL_TYPE = - 1 + (kIsNotInternalizedMask | kUncachedExternalStringMask | - kStringEncodingMask | - kStringRepresentationMask), // FIRST_NONSTRING_TYPE, LAST_NAME_TYPE - - // Other primitives (cannot contain non-map-word pointers to heap objects). - HEAP_NUMBER_TYPE, - BIGINT_TYPE, - ODDBALL_TYPE, // LAST_PRIMITIVE_TYPE - - // Objects allocated in their own spaces (never in new space). - MAP_TYPE, - CODE_TYPE, - - // "Data", objects that cannot contain non-map-word pointers to heap - // objects. - FOREIGN_TYPE, - BYTE_ARRAY_TYPE, - BYTECODE_ARRAY_TYPE, - FREE_SPACE_TYPE, - FIXED_DOUBLE_ARRAY_TYPE, - FEEDBACK_METADATA_TYPE, - FILLER_TYPE, // LAST_DATA_TYPE - - // Structs. - ACCESS_CHECK_INFO_TYPE, - ACCESSOR_INFO_TYPE, - ACCESSOR_PAIR_TYPE, - ALIASED_ARGUMENTS_ENTRY_TYPE, - ALLOCATION_MEMENTO_TYPE, - ARRAY_BOILERPLATE_DESCRIPTION_TYPE, - ASM_WASM_DATA_TYPE, - ASYNC_GENERATOR_REQUEST_TYPE, - CLASS_POSITIONS_TYPE, - DEBUG_INFO_TYPE, - ENUM_CACHE_TYPE, - FUNCTION_TEMPLATE_INFO_TYPE, - FUNCTION_TEMPLATE_RARE_DATA_TYPE, - INTERCEPTOR_INFO_TYPE, - INTERPRETER_DATA_TYPE, - OBJECT_TEMPLATE_INFO_TYPE, - PROMISE_CAPABILITY_TYPE, - PROMISE_REACTION_TYPE, - PROTOTYPE_INFO_TYPE, - SCRIPT_TYPE, - SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE, - SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE, - STACK_FRAME_INFO_TYPE, - STACK_TRACE_FRAME_TYPE, - TEMPLATE_OBJECT_DESCRIPTION_TYPE, - TUPLE2_TYPE, - TUPLE3_TYPE, - WASM_CAPI_FUNCTION_DATA_TYPE, - WASM_DEBUG_INFO_TYPE, - WASM_EXCEPTION_TAG_TYPE, - WASM_EXPORTED_FUNCTION_DATA_TYPE, - WASM_INDIRECT_FUNCTION_TABLE_TYPE, - WASM_JS_FUNCTION_DATA_TYPE, - - CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE - CALLBACK_TASK_TYPE, - PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, - PROMISE_REJECT_REACTION_JOB_TASK_TYPE, - PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, // LAST_MICROTASK_TYPE - -#define MAKE_TORQUE_INSTANCE_TYPE(V) V, - TORQUE_DEFINED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE) +// Most instance types are defined in Torque, with the exception of the string +// types above. They are ordered by inheritance hierarchy so that we can easily +// use range checks to determine whether an object is an instance of a subclass +// of any type. There are a few more constraints specified in the Torque type +// definitions: +// - Some instance types are exposed in v8.h, so they are locked to specific +// values to not unnecessarily change the ABI. +// - JSSpecialObject and JSCustomElementsObject are aligned with the beginning +// of the JSObject range, so that we can use a larger range check from +// FIRST_JS_RECEIVER_TYPE to the end of those ranges and include JSProxy too. +// - JSFunction is last, meaning we can use a single inequality check to +// determine whether an instance type is within the range for any class in the +// inheritance hierarchy of JSFunction. This includes commonly-checked classes +// JSObject and JSReceiver. +#define MAKE_TORQUE_INSTANCE_TYPE(TYPE, value) TYPE = value, + TORQUE_ASSIGNED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE) #undef MAKE_TORQUE_INSTANCE_TYPE - // Modules - SOURCE_TEXT_MODULE_TYPE, // FIRST_MODULE_TYPE - SYNTHETIC_MODULE_TYPE, // LAST_MODULE_TYPE - - ALLOCATION_SITE_TYPE, - EMBEDDER_DATA_ARRAY_TYPE, - // FixedArrays. - FIXED_ARRAY_TYPE, // FIRST_FIXED_ARRAY_TYPE - OBJECT_BOILERPLATE_DESCRIPTION_TYPE, - CLOSURE_FEEDBACK_CELL_ARRAY_TYPE, - HASH_TABLE_TYPE, // FIRST_HASH_TABLE_TYPE - ORDERED_HASH_MAP_TYPE, - ORDERED_HASH_SET_TYPE, - ORDERED_NAME_DICTIONARY_TYPE, - NAME_DICTIONARY_TYPE, - GLOBAL_DICTIONARY_TYPE, - NUMBER_DICTIONARY_TYPE, - SIMPLE_NUMBER_DICTIONARY_TYPE, - STRING_TABLE_TYPE, - EPHEMERON_HASH_TABLE_TYPE, // LAST_HASH_TABLE_TYPE - SCOPE_INFO_TYPE, - SCRIPT_CONTEXT_TABLE_TYPE, // LAST_FIXED_ARRAY_TYPE, - - // Contexts. - AWAIT_CONTEXT_TYPE, // FIRST_CONTEXT_TYPE - BLOCK_CONTEXT_TYPE, - CATCH_CONTEXT_TYPE, - DEBUG_EVALUATE_CONTEXT_TYPE, - EVAL_CONTEXT_TYPE, - FUNCTION_CONTEXT_TYPE, - MODULE_CONTEXT_TYPE, - NATIVE_CONTEXT_TYPE, - SCRIPT_CONTEXT_TYPE, - WITH_CONTEXT_TYPE, // LAST_CONTEXT_TYPE - - WEAK_FIXED_ARRAY_TYPE, // FIRST_WEAK_FIXED_ARRAY_TYPE - TRANSITION_ARRAY_TYPE, // LAST_WEAK_FIXED_ARRAY_TYPE - - // Misc. - CALL_HANDLER_INFO_TYPE, - CELL_TYPE, - CODE_DATA_CONTAINER_TYPE, - DESCRIPTOR_ARRAY_TYPE, - FEEDBACK_CELL_TYPE, - FEEDBACK_VECTOR_TYPE, - LOAD_HANDLER_TYPE, - PREPARSE_DATA_TYPE, - PROPERTY_ARRAY_TYPE, - PROPERTY_CELL_TYPE, - SHARED_FUNCTION_INFO_TYPE, - SMALL_ORDERED_HASH_MAP_TYPE, - SMALL_ORDERED_HASH_SET_TYPE, - SMALL_ORDERED_NAME_DICTIONARY_TYPE, - STORE_HANDLER_TYPE, - UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE, - UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE, - WEAK_ARRAY_LIST_TYPE, - WEAK_CELL_TYPE, - - // All the following types are subtypes of JSReceiver, which corresponds to - // objects in the JS sense. The first and the last type in this range are - // the two forms of function. This organization enables using the same - // compares for checking the JS_RECEIVER and the NONCALLABLE_JS_OBJECT range. - // Some of the following instance types are exposed in v8.h, so to not - // unnecessarily change the ABI when we introduce new instance types in the - // future, we leave some space between instance types. - JS_PROXY_TYPE = 0x0400, // FIRST_JS_RECEIVER_TYPE - JS_GLOBAL_OBJECT_TYPE, // FIRST_JS_OBJECT_TYPE - JS_GLOBAL_PROXY_TYPE, - JS_MODULE_NAMESPACE_TYPE, - // Like JS_API_OBJECT_TYPE, but requires access checks and/or has - // interceptors. - JS_SPECIAL_API_OBJECT_TYPE = 0x0410, // LAST_SPECIAL_RECEIVER_TYPE - JS_PRIMITIVE_WRAPPER_TYPE, // LAST_CUSTOM_ELEMENTS_RECEIVER - // Like JS_OBJECT_TYPE, but created from API function. - JS_API_OBJECT_TYPE = 0x0420, - JS_OBJECT_TYPE, - JS_ARGUMENTS_TYPE, - JS_ARRAY_BUFFER_TYPE, - JS_ARRAY_ITERATOR_TYPE, - JS_ARRAY_TYPE, - JS_ASYNC_FROM_SYNC_ITERATOR_TYPE, - JS_ASYNC_FUNCTION_OBJECT_TYPE, - JS_ASYNC_GENERATOR_OBJECT_TYPE, - JS_CONTEXT_EXTENSION_OBJECT_TYPE, - JS_DATE_TYPE, - JS_ERROR_TYPE, - JS_GENERATOR_OBJECT_TYPE, - JS_MAP_TYPE, - JS_MAP_KEY_ITERATOR_TYPE, - JS_MAP_KEY_VALUE_ITERATOR_TYPE, - JS_MAP_VALUE_ITERATOR_TYPE, - JS_MESSAGE_OBJECT_TYPE, - JS_PROMISE_TYPE, - JS_REGEXP_TYPE, - JS_REGEXP_STRING_ITERATOR_TYPE, - JS_SET_TYPE, - JS_SET_KEY_VALUE_ITERATOR_TYPE, - JS_SET_VALUE_ITERATOR_TYPE, - JS_STRING_ITERATOR_TYPE, - JS_WEAK_REF_TYPE, - JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE, - JS_FINALIZATION_GROUP_TYPE, - JS_WEAK_MAP_TYPE, - JS_WEAK_SET_TYPE, - - JS_TYPED_ARRAY_TYPE, - JS_DATA_VIEW_TYPE, - -#ifdef V8_INTL_SUPPORT - JS_INTL_V8_BREAK_ITERATOR_TYPE, - JS_INTL_COLLATOR_TYPE, - JS_INTL_DATE_TIME_FORMAT_TYPE, - JS_INTL_LIST_FORMAT_TYPE, - JS_INTL_LOCALE_TYPE, - JS_INTL_NUMBER_FORMAT_TYPE, - JS_INTL_PLURAL_RULES_TYPE, - JS_INTL_RELATIVE_TIME_FORMAT_TYPE, - JS_INTL_SEGMENT_ITERATOR_TYPE, - JS_INTL_SEGMENTER_TYPE, -#endif // V8_INTL_SUPPORT - - WASM_EXCEPTION_TYPE, - WASM_GLOBAL_TYPE, - WASM_INSTANCE_TYPE, - WASM_MEMORY_TYPE, - WASM_MODULE_TYPE, - WASM_TABLE_TYPE, - JS_BOUND_FUNCTION_TYPE, - JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE - // Pseudo-types - FIRST_TYPE = 0x0, - LAST_TYPE = JS_FUNCTION_TYPE, - FIRST_STRING_TYPE = FIRST_TYPE, - FIRST_NAME_TYPE = FIRST_STRING_TYPE, - LAST_NAME_TYPE = SYMBOL_TYPE, FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_STRING_TYPE, LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE, FIRST_NONSTRING_TYPE = SYMBOL_TYPE, - FIRST_PRIMITIVE_TYPE = FIRST_NAME_TYPE, - LAST_PRIMITIVE_TYPE = ODDBALL_TYPE, - FIRST_FUNCTION_TYPE = JS_BOUND_FUNCTION_TYPE, - LAST_FUNCTION_TYPE = JS_FUNCTION_TYPE, - // Boundaries for testing if given HeapObject is a subclass of FixedArray. - FIRST_FIXED_ARRAY_TYPE = FIXED_ARRAY_TYPE, - LAST_FIXED_ARRAY_TYPE = SCRIPT_CONTEXT_TABLE_TYPE, - // Boundaries for testing if given HeapObject is a subclass of HashTable - FIRST_HASH_TABLE_TYPE = HASH_TABLE_TYPE, - LAST_HASH_TABLE_TYPE = EPHEMERON_HASH_TABLE_TYPE, - // Boundaries for testing if given HeapObject is a subclass of WeakFixedArray. - FIRST_WEAK_FIXED_ARRAY_TYPE = WEAK_FIXED_ARRAY_TYPE, - LAST_WEAK_FIXED_ARRAY_TYPE = TRANSITION_ARRAY_TYPE, - // Boundaries for testing if given HeapObject is a Context - FIRST_CONTEXT_TYPE = AWAIT_CONTEXT_TYPE, - LAST_CONTEXT_TYPE = WITH_CONTEXT_TYPE, - // Boundaries for testing if given HeapObject is a subclass of Microtask. - FIRST_MICROTASK_TYPE = CALLABLE_TASK_TYPE, - LAST_MICROTASK_TYPE = PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, - // Boundaries of module record types - FIRST_MODULE_TYPE = SOURCE_TEXT_MODULE_TYPE, - LAST_MODULE_TYPE = SYNTHETIC_MODULE_TYPE, - // Boundary for promotion to old space. - LAST_DATA_TYPE = FILLER_TYPE, - // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy). - // Note that there is no range for JSObject or JSProxy, since their subtypes - // are not continuous in this enum! The enum ranges instead reflect the - // external class names, where proxies are treated as either ordinary objects, - // or functions. - FIRST_JS_RECEIVER_TYPE = JS_PROXY_TYPE, - LAST_JS_RECEIVER_TYPE = LAST_TYPE, - // Boundaries for testing the types represented as JSObject - FIRST_JS_OBJECT_TYPE = JS_GLOBAL_OBJECT_TYPE, - LAST_JS_OBJECT_TYPE = LAST_TYPE, // Boundary for testing JSReceivers that need special property lookup handling - LAST_SPECIAL_RECEIVER_TYPE = JS_SPECIAL_API_OBJECT_TYPE, + LAST_SPECIAL_RECEIVER_TYPE = LAST_JS_SPECIAL_OBJECT_TYPE, // Boundary case for testing JSReceivers that may have elements while having // an empty fixed array as elements backing store. This is true for string // wrappers. - LAST_CUSTOM_ELEMENTS_RECEIVER = JS_PRIMITIVE_WRAPPER_TYPE, - - FIRST_SET_ITERATOR_TYPE = JS_SET_KEY_VALUE_ITERATOR_TYPE, - LAST_SET_ITERATOR_TYPE = JS_SET_VALUE_ITERATOR_TYPE, - - FIRST_MAP_ITERATOR_TYPE = JS_MAP_KEY_ITERATOR_TYPE, - LAST_MAP_ITERATOR_TYPE = JS_MAP_VALUE_ITERATOR_TYPE, + LAST_CUSTOM_ELEMENTS_RECEIVER = LAST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE, + + // Convenient names for things where the generated name is awkward: + FIRST_TYPE = FIRST_HEAP_OBJECT_TYPE, + LAST_TYPE = LAST_HEAP_OBJECT_TYPE, + FIRST_FUNCTION_TYPE = FIRST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE, + LAST_FUNCTION_TYPE = LAST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE, + BIGINT_TYPE = BIG_INT_BASE_TYPE, }; // This constant is defined outside of the InstanceType enum because the @@ -389,6 +168,40 @@ STATIC_ASSERT(FIRST_NONSTRING_TYPE == Internals::kFirstNonstringType); STATIC_ASSERT(ODDBALL_TYPE == Internals::kOddballType); STATIC_ASSERT(FOREIGN_TYPE == Internals::kForeignType); +// Verify that string types are all less than other types. +#define CHECK_STRING_RANGE(TYPE, ...) \ + STATIC_ASSERT(TYPE < FIRST_NONSTRING_TYPE); +STRING_TYPE_LIST(CHECK_STRING_RANGE) +#undef CHECK_STRING_RANGE +#define CHECK_NONSTRING_RANGE(TYPE) STATIC_ASSERT(TYPE >= FIRST_NONSTRING_TYPE); +TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(CHECK_NONSTRING_RANGE) +#undef CHECK_NONSTRING_RANGE + +// Two ranges don't cleanly follow the inheritance hierarchy. Here we ensure +// that only expected types fall within these ranges. +// - From FIRST_JS_RECEIVER_TYPE to LAST_SPECIAL_RECEIVER_TYPE should correspond +// to the union type JSProxy | JSSpecialObject. +// - From FIRST_JS_RECEIVER_TYPE to LAST_CUSTOM_ELEMENTS_RECEIVER should +// correspond to the union type JSProxy | JSCustomElementsObject. +// Note in particular that these ranges include all subclasses of JSReceiver +// that are not also subclasses of JSObject (currently only JSProxy). +#define CHECK_INSTANCE_TYPE(TYPE) \ + STATIC_ASSERT((TYPE >= FIRST_JS_RECEIVER_TYPE && \ + TYPE <= LAST_SPECIAL_RECEIVER_TYPE) == \ + (TYPE == JS_PROXY_TYPE || TYPE == JS_GLOBAL_OBJECT_TYPE || \ + TYPE == JS_GLOBAL_PROXY_TYPE || \ + TYPE == JS_MODULE_NAMESPACE_TYPE || \ + TYPE == JS_SPECIAL_API_OBJECT_TYPE)); \ + STATIC_ASSERT((TYPE >= FIRST_JS_RECEIVER_TYPE && \ + TYPE <= LAST_CUSTOM_ELEMENTS_RECEIVER) == \ + (TYPE == JS_PROXY_TYPE || TYPE == JS_GLOBAL_OBJECT_TYPE || \ + TYPE == JS_GLOBAL_PROXY_TYPE || \ + TYPE == JS_MODULE_NAMESPACE_TYPE || \ + TYPE == JS_SPECIAL_API_OBJECT_TYPE || \ + TYPE == JS_PRIMITIVE_WRAPPER_TYPE)); +TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(CHECK_INSTANCE_TYPE) +#undef CHECK_INSTANCE_TYPE + // Make sure it doesn't matter whether we sign-extend or zero-extend these // values, because Torque treats InstanceType as signed. STATIC_ASSERT(LAST_TYPE < 1 << 15); @@ -424,8 +237,8 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, V(FreeSpace, FREE_SPACE_TYPE) \ V(GlobalDictionary, GLOBAL_DICTIONARY_TYPE) \ V(HeapNumber, HEAP_NUMBER_TYPE) \ - V(JSArgumentsObject, JS_ARGUMENTS_TYPE) \ - V(JSArgumentsObjectWithLength, JS_ARGUMENTS_TYPE) \ + V(JSArgumentsObject, JS_ARGUMENTS_OBJECT_TYPE) \ + V(JSArgumentsObjectWithLength, JS_ARGUMENTS_OBJECT_TYPE) \ V(JSArray, JS_ARRAY_TYPE) \ V(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE) \ V(JSArrayIterator, JS_ARRAY_ITERATOR_TYPE) \ @@ -449,9 +262,10 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, V(JSPrimitiveWrapper, JS_PRIMITIVE_WRAPPER_TYPE) \ V(JSPromise, JS_PROMISE_TYPE) \ V(JSProxy, JS_PROXY_TYPE) \ - V(JSRegExp, JS_REGEXP_TYPE) \ + V(JSRegExp, JS_REG_EXP_TYPE) \ V(JSRegExpResult, JS_ARRAY_TYPE) \ - V(JSRegExpStringIterator, JS_REGEXP_STRING_ITERATOR_TYPE) \ + V(JSRegExpResultIndices, JS_ARRAY_TYPE) \ + V(JSRegExpStringIterator, JS_REG_EXP_STRING_ITERATOR_TYPE) \ V(JSSet, JS_SET_TYPE) \ V(JSStringIterator, JS_STRING_ITERATOR_TYPE) \ V(JSTypedArray, JS_TYPED_ARRAY_TYPE) \ @@ -487,28 +301,28 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, V(UncompiledDataWithoutPreparseData, \ UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE) \ V(UncompiledDataWithPreparseData, UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE) \ - V(WasmExceptionObject, WASM_EXCEPTION_TYPE) \ - V(WasmGlobalObject, WASM_GLOBAL_TYPE) \ - V(WasmInstanceObject, WASM_INSTANCE_TYPE) \ - V(WasmMemoryObject, WASM_MEMORY_TYPE) \ - V(WasmModuleObject, WASM_MODULE_TYPE) \ - V(WasmTableObject, WASM_TABLE_TYPE) \ + V(WasmExceptionObject, WASM_EXCEPTION_OBJECT_TYPE) \ + V(WasmGlobalObject, WASM_GLOBAL_OBJECT_TYPE) \ + V(WasmInstanceObject, WASM_INSTANCE_OBJECT_TYPE) \ + V(WasmMemoryObject, WASM_MEMORY_OBJECT_TYPE) \ + V(WasmModuleObject, WASM_MODULE_OBJECT_TYPE) \ + V(WasmTableObject, WASM_TABLE_OBJECT_TYPE) \ V(WeakArrayList, WEAK_ARRAY_LIST_TYPE) \ V(WeakCell, WEAK_CELL_TYPE) #ifdef V8_INTL_SUPPORT -#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \ - INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V) \ - V(JSV8BreakIterator, JS_INTL_V8_BREAK_ITERATOR_TYPE) \ - V(JSCollator, JS_INTL_COLLATOR_TYPE) \ - V(JSDateTimeFormat, JS_INTL_DATE_TIME_FORMAT_TYPE) \ - V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE) \ - V(JSLocale, JS_INTL_LOCALE_TYPE) \ - V(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE) \ - V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \ - V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \ - V(JSSegmentIterator, JS_INTL_SEGMENT_ITERATOR_TYPE) \ - V(JSSegmenter, JS_INTL_SEGMENTER_TYPE) +#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \ + INSTANCE_TYPE_CHECKERS_SINGLE_BASE(V) \ + V(JSV8BreakIterator, JS_V8_BREAK_ITERATOR_TYPE) \ + V(JSCollator, JS_COLLATOR_TYPE) \ + V(JSDateTimeFormat, JS_DATE_TIME_FORMAT_TYPE) \ + V(JSListFormat, JS_LIST_FORMAT_TYPE) \ + V(JSLocale, JS_LOCALE_TYPE) \ + V(JSNumberFormat, JS_NUMBER_FORMAT_TYPE) \ + V(JSPluralRules, JS_PLURAL_RULES_TYPE) \ + V(JSRelativeTimeFormat, JS_RELATIVE_TIME_FORMAT_TYPE) \ + V(JSSegmentIterator, JS_SEGMENT_ITERATOR_TYPE) \ + V(JSSegmenter, JS_SEGMENTER_TYPE) #else @@ -516,16 +330,23 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, #endif // V8_INTL_SUPPORT -#define INSTANCE_TYPE_CHECKERS_RANGE(V) \ - V(Context, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE) \ - V(FixedArray, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE) \ - V(HashTable, FIRST_HASH_TABLE_TYPE, LAST_HASH_TABLE_TYPE) \ - V(JSMapIterator, FIRST_MAP_ITERATOR_TYPE, LAST_MAP_ITERATOR_TYPE) \ - V(JSSetIterator, FIRST_SET_ITERATOR_TYPE, LAST_SET_ITERATOR_TYPE) \ - V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE) \ - V(Module, FIRST_MODULE_TYPE, LAST_MODULE_TYPE) \ - V(Name, FIRST_NAME_TYPE, LAST_NAME_TYPE) \ - V(String, FIRST_STRING_TYPE, LAST_STRING_TYPE) \ +#define INSTANCE_TYPE_CHECKERS_RANGE(V) \ + V(Context, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE) \ + V(FixedArray, FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE) \ + V(HashTable, FIRST_HASH_TABLE_TYPE, LAST_HASH_TABLE_TYPE) \ + V(JSCustomElementsObject, FIRST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE, \ + LAST_JS_CUSTOM_ELEMENTS_OBJECT_TYPE) \ + V(JSFunctionOrBoundFunction, FIRST_FUNCTION_TYPE, LAST_FUNCTION_TYPE) \ + V(JSMapIterator, FIRST_JS_MAP_ITERATOR_TYPE, LAST_JS_MAP_ITERATOR_TYPE) \ + V(JSSetIterator, FIRST_JS_SET_ITERATOR_TYPE, LAST_JS_SET_ITERATOR_TYPE) \ + V(JSSpecialObject, FIRST_JS_SPECIAL_OBJECT_TYPE, \ + LAST_JS_SPECIAL_OBJECT_TYPE) \ + V(Microtask, FIRST_MICROTASK_TYPE, LAST_MICROTASK_TYPE) \ + V(Module, FIRST_MODULE_TYPE, LAST_MODULE_TYPE) \ + V(Name, FIRST_NAME_TYPE, LAST_NAME_TYPE) \ + V(PrimitiveHeapObject, FIRST_PRIMITIVE_HEAP_OBJECT_TYPE, \ + LAST_PRIMITIVE_HEAP_OBJECT_TYPE) \ + V(String, FIRST_STRING_TYPE, LAST_STRING_TYPE) \ V(WeakFixedArray, FIRST_WEAK_FIXED_ARRAY_TYPE, LAST_WEAK_FIXED_ARRAY_TYPE) #define INSTANCE_TYPE_CHECKERS_CUSTOM(V) \ diff --git a/deps/v8/src/objects/internal-index.h b/deps/v8/src/objects/internal-index.h new file mode 100644 index 00000000000000..ce7378a9017d2c --- /dev/null +++ b/deps/v8/src/objects/internal-index.h @@ -0,0 +1,79 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_INTERNAL_INDEX_H_ +#define V8_OBJECTS_INTERNAL_INDEX_H_ + +#include <stdint.h> + +#include <limits> + +#include "src/base/logging.h" + +namespace v8 { +namespace internal { + +// Simple wrapper around an entry (which is notably different from "index" for +// dictionary backing stores). Most code should treat this as an opaque +// wrapper: get it via GetEntryForIndex, pass it on to consumers. +class InternalIndex { + public: + explicit InternalIndex(size_t raw) : entry_(raw) {} + static InternalIndex NotFound() { return InternalIndex(kNotFound); } + + InternalIndex adjust_down(size_t subtract) { + DCHECK_GE(entry_, subtract); + return InternalIndex(entry_ - subtract); + } + InternalIndex adjust_up(size_t add) { + DCHECK_LT(entry_, std::numeric_limits<size_t>::max() - add); + return InternalIndex(entry_ + add); + } + + bool is_found() const { return entry_ != kNotFound; } + bool is_not_found() const { return entry_ == kNotFound; } + + size_t raw_value() const { return entry_; } + uint32_t as_uint32() const { + DCHECK_LE(entry_, std::numeric_limits<uint32_t>::max()); + return static_cast<uint32_t>(entry_); + } + int as_int() const { + DCHECK(entry_ >= 0 && entry_ <= std::numeric_limits<int>::max()); + return static_cast<int>(entry_); + } + + bool operator==(const InternalIndex& other) { return entry_ == other.entry_; } + + // Iteration support. + InternalIndex operator*() { return *this; } + bool operator!=(const InternalIndex& other) { return entry_ != other.entry_; } + InternalIndex& operator++() { + entry_++; + return *this; + } + + class Range { + public: + explicit Range(size_t max) : min_(0), max_(max) {} + Range(size_t min, size_t max) : min_(min), max_(max) {} + + InternalIndex begin() { return InternalIndex(min_); } + InternalIndex end() { return InternalIndex(max_); } + + private: + size_t min_; + size_t max_; + }; + + private: + static const size_t kNotFound = std::numeric_limits<size_t>::max(); + + size_t entry_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_OBJECTS_INTERNAL_INDEX_H_ diff --git a/deps/v8/src/objects/intl-objects.cc b/deps/v8/src/objects/intl-objects.cc index dbf212aaf8228e..a6a2fdd22997f1 100644 --- a/deps/v8/src/objects/intl-objects.cc +++ b/deps/v8/src/objects/intl-objects.cc @@ -20,6 +20,7 @@ #include "src/objects/js-collator-inl.h" #include "src/objects/js-date-time-format-inl.h" #include "src/objects/js-locale-inl.h" +#include "src/objects/js-locale.h" #include "src/objects/js-number-format-inl.h" #include "src/objects/objects-inl.h" #include "src/objects/property-descriptor.h" @@ -32,6 +33,7 @@ #include "unicode/datefmt.h" #include "unicode/decimfmt.h" #include "unicode/formattedvalue.h" +#include "unicode/localebuilder.h" #include "unicode/locid.h" #include "unicode/normalizer2.h" #include "unicode/numberformatter.h" @@ -177,12 +179,13 @@ const UChar* GetUCharBufferFromFlat(const String::FlatContent& flat, template <typename T> MaybeHandle<T> New(Isolate* isolate, Handle<JSFunction> constructor, - Handle<Object> locales, Handle<Object> options) { + Handle<Object> locales, Handle<Object> options, + const char* method) { Handle<Map> map; ASSIGN_RETURN_ON_EXCEPTION( isolate, map, JSFunction::GetDerivedMap(isolate, constructor, constructor), T); - return T::New(isolate, map, locales, options); + return T::New(isolate, map, locales, options, method); } } // namespace @@ -783,6 +786,11 @@ Maybe<std::string> Intl::CanonicalizeLanguageTag(Isolate* isolate, } std::string locale(locale_str->ToCString().get()); + if (!IsStructurallyValidLanguageTag(locale)) { + THROW_NEW_ERROR_RETURN_VALUE( + isolate, NewRangeError(MessageTemplate::kLocaleBadParameters), + Nothing<std::string>()); + } return Intl::CanonicalizeLanguageTag(isolate, locale); } @@ -995,11 +1003,9 @@ MaybeHandle<String> Intl::StringLocaleConvertCase(Isolate* isolate, } } -MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate, - Handle<String> string1, - Handle<String> string2, - Handle<Object> locales, - Handle<Object> options) { +MaybeHandle<Object> Intl::StringLocaleCompare( + Isolate* isolate, Handle<String> string1, Handle<String> string2, + Handle<Object> locales, Handle<Object> options, const char* method) { // We only cache the instance when both locales and options are undefined, // as that is the only case when the specified side-effects of examining // those arguments are unobservable. @@ -1025,7 +1031,7 @@ MaybeHandle<Object> Intl::StringLocaleCompare(Isolate* isolate, Handle<JSCollator> collator; ASSIGN_RETURN_ON_EXCEPTION( isolate, collator, - New<JSCollator>(isolate, constructor, locales, options), Object); + New<JSCollator>(isolate, constructor, locales, options, method), Object); if (can_cache) { isolate->set_icu_object_in_cache( Isolate::ICUObjectCacheType::kDefaultCollator, @@ -1084,15 +1090,11 @@ Handle<Object> Intl::CompareStrings(Isolate* isolate, MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, Handle<Object> num, Handle<Object> locales, - Handle<Object> options) { + Handle<Object> options, + const char* method) { Handle<Object> numeric_obj; - if (FLAG_harmony_intl_bigint) { - ASSIGN_RETURN_ON_EXCEPTION(isolate, numeric_obj, - Object::ToNumeric(isolate, num), String); - } else { - ASSIGN_RETURN_ON_EXCEPTION(isolate, numeric_obj, - Object::ToNumber(isolate, num), String); - } + ASSIGN_RETURN_ON_EXCEPTION(isolate, numeric_obj, + Object::ToNumeric(isolate, num), String); // We only cache the instance when both locales and options are undefined, // as that is the only case when the specified side-effects of examining @@ -1119,7 +1121,8 @@ MaybeHandle<String> Intl::NumberToLocaleString(Isolate* isolate, // 2. Let numberFormat be ? Construct(%NumberFormat%, « locales, options »). ASSIGN_RETURN_ON_EXCEPTION( isolate, number_format, - New<JSNumberFormat>(isolate, constructor, locales, options), String); + New<JSNumberFormat>(isolate, constructor, locales, options, method), + String); if (can_cache) { isolate->set_icu_object_in_cache( @@ -1203,40 +1206,18 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions( int mxfd = 0; Handle<Object> mnfd_obj; Handle<Object> mxfd_obj; - if (FLAG_harmony_intl_numberformat_unified) { - // 6. Let mnfd be ? Get(options, "minimumFractionDigits"). - Handle<String> mnfd_str = factory->minimumFractionDigits_string(); - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, mnfd_obj, JSReceiver::GetProperty(isolate, options, mnfd_str), - Nothing<NumberFormatDigitOptions>()); - - // 8. Let mnfd be ? Get(options, "maximumFractionDigits"). - Handle<String> mxfd_str = factory->maximumFractionDigits_string(); - ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, mxfd_obj, JSReceiver::GetProperty(isolate, options, mxfd_str), - Nothing<NumberFormatDigitOptions>()); - } else { - // 6. Let mnfd be ? GetNumberOption(options, "minimumFractionDigits", 0, 20, - // mnfdDefault). - if (!Intl::GetNumberOption(isolate, options, - factory->minimumFractionDigits_string(), 0, 20, - mnfd_default) - .To(&mnfd)) { - return Nothing<NumberFormatDigitOptions>(); - } - // 7. Let mxfdActualDefault be max( mnfd, mxfdDefault ). - int mxfd_actual_default = std::max(mnfd, mxfd_default); + // 6. Let mnfd be ? Get(options, "minimumFractionDigits"). + Handle<String> mnfd_str = factory->minimumFractionDigits_string(); + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, mnfd_obj, JSReceiver::GetProperty(isolate, options, mnfd_str), + Nothing<NumberFormatDigitOptions>()); - // 8. Let mxfd be ? GetNumberOption(options, - // "maximumFractionDigits", mnfd, 20, mxfdActualDefault). - if (!Intl::GetNumberOption(isolate, options, - factory->maximumFractionDigits_string(), mnfd, - 20, mxfd_actual_default) - .To(&mxfd)) { - return Nothing<NumberFormatDigitOptions>(); - } - } + // 8. Let mxfd be ? Get(options, "maximumFractionDigits"). + Handle<String> mxfd_str = factory->maximumFractionDigits_string(); + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, mxfd_obj, JSReceiver::GetProperty(isolate, options, mxfd_str), + Nothing<NumberFormatDigitOptions>()); // 9. Let mnsd be ? Get(options, "minimumSignificantDigits"). Handle<Object> mnsd_obj; @@ -1285,47 +1266,44 @@ Maybe<Intl::NumberFormatDigitOptions> Intl::SetNumberFormatDigitOptions( digit_options.minimum_significant_digits = 0; digit_options.maximum_significant_digits = 0; - if (FLAG_harmony_intl_numberformat_unified) { - // 15. Else If mnfd is not undefined or mxfd is not undefined, then - if (!mnfd_obj->IsUndefined(isolate) || !mxfd_obj->IsUndefined(isolate)) { - // 15. b. Let mnfd be ? DefaultNumberOption(mnfd, 0, 20, mnfdDefault). - Handle<String> mnfd_str = factory->minimumFractionDigits_string(); - if (!DefaultNumberOption(isolate, mnfd_obj, 0, 20, mnfd_default, - mnfd_str) - .To(&mnfd)) { - return Nothing<NumberFormatDigitOptions>(); - } - - // 15. c. Let mxfdActualDefault be max( mnfd, mxfdDefault ). - int mxfd_actual_default = std::max(mnfd, mxfd_default); + // 15. Else If mnfd is not undefined or mxfd is not undefined, then + if (!mnfd_obj->IsUndefined(isolate) || !mxfd_obj->IsUndefined(isolate)) { + // 15. b. Let mnfd be ? DefaultNumberOption(mnfd, 0, 20, mnfdDefault). + Handle<String> mnfd_str = factory->minimumFractionDigits_string(); + if (!DefaultNumberOption(isolate, mnfd_obj, 0, 20, mnfd_default, mnfd_str) + .To(&mnfd)) { + return Nothing<NumberFormatDigitOptions>(); + } - // 15. d. Let mxfd be ? DefaultNumberOption(mxfd, mnfd, 20, - // mxfdActualDefault). - Handle<String> mxfd_str = factory->maximumFractionDigits_string(); - if (!DefaultNumberOption(isolate, mxfd_obj, mnfd, 20, - mxfd_actual_default, mxfd_str) - .To(&mxfd)) { - return Nothing<NumberFormatDigitOptions>(); - } - // 15. e. Set intlObj.[[MinimumFractionDigits]] to mnfd. - digit_options.minimum_fraction_digits = mnfd; - - // 15. f. Set intlObj.[[MaximumFractionDigits]] to mxfd. - digit_options.maximum_fraction_digits = mxfd; - // Else If intlObj.[[Notation]] is "compact", then - } else if (notation_is_compact) { - // a. Set intlObj.[[RoundingType]] to "compact-rounding". - // Set minimum_significant_digits to -1 to represent roundingtype is - // "compact-rounding". - digit_options.minimum_significant_digits = -1; - // 17. Else, - } else { - // 17. b. Set intlObj.[[MinimumFractionDigits]] to mnfdDefault. - digit_options.minimum_fraction_digits = mnfd_default; + // 15. c. Let mxfdActualDefault be max( mnfd, mxfdDefault ). + int mxfd_actual_default = std::max(mnfd, mxfd_default); - // 17. c. Set intlObj.[[MaximumFractionDigits]] to mxfdDefault. - digit_options.maximum_fraction_digits = mxfd_default; + // 15. d. Let mxfd be ? DefaultNumberOption(mxfd, mnfd, 20, + // mxfdActualDefault). + Handle<String> mxfd_str = factory->maximumFractionDigits_string(); + if (!DefaultNumberOption(isolate, mxfd_obj, mnfd, 20, mxfd_actual_default, + mxfd_str) + .To(&mxfd)) { + return Nothing<NumberFormatDigitOptions>(); } + // 15. e. Set intlObj.[[MinimumFractionDigits]] to mnfd. + digit_options.minimum_fraction_digits = mnfd; + + // 15. f. Set intlObj.[[MaximumFractionDigits]] to mxfd. + digit_options.maximum_fraction_digits = mxfd; + // Else If intlObj.[[Notation]] is "compact", then + } else if (notation_is_compact) { + // a. Set intlObj.[[RoundingType]] to "compact-rounding". + // Set minimum_significant_digits to -1 to represent roundingtype is + // "compact-rounding". + digit_options.minimum_significant_digits = -1; + // 17. Else, + } else { + // 17. b. Set intlObj.[[MinimumFractionDigits]] to mnfdDefault. + digit_options.minimum_fraction_digits = mnfd_default; + + // 17. c. Set intlObj.[[MaximumFractionDigits]] to mxfdDefault. + digit_options.maximum_fraction_digits = mxfd_default; } } return Just(digit_options); @@ -1605,14 +1583,16 @@ bool IsValidCollation(const icu::Locale& locale, const std::string& value) { } // namespace +bool Intl::IsWellFormedCalendar(const std::string& value) { + return JSLocale::Is38AlphaNumList(value); +} + bool Intl::IsValidCalendar(const icu::Locale& locale, const std::string& value) { return IsValidExtension<icu::Calendar>(locale, "calendar", value); } -namespace { - -bool IsValidNumberingSystem(const std::string& value) { +bool Intl::IsValidNumberingSystem(const std::string& value) { std::set<std::string> invalid_values = {"native", "traditio", "finance"}; if (invalid_values.find(value) != invalid_values.end()) return false; UErrorCode status = U_ZERO_ERROR; @@ -1621,11 +1601,19 @@ bool IsValidNumberingSystem(const std::string& value) { return U_SUCCESS(status) && numbering_system.get() != nullptr; } +namespace { + +bool IsWellFormedNumberingSystem(const std::string& value) { + return JSLocale::Is38AlphaNumList(value); +} + std::map<std::string, std::string> LookupAndValidateUnicodeExtensions( icu::Locale* icu_locale, const std::set<std::string>& relevant_keys) { std::map<std::string, std::string> extensions; UErrorCode status = U_ZERO_ERROR; + icu::LocaleBuilder builder; + builder.setLocale(*icu_locale).clearExtensions(); std::unique_ptr<icu::StringEnumeration> keywords( icu_locale->createKeywords(status)); if (U_FAILURE(status)) return extensions; @@ -1682,20 +1670,19 @@ std::map<std::string, std::string> LookupAndValidateUnicodeExtensions( std::set<std::string> valid_values = {"upper", "lower", "false"}; is_valid_value = valid_values.find(bcp47_value) != valid_values.end(); } else if (strcmp("nu", bcp47_key) == 0) { - is_valid_value = IsValidNumberingSystem(bcp47_value); + is_valid_value = Intl::IsValidNumberingSystem(bcp47_value); } if (is_valid_value) { extensions.insert( std::pair<std::string, std::string>(bcp47_key, bcp47_value)); - continue; + builder.setUnicodeLocaleKeyword(bcp47_key, bcp47_value); } } - status = U_ZERO_ERROR; - icu_locale->setUnicodeKeywordValue( - bcp47_key == nullptr ? keyword : bcp47_key, nullptr, status); - CHECK(U_SUCCESS(status)); } + status = U_ZERO_ERROR; + *icu_locale = builder.build(status); + return extensions; } @@ -2003,7 +1990,7 @@ Maybe<bool> Intl::GetNumberingSystem(Isolate* isolate, empty_values, method, result); MAYBE_RETURN(maybe, Nothing<bool>()); if (maybe.FromJust() && *result != nullptr) { - if (!IsValidNumberingSystem(result->get())) { + if (!IsWellFormedNumberingSystem(result->get())) { THROW_NEW_ERROR_RETURN_VALUE( isolate, NewRangeError( @@ -2120,5 +2107,9 @@ MaybeHandle<String> Intl::FormattedToString( return Intl::ToString(isolate, result); } +bool Intl::IsStructurallyValidLanguageTag(const std::string& tag) { + return JSLocale::StartsWithUnicodeLanguageId(tag); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/objects/intl-objects.h b/deps/v8/src/objects/intl-objects.h index 4d4d3245fd31cb..0c4a77b745f92f 100644 --- a/deps/v8/src/objects/intl-objects.h +++ b/deps/v8/src/objects/intl-objects.h @@ -10,6 +10,7 @@ #define V8_OBJECTS_INTL_OBJECTS_H_ #include <map> +#include <memory> #include <set> #include <string> @@ -164,7 +165,7 @@ class Intl { V8_WARN_UNUSED_RESULT static MaybeHandle<Object> StringLocaleCompare( Isolate* isolate, Handle<String> s1, Handle<String> s2, - Handle<Object> locales, Handle<Object> options); + Handle<Object> locales, Handle<Object> options, const char* method); V8_WARN_UNUSED_RESULT static Handle<Object> CompareStrings( Isolate* isolate, const icu::Collator& collator, Handle<String> s1, @@ -173,7 +174,7 @@ class Intl { // ecma402/#sup-properties-of-the-number-prototype-object V8_WARN_UNUSED_RESULT static MaybeHandle<String> NumberToLocaleString( Isolate* isolate, Handle<Object> num, Handle<Object> locales, - Handle<Object> options); + Handle<Object> options, const char* method); // ecma402/#sec-setnfdigitoptions struct NumberFormatDigitOptions { @@ -239,14 +240,14 @@ class Intl { Handle<JSFunction> constructor, bool has_initialized_slot); // enum for "caseFirst" option: shared by Intl.Locale and Intl.Collator. - enum class CaseFirst { kUpper, kLower, kFalse, kUndefined }; + enum class CaseFirst { kUndefined, kUpper, kLower, kFalse }; // Shared function to read the "caseFirst" option. V8_WARN_UNUSED_RESULT static Maybe<CaseFirst> GetCaseFirst( Isolate* isolate, Handle<JSReceiver> options, const char* method); // enum for "hourCycle" option: shared by Intl.Locale and Intl.DateTimeFormat. - enum class HourCycle { kH11, kH12, kH23, kH24, kUndefined }; + enum class HourCycle { kUndefined, kH11, kH12, kH23, kH24 }; static HourCycle ToHourCycle(const std::string& str); @@ -270,6 +271,12 @@ class Intl { static bool IsValidCalendar(const icu::Locale& locale, const std::string& value); + // Check the numberingSystem is valid. + static bool IsValidNumberingSystem(const std::string& value); + + // Check the calendar is well formed. + static bool IsWellFormedCalendar(const std::string& value); + struct ResolvedLocale { std::string locale; icu::Locale icu_locale; @@ -336,6 +343,8 @@ class Intl { static const std::set<std::string>& GetAvailableLocalesForLocale(); static const std::set<std::string>& GetAvailableLocalesForDateFormat(); + + static bool IsStructurallyValidLanguageTag(const std::string& tag); }; } // namespace internal diff --git a/deps/v8/src/objects/js-array-buffer-inl.h b/deps/v8/src/objects/js-array-buffer-inl.h index 9151be6da49c11..4ed347baa80967 100644 --- a/deps/v8/src/objects/js-array-buffer-inl.h +++ b/deps/v8/src/objects/js-array-buffer-inl.h @@ -48,14 +48,6 @@ size_t JSArrayBuffer::allocation_length() const { if (backing_store() == nullptr) { return 0; } - // If this buffer is managed by the WasmMemoryTracker - if (is_wasm_memory()) { - const auto* data = - GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData( - backing_store()); - DCHECK_NOT_NULL(data); - return data->allocation_length; - } return byte_length(); } @@ -63,25 +55,9 @@ void* JSArrayBuffer::allocation_base() const { if (backing_store() == nullptr) { return nullptr; } - // If this buffer is managed by the WasmMemoryTracker - if (is_wasm_memory()) { - const auto* data = - GetIsolate()->wasm_engine()->memory_tracker()->FindAllocationData( - backing_store()); - DCHECK_NOT_NULL(data); - return data->allocation_base; - } return backing_store(); } -bool JSArrayBuffer::is_wasm_memory() const { - return IsWasmMemoryBit::decode(bit_field()); -} - -void JSArrayBuffer::set_is_wasm_memory(bool is_wasm_memory) { - set_bit_field(IsWasmMemoryBit::update(bit_field(), is_wasm_memory)); -} - void JSArrayBuffer::clear_padding() { if (FIELD_SIZE(kOptionalPaddingOffset) != 0) { DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); @@ -105,6 +81,8 @@ BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_detachable, JSArrayBuffer::IsDetachableBit) BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, was_detached, JSArrayBuffer::WasDetachedBit) +BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_asmjs_memory, + JSArrayBuffer::IsAsmJsMemoryBit) BIT_FIELD_ACCESSORS(JSArrayBuffer, bit_field, is_shared, JSArrayBuffer::IsSharedBit) @@ -136,31 +114,61 @@ void JSTypedArray::set_length(size_t value) { WriteField<size_t>(kLengthOffset, value); } -void* JSTypedArray::external_pointer() const { - return reinterpret_cast<void*>(ReadField<Address>(kExternalPointerOffset)); +Address JSTypedArray::external_pointer() const { + return ReadField<Address>(kExternalPointerOffset); +} + +void JSTypedArray::set_external_pointer(Address value) { + WriteField<Address>(kExternalPointerOffset, value); } -void JSTypedArray::set_external_pointer(void* value) { - WriteField<Address>(kExternalPointerOffset, reinterpret_cast<Address>(value)); +Address JSTypedArray::ExternalPointerCompensationForOnHeapArray( + Isolate* isolate) { +#ifdef V8_COMPRESS_POINTERS + return GetIsolateRoot(isolate); +#else + return 0; +#endif +} + +void JSTypedArray::RemoveExternalPointerCompensationForSerialization() { + DCHECK(is_on_heap()); + Isolate* isolate = GetIsolateForPtrCompr(*this); + set_external_pointer(external_pointer() - + ExternalPointerCompensationForOnHeapArray(isolate)); } ACCESSORS(JSTypedArray, base_pointer, Object, kBasePointerOffset) void* JSTypedArray::DataPtr() { - return reinterpret_cast<void*>( - base_pointer().ptr() + reinterpret_cast<intptr_t>(external_pointer())); + // Zero-extend Tagged_t to Address according to current compression scheme + // so that the addition with |external_pointer| (which already contains + // compensated offset value) will decompress the tagged value. + // See JSTypedArray::ExternalPointerCompensationForOnHeapArray() for details. + return reinterpret_cast<void*>(external_pointer() + + static_cast<Tagged_t>(base_pointer().ptr())); +} + +void JSTypedArray::SetOffHeapDataPtr(void* base, Address offset) { + set_base_pointer(Smi::kZero, SKIP_WRITE_BARRIER); + Address address = reinterpret_cast<Address>(base) + offset; + set_external_pointer(address); + DCHECK_EQ(address, reinterpret_cast<Address>(DataPtr())); +} + +void JSTypedArray::SetOnHeapDataPtr(HeapObject base, Address offset) { + set_base_pointer(base); + Isolate* isolate = GetIsolateForPtrCompr(*this); + set_external_pointer(offset + + ExternalPointerCompensationForOnHeapArray(isolate)); + DCHECK_EQ(base.ptr() + offset, reinterpret_cast<Address>(DataPtr())); } bool JSTypedArray::is_on_heap() const { DisallowHeapAllocation no_gc; // Checking that buffer()->backing_store() is not nullptr is not sufficient; // it will be nullptr when byte_length is 0 as well. - return base_pointer().ptr() == elements().ptr(); -} - -// static -void* JSTypedArray::ExternalPointerForOnHeapArray() { - return reinterpret_cast<void*>(ByteArray::kHeaderSize - kHeapObjectTag); + return base_pointer() == elements(); } // static diff --git a/deps/v8/src/objects/js-array-buffer.cc b/deps/v8/src/objects/js-array-buffer.cc index a506920f9524d1..d3f5a0a9520b2d 100644 --- a/deps/v8/src/objects/js-array-buffer.cc +++ b/deps/v8/src/objects/js-array-buffer.cc @@ -5,6 +5,7 @@ #include "src/objects/js-array-buffer.h" #include "src/objects/js-array-buffer-inl.h" +#include "src/execution/protectors-inl.h" #include "src/logging/counters.h" #include "src/objects/property-descriptor.h" @@ -31,167 +32,105 @@ bool CanonicalNumericIndexString(Isolate* isolate, Handle<Object> s, *index = result; return true; } - -inline int ConvertToMb(size_t size) { - return static_cast<int>(size / static_cast<size_t>(MB)); -} - } // anonymous namespace -void JSArrayBuffer::Detach() { - CHECK(is_detachable()); - CHECK(!was_detached()); - CHECK(is_external()); - set_backing_store(nullptr); - set_byte_length(0); - set_was_detached(true); - set_is_detachable(false); - // Invalidate the detaching protector. - Isolate* const isolate = GetIsolate(); - if (isolate->IsArrayBufferDetachingIntact()) { - isolate->InvalidateArrayBufferDetachingProtector(); +void JSArrayBuffer::Setup(SharedFlag shared, + std::shared_ptr<BackingStore> backing_store) { + clear_padding(); + set_bit_field(0); + set_is_shared(shared == SharedFlag::kShared); + set_is_detachable(shared != SharedFlag::kShared); + for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) { + SetEmbedderField(i, Smi::kZero); + } + if (!backing_store) { + set_backing_store(nullptr); + set_byte_length(0); + } else { + Attach(std::move(backing_store)); } } -void JSArrayBuffer::FreeBackingStoreFromMainThread() { - if (allocation_base() == nullptr) { - return; - } - FreeBackingStore(GetIsolate(), {allocation_base(), allocation_length(), - backing_store(), is_wasm_memory()}); - // Zero out the backing store and allocation base to avoid dangling - // pointers. - set_backing_store(nullptr); +void JSArrayBuffer::Attach(std::shared_ptr<BackingStore> backing_store) { + DCHECK_NOT_NULL(backing_store); + DCHECK_EQ(is_shared(), backing_store->is_shared()); + set_backing_store(backing_store->buffer_start()); + set_byte_length(backing_store->byte_length()); + if (backing_store->is_wasm_memory()) set_is_detachable(false); + if (!backing_store->free_on_destruct()) set_is_external(true); + GetIsolate()->heap()->RegisterBackingStore(*this, std::move(backing_store)); } -// static -void JSArrayBuffer::FreeBackingStore(Isolate* isolate, Allocation allocation) { - if (allocation.is_wasm_memory) { - wasm::WasmMemoryTracker* memory_tracker = - isolate->wasm_engine()->memory_tracker(); - memory_tracker->FreeWasmMemory(isolate, allocation.backing_store); - } else { - isolate->array_buffer_allocator()->Free(allocation.allocation_base, - allocation.length); +void JSArrayBuffer::Detach(bool force_for_wasm_memory) { + if (was_detached()) return; + + if (force_for_wasm_memory) { + // Skip the is_detachable() check. + } else if (!is_detachable()) { + // Not detachable, do nothing. + return; } -} -void JSArrayBuffer::Setup(Handle<JSArrayBuffer> array_buffer, Isolate* isolate, - bool is_external, void* data, size_t byte_length, - SharedFlag shared_flag, bool is_wasm_memory) { - DCHECK_EQ(array_buffer->GetEmbedderFieldCount(), - v8::ArrayBuffer::kEmbedderFieldCount); - DCHECK_LE(byte_length, JSArrayBuffer::kMaxByteLength); - for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) { - array_buffer->SetEmbedderField(i, Smi::kZero); + Isolate* const isolate = GetIsolate(); + if (backing_store()) { + auto backing_store = isolate->heap()->UnregisterBackingStore(*this); + CHECK_IMPLIES(force_for_wasm_memory, backing_store->is_wasm_memory()); } - array_buffer->set_byte_length(byte_length); - array_buffer->set_bit_field(0); - array_buffer->clear_padding(); - array_buffer->set_is_external(is_external); - array_buffer->set_is_detachable(shared_flag == SharedFlag::kNotShared); - array_buffer->set_is_shared(shared_flag == SharedFlag::kShared); - array_buffer->set_is_wasm_memory(is_wasm_memory); - // Initialize backing store at last to avoid handling of |JSArrayBuffers| that - // are currently being constructed in the |ArrayBufferTracker|. The - // registration method below handles the case of registering a buffer that has - // already been promoted. - array_buffer->set_backing_store(data); - if (data && !is_external) { - isolate->heap()->RegisterNewArrayBuffer(*array_buffer); + if (Protectors::IsArrayBufferDetachingIntact(isolate)) { + Protectors::InvalidateArrayBufferDetaching(isolate); } -} -void JSArrayBuffer::SetupAsEmpty(Handle<JSArrayBuffer> array_buffer, - Isolate* isolate) { - Setup(array_buffer, isolate, false, nullptr, 0, SharedFlag::kNotShared); + DCHECK(!is_shared()); + DCHECK(!is_asmjs_memory()); + set_backing_store(nullptr); + set_byte_length(0); + set_was_detached(true); } -bool JSArrayBuffer::SetupAllocatingData(Handle<JSArrayBuffer> array_buffer, - Isolate* isolate, - size_t allocated_length, - bool initialize, - SharedFlag shared_flag) { - void* data; - CHECK_NOT_NULL(isolate->array_buffer_allocator()); - if (allocated_length != 0) { - if (allocated_length >= MB) - isolate->counters()->array_buffer_big_allocations()->AddSample( - ConvertToMb(allocated_length)); - if (shared_flag == SharedFlag::kShared) - isolate->counters()->shared_array_allocations()->AddSample( - ConvertToMb(allocated_length)); - if (initialize) { - data = isolate->array_buffer_allocator()->Allocate(allocated_length); - } else { - data = isolate->array_buffer_allocator()->AllocateUninitialized( - allocated_length); - } - if (data == nullptr) { - isolate->counters()->array_buffer_new_size_failures()->AddSample( - ConvertToMb(allocated_length)); - SetupAsEmpty(array_buffer, isolate); - return false; - } - } else { - data = nullptr; - } - - const bool is_external = false; - JSArrayBuffer::Setup(array_buffer, isolate, is_external, data, - allocated_length, shared_flag); - return true; +std::shared_ptr<BackingStore> JSArrayBuffer::GetBackingStore() { + return GetIsolate()->heap()->LookupBackingStore(*this); } -Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( - Handle<JSTypedArray> typed_array) { - DCHECK(typed_array->is_on_heap()); +Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { + Isolate* isolate = GetIsolate(); + Handle<JSTypedArray> self(*this, isolate); + DCHECK(IsTypedArrayElementsKind(self->GetElementsKind())); + + Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(self->buffer()), + isolate); + if (!is_on_heap()) { + // Already is off heap, so return the existing buffer. + return array_buffer; + } - Isolate* isolate = typed_array->GetIsolate(); + // The existing array buffer should be empty. + DCHECK_NULL(array_buffer->backing_store()); - DCHECK(IsTypedArrayElementsKind(typed_array->GetElementsKind())); + // Allocate a new backing store and attach it to the existing array buffer. + size_t byte_length = self->byte_length(); + auto backing_store = + BackingStore::Allocate(isolate, byte_length, SharedFlag::kNotShared, + InitializedFlag::kUninitialized); - Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(typed_array->buffer()), - isolate); - // This code does not know how to materialize from wasm buffers. - DCHECK(!buffer->is_wasm_memory()); + if (!backing_store) { + isolate->heap()->FatalProcessOutOfMemory("JSTypedArray::GetBuffer"); + } - void* backing_store = - isolate->array_buffer_allocator()->AllocateUninitialized( - typed_array->byte_length()); - if (backing_store == nullptr) { - isolate->heap()->FatalProcessOutOfMemory( - "JSTypedArray::MaterializeArrayBuffer"); + // Copy the elements into the backing store of the array buffer. + if (byte_length > 0) { + memcpy(backing_store->buffer_start(), self->DataPtr(), byte_length); } - buffer->set_is_external(false); - DCHECK_EQ(buffer->byte_length(), typed_array->byte_length()); - // Initialize backing store at last to avoid handling of |JSArrayBuffers| that - // are currently being constructed in the |ArrayBufferTracker|. The - // registration method below handles the case of registering a buffer that has - // already been promoted. - buffer->set_backing_store(backing_store); - // RegisterNewArrayBuffer expects a valid length for adjusting counters. - isolate->heap()->RegisterNewArrayBuffer(*buffer); - memcpy(buffer->backing_store(), typed_array->DataPtr(), - typed_array->byte_length()); - typed_array->set_elements(ReadOnlyRoots(isolate).empty_byte_array()); - typed_array->set_external_pointer(backing_store); - typed_array->set_base_pointer(Smi::kZero); - DCHECK(!typed_array->is_on_heap()); + // Attach the backing store to the array buffer. + array_buffer->Setup(SharedFlag::kNotShared, std::move(backing_store)); - return buffer; -} + // Clear the elements of the typed array. + self->set_elements(ReadOnlyRoots(isolate).empty_byte_array()); + self->SetOffHeapDataPtr(array_buffer->backing_store(), 0); + DCHECK(!self->is_on_heap()); -Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { - if (!is_on_heap()) { - Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(buffer()), - GetIsolate()); - return array_buffer; - } - Handle<JSTypedArray> self(*this, GetIsolate()); - return MaterializeArrayBuffer(self); + return array_buffer; } // ES#sec-integer-indexed-exotic-objects-defineownproperty-p-desc diff --git a/deps/v8/src/objects/js-array-buffer.h b/deps/v8/src/objects/js-array-buffer.h index 7bf2e1ae94b805..71adb42ae84196 100644 --- a/deps/v8/src/objects/js-array-buffer.h +++ b/deps/v8/src/objects/js-array-buffer.h @@ -5,6 +5,7 @@ #ifndef V8_OBJECTS_JS_ARRAY_BUFFER_H_ #define V8_OBJECTS_JS_ARRAY_BUFFER_H_ +#include "src/objects/backing-store.h" #include "src/objects/js-objects.h" // Has to be the last include (doesn't have include guards): @@ -13,9 +14,6 @@ namespace v8 { namespace internal { -// Whether a JSArrayBuffer is a SharedArrayBuffer or not. -enum class SharedFlag : uint32_t { kNotShared, kShared }; - class JSArrayBuffer : public JSObject { public: // The maximum length for JSArrayBuffer's supported by V8. @@ -51,8 +49,8 @@ class JSArrayBuffer : public JSObject { V(IsExternalBit, bool, 1, _) \ V(IsDetachableBit, bool, 1, _) \ V(WasDetachedBit, bool, 1, _) \ - V(IsSharedBit, bool, 1, _) \ - V(IsWasmMemoryBit, bool, 1, _) + V(IsAsmJsMemoryBit, bool, 1, _) \ + V(IsSharedBit, bool, 1, _) DEFINE_BIT_FIELDS(JS_ARRAY_BUFFER_BIT_FIELD_FIELDS) #undef JS_ARRAY_BUFFER_BIT_FIELD_FIELDS @@ -61,57 +59,45 @@ class JSArrayBuffer : public JSObject { // memory block once all ArrayBuffers referencing it are collected by the GC. DECL_BOOLEAN_ACCESSORS(is_external) - // [is_detachable]: false indicates that this buffer cannot be detached. + // [is_detachable]: false => this buffer cannot be detached. DECL_BOOLEAN_ACCESSORS(is_detachable) - // [was_detached]: true if the buffer was previously detached. + // [was_detached]: true => the buffer was previously detached. DECL_BOOLEAN_ACCESSORS(was_detached) + // [is_asmjs_memory]: true => this buffer was once used as asm.js memory. + DECL_BOOLEAN_ACCESSORS(is_asmjs_memory) + // [is_shared]: tells whether this is an ArrayBuffer or a SharedArrayBuffer. DECL_BOOLEAN_ACCESSORS(is_shared) - // [is_wasm_memory]: whether the buffer is tracked by the WasmMemoryTracker. - DECL_BOOLEAN_ACCESSORS(is_wasm_memory) - DECL_CAST(JSArrayBuffer) - void Detach(); - - struct Allocation { - Allocation(void* allocation_base, size_t length, void* backing_store, - bool is_wasm_memory) - : allocation_base(allocation_base), - length(length), - backing_store(backing_store), - is_wasm_memory(is_wasm_memory) {} - - void* allocation_base; - size_t length; - void* backing_store; - bool is_wasm_memory; - }; - - V8_EXPORT_PRIVATE void FreeBackingStoreFromMainThread(); - V8_EXPORT_PRIVATE static void FreeBackingStore(Isolate* isolate, - Allocation allocation); - - V8_EXPORT_PRIVATE static void Setup( - Handle<JSArrayBuffer> array_buffer, Isolate* isolate, bool is_external, - void* data, size_t allocated_length, - SharedFlag shared_flag = SharedFlag::kNotShared, - bool is_wasm_memory = false); - - // Initialize the object as empty one to avoid confusing heap verifier if - // the failure happened in the middle of JSArrayBuffer construction. - V8_EXPORT_PRIVATE static void SetupAsEmpty(Handle<JSArrayBuffer> array_buffer, - Isolate* isolate); - - // Returns false if array buffer contents could not be allocated. - // In this case, |array_buffer| will not be set up. - V8_EXPORT_PRIVATE static bool SetupAllocatingData( - Handle<JSArrayBuffer> array_buffer, Isolate* isolate, - size_t allocated_length, bool initialize = true, - SharedFlag shared_flag = SharedFlag::kNotShared) V8_WARN_UNUSED_RESULT; + // Initializes the fields of the ArrayBuffer. The provided backing_store can + // be nullptr. If it is not nullptr, then the function registers it with + // src/heap/array-buffer-tracker.h. + V8_EXPORT_PRIVATE void Setup(SharedFlag shared, + std::shared_ptr<BackingStore> backing_store); + + // Attaches the backing store to an already constructed empty ArrayBuffer. + // This is intended to be used only in ArrayBufferConstructor builtin. + V8_EXPORT_PRIVATE void Attach(std::shared_ptr<BackingStore> backing_store); + // Detach the backing store from this array buffer if it is detachable. + // This sets the internal pointer and length to 0 and unregisters the backing + // store from the array buffer tracker. If the array buffer is not detachable, + // this is a nop. + // + // Array buffers that wrap wasm memory objects are special in that they + // are normally not detachable, but can become detached as a side effect + // of growing the underlying memory object. The {force_for_wasm_memory} flag + // is used by the implementation of Wasm memory growth in order to bypass the + // non-detachable check. + V8_EXPORT_PRIVATE void Detach(bool force_for_wasm_memory = false); + + // Get a reference to backing store of this array buffer, if there is a + // backing store. Returns nullptr if there is no backing store (e.g. detached + // or a zero-length array buffer). + std::shared_ptr<BackingStore> GetBackingStore(); // Dispatched behavior. DECL_PRINTER(JSArrayBuffer) @@ -187,12 +173,6 @@ class JSTypedArray : public JSArrayBufferView { // [length]: length of typed array in elements. DECL_PRIMITIVE_ACCESSORS(length, size_t) - // [external_pointer]: TODO(v8:4153) - DECL_PRIMITIVE_ACCESSORS(external_pointer, void*) - - // [base_pointer]: TODO(v8:4153) - DECL_ACCESSORS(base_pointer, Object) - // ES6 9.4.5.3 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( Isolate* isolate, Handle<JSTypedArray> o, Handle<Object> key, @@ -208,10 +188,26 @@ class JSTypedArray : public JSArrayBufferView { // Use with care: returns raw pointer into heap. inline void* DataPtr(); + inline void SetOffHeapDataPtr(void* base, Address offset); + inline void SetOnHeapDataPtr(HeapObject base, Address offset); + // Whether the buffer's backing store is on-heap or off-heap. inline bool is_on_heap() const; - static inline void* ExternalPointerForOnHeapArray(); + // Note: this is a pointer compression specific optimization. + // Normally, on-heap typed arrays contain HeapObject value in |base_pointer| + // field and an offset in |external_pointer|. + // When pointer compression is enabled we want to combine decompression with + // the offset addition. In order to do that we add an isolate root to the + // |external_pointer| value and therefore the data pointer computation can + // is a simple addition of a (potentially sign-extended) |base_pointer| loaded + // as Tagged_t value and an |external_pointer| value. + // For full-pointer mode the compensation value is zero. + static inline Address ExternalPointerCompensationForOnHeapArray( + Isolate* isolate); + + // Subtracts external pointer compensation from the external pointer value. + inline void RemoveExternalPointerCompensationForSerialization(); static inline MaybeHandle<JSTypedArray> Validate(Isolate* isolate, Handle<Object> receiver, @@ -250,8 +246,13 @@ class JSTypedArray : public JSArrayBufferView { #endif private: - static Handle<JSArrayBuffer> MaterializeArrayBuffer( - Handle<JSTypedArray> typed_array); + friend class Deserializer; + + // [base_pointer]: TODO(v8:4153) + DECL_ACCESSORS(base_pointer, Object) + + // [external_pointer]: TODO(v8:4153) + DECL_PRIMITIVE_ACCESSORS(external_pointer, Address) OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView); }; diff --git a/deps/v8/src/objects/js-array.h b/deps/v8/src/objects/js-array.h index eb581c104e0180..c990151b2758ab 100644 --- a/deps/v8/src/objects/js-array.h +++ b/deps/v8/src/objects/js-array.h @@ -108,7 +108,7 @@ class JSArray : public JSObject { static const int kPreallocatedArrayElements = 4; DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSARRAY_FIELDS) + TORQUE_GENERATED_JS_ARRAY_FIELDS) static const int kLengthDescriptorIndex = 0; @@ -178,7 +178,7 @@ class JSArrayIterator : public JSObject { inline void set_kind(IterationKind kind); DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSARRAY_ITERATOR_FIELDS) + TORQUE_GENERATED_JS_ARRAY_ITERATOR_FIELDS) private: DECL_INT_ACCESSORS(raw_kind) diff --git a/deps/v8/src/objects/js-break-iterator.cc b/deps/v8/src/objects/js-break-iterator.cc index 31ed3f86117696..1a9d096411868a 100644 --- a/deps/v8/src/objects/js-break-iterator.cc +++ b/deps/v8/src/objects/js-break-iterator.cc @@ -17,7 +17,7 @@ namespace internal { MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New( Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options_obj) { + Handle<Object> options_obj, const char* service) { Factory* factory = isolate->factory(); // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). @@ -31,15 +31,14 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New( if (options_obj->IsUndefined(isolate)) { options = factory->NewJSObjectWithNullProto(); } else { - ASSIGN_RETURN_ON_EXCEPTION( - isolate, options, - Object::ToObject(isolate, options_obj, "Intl.JSV8BreakIterator"), - JSV8BreakIterator); + ASSIGN_RETURN_ON_EXCEPTION(isolate, options, + Object::ToObject(isolate, options_obj, service), + JSV8BreakIterator); } // Extract locale string Maybe<Intl::MatcherOption> maybe_locale_matcher = - Intl::GetLocaleMatcher(isolate, options, "Intl.JSV8BreakIterator"); + Intl::GetLocaleMatcher(isolate, options, service); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSV8BreakIterator>()); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); @@ -49,7 +48,7 @@ MaybeHandle<JSV8BreakIterator> JSV8BreakIterator::New( // Extract type from options Maybe<Type> maybe_type = Intl::GetStringOption<Type>( - isolate, options, "type", "Intl.v8BreakIterator", + isolate, options, "type", service, {"word", "character", "sentence", "line"}, {Type::WORD, Type::CHARACTER, Type::SENTENCE, Type::LINE}, Type::WORD); MAYBE_RETURN(maybe_type, MaybeHandle<JSV8BreakIterator>()); diff --git a/deps/v8/src/objects/js-break-iterator.h b/deps/v8/src/objects/js-break-iterator.h index 4b40192c8134b8..ea66fe6732bd88 100644 --- a/deps/v8/src/objects/js-break-iterator.h +++ b/deps/v8/src/objects/js-break-iterator.h @@ -31,7 +31,7 @@ class JSV8BreakIterator : public JSObject { public: V8_WARN_UNUSED_RESULT static MaybeHandle<JSV8BreakIterator> New( Isolate* isolate, Handle<Map> map, Handle<Object> input_locales, - Handle<Object> input_options); + Handle<Object> input_options, const char* service); static Handle<JSObject> ResolvedOptions( Isolate* isolate, Handle<JSV8BreakIterator> break_iterator); @@ -72,7 +72,7 @@ class JSV8BreakIterator : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSV8BREAK_ITERATOR_FIELDS) + TORQUE_GENERATED_JS_V8_BREAK_ITERATOR_FIELDS) private: DECL_INT_ACCESSORS(raw_type) diff --git a/deps/v8/src/objects/js-collator.cc b/deps/v8/src/objects/js-collator.cc index 0413e2acd1ec55..39178b3acf351f 100644 --- a/deps/v8/src/objects/js-collator.cc +++ b/deps/v8/src/objects/js-collator.cc @@ -243,7 +243,8 @@ void SetCaseFirstOption(icu::Collator* icu_collator, // static MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options_obj) { + Handle<Object> options_obj, + const char* service) { // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). Maybe<std::vector<std::string>> maybe_requested_locales = Intl::CanonicalizeLocaleList(isolate, locales); @@ -258,9 +259,9 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, } else { // 3. Else // 3. a. Let options be ? ToObject(options). - ASSIGN_RETURN_ON_EXCEPTION( - isolate, options_obj, - Object::ToObject(isolate, options_obj, "Intl.Collator"), JSCollator); + ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj, + Object::ToObject(isolate, options_obj, service), + JSCollator); } // At this point, options_obj can either be a JSObject or a JSProxy only. @@ -269,7 +270,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, // 4. Let usage be ? GetOption(options, "usage", "string", « "sort", // "search" », "sort"). Maybe<Usage> maybe_usage = Intl::GetStringOption<Usage>( - isolate, options, "usage", "Intl.Collator", {"sort", "search"}, + isolate, options, "usage", service, {"sort", "search"}, {Usage::SORT, Usage::SEARCH}, Usage::SORT); MAYBE_RETURN(maybe_usage, MaybeHandle<JSCollator>()); Usage usage = maybe_usage.FromJust(); @@ -278,7 +279,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, // « "lookup", "best fit" », "best fit"). // 10. Set opt.[[localeMatcher]] to matcher. Maybe<Intl::MatcherOption> maybe_locale_matcher = - Intl::GetLocaleMatcher(isolate, options, "Intl.Collator"); + Intl::GetLocaleMatcher(isolate, options, service); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSCollator>()); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); @@ -293,14 +294,14 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, // // 13. Set opt.[[kn]] to numeric. bool numeric; - Maybe<bool> found_numeric = Intl::GetBoolOption(isolate, options, "numeric", - "Intl.Collator", &numeric); + Maybe<bool> found_numeric = + Intl::GetBoolOption(isolate, options, "numeric", service, &numeric); MAYBE_RETURN(found_numeric, MaybeHandle<JSCollator>()); // 14. Let caseFirst be ? GetOption(options, "caseFirst", "string", // « "upper", "lower", "false" », undefined). Maybe<Intl::CaseFirst> maybe_case_first = - Intl::GetCaseFirst(isolate, options, "Intl.Collator"); + Intl::GetCaseFirst(isolate, options, service); MAYBE_RETURN(maybe_case_first, MaybeHandle<JSCollator>()); Intl::CaseFirst case_first = maybe_case_first.FromJust(); @@ -411,7 +412,7 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, // 24. Let sensitivity be ? GetOption(options, "sensitivity", // "string", « "base", "accent", "case", "variant" », undefined). Maybe<Sensitivity> maybe_sensitivity = Intl::GetStringOption<Sensitivity>( - isolate, options, "sensitivity", "Intl.Collator", + isolate, options, "sensitivity", service, {"base", "accent", "case", "variant"}, {Sensitivity::kBase, Sensitivity::kAccent, Sensitivity::kCase, Sensitivity::kVariant}, @@ -451,9 +452,8 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, Handle<Map> map, // 27.Let ignorePunctuation be ? GetOption(options, // "ignorePunctuation", "boolean", undefined, false). bool ignore_punctuation; - Maybe<bool> found_ignore_punctuation = - Intl::GetBoolOption(isolate, options, "ignorePunctuation", - "Intl.Collator", &ignore_punctuation); + Maybe<bool> found_ignore_punctuation = Intl::GetBoolOption( + isolate, options, "ignorePunctuation", service, &ignore_punctuation); MAYBE_RETURN(found_ignore_punctuation, MaybeHandle<JSCollator>()); // 28. Set collator.[[IgnorePunctuation]] to ignorePunctuation. diff --git a/deps/v8/src/objects/js-collator.h b/deps/v8/src/objects/js-collator.h index e9114afeb1ea81..0147b80ebb06c4 100644 --- a/deps/v8/src/objects/js-collator.h +++ b/deps/v8/src/objects/js-collator.h @@ -34,7 +34,7 @@ class JSCollator : public JSObject { // ecma402/#sec-initializecollator V8_WARN_UNUSED_RESULT static MaybeHandle<JSCollator> New( Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options); + Handle<Object> options, const char* service); // ecma402/#sec-intl.collator.prototype.resolvedoptions static Handle<JSObject> ResolvedOptions(Isolate* isolate, @@ -48,7 +48,7 @@ class JSCollator : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSCOLLATOR_FIELDS) + TORQUE_GENERATED_JS_COLLATOR_FIELDS) DECL_ACCESSORS(icu_collator, Managed<icu::Collator>) DECL_ACCESSORS(bound_compare, Object) diff --git a/deps/v8/src/objects/js-collection-iterator.h b/deps/v8/src/objects/js-collection-iterator.h index b193aa84cdde68..0a4083767760e5 100644 --- a/deps/v8/src/objects/js-collection-iterator.h +++ b/deps/v8/src/objects/js-collection-iterator.h @@ -22,6 +22,10 @@ class JSCollectionIterator public: void JSCollectionIteratorPrint(std::ostream& os, const char* name); + // JSCollectionIterator is abstract, but also defines the size for all of its + // concrete subclasses. + static constexpr int kSize = kHeaderSize; + TQ_OBJECT_CONSTRUCTORS(JSCollectionIterator) }; diff --git a/deps/v8/src/objects/js-date-time-format.cc b/deps/v8/src/objects/js-date-time-format.cc index 29fcfb0d7cbfad..835f3dc43ab905 100644 --- a/deps/v8/src/objects/js-date-time-format.cc +++ b/deps/v8/src/objects/js-date-time-format.cc @@ -79,16 +79,6 @@ static std::vector<PatternItem> BuildPatternItems() { kNarrowLongShort), PatternItem("year", {{"yy", "2-digit"}, {"y", "numeric"}}, k2DigitNumeric)}; - if (FLAG_harmony_intl_dateformat_quarter) { - items.push_back(PatternItem("quarter", - {{"QQQQQ", "narrow"}, - {"QQQQ", "long"}, - {"QQQ", "short"}, - {"qqqqq", "narrow"}, - {"qqqq", "long"}, - {"qqq", "short"}}, - kNarrowLongShort)); - } // Sometimes we get L instead of M for month - standalone name. items.push_back(PatternItem("month", {{"MMMMM", "narrow"}, @@ -641,7 +631,8 @@ Isolate::ICUObjectCacheType ConvertToCacheType( MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime( Isolate* isolate, Handle<Object> date, Handle<Object> locales, - Handle<Object> options, RequiredOption required, DefaultsOption defaults) { + Handle<Object> options, RequiredOption required, DefaultsOption defaults, + const char* method) { Isolate::ICUObjectCacheType cache_type = ConvertToCacheType(defaults); Factory* factory = isolate->factory(); @@ -691,7 +682,8 @@ MaybeHandle<String> JSDateTimeFormat::ToLocaleDateTime( Handle<JSDateTimeFormat> date_time_format; ASSIGN_RETURN_ON_EXCEPTION( isolate, date_time_format, - JSDateTimeFormat::New(isolate, map, locales, internal_options), String); + JSDateTimeFormat::New(isolate, map, locales, internal_options, method), + String); if (can_cache) { isolate->set_icu_object_in_cache( @@ -775,13 +767,10 @@ MaybeHandle<JSObject> JSDateTimeFormat::ToDateTimeOptions( // 4. If required is "date" or "any", then if (required == RequiredOption::kAny || required == RequiredOption::kDate) { - // a. For each of the property names "weekday", "year", "quarter", "month", + // a. For each of the property names "weekday", "year", "month", // "day", do std::vector<Handle<String>> list( {factory->weekday_string(), factory->year_string()}); - if (FLAG_harmony_intl_dateformat_quarter) { - list.push_back(factory->quarter_string()); - } list.push_back(factory->month_string()); list.push_back(factory->day_string()); Maybe<bool> maybe_needs_default = NeedsDefault(isolate, options, list); @@ -941,7 +930,7 @@ icu::Calendar* CreateCalendar(Isolate* isolate, const icu::Locale& icu_locale, std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat( const icu::Locale& icu_locale, const icu::UnicodeString& skeleton, - icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references) + icu::DateTimePatternGenerator* generator) { // See https://github.com/tc39/ecma402/issues/225 . The best pattern // generation needs to be done in the base locale according to the // current spec however odd it may be. See also crbug.com/826549 . @@ -954,8 +943,8 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat( // has to be discussed. Revisit once the spec is clarified/revised. icu::UnicodeString pattern; UErrorCode status = U_ZERO_ERROR; - pattern = generator.getBestPattern(skeleton, UDATPG_MATCH_HOUR_FIELD_LENGTH, - status); + pattern = generator->getBestPattern(skeleton, UDATPG_MATCH_HOUR_FIELD_LENGTH, + status); CHECK(U_SUCCESS(status)); // Make formatter from skeleton. Calendar and numbering system are added @@ -971,9 +960,9 @@ std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormat( class DateFormatCache { public: - icu::SimpleDateFormat* Create( - const icu::Locale& icu_locale, const icu::UnicodeString& skeleton, - icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references) + icu::SimpleDateFormat* Create(const icu::Locale& icu_locale, + const icu::UnicodeString& skeleton, + icu::DateTimePatternGenerator* generator) { std::string key; skeleton.toUTF8String<std::string>(key); key += ":"; @@ -1002,7 +991,7 @@ class DateFormatCache { std::unique_ptr<icu::SimpleDateFormat> CreateICUDateFormatFromCache( const icu::Locale& icu_locale, const icu::UnicodeString& skeleton, - icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references) + icu::DateTimePatternGenerator* generator) { static base::LazyInstance<DateFormatCache>::type cache = LAZY_INSTANCE_INITIALIZER; return std::unique_ptr<icu::SimpleDateFormat>( @@ -1138,8 +1127,7 @@ icu::UnicodeString ReplaceSkeleton(const icu::UnicodeString input, std::unique_ptr<icu::SimpleDateFormat> DateTimeStylePattern( JSDateTimeFormat::DateTimeStyle date_style, JSDateTimeFormat::DateTimeStyle time_style, const icu::Locale& icu_locale, - Intl::HourCycle hc, - icu::DateTimePatternGenerator& generator) { // NOLINT(runtime/references) + Intl::HourCycle hc, icu::DateTimePatternGenerator* generator) { std::unique_ptr<icu::SimpleDateFormat> result; if (date_style != JSDateTimeFormat::DateTimeStyle::kUndefined) { if (time_style != JSDateTimeFormat::DateTimeStyle::kUndefined) { @@ -1164,10 +1152,40 @@ std::unique_ptr<icu::SimpleDateFormat> DateTimeStylePattern( UNREACHABLE(); } } + + UErrorCode status = U_ZERO_ERROR; + // Somehow we fail to create the instance. + if (result.get() == nullptr) { + icu::Locale modified_locale(icu_locale); + // Fallback to the locale without "nu". + if (!icu_locale.getUnicodeKeywordValue<std::string>("nu", status).empty()) { + status = U_ZERO_ERROR; + modified_locale.setUnicodeKeywordValue("nu", nullptr, status); + return DateTimeStylePattern(date_style, time_style, modified_locale, hc, + generator); + } + status = U_ZERO_ERROR; + // Fallback to the locale without "hc". + if (!icu_locale.getUnicodeKeywordValue<std::string>("hc", status).empty()) { + status = U_ZERO_ERROR; + modified_locale.setUnicodeKeywordValue("hc", nullptr, status); + return DateTimeStylePattern(date_style, time_style, modified_locale, hc, + generator); + } + status = U_ZERO_ERROR; + // Fallback to the locale without "ca". + if (!icu_locale.getUnicodeKeywordValue<std::string>("ca", status).empty()) { + status = U_ZERO_ERROR; + modified_locale.setUnicodeKeywordValue("ca", nullptr, status); + return DateTimeStylePattern(date_style, time_style, modified_locale, hc, + generator); + } + return nullptr; + } icu::UnicodeString pattern; pattern = result->toPattern(pattern); - UErrorCode status = U_ZERO_ERROR; + status = U_ZERO_ERROR; icu::UnicodeString skeleton = icu::DateTimePatternGenerator::staticGetSkeleton(pattern, status); CHECK(U_SUCCESS(status)); @@ -1185,7 +1203,8 @@ class DateTimePatternGeneratorCache { public: // Return a clone copy that the caller have to free. icu::DateTimePatternGenerator* CreateGenerator(const icu::Locale& locale) { - std::string key(locale.getBaseName()); + std::string key(FLAG_harmony_intl_other_calendars ? locale.getName() + : locale.getBaseName()); base::MutexGuard guard(&mutex_); auto it = map_.find(key); if (it != map_.end()) { @@ -1193,7 +1212,8 @@ class DateTimePatternGeneratorCache { } UErrorCode status = U_ZERO_ERROR; map_[key].reset(icu::DateTimePatternGenerator::createInstance( - icu::Locale(key.c_str()), status)); + FLAG_harmony_intl_other_calendars ? locale : icu::Locale(key.c_str()), + status)); // Fallback to use "root". if (U_FAILURE(status)) { status = U_ZERO_ERROR; @@ -1216,7 +1236,7 @@ enum FormatMatcherOption { kBestFit, kBasic }; // ecma402/#sec-initializedatetimeformat MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> input_options) { + Handle<Object> input_options, const char* service) { Factory* factory = isolate->factory(); // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). Maybe<std::vector<std::string>> maybe_requested_locales = @@ -1235,6 +1255,10 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // 4. Let matcher be ? GetOption(options, "localeMatcher", "string", // « "lookup", "best fit" », "best fit"). // 5. Set opt.[[localeMatcher]] to matcher. + Maybe<Intl::MatcherOption> maybe_locale_matcher = + Intl::GetLocaleMatcher(isolate, options, service); + MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDateTimeFormat>()); + Intl::MatcherOption locale_matcher = maybe_locale_matcher.FromJust(); std::unique_ptr<char[]> calendar_str = nullptr; std::unique_ptr<char[]> numbering_system_str = nullptr; @@ -1242,13 +1266,12 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( const std::vector<const char*> empty_values = {}; // 6. Let calendar be ? GetOption(options, "calendar", // "string", undefined, undefined). - Maybe<bool> maybe_calendar = - Intl::GetStringOption(isolate, options, "calendar", empty_values, - "Intl.NumberFormat", &calendar_str); + Maybe<bool> maybe_calendar = Intl::GetStringOption( + isolate, options, "calendar", empty_values, service, &calendar_str); MAYBE_RETURN(maybe_calendar, MaybeHandle<JSDateTimeFormat>()); if (maybe_calendar.FromJust() && calendar_str != nullptr) { icu::Locale default_locale; - if (!Intl::IsValidCalendar(default_locale, calendar_str.get())) { + if (!Intl::IsWellFormedCalendar(calendar_str.get())) { THROW_NEW_ERROR( isolate, NewRangeError( @@ -1261,26 +1284,21 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // 8. Let numberingSystem be ? GetOption(options, "numberingSystem", // "string", undefined, undefined). Maybe<bool> maybe_numberingSystem = Intl::GetNumberingSystem( - isolate, options, "Intl.NumberFormat", &numbering_system_str); + isolate, options, service, &numbering_system_str); MAYBE_RETURN(maybe_numberingSystem, MaybeHandle<JSDateTimeFormat>()); } - Maybe<Intl::MatcherOption> maybe_locale_matcher = - Intl::GetLocaleMatcher(isolate, options, "Intl.DateTimeFormat"); - MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSDateTimeFormat>()); - Intl::MatcherOption locale_matcher = maybe_locale_matcher.FromJust(); - // 6. Let hour12 be ? GetOption(options, "hour12", "boolean", undefined, // undefined). bool hour12; - Maybe<bool> maybe_get_hour12 = Intl::GetBoolOption( - isolate, options, "hour12", "Intl.DateTimeFormat", &hour12); + Maybe<bool> maybe_get_hour12 = + Intl::GetBoolOption(isolate, options, "hour12", service, &hour12); MAYBE_RETURN(maybe_get_hour12, Handle<JSDateTimeFormat>()); // 7. Let hourCycle be ? GetOption(options, "hourCycle", "string", « "h11", // "h12", "h23", "h24" », undefined). Maybe<Intl::HourCycle> maybe_hour_cycle = - Intl::GetHourCycle(isolate, options, "Intl.DateTimeFormat"); + Intl::GetHourCycle(isolate, options, service); MAYBE_RETURN(maybe_hour_cycle, MaybeHandle<JSDateTimeFormat>()); Intl::HourCycle hour_cycle = maybe_hour_cycle.FromJust(); @@ -1309,12 +1327,14 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( DCHECK(!icu_locale.isBogus()); UErrorCode status = U_ZERO_ERROR; - if (calendar_str != nullptr) { + if (calendar_str != nullptr && + Intl::IsValidCalendar(icu_locale, calendar_str.get())) { icu_locale.setUnicodeKeywordValue("ca", calendar_str.get(), status); CHECK(U_SUCCESS(status)); } - if (numbering_system_str != nullptr) { + if (numbering_system_str != nullptr && + Intl::IsValidNumberingSystem(numbering_system_str.get())) { icu_locale.setUnicodeKeywordValue("nu", numbering_system_str.get(), status); CHECK(U_SUCCESS(status)); } @@ -1322,9 +1342,8 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // 17. Let timeZone be ? Get(options, "timeZone"). const std::vector<const char*> empty_values; std::unique_ptr<char[]> timezone = nullptr; - Maybe<bool> maybe_timezone = - Intl::GetStringOption(isolate, options, "timeZone", empty_values, - "Intl.DateTimeFormat", &timezone); + Maybe<bool> maybe_timezone = Intl::GetStringOption( + isolate, options, "timeZone", empty_values, service, &timezone); MAYBE_RETURN(maybe_timezone, Handle<JSDateTimeFormat>()); std::unique_ptr<icu::TimeZone> tz = CreateTimeZone(isolate, timezone.get()); @@ -1409,43 +1428,40 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( DateTimeStyle time_style = DateTimeStyle::kUndefined; std::unique_ptr<icu::SimpleDateFormat> icu_date_format; - if (FLAG_harmony_intl_datetime_style) { - // 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « - // "full", "long", "medium", "short" », undefined). - Maybe<DateTimeStyle> maybe_date_style = - Intl::GetStringOption<DateTimeStyle>( - isolate, options, "dateStyle", "Intl.DateTimeFormat", - {"full", "long", "medium", "short"}, - {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, - DateTimeStyle::kShort}, - DateTimeStyle::kUndefined); - MAYBE_RETURN(maybe_date_style, MaybeHandle<JSDateTimeFormat>()); - // 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to - // dateStyle. - date_style = maybe_date_style.FromJust(); - - // 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « - // "full", "long", "medium", "short" »). - Maybe<DateTimeStyle> maybe_time_style = - Intl::GetStringOption<DateTimeStyle>( - isolate, options, "timeStyle", "Intl.DateTimeFormat", - {"full", "long", "medium", "short"}, - {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, - DateTimeStyle::kShort}, - DateTimeStyle::kUndefined); - MAYBE_RETURN(maybe_time_style, MaybeHandle<JSDateTimeFormat>()); - - // 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to - // timeStyle. - time_style = maybe_time_style.FromJust(); - - // 32. If dateStyle or timeStyle are not undefined, then - if (date_style != DateTimeStyle::kUndefined || - time_style != DateTimeStyle::kUndefined) { - icu_date_format = DateTimeStylePattern(date_style, time_style, icu_locale, - hc, *generator); - } + // 28. Let dateStyle be ? GetOption(options, "dateStyle", "string", « + // "full", "long", "medium", "short" », undefined). + Maybe<DateTimeStyle> maybe_date_style = Intl::GetStringOption<DateTimeStyle>( + isolate, options, "dateStyle", service, + {"full", "long", "medium", "short"}, + {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, + DateTimeStyle::kShort}, + DateTimeStyle::kUndefined); + MAYBE_RETURN(maybe_date_style, MaybeHandle<JSDateTimeFormat>()); + // 29. If dateStyle is not undefined, set dateTimeFormat.[[DateStyle]] to + // dateStyle. + date_style = maybe_date_style.FromJust(); + + // 30. Let timeStyle be ? GetOption(options, "timeStyle", "string", « + // "full", "long", "medium", "short" »). + Maybe<DateTimeStyle> maybe_time_style = Intl::GetStringOption<DateTimeStyle>( + isolate, options, "timeStyle", service, + {"full", "long", "medium", "short"}, + {DateTimeStyle::kFull, DateTimeStyle::kLong, DateTimeStyle::kMedium, + DateTimeStyle::kShort}, + DateTimeStyle::kUndefined); + MAYBE_RETURN(maybe_time_style, MaybeHandle<JSDateTimeFormat>()); + + // 31. If timeStyle is not undefined, set dateTimeFormat.[[TimeStyle]] to + // timeStyle. + time_style = maybe_time_style.FromJust(); + + // 32. If dateStyle or timeStyle are not undefined, then + if (date_style != DateTimeStyle::kUndefined || + time_style != DateTimeStyle::kUndefined) { + icu_date_format = DateTimeStylePattern(date_style, time_style, icu_locale, + hc, generator.get()); } + // 33. Else, if (icu_date_format.get() == nullptr) { bool has_hour_option = false; @@ -1456,9 +1472,9 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // i. Let prop be the name given in the Property column of the row. // ii. Let value be ? GetOption(options, prop, "string", « the strings // given in the Values column of the row », undefined). - Maybe<bool> maybe_get_option = Intl::GetStringOption( - isolate, options, item.property.c_str(), item.allowed_values, - "Intl.DateTimeFormat", &input); + Maybe<bool> maybe_get_option = + Intl::GetStringOption(isolate, options, item.property.c_str(), + item.allowed_values, service, &input); MAYBE_RETURN(maybe_get_option, Handle<JSDateTimeFormat>()); if (maybe_get_option.FromJust()) { if (item.property == "hour") { @@ -1487,8 +1503,7 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // « "basic", "best fit" », "best fit"). Maybe<FormatMatcherOption> maybe_format_matcher = Intl::GetStringOption<FormatMatcherOption>( - isolate, options, "formatMatcher", "Intl.DateTimeFormat", - {"best fit", "basic"}, + isolate, options, "formatMatcher", service, {"best fit", "basic"}, {FormatMatcherOption::kBestFit, FormatMatcherOption::kBasic}, FormatMatcherOption::kBestFit); MAYBE_RETURN(maybe_format_matcher, MaybeHandle<JSDateTimeFormat>()); @@ -1496,13 +1511,13 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( // FormatMatcherOption format_matcher = maybe_format_matcher.FromJust(); icu::UnicodeString skeleton_ustr(skeleton.c_str()); - icu_date_format = - CreateICUDateFormatFromCache(icu_locale, skeleton_ustr, *generator); + icu_date_format = CreateICUDateFormatFromCache(icu_locale, skeleton_ustr, + generator.get()); if (icu_date_format.get() == nullptr) { // Remove extensions and try again. icu_locale = icu::Locale(icu_locale.getBaseName()); - icu_date_format = - CreateICUDateFormatFromCache(icu_locale, skeleton_ustr, *generator); + icu_date_format = CreateICUDateFormatFromCache(icu_locale, skeleton_ustr, + generator.get()); if (icu_date_format.get() == nullptr) { FATAL("Failed to create ICU date format, are ICU data files missing?"); } @@ -1561,12 +1576,16 @@ MaybeHandle<JSDateTimeFormat> JSDateTimeFormat::New( isolate->factory()->NewFastOrSlowJSObjectFromMap(map)); DisallowHeapAllocation no_gc; date_time_format->set_flags(0); - date_time_format->set_hour_cycle(hc); if (date_style != DateTimeStyle::kUndefined) { date_time_format->set_date_style(date_style); } if (time_style != DateTimeStyle::kUndefined) { date_time_format->set_time_style(time_style); + date_time_format->set_hour_cycle(hc); + } + if ((date_style == DateTimeStyle::kUndefined) && + (time_style == DateTimeStyle::kUndefined)) { + date_time_format->set_hour_cycle(hc); } date_time_format->set_icu_locale(*managed_locale); date_time_format->set_icu_simple_date_format(*managed_format); @@ -1585,11 +1604,9 @@ Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) { return isolate->factory()->literal_string(); case UDAT_YEAR_FIELD: case UDAT_EXTENDED_YEAR_FIELD: - case UDAT_YEAR_NAME_FIELD: return isolate->factory()->year_string(); - case UDAT_QUARTER_FIELD: - case UDAT_STANDALONE_QUARTER_FIELD: - return isolate->factory()->quarter_string(); + case UDAT_YEAR_NAME_FIELD: + return isolate->factory()->yearName_string(); case UDAT_MONTH_FIELD: case UDAT_STANDALONE_MONTH_FIELD: return isolate->factory()->month_string(); @@ -1624,6 +1641,11 @@ Handle<String> IcuDateFieldIdToDateType(int32_t field_id, Isolate* isolate) { return isolate->factory()->era_string(); case UDAT_FRACTIONAL_SECOND_FIELD: return isolate->factory()->fractionalSecond_string(); + case UDAT_RELATED_YEAR_FIELD: + return isolate->factory()->relatedYear_string(); + + case UDAT_QUARTER_FIELD: + case UDAT_STANDALONE_QUARTER_FIELD: default: // Other UDAT_*_FIELD's cannot show up because there is no way to specify // them via options of Intl.DateTimeFormat. diff --git a/deps/v8/src/objects/js-date-time-format.h b/deps/v8/src/objects/js-date-time-format.h index f4a8ccc8f5c871..acf99b361850e8 100644 --- a/deps/v8/src/objects/js-date-time-format.h +++ b/deps/v8/src/objects/js-date-time-format.h @@ -34,7 +34,7 @@ class JSDateTimeFormat : public JSObject { public: V8_WARN_UNUSED_RESULT static MaybeHandle<JSDateTimeFormat> New( Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options); + Handle<Object> options, const char* service); V8_WARN_UNUSED_RESULT static MaybeHandle<JSObject> ResolvedOptions( Isolate* isolate, Handle<JSDateTimeFormat> date_time_format); @@ -82,7 +82,8 @@ class JSDateTimeFormat : public JSObject { V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToLocaleDateTime( Isolate* isolate, Handle<Object> date, Handle<Object> locales, - Handle<Object> options, RequiredOption required, DefaultsOption defaults); + Handle<Object> options, RequiredOption required, DefaultsOption defaults, + const char* method); V8_EXPORT_PRIVATE static const std::set<std::string>& GetAvailableLocales(); @@ -94,7 +95,7 @@ class JSDateTimeFormat : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSDATE_TIME_FORMAT_FIELDS) + TORQUE_GENERATED_JS_DATE_TIME_FORMAT_FIELDS) inline void set_hour_cycle(Intl::HourCycle hour_cycle); inline Intl::HourCycle hour_cycle() const; diff --git a/deps/v8/src/objects/js-list-format.cc b/deps/v8/src/objects/js-list-format.cc index 4f303b18745829..90b93e308adc4e 100644 --- a/deps/v8/src/objects/js-list-format.cc +++ b/deps/v8/src/objects/js-list-format.cc @@ -252,40 +252,22 @@ namespace { // Extract String from JSArray into array of UnicodeString Maybe<std::vector<icu::UnicodeString>> ToUnicodeStringArray( Isolate* isolate, Handle<JSArray> array) { - Factory* factory = isolate->factory(); - // In general, ElementsAccessor::Get actually isn't guaranteed to give us the - // elements in order. But if it is a holey array, it will cause the exception - // with the IsString check. + // Thanks to iterable-to-list preprocessing, we never see dictionary-mode + // arrays here, so the loop below can construct an entry from the index. + DCHECK(array->HasFastElements(isolate)); auto* accessor = array->GetElementsAccessor(); uint32_t length = accessor->NumberOfElements(*array); - // ecma402 #sec-createpartsfromlist - // 2. If list contains any element value such that Type(value) is not String, - // throw a TypeError exception. - // - // Per spec it looks like we're supposed to throw a TypeError exception if the - // item isn't already a string, rather than coercing to a string. std::vector<icu::UnicodeString> result; for (uint32_t i = 0; i < length; i++) { - DCHECK(accessor->HasElement(*array, i)); - Handle<Object> item = accessor->Get(array, i); - DCHECK(!item.is_null()); - if (!item->IsString()) { - THROW_NEW_ERROR_RETURN_VALUE( - isolate, - NewTypeError(MessageTemplate::kArrayItemNotType, - factory->list_string(), - // TODO(ftang): For dictionary-mode arrays, i isn't - // actually the index in the array but the index in the - // dictionary. - factory->NewNumber(i), factory->String_string()), - Nothing<std::vector<icu::UnicodeString>>()); - } + InternalIndex entry(i); + DCHECK(accessor->HasEntry(*array, entry)); + Handle<Object> item = accessor->Get(array, entry); + DCHECK(item->IsString()); Handle<String> item_str = Handle<String>::cast(item); if (!item_str->IsFlat()) item_str = String::Flatten(isolate, item_str); result.push_back(Intl::ToICUUnicodeString(isolate, item_str)); } - DCHECK(!array->HasDictionaryElements()); return Just(result); } @@ -294,9 +276,6 @@ MaybeHandle<T> FormatListCommon( Isolate* isolate, Handle<JSListFormat> format, Handle<JSArray> list, MaybeHandle<T> (*formatToResult)(Isolate*, const icu::FormattedValue&)) { DCHECK(!list->IsUndefined()); - // ecma402 #sec-createpartsfromlist - // 2. If list contains any element value such that Type(value) is not String, - // throw a TypeError exception. Maybe<std::vector<icu::UnicodeString>> maybe_array = ToUnicodeStringArray(isolate, list); MAYBE_RETURN(maybe_array, Handle<T>()); diff --git a/deps/v8/src/objects/js-list-format.h b/deps/v8/src/objects/js-list-format.h index df937722e6586b..1ff76790f951cb 100644 --- a/deps/v8/src/objects/js-list-format.h +++ b/deps/v8/src/objects/js-list-format.h @@ -104,7 +104,7 @@ class JSListFormat : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSLIST_FORMAT_FIELDS) + TORQUE_GENERATED_JS_LIST_FORMAT_FIELDS) OBJECT_CONSTRUCTORS(JSListFormat, JSObject); }; diff --git a/deps/v8/src/objects/js-locale.cc b/deps/v8/src/objects/js-locale.cc index 4a66ea9eca739c..9e8053b1dc81d8 100644 --- a/deps/v8/src/objects/js-locale.cc +++ b/deps/v8/src/objects/js-locale.cc @@ -168,10 +168,20 @@ bool IsUnicodeVariantSubtag(const std::string& value) { bool IsExtensionSingleton(const std::string& value) { return IsAlphanum(value, 1, 1); } +} // namespace + +bool JSLocale::Is38AlphaNumList(const std::string& value) { + std::size_t found = value.find("-"); + if (found == std::string::npos) { + return IsAlphanum(value, 3, 8); + } + return IsAlphanum(value.substr(0, found), 3, 8) && + JSLocale::Is38AlphaNumList(value.substr(found + 1)); +} // TODO(ftang) Replace the following check w/ icu::LocaleBuilder // once ICU64 land in March 2019. -bool StartsWithUnicodeLanguageId(const std::string& value) { +bool JSLocale::StartsWithUnicodeLanguageId(const std::string& value) { // unicode_language_id = // unicode_language_subtag (sep unicode_script_subtag)? // (sep unicode_region_subtag)? (sep unicode_variant_subtag)* ; @@ -207,6 +217,7 @@ bool StartsWithUnicodeLanguageId(const std::string& value) { return true; } +namespace { Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, Handle<JSReceiver> options, icu::LocaleBuilder* builder) { @@ -223,7 +234,7 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, Handle<String> tag, CHECK_NOT_NULL(*bcp47_tag); // 2. If IsStructurallyValidLanguageTag(tag) is false, throw a RangeError // exception. - if (!StartsWithUnicodeLanguageId(*bcp47_tag)) { + if (!JSLocale::StartsWithUnicodeLanguageId(*bcp47_tag)) { return Just(false); } UErrorCode status = U_ZERO_ERROR; diff --git a/deps/v8/src/objects/js-locale.h b/deps/v8/src/objects/js-locale.h index e1806e6b7f845c..f2fca3ce14aca5 100644 --- a/deps/v8/src/objects/js-locale.h +++ b/deps/v8/src/objects/js-locale.h @@ -49,6 +49,13 @@ class JSLocale : public JSObject { static Handle<String> ToString(Isolate* isolate, Handle<JSLocale> locale); static std::string ToString(Handle<JSLocale> locale); + // Help function to validate locale by other Intl objects. + static bool StartsWithUnicodeLanguageId(const std::string& value); + + // Help function to check well-formed + // "(3*8alphanum) *("-" (3*8alphanum)) sequence" sequence + static bool Is38AlphaNumList(const std::string& value); + DECL_CAST(JSLocale) DECL_ACCESSORS(icu_locale, Managed<icu::Locale>) @@ -58,7 +65,7 @@ class JSLocale : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSLOCALE_FIELDS) + TORQUE_GENERATED_JS_LOCALE_FIELDS) OBJECT_CONSTRUCTORS(JSLocale, JSObject); }; diff --git a/deps/v8/src/objects/js-number-format-inl.h b/deps/v8/src/objects/js-number-format-inl.h index afdfef89f2c2d6..f68252ab0b8da6 100644 --- a/deps/v8/src/objects/js-number-format-inl.h +++ b/deps/v8/src/objects/js-number-format-inl.h @@ -26,46 +26,8 @@ ACCESSORS(JSNumberFormat, icu_number_formatter, kIcuNumberFormatterOffset) ACCESSORS(JSNumberFormat, bound_format, Object, kBoundFormatOffset) -// Currenct ECMA 402 spec mandate to record (Min|Max)imumFractionDigits -// uncondictionally while the unified number proposal eventually will only -// record either (Min|Max)imumFractionDigits or (Min|Max)imumSignaficantDigits -// Since LocalizedNumberFormatter can only remember one set, and during -// 2019-1-17 ECMA402 meeting that the committee decide not to take a PR to -// address that prior to the unified number proposal, we have to add these two -// 5 bits int into flags to remember the (Min|Max)imumFractionDigits while -// (Min|Max)imumSignaficantDigits is present. -// TODO(ftang) remove the following once we ship int-number-format-unified -// * SMI_ACCESSORS of flags -// * Four inline functions: (set_)?(min|max)imum_fraction_digits - SMI_ACCESSORS(JSNumberFormat, flags, kFlagsOffset) -inline int JSNumberFormat::minimum_fraction_digits() const { - return MinimumFractionDigitsBits::decode(flags()); -} - -inline void JSNumberFormat::set_minimum_fraction_digits(int digits) { - DCHECK_GE(MinimumFractionDigitsBits::kMax, digits); - DCHECK_LE(0, digits); - DCHECK_GE(20, digits); - int hints = flags(); - hints = MinimumFractionDigitsBits::update(hints, digits); - set_flags(hints); -} - -inline int JSNumberFormat::maximum_fraction_digits() const { - return MaximumFractionDigitsBits::decode(flags()); -} - -inline void JSNumberFormat::set_maximum_fraction_digits(int digits) { - DCHECK_GE(MaximumFractionDigitsBits::kMax, digits); - DCHECK_LE(0, digits); - DCHECK_GE(20, digits); - int hints = flags(); - hints = MaximumFractionDigitsBits::update(hints, digits); - set_flags(hints); -} - inline void JSNumberFormat::set_style(Style style) { DCHECK_GE(StyleBits::kMax, style); int hints = flags(); diff --git a/deps/v8/src/objects/js-number-format.cc b/deps/v8/src/objects/js-number-format.cc index ff564975d6f4a1..c065a3f725d67f 100644 --- a/deps/v8/src/objects/js-number-format.cc +++ b/deps/v8/src/objects/js-number-format.cc @@ -33,7 +33,6 @@ namespace { // [[CurrencyDisplay]] is one of the values "code", "symbol", "name", // or "narrowSymbol" identifying the display of the currency number format. -// Note: "narrowSymbol" is added in proposal-unified-intl-numberformat enum class CurrencyDisplay { CODE, SYMBOL, @@ -621,12 +620,11 @@ JSNumberFormat::SetDigitOptionsToFormatter( result = result.integerWidth(icu::number::IntegerWidth::zeroFillTo( digit_options.minimum_integer_digits)); } - if (FLAG_harmony_intl_numberformat_unified) { - // Value -1 of minimum_significant_digits represent the roundingtype is - // "compact-rounding". - if (digit_options.minimum_significant_digits < 0) { - return result; - } + + // Value -1 of minimum_significant_digits represent the roundingtype is + // "compact-rounding". + if (digit_options.minimum_significant_digits < 0) { + return result; } icu::number::Precision precision = (digit_options.minimum_significant_digits > 0) @@ -704,15 +702,12 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions( isolate, options, factory->currencyDisplay_string(), CurrencyDisplayString(isolate, skeleton), Just(kDontThrow)) .FromJust()); - if (FLAG_harmony_intl_numberformat_unified) { - CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->currencySign_string(), - CurrencySignString(isolate, skeleton), Just(kDontThrow)) - .FromJust()); - } + CHECK(JSReceiver::CreateDataProperty( + isolate, options, factory->currencySign_string(), + CurrencySignString(isolate, skeleton), Just(kDontThrow)) + .FromJust()); } - if (FLAG_harmony_intl_numberformat_unified) { if (style == JSNumberFormat::Style::UNIT) { std::string unit = UnitFromSkeleton(skeleton); if (!unit.empty()) { @@ -727,7 +722,6 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions( UnitDisplayString(isolate, skeleton), Just(kDontThrow)) .FromJust()); } - } CHECK( JSReceiver::CreateDataProperty( @@ -735,45 +729,25 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions( factory->NewNumberFromInt(MinimumIntegerDigitsFromSkeleton(skeleton)), Just(kDontThrow)) .FromJust()); + int32_t minimum = 0, maximum = 0; - bool output_fraction = - FractionDigitsFromSkeleton(skeleton, &minimum, &maximum); - - if (!FLAG_harmony_intl_numberformat_unified && !output_fraction) { - // Currenct ECMA 402 spec mandate to record (Min|Max)imumFractionDigits - // uncondictionally while the unified number proposal eventually will only - // record either (Min|Max)imumFractionDigits or - // (Min|Max)imumSignaficantDigits Since LocalizedNumberFormatter can only - // remember one set, and during 2019-1-17 ECMA402 meeting that the committee - // decide not to take a PR to address that prior to the unified number - // proposal, we have to add these two 5 bits int into flags to remember the - // (Min|Max)imumFractionDigits while (Min|Max)imumSignaficantDigits is - // present. - // TODO(ftang) remove the following two lines once we ship - // int-number-format-unified - output_fraction = true; - minimum = number_format->minimum_fraction_digits(); - maximum = number_format->maximum_fraction_digits(); - } - if (output_fraction) { + if (SignificantDigitsFromSkeleton(skeleton, &minimum, &maximum)) { CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->minimumFractionDigits_string(), + isolate, options, factory->minimumSignificantDigits_string(), factory->NewNumberFromInt(minimum), Just(kDontThrow)) .FromJust()); CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->maximumFractionDigits_string(), + isolate, options, factory->maximumSignificantDigits_string(), factory->NewNumberFromInt(maximum), Just(kDontThrow)) .FromJust()); - } - minimum = 0; - maximum = 0; - if (SignificantDigitsFromSkeleton(skeleton, &minimum, &maximum)) { + } else { + FractionDigitsFromSkeleton(skeleton, &minimum, &maximum); CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->minimumSignificantDigits_string(), + isolate, options, factory->minimumFractionDigits_string(), factory->NewNumberFromInt(minimum), Just(kDontThrow)) .FromJust()); CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->maximumSignificantDigits_string(), + isolate, options, factory->maximumFractionDigits_string(), factory->NewNumberFromInt(maximum), Just(kDontThrow)) .FromJust()); } @@ -783,24 +757,22 @@ Handle<JSObject> JSNumberFormat::ResolvedOptions( factory->ToBoolean(UseGroupingFromSkeleton(skeleton)), Just(kDontThrow)) .FromJust()); - if (FLAG_harmony_intl_numberformat_unified) { - Notation notation = NotationFromSkeleton(skeleton); - CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->notation_string(), - NotationAsString(isolate, notation), Just(kDontThrow)) - .FromJust()); - // Only output compactDisplay when notation is compact. - if (notation == Notation::COMPACT) { - CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->compactDisplay_string(), - CompactDisplayString(isolate, skeleton), Just(kDontThrow)) - .FromJust()); - } + Notation notation = NotationFromSkeleton(skeleton); + CHECK(JSReceiver::CreateDataProperty( + isolate, options, factory->notation_string(), + NotationAsString(isolate, notation), Just(kDontThrow)) + .FromJust()); + // Only output compactDisplay when notation is compact. + if (notation == Notation::COMPACT) { CHECK(JSReceiver::CreateDataProperty( - isolate, options, factory->signDisplay_string(), - SignDisplayString(isolate, skeleton), Just(kDontThrow)) + isolate, options, factory->compactDisplay_string(), + CompactDisplayString(isolate, skeleton), Just(kDontThrow)) .FromJust()); } + CHECK(JSReceiver::CreateDataProperty( + isolate, options, factory->signDisplay_string(), + SignDisplayString(isolate, skeleton), Just(kDontThrow)) + .FromJust()); return options; } @@ -837,7 +809,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::UnwrapNumberFormat( MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options_obj) { + Handle<Object> options_obj, + const char* service) { Factory* factory = isolate->factory(); // 1. Let requestedLocales be ? CanonicalizeLocaleList(locales). @@ -854,10 +827,9 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, } else { // 3. Else // 3. a. Let options be ? ToObject(options). - ASSIGN_RETURN_ON_EXCEPTION( - isolate, options_obj, - Object::ToObject(isolate, options_obj, "Intl.NumberFormat"), - JSNumberFormat); + ASSIGN_RETURN_ON_EXCEPTION(isolate, options_obj, + Object::ToObject(isolate, options_obj, service), + JSNumberFormat); } // At this point, options_obj can either be a JSObject or a JSProxy only. @@ -868,7 +840,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, // "lookup", "best fit" », "best fit"). // 6. Set opt.[[localeMatcher]] to matcher. Maybe<Intl::MatcherOption> maybe_locale_matcher = - Intl::GetLocaleMatcher(isolate, options, "Intl.NumberFormat"); + Intl::GetLocaleMatcher(isolate, options, service); MAYBE_RETURN(maybe_locale_matcher, MaybeHandle<JSNumberFormat>()); Intl::MatcherOption matcher = maybe_locale_matcher.FromJust(); @@ -877,7 +849,7 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, // 7. Let _numberingSystem_ be ? GetOption(_options_, `"numberingSystem"`, // `"string"`, *undefined*, *undefined*). Maybe<bool> maybe_numberingSystem = Intl::GetNumberingSystem( - isolate, options, "Intl.RelativeTimeFormat", &numbering_system_str); + isolate, options, service, &numbering_system_str); // 8. If _numberingSystem_ is not *undefined*, then // a. If _numberingSystem_ does not match the // `(3*8alphanum) *("-" (3*8alphanum))` sequence, throw a *RangeError* @@ -895,7 +867,8 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, requested_locales, matcher, relevant_extension_keys); UErrorCode status = U_ZERO_ERROR; - if (numbering_system_str != nullptr) { + if (numbering_system_str != nullptr && + Intl::IsValidNumberingSystem(numbering_system_str.get())) { r.icu_locale.setUnicodeKeywordValue("nu", numbering_system_str.get(), status); CHECK(U_SUCCESS(status)); @@ -913,21 +886,15 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, .roundingMode(UNUM_ROUND_HALFUP); // 12. Let style be ? GetOption(options, "style", "string", « "decimal", - // "percent", "currency" », "decimal"). - const char* service = "Intl.NumberFormat"; + // "percent", "currency", "unit" », "decimal"). - std::vector<const char*> style_str_values({"decimal", "percent", "currency"}); - std::vector<JSNumberFormat::Style> style_enum_values( - {JSNumberFormat::Style::DECIMAL, JSNumberFormat::Style::PERCENT, - JSNumberFormat::Style::CURRENCY}); - if (FLAG_harmony_intl_numberformat_unified) { - style_str_values.push_back("unit"); - style_enum_values.push_back(JSNumberFormat::Style::UNIT); - } Maybe<JSNumberFormat::Style> maybe_style = Intl::GetStringOption<JSNumberFormat::Style>( - isolate, options, "style", service, style_str_values, - style_enum_values, JSNumberFormat::Style::DECIMAL); + isolate, options, "style", service, + {"decimal", "percent", "currency", "unit"}, + {JSNumberFormat::Style::DECIMAL, JSNumberFormat::Style::PERCENT, + JSNumberFormat::Style::CURRENCY, JSNumberFormat::Style::UNIT}, + JSNumberFormat::Style::DECIMAL); MAYBE_RETURN(maybe_style, MaybeHandle<JSNumberFormat>()); JSNumberFormat::Style style = maybe_style.FromJust(); @@ -977,99 +944,87 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, } // 18. Let currencyDisplay be ? GetOption(options, "currencyDisplay", - // "string", « "code", "symbol", "name" », "symbol"). - std::vector<const char*> currency_display_str_values( - {"code", "symbol", "name"}); - std::vector<CurrencyDisplay> currency_display_enum_values( - {CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL, CurrencyDisplay::NAME}); - if (FLAG_harmony_intl_numberformat_unified) { - currency_display_str_values.push_back("narrowSymbol"); - currency_display_enum_values.push_back(CurrencyDisplay::NARROW_SYMBOL); - } + // "string", « "code", "symbol", "name", "narrowSymbol" », "symbol"). Maybe<CurrencyDisplay> maybe_currency_display = Intl::GetStringOption<CurrencyDisplay>( isolate, options, "currencyDisplay", service, - currency_display_str_values, currency_display_enum_values, + {"code", "symbol", "name", "narrowSymbol"}, + {CurrencyDisplay::CODE, CurrencyDisplay::SYMBOL, + CurrencyDisplay::NAME, CurrencyDisplay::NARROW_SYMBOL}, CurrencyDisplay::SYMBOL); MAYBE_RETURN(maybe_currency_display, MaybeHandle<JSNumberFormat>()); CurrencyDisplay currency_display = maybe_currency_display.FromJust(); CurrencySign currency_sign = CurrencySign::STANDARD; - if (FLAG_harmony_intl_numberformat_unified) { - // Let currencySign be ? GetOption(options, "currencySign", "string", « - // "standard", "accounting" », "standard"). - Maybe<CurrencySign> maybe_currency_sign = - Intl::GetStringOption<CurrencySign>( - isolate, options, "currencySign", service, - {"standard", "accounting"}, - {CurrencySign::STANDARD, CurrencySign::ACCOUNTING}, - CurrencySign::STANDARD); - MAYBE_RETURN(maybe_currency_sign, MaybeHandle<JSNumberFormat>()); - currency_sign = maybe_currency_sign.FromJust(); - - // Let unit be ? GetOption(options, "unit", "string", undefined, undefined). - std::unique_ptr<char[]> unit_cstr; - Maybe<bool> found_unit = Intl::GetStringOption( - isolate, options, "unit", empty_values, service, &unit_cstr); - MAYBE_RETURN(found_unit, MaybeHandle<JSNumberFormat>()); - - std::string unit; - if (found_unit.FromJust()) { - DCHECK_NOT_NULL(unit_cstr.get()); - unit = unit_cstr.get(); + // Let currencySign be ? GetOption(options, "currencySign", "string", « + // "standard", "accounting" », "standard"). + Maybe<CurrencySign> maybe_currency_sign = Intl::GetStringOption<CurrencySign>( + isolate, options, "currencySign", service, {"standard", "accounting"}, + {CurrencySign::STANDARD, CurrencySign::ACCOUNTING}, + CurrencySign::STANDARD); + MAYBE_RETURN(maybe_currency_sign, MaybeHandle<JSNumberFormat>()); + currency_sign = maybe_currency_sign.FromJust(); + + // Let unit be ? GetOption(options, "unit", "string", undefined, undefined). + std::unique_ptr<char[]> unit_cstr; + Maybe<bool> found_unit = Intl::GetStringOption( + isolate, options, "unit", empty_values, service, &unit_cstr); + MAYBE_RETURN(found_unit, MaybeHandle<JSNumberFormat>()); + + std::string unit; + if (found_unit.FromJust()) { + DCHECK_NOT_NULL(unit_cstr.get()); + unit = unit_cstr.get(); + } + + // Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « + // "short", "narrow", "long" », "short"). + Maybe<UnitDisplay> maybe_unit_display = Intl::GetStringOption<UnitDisplay>( + isolate, options, "unitDisplay", service, {"short", "narrow", "long"}, + {UnitDisplay::SHORT, UnitDisplay::NARROW, UnitDisplay::LONG}, + UnitDisplay::SHORT); + MAYBE_RETURN(maybe_unit_display, MaybeHandle<JSNumberFormat>()); + UnitDisplay unit_display = maybe_unit_display.FromJust(); + + // If style is "unit", then + if (style == JSNumberFormat::Style::UNIT) { + // If unit is undefined, throw a TypeError exception. + if (unit == "") { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kInvalidUnit, + factory->NewStringFromAsciiChecked(service), + factory->empty_string()), + JSNumberFormat); } - // Let unitDisplay be ? GetOption(options, "unitDisplay", "string", « - // "short", "narrow", "long" », "short"). - Maybe<UnitDisplay> maybe_unit_display = Intl::GetStringOption<UnitDisplay>( - isolate, options, "unitDisplay", service, {"short", "narrow", "long"}, - {UnitDisplay::SHORT, UnitDisplay::NARROW, UnitDisplay::LONG}, - UnitDisplay::SHORT); - MAYBE_RETURN(maybe_unit_display, MaybeHandle<JSNumberFormat>()); - UnitDisplay unit_display = maybe_unit_display.FromJust(); - - // If style is "unit", then - if (style == JSNumberFormat::Style::UNIT) { - // If unit is undefined, throw a TypeError exception. - if (unit == "") { - THROW_NEW_ERROR( - isolate, - NewTypeError(MessageTemplate::kInvalidUnit, - factory->NewStringFromStaticChars("Intl.NumberFormat"), - factory->empty_string()), - JSNumberFormat); - } - - // If the result of IsWellFormedUnitIdentifier(unit) is false, throw a - // RangeError exception. - Maybe<std::pair<icu::MeasureUnit, icu::MeasureUnit>> maybe_wellformed = - IsWellFormedUnitIdentifier(isolate, unit); - if (maybe_wellformed.IsNothing()) { - THROW_NEW_ERROR( - isolate, - NewRangeError( - MessageTemplate::kInvalidUnit, - factory->NewStringFromStaticChars("Intl.NumberFormat"), - factory->NewStringFromAsciiChecked(unit.c_str())), - JSNumberFormat); - } - std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair = - maybe_wellformed.FromJust(); + // If the result of IsWellFormedUnitIdentifier(unit) is false, throw a + // RangeError exception. + Maybe<std::pair<icu::MeasureUnit, icu::MeasureUnit>> maybe_wellformed = + IsWellFormedUnitIdentifier(isolate, unit); + if (maybe_wellformed.IsNothing()) { + THROW_NEW_ERROR( + isolate, + NewRangeError(MessageTemplate::kInvalidUnit, + factory->NewStringFromAsciiChecked(service), + factory->NewStringFromAsciiChecked(unit.c_str())), + JSNumberFormat); + } + std::pair<icu::MeasureUnit, icu::MeasureUnit> unit_pair = + maybe_wellformed.FromJust(); - // Set intlObj.[[Unit]] to unit. - if (unit_pair.first != icu::NoUnit::base()) { - icu_number_formatter = icu_number_formatter.unit(unit_pair.first); - } - if (unit_pair.second != icu::NoUnit::base()) { - icu_number_formatter = icu_number_formatter.perUnit(unit_pair.second); - } + // Set intlObj.[[Unit]] to unit. + if (unit_pair.first != icu::NoUnit::base()) { + icu_number_formatter = icu_number_formatter.unit(unit_pair.first); + } + if (unit_pair.second != icu::NoUnit::base()) { + icu_number_formatter = icu_number_formatter.perUnit(unit_pair.second); + } - // The default unitWidth is SHORT in ICU and that mapped from - // Symbol so we can skip the setting for optimization. - if (unit_display != UnitDisplay::SHORT) { - icu_number_formatter = - icu_number_formatter.unitWidth(ToUNumberUnitWidth(unit_display)); - } + // The default unitWidth is SHORT in ICU and that mapped from + // Symbol so we can skip the setting for optimization. + if (unit_display != UnitDisplay::SHORT) { + icu_number_formatter = + icu_number_formatter.unitWidth(ToUNumberUnitWidth(unit_display)); } } @@ -1125,18 +1080,16 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, } Notation notation = Notation::STANDARD; - if (FLAG_harmony_intl_numberformat_unified) { - // 25. Let notation be ? GetOption(options, "notation", "string", « - // "standard", "scientific", "engineering", "compact" », "standard"). - Maybe<Notation> maybe_notation = Intl::GetStringOption<Notation>( - isolate, options, "notation", service, - {"standard", "scientific", "engineering", "compact"}, - {Notation::STANDARD, Notation::SCIENTIFIC, Notation::ENGINEERING, - Notation::COMPACT}, - Notation::STANDARD); - MAYBE_RETURN(maybe_notation, MaybeHandle<JSNumberFormat>()); - notation = maybe_notation.FromJust(); - } + // 25. Let notation be ? GetOption(options, "notation", "string", « + // "standard", "scientific", "engineering", "compact" », "standard"). + Maybe<Notation> maybe_notation = Intl::GetStringOption<Notation>( + isolate, options, "notation", service, + {"standard", "scientific", "engineering", "compact"}, + {Notation::STANDARD, Notation::SCIENTIFIC, Notation::ENGINEERING, + Notation::COMPACT}, + Notation::STANDARD); + MAYBE_RETURN(maybe_notation, MaybeHandle<JSNumberFormat>()); + notation = maybe_notation.FromJust(); // 27. Perform ? SetNumberFormatDigitOptions(numberFormat, options, // mnfdDefault, mxfdDefault). @@ -1149,24 +1102,21 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, icu_number_formatter = JSNumberFormat::SetDigitOptionsToFormatter( icu_number_formatter, digit_options); - if (FLAG_harmony_intl_numberformat_unified) { - // 28. Let compactDisplay be ? GetOption(options, "compactDisplay", - // "string", « "short", "long" », "short"). - Maybe<CompactDisplay> maybe_compact_display = - Intl::GetStringOption<CompactDisplay>( - isolate, options, "compactDisplay", service, {"short", "long"}, - {CompactDisplay::SHORT, CompactDisplay::LONG}, - CompactDisplay::SHORT); - MAYBE_RETURN(maybe_compact_display, MaybeHandle<JSNumberFormat>()); - CompactDisplay compact_display = maybe_compact_display.FromJust(); - - // 26. Set numberFormat.[[Notation]] to notation. - // The default notation in ICU is Simple, which mapped from STANDARD - // so we can skip setting it. - if (notation != Notation::STANDARD) { - icu_number_formatter = icu_number_formatter.notation( - ToICUNotation(notation, compact_display)); - } + // 28. Let compactDisplay be ? GetOption(options, "compactDisplay", + // "string", « "short", "long" », "short"). + Maybe<CompactDisplay> maybe_compact_display = + Intl::GetStringOption<CompactDisplay>( + isolate, options, "compactDisplay", service, {"short", "long"}, + {CompactDisplay::SHORT, CompactDisplay::LONG}, CompactDisplay::SHORT); + MAYBE_RETURN(maybe_compact_display, MaybeHandle<JSNumberFormat>()); + CompactDisplay compact_display = maybe_compact_display.FromJust(); + + // 26. Set numberFormat.[[Notation]] to notation. + // The default notation in ICU is Simple, which mapped from STANDARD + // so we can skip setting it. + if (notation != Notation::STANDARD) { + icu_number_formatter = + icu_number_formatter.notation(ToICUNotation(notation, compact_display)); } // 30. Let useGrouping be ? GetOption(options, "useGrouping", "boolean", // undefined, true). @@ -1180,27 +1130,25 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, UNumberGroupingStrategy::UNUM_GROUPING_OFF); } - if (FLAG_harmony_intl_numberformat_unified) { - // 32. Let signDisplay be ? GetOption(options, "signDisplay", "string", « - // "auto", "never", "always", "exceptZero" », "auto"). - Maybe<SignDisplay> maybe_sign_display = Intl::GetStringOption<SignDisplay>( - isolate, options, "signDisplay", service, - {"auto", "never", "always", "exceptZero"}, - {SignDisplay::AUTO, SignDisplay::NEVER, SignDisplay::ALWAYS, - SignDisplay::EXCEPT_ZERO}, - SignDisplay::AUTO); - MAYBE_RETURN(maybe_sign_display, MaybeHandle<JSNumberFormat>()); - SignDisplay sign_display = maybe_sign_display.FromJust(); - - // 33. Set numberFormat.[[SignDisplay]] to signDisplay. - // The default sign in ICU is UNUM_SIGN_AUTO which is mapped from - // SignDisplay::AUTO and CurrencySign::STANDARD so we can skip setting - // under that values for optimization. - if (sign_display != SignDisplay::AUTO || - currency_sign != CurrencySign::STANDARD) { - icu_number_formatter = icu_number_formatter.sign( - ToUNumberSignDisplay(sign_display, currency_sign)); - } + // 32. Let signDisplay be ? GetOption(options, "signDisplay", "string", « + // "auto", "never", "always", "exceptZero" », "auto"). + Maybe<SignDisplay> maybe_sign_display = Intl::GetStringOption<SignDisplay>( + isolate, options, "signDisplay", service, + {"auto", "never", "always", "exceptZero"}, + {SignDisplay::AUTO, SignDisplay::NEVER, SignDisplay::ALWAYS, + SignDisplay::EXCEPT_ZERO}, + SignDisplay::AUTO); + MAYBE_RETURN(maybe_sign_display, MaybeHandle<JSNumberFormat>()); + SignDisplay sign_display = maybe_sign_display.FromJust(); + + // 33. Set numberFormat.[[SignDisplay]] to signDisplay. + // The default sign in ICU is UNUM_SIGN_AUTO which is mapped from + // SignDisplay::AUTO and CurrencySign::STANDARD so we can skip setting + // under that values for optimization. + if (sign_display != SignDisplay::AUTO || + currency_sign != CurrencySign::STANDARD) { + icu_number_formatter = icu_number_formatter.sign( + ToUNumberSignDisplay(sign_display, currency_sign)); } // 25. Let dataLocaleData be localeData.[[<dataLocale>]]. @@ -1231,24 +1179,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, number_format->set_style(style); number_format->set_locale(*locale_str); - if (digit_options.minimum_significant_digits > 0) { - // The current ECMA 402 spec mandates recording (Min|Max)imumFractionDigits - // unconditionally, while the unified number proposal eventually will only - // record either (Min|Max)imumFractionDigits or - // (Min|Max)imumSignificantDigits. Since LocalizedNumberFormatter can only - // remember one set, and during 2019-1-17 ECMA402 meeting the committee - // decided not to take a PR to address that prior to the unified number - // proposal, we have to add these two 5-bit ints into flags to remember the - // (Min|Max)imumFractionDigits while (Min|Max)imumSignificantDigits is - // present. - // TODO(ftang) remove the following two lines once we ship - // int-number-format-unified - number_format->set_minimum_fraction_digits( - digit_options.minimum_fraction_digits); - number_format->set_maximum_fraction_digits( - digit_options.maximum_fraction_digits); - } - number_format->set_icu_number_formatter(*managed_number_formatter); number_format->set_bound_format(*factory->undefined_value()); diff --git a/deps/v8/src/objects/js-number-format.h b/deps/v8/src/objects/js-number-format.h index 2979ab10f43f66..a5196f8d517587 100644 --- a/deps/v8/src/objects/js-number-format.h +++ b/deps/v8/src/objects/js-number-format.h @@ -36,7 +36,7 @@ class JSNumberFormat : public JSObject { // ecma402/#sec-initializenumberformat V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> New( Isolate* isolate, Handle<Map> map, Handle<Object> locales, - Handle<Object> options); + Handle<Object> options, const char* service); // ecma402/#sec-unwrapnumberformat V8_WARN_UNUSED_RESULT static MaybeHandle<JSNumberFormat> UnwrapNumberFormat( @@ -72,26 +72,6 @@ class JSNumberFormat : public JSObject { DECL_PRINTER(JSNumberFormat) DECL_VERIFIER(JSNumberFormat) - // Current ECMA 402 spec mandates to record (Min|Max)imumFractionDigits - // unconditionally while the unified number proposal eventually will only - // record either (Min|Max)imumFractionDigits or (Min|Max)imumSignaficantDigits - // Since LocalizedNumberFormatter can only remember one set, and during - // 2019-1-17 ECMA402 meeting that the committee decide not to take a PR to - // address that prior to the unified number proposal, we have to add these two - // 5 bits int into flags to remember the (Min|Max)imumFractionDigits while - // (Min|Max)imumSignaficantDigits is present. - // TODO(ftang) remove the following once we ship int-number-format-unified - // * Four inline functions: (set_)?(min|max)imum_fraction_digits - // * kFlagsOffset - // * #define FLAGS_BIT_FIELDS - // * DECL_INT_ACCESSORS(flags) - - inline int minimum_fraction_digits() const; - inline void set_minimum_fraction_digits(int digits); - - inline int maximum_fraction_digits() const; - inline void set_maximum_fraction_digits(int digits); - // [[Style]] is one of the values "decimal", "percent", "currency", // or "unit" identifying the style of the number format. // Note: "unit" is added in proposal-unified-intl-numberformat @@ -102,19 +82,15 @@ class JSNumberFormat : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSNUMBER_FORMAT_FIELDS) + TORQUE_GENERATED_JS_NUMBER_FORMAT_FIELDS) // Bit positions in |flags|. #define FLAGS_BIT_FIELDS(V, _) \ - V(MinimumFractionDigitsBits, int, 5, _) \ - V(MaximumFractionDigitsBits, int, 5, _) \ V(StyleBits, Style, 2, _) DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS) #undef FLAGS_BIT_FIELDS - STATIC_ASSERT(20 <= MinimumFractionDigitsBits::kMax); - STATIC_ASSERT(20 <= MaximumFractionDigitsBits::kMax); STATIC_ASSERT(Style::DECIMAL <= StyleBits::kMax); STATIC_ASSERT(Style::PERCENT <= StyleBits::kMax); STATIC_ASSERT(Style::CURRENCY <= StyleBits::kMax); diff --git a/deps/v8/src/objects/js-objects-inl.h b/deps/v8/src/objects/js-objects-inl.h index f8fe069d3dddd7..a6b9e9ad83daf8 100644 --- a/deps/v8/src/objects/js-objects-inl.h +++ b/deps/v8/src/objects/js-objects-inl.h @@ -31,16 +31,19 @@ namespace internal { OBJECT_CONSTRUCTORS_IMPL(JSReceiver, HeapObject) TQ_OBJECT_CONSTRUCTORS_IMPL(JSObject) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSCustomElementsObject) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSSpecialObject) TQ_OBJECT_CONSTRUCTORS_IMPL(JSAsyncFromSyncIterator) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSFunctionOrBoundFunction) TQ_OBJECT_CONSTRUCTORS_IMPL(JSBoundFunction) TQ_OBJECT_CONSTRUCTORS_IMPL(JSDate) -OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSObject) -OBJECT_CONSTRUCTORS_IMPL(JSGlobalObject, JSObject) +OBJECT_CONSTRUCTORS_IMPL(JSFunction, JSFunctionOrBoundFunction) +OBJECT_CONSTRUCTORS_IMPL(JSGlobalObject, JSSpecialObject) TQ_OBJECT_CONSTRUCTORS_IMPL(JSGlobalProxy) JSIteratorResult::JSIteratorResult(Address ptr) : JSObject(ptr) {} OBJECT_CONSTRUCTORS_IMPL(JSMessageObject, JSObject) TQ_OBJECT_CONSTRUCTORS_IMPL(JSPrimitiveWrapper) -OBJECT_CONSTRUCTORS_IMPL(JSStringIterator, JSObject) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSStringIterator) NEVER_READ_ONLY_SPACE_IMPL(JSReceiver) @@ -49,7 +52,6 @@ CAST_ACCESSOR(JSGlobalObject) CAST_ACCESSOR(JSIteratorResult) CAST_ACCESSOR(JSMessageObject) CAST_ACCESSOR(JSReceiver) -CAST_ACCESSOR(JSStringIterator) MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate, Handle<JSReceiver> receiver, @@ -375,7 +377,7 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object value) { } } -void JSObject::WriteToField(int descriptor, PropertyDetails details, +void JSObject::WriteToField(InternalIndex descriptor, PropertyDetails details, Object value) { DCHECK_EQ(kField, details.location()); DCHECK_EQ(kData, details.kind()); @@ -540,7 +542,9 @@ Code JSFunction::code() const { void JSFunction::set_code(Code value) { DCHECK(!ObjectInYoungGeneration(value)); RELAXED_WRITE_FIELD(*this, kCodeOffset, value); +#ifndef V8_DISABLE_WRITE_BARRIERS MarkingBarrier(*this, RawField(kCodeOffset), value); +#endif } void JSFunction::set_code_no_write_barrier(Code value) { @@ -1007,8 +1011,7 @@ inline int JSGlobalProxy::SizeWithEmbedderFields(int embedder_field_count) { ACCESSORS(JSIteratorResult, value, Object, kValueOffset) ACCESSORS(JSIteratorResult, done, Object, kDoneOffset) -ACCESSORS(JSStringIterator, string, String, kStringOffset) -SMI_ACCESSORS(JSStringIterator, index, kNextIndexOffset) +TQ_SMI_ACCESSORS(JSStringIterator, index) // If the fast-case backing storage takes up much more memory than a dictionary // backing storage would, the object should have slow elements. diff --git a/deps/v8/src/objects/js-objects.cc b/deps/v8/src/objects/js-objects.cc index 3666f5afbe2dc0..ea0917f18feb10 100644 --- a/deps/v8/src/objects/js-objects.cc +++ b/deps/v8/src/objects/js-objects.cc @@ -216,15 +216,19 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign( } Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); - int length = map->NumberOfOwnDescriptors(); bool stable = true; - for (int i = 0; i < length; i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { + HandleScope inner_scope(isolate); + Handle<Name> next_key(descriptors->GetKey(i), isolate); Handle<Object> prop_value; // Directly decode from the descriptor array if |from| did not change shape. if (stable) { + DCHECK_EQ(from->map(), *map); + DCHECK_EQ(*descriptors, map->instance_descriptors()); + PropertyDetails details = descriptors->GetDetails(i); if (!details.IsEnumerable()) continue; if (details.kind() == kData) { @@ -232,7 +236,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign( prop_value = handle(descriptors->GetStrongValue(i), isolate); } else { Representation representation = details.representation(); - FieldIndex index = FieldIndex::ForDescriptor(*map, i); + FieldIndex index = FieldIndex::ForPropertyIndex( + *map, details.field_index(), representation); prop_value = JSObject::FastPropertyAt(from, representation, index); } } else { @@ -240,6 +245,7 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign( isolate, prop_value, JSReceiver::GetProperty(isolate, from, next_key), Nothing<bool>()); stable = from->map() == *map; + *descriptors.location() = map->instance_descriptors().ptr(); } } else { // If the map did change, do a slower lookup. We are still guaranteed that @@ -260,7 +266,10 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign( Object::SetProperty(&it, prop_value, StoreOrigin::kNamed, Just(ShouldThrow::kThrowOnError)); if (result.IsNothing()) return result; - if (stable) stable = from->map() == *map; + if (stable) { + stable = from->map() == *map; + *descriptors.location() = map->instance_descriptors().ptr(); + } } else { if (excluded_properties != nullptr && HasExcludedProperty(excluded_properties, next_key)) { @@ -1094,8 +1103,7 @@ Maybe<bool> SetPropertyWithInterceptorInternal( Maybe<bool> DefinePropertyWithInterceptorInternal( LookupIterator* it, Handle<InterceptorInfo> interceptor, - Maybe<ShouldThrow> should_throw, - PropertyDescriptor& desc) { // NOLINT(runtime/references) + Maybe<ShouldThrow> should_throw, PropertyDescriptor* desc) { Isolate* isolate = it->isolate(); // Make sure that the top context does not change when doing callbacks or // interceptor calls. @@ -1116,23 +1124,23 @@ Maybe<bool> DefinePropertyWithInterceptorInternal( std::unique_ptr<v8::PropertyDescriptor> descriptor( new v8::PropertyDescriptor()); - if (PropertyDescriptor::IsAccessorDescriptor(&desc)) { + if (PropertyDescriptor::IsAccessorDescriptor(desc)) { descriptor.reset(new v8::PropertyDescriptor( - v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set()))); - } else if (PropertyDescriptor::IsDataDescriptor(&desc)) { - if (desc.has_writable()) { + v8::Utils::ToLocal(desc->get()), v8::Utils::ToLocal(desc->set()))); + } else if (PropertyDescriptor::IsDataDescriptor(desc)) { + if (desc->has_writable()) { descriptor.reset(new v8::PropertyDescriptor( - v8::Utils::ToLocal(desc.value()), desc.writable())); + v8::Utils::ToLocal(desc->value()), desc->writable())); } else { descriptor.reset( - new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value()))); + new v8::PropertyDescriptor(v8::Utils::ToLocal(desc->value()))); } } - if (desc.has_enumerable()) { - descriptor->set_enumerable(desc.enumerable()); + if (desc->has_enumerable()) { + descriptor->set_enumerable(desc->enumerable()); } - if (desc.has_configurable()) { - descriptor->set_configurable(desc.configurable()); + if (desc->has_configurable()) { + descriptor->set_configurable(desc->configurable()); } if (it->IsElement()) { @@ -1166,7 +1174,7 @@ Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty( if (it->state() == LookupIterator::INTERCEPTOR) { if (it->HolderIsReceiverOrHiddenPrototype()) { Maybe<bool> result = DefinePropertyWithInterceptorInternal( - it, it->GetInterceptor(), should_throw, *desc); + it, it->GetInterceptor(), should_throw, desc); if (result.IsNothing() || result.FromJust()) { return result; } @@ -1834,8 +1842,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries( if (!map->OnlyHasSimpleProperties()) return Just(false); Handle<JSObject> object(JSObject::cast(*receiver), isolate); - Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate); + int number_of_own_descriptors = map->NumberOfOwnDescriptors(); int number_of_own_elements = object->GetElementsAccessor()->GetCapacity(*object, object->elements()); @@ -1857,15 +1865,25 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries( Nothing<bool>()); } - bool stable = object->map() == *map; + // We may have already lost stability, if CollectValuesOrEntries had + // side-effects. + bool stable = *map == object->map(); + if (stable) { + *descriptors.location() = map->instance_descriptors().ptr(); + } + + for (InternalIndex index : InternalIndex::Range(number_of_own_descriptors)) { + HandleScope inner_scope(isolate); - for (int index = 0; index < number_of_own_descriptors; index++) { Handle<Name> next_key(descriptors->GetKey(index), isolate); if (!next_key->IsString()) continue; Handle<Object> prop_value; // Directly decode from the descriptor array if |from| did not change shape. if (stable) { + DCHECK_EQ(object->map(), *map); + DCHECK_EQ(*descriptors, map->instance_descriptors()); + PropertyDetails details = descriptors->GetDetails(index); if (!details.IsEnumerable()) continue; if (details.kind() == kData) { @@ -1873,7 +1891,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries( prop_value = handle(descriptors->GetStrongValue(index), isolate); } else { Representation representation = details.representation(); - FieldIndex field_index = FieldIndex::ForDescriptor(*map, index); + FieldIndex field_index = FieldIndex::ForPropertyIndex( + *map, details.field_index(), representation); prop_value = JSObject::FastPropertyAt(object, representation, field_index); } @@ -1883,6 +1902,7 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries( JSReceiver::GetProperty(isolate, object, next_key), Nothing<bool>()); stable = object->map() == *map; + *descriptors.location() = map->instance_descriptors().ptr(); } } else { // If the map did change, do a slower lookup. We are still guaranteed that @@ -2121,15 +2141,15 @@ int JSObject::GetHeaderSize(InstanceType type, return JSWeakSet::kSize; case JS_PROMISE_TYPE: return JSPromise::kSize; - case JS_REGEXP_TYPE: + case JS_REG_EXP_TYPE: return JSRegExp::kSize; - case JS_REGEXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: return JSRegExpStringIterator::kSize; case JS_CONTEXT_EXTENSION_OBJECT_TYPE: return JSObject::kHeaderSize; case JS_MESSAGE_OBJECT_TYPE: return JSMessageObject::kSize; - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: return JSObject::kHeaderSize; case JS_ERROR_TYPE: return JSObject::kHeaderSize; @@ -2138,38 +2158,38 @@ int JSObject::GetHeaderSize(InstanceType type, case JS_MODULE_NAMESPACE_TYPE: return JSModuleNamespace::kHeaderSize; #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: return JSV8BreakIterator::kSize; - case JS_INTL_COLLATOR_TYPE: + case JS_COLLATOR_TYPE: return JSCollator::kSize; - case JS_INTL_DATE_TIME_FORMAT_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: return JSDateTimeFormat::kSize; - case JS_INTL_LIST_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: return JSListFormat::kSize; - case JS_INTL_LOCALE_TYPE: + case JS_LOCALE_TYPE: return JSLocale::kSize; - case JS_INTL_NUMBER_FORMAT_TYPE: + case JS_NUMBER_FORMAT_TYPE: return JSNumberFormat::kSize; - case JS_INTL_PLURAL_RULES_TYPE: + case JS_PLURAL_RULES_TYPE: return JSPluralRules::kSize; - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: return JSRelativeTimeFormat::kSize; - case JS_INTL_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: return JSSegmentIterator::kSize; - case JS_INTL_SEGMENTER_TYPE: + case JS_SEGMENTER_TYPE: return JSSegmenter::kSize; #endif // V8_INTL_SUPPORT - case WASM_GLOBAL_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: return WasmGlobalObject::kSize; - case WASM_INSTANCE_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: return WasmInstanceObject::kSize; - case WASM_MEMORY_TYPE: + case WASM_MEMORY_OBJECT_TYPE: return WasmMemoryObject::kSize; - case WASM_MODULE_TYPE: + case WASM_MODULE_OBJECT_TYPE: return WasmModuleObject::kSize; - case WASM_TABLE_TYPE: + case WASM_TABLE_OBJECT_TYPE: return WasmTableObject::kSize; - case WASM_EXCEPTION_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: return WasmExceptionObject::kSize; default: UNREACHABLE(); @@ -2377,7 +2397,7 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) { accumulator->Add("<JSWeakSet>"); break; } - case JS_REGEXP_TYPE: { + case JS_REG_EXP_TYPE: { accumulator->Add("<JSRegExp"); JSRegExp regexp = JSRegExp::cast(*this); if (regexp.source().IsString()) { @@ -2506,7 +2526,7 @@ void JSObject::PrintInstanceMigration(FILE* file, Map original_map, PrintF(file, "[migrating]"); DescriptorArray o = original_map.instance_descriptors(); DescriptorArray n = new_map.instance_descriptors(); - for (int i = 0; i < original_map.NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : original_map.IterateOwnDescriptors()) { Representation o_r = o.GetDetails(i).representation(); Representation n_r = n.GetDetails(i).representation(); if (!o_r.Equals(n_r)) { @@ -2703,7 +2723,7 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, // number of properties. DCHECK(old_nof <= new_nof); - for (int i = 0; i < old_nof; i++) { + for (InternalIndex i : InternalIndex::Range(old_nof)) { PropertyDetails details = new_descriptors->GetDetails(i); if (details.location() != kField) continue; DCHECK_EQ(kData, details.kind()); @@ -2753,7 +2773,7 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, } } - for (int i = old_nof; i < new_nof; i++) { + for (InternalIndex i : InternalIndex::Range(old_nof, new_nof)) { PropertyDetails details = new_descriptors->GetDetails(i); if (details.location() != kField) continue; DCHECK_EQ(kData, details.kind()); @@ -2776,9 +2796,10 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, Heap* heap = isolate->heap(); - int old_instance_size = old_map->instance_size(); - - heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation); + // Invalidate slots manually later in case of tagged to untagged translation. + // In all other cases the recorded slot remains dereferenceable. + heap->NotifyObjectLayoutChange(*object, no_allocation, + InvalidateRecordedSlots::kNo); // Copy (real) inobject properties. If necessary, stop at number_of_fields to // avoid overwriting |one_pointer_filler_map|. @@ -2795,7 +2816,8 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, index, HeapNumber::cast(value).value_as_bits()); if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) { // Transition from tagged to untagged slot. - heap->ClearRecordedSlot(*object, object->RawField(index.offset())); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(*object); + chunk->InvalidateRecordedSlots(*object); } else { #ifdef DEBUG heap->VerifyClearedSlot(*object, object->RawField(index.offset())); @@ -2809,6 +2831,7 @@ void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object, object->SetProperties(*array); // Create filler object past the new instance size. + int old_instance_size = old_map->instance_size(); int new_instance_size = new_map->instance_size(); int instance_size_delta = old_instance_size - new_instance_size; DCHECK_GE(instance_size_delta, 0); @@ -2851,7 +2874,7 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object, NameDictionary::New(isolate, property_count); Handle<DescriptorArray> descs(map->instance_descriptors(isolate), isolate); - for (int i = 0; i < real_size; i++) { + for (InternalIndex i : InternalIndex::Range(real_size)) { PropertyDetails details = descs->GetDetails(i); Handle<Name> key(descs->GetKey(isolate, i), isolate); Handle<Object> value; @@ -2891,10 +2914,15 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object, DisallowHeapAllocation no_allocation; Heap* heap = isolate->heap(); - int old_instance_size = map->instance_size(); - heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation); + + // Invalidate slots manually later in case the new map has in-object + // properties. If not, it is not possible to store an untagged value + // in a recorded slot. + heap->NotifyObjectLayoutChange(*object, no_allocation, + InvalidateRecordedSlots::kNo); // Resize the object in the heap if necessary. + int old_instance_size = map->instance_size(); int new_instance_size = new_map->instance_size(); int instance_size_delta = old_instance_size - new_instance_size; DCHECK_GE(instance_size_delta, 0); @@ -2914,10 +2942,8 @@ void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object, // garbage. int inobject_properties = new_map->GetInObjectProperties(); if (inobject_properties) { - Heap* heap = isolate->heap(); - heap->ClearRecordedSlotRange( - object->address() + map->GetInObjectPropertyOffset(0), - object->address() + new_instance_size); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(*object); + chunk->InvalidateRecordedSlots(*object); for (int i = 0; i < inobject_properties; i++) { FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); @@ -3047,7 +3073,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external); - for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { PropertyDetails details = descriptors->GetDetails(i); Representation representation = details.representation(); if (!representation.IsDouble()) continue; @@ -3344,8 +3370,8 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object, } // Allocate the instance descriptor. - Handle<DescriptorArray> descriptors = DescriptorArray::Allocate( - isolate, instance_descriptor_length, 0, AllocationType::kOld); + Handle<DescriptorArray> descriptors = + DescriptorArray::Allocate(isolate, instance_descriptor_length, 0); int number_of_allocated_fields = number_of_fields + unused_property_fields - inobject_props; @@ -3410,7 +3436,7 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object, } current_offset += details.field_width_in_words(); } - descriptors->Set(i, &d); + descriptors->Set(InternalIndex(i), &d); } DCHECK(current_offset == number_of_fields); @@ -3441,6 +3467,8 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object, } void JSObject::RequireSlowElements(NumberDictionary dictionary) { + DCHECK_NE(dictionary, + ReadOnlyRoots(GetIsolate()).empty_slow_element_dictionary()); if (dictionary.requires_slow_elements()) return; dictionary.set_requires_slow_elements(); if (map().is_prototype_map()) { @@ -3603,8 +3631,7 @@ bool TestFastPropertiesIntegrityLevel(Map map, PropertyAttributes level) { DCHECK(!map.is_dictionary_map()); DescriptorArray descriptors = map.instance_descriptors(); - int number_of_own_descriptors = map.NumberOfOwnDescriptors(); - for (int i = 0; i < number_of_own_descriptors; i++) { + for (InternalIndex i : map.IterateOwnDescriptors()) { if (descriptors.GetKey(i).IsPrivate()) continue; PropertyDetails details = descriptors.GetDetails(i); if (details.IsConfigurable()) return false; @@ -3709,7 +3736,9 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, object->HasSlowArgumentsElements()); // Make sure that we never go back to fast case. - object->RequireSlowElements(*dictionary); + if (*dictionary != ReadOnlyRoots(isolate).empty_slow_element_dictionary()) { + object->RequireSlowElements(*dictionary); + } } // Do a map transition, other objects with this map may still @@ -4136,10 +4165,9 @@ MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object, Object JSObject::SlowReverseLookup(Object value) { if (HasFastProperties()) { - int number_of_own_descriptors = map().NumberOfOwnDescriptors(); DescriptorArray descs = map().instance_descriptors(); bool value_is_number = value.IsNumber(); - for (int i = 0; i < number_of_own_descriptors; i++) { + for (InternalIndex i : map().IterateOwnDescriptors()) { PropertyDetails details = descs.GetDetails(i); if (details.location() == kField) { DCHECK_EQ(kData, details.kind()); @@ -5187,16 +5215,16 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) { case JS_FUNCTION_TYPE: case JS_GENERATOR_OBJECT_TYPE: #ifdef V8_INTL_SUPPORT - case JS_INTL_COLLATOR_TYPE: - case JS_INTL_DATE_TIME_FORMAT_TYPE: - case JS_INTL_LIST_FORMAT_TYPE: - case JS_INTL_LOCALE_TYPE: - case JS_INTL_NUMBER_FORMAT_TYPE: - case JS_INTL_PLURAL_RULES_TYPE: - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: - case JS_INTL_SEGMENT_ITERATOR_TYPE: - case JS_INTL_SEGMENTER_TYPE: - case JS_INTL_V8_BREAK_ITERATOR_TYPE: + case JS_COLLATOR_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: + case JS_LOCALE_TYPE: + case JS_NUMBER_FORMAT_TYPE: + case JS_PLURAL_RULES_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENTER_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: #endif case JS_ASYNC_FUNCTION_OBJECT_TYPE: case JS_ASYNC_GENERATOR_OBJECT_TYPE: @@ -5205,9 +5233,9 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) { case JS_OBJECT_TYPE: case JS_ERROR_TYPE: case JS_FINALIZATION_GROUP_TYPE: - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: case JS_PROMISE_TYPE: - case JS_REGEXP_TYPE: + case JS_REG_EXP_TYPE: case JS_SET_TYPE: case JS_SPECIAL_API_OBJECT_TYPE: case JS_TYPED_ARRAY_TYPE: @@ -5215,11 +5243,11 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) { case JS_WEAK_MAP_TYPE: case JS_WEAK_REF_TYPE: case JS_WEAK_SET_TYPE: - case WASM_GLOBAL_TYPE: - case WASM_INSTANCE_TYPE: - case WASM_MEMORY_TYPE: - case WASM_MODULE_TYPE: - case WASM_TABLE_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: + case WASM_MEMORY_OBJECT_TYPE: + case WASM_MODULE_OBJECT_TYPE: + case WASM_TABLE_OBJECT_TYPE: return true; case BIGINT_TYPE: diff --git a/deps/v8/src/objects/js-objects.h b/deps/v8/src/objects/js-objects.h index a9510642f1bf61..f38cbe16e69fea 100644 --- a/deps/v8/src/objects/js-objects.h +++ b/deps/v8/src/objects/js-objects.h @@ -6,6 +6,8 @@ #define V8_OBJECTS_JS_OBJECTS_H_ #include "src/objects/embedder-data-slot.h" +// TODO(jkummerow): Consider forward-declaring instead. +#include "src/objects/internal-index.h" #include "src/objects/objects.h" #include "src/objects/property-array.h" #include "torque-generated/class-definitions-tq.h" @@ -264,7 +266,7 @@ class JSReceiver : public HeapObject { static const int kHashMask = PropertyArray::HashField::kMask; DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_JSRECEIVER_FIELDS) + TORQUE_GENERATED_JS_RECEIVER_FIELDS) bool HasProxyInPrototype(Isolate* isolate); V8_WARN_UNUSED_RESULT static MaybeHandle<FixedArray> GetPrivateEntries( @@ -631,7 +633,7 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> { FieldIndex index, Object value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); inline void RawFastDoublePropertyAsBitsAtPut(FieldIndex index, uint64_t bits); - inline void WriteToField(int descriptor, PropertyDetails details, + inline void WriteToField(InternalIndex descriptor, PropertyDetails details, Object value); // Access to in object properties. @@ -806,6 +808,29 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> { TQ_OBJECT_CONSTRUCTORS(JSObject) }; +// An abstract superclass for JSObjects that may have elements while having an +// empty fixed array as elements backing store. It doesn't carry any +// functionality but allows function classes to be identified in the type +// system. +class JSCustomElementsObject + : public TorqueGeneratedJSCustomElementsObject<JSCustomElementsObject, + JSObject> { + public: + STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); + TQ_OBJECT_CONSTRUCTORS(JSCustomElementsObject) +}; + +// An abstract superclass for JSObjects that require non-standard element +// access. It doesn't carry any functionality but allows function classes to be +// identified in the type system. +class JSSpecialObject + : public TorqueGeneratedJSSpecialObject<JSSpecialObject, + JSCustomElementsObject> { + public: + STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); + TQ_OBJECT_CONSTRUCTORS(JSSpecialObject) +}; + // JSAccessorPropertyDescriptor is just a JSObject with a specific initial // map. This initial map adds in-object properties for "get", "set", // "enumerable" and "configurable" properties, as assigned by the @@ -893,9 +918,21 @@ class JSIteratorResult : public JSObject { OBJECT_CONSTRUCTORS(JSIteratorResult, JSObject); }; +// An abstract superclass for classes representing JavaScript function values. +// It doesn't carry any functionality but allows function classes to be +// identified in the type system. +class JSFunctionOrBoundFunction + : public TorqueGeneratedJSFunctionOrBoundFunction<JSFunctionOrBoundFunction, + JSObject> { + public: + STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize); + TQ_OBJECT_CONSTRUCTORS(JSFunctionOrBoundFunction) +}; + // JSBoundFunction describes a bound function exotic object. class JSBoundFunction - : public TorqueGeneratedJSBoundFunction<JSBoundFunction, JSObject> { + : public TorqueGeneratedJSBoundFunction<JSBoundFunction, + JSFunctionOrBoundFunction> { public: static MaybeHandle<String> GetName(Isolate* isolate, Handle<JSBoundFunction> function); @@ -916,7 +953,7 @@ class JSBoundFunction }; // JSFunction describes JavaScript functions. -class JSFunction : public JSObject { +class JSFunction : public JSFunctionOrBoundFunction { public: // [prototype_or_initial_map]: DECL_ACCESSORS(prototype_or_initial_map, HeapObject) @@ -1119,13 +1156,13 @@ class JSFunction : public JSObject { // ES6 section 19.2.3.5 Function.prototype.toString ( ). static Handle<String> ToString(Handle<JSFunction> function); - DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSFUNCTION_FIELDS) + DEFINE_FIELD_OFFSET_CONSTANTS(JSFunctionOrBoundFunction::kHeaderSize, + TORQUE_GENERATED_JS_FUNCTION_FIELDS) static constexpr int kSizeWithoutPrototype = kPrototypeOrInitialMapOffset; static constexpr int kSizeWithPrototype = kSize; - OBJECT_CONSTRUCTORS(JSFunction, JSObject); + OBJECT_CONSTRUCTORS(JSFunction, JSFunctionOrBoundFunction); }; // JSGlobalProxy's prototype must be a JSGlobalObject or null, @@ -1137,7 +1174,7 @@ class JSFunction : public JSObject { // Accessing a JSGlobalProxy requires security check. class JSGlobalProxy - : public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSObject> { + : public TorqueGeneratedJSGlobalProxy<JSGlobalProxy, JSSpecialObject> { public: inline bool IsDetachedFrom(JSGlobalObject global) const; @@ -1151,7 +1188,7 @@ class JSGlobalProxy }; // JavaScript global object. -class JSGlobalObject : public JSObject { +class JSGlobalObject : public JSSpecialObject { public: // [native context]: the natives corresponding to this global object. DECL_ACCESSORS(native_context, NativeContext) @@ -1179,15 +1216,16 @@ class JSGlobalObject : public JSObject { DECL_VERIFIER(JSGlobalObject) // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSGLOBAL_OBJECT_FIELDS) + DEFINE_FIELD_OFFSET_CONSTANTS(JSSpecialObject::kHeaderSize, + TORQUE_GENERATED_JS_GLOBAL_OBJECT_FIELDS) - OBJECT_CONSTRUCTORS(JSGlobalObject, JSObject); + OBJECT_CONSTRUCTORS(JSGlobalObject, JSSpecialObject); }; // Representation for JS Wrapper objects, String, Number, Boolean, etc. class JSPrimitiveWrapper - : public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper, JSObject> { + : public TorqueGeneratedJSPrimitiveWrapper<JSPrimitiveWrapper, + JSCustomElementsObject> { public: // Dispatched behavior. DECL_PRINTER(JSPrimitiveWrapper) @@ -1319,7 +1357,7 @@ class JSMessageObject : public JSObject { DECL_VERIFIER(JSMessageObject) DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSMESSAGE_OBJECT_FIELDS) + TORQUE_GENERATED_JS_MESSAGE_OBJECT_FIELDS) // TODO(v8:8989): [torque] Support marker constants. static const int kPointerFieldsEndOffset = kStartPositionOffset; @@ -1370,25 +1408,18 @@ class JSAsyncFromSyncIterator TQ_OBJECT_CONSTRUCTORS(JSAsyncFromSyncIterator) }; -class JSStringIterator : public JSObject { +class JSStringIterator + : public TorqueGeneratedJSStringIterator<JSStringIterator, JSObject> { public: // Dispatched behavior. DECL_PRINTER(JSStringIterator) DECL_VERIFIER(JSStringIterator) - DECL_CAST(JSStringIterator) - - // [string]: the [[IteratedString]] inobject property. - DECL_ACCESSORS(string, String) - // [index]: The [[StringIteratorNextIndex]] inobject property. inline int index() const; inline void set_index(int value); - DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSSTRING_ITERATOR_FIELDS) - - OBJECT_CONSTRUCTORS(JSStringIterator, JSObject); + TQ_OBJECT_CONSTRUCTORS(JSStringIterator) }; } // namespace internal diff --git a/deps/v8/src/objects/js-plural-rules.cc b/deps/v8/src/objects/js-plural-rules.cc index 84fe9b6d52a7f5..bf928416f41809 100644 --- a/deps/v8/src/objects/js-plural-rules.cc +++ b/deps/v8/src/objects/js-plural-rules.cc @@ -241,17 +241,18 @@ Handle<JSObject> JSPluralRules::ResolvedOptions( JSNumberFormat::MinimumIntegerDigitsFromSkeleton(skeleton), "minimumIntegerDigits"); int32_t min = 0, max = 0; - JSNumberFormat::FractionDigitsFromSkeleton(skeleton, &min, &max); - - CreateDataPropertyForOptions(isolate, options, min, "minimumFractionDigits"); - - CreateDataPropertyForOptions(isolate, options, max, "maximumFractionDigits"); if (JSNumberFormat::SignificantDigitsFromSkeleton(skeleton, &min, &max)) { CreateDataPropertyForOptions(isolate, options, min, "minimumSignificantDigits"); CreateDataPropertyForOptions(isolate, options, max, "maximumSignificantDigits"); + } else { + JSNumberFormat::FractionDigitsFromSkeleton(skeleton, &min, &max); + CreateDataPropertyForOptions(isolate, options, min, + "minimumFractionDigits"); + CreateDataPropertyForOptions(isolate, options, max, + "maximumFractionDigits"); } // 6. Let pluralCategories be a List of Strings representing the diff --git a/deps/v8/src/objects/js-plural-rules.h b/deps/v8/src/objects/js-plural-rules.h index 840efb07ed4849..0303266894ceb5 100644 --- a/deps/v8/src/objects/js-plural-rules.h +++ b/deps/v8/src/objects/js-plural-rules.h @@ -68,7 +68,7 @@ class JSPluralRules : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSPLURAL_RULES_FIELDS) + TORQUE_GENERATED_JS_PLURAL_RULES_FIELDS) DECL_ACCESSORS(locale, String) DECL_INT_ACCESSORS(flags) diff --git a/deps/v8/src/objects/js-proxy.h b/deps/v8/src/objects/js-proxy.h index 8e29c08bc141d4..c6bb844fe57eaf 100644 --- a/deps/v8/src/objects/js-proxy.h +++ b/deps/v8/src/objects/js-proxy.h @@ -128,7 +128,7 @@ class JSProxyRevocableResult : public JSObject { public: // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS( - JSObject::kHeaderSize, TORQUE_GENERATED_JSPROXY_REVOCABLE_RESULT_FIELDS) + JSObject::kHeaderSize, TORQUE_GENERATED_JS_PROXY_REVOCABLE_RESULT_FIELDS) // Indices of in-object properties. static const int kProxyIndex = 0; diff --git a/deps/v8/src/objects/js-regexp-inl.h b/deps/v8/src/objects/js-regexp-inl.h index b69d1cca975db9..885bc4804d703c 100644 --- a/deps/v8/src/objects/js-regexp-inl.h +++ b/deps/v8/src/objects/js-regexp-inl.h @@ -7,6 +7,7 @@ #include "src/objects/js-regexp.h" +#include "src/objects/js-array-inl.h" #include "src/objects/objects-inl.h" // Needed for write barriers #include "src/objects/smi.h" #include "src/objects/string.h" @@ -18,9 +19,18 @@ namespace v8 { namespace internal { TQ_OBJECT_CONSTRUCTORS_IMPL(JSRegExp) +OBJECT_CONSTRUCTORS_IMPL(JSRegExpResult, JSArray) +OBJECT_CONSTRUCTORS_IMPL(JSRegExpResultIndices, JSArray) + +CAST_ACCESSOR(JSRegExpResult) +CAST_ACCESSOR(JSRegExpResultIndices) ACCESSORS(JSRegExp, last_index, Object, kLastIndexOffset) +ACCESSORS(JSRegExpResult, cached_indices_or_match_info, Object, + kCachedIndicesOrMatchInfoOffset) +ACCESSORS(JSRegExpResult, names, Object, kNamesOffset) + JSRegExp::Type JSRegExp::TypeTag() const { Object data = this->data(); if (data.IsUndefined()) return JSRegExp::NOT_COMPILED; diff --git a/deps/v8/src/objects/js-regexp.cc b/deps/v8/src/objects/js-regexp.cc new file mode 100644 index 00000000000000..c7f96fe278c065 --- /dev/null +++ b/deps/v8/src/objects/js-regexp.cc @@ -0,0 +1,118 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/objects/js-regexp.h" + +#include "src/objects/js-array-inl.h" +#include "src/objects/js-regexp-inl.h" + +namespace v8 { +namespace internal { +Handle<JSArray> JSRegExpResult::GetAndCacheIndices( + Isolate* isolate, Handle<JSRegExpResult> regexp_result) { + // Check for cached indices. + Handle<Object> indices_or_match_info( + regexp_result->cached_indices_or_match_info(), isolate); + if (indices_or_match_info->IsRegExpMatchInfo()) { + // Build and cache indices for next lookup. + // TODO(joshualitt): Instead of caching the indices, we could call + // ReconfigureToDataProperty on 'indices' setting its value to this + // newly created array. However, care would have to be taken to ensure + // a new map is not created each time. + Handle<RegExpMatchInfo> match_info( + RegExpMatchInfo::cast(regexp_result->cached_indices_or_match_info()), + isolate); + Handle<Object> maybe_names(regexp_result->names(), isolate); + indices_or_match_info = + JSRegExpResultIndices::BuildIndices(isolate, match_info, maybe_names); + + // Cache the result and clear the names array. + regexp_result->set_cached_indices_or_match_info(*indices_or_match_info); + regexp_result->set_names(ReadOnlyRoots(isolate).undefined_value()); + } + return Handle<JSArray>::cast(indices_or_match_info); +} + +Handle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices( + Isolate* isolate, Handle<RegExpMatchInfo> match_info, + Handle<Object> maybe_names) { + Handle<JSRegExpResultIndices> indices(Handle<JSRegExpResultIndices>::cast( + isolate->factory()->NewJSObjectFromMap( + isolate->regexp_result_indices_map()))); + + // Initialize indices length to avoid having a partially initialized object + // should GC be triggered by creating a NewFixedArray. + indices->set_length(Smi::kZero); + + // Build indices array from RegExpMatchInfo. + int num_indices = match_info->NumberOfCaptureRegisters(); + int num_results = num_indices >> 1; + Handle<FixedArray> indices_array = + isolate->factory()->NewFixedArray(num_results); + JSArray::SetContent(indices, indices_array); + + for (int i = 0; i < num_results; i++) { + int base_offset = i * 2; + int start_offset = match_info->Capture(base_offset); + int end_offset = match_info->Capture(base_offset + 1); + + // Any unmatched captures are set to undefined, otherwise we set them to a + // subarray of the indices. + if (start_offset == -1) { + indices_array->set(i, ReadOnlyRoots(isolate).undefined_value()); + } else { + Handle<FixedArray> indices_sub_array( + isolate->factory()->NewFixedArray(2)); + indices_sub_array->set(0, Smi::FromInt(start_offset)); + indices_sub_array->set(1, Smi::FromInt(end_offset)); + Handle<JSArray> indices_sub_jsarray = + isolate->factory()->NewJSArrayWithElements(indices_sub_array, + PACKED_SMI_ELEMENTS, 2); + indices_array->set(i, *indices_sub_jsarray); + } + } + + // If there are no capture groups, set the groups property to undefined. + FieldIndex groups_index = FieldIndex::ForDescriptor( + indices->map(), InternalIndex(kGroupsDescriptorIndex)); + if (maybe_names->IsUndefined(isolate)) { + indices->RawFastPropertyAtPut(groups_index, + ReadOnlyRoots(isolate).undefined_value()); + return indices; + } + + // Create a groups property which returns a dictionary of named captures to + // their corresponding capture indices. + Handle<FixedArray> names(Handle<FixedArray>::cast(maybe_names)); + int num_names = names->length() >> 1; + Handle<NameDictionary> group_names = NameDictionary::New(isolate, num_names); + for (int i = 0; i < num_names; i++) { + int base_offset = i * 2; + int name_offset = base_offset; + int index_offset = base_offset + 1; + Handle<String> name(String::cast(names->get(name_offset)), isolate); + Handle<Smi> smi_index(Smi::cast(names->get(index_offset)), isolate); + Handle<Object> capture_indices(indices_array->get(smi_index->value()), + isolate); + if (!capture_indices->IsUndefined(isolate)) { + capture_indices = Handle<JSArray>::cast(capture_indices); + } + group_names = NameDictionary::Add( + isolate, group_names, name, capture_indices, PropertyDetails::Empty()); + } + + // Convert group_names to a JSObject and store at the groups property of the + // result indices. + Handle<FixedArrayBase> elements = isolate->factory()->empty_fixed_array(); + Handle<HeapObject> null = + Handle<HeapObject>::cast(isolate->factory()->null_value()); + Handle<JSObject> js_group_names = + isolate->factory()->NewSlowJSObjectWithPropertiesAndElements( + null, group_names, elements); + indices->RawFastPropertyAtPut(groups_index, *js_group_names); + return indices; +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/objects/js-regexp.h b/deps/v8/src/objects/js-regexp.h index b3ef06bd5cbd53..03efd4913c0b53 100644 --- a/deps/v8/src/objects/js-regexp.h +++ b/deps/v8/src/objects/js-regexp.h @@ -96,7 +96,8 @@ class JSRegExp : public TorqueGeneratedJSRegExp<JSRegExp, JSObject> { Handle<String> flags_string); bool MarkedForTierUp(); - void ResetTierUp(); + void ResetLastTierUpTick(); + void TierUpTick(); void MarkTierUpForNextExec(); inline Type TypeTag() const; @@ -176,9 +177,13 @@ class JSRegExp : public TorqueGeneratedJSRegExp<JSRegExp, JSObject> { // Maps names of named capture groups (at indices 2i) to their corresponding // (1-based) capture group indices (at indices 2i + 1). static const int kIrregexpCaptureNameMapIndex = kDataIndex + 6; - static const int kIrregexpTierUpTicksIndex = kDataIndex + 7; + // Tier-up ticks are set to the value of the tier-up ticks flag. The value is + // decremented on each execution of the bytecode, so that the tier-up + // happens once the ticks reach zero. + // This value is ignored if the regexp-tier-up flag isn't turned on. + static const int kIrregexpTicksUntilTierUpIndex = kDataIndex + 7; - static const int kIrregexpDataSize = kIrregexpTierUpTicksIndex + 1; + static const int kIrregexpDataSize = kIrregexpTicksUntilTierUpIndex + 1; // In-object fields. static const int kLastIndexFieldIndex = 0; @@ -195,6 +200,10 @@ class JSRegExp : public TorqueGeneratedJSRegExp<JSRegExp, JSObject> { // The uninitialized value for a regexp code object. static const int kUninitializedValue = -1; + // The heuristic value for the length of the subject string for which we + // tier-up to the compiler immediately, instead of using the interpreter. + static constexpr int kTierUpForSubjectLengthValue = 1000; + TQ_OBJECT_CONSTRUCTORS(JSRegExp) }; @@ -208,18 +217,63 @@ DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags) // After creation the result must be treated as a JSArray in all regards. class JSRegExpResult : public JSArray { public: + DECL_CAST(JSRegExpResult) + + // TODO(joshualitt): We would like to add printers and verifiers to + // JSRegExpResult, and maybe JSRegExpResultIndices, but both have the same + // instance type as JSArray. + + // cached_indices_or_match_info and names, are used to construct the + // JSRegExpResultIndices returned from the indices property lazily. + DECL_ACCESSORS(cached_indices_or_match_info, Object) + DECL_ACCESSORS(names, Object) + // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSArray::kSize, - TORQUE_GENERATED_JSREG_EXP_RESULT_FIELDS) + TORQUE_GENERATED_JS_REG_EXP_RESULT_FIELDS) + + static Handle<JSArray> GetAndCacheIndices( + Isolate* isolate, Handle<JSRegExpResult> regexp_result); // Indices of in-object properties. static const int kIndexIndex = 0; static const int kInputIndex = 1; static const int kGroupsIndex = 2; - static const int kInObjectPropertyCount = 3; - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(JSRegExpResult); + // Private internal only fields. + static const int kCachedIndicesOrMatchInfoIndex = 3; + static const int kNamesIndex = 4; + static const int kInObjectPropertyCount = 5; + + OBJECT_CONSTRUCTORS(JSRegExpResult, JSArray); +}; + +// JSRegExpResultIndices is just a JSArray with a specific initial map. +// This initial map adds in-object properties for "group" +// properties, as assigned by RegExp.prototype.exec, which allows +// faster creation of RegExp exec results. +// This class just holds constants used when creating the result. +// After creation the result must be treated as a JSArray in all regards. +class JSRegExpResultIndices : public JSArray { + public: + DECL_CAST(JSRegExpResultIndices) + + // Layout description. + DEFINE_FIELD_OFFSET_CONSTANTS( + JSArray::kSize, TORQUE_GENERATED_JS_REG_EXP_RESULT_INDICES_FIELDS) + + static Handle<JSRegExpResultIndices> BuildIndices( + Isolate* isolate, Handle<RegExpMatchInfo> match_info, + Handle<Object> maybe_names); + + // Indices of in-object properties. + static const int kGroupsIndex = 0; + static const int kInObjectPropertyCount = 1; + + // Descriptor index of groups. + static const int kGroupsDescriptorIndex = 1; + + OBJECT_CONSTRUCTORS(JSRegExpResultIndices, JSArray); }; } // namespace internal diff --git a/deps/v8/src/objects/js-relative-time-format.cc b/deps/v8/src/objects/js-relative-time-format.cc index 28f8c757ee1c6d..edf3e26c2250c3 100644 --- a/deps/v8/src/objects/js-relative-time-format.cc +++ b/deps/v8/src/objects/js-relative-time-format.cc @@ -112,7 +112,8 @@ MaybeHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New( // 14. Let dataLocale be r.[[DataLocale]]. icu::Locale icu_locale = r.icu_locale; UErrorCode status = U_ZERO_ERROR; - if (numbering_system_str != nullptr) { + if (numbering_system_str != nullptr && + Intl::IsValidNumberingSystem(numbering_system_str.get())) { icu_locale.setUnicodeKeywordValue("nu", numbering_system_str.get(), status); CHECK(U_SUCCESS(status)); } diff --git a/deps/v8/src/objects/js-relative-time-format.h b/deps/v8/src/objects/js-relative-time-format.h index 6e405e345e9e42..c642367988523c 100644 --- a/deps/v8/src/objects/js-relative-time-format.h +++ b/deps/v8/src/objects/js-relative-time-format.h @@ -107,7 +107,7 @@ class JSRelativeTimeFormat : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSRELATIVE_TIME_FORMAT_FIELDS) + TORQUE_GENERATED_JS_RELATIVE_TIME_FORMAT_FIELDS) private: static Style getStyle(const char* str); diff --git a/deps/v8/src/objects/js-segment-iterator.h b/deps/v8/src/objects/js-segment-iterator.h index cadb99e79d2ddb..1c71af886495d4 100644 --- a/deps/v8/src/objects/js-segment-iterator.h +++ b/deps/v8/src/objects/js-segment-iterator.h @@ -91,7 +91,7 @@ class JSSegmentIterator : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSSEGMENT_ITERATOR_FIELDS) + TORQUE_GENERATED_JS_SEGMENT_ITERATOR_FIELDS) OBJECT_CONSTRUCTORS(JSSegmentIterator, JSObject); }; diff --git a/deps/v8/src/objects/js-segmenter.h b/deps/v8/src/objects/js-segmenter.h index 641cf106fbd02f..209c4682b37fe1 100644 --- a/deps/v8/src/objects/js-segmenter.h +++ b/deps/v8/src/objects/js-segmenter.h @@ -78,7 +78,7 @@ class JSSegmenter : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSSEGMENTER_FIELDS) + TORQUE_GENERATED_JS_SEGMENTER_FIELDS) private: static Granularity GetGranularity(const char* str); diff --git a/deps/v8/src/objects/js-weak-refs-inl.h b/deps/v8/src/objects/js-weak-refs-inl.h index 004ffd6d791365..06351536112bd4 100644 --- a/deps/v8/src/objects/js-weak-refs-inl.h +++ b/deps/v8/src/objects/js-weak-refs-inl.h @@ -17,38 +17,21 @@ namespace v8 { namespace internal { -OBJECT_CONSTRUCTORS_IMPL(WeakCell, HeapObject) -OBJECT_CONSTRUCTORS_IMPL(JSWeakRef, JSObject) +TQ_OBJECT_CONSTRUCTORS_IMPL(WeakCell) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSWeakRef) OBJECT_CONSTRUCTORS_IMPL(JSFinalizationGroup, JSObject) -OBJECT_CONSTRUCTORS_IMPL(JSFinalizationGroupCleanupIterator, JSObject) +TQ_OBJECT_CONSTRUCTORS_IMPL(JSFinalizationGroupCleanupIterator) ACCESSORS(JSFinalizationGroup, native_context, NativeContext, kNativeContextOffset) ACCESSORS(JSFinalizationGroup, cleanup, Object, kCleanupOffset) -ACCESSORS(JSFinalizationGroup, active_cells, Object, kActiveCellsOffset) -ACCESSORS(JSFinalizationGroup, cleared_cells, Object, kClearedCellsOffset) +ACCESSORS(JSFinalizationGroup, active_cells, HeapObject, kActiveCellsOffset) +ACCESSORS(JSFinalizationGroup, cleared_cells, HeapObject, kClearedCellsOffset) ACCESSORS(JSFinalizationGroup, key_map, Object, kKeyMapOffset) SMI_ACCESSORS(JSFinalizationGroup, flags, kFlagsOffset) ACCESSORS(JSFinalizationGroup, next, Object, kNextOffset) CAST_ACCESSOR(JSFinalizationGroup) -ACCESSORS(WeakCell, finalization_group, Object, kFinalizationGroupOffset) -ACCESSORS(WeakCell, target, HeapObject, kTargetOffset) -ACCESSORS(WeakCell, holdings, Object, kHoldingsOffset) -ACCESSORS(WeakCell, next, Object, kNextOffset) -ACCESSORS(WeakCell, prev, Object, kPrevOffset) -ACCESSORS(WeakCell, key, Object, kKeyOffset) -ACCESSORS(WeakCell, key_list_next, Object, kKeyListNextOffset) -ACCESSORS(WeakCell, key_list_prev, Object, kKeyListPrevOffset) -CAST_ACCESSOR(WeakCell) - -CAST_ACCESSOR(JSWeakRef) -ACCESSORS(JSWeakRef, target, HeapObject, kTargetOffset) - -ACCESSORS(JSFinalizationGroupCleanupIterator, finalization_group, - JSFinalizationGroup, kFinalizationGroupOffset) -CAST_ACCESSOR(JSFinalizationGroupCleanupIterator) - void JSFinalizationGroup::Register( Handle<JSFinalizationGroup> finalization_group, Handle<JSReceiver> target, Handle<Object> holdings, Handle<Object> key, Isolate* isolate) { @@ -101,7 +84,7 @@ bool JSFinalizationGroup::Unregister( Handle<ObjectHashTable> key_map = handle(ObjectHashTable::cast(finalization_group->key_map()), isolate); Object value = key_map->Lookup(unregister_token); - Object undefined = ReadOnlyRoots(isolate).undefined_value(); + HeapObject undefined = ReadOnlyRoots(isolate).undefined_value(); while (value.IsWeakCell()) { WeakCell weak_cell = WeakCell::cast(value); weak_cell.RemoveFromFinalizationGroupCells(isolate); diff --git a/deps/v8/src/objects/js-weak-refs.h b/deps/v8/src/objects/js-weak-refs.h index 723e0e31358de9..8d61b125a1ffd7 100644 --- a/deps/v8/src/objects/js-weak-refs.h +++ b/deps/v8/src/objects/js-weak-refs.h @@ -28,8 +28,8 @@ class JSFinalizationGroup : public JSObject { DECL_ACCESSORS(native_context, NativeContext) DECL_ACCESSORS(cleanup, Object) - DECL_ACCESSORS(active_cells, Object) - DECL_ACCESSORS(cleared_cells, Object) + DECL_ACCESSORS(active_cells, HeapObject) + DECL_ACCESSORS(cleared_cells, HeapObject) DECL_ACCESSORS(key_map, Object) // For storing a list of JSFinalizationGroup objects in NativeContext. @@ -66,7 +66,7 @@ class JSFinalizationGroup : public JSObject { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSFINALIZATION_GROUP_FIELDS) + TORQUE_GENERATED_JS_FINALIZATION_GROUP_FIELDS) // Bitfields in flags. using ScheduledForCleanupField = BitField<bool, 0, 1>; @@ -75,32 +75,10 @@ class JSFinalizationGroup : public JSObject { }; // Internal object for storing weak references in JSFinalizationGroup. -class WeakCell : public HeapObject { +class WeakCell : public TorqueGeneratedWeakCell<WeakCell, HeapObject> { public: DECL_PRINTER(WeakCell) EXPORT_DECL_VERIFIER(WeakCell) - DECL_CAST(WeakCell) - - DECL_ACCESSORS(finalization_group, Object) - DECL_ACCESSORS(target, HeapObject) - DECL_ACCESSORS(holdings, Object) - - // For storing doubly linked lists of WeakCells in JSFinalizationGroup's - // "active_cells" and "cleared_cells" lists. - DECL_ACCESSORS(prev, Object) - DECL_ACCESSORS(next, Object) - - // For storing doubly linked lists of WeakCells per key in - // JSFinalizationGroup's key-based hashmap. WeakCell also needs to know its - // key, so that we can remove the key from the key_map when we remove the last - // WeakCell associated with it. - DECL_ACCESSORS(key, Object) - DECL_ACCESSORS(key_list_prev, Object) - DECL_ACCESSORS(key_list_next, Object) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_WEAK_CELL_FIELDS) class BodyDescriptor; @@ -115,40 +93,27 @@ class WeakCell : public HeapObject { inline void RemoveFromFinalizationGroupCells(Isolate* isolate); - OBJECT_CONSTRUCTORS(WeakCell, HeapObject); + TQ_OBJECT_CONSTRUCTORS(WeakCell) }; -class JSWeakRef : public JSObject { +class JSWeakRef : public TorqueGeneratedJSWeakRef<JSWeakRef, JSObject> { public: DECL_PRINTER(JSWeakRef) EXPORT_DECL_VERIFIER(JSWeakRef) - DECL_CAST(JSWeakRef) - - DECL_ACCESSORS(target, HeapObject) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, - TORQUE_GENERATED_JSWEAK_REF_FIELDS) class BodyDescriptor; - OBJECT_CONSTRUCTORS(JSWeakRef, JSObject); + TQ_OBJECT_CONSTRUCTORS(JSWeakRef) }; -class JSFinalizationGroupCleanupIterator : public JSObject { +class JSFinalizationGroupCleanupIterator + : public TorqueGeneratedJSFinalizationGroupCleanupIterator< + JSFinalizationGroupCleanupIterator, JSObject> { public: DECL_PRINTER(JSFinalizationGroupCleanupIterator) DECL_VERIFIER(JSFinalizationGroupCleanupIterator) - DECL_CAST(JSFinalizationGroupCleanupIterator) - - DECL_ACCESSORS(finalization_group, JSFinalizationGroup) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS( - JSObject::kHeaderSize, - TORQUE_GENERATED_JSFINALIZATION_GROUP_CLEANUP_ITERATOR_FIELDS) - OBJECT_CONSTRUCTORS(JSFinalizationGroupCleanupIterator, JSObject); + TQ_OBJECT_CONSTRUCTORS(JSFinalizationGroupCleanupIterator) }; } // namespace internal diff --git a/deps/v8/src/objects/keys.cc b/deps/v8/src/objects/keys.cc index 7496399cad42cf..0231df18d35bb8 100644 --- a/deps/v8/src/objects/keys.cc +++ b/deps/v8/src/objects/keys.cc @@ -279,9 +279,13 @@ void FastKeyAccumulator::Prepare() { is_receiver_simple_enum_ = false; has_empty_prototype_ = true; JSReceiver last_prototype; + may_have_elements_ = MayHaveElements(*receiver_); for (PrototypeIterator iter(isolate_, *receiver_); !iter.IsAtEnd(); iter.Advance()) { JSReceiver current = iter.GetCurrent<JSReceiver>(); + if (!may_have_elements_) { + may_have_elements_ = MayHaveElements(current); + } bool has_no_properties = CheckAndInitalizeEmptyEnumCache(current); if (has_no_properties) continue; last_prototype = current; @@ -338,13 +342,12 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, Handle<DescriptorArray> descriptors = Handle<DescriptorArray>(map->instance_descriptors(), isolate); isolate->counters()->enum_cache_misses()->Increment(); - int nod = map->NumberOfOwnDescriptors(); // Create the keys array. int index = 0; bool fields_only = true; keys = isolate->factory()->NewFixedArray(enum_length); - for (int i = 0; i < nod; i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { DisallowHeapAllocation no_gc; PropertyDetails details = descriptors->GetDetails(i); if (details.IsDontEnum()) continue; @@ -361,7 +364,7 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate, if (fields_only) { indices = isolate->factory()->NewFixedArray(enum_length); index = 0; - for (int i = 0; i < nod; i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { DisallowHeapAllocation no_gc; PropertyDetails details = descriptors->GetDetails(i); if (details.IsDontEnum()) continue; @@ -499,12 +502,21 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( accumulator.set_is_for_in(is_for_in_); accumulator.set_skip_indices(skip_indices_); accumulator.set_last_non_empty_prototype(last_non_empty_prototype_); + accumulator.set_may_have_elements(may_have_elements_); MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_), MaybeHandle<FixedArray>()); return accumulator.GetKeys(keys_conversion); } +bool FastKeyAccumulator::MayHaveElements(JSReceiver receiver) { + if (!receiver.IsJSObject()) return true; + JSObject object = JSObject::cast(receiver); + if (object.HasEnumerableElements()) return true; + if (object.HasIndexedInterceptor()) return true; + return false; +} + namespace { enum IndexedOrNamed { kIndexed, kNamed }; @@ -518,13 +530,14 @@ V8_WARN_UNUSED_RESULT ExceptionStatus FilterForEnumerableProperties( uint32_t length = accessor->GetCapacity(*result, result->elements()); for (uint32_t i = 0; i < length; i++) { - if (!accessor->HasEntry(*result, i)) continue; + InternalIndex entry(i); + if (!accessor->HasEntry(*result, entry)) continue; // args are invalid after args.Call(), create a new one in every iteration. PropertyCallbackArguments args(accumulator->isolate(), interceptor->data(), *receiver, *object, Just(kDontThrow)); - Handle<Object> element = accessor->Get(result, i); + Handle<Object> element = accessor->Get(result, entry); Handle<Object> attributes; if (type == kIndexed) { uint32_t number; @@ -624,7 +637,7 @@ base::Optional<int> CollectOwnPropertyNamesInternal( int first_skipped = -1; PropertyFilter filter = keys->filter(); KeyCollectionMode mode = keys->mode(); - for (int i = start_index; i < limit; i++) { + for (InternalIndex i : InternalIndex::Range(start_index, limit)) { bool is_shadowing_key = false; PropertyDetails details = descs->GetDetails(i); @@ -645,7 +658,7 @@ base::Optional<int> CollectOwnPropertyNamesInternal( Name key = descs->GetKey(i); if (skip_symbols == key.IsSymbol()) { - if (first_skipped == -1) first_skipped = i; + if (first_skipped == -1) first_skipped = i.as_int(); continue; } if (key.FilterKey(keys->filter())) continue; @@ -689,13 +702,15 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver, Map map = object->map(); int nof_descriptors = map.NumberOfOwnDescriptors(); if (enum_keys->length() != nof_descriptors) { - Handle<DescriptorArray> descs = - Handle<DescriptorArray>(map.instance_descriptors(), isolate_); - for (int i = 0; i < nof_descriptors; i++) { - PropertyDetails details = descs->GetDetails(i); - if (!details.IsDontEnum()) continue; - Object key = descs->GetKey(i); - this->AddShadowingKey(key); + if (map.prototype(isolate_) != ReadOnlyRoots(isolate_).null_value()) { + Handle<DescriptorArray> descs = + Handle<DescriptorArray>(map.instance_descriptors(), isolate_); + for (InternalIndex i : InternalIndex::Range(nof_descriptors)) { + PropertyDetails details = descs->GetDetails(i); + if (!details.IsDontEnum()) continue; + Object key = descs->GetKey(i); + this->AddShadowingKey(key); + } } } } else if (object->IsJSGlobalObject()) { @@ -823,7 +838,9 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver, return Just(true); } - MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>()); + if (may_have_elements_) { + MAYBE_RETURN(CollectOwnElementIndices(receiver, object), Nothing<bool>()); + } MAYBE_RETURN(CollectOwnPropertyNames(receiver, object), Nothing<bool>()); return Just(true); } diff --git a/deps/v8/src/objects/keys.h b/deps/v8/src/objects/keys.h index 5d8632e2a77cd5..4c2307a20b4af5 100644 --- a/deps/v8/src/objects/keys.h +++ b/deps/v8/src/objects/keys.h @@ -93,6 +93,7 @@ class KeyAccumulator final { void set_last_non_empty_prototype(Handle<JSReceiver> object) { last_non_empty_prototype_ = object; } + void set_may_have_elements(bool value) { may_have_elements_ = value; } // Shadowing keys are used to filter keys. This happens when non-enumerable // keys appear again on the prototype chain. void AddShadowingKey(Object key); @@ -125,6 +126,7 @@ class KeyAccumulator final { // For all the keys on the first receiver adding a shadowing key we can skip // the shadow check. bool skip_shadow_check_ = true; + bool may_have_elements_ = true; DISALLOW_COPY_AND_ASSIGN(KeyAccumulator); }; @@ -149,6 +151,7 @@ class FastKeyAccumulator { bool is_receiver_simple_enum() { return is_receiver_simple_enum_; } bool has_empty_prototype() { return has_empty_prototype_; } + bool may_have_elements() { return may_have_elements_; } MaybeHandle<FixedArray> GetKeys( GetKeysConversion convert = GetKeysConversion::kKeepNumbers); @@ -160,6 +163,8 @@ class FastKeyAccumulator { MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(); + bool MayHaveElements(JSReceiver receiver); + Isolate* isolate_; Handle<JSReceiver> receiver_; Handle<JSReceiver> last_non_empty_prototype_; @@ -169,6 +174,7 @@ class FastKeyAccumulator { bool skip_indices_ = false; bool is_receiver_simple_enum_ = false; bool has_empty_prototype_ = false; + bool may_have_elements_ = true; DISALLOW_COPY_AND_ASSIGN(FastKeyAccumulator); }; diff --git a/deps/v8/src/objects/layout-descriptor-inl.h b/deps/v8/src/objects/layout-descriptor-inl.h index ad0a058a92c8ca..30fe132129327f 100644 --- a/deps/v8/src/objects/layout-descriptor-inl.h +++ b/deps/v8/src/objects/layout-descriptor-inl.h @@ -169,7 +169,7 @@ int LayoutDescriptor::CalculateCapacity(Map map, DescriptorArray descriptors, } else { layout_descriptor_length = 0; - for (int i = 0; i < num_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(num_descriptors)) { PropertyDetails details = descriptors.GetDetails(i); if (!InobjectUnboxedField(inobject_properties, details)) continue; int field_index = details.field_index(); @@ -188,7 +188,7 @@ LayoutDescriptor LayoutDescriptor::Initialize( DisallowHeapAllocation no_allocation; int inobject_properties = map.GetInObjectProperties(); - for (int i = 0; i < num_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(num_descriptors)) { PropertyDetails details = descriptors.GetDetails(i); if (!InobjectUnboxedField(inobject_properties, details)) { DCHECK(details.location() != kField || diff --git a/deps/v8/src/objects/layout-descriptor.cc b/deps/v8/src/objects/layout-descriptor.cc index 76421aaf4f5b0b..2b588a58bf19e6 100644 --- a/deps/v8/src/objects/layout-descriptor.cc +++ b/deps/v8/src/objects/layout-descriptor.cc @@ -258,9 +258,8 @@ LayoutDescriptor LayoutDescriptor::Trim(Heap* heap, Map map, bool LayoutDescriptor::IsConsistentWithMap(Map map, bool check_tail) { if (FLAG_unbox_double_fields) { DescriptorArray descriptors = map.instance_descriptors(); - int nof_descriptors = map.NumberOfOwnDescriptors(); int last_field_index = 0; - for (int i = 0; i < nof_descriptors; i++) { + for (InternalIndex i : map.IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(i); if (details.location() != kField) continue; FieldIndex field_index = FieldIndex::ForDescriptor(map, i); diff --git a/deps/v8/src/objects/literal-objects.cc b/deps/v8/src/objects/literal-objects.cc index 95beb6cbdb6c6a..98c41cbfb5f49f 100644 --- a/deps/v8/src/objects/literal-objects.cc +++ b/deps/v8/src/objects/literal-objects.cc @@ -31,11 +31,11 @@ void AddToDescriptorArrayTemplate( Isolate* isolate, Handle<DescriptorArray> descriptor_array_template, Handle<Name> name, ClassBoilerplate::ValueKind value_kind, Handle<Object> value) { - int entry = descriptor_array_template->Search( + InternalIndex entry = descriptor_array_template->Search( *name, descriptor_array_template->number_of_descriptors()); // TODO(ishell): deduplicate properties at AST level, this will allow us to // avoid creation of closures that will be overwritten anyway. - if (entry == DescriptorArray::kNotFound) { + if (entry.is_not_found()) { // Entry not found, add new one. Descriptor d; if (value_kind == ClassBoilerplate::kData) { @@ -412,8 +412,8 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate( ObjectDescriptor static_desc(kMinimumClassPropertiesCount); ObjectDescriptor instance_desc(kMinimumPrototypePropertiesCount); - for (int i = 0; i < expr->properties()->length(); i++) { - ClassLiteral::Property* property = expr->properties()->at(i); + for (int i = 0; i < expr->public_members()->length(); i++) { + ClassLiteral::Property* property = expr->public_members()->at(i); ObjectDescriptor& desc = property->is_static() ? static_desc : instance_desc; if (property->is_computed_name()) { @@ -477,14 +477,8 @@ Handle<ClassBoilerplate> ClassBoilerplate::BuildClassBoilerplate( // int dynamic_argument_index = ClassBoilerplate::kFirstDynamicArgumentIndex; - for (int i = 0; i < expr->properties()->length(); i++) { - ClassLiteral::Property* property = expr->properties()->at(i); - - // Private members are not processed using the class boilerplate. - if (property->is_private()) { - continue; - } - + for (int i = 0; i < expr->public_members()->length(); i++) { + ClassLiteral::Property* property = expr->public_members()->at(i); ClassBoilerplate::ValueKind value_kind; switch (property->kind()) { case ClassLiteral::Property::METHOD: diff --git a/deps/v8/src/objects/lookup-inl.h b/deps/v8/src/objects/lookup-inl.h index 648398be5efceb..49a42e71313724 100644 --- a/deps/v8/src/objects/lookup-inl.h +++ b/deps/v8/src/objects/lookup-inl.h @@ -10,6 +10,7 @@ #include "src/handles/handles-inl.h" #include "src/heap/factory-inl.h" #include "src/objects/api-callbacks.h" +#include "src/objects/internal-index.h" #include "src/objects/map-inl.h" #include "src/objects/name-inl.h" #include "src/objects/objects-inl.h" @@ -136,11 +137,11 @@ void LookupIterator::UpdateProtector() { } } -int LookupIterator::descriptor_number() const { +InternalIndex LookupIterator::descriptor_number() const { DCHECK(!IsElement()); DCHECK(has_property_); DCHECK(holder_->HasFastProperties(isolate_)); - return number_; + return InternalIndex(number_); } int LookupIterator::dictionary_entry() const { diff --git a/deps/v8/src/objects/lookup.cc b/deps/v8/src/objects/lookup.cc index 4646b71a9ecdb1..7f626cc22332e2 100644 --- a/deps/v8/src/objects/lookup.cc +++ b/deps/v8/src/objects/lookup.cc @@ -249,10 +249,10 @@ void LookupIterator::InternalUpdateProtector() { } if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_) && - !isolate_->IsPromiseSpeciesLookupChainIntact() && + !Protectors::IsPromiseSpeciesLookupChainIntact(isolate_) && !Protectors::IsRegExpSpeciesLookupChainProtectorIntact( native_context) && - !isolate_->IsTypedArraySpeciesLookupChainIntact()) { + !Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) { return; } // Setting the constructor property could change an instance's @@species @@ -263,8 +263,8 @@ void LookupIterator::InternalUpdateProtector() { Protectors::InvalidateArraySpeciesLookupChain(isolate_); return; } else if (receiver->IsJSPromise(isolate_)) { - if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return; - isolate_->InvalidatePromiseSpeciesProtector(); + if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); return; } else if (receiver->IsJSRegExp(isolate_)) { if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( @@ -275,8 +275,8 @@ void LookupIterator::InternalUpdateProtector() { native_context); return; } else if (receiver->IsJSTypedArray(isolate_)) { - if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return; - isolate_->InvalidateTypedArraySpeciesProtector(); + if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); return; } if (receiver->map(isolate_).is_prototype_map()) { @@ -294,8 +294,8 @@ void LookupIterator::InternalUpdateProtector() { Protectors::InvalidateArraySpeciesLookupChain(isolate_); } else if (isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) { - if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return; - isolate_->InvalidatePromiseSpeciesProtector(); + if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); } else if (isolate_->IsInAnyContext(*receiver, Context::REGEXP_PROTOTYPE_INDEX)) { if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( @@ -307,8 +307,8 @@ void LookupIterator::InternalUpdateProtector() { } else if (isolate_->IsInAnyContext( receiver->map(isolate_).prototype(isolate_), Context::TYPED_ARRAY_PROTOTYPE_INDEX)) { - if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return; - isolate_->InvalidateTypedArraySpeciesProtector(); + if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); } } } else if (*name_ == roots.next_string()) { @@ -317,26 +317,26 @@ void LookupIterator::InternalUpdateProtector() { *receiver, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)) { // Setting the next property of %ArrayIteratorPrototype% also needs to // invalidate the array iterator protector. - if (!isolate_->IsArrayIteratorLookupChainIntact()) return; - isolate_->InvalidateArrayIteratorProtector(); + if (!Protectors::IsArrayIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateArrayIteratorLookupChain(isolate_); } else if (receiver->IsJSMapIterator() || isolate_->IsInAnyContext( *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) { - if (!isolate_->IsMapIteratorLookupChainIntact()) return; - isolate_->InvalidateMapIteratorProtector(); + if (!Protectors::IsMapIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateMapIteratorLookupChain(isolate_); } else if (receiver->IsJSSetIterator() || isolate_->IsInAnyContext( *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX)) { - if (!isolate_->IsSetIteratorLookupChainIntact()) return; - isolate_->InvalidateSetIteratorProtector(); + if (!Protectors::IsSetIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateSetIteratorLookupChain(isolate_); } else if (receiver->IsJSStringIterator() || isolate_->IsInAnyContext( *receiver, Context::INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX)) { // Setting the next property of %StringIteratorPrototype% invalidates the // string iterator protector. - if (!isolate_->IsStringIteratorLookupChainIntact()) return; - isolate_->InvalidateStringIteratorProtector(); + if (!Protectors::IsStringIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateStringIteratorLookupChain(isolate_); } } else if (*name_ == roots.species_symbol()) { // Fetching the context in here since the operation is rather expensive. @@ -345,10 +345,10 @@ void LookupIterator::InternalUpdateProtector() { } if (!Protectors::IsArraySpeciesLookupChainIntact(isolate_) && - !isolate_->IsPromiseSpeciesLookupChainIntact() && + !Protectors::IsPromiseSpeciesLookupChainIntact(isolate_) && !Protectors::IsRegExpSpeciesLookupChainProtectorIntact( native_context) && - !isolate_->IsTypedArraySpeciesLookupChainIntact()) { + !Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) { return; } // Setting the Symbol.species property of any Array, Promise or TypedArray @@ -360,8 +360,8 @@ void LookupIterator::InternalUpdateProtector() { Protectors::InvalidateArraySpeciesLookupChain(isolate_); } else if (isolate_->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) { - if (!isolate_->IsPromiseSpeciesLookupChainIntact()) return; - isolate_->InvalidatePromiseSpeciesProtector(); + if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidatePromiseSpeciesLookupChain(isolate_); } else if (isolate_->IsInAnyContext(*receiver, Context::REGEXP_FUNCTION_INDEX)) { if (!Protectors::IsRegExpSpeciesLookupChainProtectorIntact( @@ -371,37 +371,37 @@ void LookupIterator::InternalUpdateProtector() { Protectors::InvalidateRegExpSpeciesLookupChainProtector(isolate_, native_context); } else if (IsTypedArrayFunctionInAnyContext(isolate_, *receiver)) { - if (!isolate_->IsTypedArraySpeciesLookupChainIntact()) return; - isolate_->InvalidateTypedArraySpeciesProtector(); + if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate_)) return; + Protectors::InvalidateTypedArraySpeciesLookupChain(isolate_); } } else if (*name_ == roots.is_concat_spreadable_symbol()) { - if (!isolate_->IsIsConcatSpreadableLookupChainIntact()) return; - isolate_->InvalidateIsConcatSpreadableProtector(); + if (!Protectors::IsIsConcatSpreadableLookupChainIntact(isolate_)) return; + Protectors::InvalidateIsConcatSpreadableLookupChain(isolate_); } else if (*name_ == roots.iterator_symbol()) { if (receiver->IsJSArray(isolate_)) { - if (!isolate_->IsArrayIteratorLookupChainIntact()) return; - isolate_->InvalidateArrayIteratorProtector(); + if (!Protectors::IsArrayIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateArrayIteratorLookupChain(isolate_); } else if (receiver->IsJSSet(isolate_) || receiver->IsJSSetIterator() || isolate_->IsInAnyContext( *receiver, Context::INITIAL_SET_ITERATOR_PROTOTYPE_INDEX) || isolate_->IsInAnyContext(*receiver, Context::INITIAL_SET_PROTOTYPE_INDEX)) { - if (isolate_->IsSetIteratorLookupChainIntact()) { - isolate_->InvalidateSetIteratorProtector(); + if (Protectors::IsSetIteratorLookupChainIntact(isolate_)) { + Protectors::InvalidateSetIteratorLookupChain(isolate_); } } else if (receiver->IsJSMapIterator() || isolate_->IsInAnyContext( *receiver, Context::INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX)) { - if (isolate_->IsMapIteratorLookupChainIntact()) { - isolate_->InvalidateMapIteratorProtector(); + if (Protectors::IsMapIteratorLookupChainIntact(isolate_)) { + Protectors::InvalidateMapIteratorLookupChain(isolate_); } } else if (isolate_->IsInAnyContext( *receiver, Context::INITIAL_ITERATOR_PROTOTYPE_INDEX)) { - if (isolate_->IsMapIteratorLookupChainIntact()) { - isolate_->InvalidateMapIteratorProtector(); + if (Protectors::IsMapIteratorLookupChainIntact(isolate_)) { + Protectors::InvalidateMapIteratorLookupChain(isolate_); } - if (isolate_->IsSetIteratorLookupChainIntact()) { - isolate_->InvalidateSetIteratorProtector(); + if (Protectors::IsSetIteratorLookupChainIntact(isolate_)) { + Protectors::InvalidateSetIteratorLookupChain(isolate_); } } else if (isolate_->IsInAnyContext( *receiver, Context::INITIAL_STRING_PROTOTYPE_INDEX)) { @@ -409,18 +409,18 @@ void LookupIterator::InternalUpdateProtector() { // the string iterator protector. Symbol.iterator can also be set on a // String wrapper, but not on a primitive string. We only support // protector for primitive strings. - if (!isolate_->IsStringIteratorLookupChainIntact()) return; - isolate_->InvalidateStringIteratorProtector(); + if (!Protectors::IsStringIteratorLookupChainIntact(isolate_)) return; + Protectors::InvalidateStringIteratorLookupChain(isolate_); } } else if (*name_ == roots.resolve_string()) { - if (!isolate_->IsPromiseResolveLookupChainIntact()) return; + if (!Protectors::IsPromiseResolveLookupChainIntact(isolate_)) return; // Setting the "resolve" property on any %Promise% intrinsic object // invalidates the Promise.resolve protector. if (isolate_->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) { - isolate_->InvalidatePromiseResolveProtector(); + Protectors::InvalidatePromiseResolveLookupChain(isolate_); } } else if (*name_ == roots.then_string()) { - if (!isolate_->IsPromiseThenLookupChainIntact()) return; + if (!Protectors::IsPromiseThenLookupChainIntact(isolate_)) return; // Setting the "then" property on any JSPromise instance or on the // initial %PromisePrototype% invalidates the Promise#then protector. // Also setting the "then" property on the initial %ObjectPrototype% @@ -432,7 +432,7 @@ void LookupIterator::InternalUpdateProtector() { isolate_->IsInAnyContext(*receiver, Context::INITIAL_OBJECT_PROTOTYPE_INDEX) || isolate_->IsInAnyContext(*receiver, Context::PROMISE_PROTOTYPE_INDEX)) { - isolate_->InvalidatePromiseThenProtector(); + Protectors::InvalidatePromiseThenLookupChain(isolate_); } } } @@ -534,7 +534,7 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value, DCHECK(attributes != NONE || !holder_obj->HasFastElements(isolate_)); Handle<FixedArrayBase> elements(holder_obj->elements(isolate_), isolate()); holder_obj->GetElementsAccessor(isolate_)->Reconfigure( - holder_obj, elements, number_, value, attributes); + holder_obj, elements, InternalIndex(number_), value, attributes); ReloadPropertyInformation<true>(); } else if (holder_obj->HasFastProperties(isolate_)) { Handle<Map> old_map(holder_obj->map(isolate_), isolate_); @@ -699,8 +699,7 @@ void LookupIterator::ApplyTransitionToDataProperty( } if (simple_transition) { - int number = transition->LastAdded(); - number_ = static_cast<uint32_t>(number); + number_ = transition->LastAdded().as_uint32(); property_details_ = transition->GetLastDescriptorDetails(isolate_); state_ = DATA; } else if (receiver->map(isolate_).is_dictionary_map()) { @@ -731,7 +730,7 @@ void LookupIterator::Delete() { if (IsElement()) { Handle<JSObject> object = Handle<JSObject>::cast(holder); ElementsAccessor* accessor = object->GetElementsAccessor(isolate_); - accessor->Delete(object, number_); + accessor->Delete(object, InternalIndex(number_)); } else { DCHECK(!name()->IsPrivateName(isolate_)); bool is_prototype_map = holder->map(isolate_).is_prototype_map(); @@ -777,8 +776,11 @@ void LookupIterator::TransitionToAccessorProperty( } else if (state_ == INTERCEPTOR) { LookupInRegularHolder<false>(*old_map, *holder_); } - int descriptor = - IsFound() ? static_cast<int>(number_) : DescriptorArray::kNotFound; + // TODO(jkummerow): {IsFound()} should be enough once {number_} has type + // {InternalIndex}. + InternalIndex descriptor = (IsFound() && number_ != kMaxUInt32) + ? InternalIndex(number_) + : InternalIndex::NotFound(); Handle<Map> new_map = Map::TransitionToAccessorProperty( isolate_, old_map, name_, descriptor, getter, setter, attributes); @@ -787,8 +789,7 @@ void LookupIterator::TransitionToAccessorProperty( JSObject::MigrateToMap(isolate_, receiver, new_map); if (simple_transition) { - int number = new_map->LastAdded(); - number_ = static_cast<uint32_t>(number); + number_ = new_map->LastAdded().as_uint32(); property_details_ = new_map->GetLastDescriptorDetails(isolate_); state_ = ACCESSOR; return; @@ -894,23 +895,24 @@ Handle<Object> LookupIterator::FetchValue() const { if (IsElement()) { Handle<JSObject> holder = GetHolder<JSObject>(); ElementsAccessor* accessor = holder->GetElementsAccessor(isolate_); - return accessor->Get(holder, number_); + return accessor->Get(holder, InternalIndex(number_)); } else if (holder_->IsJSGlobalObject(isolate_)) { Handle<JSGlobalObject> holder = GetHolder<JSGlobalObject>(); result = holder->global_dictionary(isolate_).ValueAt(isolate_, number_); } else if (!holder_->HasFastProperties(isolate_)) { - result = holder_->property_dictionary(isolate_).ValueAt(isolate_, number_); + result = holder_->property_dictionary(isolate_).ValueAt(isolate_, + dictionary_entry()); } else if (property_details_.location() == kField) { DCHECK_EQ(kData, property_details_.kind()); Handle<JSObject> holder = GetHolder<JSObject>(); FieldIndex field_index = - FieldIndex::ForDescriptor(holder->map(isolate_), number_); + FieldIndex::ForDescriptor(holder->map(isolate_), descriptor_number()); return JSObject::FastPropertyAt(holder, property_details_.representation(), field_index); } else { result = holder_->map(isolate_).instance_descriptors(isolate_).GetStrongValue( - isolate_, number_); + isolate_, descriptor_number()); } return handle(result, isolate_); } @@ -922,7 +924,7 @@ bool LookupIterator::IsConstFieldValueEqualTo(Object value) const { DCHECK_EQ(PropertyConstness::kConst, property_details_.constness()); Handle<JSObject> holder = GetHolder<JSObject>(); FieldIndex field_index = - FieldIndex::ForDescriptor(holder->map(isolate_), number_); + FieldIndex::ForDescriptor(holder->map(isolate_), descriptor_number()); if (property_details_.representation().IsDouble()) { if (!value.IsNumber(isolate_)) return false; uint64_t bits; @@ -958,7 +960,8 @@ int LookupIterator::GetFieldDescriptorIndex() const { DCHECK(holder_->HasFastProperties()); DCHECK_EQ(kField, property_details_.location()); DCHECK_EQ(kData, property_details_.kind()); - return descriptor_number(); + // TODO(jkummerow): Propagate InternalIndex further. + return descriptor_number().as_int(); } int LookupIterator::GetAccessorIndex() const { @@ -966,7 +969,7 @@ int LookupIterator::GetAccessorIndex() const { DCHECK(holder_->HasFastProperties(isolate_)); DCHECK_EQ(kDescriptor, property_details_.location()); DCHECK_EQ(kAccessor, property_details_.kind()); - return descriptor_number(); + return descriptor_number().as_int(); } Handle<Map> LookupIterator::GetFieldOwnerMap() const { @@ -1028,7 +1031,7 @@ void LookupIterator::WriteDataValue(Handle<Object> value, if (IsElement()) { Handle<JSObject> object = Handle<JSObject>::cast(holder); ElementsAccessor* accessor = object->GetElementsAccessor(isolate_); - accessor->Set(object, number_, *value); + accessor->Set(object, InternalIndex(number_), *value); } else if (holder->HasFastProperties(isolate_)) { if (property_details_.location() == kField) { // Check that in case of VariableMode::kConst field the existing value is @@ -1164,13 +1167,15 @@ LookupIterator::State LookupIterator::LookupInRegularHolder( JSObject js_object = JSObject::cast(holder); ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_); FixedArrayBase backing_store = js_object.elements(isolate_); - number_ = + // TODO(jkummerow): {number_} should have type InternalIndex. + InternalIndex entry = accessor->GetEntryForIndex(isolate_, js_object, backing_store, index_); + number_ = entry.is_found() ? entry.as_uint32() : kMaxUInt32; if (number_ == kMaxUInt32) { return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC : NOT_FOUND; } - property_details_ = accessor->GetDetails(js_object, number_); + property_details_ = accessor->GetDetails(js_object, InternalIndex(number_)); if (map.has_frozen_elements()) { property_details_ = property_details_.CopyAddAttributes(FROZEN); } else if (map.has_sealed_elements()) { @@ -1178,10 +1183,10 @@ LookupIterator::State LookupIterator::LookupInRegularHolder( } } else if (!map.is_dictionary_map()) { DescriptorArray descriptors = map.instance_descriptors(isolate_); - int number = descriptors.SearchWithCache(isolate_, *name_, map); - if (number == DescriptorArray::kNotFound) return NotFound(holder); - number_ = static_cast<uint32_t>(number); - property_details_ = descriptors.GetDetails(number_); + InternalIndex number = descriptors.SearchWithCache(isolate_, *name_, map); + if (number.is_not_found()) return NotFound(holder); + number_ = number.as_uint32(); + property_details_ = descriptors.GetDetails(InternalIndex(number_)); } else { DCHECK_IMPLIES(holder.IsJSProxy(isolate_), name()->IsPrivate(isolate_)); NameDictionary dict = holder.property_dictionary(isolate_); diff --git a/deps/v8/src/objects/lookup.h b/deps/v8/src/objects/lookup.h index 565ea4bb75be02..2a1f0e2f1bbb19 100644 --- a/deps/v8/src/objects/lookup.h +++ b/deps/v8/src/objects/lookup.h @@ -241,7 +241,7 @@ class V8_EXPORT_PRIVATE LookupIterator final { bool check_interceptor() const { return (configuration_ & kInterceptor) != 0; } - inline int descriptor_number() const; + inline InternalIndex descriptor_number() const; inline int dictionary_entry() const; static inline Configuration ComputeConfiguration(Isolate* isolate, diff --git a/deps/v8/src/objects/map-inl.h b/deps/v8/src/objects/map-inl.h index 48bb86e2dab454..557c004401820e 100644 --- a/deps/v8/src/objects/map-inl.h +++ b/deps/v8/src/objects/map-inl.h @@ -112,7 +112,7 @@ bool Map::IsMostGeneralFieldType(Representation representation, bool Map::CanHaveFastTransitionableElementsKind(InstanceType instance_type) { return instance_type == JS_ARRAY_TYPE || instance_type == JS_PRIMITIVE_WRAPPER_TYPE || - instance_type == JS_ARGUMENTS_TYPE; + instance_type == JS_ARGUMENTS_OBJECT_TYPE; } bool Map::CanHaveFastTransitionableElementsKind() const { @@ -177,10 +177,10 @@ PropertyDetails Map::GetLastDescriptorDetails(Isolate* isolate) const { return instance_descriptors(isolate).GetDetails(LastAdded()); } -int Map::LastAdded() const { +InternalIndex Map::LastAdded() const { int number_of_own_descriptors = NumberOfOwnDescriptors(); DCHECK_GT(number_of_own_descriptors, 0); - return number_of_own_descriptors - 1; + return InternalIndex(number_of_own_descriptors - 1); } int Map::NumberOfOwnDescriptors() const { @@ -194,6 +194,10 @@ void Map::SetNumberOfOwnDescriptors(int number) { set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); } +InternalIndex::Range Map::IterateOwnDescriptors() const { + return InternalIndex::Range(NumberOfOwnDescriptors()); +} + int Map::EnumLength() const { return EnumLengthBits::decode(bit_field3()); } void Map::SetEnumLength(int length) { @@ -207,7 +211,8 @@ void Map::SetEnumLength(int length) { FixedArrayBase Map::GetInitialElements() const { FixedArrayBase result; - if (has_fast_elements() || has_fast_string_wrapper_elements()) { + if (has_fast_elements() || has_fast_string_wrapper_elements() || + has_any_nonextensible_elements()) { result = GetReadOnlyRoots().empty_fixed_array(); } else if (has_fast_sloppy_arguments_elements()) { result = GetReadOnlyRoots().empty_sloppy_arguments_elements(); @@ -540,12 +545,12 @@ void Map::mark_unstable() { bool Map::is_stable() const { return !IsUnstableBit::decode(bit_field3()); } bool Map::CanBeDeprecated() const { - int descriptor = LastAdded(); - for (int i = 0; i <= descriptor; i++) { + for (InternalIndex i : IterateOwnDescriptors()) { PropertyDetails details = instance_descriptors().GetDetails(i); if (details.representation().IsNone()) return true; if (details.representation().IsSmi()) return true; - if (details.representation().IsDouble()) return true; + if (details.representation().IsDouble() && FLAG_unbox_double_fields) + return true; if (details.representation().IsHeapObject()) return true; if (details.kind() == kData && details.location() == kDescriptor) { return true; @@ -584,7 +589,7 @@ bool Map::IsNullOrUndefinedMap() const { } bool Map::IsPrimitiveMap() const { - return instance_type() <= LAST_PRIMITIVE_TYPE; + return instance_type() <= LAST_PRIMITIVE_HEAP_OBJECT_TYPE; } LayoutDescriptor Map::layout_descriptor_gc_safe() const { @@ -675,8 +680,10 @@ void Map::AppendDescriptor(Isolate* isolate, Descriptor* desc) { // barrier. descriptors.Append(desc); SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); +#ifndef V8_DISABLE_WRITE_BARRIERS MarkingBarrierForDescriptorArray(isolate->heap(), *this, descriptors, number_of_own_descriptors + 1); +#endif } // Properly mark the map if the {desc} is an "interesting symbol". if (desc->GetKey()->IsInterestingSymbol()) { diff --git a/deps/v8/src/objects/map-updater.cc b/deps/v8/src/objects/map-updater.cc index 49b9ccea91f73c..8c9b94014f8efa 100644 --- a/deps/v8/src/objects/map-updater.cc +++ b/deps/v8/src/objects/map-updater.cc @@ -38,12 +38,12 @@ MapUpdater::MapUpdater(Isolate* isolate, Handle<Map> old_map) !old_map->FindRootMap(isolate).GetConstructor().IsFunctionTemplateInfo()); } -Name MapUpdater::GetKey(int descriptor) const { +Name MapUpdater::GetKey(InternalIndex descriptor) const { return old_descriptors_->GetKey(descriptor); } -PropertyDetails MapUpdater::GetDetails(int descriptor) const { - DCHECK_LE(0, descriptor); +PropertyDetails MapUpdater::GetDetails(InternalIndex descriptor) const { + DCHECK(descriptor.is_found()); if (descriptor == modified_descriptor_) { PropertyAttributes attributes = new_attributes_; // If the original map was sealed or frozen, let us used the old @@ -59,8 +59,8 @@ PropertyDetails MapUpdater::GetDetails(int descriptor) const { return old_descriptors_->GetDetails(descriptor); } -Object MapUpdater::GetValue(int descriptor) const { - DCHECK_LE(0, descriptor); +Object MapUpdater::GetValue(InternalIndex descriptor) const { + DCHECK(descriptor.is_found()); if (descriptor == modified_descriptor_) { DCHECK_EQ(kDescriptor, new_location_); return *new_value_; @@ -69,8 +69,8 @@ Object MapUpdater::GetValue(int descriptor) const { return old_descriptors_->GetStrongValue(descriptor); } -FieldType MapUpdater::GetFieldType(int descriptor) const { - DCHECK_LE(0, descriptor); +FieldType MapUpdater::GetFieldType(InternalIndex descriptor) const { + DCHECK(descriptor.is_found()); if (descriptor == modified_descriptor_) { DCHECK_EQ(kField, new_location_); return *new_field_type_; @@ -80,9 +80,9 @@ FieldType MapUpdater::GetFieldType(int descriptor) const { } Handle<FieldType> MapUpdater::GetOrComputeFieldType( - int descriptor, PropertyLocation location, + InternalIndex descriptor, PropertyLocation location, Representation representation) const { - DCHECK_LE(0, descriptor); + DCHECK(descriptor.is_found()); // |location| is just a pre-fetched GetDetails(descriptor).location(). DCHECK_EQ(location, GetDetails(descriptor).location()); if (location == kField) { @@ -93,7 +93,7 @@ Handle<FieldType> MapUpdater::GetOrComputeFieldType( } Handle<FieldType> MapUpdater::GetOrComputeFieldType( - Handle<DescriptorArray> descriptors, int descriptor, + Handle<DescriptorArray> descriptors, InternalIndex descriptor, PropertyLocation location, Representation representation) { // |location| is just a pre-fetched GetDetails(descriptor).location(). DCHECK_EQ(descriptors->GetDetails(descriptor).location(), location); @@ -105,13 +105,13 @@ Handle<FieldType> MapUpdater::GetOrComputeFieldType( } } -Handle<Map> MapUpdater::ReconfigureToDataField(int descriptor, +Handle<Map> MapUpdater::ReconfigureToDataField(InternalIndex descriptor, PropertyAttributes attributes, PropertyConstness constness, Representation representation, Handle<FieldType> field_type) { DCHECK_EQ(kInitialized, state_); - DCHECK_LE(0, descriptor); + DCHECK(descriptor.is_found()); DCHECK(!old_map_->is_dictionary_map()); modified_descriptor_ = descriptor; new_kind_ = kData; @@ -190,7 +190,7 @@ Handle<Map> MapUpdater::Update() { return result_map_; } -void MapUpdater::GeneralizeField(Handle<Map> map, int modify_index, +void MapUpdater::GeneralizeField(Handle<Map> map, InternalIndex modify_index, PropertyConstness new_constness, Representation new_representation, Handle<FieldType> new_field_type) { @@ -338,7 +338,8 @@ MapUpdater::State MapUpdater::FindRootMap() { } int root_nof = root_map_->NumberOfOwnDescriptors(); - if (modified_descriptor_ >= 0 && modified_descriptor_ < root_nof) { + if (modified_descriptor_.is_found() && + modified_descriptor_.as_int() < root_nof) { PropertyDetails old_details = old_descriptors_->GetDetails(modified_descriptor_); if (old_details.kind() != new_kind_ || @@ -374,7 +375,7 @@ MapUpdater::State MapUpdater::FindTargetMap() { target_map_ = root_map_; int root_nof = root_map_->NumberOfOwnDescriptors(); - for (int i = root_nof; i < old_nof_; ++i) { + for (InternalIndex i : InternalIndex::Range(root_nof, old_nof_)) { PropertyDetails old_details = GetDetails(i); Map transition = TransitionsAccessor(isolate_, target_map_) .SearchTransition(GetKey(i), old_details.kind(), @@ -423,7 +424,7 @@ MapUpdater::State MapUpdater::FindTargetMap() { int target_nof = target_map_->NumberOfOwnDescriptors(); if (target_nof == old_nof_) { #ifdef DEBUG - if (modified_descriptor_ >= 0) { + if (modified_descriptor_.is_found()) { DescriptorArray target_descriptors = target_map_->instance_descriptors(); PropertyDetails details = target_descriptors.GetDetails(modified_descriptor_); @@ -465,7 +466,7 @@ MapUpdater::State MapUpdater::FindTargetMap() { } // Find the last compatible target map in the transition tree. - for (int i = target_nof; i < old_nof_; ++i) { + for (InternalIndex i : InternalIndex::Range(target_nof, old_nof_)) { PropertyDetails old_details = GetDetails(i); Map transition = TransitionsAccessor(isolate_, target_map_) .SearchTransition(GetKey(i), old_details.kind(), @@ -521,7 +522,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() { // general than we requested. Take |root_nof| entries as is. // 0 -> |root_nof| int current_offset = 0; - for (int i = 0; i < root_nof; ++i) { + for (InternalIndex i : InternalIndex::Range(root_nof)) { PropertyDetails old_details = old_descriptors_->GetDetails(i); if (old_details.location() == kField) { current_offset += old_details.field_width_in_words(); @@ -534,7 +535,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() { // Merge "updated" old_descriptor entries with target_descriptor entries. // |root_nof| -> |target_nof| - for (int i = root_nof; i < target_nof; ++i) { + for (InternalIndex i : InternalIndex::Range(root_nof, target_nof)) { Handle<Name> key(GetKey(i), isolate_); PropertyDetails old_details = GetDetails(i); PropertyDetails target_details = target_descriptors->GetDetails(i); @@ -606,7 +607,7 @@ Handle<DescriptorArray> MapUpdater::BuildDescriptorArray() { // Take "updated" old_descriptor entries. // |target_nof| -> |old_nof| - for (int i = target_nof; i < old_nof_; ++i) { + for (InternalIndex i : InternalIndex::Range(target_nof, old_nof_)) { PropertyDetails old_details = GetDetails(i); Handle<Name> key(GetKey(i), isolate_); @@ -665,7 +666,7 @@ Handle<Map> MapUpdater::FindSplitMap(Handle<DescriptorArray> descriptors) { int root_nof = root_map_->NumberOfOwnDescriptors(); Map current = *root_map_; - for (int i = root_nof; i < old_nof_; i++) { + for (InternalIndex i : InternalIndex::Range(root_nof, old_nof_)) { Name name = descriptors->GetKey(i); PropertyDetails details = descriptors->GetDetails(i); Map next = @@ -707,13 +708,13 @@ MapUpdater::State MapUpdater::ConstructNewMap() { state_ = kAtIntegrityLevelSource; return state_; } - - PropertyDetails split_details = GetDetails(split_nof); + InternalIndex split_index(split_nof); + PropertyDetails split_details = GetDetails(split_index); TransitionsAccessor transitions(isolate_, split_map); // Invalidate a transition target at |key|. Map maybe_transition = transitions.SearchTransition( - GetKey(split_nof), split_details.kind(), split_details.attributes()); + GetKey(split_index), split_details.kind(), split_details.attributes()); if (!maybe_transition.is_null()) { maybe_transition.DeprecateTransitionTree(isolate_); } @@ -727,7 +728,7 @@ MapUpdater::State MapUpdater::ConstructNewMap() { old_map_->NotifyLeafMapLayoutChange(isolate_); - if (FLAG_trace_generalization && modified_descriptor_ >= 0) { + if (FLAG_trace_generalization && modified_descriptor_.is_found()) { PropertyDetails old_details = old_descriptors_->GetDetails(modified_descriptor_); PropertyDetails new_details = diff --git a/deps/v8/src/objects/map-updater.h b/deps/v8/src/objects/map-updater.h index 6ee373cbdf3bb4..11bdd0859ff28d 100644 --- a/deps/v8/src/objects/map-updater.h +++ b/deps/v8/src/objects/map-updater.h @@ -54,7 +54,7 @@ class MapUpdater { // Prepares for reconfiguring of a property at |descriptor| to data field // with given |attributes| and |representation|/|field_type| and // performs the steps 1-5. - Handle<Map> ReconfigureToDataField(int descriptor, + Handle<Map> ReconfigureToDataField(InternalIndex descriptor, PropertyAttributes attributes, PropertyConstness constness, Representation representation, @@ -127,26 +127,26 @@ class MapUpdater { State Normalize(const char* reason); // Returns name of a |descriptor| property. - inline Name GetKey(int descriptor) const; + inline Name GetKey(InternalIndex descriptor) const; // Returns property details of a |descriptor| in "updated" |old_descrtiptors_| // array. - inline PropertyDetails GetDetails(int descriptor) const; + inline PropertyDetails GetDetails(InternalIndex descriptor) const; // Returns value of a |descriptor| with kDescriptor location in "updated" // |old_descrtiptors_| array. - inline Object GetValue(int descriptor) const; + inline Object GetValue(InternalIndex descriptor) const; // Returns field type for a |descriptor| with kField location in "updated" // |old_descrtiptors_| array. - inline FieldType GetFieldType(int descriptor) const; + inline FieldType GetFieldType(InternalIndex descriptor) const; // If a |descriptor| property in "updated" |old_descriptors_| has kField // location then returns it's field type otherwise computes optimal field // type for the descriptor's value and |representation|. The |location| // value must be a pre-fetched location for |descriptor|. inline Handle<FieldType> GetOrComputeFieldType( - int descriptor, PropertyLocation location, + InternalIndex descriptor, PropertyLocation location, Representation representation) const; // If a |descriptor| property in given |descriptors| array has kField @@ -154,10 +154,10 @@ class MapUpdater { // type for the descriptor's value and |representation|. // The |location| value must be a pre-fetched location for |descriptor|. inline Handle<FieldType> GetOrComputeFieldType( - Handle<DescriptorArray> descriptors, int descriptor, + Handle<DescriptorArray> descriptors, InternalIndex descriptor, PropertyLocation location, Representation representation); - void GeneralizeField(Handle<Map> map, int modify_index, + void GeneralizeField(Handle<Map> map, InternalIndex modify_index, PropertyConstness new_constness, Representation new_representation, Handle<FieldType> new_field_type); @@ -182,9 +182,9 @@ class MapUpdater { ElementsKind new_elements_kind_; bool is_transitionable_fast_elements_kind_; - // If |modified_descriptor_| is not equal to -1 then the fields below form + // If |modified_descriptor_.is_found()|, then the fields below form // an "update" of the |old_map_|'s descriptors. - int modified_descriptor_ = -1; + InternalIndex modified_descriptor_ = InternalIndex::NotFound(); PropertyKind new_kind_ = kData; PropertyAttributes new_attributes_ = NONE; PropertyConstness new_constness_ = PropertyConstness::kMutable; diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc index a672d6580a0837..0f448922ebddf4 100644 --- a/deps/v8/src/objects/map.cc +++ b/deps/v8/src/objects/map.cc @@ -56,20 +56,8 @@ MaybeHandle<JSFunction> Map::GetConstructorFunction( return MaybeHandle<JSFunction>(); } -bool Map::IsMapOfGlobalProxy(Handle<NativeContext> native_context) const { - DisallowHeapAllocation no_gc; - if (IsJSGlobalProxyMap()) { - Object maybe_constructor = GetConstructor(); - // Detached global proxies have |null| as their constructor. - return maybe_constructor.IsJSFunction() && - JSFunction::cast(maybe_constructor).native_context() == - *native_context; - } - return false; -} - -void Map::PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index, - PropertyKind kind, +void Map::PrintReconfiguration(Isolate* isolate, FILE* file, + InternalIndex modify_index, PropertyKind kind, PropertyAttributes attributes) { OFStream os(file); os << "[reconfiguring]"; @@ -256,7 +244,7 @@ VisitorId Map::GetVisitorId(Map map) { case CODE_DATA_CONTAINER_TYPE: return kVisitCodeDataContainer; - case WASM_INSTANCE_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: return kVisitWasmInstanceObject; case PREPARSE_DATA_TYPE: @@ -270,7 +258,7 @@ VisitorId Map::GetVisitorId(Map map) { case JS_OBJECT_TYPE: case JS_ERROR_TYPE: - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE: case JS_GENERATOR_OBJECT_TYPE: @@ -291,27 +279,27 @@ VisitorId Map::GetVisitorId(Map map) { case JS_MAP_VALUE_ITERATOR_TYPE: case JS_STRING_ITERATOR_TYPE: case JS_PROMISE_TYPE: - case JS_REGEXP_TYPE: - case JS_REGEXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE: case JS_FINALIZATION_GROUP_TYPE: #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: - case JS_INTL_COLLATOR_TYPE: - case JS_INTL_DATE_TIME_FORMAT_TYPE: - case JS_INTL_LIST_FORMAT_TYPE: - case JS_INTL_LOCALE_TYPE: - case JS_INTL_NUMBER_FORMAT_TYPE: - case JS_INTL_PLURAL_RULES_TYPE: - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: - case JS_INTL_SEGMENT_ITERATOR_TYPE: - case JS_INTL_SEGMENTER_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: + case JS_COLLATOR_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: + case JS_LOCALE_TYPE: + case JS_NUMBER_FORMAT_TYPE: + case JS_PLURAL_RULES_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENTER_TYPE: #endif // V8_INTL_SUPPORT - case WASM_EXCEPTION_TYPE: - case WASM_GLOBAL_TYPE: - case WASM_MEMORY_TYPE: - case WASM_MODULE_TYPE: - case WASM_TABLE_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: + case WASM_MEMORY_OBJECT_TYPE: + case WASM_MODULE_OBJECT_TYPE: + case WASM_TABLE_OBJECT_TYPE: case JS_BOUND_FUNCTION_TYPE: { const bool has_raw_data_fields = (FLAG_unbox_double_fields && !map.HasFastPointerLayout()) || @@ -371,12 +359,13 @@ VisitorId Map::GetVisitorId(Map map) { } void Map::PrintGeneralization( - Isolate* isolate, FILE* file, const char* reason, int modify_index, - int split, int descriptors, bool descriptor_to_field, - Representation old_representation, Representation new_representation, - PropertyConstness old_constness, PropertyConstness new_constness, - MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value, - MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value) { + Isolate* isolate, FILE* file, const char* reason, + InternalIndex modify_index, int split, int descriptors, + bool descriptor_to_field, Representation old_representation, + Representation new_representation, PropertyConstness old_constness, + PropertyConstness new_constness, MaybeHandle<FieldType> old_field_type, + MaybeHandle<Object> old_value, MaybeHandle<FieldType> new_field_type, + MaybeHandle<Object> new_value) { OFStream os(file); os << "[generalizing]"; Name name = instance_descriptors().GetKey(modify_index); @@ -440,9 +429,9 @@ MaybeHandle<Map> Map::CopyWithField(Isolate* isolate, Handle<Map> map, PropertyConstness constness, Representation representation, TransitionFlag flag) { - DCHECK( - DescriptorArray::kNotFound == - map->instance_descriptors().Search(*name, map->NumberOfOwnDescriptors())); + DCHECK(map->instance_descriptors() + .Search(*name, map->NumberOfOwnDescriptors()) + .is_not_found()); // Ensure the descriptor array does not get too big. if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { @@ -536,8 +525,7 @@ bool Map::InstancesNeedRewriting(Map target, int target_number_of_fields, // If smi descriptors were replaced by double descriptors, rewrite. DescriptorArray old_desc = instance_descriptors(); DescriptorArray new_desc = target.instance_descriptors(); - int limit = NumberOfOwnDescriptors(); - for (int i = 0; i < limit; i++) { + for (InternalIndex i : IterateOwnDescriptors()) { if (new_desc.GetDetails(i).representation().IsDouble() != old_desc.GetDetails(i).representation().IsDouble()) { return true; @@ -562,7 +550,7 @@ bool Map::InstancesNeedRewriting(Map target, int target_number_of_fields, int Map::NumberOfFields() const { DescriptorArray descriptors = instance_descriptors(); int result = 0; - for (int i = 0; i < NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : IterateOwnDescriptors()) { if (descriptors.GetDetails(i).location() == kField) result++; } return result; @@ -572,7 +560,7 @@ Map::FieldCounts Map::GetFieldCounts() const { DescriptorArray descriptors = instance_descriptors(); int mutable_count = 0; int const_count = 0; - for (int i = 0; i < NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(i); if (details.location() == kField) { switch (details.constness()) { @@ -625,8 +613,10 @@ void Map::ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors, // descriptors will not be trimmed in the mark-compactor, we need to mark // all its elements. Map current = *this; +#ifndef V8_DISABLE_WRITE_BARRIERS MarkingBarrierForDescriptorArray(isolate->heap(), current, to_replace, to_replace.number_of_descriptors()); +#endif while (current.instance_descriptors(isolate) == to_replace) { Object next = current.GetBackPointer(isolate); if (next.IsUndefined(isolate)) break; // Stop overwriting at initial map. @@ -654,7 +644,7 @@ Map Map::FindRootMap(Isolate* isolate) const { } } -Map Map::FindFieldOwner(Isolate* isolate, int descriptor) const { +Map Map::FindFieldOwner(Isolate* isolate, InternalIndex descriptor) const { DisallowHeapAllocation no_allocation; DCHECK_EQ(kField, instance_descriptors(isolate).GetDetails(descriptor).location()); @@ -663,14 +653,14 @@ Map Map::FindFieldOwner(Isolate* isolate, int descriptor) const { Object back = result.GetBackPointer(isolate); if (back.IsUndefined(isolate)) break; const Map parent = Map::cast(back); - if (parent.NumberOfOwnDescriptors() <= descriptor) break; + if (parent.NumberOfOwnDescriptors() <= descriptor.as_int()) break; result = parent; } return result; } -void Map::UpdateFieldType(Isolate* isolate, int descriptor, Handle<Name> name, - PropertyConstness new_constness, +void Map::UpdateFieldType(Isolate* isolate, InternalIndex descriptor, + Handle<Name> name, PropertyConstness new_constness, Representation new_representation, const MaybeObjectHandle& new_wrapped_type) { DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeak()); @@ -740,7 +730,8 @@ Handle<FieldType> Map::GeneralizeFieldType(Representation rep1, } // static -void Map::GeneralizeField(Isolate* isolate, Handle<Map> map, int modify_index, +void Map::GeneralizeField(Isolate* isolate, Handle<Map> map, + InternalIndex modify_index, PropertyConstness new_constness, Representation new_representation, Handle<FieldType> new_field_type) { @@ -791,7 +782,8 @@ void Map::GeneralizeField(Isolate* isolate, Handle<Map> map, int modify_index, map->PrintGeneralization( isolate, stdout, "field type generalization", modify_index, map->NumberOfOwnDescriptors(), map->NumberOfOwnDescriptors(), false, - details.representation(), details.representation(), old_constness, + details.representation(), + descriptors->GetDetails(modify_index).representation(), old_constness, new_constness, old_field_type, MaybeHandle<Object>(), new_field_type, MaybeHandle<Object>()); } @@ -800,7 +792,8 @@ void Map::GeneralizeField(Isolate* isolate, Handle<Map> map, int modify_index, // TODO(ishell): remove. // static Handle<Map> Map::ReconfigureProperty(Isolate* isolate, Handle<Map> map, - int modify_index, PropertyKind new_kind, + InternalIndex modify_index, + PropertyKind new_kind, PropertyAttributes new_attributes, Representation new_representation, Handle<FieldType> new_field_type) { @@ -840,9 +833,8 @@ Map SearchMigrationTarget(Isolate* isolate, Map old_map) { // types instead of old_map's types. // Go to slow map updating if the old_map has fast properties with cleared // field types. - int old_nof = old_map.NumberOfOwnDescriptors(); DescriptorArray old_descriptors = old_map.instance_descriptors(); - for (int i = 0; i < old_nof; i++) { + for (InternalIndex i : old_map.IterateOwnDescriptors()) { PropertyDetails old_details = old_descriptors.GetDetails(i); if (old_details.location() == kField && old_details.kind() == kData) { FieldType old_type = old_descriptors.GetFieldType(i); @@ -1007,7 +999,7 @@ Map Map::TryReplayPropertyTransitions(Isolate* isolate, Map old_map) { DescriptorArray old_descriptors = old_map.instance_descriptors(); Map new_map = *this; - for (int i = root_nof; i < old_nof; ++i) { + for (InternalIndex i : InternalIndex::Range(root_nof, old_nof)) { PropertyDetails old_details = old_descriptors.GetDetails(i); Map transition = TransitionsAccessor(isolate, new_map, &no_allocation) @@ -1107,8 +1099,10 @@ void Map::EnsureDescriptorSlack(Isolate* isolate, Handle<Map> map, int slack) { // Replace descriptors by new_descriptors in all maps that share it. The old // descriptors will not be trimmed in the mark-compactor, we need to mark // all its elements. +#ifndef V8_DISABLE_WRITE_BARRIERS MarkingBarrierForDescriptorArray(isolate->heap(), *map, *descriptors, descriptors->number_of_descriptors()); +#endif Map current = *map; while (current.instance_descriptors() == *descriptors) { @@ -1363,8 +1357,7 @@ Handle<Map> Map::AsElementsKind(Isolate* isolate, Handle<Map> map, int Map::NumberOfEnumerableProperties() const { int result = 0; DescriptorArray descs = instance_descriptors(); - int limit = NumberOfOwnDescriptors(); - for (int i = 0; i < limit; i++) { + for (InternalIndex i : IterateOwnDescriptors()) { if ((descs.GetDetails(i).attributes() & ONLY_ENUMERABLE) == 0 && !descs.GetKey(i).FilterKey(ENUMERABLE_STRINGS)) { result++; @@ -1378,7 +1371,7 @@ int Map::NextFreePropertyIndex() const { DescriptorArray descs = instance_descriptors(); // Search properties backwards to find the last field. for (int i = number_of_own_descriptors - 1; i >= 0; --i) { - PropertyDetails details = descs.GetDetails(i); + PropertyDetails details = descs.GetDetails(InternalIndex(i)); if (details.location() == kField) { return details.field_index() + details.field_width_in_words(); } @@ -1788,7 +1781,7 @@ Handle<Map> Map::AddMissingTransitions( // if there are no dead transitions from that map and this is exactly the // case for all the intermediate maps we create here. Handle<Map> map = split_map; - for (int i = split_nof; i < nof_descriptors - 1; ++i) { + for (InternalIndex i : InternalIndex::Range(split_nof, nof_descriptors - 1)) { Handle<Map> new_map = CopyDropDescriptors(isolate, map); InstallDescriptors(isolate, map, new_map, i, descriptors, full_layout_descriptor); @@ -1797,20 +1790,21 @@ Handle<Map> Map::AddMissingTransitions( } map->NotifyLeafMapLayoutChange(isolate); last_map->set_may_have_interesting_symbols(false); - InstallDescriptors(isolate, map, last_map, nof_descriptors - 1, descriptors, - full_layout_descriptor); + InstallDescriptors(isolate, map, last_map, InternalIndex(nof_descriptors - 1), + descriptors, full_layout_descriptor); return last_map; } // Since this method is used to rewrite an existing transition tree, it can // always insert transitions without checking. void Map::InstallDescriptors(Isolate* isolate, Handle<Map> parent, - Handle<Map> child, int new_descriptor, + Handle<Map> child, InternalIndex new_descriptor, Handle<DescriptorArray> descriptors, Handle<LayoutDescriptor> full_layout_descriptor) { DCHECK(descriptors->IsSortedNoDuplicates()); - child->SetInstanceDescriptors(isolate, *descriptors, new_descriptor + 1); + child->SetInstanceDescriptors(isolate, *descriptors, + new_descriptor.as_int() + 1); child->CopyUnusedPropertyFields(*parent); PropertyDetails details = descriptors->GetDetails(new_descriptor); if (details.location() == kField) { @@ -2063,7 +2057,7 @@ Handle<Map> Map::CopyForPreventExtensions( namespace { -bool CanHoldValue(DescriptorArray descriptors, int descriptor, +bool CanHoldValue(DescriptorArray descriptors, InternalIndex descriptor, PropertyConstness constness, Object value) { PropertyDetails details = descriptors.GetDetails(descriptor); if (details.location() == kField) { @@ -2086,7 +2080,7 @@ bool CanHoldValue(DescriptorArray descriptors, int descriptor, } Handle<Map> UpdateDescriptorForValue(Isolate* isolate, Handle<Map> map, - int descriptor, + InternalIndex descriptor, PropertyConstness constness, Handle<Object> value) { if (CanHoldValue(map->instance_descriptors(), descriptor, constness, @@ -2108,7 +2102,7 @@ Handle<Map> UpdateDescriptorForValue(Isolate* isolate, Handle<Map> map, // static Handle<Map> Map::PrepareForDataProperty(Isolate* isolate, Handle<Map> map, - int descriptor, + InternalIndex descriptor, PropertyConstness constness, Handle<Object> value) { // Update to the newest map before storing the property. @@ -2140,7 +2134,7 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map, .SearchTransition(*name, kData, attributes); if (!maybe_transition.is_null()) { Handle<Map> transition(maybe_transition, isolate); - int descriptor = transition->LastAdded(); + InternalIndex descriptor = transition->LastAdded(); DCHECK_EQ( attributes, @@ -2206,7 +2200,8 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map, } Handle<Map> Map::ReconfigureExistingProperty(Isolate* isolate, Handle<Map> map, - int descriptor, PropertyKind kind, + InternalIndex descriptor, + PropertyKind kind, PropertyAttributes attributes, PropertyConstness constness) { // Dictionaries have to be reconfigured in-place. @@ -2232,7 +2227,8 @@ Handle<Map> Map::ReconfigureExistingProperty(Isolate* isolate, Handle<Map> map, } Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, - Handle<Name> name, int descriptor, + Handle<Name> name, + InternalIndex descriptor, Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes) { @@ -2261,7 +2257,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, if (!maybe_transition.is_null()) { Handle<Map> transition(maybe_transition, isolate); DescriptorArray descriptors = transition->instance_descriptors(); - int descriptor = transition->LastAdded(); + InternalIndex descriptor = transition->LastAdded(); DCHECK(descriptors.GetKey(descriptor).Equals(*name)); DCHECK_EQ(kAccessor, descriptors.GetDetails(descriptor).kind()); @@ -2284,7 +2280,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map, Handle<AccessorPair> pair; DescriptorArray old_descriptors = map->instance_descriptors(); - if (descriptor != DescriptorArray::kNotFound) { + if (descriptor.is_found()) { if (descriptor != map->LastAdded()) { return Map::Normalize(isolate, map, mode, "AccessorsOverwritingNonLast"); } @@ -2374,9 +2370,9 @@ Handle<Map> Map::CopyInsertDescriptor(Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate); // We replace the key if it is already present. - int index = + InternalIndex index = old_descriptors->SearchWithCache(isolate, *descriptor->GetKey(), *map); - if (index != DescriptorArray::kNotFound) { + if (index.is_found()) { return CopyReplaceDescriptor(isolate, map, old_descriptors, descriptor, index, flag); } @@ -2386,7 +2382,7 @@ Handle<Map> Map::CopyInsertDescriptor(Isolate* isolate, Handle<Map> map, Handle<Map> Map::CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors, Descriptor* descriptor, - int insertion_index, + InternalIndex insertion_index, TransitionFlag flag) { Handle<Name> key = descriptor->GetKey(); DCHECK_EQ(*key, descriptors->GetKey(insertion_index)); @@ -2403,7 +2399,7 @@ Handle<Map> Map::CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map, isolate, map, new_descriptors, new_descriptors->number_of_descriptors()); SimpleTransitionFlag simple_flag = - (insertion_index == descriptors->number_of_descriptors() - 1) + (insertion_index.as_int() == descriptors->number_of_descriptors() - 1) ? SIMPLE_PROPERTY_TRANSITION : PROPERTY_TRANSITION; return CopyReplaceDescriptors(isolate, map, new_descriptors, @@ -2465,8 +2461,7 @@ bool Map::EquivalentToForElementsKindTransition(const Map other) const { // with fields that may be generalized in-place. This must already be handled // during addition of a new field. DescriptorArray descriptors = instance_descriptors(); - int nof = NumberOfOwnDescriptors(); - for (int i = 0; i < nof; i++) { + for (InternalIndex i : IterateOwnDescriptors()) { PropertyDetails details = descriptors.GetDetails(i); if (details.location() == kField) { DCHECK(IsMostGeneralFieldType(details.representation(), @@ -2547,8 +2542,10 @@ void Map::SetInstanceDescriptors(Isolate* isolate, DescriptorArray descriptors, int number_of_own_descriptors) { set_synchronized_instance_descriptors(descriptors); SetNumberOfOwnDescriptors(number_of_own_descriptors); +#ifndef V8_DISABLE_WRITE_BARRIERS MarkingBarrierForDescriptorArray(isolate->heap(), *this, descriptors, number_of_own_descriptors); +#endif } // static diff --git a/deps/v8/src/objects/map.h b/deps/v8/src/objects/map.h index ef16019685f1c2..0daadbee088bb7 100644 --- a/deps/v8/src/objects/map.h +++ b/deps/v8/src/objects/map.h @@ -8,6 +8,7 @@ #include "src/common/globals.h" #include "src/objects/code.h" #include "src/objects/heap-object.h" +#include "src/objects/internal-index.h" #include "src/objects/objects.h" #include "torque-generated/field-offsets-tq.h" @@ -470,7 +471,8 @@ class Map : public HeapObject { Map GetPrototypeChainRootMap(Isolate* isolate) const; V8_EXPORT_PRIVATE Map FindRootMap(Isolate* isolate) const; - V8_EXPORT_PRIVATE Map FindFieldOwner(Isolate* isolate, int descriptor) const; + V8_EXPORT_PRIVATE Map FindFieldOwner(Isolate* isolate, + InternalIndex descriptor) const; inline int GetInObjectPropertyOffset(int index) const; @@ -513,7 +515,8 @@ class Map : public HeapObject { Representation rep1, Handle<FieldType> type1, Representation rep2, Handle<FieldType> type2, Isolate* isolate); static void GeneralizeField(Isolate* isolate, Handle<Map> map, - int modify_index, PropertyConstness new_constness, + InternalIndex modify_index, + PropertyConstness new_constness, Representation new_representation, Handle<FieldType> new_field_type); // Returns true if the |field_type| is the most general one for @@ -533,7 +536,7 @@ class Map : public HeapObject { Representation* representation, Handle<FieldType>* field_type); V8_EXPORT_PRIVATE static Handle<Map> ReconfigureProperty( - Isolate* isolate, Handle<Map> map, int modify_index, + Isolate* isolate, Handle<Map> map, InternalIndex modify_index, PropertyKind new_kind, PropertyAttributes new_attributes, Representation new_representation, Handle<FieldType> new_field_type); @@ -541,7 +544,7 @@ class Map : public HeapObject { Isolate* isolate, Handle<Map> map, ElementsKind new_elements_kind); V8_EXPORT_PRIVATE static Handle<Map> PrepareForDataProperty( - Isolate* isolate, Handle<Map> old_map, int descriptor_number, + Isolate* isolate, Handle<Map> old_map, InternalIndex descriptor_number, PropertyConstness constness, Handle<Object> value); V8_EXPORT_PRIVATE static Handle<Map> Normalize(Isolate* isolate, @@ -636,10 +639,11 @@ class Map : public HeapObject { inline PropertyDetails GetLastDescriptorDetails(Isolate* isolate) const; - inline int LastAdded() const; + inline InternalIndex LastAdded() const; inline int NumberOfOwnDescriptors() const; inline void SetNumberOfOwnDescriptors(int number); + inline InternalIndex::Range IterateOwnDescriptors() const; inline Cell RetrieveDescriptorsPointer(); @@ -742,12 +746,13 @@ class Map : public HeapObject { Handle<Object> value, PropertyAttributes attributes, PropertyConstness constness, StoreOrigin store_origin); V8_EXPORT_PRIVATE static Handle<Map> TransitionToAccessorProperty( - Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor, - Handle<Object> getter, Handle<Object> setter, + Isolate* isolate, Handle<Map> map, Handle<Name> name, + InternalIndex descriptor, Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes); V8_EXPORT_PRIVATE static Handle<Map> ReconfigureExistingProperty( - Isolate* isolate, Handle<Map> map, int descriptor, PropertyKind kind, - PropertyAttributes attributes, PropertyConstness constness); + Isolate* isolate, Handle<Map> map, InternalIndex descriptor, + PropertyKind kind, PropertyAttributes attributes, + PropertyConstness constness); inline void AppendDescriptor(Isolate* isolate, Descriptor* desc); @@ -881,9 +886,6 @@ class Map : public HeapObject { InstanceType instance_type); inline bool CanHaveFastTransitionableElementsKind() const; - // Whether this is the map of the given native context's global proxy. - bool IsMapOfGlobalProxy(Handle<NativeContext> native_context) const; - private: // This byte encodes either the instance size without the in-object slack or // the slack size in properties backing store. @@ -925,7 +927,7 @@ class Map : public HeapObject { Handle<LayoutDescriptor> full_layout_descriptor); static void InstallDescriptors( Isolate* isolate, Handle<Map> parent_map, Handle<Map> child_map, - int new_descriptor, Handle<DescriptorArray> descriptors, + InternalIndex new_descriptor, Handle<DescriptorArray> descriptors, Handle<LayoutDescriptor> full_layout_descriptor); static Handle<Map> CopyAddDescriptor(Isolate* isolate, Handle<Map> map, Descriptor* descriptor, @@ -938,7 +940,8 @@ class Map : public HeapObject { static Handle<Map> CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors, - Descriptor* descriptor, int index, + Descriptor* descriptor, + InternalIndex index, TransitionFlag flag); static Handle<Map> CopyNormalized(Isolate* isolate, Handle<Map> map, PropertyNormalizationMode mode); @@ -951,22 +954,24 @@ class Map : public HeapObject { // Update field type of the given descriptor to new representation and new // type. The type must be prepared for storing in descriptor array: // it must be either a simple type or a map wrapped in a weak cell. - void UpdateFieldType(Isolate* isolate, int descriptor_number, + void UpdateFieldType(Isolate* isolate, InternalIndex descriptor_number, Handle<Name> name, PropertyConstness new_constness, Representation new_representation, const MaybeObjectHandle& new_wrapped_type); // TODO(ishell): Move to MapUpdater. - void PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index, - PropertyKind kind, PropertyAttributes attributes); + void PrintReconfiguration(Isolate* isolate, FILE* file, + InternalIndex modify_index, PropertyKind kind, + PropertyAttributes attributes); // TODO(ishell): Move to MapUpdater. void PrintGeneralization( - Isolate* isolate, FILE* file, const char* reason, int modify_index, - int split, int descriptors, bool constant_to_field, - Representation old_representation, Representation new_representation, - PropertyConstness old_constness, PropertyConstness new_constness, - MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value, - MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value); + Isolate* isolate, FILE* file, const char* reason, + InternalIndex modify_index, int split, int descriptors, + bool constant_to_field, Representation old_representation, + Representation new_representation, PropertyConstness old_constness, + PropertyConstness new_constness, MaybeHandle<FieldType> old_field_type, + MaybeHandle<Object> old_value, MaybeHandle<FieldType> new_field_type, + MaybeHandle<Object> new_value); // Use the high-level instance_descriptors/SetInstanceDescriptors instead. DECL_ACCESSORS(synchronized_instance_descriptors, DescriptorArray) diff --git a/deps/v8/src/objects/module-inl.h b/deps/v8/src/objects/module-inl.h index ac5451637666e5..aaf790cc8ac45c 100644 --- a/deps/v8/src/objects/module-inl.h +++ b/deps/v8/src/objects/module-inl.h @@ -38,9 +38,17 @@ SMI_ACCESSORS(Module, hash, kHashOffset) TQ_SMI_ACCESSORS(SourceTextModule, dfs_index) TQ_SMI_ACCESSORS(SourceTextModule, dfs_ancestor_index) +TQ_SMI_ACCESSORS(SourceTextModule, flags) +BOOL_ACCESSORS(SourceTextModule, flags, async, kAsyncBit) +BOOL_ACCESSORS(SourceTextModule, flags, async_evaluating, kAsyncEvaluatingBit) +TQ_SMI_ACCESSORS(SourceTextModule, pending_async_dependencies) +ACCESSORS(SourceTextModule, async_parent_modules, ArrayList, + kAsyncParentModulesOffset) +ACCESSORS(SourceTextModule, top_level_capability, HeapObject, + kTopLevelCapabilityOffset) SourceTextModuleInfo SourceTextModule::info() const { - return (status() >= kEvaluating) + return status() == kErrored ? SourceTextModuleInfo::cast(code()) : GetSharedFunctionInfo().scope_info().ModuleDescriptorInfo(); } @@ -112,6 +120,37 @@ class UnorderedModuleSet ZoneAllocator<Handle<Module>>(zone)) {} }; +void SourceTextModule::AddAsyncParentModule(Isolate* isolate, + Handle<SourceTextModule> module) { + Handle<ArrayList> new_array_list = + ArrayList::Add(isolate, handle(async_parent_modules(), isolate), module); + set_async_parent_modules(*new_array_list); +} + +Handle<SourceTextModule> SourceTextModule::GetAsyncParentModule( + Isolate* isolate, int index) { + Handle<SourceTextModule> module( + SourceTextModule::cast(async_parent_modules().Get(index)), isolate); + return module; +} + +int SourceTextModule::AsyncParentModuleCount() { + return async_parent_modules().Length(); +} + +bool SourceTextModule::HasPendingAsyncDependencies() { + DCHECK_GE(pending_async_dependencies(), 0); + return pending_async_dependencies() > 0; +} + +void SourceTextModule::IncrementPendingAsyncDependencies() { + set_pending_async_dependencies(pending_async_dependencies() + 1); +} + +void SourceTextModule::DecrementPendingAsyncDependencies() { + set_pending_async_dependencies(pending_async_dependencies() - 1); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/objects/module.cc b/deps/v8/src/objects/module.cc index 60b9145d10181e..9c37de0c855dd0 100644 --- a/deps/v8/src/objects/module.cc +++ b/deps/v8/src/objects/module.cc @@ -10,6 +10,7 @@ #include "src/api/api-inl.h" #include "src/ast/modules.h" #include "src/builtins/accessors.h" +#include "src/heap/heap-inl.h" #include "src/objects/cell-inl.h" #include "src/objects/hash-table-inl.h" #include "src/objects/js-generator-inl.h" @@ -50,12 +51,14 @@ void Module::SetStatus(Status new_status) { set_status(new_status); } -void Module::RecordError(Isolate* isolate) { - DisallowHeapAllocation no_alloc; - DCHECK(exception().IsTheHole(isolate)); - Object the_exception = isolate->pending_exception(); - DCHECK(!the_exception.IsTheHole(isolate)); +void Module::RecordErrorUsingPendingException(Isolate* isolate) { + Handle<Object> the_exception(isolate->pending_exception(), isolate); + RecordError(isolate, the_exception); +} +void Module::RecordError(Isolate* isolate, Handle<Object> error) { + DCHECK(exception().IsTheHole(isolate)); + DCHECK(!error->IsTheHole(isolate)); if (this->IsSourceTextModule()) { Handle<SourceTextModule> self(SourceTextModule::cast(*this), GetIsolate()); self->set_code(self->info()); @@ -64,7 +67,7 @@ void Module::RecordError(Isolate* isolate) { PrintStatusTransition(Module::kErrored); #endif // DEBUG set_status(Module::kErrored); - set_exception(the_exception); + set_exception(*error); } void Module::ResetGraph(Isolate* isolate, Handle<Module> module) { @@ -244,46 +247,35 @@ MaybeHandle<Object> Module::Evaluate(Isolate* isolate, Handle<Module> module) { #endif // OBJECT_PRINT } #endif // DEBUG - if (module->status() == kErrored) { - isolate->Throw(module->GetException()); - return MaybeHandle<Object>(); - } - DCHECK_NE(module->status(), kEvaluating); - DCHECK_GE(module->status(), kInstantiated); - Zone zone(isolate->allocator(), ZONE_NAME); - - ZoneForwardList<Handle<SourceTextModule>> stack(&zone); - unsigned dfs_index = 0; - Handle<Object> result; - if (!Evaluate(isolate, module, &stack, &dfs_index).ToHandle(&result)) { - for (auto& descendant : stack) { - DCHECK_EQ(descendant->status(), kEvaluating); - descendant->RecordError(isolate); - } - DCHECK_EQ(module->GetException(), isolate->pending_exception()); - return MaybeHandle<Object>(); + STACK_CHECK(isolate, MaybeHandle<Object>()); + if (FLAG_harmony_top_level_await && module->IsSourceTextModule()) { + return SourceTextModule::EvaluateMaybeAsync( + isolate, Handle<SourceTextModule>::cast(module)); + } else { + return Module::InnerEvaluate(isolate, module); } - DCHECK_EQ(module->status(), kEvaluated); - DCHECK(stack.empty()); - return result; } -MaybeHandle<Object> Module::Evaluate( - Isolate* isolate, Handle<Module> module, - ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index) { +MaybeHandle<Object> Module::InnerEvaluate(Isolate* isolate, + Handle<Module> module) { if (module->status() == kErrored) { isolate->Throw(module->GetException()); return MaybeHandle<Object>(); - } - if (module->status() >= kEvaluating) { + } else if (module->status() == kEvaluated) { return isolate->factory()->undefined_value(); } - DCHECK_EQ(module->status(), kInstantiated); - STACK_CHECK(isolate, MaybeHandle<Object>()); + + // InnerEvaluate can be called both to evaluate top level modules without + // the harmony_top_level_await flag and recursively to evaluate + // SyntheticModules in the dependency graphs of SourceTextModules. + // + // However, SyntheticModules transition directly to 'Evaluated,' so we should + // never see an 'Evaluating' module at this point. + CHECK_EQ(module->status(), kInstantiated); if (module->IsSourceTextModule()) { - return SourceTextModule::Evaluate( - isolate, Handle<SourceTextModule>::cast(module), stack, dfs_index); + return SourceTextModule::Evaluate(isolate, + Handle<SourceTextModule>::cast(module)); } else { return SyntheticModule::Evaluate(isolate, Handle<SyntheticModule>::cast(module)); diff --git a/deps/v8/src/objects/module.h b/deps/v8/src/objects/module.h index 08badf0357d220..d0ea22e6e58235 100644 --- a/deps/v8/src/objects/module.h +++ b/deps/v8/src/objects/module.h @@ -112,18 +112,19 @@ class Module : public HeapObject { ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index, Zone* zone); - static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate( - Isolate* isolate, Handle<Module> module, - ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index); + static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerEvaluate( + Isolate* isolate, Handle<Module> module); // Set module's status back to kUninstantiated and reset other internal state. // This is used when instantiation fails. static void Reset(Isolate* isolate, Handle<Module> module); static void ResetGraph(Isolate* isolate, Handle<Module> module); - // To set status to kErrored, RecordError should be used. + // To set status to kErrored, RecordError or RecordErrorUsingPendingException + // should be used. void SetStatus(Status status); - void RecordError(Isolate* isolate); + void RecordErrorUsingPendingException(Isolate* isolate); + void RecordError(Isolate* isolate, Handle<Object> error); #ifdef DEBUG // For --trace-module-status. @@ -137,7 +138,8 @@ class Module : public HeapObject { // JSModuleNamespace object (representing module "bar") is created and bound to // the declared variable (foo). A module can have at most one namespace object. class JSModuleNamespace - : public TorqueGeneratedJSModuleNamespace<JSModuleNamespace, JSObject> { + : public TorqueGeneratedJSModuleNamespace<JSModuleNamespace, + JSSpecialObject> { public: DECL_PRINTER(JSModuleNamespace) diff --git a/deps/v8/src/objects/name-inl.h b/deps/v8/src/objects/name-inl.h index b76ae245a2d7f5..88ae2feea58b61 100644 --- a/deps/v8/src/objects/name-inl.h +++ b/deps/v8/src/objects/name-inl.h @@ -9,6 +9,7 @@ #include "src/heap/heap-write-barrier-inl.h" #include "src/objects/map-inl.h" +#include "src/objects/primitive-heap-object-inl.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -100,6 +101,10 @@ bool Name::AsArrayIndex(uint32_t* index) { return IsString() && String::cast(*this).AsArrayIndex(index); } +bool Name::AsIntegerIndex(size_t* index) { + return IsString() && String::cast(*this).AsIntegerIndex(index); +} + // static bool Name::ContainsCachedArrayIndex(uint32_t hash) { return (hash & Name::kDoesNotContainCachedArrayIndexMask) == 0; diff --git a/deps/v8/src/objects/name.h b/deps/v8/src/objects/name.h index a02bb3d794520a..386b9ec0556033 100644 --- a/deps/v8/src/objects/name.h +++ b/deps/v8/src/objects/name.h @@ -5,9 +5,8 @@ #ifndef V8_OBJECTS_NAME_H_ #define V8_OBJECTS_NAME_H_ -#include "src/objects/heap-object.h" #include "src/objects/objects.h" -#include "torque-generated/class-definitions-tq.h" +#include "src/objects/primitive-heap-object.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -17,7 +16,7 @@ namespace internal { // The Name abstract class captures anything that can be used as a property // name, i.e., strings and symbols. All names store a hash value. -class Name : public TorqueGeneratedName<Name, HeapObject> { +class Name : public TorqueGeneratedName<Name, PrimitiveHeapObject> { public: // Tells whether the hash code has been computed. inline bool HasHashCode(); @@ -32,6 +31,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { // Conversion. inline bool AsArrayIndex(uint32_t* index); + inline bool AsIntegerIndex(size_t* index); // An "interesting symbol" is a well-known symbol, like @@toStringTag, // that's often looked up on random objects but is usually not present. @@ -73,7 +73,8 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { // array index. static const int kHashNotComputedMask = 1; static const int kIsNotArrayIndexMask = 1 << 1; - static const int kNofHashBitFields = 2; + static const int kIsNotIntegerIndexMask = 1 << 2; + static const int kNofHashBitFields = 3; // Shift constant retrieving hash code from hash field. static const int kHashShift = kNofHashBitFields; @@ -88,6 +89,14 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { // Maximum number of characters to consider when trying to convert a string // value into an array index. static const int kMaxArrayIndexSize = 10; + // Maximum number of characters that might be parsed into a size_t: + // 10 characters per 32 bits of size_t width. + // We choose this as large as possible (rather than MAX_SAFE_INTEGER range) + // because TypedArray accesses will treat all string keys that are + // canonical representations of numbers in the range [MAX_SAFE_INTEGER .. + // size_t::max] as out-of-bounds accesses, and we can handle those in the + // fast path if we tag them as such (see kIsNotIntegerIndexMask). + static const int kMaxIntegerIndexSize = 10 * (sizeof(size_t) / 4); // For strings which are array indexes the hash value has the string length // mixed into the hash, mainly to avoid a hash value of zero which would be @@ -120,7 +129,7 @@ class Name : public TorqueGeneratedName<Name, HeapObject> { // Value of empty hash field indicating that the hash is not computed. static const int kEmptyHashField = - kIsNotArrayIndexMask | kHashNotComputedMask; + kIsNotIntegerIndexMask | kIsNotArrayIndexMask | kHashNotComputedMask; protected: static inline bool IsHashFieldComputed(uint32_t field); diff --git a/deps/v8/src/objects/object-list-macros.h b/deps/v8/src/objects/object-list-macros.h index d5bce62d43393f..09b1bdc5f05a36 100644 --- a/deps/v8/src/objects/object-list-macros.h +++ b/deps/v8/src/objects/object-list-macros.h @@ -41,6 +41,7 @@ class HeapNumber; class ObjectHashTable; class ObjectTemplateInfo; class ObjectVisitor; +class OSROptimizedCodeCache; class PreparseData; class PropertyArray; class PropertyCell; @@ -138,12 +139,14 @@ class ZoneForwardList; V(JSCollection) \ V(JSCollectionIterator) \ V(JSContextExtensionObject) \ + V(JSCustomElementsObject) \ V(JSDataView) \ V(JSDate) \ V(JSError) \ V(JSFinalizationGroup) \ V(JSFinalizationGroupCleanupIterator) \ V(JSFunction) \ + V(JSFunctionOrBoundFunction) \ V(JSGeneratorObject) \ V(JSGlobalObject) \ V(JSGlobalProxy) \ @@ -158,10 +161,12 @@ class ZoneForwardList; V(JSReceiver) \ V(JSRegExp) \ V(JSRegExpResult) \ + V(JSRegExpResultIndices) \ V(JSRegExpStringIterator) \ V(JSSet) \ V(JSSetIterator) \ V(JSSloppyArgumentsObject) \ + V(JSSpecialObject) \ V(JSStringIterator) \ V(JSTypedArray) \ V(JSWeakCollection) \ @@ -185,7 +190,9 @@ class ZoneForwardList; V(OrderedHashMap) \ V(OrderedHashSet) \ V(OrderedNameDictionary) \ + V(OSROptimizedCodeCache) \ V(PreparseData) \ + V(PrimitiveHeapObject) \ V(PromiseReactionJobTask) \ V(PropertyArray) \ V(PropertyCell) \ @@ -225,6 +232,7 @@ class ZoneForwardList; V(Undetectable) \ V(UniqueName) \ V(WasmExceptionObject) \ + V(WasmExceptionPackage) \ V(WasmGlobalObject) \ V(WasmInstanceObject) \ V(WasmMemoryObject) \ diff --git a/deps/v8/src/objects/objects-body-descriptors-inl.h b/deps/v8/src/objects/objects-body-descriptors-inl.h index 4c980b2697c87b..68164fdce67ffe 100644 --- a/deps/v8/src/objects/objects-body-descriptors-inl.h +++ b/deps/v8/src/objects/objects-body-descriptors-inl.h @@ -913,7 +913,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3, p4); case JS_OBJECT_TYPE: case JS_ERROR_TYPE: - case JS_ARGUMENTS_TYPE: + case JS_ARGUMENTS_OBJECT_TYPE: case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE: case JS_PROMISE_TYPE: case JS_CONTEXT_EXTENSION_OBJECT_TYPE: @@ -933,8 +933,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { case JS_MAP_KEY_VALUE_ITERATOR_TYPE: case JS_MAP_VALUE_ITERATOR_TYPE: case JS_STRING_ITERATOR_TYPE: - case JS_REGEXP_STRING_ITERATOR_TYPE: - case JS_REGEXP_TYPE: + case JS_REG_EXP_STRING_ITERATOR_TYPE: + case JS_REG_EXP_TYPE: case JS_GLOBAL_PROXY_TYPE: case JS_GLOBAL_OBJECT_TYPE: case JS_API_OBJECT_TYPE: @@ -944,24 +944,24 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) { case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE: case JS_FINALIZATION_GROUP_TYPE: #ifdef V8_INTL_SUPPORT - case JS_INTL_V8_BREAK_ITERATOR_TYPE: - case JS_INTL_COLLATOR_TYPE: - case JS_INTL_DATE_TIME_FORMAT_TYPE: - case JS_INTL_LIST_FORMAT_TYPE: - case JS_INTL_LOCALE_TYPE: - case JS_INTL_NUMBER_FORMAT_TYPE: - case JS_INTL_PLURAL_RULES_TYPE: - case JS_INTL_RELATIVE_TIME_FORMAT_TYPE: - case JS_INTL_SEGMENT_ITERATOR_TYPE: - case JS_INTL_SEGMENTER_TYPE: + case JS_V8_BREAK_ITERATOR_TYPE: + case JS_COLLATOR_TYPE: + case JS_DATE_TIME_FORMAT_TYPE: + case JS_LIST_FORMAT_TYPE: + case JS_LOCALE_TYPE: + case JS_NUMBER_FORMAT_TYPE: + case JS_PLURAL_RULES_TYPE: + case JS_RELATIVE_TIME_FORMAT_TYPE: + case JS_SEGMENT_ITERATOR_TYPE: + case JS_SEGMENTER_TYPE: #endif // V8_INTL_SUPPORT - case WASM_EXCEPTION_TYPE: - case WASM_GLOBAL_TYPE: - case WASM_MEMORY_TYPE: - case WASM_MODULE_TYPE: - case WASM_TABLE_TYPE: + case WASM_EXCEPTION_OBJECT_TYPE: + case WASM_GLOBAL_OBJECT_TYPE: + case WASM_MEMORY_OBJECT_TYPE: + case WASM_MODULE_OBJECT_TYPE: + case WASM_TABLE_OBJECT_TYPE: return Op::template apply<JSObject::BodyDescriptor>(p1, p2, p3, p4); - case WASM_INSTANCE_TYPE: + case WASM_INSTANCE_OBJECT_TYPE: return Op::template apply<WasmInstanceObject::BodyDescriptor>(p1, p2, p3, p4); case JS_WEAK_MAP_TYPE: diff --git a/deps/v8/src/objects/objects-definitions.h b/deps/v8/src/objects/objects-definitions.h index b346b5b7d15188..53354014e9c197 100644 --- a/deps/v8/src/objects/objects-definitions.h +++ b/deps/v8/src/objects/objects-definitions.h @@ -32,15 +32,7 @@ namespace internal { // instance_types that are less than those of all other types: // HeapObject::Size, HeapObject::IterateBody, the typeof operator, and // Object::IsString. -// -// NOTE: Everything following JS_PRIMITIVE_WRAPPER_TYPE is considered a -// JSObject for GC purposes. The first four entries here have typeof -// 'object', whereas JS_FUNCTION_TYPE has typeof 'function'. -// -// NOTE: List had to be split into two, because of conditional item(s) from -// INTL namespace. They can't just be appended to the end, because of the -// checks we do in tests (expecting JS_FUNCTION_TYPE to be last). -#define INSTANCE_TYPE_LIST_BEFORE_INTL(V) \ +#define INSTANCE_TYPE_LIST_BASE(V) \ V(INTERNALIZED_STRING_TYPE) \ V(EXTERNAL_INTERNALIZED_STRING_TYPE) \ V(ONE_BYTE_INTERNALIZED_STRING_TYPE) \ @@ -58,191 +50,11 @@ namespace internal { V(SLICED_ONE_BYTE_STRING_TYPE) \ V(THIN_ONE_BYTE_STRING_TYPE) \ V(UNCACHED_EXTERNAL_STRING_TYPE) \ - V(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE) \ - \ - V(SYMBOL_TYPE) \ - V(HEAP_NUMBER_TYPE) \ - V(BIGINT_TYPE) \ - V(ODDBALL_TYPE) \ - \ - V(MAP_TYPE) \ - V(CODE_TYPE) \ - V(FOREIGN_TYPE) \ - V(BYTE_ARRAY_TYPE) \ - V(BYTECODE_ARRAY_TYPE) \ - V(FREE_SPACE_TYPE) \ - \ - V(FIXED_DOUBLE_ARRAY_TYPE) \ - V(FEEDBACK_METADATA_TYPE) \ - V(FILLER_TYPE) \ - \ - V(ACCESS_CHECK_INFO_TYPE) \ - V(ACCESSOR_INFO_TYPE) \ - V(ACCESSOR_PAIR_TYPE) \ - V(ALIASED_ARGUMENTS_ENTRY_TYPE) \ - V(ALLOCATION_MEMENTO_TYPE) \ - V(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) \ - V(ASM_WASM_DATA_TYPE) \ - V(ASYNC_GENERATOR_REQUEST_TYPE) \ - V(CLASS_POSITIONS_TYPE) \ - V(DEBUG_INFO_TYPE) \ - V(ENUM_CACHE_TYPE) \ - V(FUNCTION_TEMPLATE_INFO_TYPE) \ - V(FUNCTION_TEMPLATE_RARE_DATA_TYPE) \ - V(INTERCEPTOR_INFO_TYPE) \ - V(INTERPRETER_DATA_TYPE) \ - V(OBJECT_TEMPLATE_INFO_TYPE) \ - V(PROMISE_CAPABILITY_TYPE) \ - V(PROMISE_REACTION_TYPE) \ - V(PROTOTYPE_INFO_TYPE) \ - V(SCRIPT_TYPE) \ - V(SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE) \ - V(SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE) \ - V(STACK_FRAME_INFO_TYPE) \ - V(STACK_TRACE_FRAME_TYPE) \ - V(TEMPLATE_OBJECT_DESCRIPTION_TYPE) \ - V(TUPLE2_TYPE) \ - V(TUPLE3_TYPE) \ - V(WASM_CAPI_FUNCTION_DATA_TYPE) \ - V(WASM_DEBUG_INFO_TYPE) \ - V(WASM_EXCEPTION_TAG_TYPE) \ - V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \ - V(WASM_INDIRECT_FUNCTION_TABLE_TYPE) \ - V(WASM_JS_FUNCTION_DATA_TYPE) \ - \ - V(CALLABLE_TASK_TYPE) \ - V(CALLBACK_TASK_TYPE) \ - V(PROMISE_FULFILL_REACTION_JOB_TASK_TYPE) \ - V(PROMISE_REJECT_REACTION_JOB_TASK_TYPE) \ - V(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE) \ - \ - TORQUE_DEFINED_INSTANCE_TYPES(V) \ - \ - V(SOURCE_TEXT_MODULE_TYPE) \ - V(SYNTHETIC_MODULE_TYPE) \ - \ - V(ALLOCATION_SITE_TYPE) \ - V(EMBEDDER_DATA_ARRAY_TYPE) \ - \ - V(FIXED_ARRAY_TYPE) \ - V(OBJECT_BOILERPLATE_DESCRIPTION_TYPE) \ - V(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE) \ - V(HASH_TABLE_TYPE) \ - V(ORDERED_HASH_MAP_TYPE) \ - V(ORDERED_HASH_SET_TYPE) \ - V(ORDERED_NAME_DICTIONARY_TYPE) \ - V(NAME_DICTIONARY_TYPE) \ - V(GLOBAL_DICTIONARY_TYPE) \ - V(NUMBER_DICTIONARY_TYPE) \ - V(SIMPLE_NUMBER_DICTIONARY_TYPE) \ - V(STRING_TABLE_TYPE) \ - V(EPHEMERON_HASH_TABLE_TYPE) \ - V(SCOPE_INFO_TYPE) \ - V(SCRIPT_CONTEXT_TABLE_TYPE) \ - \ - V(AWAIT_CONTEXT_TYPE) \ - V(BLOCK_CONTEXT_TYPE) \ - V(CATCH_CONTEXT_TYPE) \ - V(DEBUG_EVALUATE_CONTEXT_TYPE) \ - V(EVAL_CONTEXT_TYPE) \ - V(FUNCTION_CONTEXT_TYPE) \ - V(MODULE_CONTEXT_TYPE) \ - V(NATIVE_CONTEXT_TYPE) \ - V(SCRIPT_CONTEXT_TYPE) \ - V(WITH_CONTEXT_TYPE) \ - \ - V(WEAK_FIXED_ARRAY_TYPE) \ - V(TRANSITION_ARRAY_TYPE) \ - \ - V(CALL_HANDLER_INFO_TYPE) \ - V(CELL_TYPE) \ - V(CODE_DATA_CONTAINER_TYPE) \ - V(DESCRIPTOR_ARRAY_TYPE) \ - V(FEEDBACK_CELL_TYPE) \ - V(FEEDBACK_VECTOR_TYPE) \ - V(LOAD_HANDLER_TYPE) \ - V(PREPARSE_DATA_TYPE) \ - V(PROPERTY_ARRAY_TYPE) \ - V(PROPERTY_CELL_TYPE) \ - V(SHARED_FUNCTION_INFO_TYPE) \ - V(SMALL_ORDERED_HASH_MAP_TYPE) \ - V(SMALL_ORDERED_HASH_SET_TYPE) \ - V(SMALL_ORDERED_NAME_DICTIONARY_TYPE) \ - V(STORE_HANDLER_TYPE) \ - V(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE) \ - V(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE) \ - V(WEAK_ARRAY_LIST_TYPE) \ - V(WEAK_CELL_TYPE) \ - \ - V(JS_PROXY_TYPE) \ - V(JS_GLOBAL_OBJECT_TYPE) \ - V(JS_GLOBAL_PROXY_TYPE) \ - V(JS_MODULE_NAMESPACE_TYPE) \ - V(JS_SPECIAL_API_OBJECT_TYPE) \ - V(JS_PRIMITIVE_WRAPPER_TYPE) \ - V(JS_API_OBJECT_TYPE) \ - V(JS_OBJECT_TYPE) \ - \ - V(JS_ARGUMENTS_TYPE) \ - V(JS_ARRAY_BUFFER_TYPE) \ - V(JS_ARRAY_ITERATOR_TYPE) \ - V(JS_ARRAY_TYPE) \ - V(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE) \ - V(JS_ASYNC_FUNCTION_OBJECT_TYPE) \ - V(JS_ASYNC_GENERATOR_OBJECT_TYPE) \ - V(JS_CONTEXT_EXTENSION_OBJECT_TYPE) \ - V(JS_DATE_TYPE) \ - V(JS_ERROR_TYPE) \ - V(JS_GENERATOR_OBJECT_TYPE) \ - V(JS_MAP_TYPE) \ - V(JS_MAP_KEY_ITERATOR_TYPE) \ - V(JS_MAP_KEY_VALUE_ITERATOR_TYPE) \ - V(JS_MAP_VALUE_ITERATOR_TYPE) \ - V(JS_MESSAGE_OBJECT_TYPE) \ - V(JS_PROMISE_TYPE) \ - V(JS_REGEXP_TYPE) \ - V(JS_REGEXP_STRING_ITERATOR_TYPE) \ - V(JS_SET_TYPE) \ - V(JS_SET_KEY_VALUE_ITERATOR_TYPE) \ - V(JS_SET_VALUE_ITERATOR_TYPE) \ - V(JS_STRING_ITERATOR_TYPE) \ - V(JS_WEAK_REF_TYPE) \ - V(JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE) \ - V(JS_FINALIZATION_GROUP_TYPE) \ - V(JS_WEAK_MAP_TYPE) \ - V(JS_WEAK_SET_TYPE) \ - V(JS_TYPED_ARRAY_TYPE) \ - V(JS_DATA_VIEW_TYPE) + V(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE) -#define INSTANCE_TYPE_LIST_AFTER_INTL(V) \ - V(WASM_EXCEPTION_TYPE) \ - V(WASM_GLOBAL_TYPE) \ - V(WASM_INSTANCE_TYPE) \ - V(WASM_MEMORY_TYPE) \ - V(WASM_MODULE_TYPE) \ - V(WASM_TABLE_TYPE) \ - V(JS_BOUND_FUNCTION_TYPE) \ - V(JS_FUNCTION_TYPE) - -#ifdef V8_INTL_SUPPORT -#define INSTANCE_TYPE_LIST(V) \ - INSTANCE_TYPE_LIST_BEFORE_INTL(V) \ - V(JS_INTL_V8_BREAK_ITERATOR_TYPE) \ - V(JS_INTL_COLLATOR_TYPE) \ - V(JS_INTL_DATE_TIME_FORMAT_TYPE) \ - V(JS_INTL_LIST_FORMAT_TYPE) \ - V(JS_INTL_LOCALE_TYPE) \ - V(JS_INTL_NUMBER_FORMAT_TYPE) \ - V(JS_INTL_PLURAL_RULES_TYPE) \ - V(JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \ - V(JS_INTL_SEGMENT_ITERATOR_TYPE) \ - V(JS_INTL_SEGMENTER_TYPE) \ - INSTANCE_TYPE_LIST_AFTER_INTL(V) -#else -#define INSTANCE_TYPE_LIST(V) \ - INSTANCE_TYPE_LIST_BEFORE_INTL(V) \ - INSTANCE_TYPE_LIST_AFTER_INTL(V) -#endif // V8_INTL_SUPPORT +#define INSTANCE_TYPE_LIST(V) \ + INSTANCE_TYPE_LIST_BASE(V) \ + TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) // Since string types are not consecutive, this macro is used to // iterate over them. @@ -290,11 +102,20 @@ namespace internal { // code for the class including allocation and garbage collection routines, // casts and predicates. All you need to define is the class, methods and // object verification routines. Easy, no? -// -// Note that for subtle reasons related to the ordering or numerical values of -// type tags, elements in this list have to be added to the INSTANCE_TYPE_LIST -// manually. -#define STRUCT_LIST_GENERATOR(V, _) \ +#define STRUCT_LIST_GENERATOR_BASE(V, _) \ + V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \ + promise_fulfill_reaction_job_task) \ + V(_, PROMISE_REJECT_REACTION_JOB_TASK_TYPE, PromiseRejectReactionJobTask, \ + promise_reject_reaction_job_task) \ + V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \ + V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \ + V(_, PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, PromiseResolveThenableJobTask, \ + promise_resolve_thenable_job_task) \ + V(_, FUNCTION_TEMPLATE_INFO_TYPE, FunctionTemplateInfo, \ + function_template_info) \ + V(_, OBJECT_TEMPLATE_INFO_TYPE, ObjectTemplateInfo, object_template_info) \ + V(_, TUPLE2_TYPE, Tuple2, tuple2) \ + V(_, TUPLE3_TYPE, Tuple3, tuple3) \ V(_, ACCESS_CHECK_INFO_TYPE, AccessCheckInfo, access_check_info) \ V(_, ACCESSOR_INFO_TYPE, AccessorInfo, accessor_info) \ V(_, ACCESSOR_PAIR_TYPE, AccessorPair, accessor_pair) \ @@ -309,13 +130,10 @@ namespace internal { V(_, CLASS_POSITIONS_TYPE, ClassPositions, class_positions) \ V(_, DEBUG_INFO_TYPE, DebugInfo, debug_info) \ V(_, ENUM_CACHE_TYPE, EnumCache, enum_cache) \ - V(_, FUNCTION_TEMPLATE_INFO_TYPE, FunctionTemplateInfo, \ - function_template_info) \ V(_, FUNCTION_TEMPLATE_RARE_DATA_TYPE, FunctionTemplateRareData, \ function_template_rare_data) \ V(_, INTERCEPTOR_INFO_TYPE, InterceptorInfo, interceptor_info) \ V(_, INTERPRETER_DATA_TYPE, InterpreterData, interpreter_data) \ - V(_, OBJECT_TEMPLATE_INFO_TYPE, ObjectTemplateInfo, object_template_info) \ V(_, PROMISE_CAPABILITY_TYPE, PromiseCapability, promise_capability) \ V(_, PROMISE_REACTION_TYPE, PromiseReaction, promise_reaction) \ V(_, PROTOTYPE_INFO_TYPE, PrototypeInfo, prototype_info) \ @@ -328,8 +146,6 @@ namespace internal { V(_, STACK_TRACE_FRAME_TYPE, StackTraceFrame, stack_trace_frame) \ V(_, TEMPLATE_OBJECT_DESCRIPTION_TYPE, TemplateObjectDescription, \ template_object_description) \ - V(_, TUPLE2_TYPE, Tuple2, tuple2) \ - V(_, TUPLE3_TYPE, Tuple3, tuple3) \ V(_, WASM_CAPI_FUNCTION_DATA_TYPE, WasmCapiFunctionData, \ wasm_capi_function_data) \ V(_, WASM_DEBUG_INFO_TYPE, WasmDebugInfo, wasm_debug_info) \ @@ -338,32 +154,24 @@ namespace internal { wasm_exported_function_data) \ V(_, WASM_INDIRECT_FUNCTION_TABLE_TYPE, WasmIndirectFunctionTable, \ wasm_indirect_function_table) \ - V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) \ - V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \ - V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \ - V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \ - promise_fulfill_reaction_job_task) \ - V(_, PROMISE_REJECT_REACTION_JOB_TASK_TYPE, PromiseRejectReactionJobTask, \ - promise_reject_reaction_job_task) \ - V(_, PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, PromiseResolveThenableJobTask, \ - promise_resolve_thenable_job_task) + V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) + +#define STRUCT_LIST_GENERATOR(V, _) \ + STRUCT_LIST_GENERATOR_BASE(V, _) \ + TORQUE_STRUCT_LIST_GENERATOR(V, _) // Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_LIST entry #define STRUCT_LIST_ADAPTER(V, NAME, Name, name) V(NAME, Name, name) // Produces (NAME, Name, name) entries. -#define STRUCT_LIST(V) \ - STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V) \ - TORQUE_STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V) +#define STRUCT_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_LIST_ADAPTER, V) // Adapts one STRUCT_LIST_GENERATOR entry to the STRUCT_MAPS_LIST entry #define STRUCT_MAPS_LIST_ADAPTER(V, NAME, Name, name) \ V(Map, name##_map, Name##Map) // Produces (Map, struct_name_map, StructNameMap) entries -#define STRUCT_MAPS_LIST(V) \ - STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) \ - TORQUE_STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) +#define STRUCT_MAPS_LIST(V) STRUCT_LIST_GENERATOR(STRUCT_MAPS_LIST_ADAPTER, V) // // The following macros define list of allocation size objects and list of diff --git a/deps/v8/src/objects/objects-inl.h b/deps/v8/src/objects/objects-inl.h index cf8c3ffad25044..08f4a2b6f0943e 100644 --- a/deps/v8/src/objects/objects-inl.h +++ b/deps/v8/src/objects/objects-inl.h @@ -350,6 +350,13 @@ DEF_GETTER(HeapObject, IsDependentCode, bool) { return true; } +DEF_GETTER(HeapObject, IsOSROptimizedCodeCache, bool) { + if (!IsWeakFixedArray(isolate)) return false; + // There's actually no way to see the difference between a weak fixed array + // and a osr optimized code cache. + return true; +} + DEF_GETTER(HeapObject, IsAbstractCode, bool) { return IsBytecodeArray(isolate) || IsCode(isolate); } @@ -411,6 +418,12 @@ DEF_GETTER(HeapObject, IsSmallOrderedHashTable, bool) { IsSmallOrderedNameDictionary(isolate); } +DEF_GETTER(HeapObject, IsWasmExceptionPackage, bool) { + // It is not possible to check for the existence of certain properties on the + // underlying {JSReceiver} here because that requires calling handlified code. + return IsJSReceiver(isolate); +} + bool Object::IsPrimitive() const { if (IsSmi()) return true; HeapObject this_heap_object = HeapObject::cast(*this); @@ -506,7 +519,7 @@ bool Object::IsMinusZero() const { OBJECT_CONSTRUCTORS_IMPL(RegExpMatchInfo, FixedArray) OBJECT_CONSTRUCTORS_IMPL(ScopeInfo, FixedArray) -OBJECT_CONSTRUCTORS_IMPL(BigIntBase, HeapObject) +OBJECT_CONSTRUCTORS_IMPL(BigIntBase, PrimitiveHeapObject) OBJECT_CONSTRUCTORS_IMPL(BigInt, BigIntBase) OBJECT_CONSTRUCTORS_IMPL(FreshlyAllocatedBigInt, BigIntBase) @@ -756,11 +769,13 @@ void HeapObject::set_map(Map value) { #endif } set_map_word(MapWord::FromMap(value)); +#ifndef V8_DISABLE_WRITE_BARRIERS if (!value.is_null()) { // TODO(1600) We are passing kNullAddress as a slot because maps can never // be on an evacuation candidate. MarkingBarrier(*this, ObjectSlot(kNullAddress), value); } +#endif } DEF_GETTER(HeapObject, synchronized_map, Map) { @@ -774,11 +789,13 @@ void HeapObject::synchronized_set_map(Map value) { #endif } synchronized_set_map_word(MapWord::FromMap(value)); +#ifndef V8_DISABLE_WRITE_BARRIERS if (!value.is_null()) { // TODO(1600) We are passing kNullAddress as a slot because maps can never // be on an evacuation candidate. MarkingBarrier(*this, ObjectSlot(kNullAddress), value); } +#endif } // Unsafe accessor omitting write barrier. @@ -793,12 +810,14 @@ void HeapObject::set_map_no_write_barrier(Map value) { void HeapObject::set_map_after_allocation(Map value, WriteBarrierMode mode) { set_map_word(MapWord::FromMap(value)); +#ifndef V8_DISABLE_WRITE_BARRIERS if (mode != SKIP_WRITE_BARRIER) { DCHECK(!value.is_null()); // TODO(1600) We are passing kNullAddress as a slot because maps can never // be on an evacuation candidate. MarkingBarrier(*this, ObjectSlot(kNullAddress), value); } +#endif } ObjectSlot HeapObject::map_slot() const { diff --git a/deps/v8/src/objects/objects.cc b/deps/v8/src/objects/objects.cc index 134cb3998a5585..227cff8da47a33 100644 --- a/deps/v8/src/objects/objects.cc +++ b/deps/v8/src/objects/objects.cc @@ -65,6 +65,7 @@ #include "src/objects/lookup-inl.h" #include "src/objects/map-updater.h" #include "src/objects/objects-body-descriptors-inl.h" +#include "src/objects/property-details.h" #include "src/utils/identity-map.h" #ifdef V8_INTL_SUPPORT #include "src/objects/js-break-iterator.h" @@ -1770,7 +1771,7 @@ bool Object::IterationHasObservableEffects() { // Check that the ArrayPrototype hasn't been modified in a way that would // affect iteration. - if (!isolate->IsArrayIteratorLookupChainIntact()) return true; + if (!Protectors::IsArrayIteratorLookupChainIntact(isolate)) return true; // For FastPacked kinds, iteration will have the same effect as simply // accessing each property in order. @@ -1781,7 +1782,7 @@ bool Object::IterationHasObservableEffects() { // the prototype. This could have different results if the prototype has been // changed. if (IsHoleyElementsKind(array_kind) && - isolate->IsNoElementsProtectorIntact()) { + Protectors::IsNoElementsIntact(isolate)) { return false; } return true; @@ -2188,7 +2189,8 @@ int HeapObject::SizeFromMap(Map map) const { } if (IsInRange(instance_type, FIRST_CONTEXT_TYPE, LAST_CONTEXT_TYPE)) { if (instance_type == NATIVE_CONTEXT_TYPE) return NativeContext::kSize; - return Context::SizeFor(Context::unchecked_cast(*this).length()); + return Context::SizeFor( + Context::unchecked_cast(*this).synchronized_length()); } if (instance_type == ONE_BYTE_STRING_TYPE || instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) { @@ -2378,7 +2380,7 @@ bool HeapObject::IsExternal(Isolate* isolate) const { void DescriptorArray::GeneralizeAllFields() { int length = number_of_descriptors(); - for (int i = 0; i < length; i++) { + for (InternalIndex i : InternalIndex::Range(length)) { PropertyDetails details = GetDetails(i); details = details.CopyWithRepresentation(Representation::Tagged()); if (details.location() == kField) { @@ -3717,7 +3719,7 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( DescriptorArray::Allocate(isolate, size, slack); if (attributes != NONE) { - for (int i = 0; i < size; ++i) { + for (InternalIndex i : InternalIndex::Range(size)) { MaybeObject value_or_field_type = desc->GetValue(i); Name key = desc->GetKey(i); PropertyDetails details = desc->GetDetails(i); @@ -3737,7 +3739,7 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( descriptors->Set(i, key, value_or_field_type, details); } } else { - for (int i = 0; i < size; ++i) { + for (InternalIndex i : InternalIndex::Range(size)) { descriptors->CopyFrom(i, *desc); } } @@ -3760,21 +3762,17 @@ Handle<DescriptorArray> DescriptorArray::CopyForFastObjectClone( Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(isolate, size, slack); - for (int i = 0; i < size; ++i) { + for (InternalIndex i : InternalIndex::Range(size)) { Name key = src->GetKey(i); PropertyDetails details = src->GetDetails(i); + Representation new_representation = details.representation(); DCHECK(!key.IsPrivateName()); DCHECK(details.IsEnumerable()); DCHECK_EQ(details.kind(), kData); - - // Ensure the ObjectClone property details are NONE, and that all source - // details did not contain DONT_ENUM. - PropertyDetails new_details(kData, NONE, details.location(), - details.constness(), details.representation(), - details.field_index()); - // Do not propagate the field type of normal object fields from the - // original descriptors since FieldType changes don't create new maps. + // If the new representation is an in-place changeable field, make it + // generic as possible (under in-place changes) to avoid type confusion if + // the source representation changes after this feedback has been collected. MaybeObject type = src->GetValue(i); if (details.location() == PropertyLocation::kField) { type = MaybeObject::FromObject(FieldType::Any()); @@ -3783,13 +3781,15 @@ Handle<DescriptorArray> DescriptorArray::CopyForFastObjectClone( // need to generalize the descriptors here. That will also enable // us to skip the defensive copying of the target map whenever a // CloneObjectIC misses. - if (FLAG_modify_field_representation_inplace && - (new_details.representation().IsSmi() || - new_details.representation().IsHeapObject())) { - new_details = - new_details.CopyWithRepresentation(Representation::Tagged()); - } + new_representation = new_representation.MostGenericInPlaceChange(); } + + // Ensure the ObjectClone property details are NONE, and that all source + // details did not contain DONT_ENUM. + PropertyDetails new_details(kData, NONE, details.location(), + details.constness(), new_representation, + details.field_index()); + descriptors->Set(i, key, type, new_details); } @@ -3799,7 +3799,7 @@ Handle<DescriptorArray> DescriptorArray::CopyForFastObjectClone( } bool DescriptorArray::IsEqualUpTo(DescriptorArray desc, int nof_descriptors) { - for (int i = 0; i < nof_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(nof_descriptors)) { if (GetKey(i) != desc.GetKey(i) || GetValue(i) != desc.GetValue(i)) { return false; } @@ -3816,8 +3816,7 @@ bool DescriptorArray::IsEqualUpTo(DescriptorArray desc, int nof_descriptors) { Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate, Handle<FixedArray> array, int index, - Handle<Object> value, - AllocationType allocation) { + Handle<Object> value) { if (index < array->length()) { array->set(index, *value); return array; @@ -3827,7 +3826,7 @@ Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate, capacity = JSObject::NewElementsCapacity(capacity); } while (capacity <= index); Handle<FixedArray> new_array = - isolate->factory()->NewUninitializedFixedArray(capacity, allocation); + isolate->factory()->NewUninitializedFixedArray(capacity); array->CopyTo(0, *new_array, 0, array->length()); new_array->FillWithHoles(array->length(), new_array->length()); new_array->set(index, *value); @@ -3952,6 +3951,20 @@ Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate, return array; } +Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate, + Handle<WeakArrayList> array, + const MaybeObjectHandle& value1, + const MaybeObjectHandle& value2) { + int length = array->length(); + array = EnsureSpace(isolate, array, length + 2); + // Reload length; GC might have removed elements from the array. + length = array->length(); + array->Set(length, *value1); + array->Set(length + 1, *value2); + array->set_length(length + 2); + return array; +} + bool WeakArrayList::IsFull() { return length() == capacity(); } // static @@ -4147,12 +4160,10 @@ Handle<FrameArray> FrameArray::EnsureSpace(Isolate* isolate, Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate, int nof_descriptors, - int slack, - AllocationType allocation) { + int slack) { return nof_descriptors + slack == 0 ? isolate->factory()->empty_descriptor_array() - : isolate->factory()->NewDescriptorArray(nof_descriptors, slack, - allocation); + : isolate->factory()->NewDescriptorArray(nof_descriptors, slack); } void DescriptorArray::Initialize(EnumCache enum_cache, @@ -4174,8 +4185,8 @@ void DescriptorArray::ClearEnumCache() { set_enum_cache(GetReadOnlyRoots().empty_enum_cache()); } -void DescriptorArray::Replace(int index, Descriptor* descriptor) { - descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index)); +void DescriptorArray::Replace(InternalIndex index, Descriptor* descriptor) { + descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index.as_int())); Set(index, descriptor); } @@ -4193,7 +4204,7 @@ void DescriptorArray::InitializeOrChangeEnumCache( } } -void DescriptorArray::CopyFrom(int index, DescriptorArray src) { +void DescriptorArray::CopyFrom(InternalIndex index, DescriptorArray src) { PropertyDetails details = src.GetDetails(index); Set(index, src.GetKey(index), src.GetValue(index), details); } @@ -4304,7 +4315,7 @@ bool DescriptorArray::IsEqualTo(DescriptorArray other) { if (number_of_all_descriptors() != other.number_of_all_descriptors()) { return false; } - for (int i = 0; i < number_of_descriptors(); ++i) { + for (InternalIndex i : InternalIndex::Range(number_of_descriptors())) { if (GetKey(i) != other.GetKey(i)) return false; if (GetDetails(i).AsSmi() != other.GetDetails(i).AsSmi()) return false; if (GetValue(i) != other.GetValue(i)) return false; @@ -4507,6 +4518,7 @@ uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { value |= length << String::ArrayIndexLengthBits::kShift; DCHECK_EQ(value & String::kIsNotArrayIndexMask, 0); + DCHECK_EQ(value & String::kIsNotIntegerIndexMask, 0); DCHECK_EQ(length <= String::kMaxCachedArrayIndexLength, Name::ContainsCachedArrayIndex(value)); return value; @@ -4659,8 +4671,26 @@ bool Script::GetPositionInfo(int position, PositionInfo* info, // directly. if (type() == Script::TYPE_WASM) { DCHECK_LE(0, position); - return WasmModuleObject::cast(wasm_module_object()) - .GetPositionInfo(static_cast<uint32_t>(position), info); + wasm::NativeModule* native_module = wasm_native_module(); + const wasm::WasmModule* module = native_module->module(); + if (source_mapping_url().IsString()) { + if (module->functions.size() == 0) return false; + info->line = 0; + info->column = position; + info->line_start = module->functions[0].code.offset(); + info->line_end = module->functions.back().code.end_offset(); + return true; + } + int func_index = GetContainingWasmFunction(module, position); + if (func_index < 0) return false; + + const wasm::WasmFunction& function = module->functions[func_index]; + + info->line = func_index; + info->column = position - function.code.offset(); + info->line_start = function.code.offset(); + info->line_end = function.code.end_offset(); + return true; } if (line_ends().IsUndefined()) { @@ -4972,26 +5002,8 @@ void SharedFunctionInfo::ScriptIterator::Reset(Isolate* isolate, index_ = 0; } -SharedFunctionInfo::GlobalIterator::GlobalIterator(Isolate* isolate) - : isolate_(isolate), - script_iterator_(isolate), - noscript_sfi_iterator_(isolate->heap()->noscript_shared_function_infos()), - sfi_iterator_(isolate, script_iterator_.Next()) {} - -SharedFunctionInfo SharedFunctionInfo::GlobalIterator::Next() { - HeapObject next = noscript_sfi_iterator_.Next(); - if (!next.is_null()) return SharedFunctionInfo::cast(next); - for (;;) { - next = sfi_iterator_.Next(); - if (!next.is_null()) return SharedFunctionInfo::cast(next); - Script next_script = script_iterator_.Next(); - if (next_script.is_null()) return SharedFunctionInfo(); - sfi_iterator_.Reset(isolate_, next_script); - } -} - void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, - Handle<Object> script_object, + Handle<HeapObject> script_object, int function_literal_id, bool reset_preparsed_scope_data) { if (shared->script() == *script_object) return; @@ -5020,30 +5032,8 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared, } #endif list->Set(function_literal_id, HeapObjectReference::Weak(*shared)); - - // Remove shared function info from root array. - WeakArrayList noscript_list = - isolate->heap()->noscript_shared_function_infos(); - CHECK(noscript_list.RemoveOne(MaybeObjectHandle::Weak(shared))); } else { DCHECK(shared->script().IsScript()); - Handle<WeakArrayList> list = - isolate->factory()->noscript_shared_function_infos(); - -#ifdef DEBUG - if (FLAG_enable_slow_asserts) { - WeakArrayList::Iterator iterator(*list); - for (HeapObject next = iterator.Next(); !next.is_null(); - next = iterator.Next()) { - DCHECK_NE(next, *shared); - } - } -#endif // DEBUG - - list = - WeakArrayList::AddToEnd(isolate, list, MaybeObjectHandle::Weak(shared)); - - isolate->heap()->SetRootNoScriptSharedFunctionInfos(*list); // Remove shared function info from old script's list. Script old_script = Script::cast(shared->script()); @@ -5354,6 +5344,8 @@ void SharedFunctionInfo::InitFromFunctionLiteral( Scope* outer_scope = lit->scope()->GetOuterScopeWithContext(); if (outer_scope) { shared_info->set_outer_scope_info(*outer_scope->scope_info()); + shared_info->set_private_name_lookup_skips_outer_class( + lit->scope()->private_name_lookup_skips_outer_class()); } } @@ -5669,9 +5661,10 @@ bool JSArray::HasReadOnlyLength(Handle<JSArray> array) { // Fast path: "length" is the first fast property of arrays. Since it's not // configurable, it's guaranteed to be the first in the descriptor array. if (!map.is_dictionary_map()) { - DCHECK(map.instance_descriptors().GetKey(0) == + InternalIndex first(0); + DCHECK(map.instance_descriptors().GetKey(first) == array->GetReadOnlyRoots().length_string()); - return map.instance_descriptors().GetDetails(0).IsReadOnly(); + return map.instance_descriptors().GetDetails(first).IsReadOnly(); } Isolate* isolate = array->GetIsolate(); @@ -5927,17 +5920,25 @@ MaybeHandle<Object> JSPromise::Resolve(Handle<JSPromise> promise, // 8. Let then be Get(resolution, "then"). MaybeHandle<Object> then; - if (isolate->IsPromiseThenLookupChainIntact( - Handle<JSReceiver>::cast(resolution))) { + Handle<JSReceiver> receiver(Handle<JSReceiver>::cast(resolution)); + + // Make sure a lookup of "then" on any JSPromise whose [[Prototype]] is the + // initial %PromisePrototype% yields the initial method. In addition this + // protector also guards the negative lookup of "then" on the intrinsic + // %ObjectPrototype%, meaning that such lookups are guaranteed to yield + // undefined without triggering any side-effects. + if (receiver->IsJSPromise() && + isolate->IsInAnyContext(receiver->map().prototype(), + Context::PROMISE_PROTOTYPE_INDEX) && + Protectors::IsPromiseThenLookupChainIntact(isolate)) { // We can skip the "then" lookup on {resolution} if its [[Prototype]] // is the (initial) Promise.prototype and the Promise#then protector // is intact, as that guards the lookup path for the "then" property // on JSPromise instances which have the (initial) %PromisePrototype%. then = isolate->promise_then(); } else { - then = - JSReceiver::GetProperty(isolate, Handle<JSReceiver>::cast(resolution), - isolate->factory()->then_string()); + then = JSReceiver::GetProperty(isolate, receiver, + isolate->factory()->then_string()); } // 9. If then is an abrupt completion, then @@ -6151,27 +6152,40 @@ bool JSRegExp::ShouldProduceBytecode() { } // An irregexp is considered to be marked for tier up if the tier-up ticks value -// is not zero. An atom is not subject to tier-up implementation, so the tier-up -// ticks value is not set. +// reaches zero. An atom is not subject to tier-up implementation, so the +// tier-up ticks value is not set. bool JSRegExp::MarkedForTierUp() { DCHECK(data().IsFixedArray()); - if (TypeTag() == JSRegExp::ATOM) { + if (TypeTag() == JSRegExp::ATOM || !FLAG_regexp_tier_up) { return false; } - return Smi::ToInt(DataAt(kIrregexpTierUpTicksIndex)) != 0; + return Smi::ToInt(DataAt(kIrregexpTicksUntilTierUpIndex)) == 0; +} + +void JSRegExp::ResetLastTierUpTick() { + DCHECK(FLAG_regexp_tier_up); + DCHECK_EQ(TypeTag(), JSRegExp::IRREGEXP); + int tier_up_ticks = Smi::ToInt(DataAt(kIrregexpTicksUntilTierUpIndex)) + 1; + FixedArray::cast(data()).set(JSRegExp::kIrregexpTicksUntilTierUpIndex, + Smi::FromInt(tier_up_ticks)); } -void JSRegExp::ResetTierUp() { +void JSRegExp::TierUpTick() { DCHECK(FLAG_regexp_tier_up); DCHECK_EQ(TypeTag(), JSRegExp::IRREGEXP); - FixedArray::cast(data()).set(JSRegExp::kIrregexpTierUpTicksIndex, Smi::kZero); + int tier_up_ticks = Smi::ToInt(DataAt(kIrregexpTicksUntilTierUpIndex)); + if (tier_up_ticks == 0) { + return; + } + FixedArray::cast(data()).set(JSRegExp::kIrregexpTicksUntilTierUpIndex, + Smi::FromInt(tier_up_ticks - 1)); } void JSRegExp::MarkTierUpForNextExec() { DCHECK(FLAG_regexp_tier_up); DCHECK_EQ(TypeTag(), JSRegExp::IRREGEXP); - FixedArray::cast(data()).set(JSRegExp::kIrregexpTierUpTicksIndex, - Smi::FromInt(1)); + FixedArray::cast(data()).set(JSRegExp::kIrregexpTicksUntilTierUpIndex, + Smi::kZero); } namespace { @@ -6938,7 +6952,7 @@ void AddToFeedbackCellsMap(Handle<CompilationCacheTable> cache, int cache_entry, if (entry < 0) { // Copy old optimized code map and append one new entry. new_literals_map = isolate->factory()->CopyWeakFixedArrayAndGrow( - old_literals_map, kLiteralEntryLength, AllocationType::kOld); + old_literals_map, kLiteralEntryLength); entry = old_literals_map->length(); } } @@ -7312,8 +7326,13 @@ Handle<NumberDictionary> NumberDictionary::Set( Isolate* isolate, Handle<NumberDictionary> dictionary, uint32_t key, Handle<Object> value, Handle<JSObject> dictionary_holder, PropertyDetails details) { - dictionary->UpdateMaxNumberKey(key, dictionary_holder); - return AtPut(isolate, dictionary, key, value, details); + // We could call Set with empty dictionaries. UpdateMaxNumberKey doesn't + // expect empty dictionaries so make sure to call AtPut that correctly handles + // them by creating new dictionary when required. + Handle<NumberDictionary> new_dictionary = + AtPut(isolate, dictionary, key, value, details); + new_dictionary->UpdateMaxNumberKey(key, dictionary_holder); + return new_dictionary; } void NumberDictionary::CopyValuesTo(FixedArray elements) { @@ -7898,9 +7917,6 @@ void PropertyCell::SetValueWithInvalidation(Isolate* isolate, Handle<PropertyCell> cell, Handle<Object> new_value) { if (cell->value() != *new_value) { - if (FLAG_trace_protector_invalidation) { - isolate->TraceProtectorInvalidation(cell_name); - } cell->set_value(*new_value); cell->dependent_code().DeoptimizeDependentCodeGroup( isolate, DependentCode::kPropertyCellChangedGroup); diff --git a/deps/v8/src/objects/objects.h b/deps/v8/src/objects/objects.h index b4e78a19377df7..f66023456c3ca0 100644 --- a/deps/v8/src/objects/objects.h +++ b/deps/v8/src/objects/objects.h @@ -46,19 +46,22 @@ // - JSArrayBufferView // - JSTypedArray // - JSDataView -// - JSBoundFunction // - JSCollection // - JSSet // - JSMap +// - JSCustomElementsObject (may have elements despite empty FixedArray) +// - JSSpecialObject (requires custom property lookup handling) +// - JSGlobalObject +// - JSGlobalProxy +// - JSModuleNamespace +// - JSPrimitiveWrapper // - JSDate -// - JSFunction +// - JSFunctionOrBoundFunction +// - JSBoundFunction +// - JSFunction // - JSGeneratorObject -// - JSGlobalObject -// - JSGlobalProxy // - JSMapIterator // - JSMessageObject -// - JSModuleNamespace -// - JSPrimitiveWrapper // - JSRegExp // - JSSetIterator // - JSStringIterator @@ -104,30 +107,32 @@ // - ScriptContextTable // - ClosureFeedbackCellArray // - FixedDoubleArray -// - Name -// - String -// - SeqString -// - SeqOneByteString -// - SeqTwoByteString -// - SlicedString -// - ConsString -// - ThinString -// - ExternalString -// - ExternalOneByteString -// - ExternalTwoByteString -// - InternalizedString -// - SeqInternalizedString -// - SeqOneByteInternalizedString -// - SeqTwoByteInternalizedString -// - ConsInternalizedString -// - ExternalInternalizedString -// - ExternalOneByteInternalizedString -// - ExternalTwoByteInternalizedString -// - Symbol +// - PrimitiveHeapObject +// - BigInt +// - HeapNumber +// - Name +// - String +// - SeqString +// - SeqOneByteString +// - SeqTwoByteString +// - SlicedString +// - ConsString +// - ThinString +// - ExternalString +// - ExternalOneByteString +// - ExternalTwoByteString +// - InternalizedString +// - SeqInternalizedString +// - SeqOneByteInternalizedString +// - SeqTwoByteInternalizedString +// - ConsInternalizedString +// - ExternalInternalizedString +// - ExternalOneByteInternalizedString +// - ExternalTwoByteInternalizedString +// - Symbol +// - Oddball // - Context // - NativeContext -// - HeapNumber -// - BigInt // - Cell // - DescriptorArray // - PropertyCell @@ -135,7 +140,6 @@ // - Code // - AbstractCode, a wrapper around Code or BytecodeArray // - Map -// - Oddball // - Foreign // - SmallOrderedHashTable // - SmallOrderedHashMap @@ -607,15 +611,13 @@ class Object : public TaggedImpl<HeapObjectReferenceType::STRONG, Address> { // For use with std::unordered_set. struct Hasher { size_t operator()(const Object o) const { - return std::hash<v8::internal::Address>{}(o.ptr()); + return std::hash<v8::internal::Address>{}(static_cast<Tagged_t>(o.ptr())); } }; // For use with std::map. struct Comparer { - bool operator()(const Object a, const Object b) const { - return a.ptr() < b.ptr(); - } + bool operator()(const Object a, const Object b) const { return a < b; } }; template <class T, typename std::enable_if<std::is_arithmetic<T>::value, @@ -784,7 +786,8 @@ enum AccessorComponent { ACCESSOR_GETTER, ACCESSOR_SETTER }; enum class GetKeysConversion { kKeepNumbers = static_cast<int>(v8::KeyConversionMode::kKeepNumbers), - kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString) + kConvertToString = static_cast<int>(v8::KeyConversionMode::kConvertToString), + kNoNumbers = static_cast<int>(v8::KeyConversionMode::kNoNumbers) }; enum class KeyCollectionMode { diff --git a/deps/v8/src/objects/oddball.h b/deps/v8/src/objects/oddball.h index 025f9379ba9424..e88d96624e9bbb 100644 --- a/deps/v8/src/objects/oddball.h +++ b/deps/v8/src/objects/oddball.h @@ -5,8 +5,7 @@ #ifndef V8_OBJECTS_ODDBALL_H_ #define V8_OBJECTS_ODDBALL_H_ -#include "src/objects/heap-object.h" -#include "torque-generated/class-definitions-tq.h" +#include "src/objects/primitive-heap-object.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -15,7 +14,7 @@ namespace v8 { namespace internal { // The Oddball describes objects null, undefined, true, and false. -class Oddball : public TorqueGeneratedOddball<Oddball, HeapObject> { +class Oddball : public TorqueGeneratedOddball<Oddball, PrimitiveHeapObject> { public: // [to_number_raw]: Cached raw to_number computed at startup. inline void set_to_number_raw_as_bits(uint64_t bits); diff --git a/deps/v8/src/objects/ordered-hash-table-inl.h b/deps/v8/src/objects/ordered-hash-table-inl.h index a2270b0a4a1d84..f6b8f972a98db8 100644 --- a/deps/v8/src/objects/ordered-hash-table-inl.h +++ b/deps/v8/src/objects/ordered-hash-table-inl.h @@ -164,10 +164,18 @@ inline bool OrderedHashMap::Is(Handle<HeapObject> table) { return table->IsOrderedHashMap(); } +inline bool OrderedNameDictionary::Is(Handle<HeapObject> table) { + return table->IsOrderedNameDictionary(); +} + inline bool SmallOrderedHashSet::Is(Handle<HeapObject> table) { return table->IsSmallOrderedHashSet(); } +inline bool SmallOrderedNameDictionary::Is(Handle<HeapObject> table) { + return table->IsSmallOrderedNameDictionary(); +} + inline bool SmallOrderedHashMap::Is(Handle<HeapObject> table) { return table->IsSmallOrderedHashMap(); } diff --git a/deps/v8/src/objects/ordered-hash-table.cc b/deps/v8/src/objects/ordered-hash-table.cc index f0cc7b9df78483..962224024ea805 100644 --- a/deps/v8/src/objects/ordered-hash-table.cc +++ b/deps/v8/src/objects/ordered-hash-table.cc @@ -168,8 +168,8 @@ Handle<FixedArray> OrderedHashSet::ConvertToKeysArray( for (int i = 0; i < length; i++) { int index = HashTableStartIndex() + nof_buckets + (i * kEntrySize); Object key = table->get(index); + uint32_t index_value; if (convert == GetKeysConversion::kConvertToString) { - uint32_t index_value; if (key.ToArrayIndex(&index_value)) { // Avoid trashing the Number2String cache if indices get very large. bool use_cache = i < kMaxStringTableEntries; @@ -177,6 +177,8 @@ Handle<FixedArray> OrderedHashSet::ConvertToKeysArray( } else { CHECK(key.IsName()); } + } else if (convert == GetKeysConversion::kNoNumbers) { + DCHECK(!key.ToArrayIndex(&index_value)); } result->set(i, key); } @@ -957,22 +959,19 @@ OrderedHashTableHandler<SmallOrderedNameDictionary, OrderedNameDictionary>::Allocate(Isolate* isolate, int capacity); -#if !defined(V8_OS_WIN) template <class SmallTable, class LargeTable> bool OrderedHashTableHandler<SmallTable, LargeTable>::Delete( - Handle<HeapObject> table, Handle<Object> key) { + Isolate* isolate, Handle<HeapObject> table, Handle<Object> key) { if (SmallTable::Is(table)) { - return SmallTable::Delete(Handle<SmallTable>::cast(table), key); + return SmallTable::Delete(isolate, *Handle<SmallTable>::cast(table), *key); } DCHECK(LargeTable::Is(table)); // Note: Once we migrate to the a big hash table, we never migrate // down to a smaller hash table. - return LargeTable::Delete(Handle<LargeTable>::cast(table), key); + return LargeTable::Delete(isolate, *Handle<LargeTable>::cast(table), *key); } -#endif -#if !defined(V8_OS_WIN) template <class SmallTable, class LargeTable> bool OrderedHashTableHandler<SmallTable, LargeTable>::HasKey( Isolate* isolate, Handle<HeapObject> table, Handle<Object> key) { @@ -983,7 +982,6 @@ bool OrderedHashTableHandler<SmallTable, LargeTable>::HasKey( DCHECK(LargeTable::Is(table)); return LargeTable::HasKey(isolate, LargeTable::cast(*table), *key); } -#endif template bool OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::HasKey( @@ -992,6 +990,18 @@ template bool OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::HasKey( Isolate* isolate, Handle<HeapObject> table, Handle<Object> key); +template bool +OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::Delete( + Isolate* isolate, Handle<HeapObject> table, Handle<Object> key); +template bool +OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::Delete( + Isolate* isolate, Handle<HeapObject> table, Handle<Object> key); +template bool +OrderedHashTableHandler<SmallOrderedNameDictionary, + OrderedNameDictionary>::Delete(Isolate* isolate, + Handle<HeapObject> table, + Handle<Object> key); + MaybeHandle<OrderedHashMap> OrderedHashMapHandler::AdjustRepresentation( Isolate* isolate, Handle<SmallOrderedHashMap> table) { MaybeHandle<OrderedHashMap> new_table_candidate = diff --git a/deps/v8/src/objects/ordered-hash-table.h b/deps/v8/src/objects/ordered-hash-table.h index 21decaeba72246..590846f1302775 100644 --- a/deps/v8/src/objects/ordered-hash-table.h +++ b/deps/v8/src/objects/ordered-hash-table.h @@ -658,7 +658,8 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) OrderedHashTableHandler { using Entry = int; static MaybeHandle<HeapObject> Allocate(Isolate* isolate, int capacity); - static bool Delete(Handle<HeapObject> table, Handle<Object> key); + static bool Delete(Isolate* isolate, Handle<HeapObject> table, + Handle<Object> key); static bool HasKey(Isolate* isolate, Handle<HeapObject> table, Handle<Object> key); @@ -730,6 +731,7 @@ class OrderedNameDictionary static HeapObject GetEmpty(ReadOnlyRoots ro_roots); static inline RootIndex GetMapRootIndex(); + static inline bool Is(Handle<HeapObject> table); static const int kValueOffset = 1; static const int kPropertyDetailsOffset = 2; @@ -831,6 +833,7 @@ class SmallOrderedNameDictionary Object value, PropertyDetails details); static inline RootIndex GetMapRootIndex(); + static inline bool Is(Handle<HeapObject> table); OBJECT_CONSTRUCTORS(SmallOrderedNameDictionary, SmallOrderedHashTable<SmallOrderedNameDictionary>); diff --git a/deps/v8/src/objects/osr-optimized-code-cache-inl.h b/deps/v8/src/objects/osr-optimized-code-cache-inl.h new file mode 100644 index 00000000000000..ab7a97b6aa2cae --- /dev/null +++ b/deps/v8/src/objects/osr-optimized-code-cache-inl.h @@ -0,0 +1,25 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_INL_H_ +#define V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_INL_H_ + +#include "src/objects/osr-optimized-code-cache.h" + +#include "src/objects/fixed-array-inl.h" +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +OBJECT_CONSTRUCTORS_IMPL(OSROptimizedCodeCache, WeakFixedArray) +CAST_ACCESSOR(OSROptimizedCodeCache) + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_INL_H_ diff --git a/deps/v8/src/objects/osr-optimized-code-cache.cc b/deps/v8/src/objects/osr-optimized-code-cache.cc new file mode 100644 index 00000000000000..62190529f1b3c7 --- /dev/null +++ b/deps/v8/src/objects/osr-optimized-code-cache.cc @@ -0,0 +1,223 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/execution/isolate-inl.h" +#include "src/objects/code.h" +#include "src/objects/maybe-object.h" +#include "src/objects/shared-function-info.h" + +#include "src/objects/osr-optimized-code-cache.h" + +namespace v8 { +namespace internal { + +const int OSROptimizedCodeCache::kInitialLength; +const int OSROptimizedCodeCache::kMaxLength; + +void OSROptimizedCodeCache::AddOptimizedCode( + Handle<NativeContext> native_context, Handle<SharedFunctionInfo> shared, + Handle<Code> code, BailoutId osr_offset) { + DCHECK(!osr_offset.IsNone()); + DCHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION); + STATIC_ASSERT(kEntryLength == 3); + Isolate* isolate = native_context->GetIsolate(); + DCHECK(!isolate->serializer_enabled()); + + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + + DCHECK_EQ(osr_cache->FindEntry(shared, osr_offset), -1); + int entry = -1; + for (int index = 0; index < osr_cache->length(); index += kEntryLength) { + if (osr_cache->Get(index + kSharedOffset)->IsCleared() || + osr_cache->Get(index + kCachedCodeOffset)->IsCleared()) { + entry = index; + break; + } + } + + if (entry == -1 && osr_cache->length() + kEntryLength <= kMaxLength) { + entry = GrowOSRCache(native_context, &osr_cache); + } else if (entry == -1) { + // We reached max capacity and cannot grow further. Reuse an existing entry. + // TODO(mythria): We could use better mechanisms (like lru) to replace + // existing entries. Though we don't expect this to be a common case, so + // for now choosing to replace the first entry. + entry = 0; + } + + osr_cache->InitializeEntry(entry, *shared, *code, osr_offset); +} + +void OSROptimizedCodeCache::Clear(NativeContext native_context) { + native_context.set_osr_code_cache( + *native_context.GetIsolate()->factory()->empty_weak_fixed_array()); +} + +void OSROptimizedCodeCache::Compact(Handle<NativeContext> native_context) { + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), native_context->GetIsolate()); + Isolate* isolate = native_context->GetIsolate(); + + // Re-adjust the cache so all the valid entries are on one side. This will + // enable us to compress the cache if needed. + int curr_valid_index = 0; + for (int curr_index = 0; curr_index < osr_cache->length(); + curr_index += kEntryLength) { + if (osr_cache->Get(curr_index + kSharedOffset)->IsCleared() || + osr_cache->Get(curr_index + kCachedCodeOffset)->IsCleared()) { + continue; + } + if (curr_valid_index != curr_index) { + osr_cache->MoveEntry(curr_index, curr_valid_index, isolate); + } + curr_valid_index += kEntryLength; + } + + if (!NeedsTrimming(curr_valid_index, osr_cache->length())) return; + + Handle<OSROptimizedCodeCache> new_osr_cache = + Handle<OSROptimizedCodeCache>::cast(isolate->factory()->NewWeakFixedArray( + CapacityForLength(curr_valid_index), AllocationType::kOld)); + DCHECK_LT(new_osr_cache->length(), osr_cache->length()); + { + DisallowHeapAllocation no_gc; + new_osr_cache->CopyElements(native_context->GetIsolate(), 0, *osr_cache, 0, + new_osr_cache->length(), + new_osr_cache->GetWriteBarrierMode(no_gc)); + } + native_context->set_osr_code_cache(*new_osr_cache); +} + +Code OSROptimizedCodeCache::GetOptimizedCode(Handle<SharedFunctionInfo> shared, + BailoutId osr_offset, + Isolate* isolate) { + DisallowHeapAllocation no_gc; + int index = FindEntry(shared, osr_offset); + if (index == -1) return Code(); + Code code = GetCodeFromEntry(index); + if (code.is_null()) { + ClearEntry(index, isolate); + return code; + } + DCHECK(code.is_optimized_code() && !code.marked_for_deoptimization()); + return code; +} + +void OSROptimizedCodeCache::EvictMarkedCode(Isolate* isolate) { + // This is called from DeoptimizeMarkedCodeForContext that uses raw pointers + // and hence the DisallowHeapAllocation scope here. + DisallowHeapAllocation no_gc; + for (int index = 0; index < length(); index += kEntryLength) { + MaybeObject code_entry = Get(index + kCachedCodeOffset); + HeapObject heap_object; + if (!code_entry->GetHeapObject(&heap_object)) continue; + + DCHECK(heap_object.IsCode()); + DCHECK(Code::cast(heap_object).is_optimized_code()); + if (!Code::cast(heap_object).marked_for_deoptimization()) continue; + + ClearEntry(index, isolate); + } +} + +int OSROptimizedCodeCache::GrowOSRCache( + Handle<NativeContext> native_context, + Handle<OSROptimizedCodeCache>* osr_cache) { + Isolate* isolate = native_context->GetIsolate(); + int old_length = (*osr_cache)->length(); + int grow_by = CapacityForLength(old_length) - old_length; + DCHECK_GT(grow_by, kEntryLength); + *osr_cache = Handle<OSROptimizedCodeCache>::cast( + isolate->factory()->CopyWeakFixedArrayAndGrow(*osr_cache, grow_by)); + for (int i = old_length; i < (*osr_cache)->length(); i++) { + (*osr_cache)->Set(i, HeapObjectReference::ClearedValue(isolate)); + } + native_context->set_osr_code_cache(**osr_cache); + + return old_length; +} + +Code OSROptimizedCodeCache::GetCodeFromEntry(int index) { + DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length()); + DCHECK_EQ(index % kEntryLength, 0); + HeapObject code_entry; + Get(index + OSRCodeCacheConstants::kCachedCodeOffset) + ->GetHeapObject(&code_entry); + return code_entry.is_null() ? Code() : Code::cast(code_entry); +} + +SharedFunctionInfo OSROptimizedCodeCache::GetSFIFromEntry(int index) { + DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length()); + DCHECK_EQ(index % kEntryLength, 0); + HeapObject sfi_entry; + Get(index + OSRCodeCacheConstants::kSharedOffset)->GetHeapObject(&sfi_entry); + return sfi_entry.is_null() ? SharedFunctionInfo() + : SharedFunctionInfo::cast(sfi_entry); +} + +BailoutId OSROptimizedCodeCache::GetBailoutIdFromEntry(int index) { + DCHECK_LE(index + OSRCodeCacheConstants::kEntryLength, length()); + DCHECK_EQ(index % kEntryLength, 0); + Smi osr_offset_entry; + Get(index + kOsrIdOffset)->ToSmi(&osr_offset_entry); + return BailoutId(osr_offset_entry.value()); +} + +int OSROptimizedCodeCache::FindEntry(Handle<SharedFunctionInfo> shared, + BailoutId osr_offset) { + DisallowHeapAllocation no_gc; + DCHECK(!osr_offset.IsNone()); + for (int index = 0; index < length(); index += kEntryLength) { + if (GetSFIFromEntry(index) != *shared) continue; + if (GetBailoutIdFromEntry(index) != osr_offset) continue; + return index; + } + return -1; +} + +void OSROptimizedCodeCache::ClearEntry(int index, Isolate* isolate) { + Set(index + OSRCodeCacheConstants::kSharedOffset, + HeapObjectReference::ClearedValue(isolate)); + Set(index + OSRCodeCacheConstants::kCachedCodeOffset, + HeapObjectReference::ClearedValue(isolate)); + Set(index + OSRCodeCacheConstants::kOsrIdOffset, + HeapObjectReference::ClearedValue(isolate)); +} + +void OSROptimizedCodeCache::InitializeEntry(int entry, + SharedFunctionInfo shared, + Code code, BailoutId osr_offset) { + Set(entry + OSRCodeCacheConstants::kSharedOffset, + HeapObjectReference::Weak(shared)); + Set(entry + OSRCodeCacheConstants::kCachedCodeOffset, + HeapObjectReference::Weak(code)); + Set(entry + OSRCodeCacheConstants::kOsrIdOffset, + MaybeObject::FromSmi(Smi::FromInt(osr_offset.ToInt()))); +} + +void OSROptimizedCodeCache::MoveEntry(int src, int dst, Isolate* isolate) { + Set(dst + OSRCodeCacheConstants::kSharedOffset, + Get(src + OSRCodeCacheConstants::kSharedOffset)); + Set(dst + OSRCodeCacheConstants::kCachedCodeOffset, + Get(src + OSRCodeCacheConstants::kCachedCodeOffset)); + Set(dst + OSRCodeCacheConstants::kOsrIdOffset, Get(src + kOsrIdOffset)); + ClearEntry(src, isolate); +} + +int OSROptimizedCodeCache::CapacityForLength(int curr_length) { + // TODO(mythria): This is a randomly chosen heuristic and is not based on any + // data. We may have to tune this later. + if (curr_length == 0) return kInitialLength; + if (curr_length * 2 > kMaxLength) return kMaxLength; + return curr_length * 2; +} + +bool OSROptimizedCodeCache::NeedsTrimming(int num_valid_entries, + int curr_length) { + return curr_length > kInitialLength && curr_length > num_valid_entries * 3; +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/objects/osr-optimized-code-cache.h b/deps/v8/src/objects/osr-optimized-code-cache.h new file mode 100644 index 00000000000000..99c148a7e180a6 --- /dev/null +++ b/deps/v8/src/objects/osr-optimized-code-cache.h @@ -0,0 +1,77 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ +#define V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ + +#include "src/objects/fixed-array.h" +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +class V8_EXPORT OSROptimizedCodeCache : public WeakFixedArray { + public: + DECL_CAST(OSROptimizedCodeCache) + + enum OSRCodeCacheConstants { + kSharedOffset, + kCachedCodeOffset, + kOsrIdOffset, + kEntryLength + }; + + static const int kInitialLength = OSRCodeCacheConstants::kEntryLength * 4; + static const int kMaxLength = OSRCodeCacheConstants::kEntryLength * 1024; + + // Caches the optimized code |code| corresponding to the shared function + // |shared| and bailout id |osr_offset| in the OSROptimized code cache. + // If the OSR code cache wasn't created before it creates a code cache with + // kOSRCodeCacheInitialLength entries. + static void AddOptimizedCode(Handle<NativeContext> context, + Handle<SharedFunctionInfo> shared, + Handle<Code> code, BailoutId osr_offset); + // Reduces the size of the OSR code cache if the number of valid entries are + // less than the current capacity of the cache. + static void Compact(Handle<NativeContext> context); + // Sets the OSR optimized code cache to an empty array. + static void Clear(NativeContext context); + + // Returns the code corresponding to the shared function |shared| and + // BailoutId |offset| if an entry exists in the cache. Returns an empty + // object otherwise. + Code GetOptimizedCode(Handle<SharedFunctionInfo> shared, BailoutId osr_offset, + Isolate* isolate); + + // Remove all code objects marked for deoptimization from OSR code cache. + void EvictMarkedCode(Isolate* isolate); + + private: + // Functions that implement heuristics on when to grow / shrink the cache. + static int CapacityForLength(int curr_capacity); + static bool NeedsTrimming(int num_valid_entries, int curr_capacity); + static int GrowOSRCache(Handle<NativeContext> native_context, + Handle<OSROptimizedCodeCache>* osr_cache); + + // Helper functions to get individual items from an entry in the cache. + Code GetCodeFromEntry(int index); + SharedFunctionInfo GetSFIFromEntry(int index); + BailoutId GetBailoutIdFromEntry(int index); + + inline int FindEntry(Handle<SharedFunctionInfo> shared, BailoutId osr_offset); + inline void ClearEntry(int src, Isolate* isolate); + inline void InitializeEntry(int entry, SharedFunctionInfo shared, Code code, + BailoutId osr_offset); + inline void MoveEntry(int src, int dst, Isolate* isolate); + + OBJECT_CONSTRUCTORS(OSROptimizedCodeCache, WeakFixedArray); +}; + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_OSR_OPTIMIZED_CODE_CACHE_H_ diff --git a/deps/v8/src/objects/primitive-heap-object-inl.h b/deps/v8/src/objects/primitive-heap-object-inl.h new file mode 100644 index 00000000000000..2c694bd1d6d5c2 --- /dev/null +++ b/deps/v8/src/objects/primitive-heap-object-inl.h @@ -0,0 +1,26 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_ +#define V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_ + +#include "src/objects/primitive-heap-object.h" + +#include "src/objects/heap-object-inl.h" +#include "torque-generated/class-definitions-tq-inl.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +TQ_OBJECT_CONSTRUCTORS_IMPL(PrimitiveHeapObject) + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_INL_H_ diff --git a/deps/v8/src/objects/primitive-heap-object.h b/deps/v8/src/objects/primitive-heap-object.h new file mode 100644 index 00000000000000..9bd13cafc90dbf --- /dev/null +++ b/deps/v8/src/objects/primitive-heap-object.h @@ -0,0 +1,33 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_ +#define V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_ + +#include "src/objects/heap-object.h" +#include "torque-generated/class-definitions-tq.h" + +// Has to be the last include (doesn't have include guards): +#include "src/objects/object-macros.h" + +namespace v8 { +namespace internal { + +// An abstract superclass for classes representing JavaScript primitive values +// other than Smi. It doesn't carry any functionality but allows primitive +// classes to be identified in the type system. +class PrimitiveHeapObject + : public TorqueGeneratedPrimitiveHeapObject<PrimitiveHeapObject, + HeapObject> { + public: + STATIC_ASSERT(kHeaderSize == HeapObject::kHeaderSize); + TQ_OBJECT_CONSTRUCTORS(PrimitiveHeapObject) +}; + +} // namespace internal +} // namespace v8 + +#include "src/objects/object-macros-undef.h" + +#endif // V8_OBJECTS_PRIMITIVE_HEAP_OBJECT_H_ diff --git a/deps/v8/src/objects/property-descriptor.cc b/deps/v8/src/objects/property-descriptor.cc index b3b05deceb7643..c5cfe8c9a9ddc7 100644 --- a/deps/v8/src/objects/property-descriptor.cc +++ b/deps/v8/src/objects/property-descriptor.cc @@ -58,7 +58,7 @@ bool ToPropertyDescriptorFastPath(Isolate* isolate, Handle<JSReceiver> obj, if (map.is_dictionary_map()) return false; Handle<DescriptorArray> descs = Handle<DescriptorArray>(map.instance_descriptors(), isolate); - for (int i = 0; i < map.NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map.IterateOwnDescriptors()) { PropertyDetails details = descs->GetDetails(i); Name key = descs->GetKey(i); Handle<Object> value; diff --git a/deps/v8/src/objects/property-details.h b/deps/v8/src/objects/property-details.h index e350fe2c278b83..51318f475af552 100644 --- a/deps/v8/src/objects/property-details.h +++ b/deps/v8/src/objects/property-details.h @@ -112,7 +112,19 @@ class Representation { // smi and tagged values. Doubles, however, would require a box allocation. if (IsNone()) return !other.IsDouble(); if (!FLAG_modify_field_representation_inplace) return false; - return (IsSmi() || IsHeapObject()) && other.IsTagged(); + return (IsSmi() || (!FLAG_unbox_double_fields && IsDouble()) || + IsHeapObject()) && + other.IsTagged(); + } + + // Return the most generic representation that this representation can be + // changed to in-place. If in-place representation changes are disabled, then + // this will return the current representation. + Representation MostGenericInPlaceChange() const { + if (!FLAG_modify_field_representation_inplace) return *this; + // Everything but unboxed doubles can be in-place changed to Tagged. + if (FLAG_unbox_double_fields && IsDouble()) return Representation::Double(); + return Representation::Tagged(); } bool is_more_general_than(const Representation& other) const { diff --git a/deps/v8/src/objects/scope-info.cc b/deps/v8/src/objects/scope-info.cc index c390298b5d2cf6..65a26e5d98feba 100644 --- a/deps/v8/src/objects/scope-info.cc +++ b/deps/v8/src/objects/scope-info.cc @@ -138,6 +138,10 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, const bool has_brand = scope->is_class_scope() ? scope->AsClassScope()->brand() != nullptr : false; + const bool should_save_class_variable_index = + scope->is_class_scope() + ? scope->AsClassScope()->should_save_class_variable_index() + : false; const bool has_function_name = function_name_info != NONE; const bool has_position_info = NeedsPositionInfo(scope->scope_type()); const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; @@ -146,7 +150,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, ? scope->AsDeclarationScope()->num_parameters() : 0; const bool has_outer_scope_info = !outer_scope.is_null(); + const int length = kVariablePartIndex + 2 * context_local_count + + (should_save_class_variable_index ? 1 : 0) + (has_receiver ? 1 : 0) + (has_function_name ? kFunctionNameEntries : 0) + (has_inferred_function_name ? 1 : 0) + @@ -187,6 +193,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, DeclarationScopeField::encode(scope->is_declaration_scope()) | ReceiverVariableField::encode(receiver_info) | HasClassBrandField::encode(has_brand) | + HasSavedClassVariableIndexField::encode( + should_save_class_variable_index) | HasNewTargetField::encode(has_new_target) | FunctionVariableField::encode(function_name_info) | HasInferredFunctionNameField::encode(has_inferred_function_name) | @@ -196,7 +204,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, HasOuterScopeInfoField::encode(has_outer_scope_info) | IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope()) | ForceContextAllocationField::encode( - scope->ForceContextForLanguageMode()); + scope->ForceContextForLanguageMode()) | + PrivateNameLookupSkipsOuterClassField::encode( + scope->private_name_lookup_skips_outer_class()); scope_info.SetFlags(flags); scope_info.SetParameterCount(parameter_count); @@ -220,7 +230,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, VariableModeField::encode(var->mode()) | InitFlagField::encode(var->initialization_flag()) | MaybeAssignedFlagField::encode(var->maybe_assigned()) | - ParameterNumberField::encode(ParameterNumberField::kMax); + ParameterNumberField::encode(ParameterNumberField::kMax) | + IsStaticFlagField::encode(var->is_static_flag()); scope_info.set(context_local_base + local_index, *var->name(), mode); scope_info.set(context_local_info_base + local_index, Smi::FromInt(info)); @@ -235,7 +246,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, VariableModeField::encode(var->mode()) | InitFlagField::encode(var->initialization_flag()) | MaybeAssignedFlagField::encode(var->maybe_assigned()) | - ParameterNumberField::encode(ParameterNumberField::kMax); + ParameterNumberField::encode(ParameterNumberField::kMax) | + IsStaticFlagField::encode(var->is_static_flag()); scope_info.set(module_var_entry + kModuleVariablePropertiesOffset, Smi::FromInt(properties)); module_var_entry += kModuleVariableEntryLength; @@ -273,7 +285,8 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, VariableModeField::encode(var->mode()) | InitFlagField::encode(var->initialization_flag()) | MaybeAssignedFlagField::encode(var->maybe_assigned()) | - ParameterNumberField::encode(ParameterNumberField::kMax); + ParameterNumberField::encode(ParameterNumberField::kMax) | + IsStaticFlagField::encode(var->is_static_flag()); scope_info.set(context_local_base + local_index, *var->name(), mode); scope_info.set(context_local_info_base + local_index, Smi::FromInt(info)); @@ -283,6 +296,16 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope, index += 2 * context_local_count; + DCHECK_EQ(index, scope_info.SavedClassVariableInfoIndex()); + // If the scope is a class scope and has used static private methods, save + // the context slot index of the class variable. + // Store the class variable index. + if (should_save_class_variable_index) { + Variable* class_variable = scope->AsClassScope()->class_variable(); + DCHECK_EQ(class_variable->location(), VariableLocation::CONTEXT); + scope_info.set(index++, Smi::FromInt(class_variable->index())); + } + // If the receiver is allocated, add its index. DCHECK_EQ(index, scope_info.ReceiverInfoIndex()); if (has_receiver) { @@ -362,11 +385,14 @@ Handle<ScopeInfo> ScopeInfo::CreateForWithScope( LanguageModeField::encode(LanguageMode::kSloppy) | DeclarationScopeField::encode(false) | ReceiverVariableField::encode(NONE) | HasClassBrandField::encode(false) | + HasSavedClassVariableIndexField::encode(false) | HasNewTargetField::encode(false) | FunctionVariableField::encode(NONE) | IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) | FunctionKindField::encode(kNormalFunction) | HasOuterScopeInfoField::encode(has_outer_scope_info) | - IsDebugEvaluateScopeField::encode(false); + IsDebugEvaluateScopeField::encode(false) | + ForceContextAllocationField::encode(false) | + PrivateNameLookupSkipsOuterClassField::encode(false); scope_info->SetFlags(flags); scope_info->SetParameterCount(0); @@ -425,13 +451,17 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate, LanguageModeField::encode(LanguageMode::kSloppy) | DeclarationScopeField::encode(true) | ReceiverVariableField::encode(is_empty_function ? UNUSED : CONTEXT) | - HasClassBrandField::encode(false) | HasNewTargetField::encode(false) | + HasClassBrandField::encode(false) | + HasSavedClassVariableIndexField::encode(false) | + HasNewTargetField::encode(false) | FunctionVariableField::encode(is_empty_function ? UNUSED : NONE) | HasInferredFunctionNameField::encode(has_inferred_function_name) | IsAsmModuleField::encode(false) | HasSimpleParametersField::encode(true) | FunctionKindField::encode(FunctionKind::kNormalFunction) | HasOuterScopeInfoField::encode(false) | - IsDebugEvaluateScopeField::encode(false); + IsDebugEvaluateScopeField::encode(false) | + ForceContextAllocationField::encode(false) | + PrivateNameLookupSkipsOuterClassField::encode(false); scope_info->SetFlags(flags); scope_info->SetParameterCount(parameter_count); scope_info->SetContextLocalCount(context_local_count); @@ -449,7 +479,8 @@ Handle<ScopeInfo> ScopeInfo::CreateForBootstrapping(Isolate* isolate, VariableModeField::encode(VariableMode::kConst) | InitFlagField::encode(kCreatedInitialized) | MaybeAssignedFlagField::encode(kNotAssigned) | - ParameterNumberField::encode(ParameterNumberField::kMax); + ParameterNumberField::encode(ParameterNumberField::kMax) | + IsStaticFlagField::encode(IsStaticFlag::kNotStatic); scope_info->set(index++, Smi::FromInt(value)); } @@ -549,6 +580,10 @@ bool ScopeInfo::HasClassBrand() const { return HasClassBrandField::decode(Flags()); } +bool ScopeInfo::HasSavedClassVariableIndex() const { + return HasSavedClassVariableIndexField::decode(Flags()); +} + bool ScopeInfo::HasNewTarget() const { return HasNewTargetField::decode(Flags()); } @@ -608,6 +643,11 @@ void ScopeInfo::SetIsDebugEvaluateScope() { } } +bool ScopeInfo::PrivateNameLookupSkipsOuterClass() const { + if (length() == 0) return false; + return PrivateNameLookupSkipsOuterClassField::decode(Flags()); +} + bool ScopeInfo::HasContext() const { return ContextLength() > 0; } Object ScopeInfo::FunctionName() const { @@ -674,6 +714,14 @@ VariableMode ScopeInfo::ContextLocalMode(int var) const { return VariableModeField::decode(value); } +IsStaticFlag ScopeInfo::ContextLocalIsStaticFlag(int var) const { + DCHECK_LE(0, var); + DCHECK_LT(var, ContextLocalCount()); + int info_index = ContextLocalInfosIndex() + var; + int value = Smi::ToInt(get(info_index)); + return IsStaticFlagField::decode(value); +} + InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) const { DCHECK_LE(0, var); DCHECK_LT(var, ContextLocalCount()); @@ -744,7 +792,8 @@ int ScopeInfo::ModuleIndex(String name, VariableMode* mode, int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name, VariableMode* mode, InitializationFlag* init_flag, - MaybeAssignedFlag* maybe_assigned_flag) { + MaybeAssignedFlag* maybe_assigned_flag, + IsStaticFlag* is_static_flag) { DisallowHeapAllocation no_gc; DCHECK(name.IsInternalizedString()); DCHECK_NOT_NULL(mode); @@ -759,6 +808,7 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name, if (name != scope_info.get(i)) continue; int var = i - start; *mode = scope_info.ContextLocalMode(var); + *is_static_flag = scope_info.ContextLocalIsStaticFlag(var); *init_flag = scope_info.ContextLocalInitFlag(var); *maybe_assigned_flag = scope_info.ContextLocalMaybeAssignedFlag(var); int result = Context::MIN_CONTEXT_SLOTS + var; @@ -770,6 +820,14 @@ int ScopeInfo::ContextSlotIndex(ScopeInfo scope_info, String name, return -1; } +int ScopeInfo::SavedClassVariableContextLocalIndex() const { + if (length() > 0 && HasSavedClassVariableIndexField::decode(Flags())) { + int index = Smi::ToInt(get(SavedClassVariableInfoIndex())); + return index - Context::MIN_CONTEXT_SLOTS; + } + return -1; +} + int ScopeInfo::ReceiverContextSlotIndex() const { if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT) { return Smi::ToInt(get(ReceiverInfoIndex())); @@ -801,10 +859,14 @@ int ScopeInfo::ContextLocalInfosIndex() const { return ContextLocalNamesIndex() + ContextLocalCount(); } -int ScopeInfo::ReceiverInfoIndex() const { +int ScopeInfo::SavedClassVariableInfoIndex() const { return ContextLocalInfosIndex() + ContextLocalCount(); } +int ScopeInfo::ReceiverInfoIndex() const { + return SavedClassVariableInfoIndex() + (HasSavedClassVariableIndex() ? 1 : 0); +} + int ScopeInfo::FunctionNameInfoIndex() const { return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0); } @@ -879,9 +941,10 @@ std::ostream& operator<<(std::ostream& os, } Handle<SourceTextModuleInfoEntry> SourceTextModuleInfoEntry::New( - Isolate* isolate, Handle<HeapObject> export_name, - Handle<HeapObject> local_name, Handle<HeapObject> import_name, - int module_request, int cell_index, int beg_pos, int end_pos) { + Isolate* isolate, Handle<PrimitiveHeapObject> export_name, + Handle<PrimitiveHeapObject> local_name, + Handle<PrimitiveHeapObject> import_name, int module_request, int cell_index, + int beg_pos, int end_pos) { Handle<SourceTextModuleInfoEntry> result = Handle<SourceTextModuleInfoEntry>::cast(isolate->factory()->NewStruct( SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE, AllocationType::kOld)); diff --git a/deps/v8/src/objects/scope-info.h b/deps/v8/src/objects/scope-info.h index 123b9b17973288..aa63cf2998eb70 100644 --- a/deps/v8/src/objects/scope-info.h +++ b/deps/v8/src/objects/scope-info.h @@ -72,6 +72,10 @@ class ScopeInfo : public FixedArray { // Does this scope has class brand (for private methods)? bool HasClassBrand() const; + // Does this scope contains a saved class variable context local slot index + // for checking receivers of static private methods? + bool HasSavedClassVariableIndex() const; + // Does this scope declare a "new.target" binding? bool HasNewTarget() const; @@ -121,6 +125,9 @@ class ScopeInfo : public FixedArray { // Return the mode of the given context local. VariableMode ContextLocalMode(int var) const; + // Return whether the given context local variable is static. + IsStaticFlag ContextLocalIsStaticFlag(int var) const; + // Return the initialization flag of the given context local. InitializationFlag ContextLocalInitFlag(int var) const; @@ -141,7 +148,8 @@ class ScopeInfo : public FixedArray { // mode for that variable. static int ContextSlotIndex(ScopeInfo scope_info, String name, VariableMode* mode, InitializationFlag* init_flag, - MaybeAssignedFlag* maybe_assigned_flag); + MaybeAssignedFlag* maybe_assigned_flag, + IsStaticFlag* is_static_flag); // Lookup metadata of a MODULE-allocated variable. Return 0 if there is no // module variable with the given name (the index value of a MODULE variable @@ -161,6 +169,12 @@ class ScopeInfo : public FixedArray { // context-allocated. Otherwise returns a value < 0. int ReceiverContextSlotIndex() const; + // Lookup support for serialized scope info. Returns the index of the + // saved class variable in context local slots if scope is a class scope + // and it contains static private methods that may be accessed. + // Otherwise returns a value < 0. + int SavedClassVariableContextLocalIndex() const; + FunctionKind function_kind() const; // Returns true if this ScopeInfo is linked to a outer ScopeInfo. @@ -176,6 +190,10 @@ class ScopeInfo : public FixedArray { // Return the outer ScopeInfo if present. ScopeInfo OuterScopeInfo() const; + // Returns true if this ScopeInfo was created for a scope that skips the + // closest outer class when resolving private names. + bool PrivateNameLookupSkipsOuterClass() const; + #ifdef DEBUG bool Equals(ScopeInfo other) const; #endif @@ -228,7 +246,8 @@ class ScopeInfo : public FixedArray { using ReceiverVariableField = DeclarationScopeField::Next<VariableAllocationInfo, 2>; using HasClassBrandField = ReceiverVariableField::Next<bool, 1>; - using HasNewTargetField = HasClassBrandField::Next<bool, 1>; + using HasSavedClassVariableIndexField = HasClassBrandField::Next<bool, 1>; + using HasNewTargetField = HasSavedClassVariableIndexField::Next<bool, 1>; using FunctionVariableField = HasNewTargetField::Next<VariableAllocationInfo, 2>; // TODO(cbruni): Combine with function variable field when only storing the @@ -240,6 +259,8 @@ class ScopeInfo : public FixedArray { using HasOuterScopeInfoField = FunctionKindField::Next<bool, 1>; using IsDebugEvaluateScopeField = HasOuterScopeInfoField::Next<bool, 1>; using ForceContextAllocationField = IsDebugEvaluateScopeField::Next<bool, 1>; + using PrivateNameLookupSkipsOuterClassField = + ForceContextAllocationField::Next<bool, 1>; STATIC_ASSERT(kLastFunctionKind <= FunctionKindField::kMax); @@ -256,27 +277,32 @@ class ScopeInfo : public FixedArray { // the context locals in ContextLocalNames. One slot is used per // context local, so in total this part occupies ContextLocalCount() // slots in the array. - // 3. ReceiverInfo: + // 3. SavedClassVariableInfo: + // If the scope is a class scope and it has static private methods that + // may be accessed directly or through eval, one slot is reserved to hold + // the context slot index for the class variable. + // 4. ReceiverInfo: // If the scope binds a "this" value, one slot is reserved to hold the // context or stack slot index for the variable. - // 4. FunctionNameInfo: + // 5. FunctionNameInfo: // If the scope belongs to a named function expression this part contains // information about the function variable. It always occupies two array // slots: a. The name of the function variable. // b. The context or stack slot index for the variable. - // 5. InferredFunctionName: + // 6. InferredFunctionName: // Contains the function's inferred name. - // 6. SourcePosition: + // 7. SourcePosition: // Contains two slots with a) the startPosition and b) the endPosition if // the scope belongs to a function or script. - // 7. OuterScopeInfoIndex: + // 8. OuterScopeInfoIndex: // The outer scope's ScopeInfo or the hole if there's none. - // 8. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables: + // 9. SourceTextModuleInfo, ModuleVariableCount, and ModuleVariables: // For a module scope, this part contains the SourceTextModuleInfo, the // number of MODULE-allocated variables, and the metadata of those // variables. For non-module scopes it is empty. int ContextLocalNamesIndex() const; int ContextLocalInfosIndex() const; + int SavedClassVariableInfoIndex() const; int ReceiverInfoIndex() const; int FunctionNameInfoIndex() const; int InferredFunctionNameIndex() const; @@ -310,6 +336,7 @@ class ScopeInfo : public FixedArray { using InitFlagField = VariableModeField::Next<InitializationFlag, 1>; using MaybeAssignedFlagField = InitFlagField::Next<MaybeAssignedFlag, 1>; using ParameterNumberField = MaybeAssignedFlagField::Next<uint32_t, 16>; + using IsStaticFlagField = ParameterNumberField::Next<IsStaticFlag, 1>; friend class ScopeIterator; friend std::ostream& operator<<(std::ostream& os, diff --git a/deps/v8/src/objects/script-inl.h b/deps/v8/src/objects/script-inl.h index 07450c73ec5621..c306c2c092b097 100644 --- a/deps/v8/src/objects/script-inl.h +++ b/deps/v8/src/objects/script-inl.h @@ -36,15 +36,17 @@ ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments, Object, this->type() != TYPE_WASM) SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset, this->type() != TYPE_WASM) -ACCESSORS(Script, shared_function_infos, WeakFixedArray, - kSharedFunctionInfosOffset) SMI_ACCESSORS(Script, flags, kFlagsOffset) ACCESSORS(Script, source_url, Object, kSourceUrlOffset) ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset) ACCESSORS(Script, host_defined_options, FixedArray, kHostDefinedOptionsOffset) -ACCESSORS_CHECKED(Script, wasm_module_object, Object, +ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray, kEvalFromSharedOrWrappedArgumentsOffset, this->type() == TYPE_WASM) +ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object, + kEvalFromPositionOffset, this->type() == TYPE_WASM) +ACCESSORS_CHECKED(Script, wasm_weak_instance_list, WeakArrayList, + kSharedFunctionInfosOffset, this->type() == TYPE_WASM) bool Script::is_wrapped() const { return eval_from_shared_or_wrapped_arguments().IsFixedArray(); @@ -75,6 +77,28 @@ FixedArray Script::wrapped_arguments() const { return FixedArray::cast(eval_from_shared_or_wrapped_arguments()); } +DEF_GETTER(Script, shared_function_infos, WeakFixedArray) { + return type() == TYPE_WASM + ? ReadOnlyRoots(GetHeap()).empty_weak_fixed_array() + : TaggedField<WeakFixedArray, kSharedFunctionInfosOffset>::load( + *this); +} + +void Script::set_shared_function_infos(WeakFixedArray value, + WriteBarrierMode mode) { + DCHECK_NE(TYPE_WASM, type()); + TaggedField<WeakFixedArray, kSharedFunctionInfosOffset>::store(*this, value); + CONDITIONAL_WRITE_BARRIER(*this, kSharedFunctionInfosOffset, value, mode); +} + +bool Script::has_wasm_breakpoint_infos() const { + return type() == TYPE_WASM && wasm_breakpoint_infos().length() > 0; +} + +wasm::NativeModule* Script::wasm_native_module() const { + return Managed<wasm::NativeModule>::cast(wasm_managed_native_module()).raw(); +} + Script::CompilationType Script::compilation_type() { return BooleanBit::get(flags(), kCompilationTypeBit) ? COMPILATION_TYPE_EVAL : COMPILATION_TYPE_HOST; diff --git a/deps/v8/src/objects/script.h b/deps/v8/src/objects/script.h index 2d9e4bca781ec8..935241a1492ef8 100644 --- a/deps/v8/src/objects/script.h +++ b/deps/v8/src/objects/script.h @@ -5,6 +5,8 @@ #ifndef V8_OBJECTS_SCRIPT_H_ #define V8_OBJECTS_SCRIPT_H_ +#include <memory> + #include "src/objects/fixed-array.h" #include "src/objects/objects.h" #include "src/objects/struct.h" @@ -101,9 +103,21 @@ class Script : public Struct { // [source_mapping_url]: sourceMappingURL magic comment DECL_ACCESSORS(source_mapping_url, Object) - // [wasm_module_object]: the wasm module object this script belongs to. + // [wasm_breakpoint_infos]: the list of {BreakPointInfo} objects describing + // all WebAssembly breakpoints for modules/instances managed via this script. + // This must only be called if the type of this script is TYPE_WASM. + DECL_ACCESSORS(wasm_breakpoint_infos, FixedArray) + inline bool has_wasm_breakpoint_infos() const; + + // [wasm_native_module]: the wasm {NativeModule} this script belongs to. + // This must only be called if the type of this script is TYPE_WASM. + DECL_ACCESSORS(wasm_managed_native_module, Object) + inline wasm::NativeModule* wasm_native_module() const; + + // [wasm_weak_instance_list]: the list of all {WasmInstanceObject} being + // affected by breakpoints that are managed via this script. // This must only be called if the type of this script is TYPE_WASM. - DECL_ACCESSORS(wasm_module_object, Object) + DECL_ACCESSORS(wasm_weak_instance_list, WeakArrayList) // [host_defined_options]: Options defined by the embedder. DECL_ACCESSORS(host_defined_options, FixedArray) diff --git a/deps/v8/src/objects/shared-function-info-inl.h b/deps/v8/src/objects/shared-function-info-inl.h index 6023c3b8286981..4f12bc4324a516 100644 --- a/deps/v8/src/objects/shared-function-info-inl.h +++ b/deps/v8/src/objects/shared-function-info-inl.h @@ -21,11 +21,7 @@ namespace v8 { namespace internal { -OBJECT_CONSTRUCTORS_IMPL(PreparseData, HeapObject) - -CAST_ACCESSOR(PreparseData) -INT_ACCESSORS(PreparseData, data_length, kDataLengthOffset) -INT_ACCESSORS(PreparseData, children_length, kInnerLengthOffset) +TQ_OBJECT_CONSTRUCTORS_IMPL(PreparseData) int PreparseData::inner_start_offset() const { return InnerOffset(data_length()); @@ -84,26 +80,9 @@ void PreparseData::set_child(int index, PreparseData value, CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode); } -OBJECT_CONSTRUCTORS_IMPL(UncompiledData, HeapObject) -OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData, UncompiledData) -OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData, UncompiledData) -CAST_ACCESSOR(UncompiledData) -ACCESSORS(UncompiledData, inferred_name, String, kInferredNameOffset) -INT32_ACCESSORS(UncompiledData, start_position, kStartPositionOffset) -INT32_ACCESSORS(UncompiledData, end_position, kEndPositionOffset) - -void UncompiledData::clear_padding() { - if (FIELD_SIZE(kOptionalPaddingOffset) == 0) return; - DCHECK_EQ(4, FIELD_SIZE(kOptionalPaddingOffset)); - memset(reinterpret_cast<void*>(address() + kOptionalPaddingOffset), 0, - FIELD_SIZE(kOptionalPaddingOffset)); -} - -CAST_ACCESSOR(UncompiledDataWithoutPreparseData) - -CAST_ACCESSOR(UncompiledDataWithPreparseData) -ACCESSORS(UncompiledDataWithPreparseData, preparse_data, PreparseData, - kPreparseDataOffset) +TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledData) +TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData) +TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData) DEF_GETTER(HeapObject, IsUncompiledData, bool) { return IsUncompiledDataWithoutPreparseData(isolate) || @@ -124,7 +103,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object, kNameOrScopeInfoOffset) -ACCESSORS(SharedFunctionInfo, script_or_debug_info, Object, +ACCESSORS(SharedFunctionInfo, script_or_debug_info, HeapObject, kScriptOrDebugInfoOffset) INT32_ACCESSORS(SharedFunctionInfo, function_literal_id, @@ -229,6 +208,9 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, is_safe_to_skip_arguments_adaptor, SharedFunctionInfo::IsSafeToSkipArgumentsAdaptorBit) +BIT_FIELD_ACCESSORS(SharedFunctionInfo, flags, + private_name_lookup_skips_outer_class, + SharedFunctionInfo::PrivateNameLookupSkipsOuterClassBit) bool SharedFunctionInfo::optimization_disabled() const { return disable_optimization_reason() != BailoutReason::kNoReason; @@ -613,12 +595,11 @@ void SharedFunctionInfo::ClearPreparseData() { Heap* heap = GetHeapFromWritableObject(data); // Swap the map. - heap->NotifyObjectLayoutChange(data, UncompiledDataWithPreparseData::kSize, - no_gc); + heap->NotifyObjectLayoutChange(data, no_gc); STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize < UncompiledDataWithPreparseData::kSize); STATIC_ASSERT(UncompiledDataWithoutPreparseData::kSize == - UncompiledData::kSize); + UncompiledData::kHeaderSize); data.synchronized_set_map( GetReadOnlyRoots().uncompiled_data_without_preparse_data_map()); @@ -644,7 +625,6 @@ void UncompiledData::Initialize( data, data.RawField(UncompiledData::kInferredNameOffset), inferred_name); data.set_start_position(start_position); data.set_end_position(end_position); - data.clear_padding(); } void UncompiledDataWithPreparseData::Initialize( @@ -672,16 +652,16 @@ bool SharedFunctionInfo::HasWasmCapiFunctionData() const { return function_data().IsWasmCapiFunctionData(); } -Object SharedFunctionInfo::script() const { - Object maybe_script = script_or_debug_info(); +HeapObject SharedFunctionInfo::script() const { + HeapObject maybe_script = script_or_debug_info(); if (maybe_script.IsDebugInfo()) { return DebugInfo::cast(maybe_script).script(); } return maybe_script; } -void SharedFunctionInfo::set_script(Object script) { - Object maybe_debug_info = script_or_debug_info(); +void SharedFunctionInfo::set_script(HeapObject script) { + HeapObject maybe_debug_info = script_or_debug_info(); if (maybe_debug_info.IsDebugInfo()) { DebugInfo::cast(maybe_debug_info).set_script(script); } else { diff --git a/deps/v8/src/objects/shared-function-info.h b/deps/v8/src/objects/shared-function-info.h index dc84653ede2987..9c57d3669781bc 100644 --- a/deps/v8/src/objects/shared-function-info.h +++ b/deps/v8/src/objects/shared-function-info.h @@ -5,6 +5,8 @@ #ifndef V8_OBJECTS_SHARED_FUNCTION_INFO_H_ #define V8_OBJECTS_SHARED_FUNCTION_INFO_H_ +#include <memory> + #include "src/codegen/bailout-reason.h" #include "src/objects/compressed-slots.h" #include "src/objects/function-kind.h" @@ -55,11 +57,9 @@ class WasmJSFunctionData; // +-------------------------------+ // | Inner PreparseData N | // +-------------------------------+ -class PreparseData : public HeapObject { +class PreparseData + : public TorqueGeneratedPreparseData<PreparseData, HeapObject> { public: - DECL_INT_ACCESSORS(data_length) - DECL_INT_ACCESSORS(children_length) - inline int inner_start_offset() const; inline ObjectSlot inner_data_start() const; @@ -74,12 +74,9 @@ class PreparseData : public HeapObject { // Clear uninitialized padding space. inline void clear_padding(); - DECL_CAST(PreparseData) DECL_PRINTER(PreparseData) DECL_VERIFIER(PreparseData) - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_PREPARSE_DATA_FIELDS) static const int kDataStartOffset = kSize; class BodyDescriptor; @@ -92,7 +89,7 @@ class PreparseData : public HeapObject { return InnerOffset(data_length) + children_length * kTaggedSize; } - OBJECT_CONSTRUCTORS(PreparseData, HeapObject); + TQ_OBJECT_CONSTRUCTORS(PreparseData) private: inline Object get_child_raw(int index) const; @@ -100,14 +97,9 @@ class PreparseData : public HeapObject { // Abstract class representing extra data for an uncompiled function, which is // not stored in the SharedFunctionInfo. -class UncompiledData : public HeapObject { +class UncompiledData + : public TorqueGeneratedUncompiledData<UncompiledData, HeapObject> { public: - DECL_ACCESSORS(inferred_name, String) - DECL_INT32_ACCESSORS(start_position) - DECL_INT32_ACCESSORS(end_position) - - DECL_CAST(UncompiledData) - inline static void Initialize( UncompiledData data, String inferred_name, int start_position, int end_position, @@ -115,56 +107,35 @@ class UncompiledData : public HeapObject { gc_notify_updated_slot = [](HeapObject object, ObjectSlot slot, HeapObject target) {}); - // Layout description. -#define UNCOMPILED_DATA_FIELDS(V) \ - V(kStartOfStrongFieldsOffset, 0) \ - V(kInferredNameOffset, kTaggedSize) \ - V(kEndOfStrongFieldsOffset, 0) \ - /* Raw data fields. */ \ - V(kStartPositionOffset, kInt32Size) \ - V(kEndPositionOffset, kInt32Size) \ - V(kOptionalPaddingOffset, POINTER_SIZE_PADDING(kOptionalPaddingOffset)) \ - /* Header size. */ \ - V(kSize, 0) - - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, UNCOMPILED_DATA_FIELDS) -#undef UNCOMPILED_DATA_FIELDS - - using BodyDescriptor = FixedBodyDescriptor<kStartOfStrongFieldsOffset, - kEndOfStrongFieldsOffset, kSize>; - - // Clear uninitialized padding space. - inline void clear_padding(); + using BodyDescriptor = + FixedBodyDescriptor<kStartOfStrongFieldsOffset, kEndOfStrongFieldsOffset, + kHeaderSize>; - OBJECT_CONSTRUCTORS(UncompiledData, HeapObject); + TQ_OBJECT_CONSTRUCTORS(UncompiledData) }; // Class representing data for an uncompiled function that does not have any // data from the pre-parser, either because it's a leaf function or because the // pre-parser bailed out. -class UncompiledDataWithoutPreparseData : public UncompiledData { +class UncompiledDataWithoutPreparseData + : public TorqueGeneratedUncompiledDataWithoutPreparseData< + UncompiledDataWithoutPreparseData, UncompiledData> { public: - DECL_CAST(UncompiledDataWithoutPreparseData) DECL_PRINTER(UncompiledDataWithoutPreparseData) - DECL_VERIFIER(UncompiledDataWithoutPreparseData) - - static const int kSize = UncompiledData::kSize; // No extra fields compared to UncompiledData. using BodyDescriptor = UncompiledData::BodyDescriptor; - OBJECT_CONSTRUCTORS(UncompiledDataWithoutPreparseData, UncompiledData); + TQ_OBJECT_CONSTRUCTORS(UncompiledDataWithoutPreparseData) }; // Class representing data for an uncompiled function that has pre-parsed scope // data. -class UncompiledDataWithPreparseData : public UncompiledData { +class UncompiledDataWithPreparseData + : public TorqueGeneratedUncompiledDataWithPreparseData< + UncompiledDataWithPreparseData, UncompiledData> { public: - DECL_ACCESSORS(preparse_data, PreparseData) - - DECL_CAST(UncompiledDataWithPreparseData) DECL_PRINTER(UncompiledDataWithPreparseData) - DECL_VERIFIER(UncompiledDataWithPreparseData) inline static void Initialize( UncompiledDataWithPreparseData data, String inferred_name, @@ -173,28 +144,12 @@ class UncompiledDataWithPreparseData : public UncompiledData { gc_notify_updated_slot = [](HeapObject object, ObjectSlot slot, HeapObject target) {}); - // Layout description. - -#define UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS(V) \ - V(kStartOfStrongFieldsOffset, 0) \ - V(kPreparseDataOffset, kTaggedSize) \ - V(kEndOfStrongFieldsOffset, 0) \ - /* Total size. */ \ - V(kSize, 0) - - DEFINE_FIELD_OFFSET_CONSTANTS(UncompiledData::kSize, - UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS) -#undef UNCOMPILED_DATA_WITH_PREPARSE_DATA_FIELDS - - // Make sure the size is aligned - STATIC_ASSERT(IsAligned(kSize, kTaggedSize)); - using BodyDescriptor = SubclassBodyDescriptor< UncompiledData::BodyDescriptor, FixedBodyDescriptor<kStartOfStrongFieldsOffset, kEndOfStrongFieldsOffset, kSize>>; - OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseData, UncompiledData); + TQ_OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseData) }; class InterpreterData : public Struct { @@ -242,7 +197,7 @@ class SharedFunctionInfo : public HeapObject { // Set up the link between shared function info and the script. The shared // function info is added to the list on the script. V8_EXPORT_PRIVATE static void SetScript( - Handle<SharedFunctionInfo> shared, Handle<Object> script_object, + Handle<SharedFunctionInfo> shared, Handle<HeapObject> script_object, int function_literal_id, bool reset_preparsed_scope_data = true); // Layout description of the optimized code map. @@ -408,10 +363,10 @@ class SharedFunctionInfo : public HeapObject { // [script_or_debug_info]: One of: // - Script from which the function originates. // - a DebugInfo which holds the actual script [HasDebugInfo()]. - DECL_ACCESSORS(script_or_debug_info, Object) + DECL_ACCESSORS(script_or_debug_info, HeapObject) - inline Object script() const; - inline void set_script(Object script); + inline HeapObject script() const; + inline void set_script(HeapObject script); // The function is subject to debugging if a debug info is attached. inline bool HasDebugInfo() const; @@ -490,6 +445,10 @@ class SharedFunctionInfo : public HeapObject { // Indicates that the function has been reported for binary code coverage. DECL_BOOLEAN_ACCESSORS(has_reported_binary_coverage) + // Indicates that the private name lookups inside the function skips the + // closest outer class scope. + DECL_BOOLEAN_ACCESSORS(private_name_lookup_skips_outer_class) + inline FunctionKind kind() const; // Defines the index in a native context of closure's map instantiated using @@ -640,21 +599,6 @@ class SharedFunctionInfo : public HeapObject { DISALLOW_COPY_AND_ASSIGN(ScriptIterator); }; - // Iterate over all shared function infos on the heap. - class GlobalIterator { - public: - V8_EXPORT_PRIVATE explicit GlobalIterator(Isolate* isolate); - V8_EXPORT_PRIVATE SharedFunctionInfo Next(); - - private: - Isolate* isolate_; - Script::Iterator script_iterator_; - WeakArrayList::Iterator noscript_sfi_iterator_; - SharedFunctionInfo::ScriptIterator sfi_iterator_; - DISALLOW_HEAP_ALLOCATION(no_gc_) - DISALLOW_COPY_AND_ASSIGN(GlobalIterator); - }; - DECL_CAST(SharedFunctionInfo) // Constants. @@ -691,7 +635,8 @@ class SharedFunctionInfo : public HeapObject { V(HasReportedBinaryCoverageBit, bool, 1, _) \ V(IsTopLevelBit, bool, 1, _) \ V(IsOneshotIIFEOrPropertiesAreFinalBit, bool, 1, _) \ - V(IsSafeToSkipArgumentsAdaptorBit, bool, 1, _) + V(IsSafeToSkipArgumentsAdaptorBit, bool, 1, _) \ + V(PrivateNameLookupSkipsOuterClassBit, bool, 1, _) DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS) #undef FLAGS_BIT_FIELDS diff --git a/deps/v8/src/objects/slots-inl.h b/deps/v8/src/objects/slots-inl.h index b240729114e676..7e692b7948317a 100644 --- a/deps/v8/src/objects/slots-inl.h +++ b/deps/v8/src/objects/slots-inl.h @@ -119,7 +119,7 @@ inline void MemsetTagged(ObjectSlot start, Object value, size_t counter) { #ifdef V8_COMPRESS_POINTERS Tagged_t raw_value = CompressTagged(value.ptr()); STATIC_ASSERT(kTaggedSize == kInt32Size); - MemsetInt32(start.location(), raw_value, counter); + MemsetInt32(reinterpret_cast<int32_t*>(start.location()), raw_value, counter); #else Address raw_value = value.ptr(); MemsetPointer(start.location(), raw_value, counter); diff --git a/deps/v8/src/objects/source-text-module.cc b/deps/v8/src/objects/source-text-module.cc index f17c59de1adfd7..2959e1b8542e6c 100644 --- a/deps/v8/src/objects/source-text-module.cc +++ b/deps/v8/src/objects/source-text-module.cc @@ -78,8 +78,6 @@ class Module::ResolveSet SharedFunctionInfo SourceTextModule::GetSharedFunctionInfo() const { DisallowHeapAllocation no_alloc; - DCHECK_NE(status(), Module::kEvaluating); - DCHECK_NE(status(), Module::kEvaluated); switch (status()) { case kUninstantiated: case kPreInstantiating: @@ -89,10 +87,10 @@ SharedFunctionInfo SourceTextModule::GetSharedFunctionInfo() const { DCHECK(code().IsJSFunction()); return JSFunction::cast(code()).shared(); case kInstantiated: - DCHECK(code().IsJSGeneratorObject()); - return JSGeneratorObject::cast(code()).function().shared(); case kEvaluating: case kEvaluated: + DCHECK(code().IsJSGeneratorObject()); + return JSGeneratorObject::cast(code()).function().shared(); case kErrored: UNREACHABLE(); } @@ -580,58 +578,518 @@ Handle<JSModuleNamespace> SourceTextModule::GetModuleNamespace( return Module::GetModuleNamespace(isolate, requested_module); } +MaybeHandle<Object> SourceTextModule::EvaluateMaybeAsync( + Isolate* isolate, Handle<SourceTextModule> module) { + // In the event of errored evaluation, return a rejected promise. + if (module->status() == kErrored) { + // If we have a top level capability we assume it has already been + // rejected, and return it here. Otherwise create a new promise and + // reject it with the module's exception. + if (module->top_level_capability().IsJSPromise()) { + Handle<JSPromise> top_level_capability( + JSPromise::cast(module->top_level_capability()), isolate); + DCHECK(top_level_capability->status() == Promise::kRejected && + top_level_capability->result() == module->exception()); + return top_level_capability; + } + Handle<JSPromise> capability = isolate->factory()->NewJSPromise(); + JSPromise::Reject(capability, handle(module->exception(), isolate)); + return capability; + } + + // Start of Evaluate () Concrete Method + // 2. Assert: module.[[Status]] is "linked" or "evaluated". + CHECK(module->status() == kInstantiated || module->status() == kEvaluated); + + // 3. If module.[[Status]] is "evaluated", set module to + // GetAsyncCycleRoot(module). + if (module->status() == kEvaluated) { + module = GetAsyncCycleRoot(isolate, module); + } + + // 4. If module.[[TopLevelCapability]] is not undefined, then + // a. Return module.[[TopLevelCapability]].[[Promise]]. + if (module->top_level_capability().IsJSPromise()) { + return handle(JSPromise::cast(module->top_level_capability()), isolate); + } + DCHECK(module->top_level_capability().IsUndefined()); + + // 6. Let capability be ! NewPromiseCapability(%Promise%). + Handle<JSPromise> capability = isolate->factory()->NewJSPromise(); + + // 7. Set module.[[TopLevelCapability]] to capability. + module->set_top_level_capability(*capability); + DCHECK(module->top_level_capability().IsJSPromise()); + + // 9. If result is an abrupt completion, then + Handle<Object> unused_result; + if (!Evaluate(isolate, module).ToHandle(&unused_result)) { + // d. Perform ! Call(capability.[[Reject]], undefined, + // «result.[[Value]]»). + isolate->clear_pending_exception(); + JSPromise::Reject(capability, handle(module->exception(), isolate)); + } else { + // 10. Otherwise, + // a. Assert: module.[[Status]] is "evaluated"... + CHECK_EQ(module->status(), kEvaluated); + + // b. If module.[[AsyncEvaluating]] is false, then + if (!module->async_evaluating()) { + // i. Perform ! Call(capability.[[Resolve]], undefined, + // «undefined»). + JSPromise::Resolve(capability, isolate->factory()->undefined_value()) + .ToHandleChecked(); + } + } + + // 11. Return capability.[[Promise]]. + return capability; +} + MaybeHandle<Object> SourceTextModule::Evaluate( + Isolate* isolate, Handle<SourceTextModule> module) { + // Evaluate () Concrete Method continued from EvaluateMaybeAsync. + CHECK(module->status() == kInstantiated || module->status() == kEvaluated); + + // 5. Let stack be a new empty List. + Zone zone(isolate->allocator(), ZONE_NAME); + ZoneForwardList<Handle<SourceTextModule>> stack(&zone); + unsigned dfs_index = 0; + + // 8. Let result be InnerModuleEvaluation(module, stack, 0). + // 9. If result is an abrupt completion, then + Handle<Object> result; + if (!InnerModuleEvaluation(isolate, module, &stack, &dfs_index) + .ToHandle(&result)) { + // a. For each Cyclic Module Record m in stack, do + for (auto& descendant : stack) { + // i. Assert: m.[[Status]] is "evaluating". + CHECK_EQ(descendant->status(), kEvaluating); + // ii. Set m.[[Status]] to "evaluated". + // iii. Set m.[[EvaluationError]] to result. + descendant->RecordErrorUsingPendingException(isolate); + } + DCHECK_EQ(module->exception(), isolate->pending_exception()); + } else { + // 10. Otherwise, + // c. Assert: stack is empty. + DCHECK(stack.empty()); + } + return result; +} + +void SourceTextModule::AsyncModuleExecutionFulfilled( + Isolate* isolate, Handle<SourceTextModule> module) { + // 1. Assert: module.[[Status]] is "evaluated". + CHECK(module->status() == kEvaluated || module->status() == kErrored); + + // 2. If module.[[AsyncEvaluating]] is false, + if (!module->async_evaluating()) { + // a. Assert: module.[[EvaluationError]] is not undefined. + CHECK_EQ(module->status(), kErrored); + + // b. Return undefined. + return; + } + + // 3. Assert: module.[[EvaluationError]] is undefined. + CHECK_EQ(module->status(), kEvaluated); + + // 4. Set module.[[AsyncEvaluating]] to false. + module->set_async_evaluating(false); + + // 5. For each Module m of module.[[AsyncParentModules]], do + for (int i = 0; i < module->AsyncParentModuleCount(); i++) { + Handle<SourceTextModule> m = module->GetAsyncParentModule(isolate, i); + + // a. If module.[[DFSIndex]] is not equal to module.[[DFSAncestorIndex]], + // then + if (module->dfs_index() != module->dfs_ancestor_index()) { + // i. Assert: m.[[DFSAncestorIndex]] is equal to + // module.[[DFSAncestorIndex]]. + DCHECK_LE(m->dfs_ancestor_index(), module->dfs_ancestor_index()); + } + // b. Decrement m.[[PendingAsyncDependencies]] by 1. + m->DecrementPendingAsyncDependencies(); + + // c. If m.[[PendingAsyncDependencies]] is 0 and m.[[EvaluationError]] is + // undefined, then + if (!m->HasPendingAsyncDependencies() && m->status() == kEvaluated) { + // i. Assert: m.[[AsyncEvaluating]] is true. + DCHECK(m->async_evaluating()); + + // ii. Let cycleRoot be ! GetAsyncCycleRoot(m). + auto cycle_root = GetAsyncCycleRoot(isolate, m); + + // iii. If cycleRoot.[[EvaluationError]] is not undefined, + // return undefined. + if (cycle_root->status() == kErrored) { + return; + } + + // iv. If m.[[Async]] is true, then + if (m->async()) { + // 1. Perform ! ExecuteAsyncModule(m). + ExecuteAsyncModule(isolate, m); + } else { + // v. Otherwise, + // 1. Let result be m.ExecuteModule(). + // 2. If result is a normal completion, + Handle<Object> unused_result; + if (ExecuteModule(isolate, m).ToHandle(&unused_result)) { + // a. Perform ! AsyncModuleExecutionFulfilled(m). + AsyncModuleExecutionFulfilled(isolate, m); + } else { + // 3. Otherwise, + // a. Perform ! AsyncModuleExecutionRejected(m, + // result.[[Value]]). + Handle<Object> exception(isolate->pending_exception(), isolate); + isolate->clear_pending_exception(); + AsyncModuleExecutionRejected(isolate, m, exception); + } + } + } + } + + // 6. If module.[[TopLevelCapability]] is not undefined, then + if (!module->top_level_capability().IsUndefined(isolate)) { + // a. Assert: module.[[DFSIndex]] is equal to module.[[DFSAncestorIndex]]. + DCHECK_EQ(module->dfs_index(), module->dfs_ancestor_index()); + + // b. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], + // undefined, «undefined»). + Handle<JSPromise> capability( + JSPromise::cast(module->top_level_capability()), isolate); + JSPromise::Resolve(capability, isolate->factory()->undefined_value()) + .ToHandleChecked(); + } + + // 7. Return undefined. +} + +void SourceTextModule::AsyncModuleExecutionRejected( Isolate* isolate, Handle<SourceTextModule> module, - ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index) { + Handle<Object> exception) { + // 1. Assert: module.[[Status]] is "evaluated". + CHECK(module->status() == kEvaluated || module->status() == kErrored); + + // 2. If module.[[AsyncEvaluating]] is false, + if (!module->async_evaluating()) { + // a. Assert: module.[[EvaluationError]] is not undefined. + CHECK_EQ(module->status(), kErrored); + + // b. Return undefined. + return; + } + + // 4. Set module.[[EvaluationError]] to ThrowCompletion(error). + module->RecordError(isolate, exception); + + // 5. Set module.[[AsyncEvaluating]] to false. + module->set_async_evaluating(false); + + // 6. For each Module m of module.[[AsyncParentModules]], do + for (int i = 0; i < module->AsyncParentModuleCount(); i++) { + Handle<SourceTextModule> m = module->GetAsyncParentModule(isolate, i); + + // a. If module.[[DFSIndex]] is not equal to module.[[DFSAncestorIndex]], + // then + if (module->dfs_index() != module->dfs_ancestor_index()) { + // i. Assert: m.[[DFSAncestorIndex]] is equal to + // module.[[DFSAncestorIndex]]. + DCHECK_EQ(m->dfs_ancestor_index(), module->dfs_ancestor_index()); + } + // b. Perform ! AsyncModuleExecutionRejected(m, error). + AsyncModuleExecutionRejected(isolate, m, exception); + } + + // 7. If module.[[TopLevelCapability]] is not undefined, then + if (!module->top_level_capability().IsUndefined(isolate)) { + // a. Assert: module.[[DFSIndex]] is equal to module.[[DFSAncestorIndex]]. + DCHECK(module->dfs_index() == module->dfs_ancestor_index()); + + // b. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], + // undefined, «error»). + Handle<JSPromise> capability( + JSPromise::cast(module->top_level_capability()), isolate); + JSPromise::Reject(capability, exception); + } + + // 8. Return undefined. +} + +void SourceTextModule::ExecuteAsyncModule(Isolate* isolate, + Handle<SourceTextModule> module) { + // 1. Assert: module.[[Status]] is "evaluating" or "evaluated". + CHECK(module->status() == kEvaluating || module->status() == kEvaluated); + + // 2. Assert: module.[[Async]] is true. + DCHECK(module->async()); + + // 3. Set module.[[AsyncEvaluating]] to true. + module->set_async_evaluating(true); + + // 4. Let capability be ! NewPromiseCapability(%Promise%). + Handle<JSPromise> capability = isolate->factory()->NewJSPromise(); + + // 5. Let stepsFulfilled be the steps of a CallAsyncModuleFulfilled + Handle<JSFunction> steps_fulfilled( + isolate->native_context()->call_async_module_fulfilled(), isolate); + + ScopedVector<Handle<Object>> empty_argv(0); + + // 6. Let onFulfilled be CreateBuiltinFunction(stepsFulfilled, + // «[[Module]]»). + // 7. Set onFulfilled.[[Module]] to module. + Handle<JSBoundFunction> on_fulfilled = + isolate->factory() + ->NewJSBoundFunction(steps_fulfilled, module, empty_argv) + .ToHandleChecked(); + + // 8. Let stepsRejected be the steps of a CallAsyncModuleRejected. + Handle<JSFunction> steps_rejected( + isolate->native_context()->call_async_module_rejected(), isolate); + + // 9. Let onRejected be CreateBuiltinFunction(stepsRejected, «[[Module]]»). + // 10. Set onRejected.[[Module]] to module. + Handle<JSBoundFunction> on_rejected = + isolate->factory() + ->NewJSBoundFunction(steps_rejected, module, empty_argv) + .ToHandleChecked(); + + // 11. Perform ! PerformPromiseThen(capability.[[Promise]], + // onFulfilled, onRejected). + Handle<Object> argv[] = {on_fulfilled, on_rejected}; + Execution::CallBuiltin(isolate, isolate->promise_then(), capability, + arraysize(argv), argv) + .ToHandleChecked(); + + // 12. Perform ! module.ExecuteModule(capability). + // Note: In V8 we have broken module.ExecuteModule into + // ExecuteModule for synchronous module execution and + // InnerExecuteAsyncModule for asynchronous execution. + InnerExecuteAsyncModule(isolate, module, capability).ToHandleChecked(); + + // 13. Return. +} + +MaybeHandle<Object> SourceTextModule::InnerExecuteAsyncModule( + Isolate* isolate, Handle<SourceTextModule> module, + Handle<JSPromise> capability) { + // If we have an async module, then it has an associated + // JSAsyncFunctionObject, which we then evaluate with the passed in promise + // capability. + Handle<JSAsyncFunctionObject> async_function_object( + JSAsyncFunctionObject::cast(module->code()), isolate); + async_function_object->set_promise(*capability); + Handle<JSFunction> resume( + isolate->native_context()->async_module_evaluate_internal(), isolate); + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, result, + Execution::Call(isolate, resume, async_function_object, 0, nullptr), + Object); + return result; +} + +MaybeHandle<Object> SourceTextModule::ExecuteModule( + Isolate* isolate, Handle<SourceTextModule> module) { + // Synchronous modules have an associated JSGeneratorObject. Handle<JSGeneratorObject> generator(JSGeneratorObject::cast(module->code()), isolate); - module->set_code( - generator->function().shared().scope_info().ModuleDescriptorInfo()); + Handle<JSFunction> resume( + isolate->native_context()->generator_next_internal(), isolate); + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr), + Object); + DCHECK(JSIteratorResult::cast(*result).done().BooleanValue(isolate)); + return handle(JSIteratorResult::cast(*result).value(), isolate); +} + +MaybeHandle<Object> SourceTextModule::InnerModuleEvaluation( + Isolate* isolate, Handle<SourceTextModule> module, + ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index) { + STACK_CHECK(isolate, MaybeHandle<Object>()); + + // InnerModuleEvaluation(module, stack, index) + // 2. If module.[[Status]] is "evaluated", then + // a. If module.[[EvaluationError]] is undefined, return index. + // (We return undefined instead) + if (module->status() == kEvaluated || module->status() == kEvaluating) { + return isolate->factory()->undefined_value(); + } + + // b. Otherwise return module.[[EvaluationError]]. + // (We throw on isolate and return a MaybeHandle<Object> + // instead) + if (module->status() == kErrored) { + isolate->Throw(module->exception()); + return MaybeHandle<Object>(); + } + + // 4. Assert: module.[[Status]] is "linked". + CHECK_EQ(module->status(), kInstantiated); + + // 5. Set module.[[Status]] to "evaluating". module->SetStatus(kEvaluating); + + // 6. Set module.[[DFSIndex]] to index. module->set_dfs_index(*dfs_index); + + // 7. Set module.[[DFSAncestorIndex]] to index. module->set_dfs_ancestor_index(*dfs_index); - stack->push_front(module); + + // 8. Set module.[[PendingAsyncDependencies]] to 0. + DCHECK(!module->HasPendingAsyncDependencies()); + + // 9. Set module.[[AsyncParentModules]] to a new empty List. + Handle<ArrayList> async_parent_modules = ArrayList::New(isolate, 0); + module->set_async_parent_modules(*async_parent_modules); + + // 10. Set index to index + 1. (*dfs_index)++; + // 11. Append module to stack. + stack->push_front(module); + // Recursion. Handle<FixedArray> requested_modules(module->requested_modules(), isolate); + + // 12. For each String required that is an element of + // module.[[RequestedModules]], do for (int i = 0, length = requested_modules->length(); i < length; ++i) { Handle<Module> requested_module(Module::cast(requested_modules->get(i)), isolate); - RETURN_ON_EXCEPTION( - isolate, Module::Evaluate(isolate, requested_module, stack, dfs_index), - Object); - - DCHECK_GE(requested_module->status(), kEvaluating); - DCHECK_NE(requested_module->status(), kErrored); - SLOW_DCHECK( - // {requested_module} is evaluating iff it's on the {stack}. - (requested_module->status() == kEvaluating) == - std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) { - return *m == *requested_module; - })); - - if (requested_module->status() == kEvaluating) { - // SyntheticModules go straight to kEvaluated so this must be a - // SourceTextModule - module->set_dfs_ancestor_index( - std::min(module->dfs_ancestor_index(), - Handle<SourceTextModule>::cast(requested_module) - ->dfs_ancestor_index())); + // d. If requiredModule is a Cyclic Module Record, then + if (requested_module->IsSourceTextModule()) { + Handle<SourceTextModule> required_module( + SourceTextModule::cast(*requested_module), isolate); + RETURN_ON_EXCEPTION( + isolate, + InnerModuleEvaluation(isolate, required_module, stack, dfs_index), + Object); + + // i. Assert: requiredModule.[[Status]] is either "evaluating" or + // "evaluated". + // (We also assert the module cannot be errored, because if it was + // we would have already returned from InnerModuleEvaluation) + CHECK_GE(required_module->status(), kEvaluating); + CHECK_NE(required_module->status(), kErrored); + + // ii. Assert: requiredModule.[[Status]] is "evaluating" if and + // only if requiredModule is in stack. + SLOW_DCHECK( + (requested_module->status() == kEvaluating) == + std::count_if(stack->begin(), stack->end(), [&](Handle<Module> m) { + return *m == *requested_module; + })); + + // iii. If requiredModule.[[Status]] is "evaluating", then + if (required_module->status() == kEvaluating) { + // 1. Set module.[[DFSAncestorIndex]] to + // min( + // module.[[DFSAncestorIndex]], + // requiredModule.[[DFSAncestorIndex]]). + module->set_dfs_ancestor_index( + std::min(module->dfs_ancestor_index(), + required_module->dfs_ancestor_index())); + } else { + // iv. Otherwise, + // 1. Set requiredModule to GetAsyncCycleRoot(requiredModule). + required_module = GetAsyncCycleRoot(isolate, required_module); + + // 2. Assert: requiredModule.[[Status]] is "evaluated". + CHECK_GE(required_module->status(), kEvaluated); + + // 3. If requiredModule.[[EvaluationError]] is not undefined, + // return module.[[EvaluationError]]. + // (If there was an exception on the original required module + // we would have already returned. This check handles the case + // where the AsyncCycleRoot has an error. Instead of returning + // the exception, we throw on isolate and return a + // MaybeHandle<Object>) + if (required_module->status() == kErrored) { + isolate->Throw(required_module->exception()); + return MaybeHandle<Object>(); + } + } + // v. If requiredModule.[[AsyncEvaluating]] is true, then + if (required_module->async_evaluating()) { + // 1. Set module.[[PendingAsyncDependencies]] to + // module.[[PendingAsyncDependencies]] + 1. + module->IncrementPendingAsyncDependencies(); + + // 2. Append module to requiredModule.[[AsyncParentModules]]. + required_module->AddAsyncParentModule(isolate, module); + } + } else { + RETURN_ON_EXCEPTION(isolate, Module::Evaluate(isolate, requested_module), + Object); } } - // Evaluation of module body. - Handle<JSFunction> resume( - isolate->native_context()->generator_next_internal(), isolate); - Handle<Object> result; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, result, Execution::Call(isolate, resume, generator, 0, nullptr), - Object); - DCHECK(JSIteratorResult::cast(*result).done().BooleanValue(isolate)); + // The spec returns the module index for proper numbering of dependencies. + // However, we pass the module index by pointer instead. + // + // Before async modules v8 returned the value result from calling next + // on the module's implicit iterator. We preserve this behavior for + // synchronous modules, but return undefined for AsyncModules. + Handle<Object> result = isolate->factory()->undefined_value(); + + // 14. If module.[[PendingAsyncDependencies]] is > 0, set + // module.[[AsyncEvaluating]] to true. + if (module->HasPendingAsyncDependencies()) { + module->set_async_evaluating(true); + } else if (module->async()) { + // 15. Otherwise, if module.[[Async]] is true, + // perform ! ExecuteAsyncModule(module). + SourceTextModule::ExecuteAsyncModule(isolate, module); + } else { + // 16. Otherwise, perform ? module.ExecuteModule(). + ASSIGN_RETURN_ON_EXCEPTION(isolate, result, ExecuteModule(isolate, module), + Object); + } CHECK(MaybeTransitionComponent(isolate, module, stack, kEvaluated)); - return handle(JSIteratorResult::cast(*result).value(), isolate); + return result; +} + +Handle<SourceTextModule> SourceTextModule::GetAsyncCycleRoot( + Isolate* isolate, Handle<SourceTextModule> module) { + // 1. Assert: module.[[Status]] is "evaluated". + CHECK_GE(module->status(), kEvaluated); + + // 2. If module.[[AsyncParentModules]] is an empty List, return module. + if (module->AsyncParentModuleCount() == 0) { + return module; + } + + // 3. Repeat, while module.[[DFSIndex]] is greater than + // module.[[DFSAncestorIndex]], + while (module->dfs_index() > module->dfs_ancestor_index()) { + // a. Assert: module.[[AsyncParentModules]] is a non-empty List. + DCHECK_GT(module->AsyncParentModuleCount(), 0); + + // b. Let nextCycleModule be the first element of + // module.[[AsyncParentModules]]. + Handle<SourceTextModule> next_cycle_module = + module->GetAsyncParentModule(isolate, 0); + + // c. Assert: nextCycleModule.[[DFSAncestorIndex]] is less than or equal + // to module.[[DFSAncestorIndex]]. + DCHECK_LE(next_cycle_module->dfs_ancestor_index(), + module->dfs_ancestor_index()); + + // d. Set module to nextCycleModule + module = next_cycle_module; + } + + // 4. Assert: module.[[DFSIndex]] is equal to module.[[DFSAncestorIndex]]. + DCHECK_EQ(module->dfs_index(), module->dfs_ancestor_index()); + + // 5. Return module. + return module; } void SourceTextModule::Reset(Isolate* isolate, diff --git a/deps/v8/src/objects/source-text-module.h b/deps/v8/src/objects/source-text-module.h index e6cf260e101532..f1387635d00ca9 100644 --- a/deps/v8/src/objects/source-text-module.h +++ b/deps/v8/src/objects/source-text-module.h @@ -6,6 +6,7 @@ #define V8_OBJECTS_SOURCE_TEXT_MODULE_H_ #include "src/objects/module.h" +#include "src/objects/promise.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" @@ -28,6 +29,10 @@ class SourceTextModule // kErrored. SharedFunctionInfo GetSharedFunctionInfo() const; + // Whether or not this module is an async module. Set during module creation + // and does not change afterwards. + DECL_BOOLEAN_ACCESSORS(async) + // Get the SourceTextModuleInfo associated with the code. inline SourceTextModuleInfo info() const; @@ -41,6 +46,14 @@ class SourceTextModule static int ImportIndex(int cell_index); static int ExportIndex(int cell_index); + // Used by builtins to fulfill or reject the promise associated + // with async SourceTextModules. + static void AsyncModuleExecutionFulfilled(Isolate* isolate, + Handle<SourceTextModule> module); + static void AsyncModuleExecutionRejected(Isolate* isolate, + Handle<SourceTextModule> module, + Handle<Object> exception); + // Get the namespace object for [module_request] of [module]. If it doesn't // exist yet, it is created. static Handle<JSModuleNamespace> GetModuleNamespace( @@ -54,12 +67,54 @@ class SourceTextModule friend class Factory; friend class Module; + // Appends a tuple of module and generator to the async parent modules + // ArrayList. + inline void AddAsyncParentModule(Isolate* isolate, + Handle<SourceTextModule> module); + + // Returns a SourceTextModule, the + // ith parent in depth first traversal order of a given async child. + inline Handle<SourceTextModule> GetAsyncParentModule(Isolate* isolate, + int index); + + // Returns the number of async parent modules for a given async child. + inline int AsyncParentModuleCount(); + + inline bool HasPendingAsyncDependencies(); + inline void IncrementPendingAsyncDependencies(); + inline void DecrementPendingAsyncDependencies(); + // TODO(neis): Don't store those in the module object? DECL_INT_ACCESSORS(dfs_index) DECL_INT_ACCESSORS(dfs_ancestor_index) - // Helpers for Instantiate and Evaluate. + // Storage for boolean flags. + DECL_INT_ACCESSORS(flags) + + // Bits for flags. + static const int kAsyncBit = 0; + static const int kAsyncEvaluatingBit = 1; + + // async_evaluating, top_level_capability, pending_async_dependencies, and + // async_parent_modules are used exclusively during evaluation of async + // modules and the modules which depend on them. + // + // Whether or not this module is async and evaluating or currently evaluating + // an async child. + DECL_BOOLEAN_ACCESSORS(async_evaluating) + + // The top level promise capability of this module. Will only be defined + // for cycle roots. + DECL_ACCESSORS(top_level_capability, HeapObject) + + // The number of currently evaluating async dependencies of this module. + DECL_INT_ACCESSORS(pending_async_dependencies) + + // The parent modules of a given async dependency, use async_parent_modules() + // to retrieve the ArrayList representation. + DECL_ACCESSORS(async_parent_modules, ArrayList) + // Helpers for Instantiate and Evaluate. static void CreateExport(Isolate* isolate, Handle<SourceTextModule> module, int cell_index, Handle<FixedArray> names); static void CreateIndirectExport(Isolate* isolate, @@ -95,7 +150,16 @@ class SourceTextModule Handle<SourceTextModule> module, Zone* zone, UnorderedModuleSet* visited); + // Implementation of spec concrete method Evaluate. + static V8_WARN_UNUSED_RESULT MaybeHandle<Object> EvaluateMaybeAsync( + Isolate* isolate, Handle<SourceTextModule> module); + + // Continued implementation of spec concrete method Evaluate. static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate( + Isolate* isolate, Handle<SourceTextModule> module); + + // Implementation of spec abstract operation InnerModuleEvaluation. + static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerModuleEvaluation( Isolate* isolate, Handle<SourceTextModule> module, ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index); @@ -103,6 +167,24 @@ class SourceTextModule Isolate* isolate, Handle<SourceTextModule> module, ZoneForwardList<Handle<SourceTextModule>>* stack, Status new_status); + // Implementation of spec GetAsyncCycleRoot. + static V8_WARN_UNUSED_RESULT Handle<SourceTextModule> GetAsyncCycleRoot( + Isolate* isolate, Handle<SourceTextModule> module); + + // Implementation of spec ExecuteModule is broken up into + // InnerExecuteAsyncModule for asynchronous modules and ExecuteModule + // for synchronous modules. + static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerExecuteAsyncModule( + Isolate* isolate, Handle<SourceTextModule> module, + Handle<JSPromise> capability); + + static V8_WARN_UNUSED_RESULT MaybeHandle<Object> ExecuteModule( + Isolate* isolate, Handle<SourceTextModule> module); + + // Implementation of spec ExecuteAsyncModule. + static void ExecuteAsyncModule(Isolate* isolate, + Handle<SourceTextModule> module); + static void Reset(Isolate* isolate, Handle<SourceTextModule> module); TQ_OBJECT_CONSTRUCTORS(SourceTextModule) @@ -169,9 +251,10 @@ class SourceTextModuleInfoEntry DECL_INT_ACCESSORS(end_pos) static Handle<SourceTextModuleInfoEntry> New( - Isolate* isolate, Handle<HeapObject> export_name, - Handle<HeapObject> local_name, Handle<HeapObject> import_name, - int module_request, int cell_index, int beg_pos, int end_pos); + Isolate* isolate, Handle<PrimitiveHeapObject> export_name, + Handle<PrimitiveHeapObject> local_name, + Handle<PrimitiveHeapObject> import_name, int module_request, + int cell_index, int beg_pos, int end_pos); TQ_OBJECT_CONSTRUCTORS(SourceTextModuleInfoEntry) }; diff --git a/deps/v8/src/objects/stack-frame-info.cc b/deps/v8/src/objects/stack-frame-info.cc index 323c4b8fcbb57f..040c6f7b326dca 100644 --- a/deps/v8/src/objects/stack-frame-info.cc +++ b/deps/v8/src/objects/stack-frame-info.cc @@ -299,10 +299,8 @@ void AppendMethodCall(Isolate* isolate, Handle<StackTraceFrame> frame, } } -void SerializeJSStackFrame( - Isolate* isolate, Handle<StackTraceFrame> frame, - IncrementalStringBuilder& builder // NOLINT(runtime/references) -) { +void SerializeJSStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame, + IncrementalStringBuilder* builder) { Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame); const bool is_toplevel = StackTraceFrame::IsToplevel(frame); @@ -316,96 +314,91 @@ void SerializeJSStackFrame( const bool is_method_call = !(is_toplevel || is_constructor); if (is_async) { - builder.AppendCString("async "); + builder->AppendCString("async "); } if (is_promise_all) { - builder.AppendCString("Promise.all (index "); - builder.AppendInt(StackTraceFrame::GetPromiseAllIndex(frame)); - builder.AppendCString(")"); + builder->AppendCString("Promise.all (index "); + builder->AppendInt(StackTraceFrame::GetPromiseAllIndex(frame)); + builder->AppendCString(")"); return; } if (is_method_call) { - AppendMethodCall(isolate, frame, &builder); + AppendMethodCall(isolate, frame, builder); } else if (is_constructor) { - builder.AppendCString("new "); + builder->AppendCString("new "); if (IsNonEmptyString(function_name)) { - builder.AppendString(Handle<String>::cast(function_name)); + builder->AppendString(Handle<String>::cast(function_name)); } else { - builder.AppendCString("<anonymous>"); + builder->AppendCString("<anonymous>"); } } else if (IsNonEmptyString(function_name)) { - builder.AppendString(Handle<String>::cast(function_name)); + builder->AppendString(Handle<String>::cast(function_name)); } else { - AppendFileLocation(isolate, frame, &builder); + AppendFileLocation(isolate, frame, builder); return; } - builder.AppendCString(" ("); - AppendFileLocation(isolate, frame, &builder); - builder.AppendCString(")"); + builder->AppendCString(" ("); + AppendFileLocation(isolate, frame, builder); + builder->AppendCString(")"); } -void SerializeAsmJsWasmStackFrame( - Isolate* isolate, Handle<StackTraceFrame> frame, - IncrementalStringBuilder& builder // NOLINT(runtime/references) -) { +void SerializeAsmJsWasmStackFrame(Isolate* isolate, + Handle<StackTraceFrame> frame, + IncrementalStringBuilder* builder) { // The string should look exactly as the respective javascript frame string. // Keep this method in line to // JSStackFrame::ToString(IncrementalStringBuilder&). Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame); if (IsNonEmptyString(function_name)) { - builder.AppendString(Handle<String>::cast(function_name)); - builder.AppendCString(" ("); + builder->AppendString(Handle<String>::cast(function_name)); + builder->AppendCString(" ("); } - AppendFileLocation(isolate, frame, &builder); + AppendFileLocation(isolate, frame, builder); - if (IsNonEmptyString(function_name)) builder.AppendCString(")"); + if (IsNonEmptyString(function_name)) builder->AppendCString(")"); return; } -void SerializeWasmStackFrame( - Isolate* isolate, Handle<StackTraceFrame> frame, - IncrementalStringBuilder& builder // NOLINT(runtime/references) -) { +void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame, + IncrementalStringBuilder* builder) { Handle<Object> module_name = StackTraceFrame::GetWasmModuleName(frame); Handle<Object> function_name = StackTraceFrame::GetFunctionName(frame); const bool has_name = !module_name->IsNull() || !function_name->IsNull(); if (has_name) { if (module_name->IsNull()) { - builder.AppendString(Handle<String>::cast(function_name)); + builder->AppendString(Handle<String>::cast(function_name)); } else { - builder.AppendString(Handle<String>::cast(module_name)); + builder->AppendString(Handle<String>::cast(module_name)); if (!function_name->IsNull()) { - builder.AppendCString("."); - builder.AppendString(Handle<String>::cast(function_name)); + builder->AppendCString("."); + builder->AppendString(Handle<String>::cast(function_name)); } } - builder.AppendCString(" ("); + builder->AppendCString(" ("); } const int wasm_func_index = StackTraceFrame::GetLineNumber(frame); - builder.AppendCString("wasm-function["); - builder.AppendInt(wasm_func_index); - builder.AppendCString("]:"); + builder->AppendCString("wasm-function["); + builder->AppendInt(wasm_func_index); + builder->AppendCString("]:"); char buffer[16]; SNPrintF(ArrayVector(buffer), "0x%x", StackTraceFrame::GetColumnNumber(frame)); - builder.AppendCString(buffer); + builder->AppendCString(buffer); - if (has_name) builder.AppendCString(")"); + if (has_name) builder->AppendCString(")"); } } // namespace -void SerializeStackTraceFrame( - Isolate* isolate, Handle<StackTraceFrame> frame, - IncrementalStringBuilder& builder // NOLINT(runtime/references) -) { +void SerializeStackTraceFrame(Isolate* isolate, Handle<StackTraceFrame> frame, + IncrementalStringBuilder* builder) { // Ordering here is important, as AsmJs frames are also marked as Wasm. if (StackTraceFrame::IsAsmJsWasm(frame)) { SerializeAsmJsWasmStackFrame(isolate, frame, builder); @@ -419,7 +412,7 @@ void SerializeStackTraceFrame( MaybeHandle<String> SerializeStackTraceFrame(Isolate* isolate, Handle<StackTraceFrame> frame) { IncrementalStringBuilder builder(isolate); - SerializeStackTraceFrame(isolate, frame, builder); + SerializeStackTraceFrame(isolate, frame, &builder); return builder.Finish(); } diff --git a/deps/v8/src/objects/stack-frame-info.h b/deps/v8/src/objects/stack-frame-info.h index 7c4918a3c6bde0..54b64b611858a5 100644 --- a/deps/v8/src/objects/stack-frame-info.h +++ b/deps/v8/src/objects/stack-frame-info.h @@ -124,10 +124,8 @@ Handle<FrameArray> GetFrameArrayFromStackTrace(Isolate* isolate, Handle<FixedArray> stack_trace); class IncrementalStringBuilder; -void SerializeStackTraceFrame( - Isolate* isolate, Handle<StackTraceFrame> frame, - IncrementalStringBuilder& builder // NOLINT(runtime/references) -); +void SerializeStackTraceFrame(Isolate* isolate, Handle<StackTraceFrame> frame, + IncrementalStringBuilder* builder); MaybeHandle<String> SerializeStackTraceFrame(Isolate* isolate, Handle<StackTraceFrame> frame); diff --git a/deps/v8/src/objects/string-inl.h b/deps/v8/src/objects/string-inl.h index 083928d2119de5..b4aea68cb16bb2 100644 --- a/deps/v8/src/objects/string-inl.h +++ b/deps/v8/src/objects/string-inl.h @@ -778,6 +778,14 @@ bool String::AsArrayIndex(uint32_t* index) { return SlowAsArrayIndex(index); } +bool String::AsIntegerIndex(size_t* index) { + uint32_t field = hash_field(); + if (IsHashFieldComputed(field) && (field & kIsNotIntegerIndexMask)) { + return false; + } + return SlowAsIntegerIndex(index); +} + SubStringRange::SubStringRange(String string, const DisallowHeapAllocation& no_gc, int first, int length) diff --git a/deps/v8/src/objects/string.cc b/deps/v8/src/objects/string.cc index 41de3aef04c30c..a1eb7f43102f00 100644 --- a/deps/v8/src/objects/string.cc +++ b/deps/v8/src/objects/string.cc @@ -113,7 +113,10 @@ void String::MakeThin(Isolate* isolate, String internalized) { bool has_pointers = StringShape(*this).IsIndirect(); int old_size = this->Size(); - isolate->heap()->NotifyObjectLayoutChange(*this, old_size, no_gc); + // Slot invalidation is not necessary here: ThinString only stores tagged + // value, so it can't store an untagged value in a recorded slot. + isolate->heap()->NotifyObjectLayoutChange(*this, no_gc, + InvalidateRecordedSlots::kNo); bool one_byte = internalized.IsOneByteRepresentation(); Handle<Map> map = one_byte ? isolate->factory()->thin_one_byte_string_map() : isolate->factory()->thin_string_map(); @@ -158,7 +161,8 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) { bool has_pointers = StringShape(*this).IsIndirect(); if (has_pointers) { - isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation); + isolate->heap()->NotifyObjectLayoutChange(*this, no_allocation, + InvalidateRecordedSlots::kYes); } // Morph the string to an external string by replacing the map and // reinitializing the fields. This won't work if the space the existing @@ -184,10 +188,6 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) { isolate->heap()->CreateFillerObjectAt( this->address() + new_size, size - new_size, has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo); - if (has_pointers) { - isolate->heap()->ClearRecordedSlotRange(this->address(), - this->address() + new_size); - } // We are storing the new map using release store after creating a filler for // the left-over space to avoid races with the sweeper thread. @@ -232,7 +232,8 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { bool has_pointers = StringShape(*this).IsIndirect(); if (has_pointers) { - isolate->heap()->NotifyObjectLayoutChange(*this, size, no_allocation); + isolate->heap()->NotifyObjectLayoutChange(*this, no_allocation, + InvalidateRecordedSlots::kYes); } // Morph the string to an external string by replacing the map and // reinitializing the fields. This won't work if the space the existing @@ -257,10 +258,6 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) { isolate->heap()->CreateFillerObjectAt( this->address() + new_size, size - new_size, has_pointers ? ClearRecordedSlots::kYes : ClearRecordedSlots::kNo); - if (has_pointers) { - isolate->heap()->ClearRecordedSlotRange(this->address(), - this->address() + new_size); - } // We are storing the new map using release store after creating a filler for // the left-over space to avoid races with the sweeper thread. @@ -598,9 +595,8 @@ void String::WriteToFlat(String src, sinkchar* sink, int f, int t) { String source = src; int from = f; int to = t; - while (true) { + while (from < to) { DCHECK_LE(0, from); - DCHECK_LE(from, to); DCHECK_LE(to, source.length()); switch (StringShape(source).full_representation_tag()) { case kOneByteStringTag | kExternalStringTag: { @@ -678,6 +674,7 @@ void String::WriteToFlat(String src, sinkchar* sink, int f, int t) { break; } } + DCHECK_EQ(from, to); } template <typename SourceChar> @@ -1358,25 +1355,39 @@ uint32_t String::ComputeAndSetHash() { return result; } -bool String::ComputeArrayIndex(uint32_t* index) { +bool String::SlowAsArrayIndex(uint32_t* index) { + DisallowHeapAllocation no_gc; int length = this->length(); + if (length <= kMaxCachedArrayIndexLength) { + Hash(); // Force computation of hash code. + uint32_t field = hash_field(); + if ((field & kIsNotArrayIndexMask) != 0) return false; + *index = ArrayIndexValueBits::decode(field); + return true; + } if (length == 0 || length > kMaxArrayIndexSize) return false; StringCharacterStream stream(*this); return StringToArrayIndex(&stream, index); } -bool String::SlowAsArrayIndex(uint32_t* index) { +bool String::SlowAsIntegerIndex(size_t* index) { DisallowHeapAllocation no_gc; - if (length() <= kMaxCachedArrayIndexLength) { - Hash(); // force computation of hash code + int length = this->length(); + if (length <= kMaxCachedArrayIndexLength) { + Hash(); // Force computation of hash code. uint32_t field = hash_field(); - if ((field & kIsNotArrayIndexMask) != 0) return false; - // Isolate the array index form the full hash field. + if ((field & kIsNotArrayIndexMask) != 0) { + // If it was short but it's not an array index, then it can't be an + // integer index either. + DCHECK_NE(0, field & kIsNotIntegerIndexMask); + return false; + } *index = ArrayIndexValueBits::decode(field); return true; - } else { - return ComputeArrayIndex(index); } + if (length == 0 || length > kMaxIntegerIndexSize) return false; + StringCharacterStream stream(*this); + return StringToArrayIndex(&stream, index); } void String::PrintOn(FILE* file) { diff --git a/deps/v8/src/objects/string.h b/deps/v8/src/objects/string.h index 27bd7e87652859..fcdf75a96862e9 100644 --- a/deps/v8/src/objects/string.h +++ b/deps/v8/src/objects/string.h @@ -5,6 +5,8 @@ #ifndef V8_OBJECTS_STRING_H_ #define V8_OBJECTS_STRING_H_ +#include <memory> + #include "src/base/bits.h" #include "src/base/export-template.h" #include "src/objects/instance-type.h" @@ -306,8 +308,6 @@ class String : public TorqueGeneratedString<String, Name> { RobustnessFlag robustness_flag = FAST_STRING_TRAVERSAL, int* length_output = nullptr); - bool ComputeArrayIndex(uint32_t* index); - // Externalization. V8_EXPORT_PRIVATE bool MakeExternal( v8::String::ExternalStringResource* resource); @@ -316,8 +316,12 @@ class String : public TorqueGeneratedString<String, Name> { bool SupportsExternalization(); // Conversion. + // "array index": an index allowed by the ES spec for JSArrays. inline bool AsArrayIndex(uint32_t* index); uint32_t inline ToValidIndex(Object number); + // "integer index": the string is the decimal representation of an + // integer in the range of a size_t. Useful for TypedArray accesses. + inline bool AsIntegerIndex(size_t* index); // Trimming. enum TrimMode { kTrim, kTrimStart, kTrimEnd }; @@ -448,6 +452,7 @@ class String : public TorqueGeneratedString<String, Name> { // Slow case of AsArrayIndex. V8_EXPORT_PRIVATE bool SlowAsArrayIndex(uint32_t* index); + V8_EXPORT_PRIVATE bool SlowAsIntegerIndex(size_t* index); // Compute and set the hash code. V8_EXPORT_PRIVATE uint32_t ComputeAndSetHash(); diff --git a/deps/v8/src/objects/struct-inl.h b/deps/v8/src/objects/struct-inl.h index af0fed126b4966..34de8897861a7f 100644 --- a/deps/v8/src/objects/struct-inl.h +++ b/deps/v8/src/objects/struct-inl.h @@ -22,12 +22,10 @@ namespace internal { TQ_OBJECT_CONSTRUCTORS_IMPL(Struct) TQ_OBJECT_CONSTRUCTORS_IMPL(Tuple2) TQ_OBJECT_CONSTRUCTORS_IMPL(Tuple3) -OBJECT_CONSTRUCTORS_IMPL(AccessorPair, Struct) +TQ_OBJECT_CONSTRUCTORS_IMPL(AccessorPair) TQ_OBJECT_CONSTRUCTORS_IMPL(ClassPositions) -CAST_ACCESSOR(AccessorPair) - void Struct::InitializeBody(int object_size) { Object value = GetReadOnlyRoots().undefined_value(); for (int offset = kHeaderSize; offset < object_size; offset += kTaggedSize) { @@ -35,9 +33,6 @@ void Struct::InitializeBody(int object_size) { } } -ACCESSORS(AccessorPair, getter, Object, kGetterOffset) -ACCESSORS(AccessorPair, setter, Object, kSetterOffset) - TQ_SMI_ACCESSORS(ClassPositions, start) TQ_SMI_ACCESSORS(ClassPositions, end) diff --git a/deps/v8/src/objects/struct.h b/deps/v8/src/objects/struct.h index c9372d9ada0d48..f786c4711af711 100644 --- a/deps/v8/src/objects/struct.h +++ b/deps/v8/src/objects/struct.h @@ -16,12 +16,13 @@ namespace v8 { namespace internal { // An abstract superclass, a marker class really, for simple structure classes. -// It doesn't carry much functionality but allows struct classes to be +// It doesn't carry any functionality but allows struct classes to be // identified in the type system. class Struct : public TorqueGeneratedStruct<Struct, HeapObject> { public: inline void InitializeBody(int object_size); void BriefPrintDetails(std::ostream& os); + STATIC_ASSERT(kHeaderSize == HeapObject::kHeaderSize); TQ_OBJECT_CONSTRUCTORS(Struct) }; @@ -46,13 +47,8 @@ class Tuple3 : public TorqueGeneratedTuple3<Tuple3, Tuple2> { // * a FunctionTemplateInfo: a real (lazy) accessor // * undefined: considered an accessor by the spec, too, strangely enough // * null: an accessor which has not been set -class AccessorPair : public Struct { +class AccessorPair : public TorqueGeneratedAccessorPair<AccessorPair, Struct> { public: - DECL_ACCESSORS(getter, Object) - DECL_ACCESSORS(setter, Object) - - DECL_CAST(AccessorPair) - static Handle<AccessorPair> Copy(Isolate* isolate, Handle<AccessorPair> pair); inline Object get(AccessorComponent component); @@ -71,13 +67,8 @@ class AccessorPair : public Struct { // Dispatched behavior. DECL_PRINTER(AccessorPair) - DECL_VERIFIER(AccessorPair) - - // Layout description. - DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_ACCESSOR_PAIR_FIELDS) - OBJECT_CONSTRUCTORS(AccessorPair, Struct); + TQ_OBJECT_CONSTRUCTORS(AccessorPair) }; class ClassPositions diff --git a/deps/v8/src/objects/synthetic-module.cc b/deps/v8/src/objects/synthetic-module.cc index 850721ac99d303..75e79e8955141e 100644 --- a/deps/v8/src/objects/synthetic-module.cc +++ b/deps/v8/src/objects/synthetic-module.cc @@ -116,7 +116,7 @@ MaybeHandle<Object> SyntheticModule::Evaluate(Isolate* isolate, Utils::ToLocal(Handle<Module>::cast(module))) .ToLocal(&result)) { isolate->PromoteScheduledException(); - module->RecordError(isolate); + module->RecordErrorUsingPendingException(isolate); return MaybeHandle<Object>(); } diff --git a/deps/v8/src/objects/transitions-inl.h b/deps/v8/src/objects/transitions-inl.h index 048774f49b5926..5694d66d948325 100644 --- a/deps/v8/src/objects/transitions-inl.h +++ b/deps/v8/src/objects/transitions-inl.h @@ -64,6 +64,10 @@ Name TransitionArray::GetKey(int transition_number) { Get(ToKeyIndex(transition_number))->GetHeapObjectAssumeStrong()); } +Name TransitionArray::GetKey(InternalIndex index) { + return GetKey(index.as_int()); +} + Name TransitionsAccessor::GetKey(int transition_number) { switch (encoding()) { case kPrototypeInfo: @@ -95,7 +99,7 @@ HeapObjectSlot TransitionArray::GetTargetSlot(int transition_number) { // static PropertyDetails TransitionsAccessor::GetTargetDetails(Name name, Map target) { DCHECK(!IsSpecialTransition(name.GetReadOnlyRoots(), name)); - int descriptor = target.LastAdded(); + InternalIndex descriptor = target.LastAdded(); DescriptorArray descriptors = target.instance_descriptors(); // Transitions are allowed only for the last added property. DCHECK(descriptors.GetKey(descriptor).Equals(name)); @@ -108,7 +112,7 @@ PropertyDetails TransitionsAccessor::GetSimpleTargetDetails(Map transition) { // static Name TransitionsAccessor::GetSimpleTransitionKey(Map transition) { - int descriptor = transition.LastAdded(); + InternalIndex descriptor = transition.LastAdded(); return transition.instance_descriptors().GetKey(descriptor); } diff --git a/deps/v8/src/objects/transitions.cc b/deps/v8/src/objects/transitions.cc index 843b790b7d764f..e0ba40ce7d0230 100644 --- a/deps/v8/src/objects/transitions.cc +++ b/deps/v8/src/objects/transitions.cc @@ -247,7 +247,7 @@ bool TransitionsAccessor::CanHaveMoreTransitions() { bool TransitionsAccessor::IsMatchingMap(Map target, Name name, PropertyKind kind, PropertyAttributes attributes) { - int descriptor = target.LastAdded(); + InternalIndex descriptor = target.LastAdded(); DescriptorArray descriptors = target.instance_descriptors(); Name key = descriptors.GetKey(descriptor); if (key != name) return false; @@ -296,8 +296,7 @@ Handle<WeakFixedArray> TransitionArray::GrowPrototypeTransitionArray( new_capacity = Min(kMaxCachedPrototypeTransitions, new_capacity); DCHECK_GT(new_capacity, capacity); int grow_by = new_capacity - capacity; - array = isolate->factory()->CopyWeakFixedArrayAndGrow(array, grow_by, - AllocationType::kOld); + array = isolate->factory()->CopyWeakFixedArrayAndGrow(array, grow_by); if (capacity < 0) { // There was no prototype transitions array before, so the size // couldn't be copied. Initialize it explicitly. diff --git a/deps/v8/src/objects/transitions.h b/deps/v8/src/objects/transitions.h index f21e8cd54e5bae..5a7db13e516cf9 100644 --- a/deps/v8/src/objects/transitions.h +++ b/deps/v8/src/objects/transitions.h @@ -221,6 +221,7 @@ class TransitionArray : public WeakFixedArray { Map* target); // Required for templatized Search interface. + inline Name GetKey(InternalIndex index); static constexpr int kNotFound = -1; inline Name GetSortedKey(int transition_number); diff --git a/deps/v8/src/objects/value-serializer.cc b/deps/v8/src/objects/value-serializer.cc index 3b3506fbb9178a..af5cdc57eaf1e0 100644 --- a/deps/v8/src/objects/value-serializer.cc +++ b/deps/v8/src/objects/value-serializer.cc @@ -52,8 +52,6 @@ static const uint32_t kLatestVersion = 13; static_assert(kLatestVersion == v8::CurrentValueSerializerFormatVersion(), "Exported format version must match latest version."); -static const int kPretenureThreshold = 100 * KB; - template <typename T> static size_t BytesNeededForVarint(T value) { static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, @@ -554,7 +552,7 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { case JS_PRIMITIVE_WRAPPER_TYPE: return WriteJSPrimitiveWrapper( Handle<JSPrimitiveWrapper>::cast(receiver)); - case JS_REGEXP_TYPE: + case JS_REG_EXP_TYPE: WriteJSRegExp(JSRegExp::cast(*receiver)); return ThrowIfOutOfMemory(); case JS_MAP_TYPE: @@ -568,7 +566,7 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); case JS_ERROR_TYPE: return WriteJSError(Handle<JSObject>::cast(receiver)); - case WASM_MODULE_TYPE: { + case WASM_MODULE_OBJECT_TYPE: { auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_); if (!FLAG_wasm_disable_structured_cloning || enabled_features.threads) { // Only write WebAssembly modules if not disabled by a flag. @@ -576,7 +574,7 @@ Maybe<bool> ValueSerializer::WriteJSReceiver(Handle<JSReceiver> receiver) { } break; } - case WASM_MEMORY_TYPE: { + case WASM_MEMORY_OBJECT_TYPE: { auto enabled_features = wasm::WasmFeaturesFromIsolate(isolate_); if (enabled_features.threads) { return WriteWasmMemory(Handle<WasmMemoryObject>::cast(receiver)); @@ -604,7 +602,7 @@ Maybe<bool> ValueSerializer::WriteJSObject(Handle<JSObject> object) { // map doesn't change. uint32_t properties_written = 0; bool map_changed = false; - for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { + for (InternalIndex i : map->IterateOwnDescriptors()) { Handle<Name> key(map->instance_descriptors().GetKey(i), isolate_); if (!key->IsString()) continue; PropertyDetails details = map->instance_descriptors().GetDetails(i); @@ -1025,8 +1023,8 @@ Maybe<bool> ValueSerializer::WriteWasmMemory(Handle<WasmMemoryObject> object) { return Nothing<bool>(); } - isolate_->wasm_engine()->memory_tracker()->RegisterWasmMemoryAsShared( - object, isolate_); + GlobalBackingStoreRegistry::Register( + object->array_buffer().GetBackingStore()); WriteTag(SerializationTag::kWasmMemoryTransfer); WriteZigZag<int32_t>(object->maximum_pages()); @@ -1112,8 +1110,6 @@ ValueDeserializer::ValueDeserializer(Isolate* isolate, delegate_(delegate), position_(data.begin()), end_(data.begin() + data.length()), - allocation_(data.length() > kPretenureThreshold ? AllocationType::kOld - : AllocationType::kYoung), id_map_(isolate->global_handles()->Create( ReadOnlyRoots(isolate_).empty_fixed_array())) {} @@ -1302,19 +1298,17 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() { case SerializationTag::kInt32: { Maybe<int32_t> number = ReadZigZag<int32_t>(); if (number.IsNothing()) return MaybeHandle<Object>(); - return isolate_->factory()->NewNumberFromInt(number.FromJust(), - allocation_); + return isolate_->factory()->NewNumberFromInt(number.FromJust()); } case SerializationTag::kUint32: { Maybe<uint32_t> number = ReadVarint<uint32_t>(); if (number.IsNothing()) return MaybeHandle<Object>(); - return isolate_->factory()->NewNumberFromUint(number.FromJust(), - allocation_); + return isolate_->factory()->NewNumberFromUint(number.FromJust()); } case SerializationTag::kDouble: { Maybe<double> number = ReadDouble(); if (number.IsNothing()) return MaybeHandle<Object>(); - return isolate_->factory()->NewNumber(number.FromJust(), allocation_); + return isolate_->factory()->NewNumber(number.FromJust()); } case SerializationTag::kBigInt: return ReadBigInt(); @@ -1398,8 +1392,7 @@ MaybeHandle<BigInt> ValueDeserializer::ReadBigInt() { if (!ReadRawBytes(bytelength).To(&digits_storage)) { return MaybeHandle<BigInt>(); } - return BigInt::FromSerializedDigits(isolate_, bitfield, digits_storage, - allocation_); + return BigInt::FromSerializedDigits(isolate_, bitfield, digits_storage); } MaybeHandle<String> ValueDeserializer::ReadUtf8String() { @@ -1412,7 +1405,7 @@ MaybeHandle<String> ValueDeserializer::ReadUtf8String() { return MaybeHandle<String>(); } return isolate_->factory()->NewStringFromUtf8( - Vector<const char>::cast(utf8_bytes), allocation_); + Vector<const char>::cast(utf8_bytes)); } MaybeHandle<String> ValueDeserializer::ReadOneByteString() { @@ -1424,7 +1417,7 @@ MaybeHandle<String> ValueDeserializer::ReadOneByteString() { !ReadRawBytes(byte_length).To(&bytes)) { return MaybeHandle<String>(); } - return isolate_->factory()->NewStringFromOneByte(bytes, allocation_); + return isolate_->factory()->NewStringFromOneByte(bytes); } MaybeHandle<String> ValueDeserializer::ReadTwoByteString() { @@ -1443,7 +1436,7 @@ MaybeHandle<String> ValueDeserializer::ReadTwoByteString() { if (byte_length == 0) return isolate_->factory()->empty_string(); Handle<SeqTwoByteString> string; if (!isolate_->factory() - ->NewRawTwoByteString(byte_length / sizeof(uc16), allocation_) + ->NewRawTwoByteString(byte_length / sizeof(uc16)) .ToHandle(&string)) { return MaybeHandle<String>(); } @@ -1506,8 +1499,8 @@ MaybeHandle<JSObject> ValueDeserializer::ReadJSObject() { uint32_t id = next_id_++; HandleScope scope(isolate_); - Handle<JSObject> object = isolate_->factory()->NewJSObject( - isolate_->object_function(), allocation_); + Handle<JSObject> object = + isolate_->factory()->NewJSObject(isolate_->object_function()); AddObjectWithID(id, object); uint32_t num_properties; @@ -1532,8 +1525,8 @@ MaybeHandle<JSArray> ValueDeserializer::ReadSparseJSArray() { uint32_t id = next_id_++; HandleScope scope(isolate_); - Handle<JSArray> array = isolate_->factory()->NewJSArray( - 0, TERMINAL_FAST_ELEMENTS_KIND, allocation_); + Handle<JSArray> array = + isolate_->factory()->NewJSArray(0, TERMINAL_FAST_ELEMENTS_KIND); JSArray::SetLength(array, length); AddObjectWithID(id, array); @@ -1569,8 +1562,7 @@ MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() { uint32_t id = next_id_++; HandleScope scope(isolate_); Handle<JSArray> array = isolate_->factory()->NewJSArray( - HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, - allocation_); + HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); AddObjectWithID(id, array); Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_); @@ -1631,22 +1623,21 @@ MaybeHandle<JSPrimitiveWrapper> ValueDeserializer::ReadJSPrimitiveWrapper( Handle<JSPrimitiveWrapper> value; switch (tag) { case SerializationTag::kTrueObject: - value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject( - isolate_->boolean_function(), allocation_)); + value = Handle<JSPrimitiveWrapper>::cast( + isolate_->factory()->NewJSObject(isolate_->boolean_function())); value->set_value(ReadOnlyRoots(isolate_).true_value()); break; case SerializationTag::kFalseObject: - value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject( - isolate_->boolean_function(), allocation_)); + value = Handle<JSPrimitiveWrapper>::cast( + isolate_->factory()->NewJSObject(isolate_->boolean_function())); value->set_value(ReadOnlyRoots(isolate_).false_value()); break; case SerializationTag::kNumberObject: { double number; if (!ReadDouble().To(&number)) return MaybeHandle<JSPrimitiveWrapper>(); - value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject( - isolate_->number_function(), allocation_)); - Handle<Object> number_object = - isolate_->factory()->NewNumber(number, allocation_); + value = Handle<JSPrimitiveWrapper>::cast( + isolate_->factory()->NewJSObject(isolate_->number_function())); + Handle<Object> number_object = isolate_->factory()->NewNumber(number); value->set_value(*number_object); break; } @@ -1654,8 +1645,8 @@ MaybeHandle<JSPrimitiveWrapper> ValueDeserializer::ReadJSPrimitiveWrapper( Handle<BigInt> bigint; if (!ReadBigInt().ToHandle(&bigint)) return MaybeHandle<JSPrimitiveWrapper>(); - value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject( - isolate_->bigint_function(), allocation_)); + value = Handle<JSPrimitiveWrapper>::cast( + isolate_->factory()->NewJSObject(isolate_->bigint_function())); value->set_value(*bigint); break; } @@ -1663,8 +1654,8 @@ MaybeHandle<JSPrimitiveWrapper> ValueDeserializer::ReadJSPrimitiveWrapper( Handle<String> string; if (!ReadString().ToHandle(&string)) return MaybeHandle<JSPrimitiveWrapper>(); - value = Handle<JSPrimitiveWrapper>::cast(isolate_->factory()->NewJSObject( - isolate_->string_function(), allocation_)); + value = Handle<JSPrimitiveWrapper>::cast( + isolate_->factory()->NewJSObject(isolate_->string_function())); value->set_value(*string); break; } @@ -1801,13 +1792,12 @@ MaybeHandle<JSArrayBuffer> ValueDeserializer::ReadJSArrayBuffer( byte_length > static_cast<size_t>(end_ - position_)) { return MaybeHandle<JSArrayBuffer>(); } - const bool should_initialize = false; - Handle<JSArrayBuffer> array_buffer = isolate_->factory()->NewJSArrayBuffer( - SharedFlag::kNotShared, allocation_); - if (!JSArrayBuffer::SetupAllocatingData(array_buffer, isolate_, byte_length, - should_initialize)) { - return MaybeHandle<JSArrayBuffer>(); - } + MaybeHandle<JSArrayBuffer> result = + isolate_->factory()->NewJSArrayBufferAndBackingStore( + byte_length, InitializedFlag::kUninitialized); + Handle<JSArrayBuffer> array_buffer; + if (!result.ToHandle(&array_buffer)) return result; + if (byte_length > 0) { memcpy(array_buffer->backing_store(), position_, byte_length); } @@ -1871,8 +1861,7 @@ MaybeHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView( return MaybeHandle<JSArrayBufferView>(); } Handle<JSTypedArray> typed_array = isolate_->factory()->NewJSTypedArray( - external_array_type, buffer, byte_offset, byte_length / element_size, - allocation_); + external_array_type, buffer, byte_offset, byte_length / element_size); AddObjectWithID(id, typed_array); return typed_array; } @@ -2049,9 +2038,6 @@ MaybeHandle<WasmMemoryObject> ValueDeserializer::ReadWasmMemory() { Handle<WasmMemoryObject> result = WasmMemoryObject::New(isolate_, buffer, maximum_pages); - isolate_->wasm_engine()->memory_tracker()->RegisterWasmMemoryAsShared( - result, isolate_); - AddObjectWithID(id, result); return result; } @@ -2081,9 +2067,10 @@ static void CommitProperties(Handle<JSObject> object, Handle<Map> map, DisallowHeapAllocation no_gc; DescriptorArray descriptors = object->map().instance_descriptors(); - for (unsigned i = 0; i < properties.size(); i++) { + for (InternalIndex i : InternalIndex::Range(properties.size())) { // Initializing store. - object->WriteToField(i, descriptors.GetDetails(i), *properties[i]); + object->WriteToField(i, descriptors.GetDetails(i), + *properties[i.raw_value()]); } } @@ -2150,7 +2137,7 @@ Maybe<uint32_t> ValueDeserializer::ReadJSObjectProperties( // (though generalization may be required), store the property value so // that we can copy them all at once. Otherwise, stop transitioning. if (transitioning) { - int descriptor = static_cast<int>(properties.size()); + InternalIndex descriptor(properties.size()); PropertyDetails details = target->instance_descriptors().GetDetails(descriptor); Representation expected_representation = details.representation(); @@ -2316,8 +2303,8 @@ ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() { size_t begin_properties = stack.size() - 2 * static_cast<size_t>(num_properties); - Handle<JSObject> js_object = isolate_->factory()->NewJSObject( - isolate_->object_function(), allocation_); + Handle<JSObject> js_object = + isolate_->factory()->NewJSObject(isolate_->object_function()); if (num_properties && !SetPropertiesFromKeyValuePairs( isolate_, js_object, &stack[begin_properties], num_properties) @@ -2344,8 +2331,8 @@ ValueDeserializer::ReadObjectUsingEntireBufferForLegacyFormat() { return MaybeHandle<Object>(); } - Handle<JSArray> js_array = isolate_->factory()->NewJSArray( - 0, TERMINAL_FAST_ELEMENTS_KIND, allocation_); + Handle<JSArray> js_array = + isolate_->factory()->NewJSArray(0, TERMINAL_FAST_ELEMENTS_KIND); JSArray::SetLength(js_array, length); size_t begin_properties = stack.size() - 2 * static_cast<size_t>(num_properties); diff --git a/deps/v8/src/objects/value-serializer.h b/deps/v8/src/objects/value-serializer.h index cc9bc1caea84b1..839636ceef8841 100644 --- a/deps/v8/src/objects/value-serializer.h +++ b/deps/v8/src/objects/value-serializer.h @@ -298,7 +298,6 @@ class ValueDeserializer { v8::ValueDeserializer::Delegate* const delegate_; const uint8_t* position_; const uint8_t* const end_; - AllocationType allocation_; uint32_t version_ = 0; uint32_t next_id_ = 0; bool expect_inline_wasm_ = false; diff --git a/deps/v8/src/parsing/expression-scope-reparenter.cc b/deps/v8/src/parsing/expression-scope-reparenter.cc index 3f62616ebd33e2..2f4914398fd814 100644 --- a/deps/v8/src/parsing/expression-scope-reparenter.cc +++ b/deps/v8/src/parsing/expression-scope-reparenter.cc @@ -54,7 +54,14 @@ void Reparenter::VisitClassLiteral(ClassLiteral* class_literal) { #if DEBUG // The same goes for the rest of the class, but we do some // sanity checking in debug mode. - for (ClassLiteralProperty* prop : *class_literal->properties()) { + for (ClassLiteralProperty* prop : *class_literal->private_members()) { + // No need to visit the values, since all values are functions with + // the class scope on their scope chain. + DCHECK(prop->value()->IsFunctionLiteral()); + DCHECK_EQ(prop->value()->AsFunctionLiteral()->scope()->outer_scope(), + class_literal->scope()); + } + for (ClassLiteralProperty* prop : *class_literal->public_members()) { // No need to visit the values, since all values are functions with // the class scope on their scope chain. DCHECK(prop->value()->IsFunctionLiteral()); diff --git a/deps/v8/src/parsing/expression-scope.h b/deps/v8/src/parsing/expression-scope.h index ba931d36dab2e2..709231ebb0f8db 100644 --- a/deps/v8/src/parsing/expression-scope.h +++ b/deps/v8/src/parsing/expression-scope.h @@ -625,14 +625,8 @@ class AccumulationScope { if (!scope->CanBeExpression()) return; scope_ = scope->AsExpressionParsingScope(); for (int i = 0; i < kNumberOfErrors; i++) { - // If the underlying scope is already invalid at the start, stop - // accumulating. That means an error was found outside of an - // accumulating path. - if (!scope_->is_valid(i)) { - scope_ = nullptr; - break; - } copy(i); + scope_->clear(i); } } diff --git a/deps/v8/src/parsing/parse-info.cc b/deps/v8/src/parsing/parse-info.cc index e927c1a0d1aa69..b0a455e88d8f24 100644 --- a/deps/v8/src/parsing/parse-info.cc +++ b/deps/v8/src/parsing/parse-info.cc @@ -7,7 +7,6 @@ #include "src/ast/ast-source-ranges.h" #include "src/ast/ast-value-factory.h" #include "src/ast/ast.h" -#include "src/base/template-utils.h" #include "src/compiler-dispatcher/compiler-dispatcher.h" #include "src/heap/heap-inl.h" #include "src/logging/counters.h" @@ -21,7 +20,7 @@ namespace v8 { namespace internal { ParseInfo::ParseInfo(AccountingAllocator* zone_allocator) - : zone_(base::make_unique<Zone>(zone_allocator, ZONE_NAME)), + : zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)), flags_(0), extension_(nullptr), script_scope_(nullptr), @@ -66,6 +65,7 @@ ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator) set_allow_harmony_optional_chaining(FLAG_harmony_optional_chaining); set_allow_harmony_nullish(FLAG_harmony_nullish); set_allow_harmony_private_methods(FLAG_harmony_private_methods); + set_allow_harmony_top_level_await(FLAG_harmony_top_level_await); } ParseInfo::ParseInfo(Isolate* isolate) @@ -129,7 +129,7 @@ std::unique_ptr<ParseInfo> ParseInfo::FromParent( const ParseInfo* outer_parse_info, AccountingAllocator* zone_allocator, const FunctionLiteral* literal, const AstRawString* function_name) { std::unique_ptr<ParseInfo> result = - base::make_unique<ParseInfo>(zone_allocator); + std::make_unique<ParseInfo>(zone_allocator); // Replicate shared state of the outer_parse_info. result->flags_ = outer_parse_info->flags_; diff --git a/deps/v8/src/parsing/parse-info.h b/deps/v8/src/parsing/parse-info.h index 8afb12415513bb..dde331b88a4e3d 100644 --- a/deps/v8/src/parsing/parse-info.h +++ b/deps/v8/src/parsing/parse-info.h @@ -110,6 +110,8 @@ class V8_EXPORT_PRIVATE ParseInfo { set_collect_source_positions) FLAG_ACCESSOR(kAllowHarmonyNullish, allow_harmony_nullish, set_allow_harmony_nullish) + FLAG_ACCESSOR(kAllowHarmonyTopLevelAwait, allow_harmony_top_level_await, + set_allow_harmony_top_level_await) #undef FLAG_ACCESSOR @@ -319,6 +321,7 @@ class V8_EXPORT_PRIVATE ParseInfo { kIsOneshotIIFE = 1 << 27, kCollectSourcePositions = 1 << 28, kAllowHarmonyNullish = 1 << 29, + kAllowHarmonyTopLevelAwait = 1 << 30, }; //------------- Inputs to parsing and scope analysis ----------------------- diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index 1b3bd64cddf25a..847774910a94a1 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -267,6 +267,7 @@ class ParserBase { allow_harmony_dynamic_import_(false), allow_harmony_import_meta_(false), allow_harmony_private_methods_(false), + allow_harmony_top_level_await_(false), allow_eval_cache_(true) { pointer_buffer_.reserve(32); variable_buffer_.reserve(32); @@ -280,6 +281,7 @@ class ParserBase { ALLOW_ACCESSORS(harmony_dynamic_import) ALLOW_ACCESSORS(harmony_import_meta) ALLOW_ACCESSORS(harmony_private_methods) + ALLOW_ACCESSORS(harmony_top_level_await) ALLOW_ACCESSORS(eval_cache) #undef ALLOW_ACCESSORS @@ -527,9 +529,9 @@ class ParserBase { struct ClassInfo { public: explicit ClassInfo(ParserBase* parser) - : variable(nullptr), - extends(parser->impl()->NullExpression()), - properties(parser->impl()->NewClassPropertyList(4)), + : extends(parser->impl()->NullExpression()), + public_members(parser->impl()->NewClassPropertyList(4)), + private_members(parser->impl()->NewClassPropertyList(4)), static_fields(parser->impl()->NewClassPropertyList(4)), instance_fields(parser->impl()->NewClassPropertyList(4)), constructor(parser->impl()->NullExpression()), @@ -540,12 +542,13 @@ class ParserBase { has_instance_members(false), requires_brand(false), is_anonymous(false), + has_private_methods(false), static_fields_scope(nullptr), instance_members_scope(nullptr), computed_field_count(0) {} - Variable* variable; ExpressionT extends; - ClassPropertyListT properties; + ClassPropertyListT public_members; + ClassPropertyListT private_members; ClassPropertyListT static_fields; ClassPropertyListT instance_fields; FunctionLiteralT constructor; @@ -557,6 +560,7 @@ class ParserBase { bool has_instance_members; bool requires_brand; bool is_anonymous; + bool has_private_methods; DeclarationScope* static_fields_scope; DeclarationScope* instance_members_scope; int computed_field_count; @@ -670,8 +674,8 @@ class ParserBase { return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE); } - ClassScope* NewClassScope(Scope* parent) const { - return new (zone()) ClassScope(zone(), parent); + ClassScope* NewClassScope(Scope* parent, bool is_anonymous) const { + return new (zone()) ClassScope(zone(), parent, is_anonymous); } Scope* NewScope(ScopeType scope_type) const { @@ -942,7 +946,10 @@ class ParserBase { bool is_resumable() const { return IsResumableFunction(function_state_->kind()); } - + bool is_await_allowed() const { + return is_async_function() || (allow_harmony_top_level_await() && + IsModule(function_state_->kind())); + } const PendingCompilationErrorHandler* pending_error_handler() const { return pending_error_handler_; } @@ -1456,6 +1463,7 @@ class ParserBase { bool allow_harmony_dynamic_import_; bool allow_harmony_import_meta_; bool allow_harmony_private_methods_; + bool allow_harmony_top_level_await_; bool allow_eval_cache_; }; @@ -1582,16 +1590,17 @@ ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() { // // Here, we check if this is a new private name reference in a top // level function and throw an error if so. - ClassScope* class_scope = scope()->GetClassScope(); + PrivateNameScopeIterator private_name_scope_iter(scope()); // Parse the identifier so that we can display it in the error message name = impl()->GetIdentifier(); - if (class_scope == nullptr) { + if (private_name_scope_iter.Done()) { impl()->ReportMessageAt(Scanner::Location(pos, pos + 1), MessageTemplate::kInvalidPrivateFieldResolution, impl()->GetRawNameFromIdentifier(name)); return impl()->FailureExpression(); } - key = impl()->ExpressionFromPrivateName(class_scope, name, pos); + key = + impl()->ExpressionFromPrivateName(&private_name_scope_iter, name, pos); } else { ReportUnexpectedToken(next); return impl()->FailureExpression(); @@ -3062,7 +3071,7 @@ ParserBase<Impl>::ParseUnaryExpression() { Token::Value op = peek(); if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression(); - if (is_async_function() && op == Token::AWAIT) { + if (is_await_allowed() && op == Token::AWAIT) { return ParseAwaitExpression(); } return ParsePostfixExpression(); @@ -3577,7 +3586,19 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) { auto declaration_end = scope()->declarations()->end(); int initializer_end = end_position(); for (; declaration_it != declaration_end; ++declaration_it) { - declaration_it->var()->set_initializer_position(initializer_end); + Variable* var = declaration_it->var(); + + // The first time a variable is initialized (i.e. when the initializer + // position is unset), clear its maybe_assigned flag as it is not a true + // assignment. Since this is done directly on the Variable objects, it has + // no effect on VariableProxy objects appearing on the left-hand side of + // true assignments, so x will be still be marked as maybe_assigned for: + // (x = 1, y = (x = 2)) => {} + // and even: + // (x = (x = 2)) => {}. + if (var->initializer_position() == kNoSourcePosition) + var->clear_maybe_assigned(); + var->set_initializer_position(initializer_end); } impl()->AddFormalParameter(parameters, pattern, initializer, end_position(), @@ -4355,16 +4376,16 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( } } - ClassScope* class_scope = NewClassScope(scope()); + ClassScope* class_scope = NewClassScope(scope(), is_anonymous); BlockState block_state(&scope_, class_scope); RaiseLanguageMode(LanguageMode::kStrict); ClassInfo class_info(this); class_info.is_anonymous = is_anonymous; - impl()->DeclareClassVariable(name, &class_info, class_token_pos); scope()->set_start_position(end_position()); if (Check(Token::EXTENDS)) { + ClassScope::HeritageParsingScope heritage(class_scope); FuncNameInferrerState fni_state(&fni_); ExpressionParsingScope scope(impl()); class_info.extends = ParseLeftHandSideExpression(); @@ -4399,7 +4420,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( if (V8_UNLIKELY(prop_info.is_private)) { DCHECK(!is_constructor); - class_info.requires_brand |= !is_field; + class_info.requires_brand |= (!is_field && !prop_info.is_static); + class_info.has_private_methods |= + property_kind == ClassLiteralProperty::METHOD; impl()->DeclarePrivateClassMember(class_scope, prop_info.name, property, property_kind, prop_info.is_static, &class_info); @@ -4438,7 +4461,20 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral( } if (class_info.requires_brand) { - class_scope->DeclareBrandVariable(ast_value_factory(), kNoSourcePosition); + // TODO(joyee): implement static brand checking + class_scope->DeclareBrandVariable( + ast_value_factory(), IsStaticFlag::kNotStatic, kNoSourcePosition); + } + + bool should_save_class_variable_index = + class_scope->should_save_class_variable_index(); + if (!is_anonymous || should_save_class_variable_index) { + impl()->DeclareClassVariable(class_scope, name, &class_info, + class_token_pos); + if (should_save_class_variable_index) { + class_scope->class_variable()->set_is_used(); + class_scope->class_variable()->ForceContextAllocation(); + } } return impl()->RewriteClassLiteral(class_scope, name, &class_info, @@ -4861,7 +4897,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement( case Token::WHILE: return ParseWhileStatement(labels, own_labels); case Token::FOR: - if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) { + if (V8_UNLIKELY(is_await_allowed() && PeekAhead() == Token::AWAIT)) { return ParseForAwaitStatement(labels, own_labels); } return ParseForStatement(labels, own_labels); @@ -5921,7 +5957,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement( ZonePtrList<const AstRawString>* labels, ZonePtrList<const AstRawString>* own_labels) { // for await '(' ForDeclaration of AssignmentExpression ')' - DCHECK(is_async_function()); + DCHECK(is_await_allowed()); typename FunctionState::LoopScope loop_scope(function_state_); int stmt_pos = peek_position(); diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 3a61253db5a193..edb9604bb5cfd1 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -427,6 +427,7 @@ Parser::Parser(ParseInfo* info) set_allow_harmony_nullish(info->allow_harmony_nullish()); set_allow_harmony_optional_chaining(info->allow_harmony_optional_chaining()); set_allow_harmony_private_methods(info->allow_harmony_private_methods()); + set_allow_harmony_top_level_await(info->allow_harmony_top_level_await()); for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; ++feature) { use_counts_[feature] = 0; @@ -576,8 +577,32 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) { BuildInitialYield(kNoSourcePosition, kGeneratorFunction); body.Add( factory()->NewExpressionStatement(initial_yield, kNoSourcePosition)); - - ParseModuleItemList(&body); + if (allow_harmony_top_level_await()) { + // First parse statements into a buffer. Then, if there was a + // top level await, create an inner block and rewrite the body of the + // module as an async function. Otherwise merge the statements back + // into the main body. + BlockT block = impl()->NullBlock(); + { + StatementListT statements(pointer_buffer()); + ParseModuleItemList(&statements); + // Modules will always have an initial yield. If there are any + // additional suspends, i.e. awaits, then we treat the module as an + // AsyncModule. + if (function_state.suspend_count() > 1) { + scope->set_is_async_module(); + block = factory()->NewBlock(true, statements); + } else { + statements.MergeInto(&body); + } + } + if (IsAsyncModule(scope->function_kind())) { + impl()->RewriteAsyncFunctionBody( + &body, block, factory()->NewUndefinedLiteral(kNoSourcePosition)); + } + } else { + ParseModuleItemList(&body); + } if (!has_error() && !module()->Validate(this->scope()->AsModuleScope(), pending_error_handler(), zone())) { @@ -705,8 +730,17 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, info->set_function_name(ast_value_factory()->GetString(name)); scanner_.Initialize(); - FunctionLiteral* result = - DoParseFunction(isolate, info, info->function_name()); + FunctionLiteral* result; + if (V8_UNLIKELY(shared_info->private_name_lookup_skips_outer_class() && + original_scope_->is_class_scope())) { + // If the function skips the outer class and the outer scope is a class, the + // function is in heritage position. Otherwise the function scope's skip bit + // will be correctly inherited from the outer scope. + ClassScope::HeritageParsingScope heritage(original_scope_->AsClassScope()); + result = DoParseFunction(isolate, info, info->function_name()); + } else { + result = DoParseFunction(isolate, info, info->function_name()); + } MaybeResetCharacterStream(info, result); MaybeProcessSourceRanges(info, result, stack_limit_); if (result != nullptr) { @@ -2484,10 +2518,10 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind, bookmark.Set(function_scope->start_position()); UnresolvedList::Iterator unresolved_private_tail; - ClassScope* closest_class_scope = function_scope->GetClassScope(); - if (closest_class_scope != nullptr) { + PrivateNameScopeIterator private_name_scope_iter(function_scope); + if (!private_name_scope_iter.Done()) { unresolved_private_tail = - closest_class_scope->GetUnresolvedPrivateNameTail(); + private_name_scope_iter.GetScope()->GetUnresolvedPrivateNameTail(); } // With no cached data, we partially parse the function, without building an @@ -2511,8 +2545,8 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind, // the state before preparsing. The caller may then fully parse the function // to identify the actual error. bookmark.Apply(); - if (closest_class_scope != nullptr) { - closest_class_scope->ResetUnresolvedPrivateNameTail( + if (!private_name_scope_iter.Done()) { + private_name_scope_iter.GetScope()->ResetUnresolvedPrivateNameTail( unresolved_private_tail); } function_scope->ResetAfterPreparsing(ast_value_factory_, true); @@ -2533,8 +2567,8 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind, *num_parameters = logger->num_parameters(); *function_length = logger->function_length(); SkipFunctionLiterals(logger->num_inner_functions()); - if (closest_class_scope != nullptr) { - closest_class_scope->MigrateUnresolvedPrivateNameTail( + if (!private_name_scope_iter.Done()) { + private_name_scope_iter.GetScope()->MigrateUnresolvedPrivateNameTail( factory(), unresolved_private_tail); } function_scope->AnalyzePartially(this, factory(), MaybeParsingArrowhead()); @@ -2739,17 +2773,20 @@ void Parser::ParseFunction( *suspend_count = function_state.suspend_count(); } -void Parser::DeclareClassVariable(const AstRawString* name, +void Parser::DeclareClassVariable(ClassScope* scope, const AstRawString* name, ClassInfo* class_info, int class_token_pos) { #ifdef DEBUG - scope()->SetScopeName(name); + scope->SetScopeName(name); #endif - if (name != nullptr) { - VariableProxy* proxy = - DeclareBoundVariable(name, VariableMode::kConst, class_token_pos); - class_info->variable = proxy->var(); - } + DCHECK_IMPLIES(name == nullptr, class_info->is_anonymous); + // Declare a special class variable for anonymous classes with the dot + // if we need to save it for static private method access. + Variable* class_variable = + scope->DeclareClassVariable(ast_value_factory(), name, class_token_pos); + Declaration* declaration = factory()->NewVariableDeclaration(class_token_pos); + scope->declarations()->Add(declaration); + declaration->set_var(class_variable); } // TODO(gsathya): Ideally, this should just bypass scope analysis and @@ -2764,13 +2801,15 @@ Variable* Parser::CreateSyntheticContextVariable(const AstRawString* name) { Variable* Parser::CreatePrivateNameVariable(ClassScope* scope, VariableMode mode, + IsStaticFlag is_static_flag, const AstRawString* name) { DCHECK_NOT_NULL(name); int begin = position(); int end = end_position(); bool was_added = false; DCHECK(IsConstVariableMode(mode)); - Variable* var = scope->DeclarePrivateName(name, mode, &was_added); + Variable* var = + scope->DeclarePrivateName(name, mode, is_static_flag, &was_added); if (!was_added) { Scanner::Location loc(begin, end); ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, var->raw_name()); @@ -2796,7 +2835,7 @@ void Parser::DeclarePublicClassField(ClassScope* scope, CreateSyntheticContextVariable(ClassFieldVariableName( ast_value_factory(), class_info->computed_field_count)); property->set_computed_name_var(computed_name_var); - class_info->properties->Add(property, zone()); + class_info->public_members->Add(property, zone()); } } @@ -2816,15 +2855,17 @@ void Parser::DeclarePrivateClassMember(ClassScope* scope, } } - Variable* private_name_var = - CreatePrivateNameVariable(scope, GetVariableMode(kind), property_name); + Variable* private_name_var = CreatePrivateNameVariable( + scope, GetVariableMode(kind), + is_static ? IsStaticFlag::kStatic : IsStaticFlag::kNotStatic, + property_name); int pos = property->value()->position(); if (pos == kNoSourcePosition) { pos = property->key()->position(); } private_name_var->set_initializer_position(pos); property->set_private_name_var(private_name_var); - class_info->properties->Add(property, zone()); + class_info->private_members->Add(property, zone()); } // This method declares a property of the given class. It updates the @@ -2845,7 +2886,7 @@ void Parser::DeclarePublicClassMethod(const AstRawString* class_name, return; } - class_info->properties->Add(property, zone()); + class_info->public_members->Add(property, zone()); } FunctionLiteral* Parser::CreateInitializerFunction( @@ -2894,8 +2935,8 @@ Expression* Parser::RewriteClassLiteral(ClassScope* block_scope, } if (name != nullptr) { - DCHECK_NOT_NULL(class_info->variable); - class_info->variable->set_initializer_position(end_pos); + DCHECK_NOT_NULL(block_scope->class_variable()); + block_scope->class_variable()->set_initializer_position(end_pos); } FunctionLiteral* static_fields_initializer = nullptr; @@ -2916,11 +2957,12 @@ Expression* Parser::RewriteClassLiteral(ClassScope* block_scope, } ClassLiteral* class_literal = factory()->NewClassLiteral( - block_scope, class_info->variable, class_info->extends, - class_info->constructor, class_info->properties, + block_scope, class_info->extends, class_info->constructor, + class_info->public_members, class_info->private_members, static_fields_initializer, instance_members_initializer_function, pos, end_pos, class_info->has_name_static_property, - class_info->has_static_computed_names, class_info->is_anonymous); + class_info->has_static_computed_names, class_info->is_anonymous, + class_info->has_private_methods); AddFunctionForNameInference(class_info->constructor); return class_literal; @@ -3241,7 +3283,7 @@ void Parser::RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body, // }) // } - block->statements()->Add(factory()->NewAsyncReturnStatement( + block->statements()->Add(factory()->NewSyntheticAsyncReturnStatement( return_value, return_value->position()), zone()); block = BuildRejectPromiseOnException(block); diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h index 2bd555e88141b3..6f570b8751bb90 100644 --- a/deps/v8/src/parsing/parser.h +++ b/deps/v8/src/parsing/parser.h @@ -173,8 +173,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { parsing::ReportErrorsAndStatisticsMode stats_mode); bool AllowsLazyParsingWithoutUnresolvedVariables() const { - return scope()->AllowsLazyParsingWithoutUnresolvedVariables( - original_scope_); + return !MaybeParsingArrowhead() && + scope()->AllowsLazyParsingWithoutUnresolvedVariables( + original_scope_); } bool parse_lazily() const { return mode_ == PARSE_LAZILY; } @@ -301,6 +302,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ZonePtrList<const AstRawString>* names); Variable* CreateSyntheticContextVariable(const AstRawString* synthetic_name); Variable* CreatePrivateNameVariable(ClassScope* scope, VariableMode mode, + IsStaticFlag is_static_flag, const AstRawString* name); FunctionLiteral* CreateInitializerFunction( const char* name, DeclarationScope* scope, @@ -314,8 +316,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { Statement* DeclareClass(const AstRawString* variable_name, Expression* value, ZonePtrList<const AstRawString>* names, int class_token_pos, int end_pos); - void DeclareClassVariable(const AstRawString* name, ClassInfo* class_info, - int class_token_pos); + void DeclareClassVariable(ClassScope* scope, const AstRawString* name, + ClassInfo* class_info, int class_token_pos); void DeclareClassBrandVariable(ClassScope* scope, ClassInfo* class_info, int class_token_pos); void DeclarePrivateClassMember(ClassScope* scope, @@ -779,12 +781,12 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { Expression* ExpressionFromLiteral(Token::Value token, int pos); - V8_INLINE VariableProxy* ExpressionFromPrivateName(ClassScope* class_scope, - const AstRawString* name, - int start_position) { + V8_INLINE VariableProxy* ExpressionFromPrivateName( + PrivateNameScopeIterator* private_name_scope, const AstRawString* name, + int start_position) { VariableProxy* proxy = factory()->ast_node_factory()->NewVariableProxy( name, NORMAL_VARIABLE, start_position); - class_scope->AddUnresolvedPrivateName(proxy); + private_name_scope->AddUnresolvedPrivateName(proxy); return proxy; } diff --git a/deps/v8/src/parsing/preparse-data-impl.h b/deps/v8/src/parsing/preparse-data-impl.h index 0bc8027266c160..a993fdf93fd44d 100644 --- a/deps/v8/src/parsing/preparse-data-impl.h +++ b/deps/v8/src/parsing/preparse-data-impl.h @@ -7,6 +7,8 @@ #include "src/parsing/preparse-data.h" +#include <memory> + #include "src/common/assert-scope.h" namespace v8 { @@ -155,16 +157,18 @@ class BaseConsumedPreparseData : public ConsumedPreparseData { int* function_length, int* num_inner_functions, bool* uses_super_property, LanguageMode* language_mode) final; - void RestoreScopeAllocationData(DeclarationScope* scope) final; + void RestoreScopeAllocationData(DeclarationScope* scope, + AstValueFactory* ast_value_factory) final; #ifdef DEBUG bool VerifyDataStart(); #endif private: - void RestoreDataForScope(Scope* scope); + void RestoreDataForScope(Scope* scope, AstValueFactory* ast_value_factory); void RestoreDataForVariable(Variable* var); - void RestoreDataForInnerScopes(Scope* scope); + void RestoreDataForInnerScopes(Scope* scope, + AstValueFactory* ast_value_factory); std::unique_ptr<ByteData> scope_data_; // When consuming the data, these indexes point to the data we're going to diff --git a/deps/v8/src/parsing/preparse-data.cc b/deps/v8/src/parsing/preparse-data.cc index 8743732ea2cedd..460ae65a306c0b 100644 --- a/deps/v8/src/parsing/preparse-data.cc +++ b/deps/v8/src/parsing/preparse-data.cc @@ -24,6 +24,10 @@ namespace { using ScopeSloppyEvalCanExtendVarsField = BitField8<bool, 0, 1>; using InnerScopeCallsEvalField = ScopeSloppyEvalCanExtendVarsField::Next<bool, 1>; +using NeedsPrivateNameContextChainRecalcField = + InnerScopeCallsEvalField::Next<bool, 1>; +using ShouldSaveClassVariableIndexField = + NeedsPrivateNameContextChainRecalcField::Next<bool, 1>; using VariableMaybeAssignedField = BitField8<bool, 0, 1>; using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>; @@ -322,7 +326,7 @@ void PreparseDataBuilder::SaveScopeAllocationData(DeclarationScope* scope, if (SaveDataForSkippableFunction(builder)) num_inner_with_data_++; } - // Don't save imcoplete scope information when bailed out. + // Don't save incomplete scope information when bailed out. if (!bailed_out_) { #ifdef DEBUG // function data items, kSkippableMinFunctionDataSize each. @@ -352,13 +356,20 @@ void PreparseDataBuilder::SaveDataForScope(Scope* scope) { byte_data_.WriteUint8(scope->scope_type()); #endif - uint8_t eval = + uint8_t eval_and_private_recalc = ScopeSloppyEvalCanExtendVarsField::encode( scope->is_declaration_scope() && scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()) | - InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval()); + InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval()) | + NeedsPrivateNameContextChainRecalcField::encode( + scope->is_function_scope() && + scope->AsDeclarationScope() + ->needs_private_name_context_chain_recalc()) | + ShouldSaveClassVariableIndexField::encode( + scope->is_class_scope() && + scope->AsClassScope()->should_save_class_variable_index()); byte_data_.Reserve(kUint8Size); - byte_data_.WriteUint8(eval); + byte_data_.WriteUint8(eval_and_private_recalc); if (scope->is_function_scope()) { Variable* function = scope->AsDeclarationScope()->function_var(); @@ -562,7 +573,7 @@ BaseConsumedPreparseData<Data>::GetDataForSkippableFunction( template <class Data> void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData( - DeclarationScope* scope) { + DeclarationScope* scope, AstValueFactory* ast_value_factory) { DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE); typename ByteData::ReadingScope reading_scope(this); @@ -577,14 +588,15 @@ void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData( DCHECK_EQ(end_position_from_data, scope->end_position()); #endif - RestoreDataForScope(scope); + RestoreDataForScope(scope, ast_value_factory); // Check that we consumed all scope data. DCHECK_EQ(scope_data_->RemainingBytes(), 0); } template <typename Data> -void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) { +void BaseConsumedPreparseData<Data>::RestoreDataForScope( + Scope* scope, AstValueFactory* ast_value_factory) { if (scope->is_declaration_scope() && scope->AsDeclarationScope()->is_skipped_function()) { return; @@ -599,20 +611,48 @@ void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) { DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type()); CHECK(scope_data_->HasRemainingBytes(ByteData::kUint8Size)); - uint32_t eval = scope_data_->ReadUint8(); - if (ScopeSloppyEvalCanExtendVarsField::decode(eval)) scope->RecordEvalCall(); - if (InnerScopeCallsEvalField::decode(eval)) scope->RecordInnerScopeEvalCall(); + uint32_t scope_data_flags = scope_data_->ReadUint8(); + if (ScopeSloppyEvalCanExtendVarsField::decode(scope_data_flags)) { + scope->RecordEvalCall(); + } + if (InnerScopeCallsEvalField::decode(scope_data_flags)) { + scope->RecordInnerScopeEvalCall(); + } + if (NeedsPrivateNameContextChainRecalcField::decode(scope_data_flags)) { + scope->AsDeclarationScope()->RecordNeedsPrivateNameContextChainRecalc(); + } + if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) { + Variable* var; + // An anonymous class whose class variable needs to be saved do not + // have the class variable created during reparse since we skip parsing + // the inner scopes that contain potential access to static private + // methods. So create it now. + if (scope->AsClassScope()->is_anonymous_class()) { + var = scope->AsClassScope()->DeclareClassVariable( + ast_value_factory, nullptr, kNoSourcePosition); + AstNodeFactory factory(ast_value_factory, ast_value_factory->zone()); + Declaration* declaration = + factory.NewVariableDeclaration(kNoSourcePosition); + scope->declarations()->Add(declaration); + declaration->set_var(var); + } else { + var = scope->AsClassScope()->class_variable(); + DCHECK_NOT_NULL(var); + } + var->set_is_used(); + var->ForceContextAllocation(); + scope->AsClassScope()->set_should_save_class_variable_index(); + } if (scope->is_function_scope()) { Variable* function = scope->AsDeclarationScope()->function_var(); if (function != nullptr) RestoreDataForVariable(function); } - for (Variable* var : *scope->locals()) { if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var); } - RestoreDataForInnerScopes(scope); + RestoreDataForInnerScopes(scope, ast_value_factory); } template <typename Data> @@ -651,10 +691,11 @@ void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) { } template <typename Data> -void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(Scope* scope) { +void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes( + Scope* scope, AstValueFactory* ast_value_factory) { for (Scope* inner = scope->inner_scope(); inner != nullptr; inner = inner->sibling()) { - RestoreDataForScope(inner); + RestoreDataForScope(inner, ast_value_factory); } } @@ -731,13 +772,13 @@ ProducedPreparseData* ZoneConsumedPreparseData::GetChildData(Zone* zone, std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For( Isolate* isolate, Handle<PreparseData> data) { DCHECK(!data.is_null()); - return base::make_unique<OnHeapConsumedPreparseData>(isolate, data); + return std::make_unique<OnHeapConsumedPreparseData>(isolate, data); } std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For( Zone* zone, ZonePreparseData* data) { if (data == nullptr) return {}; - return base::make_unique<ZoneConsumedPreparseData>(zone, data); + return std::make_unique<ZoneConsumedPreparseData>(zone, data); } } // namespace internal diff --git a/deps/v8/src/parsing/preparse-data.h b/deps/v8/src/parsing/preparse-data.h index 613f13bc82e9bd..581adfa1d5b349 100644 --- a/deps/v8/src/parsing/preparse-data.h +++ b/deps/v8/src/parsing/preparse-data.h @@ -5,6 +5,8 @@ #ifndef V8_PARSING_PREPARSE_DATA_H_ #define V8_PARSING_PREPARSE_DATA_H_ +#include <memory> + #include "src/common/globals.h" #include "src/handles/handles.h" #include "src/handles/maybe-handles.h" @@ -22,6 +24,7 @@ class Parser; class PreParser; class PreparseData; class ZonePreparseData; +class AstValueFactory; /* @@ -286,7 +289,8 @@ class ConsumedPreparseData { // Restores the information needed for allocating the Scope's (and its // subscopes') variables. - virtual void RestoreScopeAllocationData(DeclarationScope* scope) = 0; + virtual void RestoreScopeAllocationData( + DeclarationScope* scope, AstValueFactory* ast_value_factory) = 0; protected: ConsumedPreparseData() = default; diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h index b4d66d726fdd44..adc3d09cac153c 100644 --- a/deps/v8/src/parsing/preparser.h +++ b/deps/v8/src/parsing/preparser.h @@ -1108,9 +1108,10 @@ class PreParser : public ParserBase<PreParser> { Variable* DeclarePrivateVariableName(const AstRawString* name, ClassScope* scope, VariableMode mode, + IsStaticFlag is_static_flag, bool* was_added) { DCHECK(IsConstVariableMode(mode)); - return scope->DeclarePrivateName(name, mode, was_added); + return scope->DeclarePrivateName(name, mode, is_static_flag, was_added); } Variable* DeclareVariableName(const AstRawString* name, VariableMode mode, @@ -1226,14 +1227,15 @@ class PreParser : public ParserBase<PreParser> { &was_added); return PreParserStatement::Default(); } - V8_INLINE void DeclareClassVariable(const PreParserIdentifier& name, + V8_INLINE void DeclareClassVariable(ClassScope* scope, + const PreParserIdentifier& name, ClassInfo* class_info, int class_token_pos) { - if (!IsNull(name)) { - bool was_added; - DeclareVariableName(name.string_, VariableMode::kConst, scope(), - &was_added); - } + DCHECK_IMPLIES(IsNull(name), class_info->is_anonymous); + // Declare a special class variable for anonymous classes with the dot + // if we need to save it for static private method access. + scope->DeclareClassVariable(ast_value_factory(), name.string_, + class_token_pos); } V8_INLINE void DeclarePublicClassMethod(const PreParserIdentifier& class_name, const PreParserExpression& property, @@ -1258,8 +1260,10 @@ class PreParser : public ParserBase<PreParser> { bool is_static, ClassInfo* class_info) { bool was_added; - DeclarePrivateVariableName(property_name.string_, scope, - GetVariableMode(kind), &was_added); + DeclarePrivateVariableName( + property_name.string_, scope, GetVariableMode(kind), + is_static ? IsStaticFlag::kStatic : IsStaticFlag::kNotStatic, + &was_added); if (!was_added) { Scanner::Location loc(property.position(), property.position() + 1); ReportMessageAt(loc, MessageTemplate::kVarRedeclaration, @@ -1591,12 +1595,12 @@ class PreParser : public ParserBase<PreParser> { return PreParserExpression::StringLiteral(); } - PreParserExpression ExpressionFromPrivateName(ClassScope* class_scope, - const PreParserIdentifier& name, - int start_position) { + PreParserExpression ExpressionFromPrivateName( + PrivateNameScopeIterator* private_name_scope, + const PreParserIdentifier& name, int start_position) { VariableProxy* proxy = factory()->ast_node_factory()->NewVariableProxy( name.string_, NORMAL_VARIABLE, start_position); - class_scope->AddUnresolvedPrivateName(proxy); + private_name_scope->AddUnresolvedPrivateName(proxy); return PreParserExpression::FromIdentifier(name); } @@ -1636,11 +1640,11 @@ class PreParser : public ParserBase<PreParser> { return PreParserStatement::Jump(); } - V8_INLINE void AddFormalParameter( - PreParserFormalParameters* parameters, - PreParserExpression& pattern, // NOLINT(runtime/references) - const PreParserExpression& initializer, int initializer_end_position, - bool is_rest) { + V8_INLINE void AddFormalParameter(PreParserFormalParameters* parameters, + const PreParserExpression& pattern, + const PreParserExpression& initializer, + int initializer_end_position, + bool is_rest) { DeclarationScope* scope = parameters->scope; scope->RecordParameter(is_rest); parameters->UpdateArityAndFunctionLength(!initializer.IsNull(), is_rest); diff --git a/deps/v8/src/parsing/scanner-character-streams.cc b/deps/v8/src/parsing/scanner-character-streams.cc index 0cd295fd2924a8..49c7e1f7933086 100644 --- a/deps/v8/src/parsing/scanner-character-streams.cc +++ b/deps/v8/src/parsing/scanner-character-streams.cc @@ -265,7 +265,7 @@ class BufferedCharacterStream : public Utf16CharacterStream { } size_t length = Min(kBufferSize, range.length()); - i::CopyCharsUnsigned(buffer_, range.start, length); + i::CopyChars(buffer_, range.start, length); buffer_end_ = &buffer_[length]; return true; } diff --git a/deps/v8/src/parsing/scanner-character-streams.h b/deps/v8/src/parsing/scanner-character-streams.h index 4b855674803bdf..c4c7064013f153 100644 --- a/deps/v8/src/parsing/scanner-character-streams.h +++ b/deps/v8/src/parsing/scanner-character-streams.h @@ -5,6 +5,8 @@ #ifndef V8_PARSING_SCANNER_CHARACTER_STREAMS_H_ #define V8_PARSING_SCANNER_CHARACTER_STREAMS_H_ +#include <memory> + #include "include/v8.h" // for v8::ScriptCompiler #include "src/common/globals.h" diff --git a/deps/v8/src/parsing/scanner.h b/deps/v8/src/parsing/scanner.h index c40d8f4ba390b8..d9216f222a051b 100644 --- a/deps/v8/src/parsing/scanner.h +++ b/deps/v8/src/parsing/scanner.h @@ -8,6 +8,7 @@ #define V8_PARSING_SCANNER_H_ #include <algorithm> +#include <memory> #include "src/base/logging.h" #include "src/common/globals.h" @@ -443,7 +444,8 @@ class V8_EXPORT_PRIVATE Scanner { #ifdef DEBUG bool CanAccessLiteral() const { return token == Token::PRIVATE_NAME || token == Token::ILLEGAL || - token == Token::UNINITIALIZED || token == Token::REGEXP_LITERAL || + token == Token::ESCAPED_KEYWORD || token == Token::UNINITIALIZED || + token == Token::REGEXP_LITERAL || IsInRange(token, Token::NUMBER, Token::STRING) || Token::IsAnyIdentifier(token) || Token::IsKeyword(token) || IsInRange(token, Token::TEMPLATE_SPAN, Token::TEMPLATE_TAIL); @@ -585,15 +587,18 @@ class V8_EXPORT_PRIVATE Scanner { // token as a one-byte literal. E.g. Token::FUNCTION pretends to have a // literal "function". Vector<const uint8_t> literal_one_byte_string() const { - DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token)); + DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) || + current().token == Token::ESCAPED_KEYWORD); return current().literal_chars.one_byte_literal(); } Vector<const uint16_t> literal_two_byte_string() const { - DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token)); + DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) || + current().token == Token::ESCAPED_KEYWORD); return current().literal_chars.two_byte_literal(); } bool is_literal_one_byte() const { - DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token)); + DCHECK(current().CanAccessLiteral() || Token::IsKeyword(current().token) || + current().token == Token::ESCAPED_KEYWORD); return current().literal_chars.is_one_byte(); } // Returns the literal string for the next token (the token that diff --git a/deps/v8/src/parsing/token.cc b/deps/v8/src/parsing/token.cc index 4dbae2d3f97c1f..ec4b623775a55e 100644 --- a/deps/v8/src/parsing/token.cc +++ b/deps/v8/src/parsing/token.cc @@ -34,7 +34,8 @@ const int8_t Token::precedence_[2][NUM_TOKENS] = {{TOKEN_LIST(T1, T1)}, #undef T2 #undef T1 -#define KT(a, b, c) IsPropertyNameBits::encode(Token::IsAnyIdentifier(a)), +#define KT(a, b, c) \ + IsPropertyNameBits::encode(Token::IsAnyIdentifier(a) || a == ESCAPED_KEYWORD), #define KK(a, b, c) \ IsKeywordBits::encode(true) | IsPropertyNameBits::encode(true), const uint8_t Token::token_flags[] = {TOKEN_LIST(KT, KK)}; diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc index 75b6aa7b77e1d1..42e72207020764 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.cc +++ b/deps/v8/src/profiler/heap-snapshot-generator.cc @@ -1306,8 +1306,7 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject js_obj, Isolate* isolate = js_obj.GetIsolate(); if (js_obj.HasFastProperties()) { DescriptorArray descs = js_obj.map().instance_descriptors(); - int real_size = js_obj.map().NumberOfOwnDescriptors(); - for (int i = 0; i < real_size; i++) { + for (InternalIndex i : js_obj.map().IterateOwnDescriptors()) { PropertyDetails details = descs.GetDetails(i); switch (details.location()) { case kField: { diff --git a/deps/v8/src/profiler/heap-snapshot-generator.h b/deps/v8/src/profiler/heap-snapshot-generator.h index 360ed1f009290f..e6c72ffcf99cae 100644 --- a/deps/v8/src/profiler/heap-snapshot-generator.h +++ b/deps/v8/src/profiler/heap-snapshot-generator.h @@ -6,6 +6,7 @@ #define V8_PROFILER_HEAP_SNAPSHOT_GENERATOR_H_ #include <deque> +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> diff --git a/deps/v8/src/profiler/profile-generator-inl.h b/deps/v8/src/profiler/profile-generator-inl.h index bb5ef0da5b7fd4..e3dc193db2736c 100644 --- a/deps/v8/src/profiler/profile-generator-inl.h +++ b/deps/v8/src/profiler/profile-generator-inl.h @@ -7,6 +7,8 @@ #include "src/profiler/profile-generator.h" +#include <memory> + namespace v8 { namespace internal { diff --git a/deps/v8/src/profiler/profile-generator.cc b/deps/v8/src/profiler/profile-generator.cc index f5f71846136543..c8fe890b583d4e 100644 --- a/deps/v8/src/profiler/profile-generator.cc +++ b/deps/v8/src/profiler/profile-generator.cc @@ -517,7 +517,7 @@ CpuProfile::CpuProfile(CpuProfiler* profiler, const char* title, DisallowHeapAllocation no_gc; i::Address raw_filter_context = reinterpret_cast<i::Address>(options_.raw_filter_context()); - context_filter_ = base::make_unique<ContextFilter>(raw_filter_context); + context_filter_ = std::make_unique<ContextFilter>(raw_filter_context); } } diff --git a/deps/v8/src/profiler/profiler-listener.cc b/deps/v8/src/profiler/profiler-listener.cc index b00c1f5cfd7ec2..13641bfd41f4bd 100644 --- a/deps/v8/src/profiler/profiler-listener.cc +++ b/deps/v8/src/profiler/profiler-listener.cc @@ -165,11 +165,10 @@ void ProfilerListener::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, SourcePosition(pos_info.shared->StartPosition()), pos_info.shared); - std::unique_ptr<CodeEntry> inline_entry = - base::make_unique<CodeEntry>( - tag, GetFunctionName(*pos_info.shared), resource_name, - start_pos_info.line + 1, start_pos_info.column + 1, nullptr, - code.InstructionStart(), inline_is_shared_cross_origin); + std::unique_ptr<CodeEntry> inline_entry = std::make_unique<CodeEntry>( + tag, GetFunctionName(*pos_info.shared), resource_name, + start_pos_info.line + 1, start_pos_info.column + 1, nullptr, + code.InstructionStart(), inline_is_shared_cross_origin); inline_entry->FillFunctionInfo(*pos_info.shared); // Create a canonical CodeEntry for each inlined frame and then re-use diff --git a/deps/v8/src/profiler/sampling-heap-profiler.cc b/deps/v8/src/profiler/sampling-heap-profiler.cc index de19d39eba605c..f5aa1dc3a052a6 100644 --- a/deps/v8/src/profiler/sampling-heap-profiler.cc +++ b/deps/v8/src/profiler/sampling-heap-profiler.cc @@ -9,7 +9,6 @@ #include "src/api/api-inl.h" #include "src/base/ieee754.h" -#include "src/base/template-utils.h" #include "src/base/utils/random-number-generator.h" #include "src/execution/frames-inl.h" #include "src/execution/isolate.h" @@ -89,7 +88,7 @@ void SamplingHeapProfiler::SampleObject(Address soon_object, size_t size) { AllocationNode* node = AddStack(); node->allocations_[size]++; auto sample = - base::make_unique<Sample>(size, node, loc, this, next_sample_id()); + std::make_unique<Sample>(size, node, loc, this, next_sample_id()); sample->global.SetWeak(sample.get(), OnWeakCallback, WeakCallbackType::kParameter); samples_.emplace(sample.get(), std::move(sample)); @@ -126,7 +125,7 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::FindOrAddChildNode( DCHECK_EQ(strcmp(child->name_, name), 0); return child; } - auto new_child = base::make_unique<AllocationNode>( + auto new_child = std::make_unique<AllocationNode>( parent, name, script_id, start_position, next_node_id()); return parent->AddChildNode(id, std::move(new_child)); } diff --git a/deps/v8/src/profiler/tracing-cpu-profiler.h b/deps/v8/src/profiler/tracing-cpu-profiler.h index d5888f54a35543..7a8fabe9581e2c 100644 --- a/deps/v8/src/profiler/tracing-cpu-profiler.h +++ b/deps/v8/src/profiler/tracing-cpu-profiler.h @@ -5,6 +5,8 @@ #ifndef V8_PROFILER_TRACING_CPU_PROFILER_H_ #define V8_PROFILER_TRACING_CPU_PROFILER_H_ +#include <memory> + #include "include/v8-platform.h" #include "src/base/atomic-utils.h" #include "src/base/macros.h" diff --git a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc index 9e00063487fb25..62a055e2a20cfd 100644 --- a/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc +++ b/deps/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc @@ -170,8 +170,11 @@ void RegExpMacroAssemblerARM64::AdvanceRegister(int reg, int by) { } case CACHED_MSW: { Register to_advance = GetCachedRegister(reg); - __ Add(to_advance, to_advance, - static_cast<int64_t>(by) << kWRegSizeInBits); + // Sign-extend to int64, shift as uint64, cast back to int64. + __ Add( + to_advance, to_advance, + static_cast<int64_t>(static_cast<uint64_t>(static_cast<int64_t>(by)) + << kWRegSizeInBits)); break; } default: diff --git a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc index 13b5c85605e7a5..a7f372ada5f0ef 100644 --- a/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc +++ b/deps/v8/src/regexp/ppc/regexp-macro-assembler-ppc.cc @@ -37,7 +37,10 @@ namespace internal { * The remaining registers are free for computations. * Each call to a public method should retain this convention. * - * The stack will have the following structure: + * The stack will have the following structure + * - fp[44] Address regexp (address of the JSRegExp object; unused in + * native code, passed to match signature of + * the interpreter): * - fp[40] Isolate* isolate (address of the current isolate) * - fp[36] lr save area (currently unused) * - fp[32] backchain (currently unused) @@ -83,7 +86,8 @@ namespace internal { * int num_capture_registers, * byte* stack_area_base, * bool direct_call = false, - * Isolate* isolate); + * Isolate* isolate, + * Address regexp); * The call is performed by NativeRegExpMacroAssembler::Execute() * (in regexp-macro-assembler.cc) via the GeneratedCode wrapper. */ @@ -109,8 +113,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, internal_failure_label_() { DCHECK_EQ(0, registers_to_save % 2); - // Because RegExp code respects C ABI, so needs a FD - __ function_descriptor(); __ b(&entry_label_); // We'll write the entry code later. // If the code gets too big or corrupted, an internal exception will be diff --git a/deps/v8/src/regexp/regexp-bytecode-generator.cc b/deps/v8/src/regexp/regexp-bytecode-generator.cc index 85b144438ec34e..0dcc288d3cf4ae 100644 --- a/deps/v8/src/regexp/regexp-bytecode-generator.cc +++ b/deps/v8/src/regexp/regexp-bytecode-generator.cc @@ -7,6 +7,7 @@ #include "src/ast/ast.h" #include "src/objects/objects-inl.h" #include "src/regexp/regexp-bytecode-generator-inl.h" +#include "src/regexp/regexp-bytecode-peephole.h" #include "src/regexp/regexp-bytecodes.h" #include "src/regexp/regexp-macro-assembler.h" @@ -18,6 +19,7 @@ RegExpBytecodeGenerator::RegExpBytecodeGenerator(Isolate* isolate, Zone* zone) buffer_(Vector<byte>::New(1024)), pc_(0), advance_current_end_(kInvalidPC), + jump_edges_(zone), isolate_(isolate) {} RegExpBytecodeGenerator::~RegExpBytecodeGenerator() { @@ -39,6 +41,7 @@ void RegExpBytecodeGenerator::Bind(Label* l) { int fixup = pos; pos = *reinterpret_cast<int32_t*>(buffer_.begin() + fixup); *reinterpret_cast<uint32_t*>(buffer_.begin() + fixup) = pc_; + jump_edges_.emplace(fixup, pc_); } } l->bind_to(pc_); @@ -46,16 +49,17 @@ void RegExpBytecodeGenerator::Bind(Label* l) { void RegExpBytecodeGenerator::EmitOrLink(Label* l) { if (l == nullptr) l = &backtrack_; + int pos = 0; if (l->is_bound()) { - Emit32(l->pos()); + pos = l->pos(); + jump_edges_.emplace(pc_, pos); } else { - int pos = 0; if (l->is_linked()) { pos = l->pos(); } l->link_to(pc_); - Emit32(pos); } + Emit32(pos); } void RegExpBytecodeGenerator::PopRegister(int register_index) { @@ -365,8 +369,16 @@ void RegExpBytecodeGenerator::IfRegisterEqPos(int register_index, Handle<HeapObject> RegExpBytecodeGenerator::GetCode(Handle<String> source) { Bind(&backtrack_); Emit(BC_POP_BT, 0); - Handle<ByteArray> array = isolate_->factory()->NewByteArray(length()); - Copy(array->GetDataStartAddress()); + + Handle<ByteArray> array; + if (FLAG_regexp_peephole_optimization) { + array = RegExpBytecodePeepholeOptimization::OptimizeBytecode( + isolate_, zone(), source, buffer_.begin(), length(), jump_edges_); + } else { + array = isolate_->factory()->NewByteArray(length()); + Copy(array->GetDataStartAddress()); + } + return array; } diff --git a/deps/v8/src/regexp/regexp-bytecode-generator.h b/deps/v8/src/regexp/regexp-bytecode-generator.h index 84b7ce361c8c2a..dfcc2ca5f8a331 100644 --- a/deps/v8/src/regexp/regexp-bytecode-generator.h +++ b/deps/v8/src/regexp/regexp-bytecode-generator.h @@ -100,6 +100,12 @@ class V8_EXPORT_PRIVATE RegExpBytecodeGenerator : public RegExpMacroAssembler { int advance_current_offset_; int advance_current_end_; + // Stores jump edges emitted for the bytecode (used by + // RegExpBytecodePeepholeOptimization). + // Key: jump source (offset in buffer_ where jump destination is stored). + // Value: jump destination (offset in buffer_ to jump to). + ZoneUnorderedMap<int, int> jump_edges_; + Isolate* isolate_; static const int kInvalidPC = -1; diff --git a/deps/v8/src/regexp/regexp-bytecode-peephole.cc b/deps/v8/src/regexp/regexp-bytecode-peephole.cc new file mode 100644 index 00000000000000..8f1f1d95a90395 --- /dev/null +++ b/deps/v8/src/regexp/regexp-bytecode-peephole.cc @@ -0,0 +1,1037 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/regexp/regexp-bytecode-peephole.h" + +#include "src/execution/isolate.h" +#include "src/flags/flags.h" +#include "src/objects/fixed-array.h" +#include "src/objects/objects-inl.h" +#include "src/regexp/regexp-bytecodes.h" +#include "src/utils/memcopy.h" +#include "src/utils/utils.h" +#include "src/zone/zone-containers.h" +#include "src/zone/zone.h" + +namespace v8 { +namespace internal { + +namespace { + +struct BytecodeArgument { + int offset; + int length; + + BytecodeArgument(int offset, int length) : offset(offset), length(length) {} +}; + +struct BytecodeArgumentMapping : BytecodeArgument { + int new_length; + + BytecodeArgumentMapping(int offset, int length, int new_length) + : BytecodeArgument(offset, length), new_length(new_length) {} +}; + +struct BytecodeArgumentCheck : BytecodeArgument { + enum CheckType { kCheckAddress = 0, kCheckValue }; + CheckType type; + int check_offset; + int check_length; + + BytecodeArgumentCheck(int offset, int length, int check_offset) + : BytecodeArgument(offset, length), + type(kCheckAddress), + check_offset(check_offset) {} + BytecodeArgumentCheck(int offset, int length, int check_offset, + int check_length) + : BytecodeArgument(offset, length), + type(kCheckValue), + check_offset(check_offset), + check_length(check_length) {} +}; + +// Trie-Node for storing bytecode sequences we want to optimize. +class BytecodeSequenceNode { + public: + // Dummy bytecode used when we need to store/return a bytecode but it's not a + // valid bytecode in the current context. + static constexpr int kDummyBytecode = -1; + + BytecodeSequenceNode(int bytecode, Zone* zone); + // Adds a new node as child of the current node if it isn't a child already. + BytecodeSequenceNode& FollowedBy(int bytecode); + // Marks the end of a sequence and sets optimized bytecode to replace all + // bytecodes of the sequence with. + BytecodeSequenceNode& ReplaceWith(int bytecode); + // Maps arguments of bytecodes in the sequence to the optimized bytecode. + // Order of invocation determines order of arguments in the optimized + // bytecode. + // Invoking this method is only allowed on nodes that mark the end of a valid + // sequence (i.e. after ReplaceWith()). + // bytecode_index_in_sequence: Zero-based index of the referred bytecode + // within the sequence (e.g. the bytecode passed to CreateSequence() has + // index 0). + // argument_offset: Zero-based offset to the argument within the bytecode + // (e.g. the first argument that's not packed with the bytecode has offset 4). + // argument_byte_length: Length of the argument. + // new_argument_byte_length: Length of the argument in the new bytecode + // (= argument_byte_length if omitted). + BytecodeSequenceNode& MapArgument(int bytecode_index_in_sequence, + int argument_offset, + int argument_byte_length, + int new_argument_byte_length = 0); + // Adds a check to the sequence node making it only a valid sequence when the + // argument of the current bytecode at the specified offset matches the offset + // to check against. + // argument_offset: Zero-based offset to the argument within the bytecode + // (e.g. the first argument that's not packed with the bytecode has offset 4). + // argument_byte_length: Length of the argument. + // check_byte_offset: Zero-based offset relative to the beginning of the + // sequence that needs to match the value given by argument_offset. (e.g. + // check_byte_offset 0 matches the address of the first bytecode in the + // sequence). + BytecodeSequenceNode& IfArgumentEqualsOffset(int argument_offset, + int argument_byte_length, + int check_byte_offset); + // Adds a check to the sequence node making it only a valid sequence when the + // argument of the current bytecode at the specified offset matches the + // argument of another bytecode in the sequence. + // This is similar to IfArgumentEqualsOffset, except that this method matches + // the values of both arguments. + BytecodeSequenceNode& IfArgumentEqualsValueAtOffset( + int argument_offset, int argument_byte_length, + int other_bytecode_index_in_sequence, int other_argument_offset, + int other_argument_byte_length); + // Marks an argument as unused. + // All arguments that are not mapped explicitly have to be marked as unused. + // bytecode_index_in_sequence: Zero-based index of the referred bytecode + // within the sequence (e.g. the bytecode passed to CreateSequence() has + // index 0). + // argument_offset: Zero-based offset to the argument within the bytecode + // (e.g. the first argument that's not packed with the bytecode has offset 4). + // argument_byte_length: Length of the argument. + BytecodeSequenceNode& IgnoreArgument(int bytecode_index_in_sequence, + int argument_offset, + int argument_byte_length); + // Checks if the current node is valid for the sequence. I.e. all conditions + // set by IfArgumentEqualsOffset and IfArgumentEquals are fulfilled by this + // node for the actual bytecode sequence. + bool CheckArguments(const byte* bytecode, int pc); + // Returns whether this node marks the end of a valid sequence (i.e. can be + // replaced with an optimized bytecode). + bool IsSequence() const; + // Returns the length of the sequence in bytes. + int SequenceLength() const; + // Returns the optimized bytecode for the node or kDummyBytecode if it is not + // the end of a valid sequence. + int OptimizedBytecode() const; + // Returns the child of the current node matching the given bytecode or + // nullptr if no such child is found. + BytecodeSequenceNode* Find(int bytecode) const; + // Returns number of arguments mapped to the current node. + // Invoking this method is only allowed on nodes that mark the end of a valid + // sequence (i.e. if IsSequence()) + size_t ArgumentSize() const; + // Returns the argument-mapping of the argument at index. + // Invoking this method is only allowed on nodes that mark the end of a valid + // sequence (i.e. if IsSequence()) + BytecodeArgumentMapping ArgumentMapping(size_t index) const; + // Returns an iterator to begin of ignored arguments. + // Invoking this method is only allowed on nodes that mark the end of a valid + // sequence (i.e. if IsSequence()) + ZoneLinkedList<BytecodeArgument>::iterator ArgumentIgnoredBegin() const; + // Returns an iterator to end of ignored arguments. + // Invoking this method is only allowed on nodes that mark the end of a valid + // sequence (i.e. if IsSequence()) + ZoneLinkedList<BytecodeArgument>::iterator ArgumentIgnoredEnd() const; + // Returns whether the current node has ignored argument or not. + bool HasIgnoredArguments() const; + + private: + // Returns a node in the sequence specified by its index within the sequence. + BytecodeSequenceNode& GetNodeByIndexInSequence(int index_in_sequence); + Zone* zone() const; + + int bytecode_; + int bytecode_replacement_; + int index_in_sequence_; + int start_offset_; + BytecodeSequenceNode* parent_; + ZoneUnorderedMap<int, BytecodeSequenceNode*> children_; + ZoneVector<BytecodeArgumentMapping>* argument_mapping_; + ZoneLinkedList<BytecodeArgumentCheck>* argument_check_; + ZoneLinkedList<BytecodeArgument>* argument_ignored_; + + Zone* zone_; +}; + +class RegExpBytecodePeephole { + public: + RegExpBytecodePeephole(Zone* zone, size_t buffer_size, + const ZoneUnorderedMap<int, int>& jump_edges); + + // Parses bytecode and fills the internal buffer with the potentially + // optimized bytecode. Returns true when optimizations were performed, false + // otherwise. + bool OptimizeBytecode(const byte* bytecode, int length); + // Copies the internal bytecode buffer to another buffer. The caller is + // responsible for allocating/freeing the memory. + void CopyOptimizedBytecode(byte* to_address) const; + int Length() const; + + private: + // Sets up all sequences that are going to be used. + void DefineStandardSequences(); + // Starts a new bytecode sequence. + BytecodeSequenceNode& CreateSequence(int bytecode); + // Checks for optimization candidates at pc and emits optimized bytecode to + // the internal buffer. Returns the length of replaced bytecodes in bytes. + int TryOptimizeSequence(const byte* bytecode, int start_pc); + // Emits optimized bytecode to the internal buffer. start_pc points to the + // start of the sequence in bytecode and last_node is the last + // BytecodeSequenceNode of the matching sequence found. + void EmitOptimization(int start_pc, const byte* bytecode, + const BytecodeSequenceNode& last_node); + // Adds a relative jump source fixup at pos. + // Jump source fixups are used to find offsets in the new bytecode that + // contain jump sources. + void AddJumpSourceFixup(int fixup, int pos); + // Adds a relative jump destination fixup at pos. + // Jump destination fixups are used to find offsets in the new bytecode that + // can be jumped to. + void AddJumpDestinationFixup(int fixup, int pos); + // Sets an absolute jump destination fixup at pos. + void SetJumpDestinationFixup(int fixup, int pos); + // Prepare internal structures used to fixup jumps. + void PrepareJumpStructures(const ZoneUnorderedMap<int, int>& jump_edges); + // Updates all jump targets in the new bytecode. + void FixJumps(); + // Update a single jump. + void FixJump(int jump_source, int jump_destination); + void AddSentinelFixups(int pos); + template <typename T> + void EmitValue(T value); + template <typename T> + void OverwriteValue(int offset, T value); + void CopyRangeToOutput(const byte* orig_bytecode, int start, int length); + void SetRange(byte value, int count); + void EmitArgument(int start_pc, const byte* bytecode, + BytecodeArgumentMapping arg); + int pc() const; + Zone* zone() const; + + ZoneVector<byte> optimized_bytecode_buffer_; + BytecodeSequenceNode* sequences_; + // Jumps used in old bytecode. + // Key: Jump source (offset where destination is stored in old bytecode) + // Value: Destination + ZoneMap<int, int> jump_edges_; + // Jumps used in new bytecode. + // Key: Jump source (offset where destination is stored in new bytecode) + // Value: Destination + ZoneMap<int, int> jump_edges_mapped_; + // Number of times a jump destination is used within the bytecode. + // Key: Jump destination (offset in old bytecode). + // Value: Number of times jump destination is used. + ZoneMap<int, int> jump_usage_counts_; + // Maps offsets in old bytecode to fixups of sources (delta to new bytecode). + // Key: Offset in old bytecode from where the fixup is valid. + // Value: Delta to map jump source from old bytecode to new bytecode in bytes. + ZoneMap<int, int> jump_source_fixups_; + // Maps offsets in old bytecode to fixups of destinations (delta to new + // bytecode). + // Key: Offset in old bytecode from where the fixup is valid. + // Value: Delta to map jump destinations from old bytecode to new bytecode in + // bytes. + ZoneMap<int, int> jump_destination_fixups_; + + Zone* zone_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(RegExpBytecodePeephole); +}; + +template <typename T> +T GetValue(const byte* buffer, int pos) { + DCHECK(IsAligned(reinterpret_cast<Address>(buffer + pos), alignof(T))); + return *reinterpret_cast<const T*>(buffer + pos); +} + +int32_t GetArgumentValue(const byte* bytecode, int offset, int length) { + switch (length) { + case 1: + return GetValue<byte>(bytecode, offset); + break; + case 2: + return GetValue<int16_t>(bytecode, offset); + break; + case 4: + return GetValue<int32_t>(bytecode, offset); + break; + default: + UNREACHABLE(); + } +} + +BytecodeSequenceNode::BytecodeSequenceNode(int bytecode, Zone* zone) + : bytecode_(bytecode), + bytecode_replacement_(kDummyBytecode), + index_in_sequence_(0), + start_offset_(0), + parent_(nullptr), + children_(ZoneUnorderedMap<int, BytecodeSequenceNode*>(zone)), + argument_mapping_(new (zone->New(sizeof(*argument_mapping_))) + ZoneVector<BytecodeArgumentMapping>(zone)), + argument_check_(new (zone->New(sizeof(*argument_check_))) + ZoneLinkedList<BytecodeArgumentCheck>(zone)), + argument_ignored_(new (zone->New(sizeof(*argument_ignored_))) + ZoneLinkedList<BytecodeArgument>(zone)), + zone_(zone) {} + +BytecodeSequenceNode& BytecodeSequenceNode::FollowedBy(int bytecode) { + DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount); + + if (children_.find(bytecode) == children_.end()) { + BytecodeSequenceNode* new_node = + new (zone()->New(sizeof(BytecodeSequenceNode))) + BytecodeSequenceNode(bytecode, zone()); + // If node is not the first in the sequence, set offsets and parent. + if (bytecode_ != kDummyBytecode) { + new_node->start_offset_ = start_offset_ + RegExpBytecodeLength(bytecode_); + new_node->index_in_sequence_ = index_in_sequence_ + 1; + new_node->parent_ = this; + } + children_[bytecode] = new_node; + } + + return *children_[bytecode]; +} + +BytecodeSequenceNode& BytecodeSequenceNode::ReplaceWith(int bytecode) { + DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount); + + bytecode_replacement_ = bytecode; + + return *this; +} + +BytecodeSequenceNode& BytecodeSequenceNode::MapArgument( + int bytecode_index_in_sequence, int argument_offset, + int argument_byte_length, int new_argument_byte_length) { + DCHECK(IsSequence()); + DCHECK_LE(bytecode_index_in_sequence, index_in_sequence_); + + BytecodeSequenceNode& ref_node = + GetNodeByIndexInSequence(bytecode_index_in_sequence); + DCHECK_LT(argument_offset, RegExpBytecodeLength(ref_node.bytecode_)); + + int absolute_offset = ref_node.start_offset_ + argument_offset; + if (new_argument_byte_length == 0) { + new_argument_byte_length = argument_byte_length; + } + + argument_mapping_->push_back(BytecodeArgumentMapping{ + absolute_offset, argument_byte_length, new_argument_byte_length}); + + return *this; +} + +BytecodeSequenceNode& BytecodeSequenceNode::IfArgumentEqualsOffset( + int argument_offset, int argument_byte_length, int check_byte_offset) { + DCHECK_LT(argument_offset, RegExpBytecodeLength(bytecode_)); + DCHECK(argument_byte_length == 1 || argument_byte_length == 2 || + argument_byte_length == 4); + + int absolute_offset = start_offset_ + argument_offset; + + argument_check_->push_back(BytecodeArgumentCheck{ + absolute_offset, argument_byte_length, check_byte_offset}); + + return *this; +} + +BytecodeSequenceNode& BytecodeSequenceNode::IfArgumentEqualsValueAtOffset( + int argument_offset, int argument_byte_length, + int other_bytecode_index_in_sequence, int other_argument_offset, + int other_argument_byte_length) { + DCHECK_LT(argument_offset, RegExpBytecodeLength(bytecode_)); + DCHECK_LE(other_bytecode_index_in_sequence, index_in_sequence_); + DCHECK_EQ(argument_byte_length, other_argument_byte_length); + + BytecodeSequenceNode& ref_node = + GetNodeByIndexInSequence(other_bytecode_index_in_sequence); + DCHECK_LT(other_argument_offset, RegExpBytecodeLength(ref_node.bytecode_)); + + int absolute_offset = start_offset_ + argument_offset; + int other_absolute_offset = ref_node.start_offset_ + other_argument_offset; + + argument_check_->push_back( + BytecodeArgumentCheck{absolute_offset, argument_byte_length, + other_absolute_offset, other_argument_byte_length}); + + return *this; +} + +BytecodeSequenceNode& BytecodeSequenceNode::IgnoreArgument( + int bytecode_index_in_sequence, int argument_offset, + int argument_byte_length) { + DCHECK(IsSequence()); + DCHECK_LE(bytecode_index_in_sequence, index_in_sequence_); + + BytecodeSequenceNode& ref_node = + GetNodeByIndexInSequence(bytecode_index_in_sequence); + DCHECK_LT(argument_offset, RegExpBytecodeLength(ref_node.bytecode_)); + + int absolute_offset = ref_node.start_offset_ + argument_offset; + + argument_ignored_->push_back( + BytecodeArgument{absolute_offset, argument_byte_length}); + + return *this; +} + +bool BytecodeSequenceNode::CheckArguments(const byte* bytecode, int pc) { + bool is_valid = true; + for (auto check_iter = argument_check_->begin(); + check_iter != argument_check_->end() && is_valid; check_iter++) { + auto value = + GetArgumentValue(bytecode, pc + check_iter->offset, check_iter->length); + if (check_iter->type == BytecodeArgumentCheck::kCheckAddress) { + is_valid &= value == pc + check_iter->check_offset; + } else if (check_iter->type == BytecodeArgumentCheck::kCheckValue) { + auto other_value = GetArgumentValue( + bytecode, pc + check_iter->check_offset, check_iter->check_length); + is_valid &= value == other_value; + } else { + UNREACHABLE(); + } + } + return is_valid; +} + +bool BytecodeSequenceNode::IsSequence() const { + return bytecode_replacement_ != kDummyBytecode; +} + +int BytecodeSequenceNode::SequenceLength() const { + return start_offset_ + RegExpBytecodeLength(bytecode_); +} + +int BytecodeSequenceNode::OptimizedBytecode() const { + return bytecode_replacement_; +} + +BytecodeSequenceNode* BytecodeSequenceNode::Find(int bytecode) const { + auto found = children_.find(bytecode); + if (found == children_.end()) return nullptr; + return found->second; +} + +size_t BytecodeSequenceNode::ArgumentSize() const { + DCHECK(IsSequence()); + return argument_mapping_->size(); +} + +BytecodeArgumentMapping BytecodeSequenceNode::ArgumentMapping( + size_t index) const { + DCHECK(IsSequence()); + DCHECK(argument_mapping_ != nullptr); + DCHECK_GE(index, 0); + DCHECK_LT(index, argument_mapping_->size()); + + return argument_mapping_->at(index); +} + +ZoneLinkedList<BytecodeArgument>::iterator +BytecodeSequenceNode::ArgumentIgnoredBegin() const { + DCHECK(IsSequence()); + DCHECK(argument_ignored_ != nullptr); + return argument_ignored_->begin(); +} + +ZoneLinkedList<BytecodeArgument>::iterator +BytecodeSequenceNode::ArgumentIgnoredEnd() const { + DCHECK(IsSequence()); + DCHECK(argument_ignored_ != nullptr); + return argument_ignored_->end(); +} + +bool BytecodeSequenceNode::HasIgnoredArguments() const { + return argument_ignored_ != nullptr; +} + +BytecodeSequenceNode& BytecodeSequenceNode::GetNodeByIndexInSequence( + int index_in_sequence) { + DCHECK_LE(index_in_sequence, index_in_sequence_); + + if (index_in_sequence < index_in_sequence_) { + DCHECK(parent_ != nullptr); + return parent_->GetNodeByIndexInSequence(index_in_sequence); + } else { + return *this; + } +} + +Zone* BytecodeSequenceNode::zone() const { return zone_; } + +RegExpBytecodePeephole::RegExpBytecodePeephole( + Zone* zone, size_t buffer_size, + const ZoneUnorderedMap<int, int>& jump_edges) + : optimized_bytecode_buffer_(zone), + sequences_(new (zone->New(sizeof(*sequences_))) BytecodeSequenceNode( + BytecodeSequenceNode::kDummyBytecode, zone)), + jump_edges_(zone), + jump_edges_mapped_(zone), + jump_usage_counts_(zone), + jump_source_fixups_(zone), + jump_destination_fixups_(zone), + zone_(zone) { + optimized_bytecode_buffer_.reserve(buffer_size); + PrepareJumpStructures(jump_edges); + DefineStandardSequences(); + // Sentinel fixups at beginning of bytecode (position -1) so we don't have to + // check for end of iterator inside the fixup loop. + // In general fixups are deltas of original offsets of jump + // sources/destinations (in the old bytecode) to find them in the new + // bytecode. All jump targets are fixed after the new bytecode is fully + // emitted in the internal buffer. + AddSentinelFixups(-1); + // Sentinel fixups at end of (old) bytecode so we don't have to check for + // end of iterator inside the fixup loop. + DCHECK_LE(buffer_size, std::numeric_limits<int>::max()); + AddSentinelFixups(static_cast<int>(buffer_size)); +} + +void RegExpBytecodePeephole::DefineStandardSequences() { + // Commonly used sequences can be found by creating regexp bytecode traces + // (--trace-regexp-bytecodes) and using v8/tools/regexp-sequences.py. + CreateSequence(BC_LOAD_CURRENT_CHAR) + .FollowedBy(BC_CHECK_BIT_IN_TABLE) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_BIT_IN_TABLE) + .MapArgument(0, 1, 3) // load offset + .MapArgument(2, 1, 3, 4) // advance by + .MapArgument(1, 8, 16) // bit table + .MapArgument(1, 4, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(2, 4, 4); // loop jump + + CreateSequence(BC_CHECK_CURRENT_POSITION) + .FollowedBy(BC_LOAD_CURRENT_CHAR_UNCHECKED) + .FollowedBy(BC_CHECK_CHAR) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_CHAR_POS_CHECKED) + .MapArgument(1, 1, 3) // load offset + .MapArgument(3, 1, 3, 2) // advance_by + .MapArgument(2, 1, 3, 2) // c + .MapArgument(0, 1, 3, 4) // eats at least + .MapArgument(2, 4, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(3, 4, 4); // loop jump + + CreateSequence(BC_CHECK_CURRENT_POSITION) + .FollowedBy(BC_LOAD_CURRENT_CHAR_UNCHECKED) + .FollowedBy(BC_AND_CHECK_CHAR) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_CHAR_AND) + .MapArgument(1, 1, 3) // load offset + .MapArgument(3, 1, 3, 2) // advance_by + .MapArgument(2, 1, 3, 2) // c + .MapArgument(2, 4, 4) // mask + .MapArgument(0, 1, 3, 4) // eats at least + .MapArgument(2, 8, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(3, 4, 4); // loop jump + + // TODO(pthier): It might make sense for short sequences like this one to only + // optimize them if the resulting optimization is not longer than the current + // one. This could be the case if there are jumps inside the sequence and we + // have to replicate parts of the sequence. A method to mark such sequences + // might be useful. + CreateSequence(BC_LOAD_CURRENT_CHAR) + .FollowedBy(BC_CHECK_CHAR) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_CHAR) + .MapArgument(0, 1, 3) // load offset + .MapArgument(2, 1, 3, 2) // advance by + .MapArgument(1, 1, 3, 2) // character + .MapArgument(1, 4, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(2, 4, 4); // loop jump + + CreateSequence(BC_LOAD_CURRENT_CHAR) + .FollowedBy(BC_CHECK_CHAR) + .FollowedBy(BC_CHECK_CHAR) + // Sequence is only valid if the jump targets of both CHECK_CHAR bytecodes + // are equal. + .IfArgumentEqualsValueAtOffset(4, 4, 1, 4, 4) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_CHAR_OR_CHAR) + .MapArgument(0, 1, 3) // load offset + .MapArgument(3, 1, 3, 4) // advance by + .MapArgument(1, 1, 3, 2) // character 1 + .MapArgument(2, 1, 3, 2) // character 2 + .MapArgument(1, 4, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(2, 4, 4) // goto when match 2 + .IgnoreArgument(3, 4, 4); // loop jump + + CreateSequence(BC_LOAD_CURRENT_CHAR) + .FollowedBy(BC_CHECK_GT) + // Sequence is only valid if the jump target of CHECK_GT is the first + // bytecode AFTER the whole sequence. + .IfArgumentEqualsOffset(4, 4, 56) + .FollowedBy(BC_CHECK_BIT_IN_TABLE) + // Sequence is only valid if the jump target of CHECK_BIT_IN_TABLE is + // the ADVANCE_CP_AND_GOTO bytecode at the end of the sequence. + .IfArgumentEqualsOffset(4, 4, 48) + .FollowedBy(BC_GOTO) + // Sequence is only valid if the jump target of GOTO is the same as the + // jump target of CHECK_GT (i.e. both jump to the first bytecode AFTER the + // whole sequence. + .IfArgumentEqualsValueAtOffset(4, 4, 1, 4, 4) + .FollowedBy(BC_ADVANCE_CP_AND_GOTO) + // Sequence is only valid if the jump target of ADVANCE_CP_AND_GOTO is the + // first bytecode in this sequence. + .IfArgumentEqualsOffset(4, 4, 0) + .ReplaceWith(BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE) + .MapArgument(0, 1, 3) // load offset + .MapArgument(4, 1, 3, 2) // advance by + .MapArgument(1, 1, 3, 2) // character + .MapArgument(2, 8, 16) // bit table + .MapArgument(1, 4, 4) // goto when match + .MapArgument(0, 4, 4) // goto on failure + .IgnoreArgument(2, 4, 4) // indirect loop jump + .IgnoreArgument(3, 4, 4) // jump out of loop + .IgnoreArgument(4, 4, 4); // loop jump +} + +bool RegExpBytecodePeephole::OptimizeBytecode(const byte* bytecode, + int length) { + int old_pc = 0; + bool did_optimize = false; + + while (old_pc < length) { + int replaced_len = TryOptimizeSequence(bytecode, old_pc); + if (replaced_len > 0) { + old_pc += replaced_len; + did_optimize = true; + } else { + int bc = bytecode[old_pc]; + int bc_len = RegExpBytecodeLength(bc); + CopyRangeToOutput(bytecode, old_pc, bc_len); + old_pc += bc_len; + } + } + + if (did_optimize) { + FixJumps(); + } + + return did_optimize; +} + +void RegExpBytecodePeephole::CopyOptimizedBytecode(byte* to_address) const { + MemCopy(to_address, &(*optimized_bytecode_buffer_.begin()), Length()); +} + +int RegExpBytecodePeephole::Length() const { return pc(); } + +BytecodeSequenceNode& RegExpBytecodePeephole::CreateSequence(int bytecode) { + DCHECK(sequences_ != nullptr); + DCHECK(0 <= bytecode && bytecode < kRegExpBytecodeCount); + + return sequences_->FollowedBy(bytecode); +} + +int RegExpBytecodePeephole::TryOptimizeSequence(const byte* bytecode, + int start_pc) { + BytecodeSequenceNode* seq_node = sequences_; + BytecodeSequenceNode* valid_seq_end = nullptr; + + int current_pc = start_pc; + + // Check for the longest valid sequence matching any of the pre-defined + // sequences in the Trie data structure. + while ((seq_node = seq_node->Find(bytecode[current_pc]))) { + if (!seq_node->CheckArguments(bytecode, start_pc)) { + break; + } + if (seq_node->IsSequence()) { + valid_seq_end = seq_node; + } + current_pc += RegExpBytecodeLength(bytecode[current_pc]); + } + + if (valid_seq_end) { + EmitOptimization(start_pc, bytecode, *valid_seq_end); + return valid_seq_end->SequenceLength(); + } + + return 0; +} + +void RegExpBytecodePeephole::EmitOptimization( + int start_pc, const byte* bytecode, const BytecodeSequenceNode& last_node) { +#ifdef DEBUG + int optimized_start_pc = pc(); +#endif + // Jump sources that are mapped or marked as unused will be deleted at the end + // of this method. We don't delete them immediately as we might need the + // information when we have to preserve bytecodes at the end. + // TODO(pthier): Replace with a stack-allocated data structure. + ZoneLinkedList<int> delete_jumps = ZoneLinkedList<int>(zone()); + + uint32_t bc = last_node.OptimizedBytecode(); + EmitValue(bc); + + for (size_t arg = 0; arg < last_node.ArgumentSize(); arg++) { + BytecodeArgumentMapping arg_map = last_node.ArgumentMapping(arg); + int arg_pos = start_pc + arg_map.offset; + // If we map any jump source we mark the old source for deletion and insert + // a new jump. + auto jump_edge_iter = jump_edges_.find(arg_pos); + if (jump_edge_iter != jump_edges_.end()) { + int jump_source = jump_edge_iter->first; + int jump_destination = jump_edge_iter->second; + // Add new jump edge add current position. + jump_edges_mapped_.emplace(Length(), jump_destination); + // Mark old jump edge for deletion. + delete_jumps.push_back(jump_source); + // Decrement usage count of jump destination. + auto jump_count_iter = jump_usage_counts_.find(jump_destination); + DCHECK(jump_count_iter != jump_usage_counts_.end()); + int& usage_count = jump_count_iter->second; + --usage_count; + } + // TODO(pthier): DCHECK that mapped arguments are never sources of jumps + // to destinations inside the sequence. + EmitArgument(start_pc, bytecode, arg_map); + } + DCHECK_EQ(pc(), optimized_start_pc + + RegExpBytecodeLength(last_node.OptimizedBytecode())); + + // Remove jumps from arguments we ignore. + if (last_node.HasIgnoredArguments()) { + for (auto ignored_arg = last_node.ArgumentIgnoredBegin(); + ignored_arg != last_node.ArgumentIgnoredEnd(); ignored_arg++) { + auto jump_edge_iter = jump_edges_.find(start_pc + ignored_arg->offset); + if (jump_edge_iter != jump_edges_.end()) { + int jump_source = jump_edge_iter->first; + int jump_destination = jump_edge_iter->second; + // Mark old jump edge for deletion. + delete_jumps.push_back(jump_source); + // Decrement usage count of jump destination. + auto jump_count_iter = jump_usage_counts_.find(jump_destination); + DCHECK(jump_count_iter != jump_usage_counts_.end()); + int& usage_count = jump_count_iter->second; + --usage_count; + } + } + } + + int fixup_length = RegExpBytecodeLength(bc) - last_node.SequenceLength(); + + // Check if there are any jumps inside the old sequence. + // If so we have to keep the bytecodes that are jumped to around. + auto jump_destination_candidate = jump_usage_counts_.upper_bound(start_pc); + int jump_candidate_destination = jump_destination_candidate->first; + int jump_candidate_count = jump_destination_candidate->second; + // Jump destinations only jumped to from inside the sequence will be ignored. + while (jump_destination_candidate != jump_usage_counts_.end() && + jump_candidate_count == 0) { + ++jump_destination_candidate; + jump_candidate_destination = jump_destination_candidate->first; + jump_candidate_count = jump_destination_candidate->second; + } + + int preserve_from = start_pc + last_node.SequenceLength(); + if (jump_destination_candidate != jump_usage_counts_.end() && + jump_candidate_destination < start_pc + last_node.SequenceLength()) { + preserve_from = jump_candidate_destination; + // Check if any jump in the sequence we are preserving has a jump + // destination inside the optimized sequence before the current position we + // want to preserve. If so we have to preserve all bytecodes starting at + // this jump destination. + for (auto jump_iter = jump_edges_.lower_bound(preserve_from); + jump_iter != jump_edges_.end() && + jump_iter->first /* jump source */ < + start_pc + last_node.SequenceLength(); + ++jump_iter) { + int jump_destination = jump_iter->second; + if (jump_destination > start_pc && jump_destination < preserve_from) { + preserve_from = jump_destination; + } + } + + // We preserve everything to the end of the sequence. This is conservative + // since it would be enough to preserve all bytecudes up to an unconditional + // jump. + int preserve_length = start_pc + last_node.SequenceLength() - preserve_from; + fixup_length += preserve_length; + // Jumps after the start of the preserved sequence need fixup. + AddJumpSourceFixup(fixup_length, + start_pc + last_node.SequenceLength() - preserve_length); + // All jump targets after the start of the optimized sequence need to be + // fixed relative to the length of the optimized sequence including + // bytecodes we preserved. + AddJumpDestinationFixup(fixup_length, start_pc + 1); + // Jumps to the sequence we preserved need absolute fixup as they could + // occur before or after the sequence. + SetJumpDestinationFixup(pc() - preserve_from, preserve_from); + CopyRangeToOutput(bytecode, preserve_from, preserve_length); + } else { + AddJumpDestinationFixup(fixup_length, start_pc + 1); + // Jumps after the end of the old sequence need fixup. + AddJumpSourceFixup(fixup_length, start_pc + last_node.SequenceLength()); + } + + // Delete jumps we definitely don't need anymore + for (int del : delete_jumps) { + if (del < preserve_from) { + jump_edges_.erase(del); + } + } +} + +void RegExpBytecodePeephole::AddJumpSourceFixup(int fixup, int pos) { + auto previous_fixup = jump_source_fixups_.lower_bound(pos); + DCHECK(previous_fixup != jump_source_fixups_.end()); + DCHECK(previous_fixup != jump_source_fixups_.begin()); + + int previous_fixup_value = (--previous_fixup)->second; + jump_source_fixups_[pos] = previous_fixup_value + fixup; +} + +void RegExpBytecodePeephole::AddJumpDestinationFixup(int fixup, int pos) { + auto previous_fixup = jump_destination_fixups_.lower_bound(pos); + DCHECK(previous_fixup != jump_destination_fixups_.end()); + DCHECK(previous_fixup != jump_destination_fixups_.begin()); + + int previous_fixup_value = (--previous_fixup)->second; + jump_destination_fixups_[pos] = previous_fixup_value + fixup; +} + +void RegExpBytecodePeephole::SetJumpDestinationFixup(int fixup, int pos) { + auto previous_fixup = jump_destination_fixups_.lower_bound(pos); + DCHECK(previous_fixup != jump_destination_fixups_.end()); + DCHECK(previous_fixup != jump_destination_fixups_.begin()); + + int previous_fixup_value = (--previous_fixup)->second; + jump_destination_fixups_.emplace(pos, fixup); + jump_destination_fixups_.emplace(pos + 1, previous_fixup_value); +} + +void RegExpBytecodePeephole::PrepareJumpStructures( + const ZoneUnorderedMap<int, int>& jump_edges) { + for (auto jump_edge : jump_edges) { + int jump_source = jump_edge.first; + int jump_destination = jump_edge.second; + + jump_edges_.emplace(jump_source, jump_destination); + jump_usage_counts_[jump_destination]++; + } +} + +void RegExpBytecodePeephole::FixJumps() { + int position_fixup = 0; + // Next position where fixup changes. + auto next_source_fixup = jump_source_fixups_.lower_bound(0); + int next_source_fixup_offset = next_source_fixup->first; + int next_source_fixup_value = next_source_fixup->second; + + for (auto jump_edge : jump_edges_) { + int jump_source = jump_edge.first; + int jump_destination = jump_edge.second; + while (jump_source >= next_source_fixup_offset) { + position_fixup = next_source_fixup_value; + ++next_source_fixup; + next_source_fixup_offset = next_source_fixup->first; + next_source_fixup_value = next_source_fixup->second; + } + jump_source += position_fixup; + + FixJump(jump_source, jump_destination); + } + + // Mapped jump edges don't need source fixups, as the position already is an + // offset in the new bytecode. + for (auto jump_edge : jump_edges_mapped_) { + int jump_source = jump_edge.first; + int jump_destination = jump_edge.second; + + FixJump(jump_source, jump_destination); + } +} + +void RegExpBytecodePeephole::FixJump(int jump_source, int jump_destination) { + int fixed_jump_destination = + jump_destination + + (--jump_destination_fixups_.upper_bound(jump_destination))->second; + DCHECK_LT(fixed_jump_destination, Length()); +#ifdef DEBUG + // TODO(pthier): This check could be better if we track the bytecodes + // actually used and check if we jump to one of them. + byte jump_bc = optimized_bytecode_buffer_[fixed_jump_destination]; + DCHECK_GT(jump_bc, 0); + DCHECK_LT(jump_bc, kRegExpBytecodeCount); +#endif + + if (jump_destination != fixed_jump_destination) { + OverwriteValue<uint32_t>(jump_source, fixed_jump_destination); + } +} + +void RegExpBytecodePeephole::AddSentinelFixups(int pos) { + jump_source_fixups_.emplace(pos, 0); + jump_destination_fixups_.emplace(pos, 0); +} + +template <typename T> +void RegExpBytecodePeephole::EmitValue(T value) { + DCHECK(optimized_bytecode_buffer_.begin() + pc() == + optimized_bytecode_buffer_.end()); + byte* value_byte_iter = reinterpret_cast<byte*>(&value); + optimized_bytecode_buffer_.insert(optimized_bytecode_buffer_.end(), + value_byte_iter, + value_byte_iter + sizeof(T)); +} + +template <typename T> +void RegExpBytecodePeephole::OverwriteValue(int offset, T value) { + byte* value_byte_iter = reinterpret_cast<byte*>(&value); + byte* value_byte_iter_end = value_byte_iter + sizeof(T); + while (value_byte_iter < value_byte_iter_end) { + optimized_bytecode_buffer_[offset++] = *value_byte_iter++; + } +} + +void RegExpBytecodePeephole::CopyRangeToOutput(const byte* orig_bytecode, + int start, int length) { + DCHECK(optimized_bytecode_buffer_.begin() + pc() == + optimized_bytecode_buffer_.end()); + optimized_bytecode_buffer_.insert(optimized_bytecode_buffer_.end(), + orig_bytecode + start, + orig_bytecode + start + length); +} + +void RegExpBytecodePeephole::SetRange(byte value, int count) { + DCHECK(optimized_bytecode_buffer_.begin() + pc() == + optimized_bytecode_buffer_.end()); + optimized_bytecode_buffer_.insert(optimized_bytecode_buffer_.end(), count, + value); +} + +void RegExpBytecodePeephole::EmitArgument(int start_pc, const byte* bytecode, + BytecodeArgumentMapping arg) { + int arg_pos = start_pc + arg.offset; + switch (arg.length) { + case 1: + DCHECK_EQ(arg.new_length, arg.length); + EmitValue(GetValue<byte>(bytecode, arg_pos)); + break; + case 2: + DCHECK_EQ(arg.new_length, arg.length); + EmitValue(GetValue<uint16_t>(bytecode, arg_pos)); + break; + case 3: { + // Length 3 only occurs in 'packed' arguments where the lowermost byte is + // the current bytecode, and the remaining 3 bytes are the packed value. + // + // We load 4 bytes from position - 1 and shift out the bytecode. +#ifdef V8_TARGET_BIG_ENDIAN + UNIMPLEMENTED(); + int32_t val = 0; +#else + int32_t val = GetValue<int32_t>(bytecode, arg_pos - 1) >> kBitsPerByte; +#endif // V8_TARGET_BIG_ENDIAN + + switch (arg.new_length) { + case 2: + EmitValue<uint16_t>(val); + break; + case 3: { + // Pack with previously emitted value. + auto prev_val = + GetValue<int32_t>(&(*optimized_bytecode_buffer_.begin()), + Length() - sizeof(uint32_t)); +#ifdef V8_TARGET_BIG_ENDIAN + UNIMPLEMENTED(); + USE(prev_val); +#else + DCHECK_EQ(prev_val & 0xFFFFFF00, 0); + OverwriteValue<uint32_t>( + pc() - sizeof(uint32_t), + (static_cast<uint32_t>(val) << 8) | (prev_val & 0xFF)); +#endif // V8_TARGET_BIG_ENDIAN + break; + } + case 4: + EmitValue<uint32_t>(val); + break; + } + break; + } + case 4: + DCHECK_EQ(arg.new_length, arg.length); + EmitValue(GetValue<uint32_t>(bytecode, arg_pos)); + break; + case 8: + DCHECK_EQ(arg.new_length, arg.length); + EmitValue(GetValue<uint64_t>(bytecode, arg_pos)); + break; + default: + CopyRangeToOutput(bytecode, arg_pos, Min(arg.length, arg.new_length)); + if (arg.length < arg.new_length) { + SetRange(0x00, arg.new_length - arg.length); + } + break; + } +} + +int RegExpBytecodePeephole::pc() const { + DCHECK_LE(optimized_bytecode_buffer_.size(), std::numeric_limits<int>::max()); + return static_cast<int>(optimized_bytecode_buffer_.size()); +} + +Zone* RegExpBytecodePeephole::zone() const { return zone_; } + +} // namespace + +// static +Handle<ByteArray> RegExpBytecodePeepholeOptimization::OptimizeBytecode( + Isolate* isolate, Zone* zone, Handle<String> source, const byte* bytecode, + int length, const ZoneUnorderedMap<int, int>& jump_edges) { + RegExpBytecodePeephole peephole(zone, length, jump_edges); + bool did_optimize = peephole.OptimizeBytecode(bytecode, length); + Handle<ByteArray> array = isolate->factory()->NewByteArray(peephole.Length()); + peephole.CopyOptimizedBytecode(array->GetDataStartAddress()); + + if (did_optimize && FLAG_trace_regexp_peephole_optimization) { + PrintF("Original Bytecode:\n"); + RegExpBytecodeDisassemble(bytecode, length, source->ToCString().get()); + PrintF("Optimized Bytecode:\n"); + RegExpBytecodeDisassemble(array->GetDataStartAddress(), peephole.Length(), + source->ToCString().get()); + } + + return array; +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/regexp/regexp-bytecode-peephole.h b/deps/v8/src/regexp/regexp-bytecode-peephole.h new file mode 100644 index 00000000000000..f116e1ac4184f6 --- /dev/null +++ b/deps/v8/src/regexp/regexp-bytecode-peephole.h @@ -0,0 +1,31 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ +#define V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ + +#include "src/common/globals.h" +#include "src/zone/zone-containers.h" + +namespace v8 { +namespace internal { + +class ByteArray; + +// Peephole optimization for regexp interpreter bytecode. +// Pre-defined bytecode sequences occuring in the bytecode generated by the +// RegExpBytecodeGenerator can be optimized into a single bytecode. +class RegExpBytecodePeepholeOptimization : public AllStatic { + public: + // Performs peephole optimization on the given bytecode and returns the + // optimized bytecode. + static Handle<ByteArray> OptimizeBytecode( + Isolate* isolate, Zone* zone, Handle<String> source, const byte* bytecode, + int length, const ZoneUnorderedMap<int, int>& jump_edges); +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ diff --git a/deps/v8/src/regexp/regexp-bytecodes.cc b/deps/v8/src/regexp/regexp-bytecodes.cc new file mode 100644 index 00000000000000..fbf8273ab4fe2c --- /dev/null +++ b/deps/v8/src/regexp/regexp-bytecodes.cc @@ -0,0 +1,46 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/regexp/regexp-bytecodes.h" + +#include <cctype> + +#include "src/utils/utils.h" + +namespace v8 { +namespace internal { + +void RegExpBytecodeDisassembleSingle(const byte* code_base, const byte* pc) { + PrintF("%s", RegExpBytecodeName(*pc)); + + // Args and the bytecode as hex. + for (int i = 0; i < RegExpBytecodeLength(*pc); i++) { + PrintF(", %02x", pc[i]); + } + PrintF(" "); + + // Args as ascii. + for (int i = 1; i < RegExpBytecodeLength(*pc); i++) { + unsigned char b = pc[i]; + PrintF("%c", std::isprint(b) ? b : '.'); + } + PrintF("\n"); +} + +void RegExpBytecodeDisassemble(const byte* code_base, int length, + const char* pattern) { + PrintF("[generated bytecode for regexp pattern: '%s']\n", pattern); + + ptrdiff_t offset = 0; + + while (offset < length) { + const byte* const pc = code_base + offset; + PrintF("%p %4" V8PRIxPTRDIFF " ", pc, offset); + RegExpBytecodeDisassembleSingle(code_base, pc); + offset += RegExpBytecodeLength(*pc); + } +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/regexp/regexp-bytecodes.h b/deps/v8/src/regexp/regexp-bytecodes.h index 3dd7637b88c402..e25945d0a03dd1 100644 --- a/deps/v8/src/regexp/regexp-bytecodes.h +++ b/deps/v8/src/regexp/regexp-bytecodes.h @@ -6,17 +6,27 @@ #define V8_REGEXP_REGEXP_BYTECODES_H_ #include "src/base/macros.h" +#include "src/common/globals.h" namespace v8 { namespace internal { -const int BYTECODE_MASK = 0xff; +// Maximum number of bytecodes that will be used (next power of 2 of actually +// defined bytecodes). +// All slots between the last actually defined bytecode and maximum id will be +// filled with BREAKs, indicating an invalid operation. This way using +// BYTECODE_MASK guarantees no OOB access to the dispatch table. +constexpr int kRegExpPaddedBytecodeCount = 1 << 6; +constexpr int BYTECODE_MASK = kRegExpPaddedBytecodeCount - 1; // The first argument is packed in with the byte code in one word, but so it // has 24 bits, but it can be positive and negative so only use 23 bits for // positive values. const unsigned int MAX_FIRST_ARG = 0x7fffffu; const int BYTECODE_SHIFT = 8; +STATIC_ASSERT(1 << BYTECODE_SHIFT > BYTECODE_MASK); +// TODO(pthier): Argument offsets of bytecodes should be easily accessible by +// name or at least by position. #define BYTECODE_ITERATOR(V) \ V(BREAK, 0, 4) /* bc8 */ \ V(PUSH_CP, 1, 4) /* bc8 pad24 */ \ @@ -34,25 +44,61 @@ const int BYTECODE_SHIFT = 8; V(FAIL, 13, 4) /* bc8 pad24 */ \ V(SUCCEED, 14, 4) /* bc8 pad24 */ \ V(ADVANCE_CP, 15, 4) /* bc8 offset24 */ \ - V(GOTO, 16, 8) /* bc8 pad24 addr32 */ \ + /* Jump to another bytecode given its offset. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x10 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: 0x00 (unused) Padding */ \ + /* 0x20 - 0x3F: Address of bytecode to jump to */ \ + V(GOTO, 16, 8) /* bc8 pad24 addr32 */ \ + /* Check if offset is in range and load character at given offset. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x11 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: Offset from current position */ \ + /* 0x20 - 0x3F: Address of bytecode when load is out of range */ \ V(LOAD_CURRENT_CHAR, 17, 8) /* bc8 offset24 addr32 */ \ + /* Load character at given offset without range checks. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x12 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: Offset from current position */ \ V(LOAD_CURRENT_CHAR_UNCHECKED, 18, 4) /* bc8 offset24 */ \ V(LOAD_2_CURRENT_CHARS, 19, 8) /* bc8 offset24 addr32 */ \ V(LOAD_2_CURRENT_CHARS_UNCHECKED, 20, 4) /* bc8 offset24 */ \ V(LOAD_4_CURRENT_CHARS, 21, 8) /* bc8 offset24 addr32 */ \ V(LOAD_4_CURRENT_CHARS_UNCHECKED, 22, 4) /* bc8 offset24 */ \ V(CHECK_4_CHARS, 23, 12) /* bc8 pad24 uint32 addr32 */ \ - V(CHECK_CHAR, 24, 8) /* bc8 pad8 uint16 addr32 */ \ + /* Check if current character is equal to a given character */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x19 (fixed) Bytecode */ \ + /* 0x08 - 0x0F: 0x00 (unused) Padding */ \ + /* 0x10 - 0x1F: Character to check */ \ + /* 0x20 - 0x3F: Address of bytecode when matched */ \ + V(CHECK_CHAR, 24, 8) /* bc8 pad8 uint16 addr32 */ \ V(CHECK_NOT_4_CHARS, 25, 12) /* bc8 pad24 uint32 addr32 */ \ V(CHECK_NOT_CHAR, 26, 8) /* bc8 pad8 uint16 addr32 */ \ V(AND_CHECK_4_CHARS, 27, 16) /* bc8 pad24 uint32 uint32 addr32 */ \ - V(AND_CHECK_CHAR, 28, 12) /* bc8 pad8 uint16 uint32 addr32 */ \ + /* Checks if the current character combined with mask (bitwise and) */ \ + /* matches a character (e.g. used when two characters in a disjunction */ \ + /* differ by only a single bit */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x1c (fixed) Bytecode */ \ + /* 0x08 - 0x0F: 0x00 (unused) Padding */ \ + /* 0x10 - 0x1F: Character to match against (after mask aplied) */ \ + /* 0x20 - 0x3F: Bitmask bitwise and combined with current character */ \ + /* 0x40 - 0x5F: Address of bytecode when matched */ \ + V(AND_CHECK_CHAR, 28, 12) /* bc8 pad8 uint16 uint32 addr32 */ \ V(AND_CHECK_NOT_4_CHARS, 29, 16) /* bc8 pad24 uint32 uint32 addr32 */ \ V(AND_CHECK_NOT_CHAR, 30, 12) /* bc8 pad8 uint16 uint32 addr32 */ \ V(MINUS_AND_CHECK_NOT_CHAR, 31, 12) /* bc8 pad8 uc16 uc16 uc16 addr32 */ \ V(CHECK_CHAR_IN_RANGE, 32, 12) /* bc8 pad24 uc16 uc16 addr32 */ \ V(CHECK_CHAR_NOT_IN_RANGE, 33, 12) /* bc8 pad24 uc16 uc16 addr32 */ \ - V(CHECK_BIT_IN_TABLE, 34, 24) /* bc8 pad24 addr32 bits128 */ \ + /* Checks if the current character matches any of the characters encoded */ \ + /* in a bit table. Similar to/inspired by boyer moore string search */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x22 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: 0x00 (unused) Padding */ \ + /* 0x20 - 0x3F: Address of bytecode when bit is set */ \ + /* 0x40 - 0xBF: Bit table */ \ + V(CHECK_BIT_IN_TABLE, 34, 24) /* bc8 pad24 addr32 bits128 */ \ V(CHECK_LT, 35, 8) /* bc8 pad8 uc16 addr32 */ \ V(CHECK_GT, 36, 8) /* bc8 pad8 uc16 addr32 */ \ V(CHECK_NOT_BACK_REF, 37, 8) /* bc8 reg_idx24 addr32 */ \ @@ -67,10 +113,99 @@ const int BYTECODE_SHIFT = 8; V(CHECK_REGISTER_EQ_POS, 46, 8) /* bc8 reg_idx24 addr32 */ \ V(CHECK_AT_START, 47, 8) /* bc8 pad24 addr32 */ \ V(CHECK_NOT_AT_START, 48, 8) /* bc8 offset24 addr32 */ \ + /* Checks if the current position matches top of backtrack stack */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x31 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: 0x00 (unused) Padding */ \ + /* 0x20 - 0x3F: Address of bytecode when current matches tos */ \ V(CHECK_GREEDY, 49, 8) /* bc8 pad24 addr32 */ \ - V(ADVANCE_CP_AND_GOTO, 50, 8) /* bc8 offset24 addr32 */ \ + /* Advance character pointer by given offset and jump to another bytecode.*/ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x32 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: Number of characters to advance */ \ + /* 0x20 - 0x3F: Address of bytecode to jump to */ \ + V(ADVANCE_CP_AND_GOTO, 50, 8) /* bc8 offset24 addr32 */ \ V(SET_CURRENT_POSITION_FROM_END, 51, 4) /* bc8 idx24 */ \ - V(CHECK_CURRENT_POSITION, 52, 8) /* bc8 idx24 addr32 */ + /* Checks if current position + given offset is in range. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07: 0x34 (fixed) Bytecode */ \ + /* 0x08 - 0x1F: Offset from current position */ \ + /* 0x20 - 0x3F: Address of bytecode when position is out of range */ \ + V(CHECK_CURRENT_POSITION, 52, 8) /* bc8 idx24 addr32 */ \ + /* Combination of: */ \ + /* LOAD_CURRENT_CHAR, CHECK_BIT_IN_TABLE and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x35 (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x3F Number of characters to advance */ \ + /* 0x40 - 0xBF Bit Table */ \ + /* 0xC0 - 0xDF Address of bytecode when character is matched */ \ + /* 0xE0 - 0xFF Address of bytecode when no match */ \ + V(SKIP_UNTIL_BIT_IN_TABLE, 53, 32) \ + /* Combination of: */ \ + /* CHECK_CURRENT_POSITION, LOAD_CURRENT_CHAR_UNCHECKED, AND_CHECK_CHAR */ \ + /* and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x36 (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x2F Number of characters to advance */ \ + /* 0x30 - 0x3F Character to match against (after mask applied) */ \ + /* 0x40 - 0x5F: Bitmask bitwise and combined with current character */ \ + /* 0x60 - 0x7F Minimum number of characters this pattern consumes */ \ + /* 0x80 - 0x9F Address of bytecode when character is matched */ \ + /* 0xA0 - 0xBF Address of bytecode when no match */ \ + V(SKIP_UNTIL_CHAR_AND, 54, 24) \ + /* Combination of: */ \ + /* LOAD_CURRENT_CHAR, CHECK_CHAR and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x37 (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x2F Number of characters to advance */ \ + /* 0x30 - 0x3F Character to match */ \ + /* 0x40 - 0x5F Address of bytecode when character is matched */ \ + /* 0x60 - 0x7F Address of bytecode when no match */ \ + V(SKIP_UNTIL_CHAR, 55, 16) \ + /* Combination of: */ \ + /* CHECK_CURRENT_POSITION, LOAD_CURRENT_CHAR_UNCHECKED, CHECK_CHAR */ \ + /* and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x38 (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x2F Number of characters to advance */ \ + /* 0x30 - 0x3F Character to match */ \ + /* 0x40 - 0x5F Minimum number of characters this pattern consumes */ \ + /* 0x60 - 0x7F Address of bytecode when character is matched */ \ + /* 0x80 - 0x9F Address of bytecode when no match */ \ + V(SKIP_UNTIL_CHAR_POS_CHECKED, 56, 20) \ + /* Combination of: */ \ + /* LOAD_CURRENT_CHAR, CHECK_CHAR, CHECK_CHAR and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x39 (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x3F Number of characters to advance */ \ + /* 0x40 - 0x4F Character to match */ \ + /* 0x50 - 0x5F Other Character to match */ \ + /* 0x60 - 0x7F Address of bytecode when either character is matched */ \ + /* 0x80 - 0x9F Address of bytecode when no match */ \ + V(SKIP_UNTIL_CHAR_OR_CHAR, 57, 20) \ + /* Combination of: */ \ + /* LOAD_CURRENT_CHAR, CHECK_GT, CHECK_BIT_IN_TABLE, GOTO and */ \ + /* and ADVANCE_CP_AND_GOTO */ \ + /* Emitted by RegExpBytecodePeepholeOptimization. */ \ + /* Bit Layout: */ \ + /* 0x00 - 0x07 0x3A (fixed) Bytecode */ \ + /* 0x08 - 0x1F Load character offset from current position */ \ + /* 0x20 - 0x2F Number of characters to advance */ \ + /* 0x30 - 0x3F Character to check if it is less than current char */ \ + /* 0x40 - 0xBF Bit Table */ \ + /* 0xC0 - 0xDF Address of bytecode when character is matched */ \ + /* 0xE0 - 0xFF Address of bytecode when no match */ \ + V(SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE, 58, 32) #define COUNT(...) +1 static constexpr int kRegExpBytecodeCount = BYTECODE_ITERATOR(COUNT); @@ -80,7 +215,7 @@ static constexpr int kRegExpBytecodeCount = BYTECODE_ITERATOR(COUNT); // contiguous, strictly increasing, and start at 0. // TODO(jgruber): Do not explicitly assign values, instead generate them // implicitly from the list order. -STATIC_ASSERT(kRegExpBytecodeCount == 53); +STATIC_ASSERT(kRegExpBytecodeCount == 59); #define DECLARE_BYTECODES(name, code, length) \ static constexpr int BC_##name = code; @@ -107,6 +242,10 @@ inline const char* RegExpBytecodeName(int bytecode) { return kRegExpBytecodeNames[bytecode]; } +void RegExpBytecodeDisassembleSingle(const byte* code_base, const byte* pc); +void RegExpBytecodeDisassemble(const byte* code_base, int length, + const char* pattern); + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/regexp/regexp-compiler.cc b/deps/v8/src/regexp/regexp-compiler.cc index 85da69f308bb67..d141f3c490de83 100644 --- a/deps/v8/src/regexp/regexp-compiler.cc +++ b/deps/v8/src/regexp/regexp-compiler.cc @@ -725,6 +725,11 @@ static int GetCaseIndependentLetters(Isolate* isolate, uc16 character, unibrow::uchar* letters, int letter_length) { #ifdef V8_INTL_SUPPORT + // Special case for U+017F which has upper case in ASCII range. + if (character == 0x017f) { + letters[0] = character; + return 1; + } icu::UnicodeSet set; set.add(character); set = set.closeOver(USET_CASE_INSENSITIVE); @@ -734,10 +739,18 @@ static int GetCaseIndependentLetters(Isolate* isolate, uc16 character, UChar32 start = set.getRangeStart(i); UChar32 end = set.getRangeEnd(i); CHECK(end - start + items <= letter_length); - while (start <= end) { - if (one_byte_subject && start > String::kMaxOneByteCharCode) break; - letters[items++] = (unibrow::uchar)(start); - start++; + // Only add to the output if character is not in ASCII range + // or the case equivalent character is in ASCII range. + // #sec-runtime-semantics-canonicalize-ch + // 3.g If the numeric value of ch ≥ 128 and the numeric value of cu < 128, + // return ch. + if (!((start >= 128) && (character < 128))) { + // No range have start and end span across code point 128. + DCHECK((start >= 128) == (end >= 128)); + for (UChar32 cu = start; cu <= end; cu++) { + if (one_byte_subject && cu > String::kMaxOneByteCharCode) break; + letters[items++] = (unibrow::uchar)(cu); + } } } return items; diff --git a/deps/v8/src/regexp/regexp-interpreter.cc b/deps/v8/src/regexp/regexp-interpreter.cc index cf2fb55e4a861c..df72951afbbc51 100644 --- a/deps/v8/src/regexp/regexp-interpreter.cc +++ b/deps/v8/src/regexp/regexp-interpreter.cc @@ -12,6 +12,7 @@ #include "src/objects/objects-inl.h" #include "src/regexp/regexp-bytecodes.h" #include "src/regexp/regexp-macro-assembler.h" +#include "src/regexp/regexp-stack.h" // For kMaximumStackSize. #include "src/regexp/regexp.h" #include "src/strings/unicode.h" #include "src/utils/utils.h" @@ -63,23 +64,6 @@ bool BackRefMatchesNoCase(Isolate* isolate, int from, int current, int len, return true; } -void DisassembleSingleBytecode(const byte* code_base, const byte* pc) { - PrintF("%s", RegExpBytecodeName(*pc)); - - // Args and the bytecode as hex. - for (int i = 0; i < RegExpBytecodeLength(*pc); i++) { - PrintF(", %02x", pc[i]); - } - PrintF(" "); - - // Args as ascii. - for (int i = 1; i < RegExpBytecodeLength(*pc); i++) { - unsigned char b = pc[i]; - PrintF("%c", std::isprint(b) ? b : '.'); - } - PrintF("\n"); -} - #ifdef DEBUG void MaybeTraceInterpreter(const byte* code_base, const byte* pc, int stack_depth, int current_position, @@ -94,7 +78,7 @@ void MaybeTraceInterpreter(const byte* code_base, const byte* pc, PrintF(format, pc - code_base, stack_depth, current_position, current_char, printable ? current_char : '.'); - DisassembleSingleBytecode(code_base, pc); + RegExpBytecodeDisassembleSingle(code_base, pc); } } #endif // DEBUG @@ -118,7 +102,10 @@ class BacktrackStack { public: BacktrackStack() = default; - void push(int v) { data_.emplace_back(v); } + V8_WARN_UNUSED_RESULT bool push(int v) { + data_.emplace_back(v); + return (static_cast<int>(data_.size()) <= kMaxSize); + } int peek() const { DCHECK(!data_.empty()); return data_.back(); @@ -141,13 +128,17 @@ class BacktrackStack { // static stack-allocated backing store, but small enough not to waste space. static constexpr int kStaticCapacity = 64; - base::SmallVector<int, kStaticCapacity> data_; + using ValueT = int; + base::SmallVector<ValueT, kStaticCapacity> data_; + + static constexpr int kMaxSize = + RegExpStack::kMaximumStackSize / sizeof(ValueT); DISALLOW_COPY_AND_ASSIGN(BacktrackStack); }; -IrregexpInterpreter::Result StackOverflow(Isolate* isolate, - RegExp::CallOrigin call_origin) { +IrregexpInterpreter::Result ThrowStackOverflow(Isolate* isolate, + RegExp::CallOrigin call_origin) { CHECK(call_origin == RegExp::CallOrigin::kFromRuntime); // We abort interpreter execution after the stack overflow is thrown, and thus // allow allocation here despite the outer DisallowHeapAllocationScope. @@ -156,6 +147,17 @@ IrregexpInterpreter::Result StackOverflow(Isolate* isolate, return IrregexpInterpreter::EXCEPTION; } +// Only throws if called from the runtime, otherwise just returns the EXCEPTION +// status code. +IrregexpInterpreter::Result MaybeThrowStackOverflow( + Isolate* isolate, RegExp::CallOrigin call_origin) { + if (call_origin == RegExp::CallOrigin::kFromRuntime) { + return ThrowStackOverflow(isolate, call_origin); + } else { + return IrregexpInterpreter::EXCEPTION; + } +} + template <typename Char> void UpdateCodeAndSubjectReferences( Isolate* isolate, Handle<ByteArray> code_array, @@ -208,7 +210,7 @@ IrregexpInterpreter::Result HandleInterrupts( Handle<String> subject_handle(*subject_string_out, isolate); if (js_has_overflowed) { - return StackOverflow(isolate, call_origin); + return ThrowStackOverflow(isolate, call_origin); } else if (check.InterruptRequested()) { const bool was_one_byte = String::IsOneByteRepresentationUnderneath(*subject_string_out); @@ -238,6 +240,13 @@ IrregexpInterpreter::Result HandleInterrupts( return IrregexpInterpreter::SUCCESS; } +bool CheckBitInTable(const uint32_t current_char, const byte* const table) { + int mask = RegExpMacroAssembler::kTableMask; + int b = table[(current_char & mask) >> kBitsPerByteLog2]; + int bit = (current_char & (kBitsPerByte - 1)); + return (b & (1 << bit)) != 0; +} + // If computed gotos are supported by the compiler, we can get addresses to // labels directly in C/C++. Every bytecode handler has its own label and we // store the addresses in a dispatch table indexed by bytecode. To execute the @@ -262,7 +271,7 @@ IrregexpInterpreter::Result HandleInterrupts( #define DISPATCH() \ pc = next_pc; \ insn = next_insn; \ - break + goto switch_dispatch_continuation #endif // V8_USE_COMPUTED_GOTO // ADVANCE/SET_PC_FROM_OFFSET are separated from DISPATCH, because ideally some @@ -297,11 +306,52 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, DisallowHeapAllocation no_gc; #if V8_USE_COMPUTED_GOTO -#define DECLARE_DISPATCH_TABLE_ENTRY(name, code, length) &&BC_##name, - static const void* const dispatch_table[] = { - BYTECODE_ITERATOR(DECLARE_DISPATCH_TABLE_ENTRY)}; + +// We have to make sure that no OOB access to the dispatch table is possible and +// all values are valid label addresses. +// Otherwise jumps to arbitrary addresses could potentially happen. +// This is ensured as follows: +// Every index to the dispatch table gets masked using BYTECODE_MASK in +// DECODE(). This way we can only get values between 0 (only the least +// significant byte of an integer is used) and kRegExpPaddedBytecodeCount - 1 +// (BYTECODE_MASK is defined to be exactly this value). +// All entries from kRegExpBytecodeCount to kRegExpPaddedBytecodeCount have to +// be filled with BREAKs (invalid operation). + +// Fill dispatch table from last defined bytecode up to the next power of two +// with BREAK (invalid operation). +// TODO(pthier): Find a way to fill up automatically (at compile time) +// 59 real bytecodes -> 5 fillers +#define BYTECODE_FILLER_ITERATOR(V) \ + V(BREAK) /* 1 */ \ + V(BREAK) /* 2 */ \ + V(BREAK) /* 3 */ \ + V(BREAK) /* 4 */ \ + V(BREAK) /* 5 */ + +#define COUNT(...) +1 + static constexpr int kRegExpBytecodeFillerCount = + BYTECODE_FILLER_ITERATOR(COUNT); +#undef COUNT + + // Make sure kRegExpPaddedBytecodeCount is actually the closest possible power + // of two. + DCHECK_EQ(kRegExpPaddedBytecodeCount, + base::bits::RoundUpToPowerOfTwo32(kRegExpBytecodeCount)); + + // Make sure every bytecode we get by using BYTECODE_MASK is well defined. + STATIC_ASSERT(kRegExpBytecodeCount <= kRegExpPaddedBytecodeCount); + STATIC_ASSERT(kRegExpBytecodeCount + kRegExpBytecodeFillerCount == + kRegExpPaddedBytecodeCount); + +#define DECLARE_DISPATCH_TABLE_ENTRY(name, ...) &&BC_##name, + static const void* const dispatch_table[kRegExpPaddedBytecodeCount] = { + BYTECODE_ITERATOR(DECLARE_DISPATCH_TABLE_ENTRY) + BYTECODE_FILLER_ITERATOR(DECLARE_DISPATCH_TABLE_ENTRY)}; #undef DECLARE_DISPATCH_TABLE_ENTRY -#endif +#undef BYTECODE_FILLER_ITERATOR + +#endif // V8_USE_COMPUTED_GOTO const byte* pc = code_array.GetDataStartAddress(); const byte* code_base = pc; @@ -329,17 +379,23 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, BYTECODE(BREAK) { UNREACHABLE(); } BYTECODE(PUSH_CP) { ADVANCE(PUSH_CP); - backtrack_stack.push(current); + if (!backtrack_stack.push(current)) { + return MaybeThrowStackOverflow(isolate, call_origin); + } DISPATCH(); } BYTECODE(PUSH_BT) { ADVANCE(PUSH_BT); - backtrack_stack.push(Load32Aligned(pc + 4)); + if (!backtrack_stack.push(Load32Aligned(pc + 4))) { + return MaybeThrowStackOverflow(isolate, call_origin); + } DISPATCH(); } BYTECODE(PUSH_REGISTER) { ADVANCE(PUSH_REGISTER); - backtrack_stack.push(registers[insn >> BYTECODE_SHIFT]); + if (!backtrack_stack.push(registers[insn >> BYTECODE_SHIFT])) { + return MaybeThrowStackOverflow(isolate, call_origin); + } DISPATCH(); } BYTECODE(SET_REGISTER) { @@ -580,10 +636,7 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, DISPATCH(); } BYTECODE(CHECK_BIT_IN_TABLE) { - int mask = RegExpMacroAssembler::kTableMask; - byte b = pc[8 + ((current_char & mask) >> kBitsPerByteLog2)]; - int bit = (current_char & (kBitsPerByte - 1)); - if ((b & (1 << bit)) != 0) { + if (CheckBitInTable(current_char, pc + 8)) { SET_PC_FROM_OFFSET(Load32Aligned(pc + 4)); } else { ADVANCE(CHECK_BIT_IN_TABLE); @@ -762,6 +815,118 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, } DISPATCH(); } + BYTECODE(SKIP_UNTIL_CHAR) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint32_t advance = Load16Aligned(pc + 4); + uint32_t c = Load16Aligned(pc + 6); + while (static_cast<uintptr_t>(current + load_offset) < + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + if (c == current_char) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 8)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 12)); + DISPATCH(); + } + BYTECODE(SKIP_UNTIL_CHAR_AND) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint16_t advance = Load16Aligned(pc + 4); + uint16_t c = Load16Aligned(pc + 6); + uint32_t mask = Load32Aligned(pc + 8); + int32_t maximum_offset = Load32Aligned(pc + 12); + while (static_cast<uintptr_t>(current + maximum_offset) <= + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + if (c == (current_char & mask)) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 16)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 20)); + DISPATCH(); + } + BYTECODE(SKIP_UNTIL_CHAR_POS_CHECKED) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint16_t advance = Load16Aligned(pc + 4); + uint16_t c = Load16Aligned(pc + 6); + int32_t maximum_offset = Load32Aligned(pc + 8); + while (static_cast<uintptr_t>(current + maximum_offset) <= + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + if (c == current_char) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 12)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 16)); + DISPATCH(); + } + BYTECODE(SKIP_UNTIL_BIT_IN_TABLE) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint32_t advance = Load16Aligned(pc + 4); + const byte* table = pc + 8; + while (static_cast<uintptr_t>(current + load_offset) < + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + if (CheckBitInTable(current_char, table)) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 24)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 28)); + DISPATCH(); + } + BYTECODE(SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint16_t advance = Load16Aligned(pc + 4); + uint16_t limit = Load16Aligned(pc + 6); + const byte* table = pc + 8; + while (static_cast<uintptr_t>(current + load_offset) < + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + if (current_char > limit) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 24)); + DISPATCH(); + } + if (!CheckBitInTable(current_char, table)) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 24)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 28)); + DISPATCH(); + } + BYTECODE(SKIP_UNTIL_CHAR_OR_CHAR) { + int load_offset = (insn >> BYTECODE_SHIFT); + uint32_t advance = Load32Aligned(pc + 4); + uint16_t c = Load16Aligned(pc + 8); + uint16_t c2 = Load16Aligned(pc + 10); + while (static_cast<uintptr_t>(current + load_offset) < + static_cast<uintptr_t>(subject.length())) { + current_char = subject[current + load_offset]; + // The two if-statements below are split up intentionally, as combining + // them seems to result in register allocation behaving quite + // differently and slowing down the resulting code. + if (c == current_char) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 12)); + DISPATCH(); + } + if (c2 == current_char) { + SET_PC_FROM_OFFSET(Load32Aligned(pc + 12)); + DISPATCH(); + } + current += advance; + } + SET_PC_FROM_OFFSET(Load32Aligned(pc + 16)); + DISPATCH(); + } #if V8_USE_COMPUTED_GOTO // Lint gets confused a lot if we just use !V8_USE_COMPUTED_GOTO or ifndef // V8_USE_COMPUTED_GOTO here. @@ -769,6 +934,9 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, default: UNREACHABLE(); } + // Label we jump to in DISPATCH(). There must be no instructions between the + // end of the switch, this label and the end of the loop. + switch_dispatch_continuation : {} #endif // V8_USE_COMPUTED_GOTO } } @@ -783,31 +951,12 @@ IrregexpInterpreter::Result RawMatch(Isolate* isolate, ByteArray code_array, } // namespace -// static -void IrregexpInterpreter::Disassemble(ByteArray byte_array, - const std::string& pattern) { - DisallowHeapAllocation no_gc; - - PrintF("[generated bytecode for regexp pattern: '%s']\n", pattern.c_str()); - - const byte* const code_base = byte_array.GetDataStartAddress(); - const int byte_array_length = byte_array.length(); - ptrdiff_t offset = 0; - - while (offset < byte_array_length) { - const byte* const pc = code_base + offset; - PrintF("%p %4" V8PRIxPTRDIFF " ", pc, offset); - DisassembleSingleBytecode(code_base, pc); - offset += RegExpBytecodeLength(*pc); - } -} - // static IrregexpInterpreter::Result IrregexpInterpreter::Match( Isolate* isolate, JSRegExp regexp, String subject_string, int* registers, int registers_length, int start_position, RegExp::CallOrigin call_origin) { if (FLAG_regexp_tier_up) { - regexp.MarkTierUpForNextExec(); + regexp.TierUpTick(); } bool is_one_byte = String::IsOneByteRepresentationUnderneath(subject_string); @@ -869,6 +1018,12 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromJs( String subject_string = String::cast(Object(subject)); JSRegExp regexp_obj = JSRegExp::cast(Object(regexp)); + if (regexp_obj.MarkedForTierUp()) { + // Returning RETRY will re-enter through runtime, where actual recompilation + // for tier-up takes place. + return IrregexpInterpreter::RETRY; + } + return Match(isolate, regexp_obj, subject_string, registers, registers_length, start_position, call_origin); } diff --git a/deps/v8/src/regexp/regexp-interpreter.h b/deps/v8/src/regexp/regexp-interpreter.h index fbc5a3b29069df..2d0b74f1360f29 100644 --- a/deps/v8/src/regexp/regexp-interpreter.h +++ b/deps/v8/src/regexp/regexp-interpreter.h @@ -31,6 +31,8 @@ class V8_EXPORT_PRIVATE IrregexpInterpreter : public AllStatic { // In case a StackOverflow occurs, EXCEPTION is returned. The caller is // responsible for creating the exception. + // RETRY is returned if a retry through the runtime is needed (e.g. when + // interrupts have been scheduled or the regexp is marked for tier-up). // Arguments input_start, input_end and backtrack_stack are // unused. They are only passed to match the signature of the native irregex // code. @@ -46,8 +48,6 @@ class V8_EXPORT_PRIVATE IrregexpInterpreter : public AllStatic { int registers_length, int start_position, RegExp::CallOrigin call_origin); - static void Disassemble(ByteArray byte_array, const std::string& pattern); - private: static Result Match(Isolate* isolate, JSRegExp regexp, String subject_string, int* registers, int registers_length, int start_position, diff --git a/deps/v8/src/regexp/regexp-macro-assembler.cc b/deps/v8/src/regexp/regexp-macro-assembler.cc index 96fb53d2a0464c..30a9955dc38983 100644 --- a/deps/v8/src/regexp/regexp-macro-assembler.cc +++ b/deps/v8/src/regexp/regexp-macro-assembler.cc @@ -289,9 +289,9 @@ int NativeRegExpMacroAssembler::Execute( Address regexp); auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(code); - int result = fn.CallIrregexp(input.ptr(), start_offset, input_start, - input_end, output, output_size, stack_base, - call_origin, isolate, regexp.ptr()); + int result = + fn.Call(input.ptr(), start_offset, input_start, input_end, output, + output_size, stack_base, call_origin, isolate, regexp.ptr()); DCHECK(result >= RETRY); if (result == EXCEPTION && !isolate->has_pending_exception()) { diff --git a/deps/v8/src/regexp/regexp-parser.cc b/deps/v8/src/regexp/regexp-parser.cc index ec1beca84b7b4f..951f81537474fb 100644 --- a/deps/v8/src/regexp/regexp-parser.cc +++ b/deps/v8/src/regexp/regexp-parser.cc @@ -84,6 +84,9 @@ void RegExpParser::Advance() { ReportError(CStrVector( MessageFormatter::TemplateString(MessageTemplate::kStackOverflow))); } else if (zone()->excess_allocation()) { + if (FLAG_correctness_fuzzer_suppressions) { + FATAL("Aborting on excess zone allocation"); + } ReportError(CStrVector("Regular expression too large")); } else { current_ = ReadNext<true>(); diff --git a/deps/v8/src/regexp/regexp-stack.h b/deps/v8/src/regexp/regexp-stack.h index 7ecaa40b819dbb..d3c5415f1f3cd5 100644 --- a/deps/v8/src/regexp/regexp-stack.h +++ b/deps/v8/src/regexp/regexp-stack.h @@ -73,6 +73,9 @@ class RegExpStack { char* RestoreStack(char* from); void FreeThreadResources() { thread_local_.Free(); } + // Maximal size of allocated stack area. + static constexpr size_t kMaximumStackSize = 64 * MB; + private: RegExpStack(); ~RegExpStack(); @@ -84,9 +87,6 @@ class RegExpStack { // Minimal size of allocated stack area. static const size_t kMinimumStackSize = 1 * KB; - // Maximal size of allocated stack area. - static const size_t kMaximumStackSize = 64 * MB; - // Structure holding the allocated memory, size and limit. struct ThreadLocal { ThreadLocal() { Clear(); } diff --git a/deps/v8/src/regexp/regexp-utils.cc b/deps/v8/src/regexp/regexp-utils.cc index c9194d5170c675..73c2015dd91347 100644 --- a/deps/v8/src/regexp/regexp-utils.cc +++ b/deps/v8/src/regexp/regexp-utils.cc @@ -171,12 +171,11 @@ bool RegExpUtils::IsUnmodifiedRegExp(Isolate* isolate, Handle<Object> obj) { // Check that the "exec" method is unmodified. // Check that the index refers to "exec" method (this has to be consistent // with the init order in the bootstrapper). + InternalIndex kExecIndex(JSRegExp::kExecFunctionDescriptorIndex); DCHECK_EQ(*(isolate->factory()->exec_string()), - proto_map.instance_descriptors().GetKey( - JSRegExp::kExecFunctionDescriptorIndex)); - if (proto_map.instance_descriptors() - .GetDetails(JSRegExp::kExecFunctionDescriptorIndex) - .constness() != PropertyConstness::kConst) { + proto_map.instance_descriptors().GetKey(kExecIndex)); + if (proto_map.instance_descriptors().GetDetails(kExecIndex).constness() != + PropertyConstness::kConst) { return false; } diff --git a/deps/v8/src/regexp/regexp.cc b/deps/v8/src/regexp/regexp.cc index e0bc4b8e32347a..a4ab48ed0ed5be 100644 --- a/deps/v8/src/regexp/regexp.cc +++ b/deps/v8/src/regexp/regexp.cc @@ -9,6 +9,7 @@ #include "src/heap/heap-inl.h" #include "src/objects/js-regexp-inl.h" #include "src/regexp/regexp-bytecode-generator.h" +#include "src/regexp/regexp-bytecodes.h" #include "src/regexp/regexp-compiler.h" #include "src/regexp/regexp-dotprinter.h" #include "src/regexp/regexp-interpreter.h" @@ -574,7 +575,7 @@ int RegExpImpl::IrregexpExecRaw(Isolate* isolate, Handle<JSRegExp> regexp, // match. // We need to reset the tier up to start over with compilation. if (FLAG_regexp_tier_up) { - regexp->ResetTierUp(); + regexp->ResetLastTierUpTick(); } is_one_byte = String::IsOneByteRepresentationUnderneath(*subject); EnsureCompiledIrregexp(isolate, regexp, subject, is_one_byte); @@ -600,6 +601,20 @@ MaybeHandle<Object> RegExpImpl::IrregexpExec( } #endif + // For very long subject strings, the regexp interpreter is currently much + // slower than the jitted code execution. If the tier-up strategy is turned + // on, we want to avoid this performance penalty so we eagerly tier-up if the + // subject string length is equal or greater than the given heuristic value. + if (FLAG_regexp_tier_up && + subject->length() >= JSRegExp::kTierUpForSubjectLengthValue) { + regexp->MarkTierUpForNextExec(); + if (FLAG_trace_regexp_tier_up) { + PrintF( + "Forcing tier-up for very long strings in " + "RegExpImpl::IrregexpExec\n"); + } + } + // Prepare space for the return values. int required_registers = RegExp::IrregexpPrepare(isolate, regexp, subject); if (required_registers < 0) { @@ -860,14 +875,15 @@ bool RegExpImpl::Compile(Isolate* isolate, Zone* zone, RegExpCompileData* data, OFStream os(trace_scope.file()); Handle<Code> c(Code::cast(result.code), isolate); auto pattern_cstring = pattern->ToCString(); - c->Disassemble(pattern_cstring.get(), os); + c->Disassemble(pattern_cstring.get(), os, isolate); } #endif if (FLAG_print_regexp_bytecode && data->compilation_target == RegExpCompilationTarget::kBytecode) { Handle<ByteArray> bytecode(ByteArray::cast(result.code), isolate); auto pattern_cstring = pattern->ToCString(); - IrregexpInterpreter::Disassemble(*bytecode, pattern_cstring.get()); + RegExpBytecodeDisassemble(bytecode->GetDataStartAddress(), + bytecode->length(), pattern_cstring.get()); } } diff --git a/deps/v8/src/regexp/regexp.h b/deps/v8/src/regexp/regexp.h index 8ccc9789a30ab4..6625b063bcf320 100644 --- a/deps/v8/src/regexp/regexp.h +++ b/deps/v8/src/regexp/regexp.h @@ -55,10 +55,7 @@ struct RegExpCompileData { class RegExp final : public AllStatic { public: - // Whether the irregexp engine generates native code or interpreter bytecode. - static bool CanGenerateNativeCode() { - return !FLAG_regexp_interpret_all || FLAG_regexp_tier_up; - } + // Whether the irregexp engine generates interpreter bytecode. static bool CanGenerateBytecode() { return FLAG_regexp_interpret_all || FLAG_regexp_tier_up; } diff --git a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc index d4144e7e6409ab..853d8b2815cdcd 100644 --- a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc +++ b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.cc @@ -38,7 +38,10 @@ namespace internal { * The remaining registers are free for computations. * Each call to a public method should retain this convention. * - * The stack will have the following structure: + * The stack will have the following structure + * - fp[112] Address regexp (address of the JSRegExp object; unused in + * native code, passed to match signature of + * the interpreter) * - fp[108] Isolate* isolate (address of the current isolate) * - fp[104] direct_call (if 1, direct call from JavaScript code, * if 0, call through the runtime system). @@ -85,7 +88,8 @@ namespace internal { * int num_capture_registers, * byte* stack_area_base, * bool direct_call = false, - * Isolate* isolate); + * Isolate* isolate, + * Address regexp); * The call is performed by NativeRegExpMacroAssembler::Execute() * (in regexp-macro-assembler.cc) via the GeneratedCode wrapper. */ @@ -204,7 +208,7 @@ void RegExpMacroAssemblerS390::CheckGreedyLoop(Label* on_equal) { Label backtrack_non_equal; __ CmpP(current_input_offset(), MemOperand(backtrack_stackpointer(), 0)); __ bne(&backtrack_non_equal); - __ AddP(backtrack_stackpointer(), Operand(kPointerSize)); + __ AddP(backtrack_stackpointer(), Operand(kSystemPointerSize)); BranchOrBacktrack(al, on_equal); __ bind(&backtrack_non_equal); @@ -635,11 +639,11 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { // Requires us to save the callee-preserved registers r6-r13 // General convention is to also save r14 (return addr) and // sp/r15 as well in a single STM/STMG - __ StoreMultipleP(r6, sp, MemOperand(sp, 6 * kPointerSize)); + __ StoreMultipleP(r6, sp, MemOperand(sp, 6 * kSystemPointerSize)); // Load stack parameters from caller stack frame - __ LoadMultipleP(r7, r9, - MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize)); + __ LoadMultipleP( + r7, r9, MemOperand(sp, kStackFrameExtraParamSlot * kSystemPointerSize)); // r7 = capture array size // r8 = stack area base // r9 = direct call @@ -654,7 +658,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { // Set frame pointer in space for it if this is not a direct call // from generated code. __ LoadRR(frame_pointer(), sp); - __ lay(sp, MemOperand(sp, -10 * kPointerSize)); + __ lay(sp, MemOperand(sp, -10 * kSystemPointerSize)); __ mov(r1, Operand::Zero()); // success counter __ LoadRR(r0, r1); // offset of location __ StoreMultipleP(r0, r9, MemOperand(sp, 0)); @@ -672,7 +676,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { __ ble(&stack_limit_hit); // Check if there is room for the variable number of registers above // the stack limit. - __ CmpLogicalP(r2, Operand(num_registers_ * kPointerSize)); + __ CmpLogicalP(r2, Operand(num_registers_ * kSystemPointerSize)); __ bge(&stack_ok); // Exit with OutOfMemory exception. There is not enough space on the stack // for our working registers. @@ -688,7 +692,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { __ bind(&stack_ok); // Allocate space on stack for registers. - __ lay(sp, MemOperand(sp, (-num_registers_ * kPointerSize))); + __ lay(sp, MemOperand(sp, (-num_registers_ * kSystemPointerSize))); // Load string end. __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); // Load input start. @@ -731,12 +735,13 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { // Fill saved registers with initial value = start offset - 1 if (num_saved_registers_ > 8) { // One slot beyond address of register 0. - __ lay(r3, MemOperand(frame_pointer(), kRegisterZero + kPointerSize)); + __ lay(r3, + MemOperand(frame_pointer(), kRegisterZero + kSystemPointerSize)); __ Load(r4, Operand(num_saved_registers_)); Label init_loop; __ bind(&init_loop); - __ StoreP(r1, MemOperand(r3, -kPointerSize)); - __ lay(r3, MemOperand(r3, -kPointerSize)); + __ StoreP(r1, MemOperand(r3, -kSystemPointerSize)); + __ lay(r3, MemOperand(r3, -kSystemPointerSize)); __ BranchOnCount(r4, &init_loop); } else { for (int i = 0; i < num_saved_registers_; i++) { @@ -871,7 +876,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { // Skip sp past regexp registers and local variables.. __ LoadRR(sp, frame_pointer()); // Restore registers r6..r15. - __ LoadMultipleP(r6, sp, MemOperand(sp, 6 * kPointerSize)); + __ LoadMultipleP(r6, sp, MemOperand(sp, 6 * kSystemPointerSize)); __ b(r14); @@ -1087,17 +1092,19 @@ void RegExpMacroAssemblerS390::CallCheckStackGuardState(Register scratch) { // Code of self. __ mov(r3, Operand(masm_->CodeObject())); // r2 becomes return address pointer. - __ lay(r2, MemOperand(sp, kStackFrameRASlot * kPointerSize)); + __ lay(r2, MemOperand(sp, kStackFrameRASlot * kSystemPointerSize)); ExternalReference stack_guard_check = ExternalReference::re_check_stack_guard_state(isolate()); __ mov(ip, Operand(stack_guard_check)); __ StoreReturnAddressAndCall(ip); - if (base::OS::ActivationFrameAlignment() > kPointerSize) { - __ LoadP(sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kPointerSize))); + if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) { + __ LoadP( + sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize))); } else { - __ la(sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kPointerSize))); + __ la(sp, + MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize))); } __ mov(code_pointer(), Operand(masm_->CodeObject())); @@ -1106,7 +1113,7 @@ void RegExpMacroAssemblerS390::CallCheckStackGuardState(Register scratch) { // Helper function for reading a value out of a stack frame. template <typename T> static T& frame_entry(Address re_frame, int frame_offset) { - DCHECK_EQ(kPointerSize, sizeof(T)); + DCHECK_EQ(kSystemPointerSize, sizeof(T)); #ifdef V8_TARGET_ARCH_S390X return reinterpret_cast<T&>(Memory<uint64_t>(re_frame + frame_offset)); #else @@ -1140,7 +1147,7 @@ MemOperand RegExpMacroAssemblerS390::register_location(int register_index) { num_registers_ = register_index + 1; } return MemOperand(frame_pointer(), - kRegisterZero - register_index * kPointerSize); + kRegisterZero - register_index * kSystemPointerSize); } void RegExpMacroAssemblerS390::CheckPosition(int cp_offset, @@ -1200,7 +1207,7 @@ void RegExpMacroAssemblerS390::SafeCallTarget(Label* name) { void RegExpMacroAssemblerS390::Push(Register source) { DCHECK(source != backtrack_stackpointer()); __ lay(backtrack_stackpointer(), - MemOperand(backtrack_stackpointer(), -kPointerSize)); + MemOperand(backtrack_stackpointer(), -kSystemPointerSize)); __ StoreP(source, MemOperand(backtrack_stackpointer())); } @@ -1208,7 +1215,7 @@ void RegExpMacroAssemblerS390::Pop(Register target) { DCHECK(target != backtrack_stackpointer()); __ LoadP(target, MemOperand(backtrack_stackpointer())); __ la(backtrack_stackpointer(), - MemOperand(backtrack_stackpointer(), kPointerSize)); + MemOperand(backtrack_stackpointer(), kSystemPointerSize)); } void RegExpMacroAssemblerS390::CheckPreemption() { @@ -1235,13 +1242,15 @@ void RegExpMacroAssemblerS390::CallCFunctionUsingStub( __ mov(code_pointer(), Operand(function)); Label ret; __ larl(r14, &ret); - __ StoreP(r14, MemOperand(sp, kStackFrameRASlot * kPointerSize)); + __ StoreP(r14, MemOperand(sp, kStackFrameRASlot * kSystemPointerSize)); __ b(code_pointer()); __ bind(&ret); - if (base::OS::ActivationFrameAlignment() > kPointerSize) { - __ LoadP(sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kPointerSize))); + if (base::OS::ActivationFrameAlignment() > kSystemPointerSize) { + __ LoadP( + sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize))); } else { - __ la(sp, MemOperand(sp, (kNumRequiredStackFrameSlots * kPointerSize))); + __ la(sp, + MemOperand(sp, (kNumRequiredStackFrameSlots * kSystemPointerSize))); } __ mov(code_pointer(), Operand(masm_->CodeObject())); } diff --git a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h index 3a6a915263c64c..4811ac7382a8c1 100644 --- a/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h +++ b/deps/v8/src/regexp/s390/regexp-macro-assembler-s390.h @@ -95,26 +95,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390 kStoredRegisters + kCalleeRegisterSaveAreaSize; // Stack parameters placed by caller. static const int kCaptureArraySize = kCallerFrame; - static const int kStackAreaBase = kCallerFrame + kPointerSize; + static const int kStackAreaBase = kCallerFrame + kSystemPointerSize; // kDirectCall again - static const int kIsolate = kStackAreaBase + 2 * kPointerSize; + static const int kIsolate = kStackAreaBase + 2 * kSystemPointerSize; // Below the frame pointer. // Register parameters stored by setup code. - static const int kDirectCall = kFramePointer - kPointerSize; - static const int kStackHighEnd = kDirectCall - kPointerSize; - static const int kNumOutputRegisters = kStackHighEnd - kPointerSize; - static const int kRegisterOutput = kNumOutputRegisters - kPointerSize; - static const int kInputEnd = kRegisterOutput - kPointerSize; - static const int kInputStart = kInputEnd - kPointerSize; - static const int kStartIndex = kInputStart - kPointerSize; - static const int kInputString = kStartIndex - kPointerSize; + static const int kDirectCall = kFramePointer - kSystemPointerSize; + static const int kStackHighEnd = kDirectCall - kSystemPointerSize; + static const int kNumOutputRegisters = kStackHighEnd - kSystemPointerSize; + static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize; + static const int kInputEnd = kRegisterOutput - kSystemPointerSize; + static const int kInputStart = kInputEnd - kSystemPointerSize; + static const int kStartIndex = kInputStart - kSystemPointerSize; + static const int kInputString = kStartIndex - kSystemPointerSize; // When adding local variables remember to push space for them in // the frame in GetCode. - static const int kSuccessfulCaptures = kInputString - kPointerSize; - static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize; + static const int kSuccessfulCaptures = kInputString - kSystemPointerSize; + static const int kStringStartMinusOne = + kSuccessfulCaptures - kSystemPointerSize; // First register address. Following registers are below it on the stack. - static const int kRegisterZero = kStringStartMinusOne - kPointerSize; + static const int kRegisterZero = kStringStartMinusOne - kSystemPointerSize; // Initial size of code buffer. static const int kRegExpCodeSize = 1024; diff --git a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc index 42ba13c4ee850b..4352c3f67f3686 100644 --- a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc +++ b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc @@ -296,7 +296,7 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( } else { DCHECK(mode_ == UC16); // Save important/volatile registers before calling C function. -#ifndef _WIN64 +#ifndef V8_TARGET_OS_WIN // Caller save on Linux and callee save in Windows. __ pushq(rsi); __ pushq(rdi); @@ -311,7 +311,7 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( // Address byte_offset2 - Address of current character position. // size_t byte_length - length of capture in bytes(!) // Isolate* isolate or 0 if unicode flag. -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN DCHECK(rcx == arg_reg_1); DCHECK(rdx == arg_reg_2); // Compute and set byte_offset1 (start of capture). @@ -333,7 +333,7 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( if (read_backward) { __ subq(rsi, rbx); } -#endif // _WIN64 +#endif // V8_TARGET_OS_WIN // Set byte_length. __ movq(arg_reg_3, rbx); @@ -358,7 +358,7 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( // Restore original values before reacting on result value. __ Move(code_object_pointer(), masm_.CodeObject()); __ popq(backtrack_stackpointer()); -#ifndef _WIN64 +#ifndef V8_TARGET_OS_WIN __ popq(rdi); __ popq(rsi); #endif @@ -683,7 +683,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ movq(rbp, rsp); // Save parameters and callee-save registers. Order here should correspond // to order of kBackup_ebx etc. -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots. // Store register parameters in pre-allocated stack slots, __ movq(Operand(rbp, kInputString), rcx); @@ -890,7 +890,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { } __ bind(&return_rax); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Restore callee save registers. __ leaq(rsp, Operand(rbp, kLastCalleeSaveRegister)); __ popq(rbx); @@ -943,7 +943,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { // Reached if the backtrack-stack limit has been hit. // Save registers before calling C function -#ifndef _WIN64 +#ifndef V8_TARGET_OS_WIN // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI. __ pushq(rsi); __ pushq(rdi); @@ -952,7 +952,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { // Call GrowStack(backtrack_stackpointer()) static const int num_arguments = 3; __ PrepareCallCFunction(num_arguments); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Microsoft passes parameters in rcx, rdx, r8. // First argument, backtrack stackpointer, is already in rcx. __ leaq(rdx, Operand(rbp, kStackHighEnd)); // Second argument @@ -974,7 +974,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { __ movq(backtrack_stackpointer(), rax); // Restore saved registers and continue. __ Move(code_object_pointer(), masm_.CodeObject()); -#ifndef _WIN64 +#ifndef V8_TARGET_OS_WIN __ popq(rdi); __ popq(rsi); #endif @@ -1159,7 +1159,7 @@ void RegExpMacroAssemblerX64::CallCheckStackGuardState() { // store anything volatile in a C call or overwritten by this function. static const int num_arguments = 3; __ PrepareCallCFunction(num_arguments); -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Second argument: Code of self. (Do this before overwriting r8). __ movq(rdx, code_object_pointer()); // Third argument: RegExp code frame pointer. diff --git a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.h b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.h index 9d011dcd467df8..1d95a2718fba1a 100644 --- a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.h +++ b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.h @@ -92,7 +92,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64 static const int kReturn_eip = kFramePointer + kSystemPointerSize; static const int kFrameAlign = kReturn_eip + kSystemPointerSize; -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Parameters (first four passed as registers, but with room on stack). // In Microsoft 64-bit Calling Convention, there is room on the callers // stack (before the return address) to spill parameter registers. We @@ -131,7 +131,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64 static const int kIsolate = kDirectCall + kSystemPointerSize; #endif -#ifdef _WIN64 +#ifdef V8_TARGET_OS_WIN // Microsoft calling convention has three callee-saved registers // (that we are using). We push these after the frame pointer. static const int kBackup_rsi = kFramePointer - kSystemPointerSize; diff --git a/deps/v8/src/roots/roots.h b/deps/v8/src/roots/roots.h index c82ec6d04f8e33..c262f639282aaf 100644 --- a/deps/v8/src/roots/roots.h +++ b/deps/v8/src/roots/roots.h @@ -206,37 +206,37 @@ class Symbol; // Mutable roots that are known to be immortal immovable, for which we can // safely skip write barriers. -#define STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ - ACCESSOR_INFO_ROOT_LIST(V) \ - /* Maps */ \ - V(Map, external_map, ExternalMap) \ - V(Map, message_object_map, JSMessageObjectMap) \ - /* Canonical empty values */ \ - V(Script, empty_script, EmptyScript) \ - V(FeedbackCell, many_closures_cell, ManyClosuresCell) \ - V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \ - /* Protectors */ \ - V(Cell, array_constructor_protector, ArrayConstructorProtector) \ - V(PropertyCell, no_elements_protector, NoElementsProtector) \ - V(Cell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \ - V(PropertyCell, array_species_protector, ArraySpeciesProtector) \ - V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \ - V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \ - V(Cell, string_length_protector, StringLengthProtector) \ - V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \ - V(PropertyCell, array_buffer_detaching_protector, \ - ArrayBufferDetachingProtector) \ - V(PropertyCell, promise_hook_protector, PromiseHookProtector) \ - V(Cell, promise_resolve_protector, PromiseResolveProtector) \ - V(PropertyCell, map_iterator_protector, MapIteratorProtector) \ - V(PropertyCell, promise_then_protector, PromiseThenProtector) \ - V(PropertyCell, set_iterator_protector, SetIteratorProtector) \ - V(PropertyCell, string_iterator_protector, StringIteratorProtector) \ - /* Caches */ \ - V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ - V(FixedArray, string_split_cache, StringSplitCache) \ - V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \ - /* Indirection lists for isolate-independent builtins */ \ +#define STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \ + ACCESSOR_INFO_ROOT_LIST(V) \ + /* Maps */ \ + V(Map, external_map, ExternalMap) \ + V(Map, message_object_map, JSMessageObjectMap) \ + /* Canonical empty values */ \ + V(Script, empty_script, EmptyScript) \ + V(FeedbackCell, many_closures_cell, ManyClosuresCell) \ + V(Cell, invalid_prototype_validity_cell, InvalidPrototypeValidityCell) \ + /* Protectors */ \ + V(PropertyCell, array_constructor_protector, ArrayConstructorProtector) \ + V(PropertyCell, no_elements_protector, NoElementsProtector) \ + V(PropertyCell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \ + V(PropertyCell, array_species_protector, ArraySpeciesProtector) \ + V(PropertyCell, typed_array_species_protector, TypedArraySpeciesProtector) \ + V(PropertyCell, promise_species_protector, PromiseSpeciesProtector) \ + V(PropertyCell, string_length_protector, StringLengthProtector) \ + V(PropertyCell, array_iterator_protector, ArrayIteratorProtector) \ + V(PropertyCell, array_buffer_detaching_protector, \ + ArrayBufferDetachingProtector) \ + V(PropertyCell, promise_hook_protector, PromiseHookProtector) \ + V(PropertyCell, promise_resolve_protector, PromiseResolveProtector) \ + V(PropertyCell, map_iterator_protector, MapIteratorProtector) \ + V(PropertyCell, promise_then_protector, PromiseThenProtector) \ + V(PropertyCell, set_iterator_protector, SetIteratorProtector) \ + V(PropertyCell, string_iterator_protector, StringIteratorProtector) \ + /* Caches */ \ + V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \ + V(FixedArray, string_split_cache, StringSplitCache) \ + V(FixedArray, regexp_multiple_cache, RegExpMultipleCache) \ + /* Indirection lists for isolate-independent builtins */ \ V(FixedArray, builtins_constants_table, BuiltinsConstantsTable) // These root references can be updated by the mutator. @@ -255,8 +255,6 @@ class Symbol; /* Feedback vectors that we need for code coverage or type profile */ \ V(Object, feedback_vectors_for_profiling_tools, \ FeedbackVectorsForProfilingTools) \ - V(WeakArrayList, noscript_shared_function_infos, \ - NoScriptSharedFunctionInfos) \ V(FixedArray, serialized_objects, SerializedObjects) \ V(FixedArray, serialized_global_proxy_sizes, SerializedGlobalProxySizes) \ V(TemplateList, message_listeners, MessageListeners) \ @@ -268,7 +266,9 @@ class Symbol; V(HeapObject, weak_refs_keep_during_job, WeakRefsKeepDuringJob) \ V(HeapObject, interpreter_entry_trampoline_for_profiling, \ InterpreterEntryTrampolineForProfiling) \ - V(Object, pending_optimize_for_test_bytecode, PendingOptimizeForTestBytecode) + V(Object, pending_optimize_for_test_bytecode, \ + PendingOptimizeForTestBytecode) \ + V(WeakArrayList, shared_wasm_memories, SharedWasmMemories) // Entries in this list are limited to Smis and are not visited during GC. #define SMI_ROOT_LIST(V) \ diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index 6190b16cff124b..34a8b2b93785ef 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -5,6 +5,7 @@ #include "src/debug/debug.h" #include "src/execution/arguments-inl.h" #include "src/execution/isolate-inl.h" +#include "src/execution/protectors-inl.h" #include "src/heap/factory.h" #include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop. #include "src/heap/heap-write-barrier-inl.h" @@ -136,8 +137,8 @@ RUNTIME_FUNCTION(Runtime_NewArray) { // just flip the bit on the global protector cell instead. // TODO(bmeurer): Find a better way to mark this. Global protectors // tend to back-fire over time... - if (isolate->IsArrayConstructorIntact()) { - isolate->InvalidateArrayConstructorProtector(); + if (Protectors::IsArrayConstructorIntact(isolate)) { + Protectors::InvalidateArrayConstructor(isolate); } } } diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index 522e93da3f25bc..a4e9680a1f5c35 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -130,7 +130,8 @@ Handle<Name> KeyToName<NumberDictionary>(Isolate* isolate, Handle<Object> key) { inline void SetHomeObject(Isolate* isolate, JSFunction method, JSObject home_object) { if (method.shared().needs_home_object()) { - const int kPropertyIndex = JSFunction::kMaybeHomeObjectDescriptorIndex; + const InternalIndex kPropertyIndex( + JSFunction::kMaybeHomeObjectDescriptorIndex); CHECK_EQ(method.map().instance_descriptors().GetKey(kPropertyIndex), ReadOnlyRoots(isolate).home_object_symbol()); @@ -303,7 +304,7 @@ bool AddDescriptorsByTemplate( // Count the number of properties that must be in the instance and // create the property array to hold the constants. int count = 0; - for (int i = 0; i < nof_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(nof_descriptors)) { PropertyDetails details = descriptors_template->GetDetails(i); if (details.location() == kDescriptor && details.kind() == kData) { count++; @@ -315,7 +316,7 @@ bool AddDescriptorsByTemplate( // Read values from |descriptors_template| and store possibly post-processed // values into "instantiated" |descriptors| array. int field_index = 0; - for (int i = 0; i < nof_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(nof_descriptors)) { Object value = descriptors_template->GetStrongValue(i); if (value.IsAccessorPair()) { Handle<AccessorPair> pair = AccessorPair::Copy( diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc index 4364c55775e4b8..c7f3201eacd531 100644 --- a/deps/v8/src/runtime/runtime-compiler.cc +++ b/deps/v8/src/runtime/runtime-compiler.cc @@ -157,6 +157,9 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); TRACE_EVENT0("v8", "V8.DeoptimizeCode"); Handle<JSFunction> function = deoptimizer->function(); + // For OSR the optimized code isn't installed on the function, so get the + // code object from deoptimizer. + Handle<Code> optimized_code = deoptimizer->compiled_code(); DeoptimizeKind type = deoptimizer->deopt_kind(); // TODO(turbofan): We currently need the native context to materialize @@ -174,7 +177,7 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { // Invalidate the underlying optimized code on non-lazy deopts. if (type != DeoptimizeKind::kLazy) { - Deoptimizer::DeoptimizeFunction(*function); + Deoptimizer::DeoptimizeFunction(*function, *optimized_code); } return ReadOnlyRoots(isolate).undefined_value(); @@ -224,8 +227,7 @@ BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) { RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + DCHECK_EQ(0, args.length()); // Only reachable when OST is enabled. CHECK(FLAG_use_osr); @@ -233,7 +235,6 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { // Determine frame triggering OSR request. JavaScriptFrameIterator it(isolate); JavaScriptFrame* frame = it.frame(); - DCHECK_EQ(frame->function(), *function); DCHECK(frame->is_interpreted()); // Determine the entry point for which this OSR request has been fired and @@ -242,6 +243,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { DCHECK(!ast_id.IsNone()); MaybeHandle<Code> maybe_result; + Handle<JSFunction> function(frame->function(), isolate); if (IsSuitableForOnStackReplacement(isolate, function)) { if (FLAG_trace_osr) { PrintF("[OSR - Compiling: "); diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index 0fbea6a193a1c8..09dd4f8132d195 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -491,8 +491,7 @@ int ScriptLinePosition(Handle<Script> script, int line) { if (line < 0) return -1; if (script->type() == Script::TYPE_WASM) { - return WasmModuleObject::cast(script->wasm_module_object()) - .GetFunctionOffset(line); + return GetWasmFunctionOffset(script->wasm_native_module()->module(), line); } Script::InitLineEnds(script); @@ -827,19 +826,6 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) { return ReadOnlyRoots(isolate).undefined_value(); } -RUNTIME_FUNCTION(Runtime_PerformSideEffectCheckForObject) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); - - DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kSideEffects); - if (!isolate->debug()->PerformSideEffectCheckForObject(object)) { - DCHECK(isolate->has_pending_exception()); - return ReadOnlyRoots(isolate).exception(); - } - return ReadOnlyRoots(isolate).undefined_value(); -} - RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); diff --git a/deps/v8/src/runtime/runtime-forin.cc b/deps/v8/src/runtime/runtime-forin.cc index 6042a867c92c69..0d7e1dc30b3a9a 100644 --- a/deps/v8/src/runtime/runtime-forin.cc +++ b/deps/v8/src/runtime/runtime-forin.cc @@ -33,7 +33,10 @@ MaybeHandle<HeapObject> Enumerate(Isolate* isolate, if (!accumulator.is_receiver_simple_enum()) { Handle<FixedArray> keys; ASSIGN_RETURN_ON_EXCEPTION( - isolate, keys, accumulator.GetKeys(GetKeysConversion::kConvertToString), + isolate, keys, + accumulator.GetKeys(accumulator.may_have_elements() + ? GetKeysConversion::kConvertToString + : GetKeysConversion::kNoNumbers), HeapObject); // Test again, since cache may have been built by GetKeys() calls above. if (!accumulator.is_receiver_simple_enum()) return keys; diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index 80f9baa48d3850..03c9e582d80a06 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -14,6 +14,7 @@ #include "src/execution/frames-inl.h" #include "src/execution/isolate-inl.h" #include "src/execution/messages.h" +#include "src/execution/runtime-profiler.h" #include "src/handles/maybe-handles.h" #include "src/init/bootstrapper.h" #include "src/logging/counters.h" @@ -296,10 +297,11 @@ RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt) { function->feedback_vector().set_invocation_count(1); return ReadOnlyRoots(isolate).undefined_value(); } - // Handle interrupts. { SealHandleScope shs(isolate); - return isolate->stack_guard()->HandleInterrupts(); + isolate->counters()->runtime_profiler_ticks()->Increment(); + isolate->runtime_profiler()->MarkCandidatesForOptimization(); + return ReadOnlyRoots(isolate).undefined_value(); } } diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index 0ffc6e932ef471..497a27dbb907d0 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -111,8 +111,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( if (copy->HasFastProperties(isolate)) { Handle<DescriptorArray> descriptors( copy->map(isolate).instance_descriptors(isolate), isolate); - int limit = copy->map(isolate).NumberOfOwnDescriptors(); - for (int i = 0; i < limit; i++) { + for (InternalIndex i : copy->map(isolate).IterateOwnDescriptors()) { PropertyDetails details = descriptors->GetDetails(i); DCHECK_EQ(kField, details.location()); DCHECK_EQ(kData, details.kind()); @@ -595,10 +594,11 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_ARG_HANDLE_CHECKED(ObjectBoilerplateDescription, description, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - Handle<FeedbackVector> vector = Handle<FeedbackVector>(); - if (!maybe_vector->IsUndefined()) { - DCHECK(maybe_vector->IsFeedbackVector()); + Handle<FeedbackVector> vector; + if (maybe_vector->IsFeedbackVector()) { vector = Handle<FeedbackVector>::cast(maybe_vector); + } else { + DCHECK(maybe_vector->IsUndefined()); } RETURN_RESULT_OR_FAILURE( isolate, CreateLiteral<ObjectLiteralHelper>( @@ -632,10 +632,11 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_ARG_HANDLE_CHECKED(ArrayBoilerplateDescription, elements, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - Handle<FeedbackVector> vector = Handle<FeedbackVector>(); - if (!maybe_vector->IsUndefined()) { - DCHECK(maybe_vector->IsFeedbackVector()); + Handle<FeedbackVector> vector; + if (maybe_vector->IsFeedbackVector()) { vector = Handle<FeedbackVector>::cast(maybe_vector); + } else { + DCHECK(maybe_vector->IsUndefined()); } RETURN_RESULT_OR_FAILURE( isolate, CreateLiteral<ArrayLiteralHelper>( @@ -649,11 +650,12 @@ RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { CONVERT_SMI_ARG_CHECKED(index, 1); CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); - Handle<FeedbackVector> vector = Handle<FeedbackVector>(); - if (!maybe_vector->IsUndefined()) { - DCHECK(maybe_vector->IsFeedbackVector()); + + Handle<FeedbackVector> vector; + if (maybe_vector->IsFeedbackVector()) { vector = Handle<FeedbackVector>::cast(maybe_vector); + } else { + DCHECK(maybe_vector->IsUndefined()); } if (vector.is_null()) { Handle<JSRegExp> new_regexp; @@ -663,20 +665,21 @@ RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { return *new_regexp; } - // Check if boilerplate exists. If not, create it first. - Handle<JSRegExp> boilerplate; + // This function assumes that the boilerplate does not yet exist. + FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); Handle<Object> literal_site(vector->Get(literal_slot)->cast<Object>(), isolate); - if (!HasBoilerplate(literal_site)) { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, boilerplate, - JSRegExp::New(isolate, pattern, JSRegExp::Flags(flags))); - if (IsUninitializedLiteralSite(*literal_site)) { - PreInitializeLiteralSite(vector, literal_slot); - return *boilerplate; - } - vector->Set(literal_slot, *boilerplate); + CHECK(!HasBoilerplate(literal_site)); + + Handle<JSRegExp> boilerplate; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, boilerplate, + JSRegExp::New(isolate, pattern, JSRegExp::Flags(flags))); + if (IsUninitializedLiteralSite(*literal_site)) { + PreInitializeLiteralSite(vector, literal_slot); + return *boilerplate; } + vector->Set(literal_slot, *boilerplate); return *JSRegExp::Copy(boilerplate); } diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 310cdaab4208f5..e07d91dd314d96 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -91,7 +91,7 @@ bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver, // (2) The property to be deleted must be the last property. int nof = receiver_map->NumberOfOwnDescriptors(); if (nof == 0) return false; - int descriptor = nof - 1; + InternalIndex descriptor(nof - 1); Handle<DescriptorArray> descriptors(receiver_map->instance_descriptors(), isolate); if (descriptors->GetKey(descriptor) != *key) return false; @@ -132,8 +132,12 @@ bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver, // for properties stored in the descriptor array. if (details.location() == kField) { DisallowHeapAllocation no_allocation; - isolate->heap()->NotifyObjectLayoutChange( - *receiver, receiver_map->instance_size(), no_allocation); + + // Invalidate slots manually later in case we delete an in-object tagged + // property. In this case we might later store an untagged value in the + // recorded slot. + isolate->heap()->NotifyObjectLayoutChange(*receiver, no_allocation, + InvalidateRecordedSlots::kNo); FieldIndex index = FieldIndex::ForPropertyIndex(*receiver_map, details.field_index()); // Special case deleting the last out-of object property. @@ -149,8 +153,13 @@ bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver, // Slot clearing is the reason why this entire function cannot currently // be implemented in the DeleteProperty stub. if (index.is_inobject() && !receiver_map->IsUnboxedDoubleField(index)) { + // We need to clear the recorded slot in this case because in-object + // slack tracking might not be finished. This ensures that we don't + // have recorded slots in free space. isolate->heap()->ClearRecordedSlot(*receiver, receiver->RawField(index.offset())); + MemoryChunk* chunk = MemoryChunk::FromHeapObject(*receiver); + chunk->InvalidateRecordedSlots(*receiver); } } } diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index e197e16e11282b..980339ee5e5a45 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -613,20 +613,6 @@ V8_WARN_UNUSED_RESULT static Object StringReplaceGlobalRegExpWithString( JSRegExp::Type typeTag = regexp->TypeTag(); if (typeTag == JSRegExp::IRREGEXP) { - // Force tier up to native code for global replaces. The global replace is - // implemented differently for native code and bytecode execution, where the - // native code expects an array to store all the matches, and the bytecode - // matches one at a time, so it's easier to tier-up to native code from the - // start. - if (FLAG_regexp_tier_up) { - regexp->MarkTierUpForNextExec(); - if (FLAG_trace_regexp_tier_up) { - PrintF( - "Forcing tier-up of JSRegExp object %p in " - "StringReplaceGlobalRegExpWithString\n", - reinterpret_cast<void*>(regexp->ptr())); - } - } // Ensure the RegExp is compiled so we can access the capture-name map. if (RegExp::IrregexpPrepare(isolate, regexp, subject) == -1) { DCHECK(isolate->has_pending_exception()); @@ -1349,6 +1335,19 @@ V8_WARN_UNUSED_RESULT MaybeHandle<String> RegExpReplace( RETURN_ON_EXCEPTION(isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0), String); + // Force tier up to native code for global replaces. The global replace is + // implemented differently for native code and bytecode execution, where the + // native code expects an array to store all the matches, and the bytecode + // matches one at a time, so it's easier to tier-up to native code from the + // start. + if (FLAG_regexp_tier_up && regexp->TypeTag() == JSRegExp::IRREGEXP) { + regexp->MarkTierUpForNextExec(); + if (FLAG_trace_regexp_tier_up) { + PrintF("Forcing tier-up of JSRegExp object %p in RegExpReplace\n", + reinterpret_cast<void*>(regexp->ptr())); + } + } + if (replace->length() == 0) { if (string->IsOneByteRepresentation()) { Object result = diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index a766dd5db29260..a58b28ce52f314 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -32,6 +32,7 @@ #include "src/utils/ostreams.h" #include "src/wasm/memory-tracing.h" #include "src/wasm/module-compiler.h" +#include "src/wasm/wasm-code-manager.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" @@ -676,6 +677,47 @@ RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) { return ReadOnlyRoots(isolate).undefined_value(); } +namespace { + +int FixedArrayLenFromSize(int size) { + return Min((size - FixedArray::kHeaderSize) / kTaggedSize, + FixedArray::kMaxRegularLength); +} + +void FillUpOneNewSpacePage(Isolate* isolate, Heap* heap) { + NewSpace* space = heap->new_space(); + int space_remaining = static_cast<int>(*space->allocation_limit_address() - + *space->allocation_top_address()); + while (space_remaining > 0) { + int length = FixedArrayLenFromSize(space_remaining); + if (length > 0) { + Handle<FixedArray> padding = + isolate->factory()->NewFixedArray(length, AllocationType::kYoung); + DCHECK(heap->new_space()->Contains(*padding)); + space_remaining -= padding->Size(); + } else { + // Not enough room to create another fixed array. Create a filler. + heap->CreateFillerObjectAt(*heap->new_space()->allocation_top_address(), + space_remaining, ClearRecordedSlots::kNo); + break; + } + } +} + +} // namespace + +RUNTIME_FUNCTION(Runtime_SimulateNewspaceFull) { + HandleScope scope(isolate); + Heap* heap = isolate->heap(); + NewSpace* space = heap->new_space(); + PauseAllocationObserversScope pause_observers(heap); + AlwaysAllocateScope always_allocate(heap); + do { + FillUpOneNewSpacePage(isolate, heap); + } while (space->AddFreshPage()); + + return ReadOnlyRoots(isolate).undefined_value(); +} RUNTIME_FUNCTION(Runtime_DebugPrint) { SealHandleScope shs(isolate); @@ -1008,7 +1050,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmRecoveredTrapCount) { RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmExceptionPackage, exception, 0); CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 1); Handle<Object> tag = WasmExceptionPackage::GetExceptionTag(isolate, exception); @@ -1024,7 +1066,7 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionId) { RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, exception, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmExceptionPackage, exception, 0); Handle<Object> values_obj = WasmExceptionPackage::GetExceptionValues(isolate, exception); CHECK(values_obj->IsFixedArray()); // Only called with correct input. @@ -1107,20 +1149,22 @@ RUNTIME_FUNCTION(Runtime_ArraySpeciesProtector) { RUNTIME_FUNCTION(Runtime_MapIteratorProtector) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); - return isolate->heap()->ToBoolean(isolate->IsMapIteratorLookupChainIntact()); + return isolate->heap()->ToBoolean( + Protectors::IsMapIteratorLookupChainIntact(isolate)); } RUNTIME_FUNCTION(Runtime_SetIteratorProtector) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); - return isolate->heap()->ToBoolean(isolate->IsSetIteratorLookupChainIntact()); + return isolate->heap()->ToBoolean( + Protectors::IsSetIteratorLookupChainIntact(isolate)); } RUNTIME_FUNCTION(Runtime_StringIteratorProtector) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); return isolate->heap()->ToBoolean( - isolate->IsStringIteratorLookupChainIntact()); + Protectors::IsStringIteratorLookupChainIntact(isolate)); } // Take a compiled wasm module and serialize it into an array buffer, which is @@ -1132,17 +1176,22 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { wasm::NativeModule* native_module = module_obj->native_module(); wasm::WasmSerializer wasm_serializer(native_module); - size_t compiled_size = wasm_serializer.GetSerializedNativeModuleSize(); - void* array_data = isolate->array_buffer_allocator()->Allocate(compiled_size); - Handle<JSArrayBuffer> array_buffer = - isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - JSArrayBuffer::Setup(array_buffer, isolate, false, array_data, compiled_size); - if (!array_data || - !wasm_serializer.SerializeNativeModule( - {reinterpret_cast<uint8_t*>(array_data), compiled_size})) { - return ReadOnlyRoots(isolate).undefined_value(); + size_t byte_length = wasm_serializer.GetSerializedNativeModuleSize(); + + MaybeHandle<JSArrayBuffer> result = + isolate->factory()->NewJSArrayBufferAndBackingStore( + byte_length, InitializedFlag::kUninitialized); + + Handle<JSArrayBuffer> array_buffer; + if (result.ToHandle(&array_buffer) && + wasm_serializer.SerializeNativeModule( + {reinterpret_cast<uint8_t*>(array_buffer->backing_store()), + byte_length})) { + return *array_buffer; } - return *array_buffer; + + // Error. Return undefined. + return ReadOnlyRoots(isolate).undefined_value(); } // Take an array buffer and attempt to reconstruct a compiled wasm module. @@ -1210,7 +1259,8 @@ RUNTIME_FUNCTION(Runtime_WasmGetNumberOfInstances) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); int instance_count = 0; - WeakArrayList weak_instance_list = module_obj->weak_instance_list(); + WeakArrayList weak_instance_list = + module_obj->script().wasm_weak_instance_list(); for (int i = 0; i < weak_instance_list.length(); ++i) { if (weak_instance_list.Get(i)->IsWeak()) instance_count++; } @@ -1226,6 +1276,22 @@ RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) { return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num)); } +RUNTIME_FUNCTION(Runtime_WasmNumCodeSpaces) { + DCHECK_EQ(1, args.length()); + HandleScope scope(isolate); + CONVERT_ARG_HANDLE_CHECKED(JSObject, argument, 0); + Handle<WasmModuleObject> module; + if (argument->IsWasmInstanceObject()) { + module = handle(Handle<WasmInstanceObject>::cast(argument)->module_object(), + isolate); + } else if (argument->IsWasmModuleObject()) { + module = Handle<WasmModuleObject>::cast(argument); + } + size_t num_spaces = + module->native_module()->GetNumberOfCodeSpacesForTesting(); + return *isolate->factory()->NewNumberFromSize(num_spaces); +} + RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) { DCHECK_EQ(2, args.length()); HandleScope scope(isolate); diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index 7fab051cbf6d1c..327c1022388eeb 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -27,22 +27,7 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferDetach) { isolate, NewTypeError(MessageTemplate::kNotTypedArray)); } Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(argument); - if (!array_buffer->is_detachable()) { - return ReadOnlyRoots(isolate).undefined_value(); - } - if (array_buffer->backing_store() == nullptr) { - CHECK_EQ(0, array_buffer->byte_length()); - return ReadOnlyRoots(isolate).undefined_value(); - } - // Shared array buffers should never be detached. - CHECK(!array_buffer->is_shared()); - DCHECK(!array_buffer->is_external()); - void* backing_store = array_buffer->backing_store(); - size_t byte_length = array_buffer->byte_length(); - array_buffer->set_is_external(true); - isolate->heap()->UnregisterArrayBuffer(*array_buffer); array_buffer->Detach(); - isolate->array_buffer_allocator()->Free(backing_store, byte_length); return ReadOnlyRoots(isolate).undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc index 57e59c07be76be..b0153b782864be 100644 --- a/deps/v8/src/runtime/runtime-wasm.cc +++ b/deps/v8/src/runtime/runtime-wasm.cc @@ -150,7 +150,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetTag) { CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); // TODO(mstarzinger): Manually box because parameters are not visited yet. Handle<Object> except_obj(except_obj_raw, isolate); - return *WasmExceptionPackage::GetExceptionTag(isolate, except_obj); + if (!except_obj->IsWasmExceptionPackage(isolate)) { + return ReadOnlyRoots(isolate).undefined_value(); + } + Handle<WasmExceptionPackage> exception = + Handle<WasmExceptionPackage>::cast(except_obj); + return *WasmExceptionPackage::GetExceptionTag(isolate, exception); } RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) { @@ -162,7 +167,12 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionGetValues) { CONVERT_ARG_CHECKED(Object, except_obj_raw, 0); // TODO(mstarzinger): Manually box because parameters are not visited yet. Handle<Object> except_obj(except_obj_raw, isolate); - return *WasmExceptionPackage::GetExceptionValues(isolate, except_obj); + if (!except_obj->IsWasmExceptionPackage(isolate)) { + return ReadOnlyRoots(isolate).undefined_value(); + } + Handle<WasmExceptionPackage> exception = + Handle<WasmExceptionPackage>::cast(except_obj); + return *WasmExceptionPackage::GetExceptionValues(isolate, exception); } RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index d705b05752c3d8..8319aabe2c8d39 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -99,7 +99,7 @@ namespace internal { F(WeakCollectionSet, 4, 1) #define FOR_EACH_INTRINSIC_COMPILER(F, I) \ - F(CompileForOnStackReplacement, 1, 1) \ + F(CompileForOnStackReplacement, 0, 1) \ F(CompileLazy, 1, 1) \ F(CompileOptimized_Concurrent, 1, 1) \ F(CompileOptimized_NotConcurrent, 1, 1) \ @@ -319,7 +319,6 @@ namespace internal { F(ObjectValues, 1, 1) \ F(ObjectValuesSkipFastPath, 1, 1) \ F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - F(PerformSideEffectCheckForObject, 1, 1) \ F(SetDataProperties, 2, 1) \ F(SetKeyedProperty, 3, 1) \ F(SetNamedProperty, 3, 1) \ @@ -515,6 +514,7 @@ namespace internal { F(SetWasmCompileControls, 2, 1) \ F(SetWasmInstantiateControls, 0, 1) \ F(SetWasmThreadsEnabled, 1, 1) \ + F(SimulateNewspaceFull, 0, 1) \ F(StringIteratorProtector, 0, 1) \ F(SystemBreak, 0, 1) \ F(TraceEnter, 0, 1) \ @@ -523,6 +523,7 @@ namespace internal { F(UnblockConcurrentRecompilation, 0, 1) \ F(WasmGetNumberOfInstances, 1, 1) \ F(WasmNumInterpretedCalls, 1, 1) \ + F(WasmNumCodeSpaces, 1, 1) \ F(WasmTierUpFunction, 2, 1) \ F(WasmTraceMemory, 1, 1) \ I(DeoptimizeNow, 0, 1) diff --git a/deps/v8/src/sanitizer/OWNERS b/deps/v8/src/sanitizer/OWNERS index 96c9d10c122abe..29f827d160e49e 100644 --- a/deps/v8/src/sanitizer/OWNERS +++ b/deps/v8/src/sanitizer/OWNERS @@ -1,3 +1,3 @@ file:../../INFRA_OWNERS -clemensh@chromium.org +clemensb@chromium.org diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc index 25e32e2cc0bfea..e477817d20ba6d 100644 --- a/deps/v8/src/snapshot/deserializer.cc +++ b/deps/v8/src/snapshot/deserializer.cc @@ -291,23 +291,30 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj, data_view.byte_offset()); } else if (obj.IsJSTypedArray()) { JSTypedArray typed_array = JSTypedArray::cast(obj); - // Only fixup for the off-heap case. - if (!typed_array.is_on_heap()) { - Smi store_index( - reinterpret_cast<Address>(typed_array.external_pointer())); - byte* backing_store = off_heap_backing_stores_[store_index.value()] + - typed_array.byte_offset(); - typed_array.set_external_pointer(backing_store); + // Fixup typed array pointers. + if (typed_array.is_on_heap()) { + typed_array.SetOnHeapDataPtr(HeapObject::cast(typed_array.base_pointer()), + typed_array.external_pointer()); + } else { + // Serializer writes backing store ref as a DataPtr() value. + size_t store_index = reinterpret_cast<size_t>(typed_array.DataPtr()); + auto backing_store = backing_stores_[store_index]; + auto start = backing_store + ? reinterpret_cast<byte*>(backing_store->buffer_start()) + : nullptr; + typed_array.SetOffHeapDataPtr(start, typed_array.byte_offset()); } } else if (obj.IsJSArrayBuffer()) { JSArrayBuffer buffer = JSArrayBuffer::cast(obj); // Only fixup for the off-heap case. if (buffer.backing_store() != nullptr) { - Smi store_index(reinterpret_cast<Address>(buffer.backing_store())); - void* backing_store = off_heap_backing_stores_[store_index.value()]; - - buffer.set_backing_store(backing_store); - isolate_->heap()->RegisterNewArrayBuffer(buffer); + // Serializer writes backing store ref in |backing_store| field. + size_t store_index = reinterpret_cast<size_t>(buffer.backing_store()); + auto backing_store = backing_stores_[store_index]; + SharedFlag shared = backing_store && backing_store->is_shared() + ? SharedFlag::kShared + : SharedFlag::kNotShared; + buffer.Setup(shared, backing_store); } } else if (obj.IsBytecodeArray()) { // TODO(mythria): Remove these once we store the default values for these @@ -523,9 +530,10 @@ bool Deserializer::ReadData(TSlot current, TSlot limit, // Write barrier support costs around 1% in startup time. In fact there // are no new space objects in current boot snapshots, so it's not needed, // but that may change. - bool write_barrier_needed = (current_object_address != kNullAddress && - source_space != SnapshotSpace::kNew && - source_space != SnapshotSpace::kCode); + bool write_barrier_needed = + (current_object_address != kNullAddress && + source_space != SnapshotSpace::kNew && + source_space != SnapshotSpace::kCode && !FLAG_disable_write_barriers); while (current < limit) { byte data = source_.Get(); switch (data) { @@ -669,12 +677,12 @@ bool Deserializer::ReadData(TSlot current, TSlot limit, case kOffHeapBackingStore: { int byte_length = source_.GetInt(); - byte* backing_store = static_cast<byte*>( - isolate->array_buffer_allocator()->AllocateUninitialized( - byte_length)); + std::unique_ptr<BackingStore> backing_store = + BackingStore::Allocate(isolate, byte_length, SharedFlag::kNotShared, + InitializedFlag::kUninitialized); CHECK_NOT_NULL(backing_store); - source_.CopyRaw(backing_store, byte_length); - off_heap_backing_stores_.push_back(backing_store); + source_.CopyRaw(backing_store->buffer_start(), byte_length); + backing_stores_.push_back(std::move(backing_store)); break; } @@ -842,6 +850,7 @@ TSlot Deserializer::ReadDataCase(Isolate* isolate, TSlot current, // Don't update current pointer here as it may be needed for write barrier. Write(current, heap_object_ref); if (emit_write_barrier && write_barrier_needed) { + DCHECK_IMPLIES(FLAG_disable_write_barriers, !write_barrier_needed); HeapObject host_object = HeapObject::FromAddress(current_object_address); SLOW_DCHECK(isolate->heap()->Contains(host_object)); GenerationalBarrier(host_object, MaybeObjectSlot(current.address()), diff --git a/deps/v8/src/snapshot/deserializer.h b/deps/v8/src/snapshot/deserializer.h index 8dce1b3f3fea30..9f66c37ac56098 100644 --- a/deps/v8/src/snapshot/deserializer.h +++ b/deps/v8/src/snapshot/deserializer.h @@ -10,6 +10,7 @@ #include "src/objects/allocation-site.h" #include "src/objects/api-callbacks.h" +#include "src/objects/backing-store.h" #include "src/objects/code.h" #include "src/objects/js-array.h" #include "src/objects/map.h" @@ -56,7 +57,7 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { allocator()->DecodeReservation(data->Reservations()); // We start the indices here at 1, so that we can distinguish between an // actual index and a nullptr in a deserialized object requiring fix-up. - off_heap_backing_stores_.push_back(nullptr); + backing_stores_.push_back({}); } void Initialize(Isolate* isolate); @@ -173,7 +174,7 @@ class V8_EXPORT_PRIVATE Deserializer : public SerializerDeserializer { std::vector<CallHandlerInfo> call_handler_infos_; std::vector<Handle<String>> new_internalized_strings_; std::vector<Handle<Script>> new_scripts_; - std::vector<byte*> off_heap_backing_stores_; + std::vector<std::shared_ptr<BackingStore>> backing_stores_; DeserializerAllocator allocator_; const bool deserializing_user_code_; diff --git a/deps/v8/src/snapshot/embedded/embedded-file-writer.h b/deps/v8/src/snapshot/embedded/embedded-file-writer.h index e487b9be9bcc77..75fdb2eac395a2 100644 --- a/deps/v8/src/snapshot/embedded/embedded-file-writer.h +++ b/deps/v8/src/snapshot/embedded/embedded-file-writer.h @@ -8,6 +8,7 @@ #include <cinttypes> #include <cstdio> #include <cstring> +#include <memory> #include "src/common/globals.h" #include "src/snapshot/embedded/embedded-data.h" diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc index a17f039fa29126..7a04a9dfabfd35 100644 --- a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc +++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-base.cc @@ -136,16 +136,16 @@ std::unique_ptr<PlatformEmbeddedFileWriterBase> NewPlatformEmbeddedFileWriter( auto embedded_target_os = ToEmbeddedTargetOs(target_os); if (embedded_target_os == EmbeddedTargetOs::kAIX) { - return base::make_unique<PlatformEmbeddedFileWriterAIX>( - embedded_target_arch, embedded_target_os); + return std::make_unique<PlatformEmbeddedFileWriterAIX>(embedded_target_arch, + embedded_target_os); } else if (embedded_target_os == EmbeddedTargetOs::kMac) { - return base::make_unique<PlatformEmbeddedFileWriterMac>( - embedded_target_arch, embedded_target_os); + return std::make_unique<PlatformEmbeddedFileWriterMac>(embedded_target_arch, + embedded_target_os); } else if (embedded_target_os == EmbeddedTargetOs::kWin) { - return base::make_unique<PlatformEmbeddedFileWriterWin>( - embedded_target_arch, embedded_target_os); + return std::make_unique<PlatformEmbeddedFileWriterWin>(embedded_target_arch, + embedded_target_os); } else { - return base::make_unique<PlatformEmbeddedFileWriterGeneric>( + return std::make_unique<PlatformEmbeddedFileWriterGeneric>( embedded_target_arch, embedded_target_os); } diff --git a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc index 688255352d1591..9a9a26fbd0abef 100644 --- a/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc +++ b/deps/v8/src/snapshot/embedded/platform-embedded-file-writer-win.cc @@ -11,7 +11,6 @@ #if defined(V8_OS_WIN64) #include "src/builtins/builtins.h" #include "src/diagnostics/unwinding-info-win64.h" -#include "src/objects/objects-inl.h" #include "src/snapshot/embedded/embedded-data.h" #include "src/snapshot/embedded/embedded-file-writer.h" #endif // V8_OS_WIN64 @@ -670,11 +669,7 @@ void PlatformEmbeddedFileWriterWin::DeclareExternalFilename( // Replace any Windows style paths (backslashes) with forward // slashes. std::string fixed_filename(filename); - for (auto& c : fixed_filename) { - if (c == '\\') { - c = '/'; - } - } + std::replace(fixed_filename.begin(), fixed_filename.end(), '\\', '/'); fprintf(fp_, ".file %d \"%s\"\n", fileid, fixed_filename.c_str()); } diff --git a/deps/v8/src/snapshot/natives-external.cc b/deps/v8/src/snapshot/natives-external.cc index fe67f3308720a9..4aa411dd92e9b7 100644 --- a/deps/v8/src/snapshot/natives-external.cc +++ b/deps/v8/src/snapshot/natives-external.cc @@ -61,9 +61,10 @@ class NativesStore { // We expect the libraries in the following format: // int: # of sources. // 2N blobs: N pairs of source name + actual source. - int library_count = source->GetInt(); - for (int i = 0; i < library_count; ++i) + int library_count = source->GetIntSlow(); + for (int i = 0; i < library_count; ++i) { store->ReadNameAndContentPair(source); + } return store; } diff --git a/deps/v8/src/snapshot/object-deserializer.cc b/deps/v8/src/snapshot/object-deserializer.cc index 63a0cfca175557..daada252ba2775 100644 --- a/deps/v8/src/snapshot/object-deserializer.cc +++ b/deps/v8/src/snapshot/object-deserializer.cc @@ -60,7 +60,9 @@ void ObjectDeserializer::FlushICache() { DCHECK(deserializing_user_code()); for (Code code : new_code_objects()) { // Record all references to embedded objects in the new code object. +#ifndef V8_DISABLE_WRITE_BARRIERS WriteBarrierForCode(code); +#endif FlushInstructionCache(code.raw_instruction_start(), code.raw_instruction_size()); } diff --git a/deps/v8/src/snapshot/partial-serializer.cc b/deps/v8/src/snapshot/partial-serializer.cc index 7b4ffbb2bfe1a1..c362fdb0ce4519 100644 --- a/deps/v8/src/snapshot/partial-serializer.cc +++ b/deps/v8/src/snapshot/partial-serializer.cc @@ -176,7 +176,8 @@ bool PartialSerializer::SerializeJSObjectWithEmbedderFields(Object obj) { } else { // If no serializer is provided and the field was empty, we serialize it // by default to nullptr. - if (serialize_embedder_fields_.callback == nullptr && object.ptr() == 0) { + if (serialize_embedder_fields_.callback == nullptr && + object == Smi::zero()) { serialized_data.push_back({nullptr, 0}); } else { DCHECK_NOT_NULL(serialize_embedder_fields_.callback); diff --git a/deps/v8/src/snapshot/serializer.cc b/deps/v8/src/snapshot/serializer.cc index 5b68aaa87bca22..f009f08fc74111 100644 --- a/deps/v8/src/snapshot/serializer.cc +++ b/deps/v8/src/snapshot/serializer.cc @@ -342,7 +342,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space, serializer_->SerializeObject(map); } -int32_t Serializer::ObjectSerializer::SerializeBackingStore( +uint32_t Serializer::ObjectSerializer::SerializeBackingStore( void* backing_store, int32_t byte_length) { SerializerReference reference = serializer_->reference_map()->LookupReference(backing_store); @@ -358,13 +358,15 @@ int32_t Serializer::ObjectSerializer::SerializeBackingStore( serializer_->reference_map()->Add(backing_store, reference); } - return static_cast<int32_t>(reference.off_heap_backing_store_index()); + return reference.off_heap_backing_store_index(); } void Serializer::ObjectSerializer::SerializeJSTypedArray() { JSTypedArray typed_array = JSTypedArray::cast(object_); - if (!typed_array.WasDetached()) { - if (!typed_array.is_on_heap()) { + if (typed_array.is_on_heap()) { + typed_array.RemoveExternalPointerCompensationForSerialization(); + } else { + if (!typed_array.WasDetached()) { // Explicitly serialize the backing store now. JSArrayBuffer buffer = JSArrayBuffer::cast(typed_array.buffer()); CHECK_LE(buffer.byte_length(), Smi::kMaxValue); @@ -372,21 +374,20 @@ void Serializer::ObjectSerializer::SerializeJSTypedArray() { int32_t byte_length = static_cast<int32_t>(buffer.byte_length()); int32_t byte_offset = static_cast<int32_t>(typed_array.byte_offset()); - // We need to calculate the backing store from the external pointer + // We need to calculate the backing store from the data pointer // because the ArrayBuffer may already have been serialized. void* backing_store = reinterpret_cast<void*>( - reinterpret_cast<intptr_t>(typed_array.external_pointer()) - - byte_offset); - int32_t ref = SerializeBackingStore(backing_store, byte_length); - - // The external_pointer is the backing_store + typed_array->byte_offset. - // To properly share the buffer, we set the backing store ref here. On - // deserialization we re-add the byte_offset to external_pointer. - typed_array.set_external_pointer( - reinterpret_cast<void*>(Smi::FromInt(ref).ptr())); + reinterpret_cast<Address>(typed_array.DataPtr()) - byte_offset); + + uint32_t ref = SerializeBackingStore(backing_store, byte_length); + // To properly share the buffer, we set the backing store ref as an + // off-heap offset from nullptr. On deserialization we re-set data + // pointer to proper value. + typed_array.SetOffHeapDataPtr(nullptr, ref); + DCHECK_EQ(ref, reinterpret_cast<Address>(typed_array.DataPtr())); + } else { + typed_array.SetOffHeapDataPtr(nullptr, 0); } - } else { - typed_array.set_external_pointer(nullptr); } SerializeObject(); } @@ -400,8 +401,11 @@ void Serializer::ObjectSerializer::SerializeJSArrayBuffer() { // The embedder-allocated backing store only exists for the off-heap case. if (backing_store != nullptr) { - int32_t ref = SerializeBackingStore(backing_store, byte_length); - buffer.set_backing_store(reinterpret_cast<void*>(Smi::FromInt(ref).ptr())); + uint32_t ref = SerializeBackingStore(backing_store, byte_length); + // To properly share the buffer, we set the backing store ref as an + // a backing store address. On deserialization we re-set data pointer + // to proper value. + buffer.set_backing_store(reinterpret_cast<void*>(static_cast<size_t>(ref))); } SerializeObject(); buffer.set_backing_store(backing_store); diff --git a/deps/v8/src/snapshot/serializer.h b/deps/v8/src/snapshot/serializer.h index fad2ec8a88fe77..73a9a1eaac46a8 100644 --- a/deps/v8/src/snapshot/serializer.h +++ b/deps/v8/src/snapshot/serializer.h @@ -328,7 +328,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor { void SerializeContent(Map map, int size); void OutputRawData(Address up_to); void OutputCode(int size); - int32_t SerializeBackingStore(void* backing_store, int32_t byte_length); + uint32_t SerializeBackingStore(void* backing_store, int32_t byte_length); void SerializeJSTypedArray(); void SerializeJSArrayBuffer(); void SerializeExternalString(); diff --git a/deps/v8/src/snapshot/snapshot-source-sink.h b/deps/v8/src/snapshot/snapshot-source-sink.h index f20f2ad33f5cbe..9cdb85089e1248 100644 --- a/deps/v8/src/snapshot/snapshot-source-sink.h +++ b/deps/v8/src/snapshot/snapshot-source-sink.h @@ -63,6 +63,24 @@ class SnapshotByteSource final { return answer; } + int GetIntSlow() { + // Unlike GetInt, this reads only up to the end of the blob, even if less + // than 4 bytes are remaining. + // TODO(jgruber): Remove once the use in MakeFromScriptsSource is gone. + DCHECK(position_ < length_); + uint32_t answer = data_[position_]; + if (position_ + 1 < length_) answer |= data_[position_ + 1] << 8; + if (position_ + 2 < length_) answer |= data_[position_ + 2] << 16; + if (position_ + 3 < length_) answer |= data_[position_ + 3] << 24; + int bytes = (answer & 3) + 1; + Advance(bytes); + uint32_t mask = 0xffffffffu; + mask >>= 32 - (bytes << 3); + answer &= mask; + answer >>= 2; + return answer; + } + // Returns length. int GetBlob(const byte** data); diff --git a/deps/v8/src/snapshot/snapshot.h b/deps/v8/src/snapshot/snapshot.h index f7e1e86b845ba5..4a4da9f755484b 100644 --- a/deps/v8/src/snapshot/snapshot.h +++ b/deps/v8/src/snapshot/snapshot.h @@ -8,7 +8,6 @@ #include "src/snapshot/partial-serializer.h" #include "src/snapshot/startup-serializer.h" -#include "src/objects/objects-inl.h" #include "src/utils/utils.h" namespace v8 { diff --git a/deps/v8/src/strings/string-hasher-inl.h b/deps/v8/src/strings/string-hasher-inl.h index b547d0a78da5b9..0c69e6c7baa15a 100644 --- a/deps/v8/src/strings/string-hasher-inl.h +++ b/deps/v8/src/strings/string-hasher-inl.h @@ -34,32 +34,63 @@ uint32_t StringHasher::GetHashCore(uint32_t running_hash) { uint32_t StringHasher::GetTrivialHash(int length) { DCHECK_GT(length, String::kMaxHashCalcLength); // String hash of a large string is simply the length. - return (length << String::kHashShift) | String::kIsNotArrayIndexMask; + return (static_cast<uint32_t>(length) << String::kHashShift) | + String::kIsNotArrayIndexMask | String::kIsNotIntegerIndexMask; } template <typename schar> uint32_t StringHasher::HashSequentialString(const schar* chars, int length, uint64_t seed) { - // Check whether the string is a valid array index. In that case, compute the - // array index hash. It'll fall through to compute a regular string hash from - // the start if it turns out that the string isn't a valid array index. - if (IsInRange(length, 1, String::kMaxArrayIndexSize)) { + DCHECK_LE(0, length); + DCHECK_IMPLIES(0 < length, chars != nullptr); + if (length >= 1) { if (IsDecimalDigit(chars[0]) && (length == 1 || chars[0] != '0')) { - uint32_t index = chars[0] - '0'; - int i = 1; - do { - if (i == length) { - return MakeArrayIndexHash(index, length); + uint32_t index = 0; + if (length <= String::kMaxArrayIndexSize) { + // Possible array index; try to compute the array index hash. + index = chars[0] - '0'; + int i = 1; + do { + if (i == length) { + return MakeArrayIndexHash(index, length); + } + } while (TryAddIndexChar(&index, chars[i++])); + } + // The following block wouldn't do anything on 32-bit platforms, + // because kMaxArrayIndexSize == kMaxIntegerIndexSize there, and + // if we wanted to compile it everywhere, then {index_big} would + // have to be a {size_t}, which the Mac compiler doesn't like to + // implicitly cast to uint64_t for the {TryAddIndexChar} call. +#if V8_HOST_ARCH_64_BIT + // No "else" here: if the block above was entered and fell through, + // we'll have to take this branch. + if (length <= String::kMaxIntegerIndexSize) { + // Not an array index, but it could still be an integer index. + // Perform a regular hash computation, and additionally check + // if there are non-digit characters. + uint32_t is_integer_index = 0; + uint32_t running_hash = static_cast<uint32_t>(seed); + uint64_t index_big = index; + const schar* end = &chars[length]; + while (chars != end) { + if (is_integer_index == 0 && !TryAddIndexChar(&index_big, *chars)) { + is_integer_index = String::kIsNotIntegerIndexMask; + } + running_hash = AddCharacterCore(running_hash, *chars++); } - } while (TryAddIndexChar(&index, chars[i++])); + return (GetHashCore(running_hash) << String::kHashShift) | + String::kIsNotArrayIndexMask | is_integer_index; + } +#endif + } + // No "else" here: if the first character was a decimal digit, we might + // still have to take this branch. + if (length > String::kMaxHashCalcLength) { + return GetTrivialHash(length); } - } else if (length > String::kMaxHashCalcLength) { - return GetTrivialHash(length); } - // Non-array-index hash. - DCHECK_LE(0, length); - DCHECK_IMPLIES(0 < length, chars != nullptr); + // Non-index hash. uint32_t running_hash = static_cast<uint32_t>(seed); const schar* end = &chars[length]; while (chars != end) { @@ -67,7 +98,7 @@ uint32_t StringHasher::HashSequentialString(const schar* chars, int length, } return (GetHashCore(running_hash) << String::kHashShift) | - String::kIsNotArrayIndexMask; + String::kIsNotArrayIndexMask | String::kIsNotIntegerIndexMask; } std::size_t SeededStringHasher::operator()(const char* name) const { diff --git a/deps/v8/src/strings/string-stream.cc b/deps/v8/src/strings/string-stream.cc index 25a8ffc3c1a795..5747f66bba1835 100644 --- a/deps/v8/src/strings/string-stream.cc +++ b/deps/v8/src/strings/string-stream.cc @@ -298,9 +298,8 @@ void StringStream::PrintName(Object name) { void StringStream::PrintUsingMap(JSObject js_object) { Map map = js_object.map(); - int real_size = map.NumberOfOwnDescriptors(); DescriptorArray descs = map.instance_descriptors(); - for (int i = 0; i < real_size; i++) { + for (InternalIndex i : map.IterateOwnDescriptors()) { PropertyDetails details = descs.GetDetails(i); if (details.location() == kField) { DCHECK_EQ(kData, details.kind()); diff --git a/deps/v8/src/strings/string-stream.h b/deps/v8/src/strings/string-stream.h index d7b616c6ff7648..3a2ba0dd354285 100644 --- a/deps/v8/src/strings/string-stream.h +++ b/deps/v8/src/strings/string-stream.h @@ -5,6 +5,8 @@ #ifndef V8_STRINGS_STRING_STREAM_H_ #define V8_STRINGS_STRING_STREAM_H_ +#include <memory> + #include "src/base/small-vector.h" #include "src/handles/handles.h" #include "src/objects/heap-object.h" diff --git a/deps/v8/src/strings/uri.cc b/deps/v8/src/strings/uri.cc index 430c8dd0ebec85..de4e339b3926cd 100644 --- a/deps/v8/src/strings/uri.cc +++ b/deps/v8/src/strings/uri.cc @@ -195,10 +195,14 @@ MaybeHandle<String> Uri::Decode(Isolate* isolate, Handle<String> uri, String); DisallowHeapAllocation no_gc; - CopyChars(result->GetChars(no_gc), one_byte_buffer.data(), - one_byte_buffer.size()); - CopyChars(result->GetChars(no_gc) + one_byte_buffer.size(), - two_byte_buffer.data(), two_byte_buffer.size()); + uc16* chars = result->GetChars(no_gc); + if (!one_byte_buffer.empty()) { + CopyChars(chars, one_byte_buffer.data(), one_byte_buffer.size()); + chars += one_byte_buffer.size(); + } + if (!two_byte_buffer.empty()) { + CopyChars(chars, two_byte_buffer.data(), two_byte_buffer.size()); + } return result; } diff --git a/deps/v8/src/tasks/OWNERS b/deps/v8/src/tasks/OWNERS index 2c6630da0c37a7..d31f346b03fc83 100644 --- a/deps/v8/src/tasks/OWNERS +++ b/deps/v8/src/tasks/OWNERS @@ -1,5 +1,5 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org mlippautz@chromium.org mstarzinger@chromium.org rmcilroy@chromium.org diff --git a/deps/v8/src/tasks/task-utils.cc b/deps/v8/src/tasks/task-utils.cc index 2b75c4549c4c14..50edeccf14837b 100644 --- a/deps/v8/src/tasks/task-utils.cc +++ b/deps/v8/src/tasks/task-utils.cc @@ -42,22 +42,22 @@ class CancelableIdleFuncTask final : public CancelableIdleTask { std::unique_ptr<CancelableTask> MakeCancelableTask(Isolate* isolate, std::function<void()> func) { - return base::make_unique<CancelableFuncTask>(isolate, std::move(func)); + return std::make_unique<CancelableFuncTask>(isolate, std::move(func)); } std::unique_ptr<CancelableTask> MakeCancelableTask( CancelableTaskManager* manager, std::function<void()> func) { - return base::make_unique<CancelableFuncTask>(manager, std::move(func)); + return std::make_unique<CancelableFuncTask>(manager, std::move(func)); } std::unique_ptr<CancelableIdleTask> MakeCancelableIdleTask( Isolate* isolate, std::function<void(double)> func) { - return base::make_unique<CancelableIdleFuncTask>(isolate, std::move(func)); + return std::make_unique<CancelableIdleFuncTask>(isolate, std::move(func)); } std::unique_ptr<CancelableIdleTask> MakeCancelableIdleTask( CancelableTaskManager* manager, std::function<void(double)> func) { - return base::make_unique<CancelableIdleFuncTask>(manager, std::move(func)); + return std::make_unique<CancelableIdleFuncTask>(manager, std::move(func)); } } // namespace internal diff --git a/deps/v8/src/torque/ast.h b/deps/v8/src/torque/ast.h index 5ce25cf13ab473..fcbb02124d4d16 100644 --- a/deps/v8/src/torque/ast.h +++ b/deps/v8/src/torque/ast.h @@ -90,7 +90,8 @@ namespace torque { AST_STATEMENT_NODE_KIND_LIST(V) \ AST_DECLARATION_NODE_KIND_LIST(V) \ V(Identifier) \ - V(LabelBlock) + V(LabelBlock) \ + V(ClassBody) struct AstNode { public: @@ -792,6 +793,12 @@ struct TypeDeclaration : Declaration { Identifier* name; }; +struct InstanceTypeConstraints { + InstanceTypeConstraints() : value(-1), num_flags_bits(-1) {} + int value; + int num_flags_bits; +}; + struct AbstractTypeDeclaration : TypeDeclaration { DEFINE_AST_NODE_LEAF_BOILERPLATE(AbstractTypeDeclaration) AbstractTypeDeclaration(SourcePosition pos, Identifier* name, bool transient, @@ -1069,24 +1076,38 @@ struct StructDeclaration : TypeDeclaration { bool IsGeneric() const { return !generic_parameters.empty(); } }; +struct ClassBody : AstNode { + DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassBody) + ClassBody(SourcePosition pos, std::vector<Declaration*> methods, + std::vector<ClassFieldExpression> fields) + : AstNode(kKind, pos), + methods(std::move(methods)), + fields(std::move(fields)) {} + std::vector<Declaration*> methods; + std::vector<ClassFieldExpression> fields; +}; + struct ClassDeclaration : TypeDeclaration { DEFINE_AST_NODE_LEAF_BOILERPLATE(ClassDeclaration) ClassDeclaration(SourcePosition pos, Identifier* name, ClassFlags flags, base::Optional<TypeExpression*> super, base::Optional<std::string> generates, std::vector<Declaration*> methods, - std::vector<ClassFieldExpression> fields) + std::vector<ClassFieldExpression> fields, + InstanceTypeConstraints instance_type_constraints) : TypeDeclaration(kKind, pos, name), flags(flags), super(super), generates(std::move(generates)), methods(std::move(methods)), - fields(std::move(fields)) {} + fields(std::move(fields)), + instance_type_constraints(std::move(instance_type_constraints)) {} ClassFlags flags; base::Optional<TypeExpression*> super; base::Optional<std::string> generates; std::vector<Declaration*> methods; std::vector<ClassFieldExpression> fields; + InstanceTypeConstraints instance_type_constraints; }; struct CppIncludeDeclaration : Declaration { diff --git a/deps/v8/src/torque/class-debug-reader-generator.cc b/deps/v8/src/torque/class-debug-reader-generator.cc index 6abdffcc91feb5..fca24099596c1d 100644 --- a/deps/v8/src/torque/class-debug-reader-generator.cc +++ b/deps/v8/src/torque/class-debug-reader-generator.cc @@ -10,12 +10,20 @@ namespace v8 { namespace internal { namespace torque { +const char* tq_object_override_decls = + R"( std::vector<std::unique_ptr<ObjectProperty>> GetProperties( + d::MemoryAccessor accessor) const override; + const char* GetName() const override; + void Visit(TqObjectVisitor* visitor) const override; + bool IsSuperclassOf(const TqObject* other) const override; +)"; + namespace { void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, std::ostream& cc_contents, std::ostream& visitor, std::unordered_set<const ClassType*>* done) { // Make sure each class only gets generated once. - if (!type.IsExtern() || !done->insert(&type).second) return; + if (!done->insert(&type).second) return; const ClassType* super_type = type.GetSuperClass(); // We must emit the classes in dependency order. If the super class hasn't @@ -25,6 +33,10 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, done); } + // Classes with undefined layout don't grant any particular value here and may + // not correspond with actual C++ classes, so skip them. + if (type.HasUndefinedLayout()) return; + const std::string name = type.name(); const std::string super_name = super_type == nullptr ? "Object" : super_type->name(); @@ -32,10 +44,7 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, h_contents << " public:\n"; h_contents << " inline Tq" << name << "(uintptr_t address) : Tq" << super_name << "(address) {}\n"; - h_contents << " std::vector<std::unique_ptr<ObjectProperty>> " - "GetProperties(d::MemoryAccessor accessor) const override;\n"; - h_contents << " const char* GetName() const override;\n"; - h_contents << " void Visit(TqObjectVisitor* visitor) const override;\n"; + h_contents << tq_object_override_decls; cc_contents << "\nconst char* Tq" << name << "::GetName() const {\n"; cc_contents << " return \"v8::internal::" << name << "\";\n"; @@ -46,6 +55,13 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, cc_contents << " visitor->Visit" << name << "(this);\n"; cc_contents << "}\n"; + cc_contents << "\nbool Tq" << name + << "::IsSuperclassOf(const TqObject* other) const {\n"; + cc_contents + << " return GetName() != other->GetName() && dynamic_cast<const Tq" + << name << "*>(other) != nullptr;\n"; + cc_contents << "}\n"; + visitor << " virtual void Visit" << name << "(const Tq" << name << "* object) {\n"; visitor << " Visit" << super_name << "(object);\n"; @@ -71,9 +87,10 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, if (is_field_tagged) { field_value_type = "uintptr_t"; field_value_type_compressed = "i::Tagged_t"; - field_cc_type = "v8::internal::" + (field_class_type.has_value() - ? (*field_class_type)->name() - : "Object"); + field_cc_type = "v8::internal::" + + (field_class_type.has_value() + ? (*field_class_type)->GetGeneratedTNodeTypeName() + : "Object"); field_cc_type_compressed = COMPRESS_POINTERS_BOOL ? "v8::internal::TaggedValue" : field_cc_type; } else { @@ -107,7 +124,7 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, std::string index_param; std::string index_offset; if (field.index) { - const Type* index_type = (*field.index)->name_and_type.type; + const Type* index_type = field.index->type; std::string index_type_name; std::string index_value; if (index_type == TypeOracle::GetSmiType()) { @@ -129,18 +146,17 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, } get_props_impl << " Value<" << index_type_name << "> indexed_field_count = Get" - << CamelifyString((*field.index)->name_and_type.name) + << CamelifyString(field.index->name) << "Value(accessor);\n"; indexed_field_info = ", " + index_value + ", GetArrayKind(indexed_field_count.validity)"; index_param = ", size_t offset"; index_offset = " + offset * sizeof(value)"; } - get_props_impl - << " result.push_back(v8::base::make_unique<ObjectProperty>(\"" - << field_name << "\", \"" << field_cc_type_compressed << "\", \"" - << field_cc_type << "\", " << address_getter << "()" - << indexed_field_info << "));\n"; + get_props_impl << " result.push_back(std::make_unique<ObjectProperty>(\"" + << field_name << "\", \"" << field_cc_type_compressed + << "\", \"" << field_cc_type << "\", " << address_getter + << "()" << indexed_field_info << "));\n"; h_contents << " uintptr_t " << address_getter << "() const;\n"; h_contents << " Value<" << field_value_type << "> " << field_getter @@ -158,7 +174,8 @@ void GenerateClassDebugReader(const ClassType& type, std::ostream& h_contents, << address_getter << "()" << index_offset << ", reinterpret_cast<uint8_t*>(&value), sizeof(value));\n"; cc_contents << " return {validity, " - << (is_field_tagged ? "Decompress(value, address_)" : "value") + << (is_field_tagged ? "EnsureDecompressed(value, address_)" + : "value") << "};\n"; cc_contents << "}\n"; } @@ -192,6 +209,11 @@ void ImplementationVisitor::GenerateClassDebugReaders( h_contents << "\n#include \"tools/debug_helper/debug-helper-internal.h\"\n\n"; + h_contents << "// Unset a windgi.h macro that causes conflicts.\n"; + h_contents << "#ifdef GetBValue\n"; + h_contents << "#undef GetBValue\n"; + h_contents << "#endif\n\n"; + cc_contents << "#include \"torque-generated/" << file_name << ".h\"\n"; cc_contents << "#include \"include/v8-internal.h\"\n\n"; cc_contents << "namespace i = v8::internal;\n\n"; diff --git a/deps/v8/src/torque/constants.h b/deps/v8/src/torque/constants.h index efbbf9588ee8b0..ebfbab0cba5ccb 100644 --- a/deps/v8/src/torque/constants.h +++ b/deps/v8/src/torque/constants.h @@ -55,6 +55,25 @@ static const char* const REFERENCE_TYPE_STRING = "Reference"; static const char* const SLICE_TYPE_STRING = "Slice"; static const char* const STRUCT_NAMESPACE_STRING = "_struct"; +static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint"; +static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier"; +static const char* const ANNOTATION_ABSTRACT = "@abstract"; +static const char* const ANNOTATION_INSTANTIATED_ABSTRACT_CLASS = + "@dirtyInstantiatedAbstractClass"; +static const char* const ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT = + "@hasSameInstanceTypeAsParent"; +static const char* const ANNOTATION_GENERATE_CPP_CLASS = "@generateCppClass"; +static const char* const ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT = + "@highestInstanceTypeWithinParentClassRange"; +static const char* const ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT = + "@lowestInstanceTypeWithinParentClassRange"; +static const char* const ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE = + "@reserveBitsInInstanceType"; +static const char* const ANNOTATION_INSTANCE_TYPE_VALUE = + "@apiExposedInstanceTypeValue"; +static const char* const ANNOTATION_IF = "@if"; +static const char* const ANNOTATION_IFNOT = "@ifnot"; + inline bool IsConstexprName(const std::string& name) { return name.substr(0, std::strlen(CONSTEXPR_TYPE_PREFIX)) == CONSTEXPR_TYPE_PREFIX; @@ -80,7 +99,10 @@ enum class ClassFlag { kInstantiatedAbstractClass = 1 << 5, kHasSameInstanceTypeAsParent = 1 << 6, kGenerateCppClassDefinitions = 1 << 7, - kHasIndexedField = 1 << 8 + kHasIndexedField = 1 << 8, + kHighestInstanceTypeWithinParent = 1 << 9, + kLowestInstanceTypeWithinParent = 1 << 10, + kUndefinedLayout = 1 << 11, }; using ClassFlags = base::Flags<ClassFlag>; diff --git a/deps/v8/src/torque/csa-generator.cc b/deps/v8/src/torque/csa-generator.cc index 7925783914ab14..2a10e4f3530908 100644 --- a/deps/v8/src/torque/csa-generator.cc +++ b/deps/v8/src/torque/csa-generator.cc @@ -41,7 +41,7 @@ Stack<std::string> CSAGenerator::EmitBlock(const Block* block) { Stack<std::string> stack; for (const Type* t : block->InputTypes()) { stack.Push(FreshNodeName()); - out_ << " compiler::TNode<" << t->GetGeneratedTNodeTypeName() << "> " + out_ << " TNode<" << t->GetGeneratedTNodeTypeName() << "> " << stack.Top() << ";\n"; } out_ << " ca_.Bind(&" << BlockName(block); @@ -56,14 +56,10 @@ Stack<std::string> CSAGenerator::EmitBlock(const Block* block) { } void CSAGenerator::EmitSourcePosition(SourcePosition pos, bool always_emit) { - std::string file = SourceFileMap::AbsolutePath(pos.source); + const std::string& file = SourceFileMap::AbsolutePath(pos.source); if (always_emit || !previous_position_.CompareStartIgnoreColumn(pos)) { // Lines in Torque SourcePositions are zero-based, while the // CodeStubAssembler and downwind systems are one-based. - for (auto& c : file) { - if (c == '\\') - c = '/'; - } out_ << " ca_.SetSourcePosition(\"" << file << "\", " << (pos.start.line + 1) << ");\n"; previous_position_ = pos; @@ -123,8 +119,8 @@ void CSAGenerator::EmitInstruction( for (const Type* lowered : LowerType(type)) { results.push_back(FreshNodeName()); stack->Push(results.back()); - out_ << " compiler::TNode<" << lowered->GetGeneratedTNodeTypeName() - << "> " << stack->Top() << ";\n"; + out_ << " TNode<" << lowered->GetGeneratedTNodeTypeName() << "> " + << stack->Top() << ";\n"; out_ << " USE(" << stack->Top() << ");\n"; } out_ << " "; @@ -179,7 +175,7 @@ void CSAGenerator::EmitInstruction(const CallIntrinsicInstruction& instruction, for (const Type* type : LowerType(return_type)) { results.push_back(FreshNodeName()); stack->Push(results.back()); - out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> " + out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> " << stack->Top() << ";\n"; out_ << " USE(" << stack->Top() << ");\n"; } @@ -302,7 +298,7 @@ void CSAGenerator::EmitInstruction(const CallCsaMacroInstruction& instruction, for (const Type* type : LowerType(return_type)) { results.push_back(FreshNodeName()); stack->Push(results.back()); - out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() << "> " + out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> " << stack->Top() << ";\n"; out_ << " USE(" << stack->Top() << ");\n"; } @@ -354,8 +350,8 @@ void CSAGenerator::EmitInstruction( for (const Type* type : LowerType(instruction.macro->signature().return_type)) { results.push_back(FreshNodeName()); - out_ << " compiler::TNode<" << type->GetGeneratedTNodeTypeName() - << "> " << results.back() << ";\n"; + out_ << " TNode<" << type->GetGeneratedTNodeTypeName() << "> " + << results.back() << ";\n"; out_ << " USE(" << results.back() << ");\n"; } } @@ -453,9 +449,8 @@ void CSAGenerator::EmitInstruction(const CallBuiltinInstruction& instruction, } else { std::string result_name = FreshNodeName(); if (result_types.size() == 1) { - out_ << " compiler::TNode<" - << result_types[0]->GetGeneratedTNodeTypeName() << "> " - << result_name << ";\n"; + out_ << " TNode<" << result_types[0]->GetGeneratedTNodeTypeName() + << "> " << result_name << ";\n"; } std::string catch_name = PreCallableExceptionPreparation(instruction.catch_block); @@ -503,8 +498,7 @@ void CSAGenerator::EmitInstruction( stack->Push(FreshNodeName()); std::string generated_type = result_types[0]->GetGeneratedTNodeTypeName(); - out_ << " compiler::TNode<" << generated_type << "> " << stack->Top() - << " = "; + out_ << " TNode<" << generated_type << "> " << stack->Top() << " = "; if (generated_type != "Object") out_ << "TORQUE_CAST("; out_ << "CodeStubAssembler(state_).CallBuiltinPointer(Builtins::" "CallableFor(ca_." @@ -543,8 +537,7 @@ void CSAGenerator::PostCallableExceptionPreparation( if (!return_type->IsNever()) { out_ << " ca_.Goto(&" << catch_name << "_skip);\n"; } - out_ << " compiler::TNode<Object> " << catch_name - << "_exception_object;\n"; + out_ << " TNode<Object> " << catch_name << "_exception_object;\n"; out_ << " ca_.Bind(&" << catch_name << "__label, &" << catch_name << "_exception_object);\n"; out_ << " ca_.Goto(&" << block_name; @@ -579,9 +572,8 @@ void CSAGenerator::EmitInstruction(const CallRuntimeInstruction& instruction, } else { std::string result_name = FreshNodeName(); if (result_types.size() == 1) { - out_ << " compiler::TNode<" - << result_types[0]->GetGeneratedTNodeTypeName() << "> " - << result_name << ";\n"; + out_ << " TNode<" << result_types[0]->GetGeneratedTNodeTypeName() + << "> " << result_name << ";\n"; } std::string catch_name = PreCallableExceptionPreparation(instruction.catch_block); @@ -722,10 +714,9 @@ void CSAGenerator::EmitInstruction( std::string offset_name = FreshNodeName(); stack->Push(offset_name); - out_ << " compiler::TNode<IntPtrT> " << offset_name - << " = ca_.IntPtrConstant("; - out_ << field.aggregate->GetGeneratedTNodeTypeName() << "::k" - << CamelifyString(field.name_and_type.name) << "Offset"; + out_ << " TNode<IntPtrT> " << offset_name << " = ca_.IntPtrConstant("; + out_ << field.aggregate->GetGeneratedTNodeTypeName() << "::k" + << CamelifyString(field.name_and_type.name) << "Offset"; out_ << ");\n" << " USE(" << stack->Top() << ");\n"; } @@ -776,8 +767,8 @@ void CSAGenerator::EmitCSAValue(VisitResult result, out << "}"; } else { DCHECK_EQ(1, result.stack_range().Size()); - out << "compiler::TNode<" << result.type()->GetGeneratedTNodeTypeName() - << ">{" << values.Peek(result.stack_range().begin()) << "}"; + out << "TNode<" << result.type()->GetGeneratedTNodeTypeName() << ">{" + << values.Peek(result.stack_range().begin()) << "}"; } } diff --git a/deps/v8/src/torque/declaration-visitor.cc b/deps/v8/src/torque/declaration-visitor.cc index f762337463cedd..c2fa1af98e8264 100644 --- a/deps/v8/src/torque/declaration-visitor.cc +++ b/deps/v8/src/torque/declaration-visitor.cc @@ -93,20 +93,6 @@ Builtin* DeclarationVisitor::CreateBuiltin(BuiltinDeclaration* decl, } } - if (TorqueBuiltinDeclaration::DynamicCast(decl)) { - for (size_t i = 0; i < signature.types().size(); ++i) { - const Type* type = signature.types()[i]; - if (!type->IsSubtypeOf(TypeOracle::GetTaggedType())) { - const Identifier* id = signature.parameter_names.size() > i - ? signature.parameter_names[i] - : nullptr; - Error("Untagged argument ", id ? (id->value + " ") : "", "at position ", - i, " to builtin ", decl->name, " is not supported.") - .Position(id ? id->pos : decl->pos); - } - } - } - if (const StructType* struct_type = StructType::DynamicCast(signature.return_type)) { Error("Builtins ", decl->name, " cannot return structs ", diff --git a/deps/v8/src/torque/declarations.h b/deps/v8/src/torque/declarations.h index 240680fa1e1bde..f3d2544ae1c46c 100644 --- a/deps/v8/src/torque/declarations.h +++ b/deps/v8/src/torque/declarations.h @@ -5,6 +5,7 @@ #ifndef V8_TORQUE_DECLARATIONS_H_ #define V8_TORQUE_DECLARATIONS_H_ +#include <memory> #include <string> #include "src/torque/declarable.h" diff --git a/deps/v8/src/torque/earley-parser.h b/deps/v8/src/torque/earley-parser.h index 9f7ba6a7aee6a5..43ad6eb4523725 100644 --- a/deps/v8/src/torque/earley-parser.h +++ b/deps/v8/src/torque/earley-parser.h @@ -6,6 +6,7 @@ #define V8_TORQUE_EARLEY_PARSER_H_ #include <map> +#include <memory> #include <vector> #include "src/base/optional.h" @@ -82,6 +83,7 @@ enum class ParseResultHolderBase::TypeId { kTypeswitchCase, kStdVectorOfTypeswitchCase, kStdVectorOfIdentifierPtr, + kOptionalClassBody, kJsonValue, kJsonMember, @@ -248,7 +250,7 @@ class Symbol { size_t rule_number() const { return rules_.size(); } void AddRule(const Rule& rule) { - rules_.push_back(base::make_unique<Rule>(rule)); + rules_.push_back(std::make_unique<Rule>(rule)); rules_.back()->SetLeftHandSide(this); } diff --git a/deps/v8/src/torque/global-context.cc b/deps/v8/src/torque/global-context.cc index 13503038c55810..e236de5a93e861 100644 --- a/deps/v8/src/torque/global-context.cc +++ b/deps/v8/src/torque/global-context.cc @@ -19,7 +19,7 @@ GlobalContext::GlobalContext(Ast ast) CurrentSourcePosition::Scope current_source_position( SourcePosition{CurrentSourceFile::Get(), {-1, -1}, {-1, -1}}); default_namespace_ = - RegisterDeclarable(base::make_unique<Namespace>(kBaseNamespaceName)); + RegisterDeclarable(std::make_unique<Namespace>(kBaseNamespaceName)); } TargetArchitecture::TargetArchitecture(bool force_32bit) diff --git a/deps/v8/src/torque/global-context.h b/deps/v8/src/torque/global-context.h index e1106adbd1c117..940325b51aafff 100644 --- a/deps/v8/src/torque/global-context.h +++ b/deps/v8/src/torque/global-context.h @@ -6,6 +6,7 @@ #define V8_TORQUE_GLOBAL_CONTEXT_H_ #include <map> +#include <memory> #include "src/common/globals.h" #include "src/torque/ast.h" diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc index 8f36afd020fe32..0c50a7009903a4 100644 --- a/deps/v8/src/torque/implementation-visitor.cc +++ b/deps/v8/src/torque/implementation-visitor.cc @@ -526,7 +526,6 @@ void ImplementationVisitor::Visit(Builtin* builtin) { source_out() << " USE(" << parameter0 << ");\n"; for (size_t i = 1; i < signature.parameter_names.size(); ++i) { - const std::string& parameter_name = signature.parameter_names[i]->value; const Type* type = signature.types()[i]; const bool mark_as_used = signature.implicit_count > i; std::string var = AddParameter(i, builtin, ¶meters, ¶meter_types, @@ -534,8 +533,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) { source_out() << " " << type->GetGeneratedTypeName() << " " << var << " = " << "UncheckedCast<" << type->GetGeneratedTNodeTypeName() - << ">(Parameter(Descriptor::k" - << CamelifyString(parameter_name) << "));\n"; + << ">(Parameter(Descriptor::ParameterIndex<" << (i - 1) + << ">()));\n"; source_out() << " USE(" << var << ");\n"; } } @@ -1008,48 +1007,40 @@ const Type* ImplementationVisitor::Visit(AssertStatement* stmt) { #if defined(DEBUG) do_check = true; #endif - if (do_check) { - // CSA_ASSERT & co. are not used here on purpose for two reasons. First, - // Torque allows and handles two types of expressions in the if protocol - // automagically, ones that return TNode<BoolT> and those that use the - // BranchIf(..., Label* true, Label* false) idiom. Because the machinery to - // handle this is embedded in the expression handling and to it's not - // possible to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH - // isn't trivial up-front. Secondly, on failure, the assert text should be - // the corresponding Torque code, not the -gen.cc code, which would be the - // case when using CSA_ASSERT_XXX. - Block* true_block = assembler().NewBlock(assembler().CurrentStack()); - Block* false_block = assembler().NewBlock(assembler().CurrentStack(), true); - GenerateExpressionBranch(stmt->expression, true_block, false_block); + Block* resume_block; + + if (!do_check) { + Block* unreachable_block = assembler().NewBlock(assembler().CurrentStack()); + resume_block = assembler().NewBlock(assembler().CurrentStack()); + assembler().Goto(resume_block); + assembler().Bind(unreachable_block); + } + + // CSA_ASSERT & co. are not used here on purpose for two reasons. First, + // Torque allows and handles two types of expressions in the if protocol + // automagically, ones that return TNode<BoolT> and those that use the + // BranchIf(..., Label* true, Label* false) idiom. Because the machinery to + // handle this is embedded in the expression handling and to it's not + // possible to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH + // isn't trivial up-front. Secondly, on failure, the assert text should be + // the corresponding Torque code, not the -gen.cc code, which would be the + // case when using CSA_ASSERT_XXX. + Block* true_block = assembler().NewBlock(assembler().CurrentStack()); + Block* false_block = assembler().NewBlock(assembler().CurrentStack(), true); + GenerateExpressionBranch(stmt->expression, true_block, false_block); - assembler().Bind(false_block); + assembler().Bind(false_block); - assembler().Emit(AbortInstruction{ - AbortInstruction::Kind::kAssertionFailure, - "Torque assert '" + FormatAssertSource(stmt->source) + "' failed"}); + assembler().Emit(AbortInstruction{ + AbortInstruction::Kind::kAssertionFailure, + "Torque assert '" + FormatAssertSource(stmt->source) + "' failed"}); - assembler().Bind(true_block); - } else { - // Visit the expression so bindings only used in asserts are marked - // as such. Otherwise they might be wrongly reported as unused bindings - // in release builds. - stmt->expression->VisitAllSubExpressions([](Expression* expression) { - if (auto id = IdentifierExpression::DynamicCast(expression)) { - ValueBindingsManager::Get().TryLookup(id->name->value); - } else if (auto call = CallExpression::DynamicCast(expression)) { - for (Identifier* label : call->labels) { - LabelBindingsManager::Get().TryLookup(label->value); - } - // TODO(szuend): In case the call expression resolves to a macro - // callable, mark the macro as used as well. - } else if (auto call = CallMethodExpression::DynamicCast(expression)) { - for (Identifier* label : call->labels) { - LabelBindingsManager::Get().TryLookup(label->value); - } - // TODO(szuend): Mark the underlying macro as used. - } - }); + assembler().Bind(true_block); + + if (!do_check) { + assembler().Bind(resume_block); } + return TypeOracle::GetVoidType(); } @@ -1214,16 +1205,16 @@ InitializerResults ImplementationVisitor::VisitInitializerResults( result.names.push_back(initializer.name); Expression* e = initializer.expression; const Field& field = class_type->LookupField(initializer.name->value); - auto field_index = field.index; + bool has_index = field.index.has_value(); if (SpreadExpression* s = SpreadExpression::DynamicCast(e)) { - if (!field_index) { + if (!has_index) { ReportError( "spread expressions can only be used to initialize indexed class " "fields ('", initializer.name->value, "' is not)"); } e = s->spreadee; - } else if (field_index) { + } else if (has_index) { ReportError("the indexed class field '", initializer.name->value, "' must be initialized with a spread operator"); } @@ -1261,7 +1252,7 @@ void ImplementationVisitor::InitializeClass( void ImplementationVisitor::InitializeFieldFromSpread( VisitResult object, const Field& field, const InitializerResults& initializer_results) { - NameAndType index = (*field.index)->name_and_type; + const NameAndType& index = *field.index; VisitResult iterator = initializer_results.field_value_map.at(field.name_and_type.name); VisitResult length = initializer_results.field_value_map.at(index.name); @@ -1289,15 +1280,14 @@ VisitResult ImplementationVisitor::AddVariableObjectSize( } VisitResult index_field_size = VisitResult(TypeOracle::GetConstInt31Type(), "kTaggedSize"); - VisitResult initializer_value = initializer_results.field_value_map.at( - (*current_field->index)->name_and_type.name); + VisitResult initializer_value = + initializer_results.field_value_map.at(current_field->index->name); Arguments args; args.parameters.push_back(object_size); args.parameters.push_back(initializer_value); args.parameters.push_back(index_field_size); - object_size = - GenerateCall("%AddIndexedFieldSizeToObjectSize", args, - {(*current_field->index)->name_and_type.type}, false); + object_size = GenerateCall("%AddIndexedFieldSizeToObjectSize", args, + {current_field->index->type}, false); } ++current_field; } @@ -1860,12 +1850,12 @@ LocationReference ImplementationVisitor::GetLocationReference( { StackScope length_scope(this); // Get a reference to the length - const Field* index_field = field.index.value(); + const NameAndType& index_field = field.index.value(); GenerateCopy(object_result); - assembler().Emit(CreateFieldReferenceInstruction{ - object_result.type(), index_field->name_and_type.name}); + assembler().Emit(CreateFieldReferenceInstruction{object_result.type(), + index_field.name}); VisitResult length_reference( - TypeOracle::GetReferenceType(index_field->name_and_type.type), + TypeOracle::GetReferenceType(index_field.type), assembler().TopRange(2)); // Load the length from the reference and convert it to intptr @@ -2670,13 +2660,34 @@ void ImplementationVisitor::Visit(Declarable* declarable) { } } -void ImplementationVisitor::GenerateBuiltinDefinitions( +std::string MachineTypeString(const Type* type) { + if (type->IsSubtypeOf(TypeOracle::GetSmiType())) { + return "MachineType::TaggedSigned()"; + } + if (type->IsSubtypeOf(TypeOracle::GetHeapObjectType())) { + return "MachineType::TaggedPointer()"; + } + if (type->IsSubtypeOf(TypeOracle::GetTaggedType())) { + return "MachineType::AnyTagged()"; + } + return "MachineTypeOf<" + type->GetGeneratedTNodeTypeName() + ">::value"; +} + +void ImplementationVisitor::GenerateBuiltinDefinitionsAndInterfaceDescriptors( const std::string& output_directory) { - std::stringstream new_contents_stream; - std::string file_name = "builtin-definitions-tq.h"; + std::stringstream builtin_definitions; + std::string builtin_definitions_file_name = "builtin-definitions-tq.h"; + + // This file contains plain interface descriptor definitions and has to be + // included in the middle of interface-descriptors.h. Thus it is not a normal + // header file and uses the .inc suffix instead of the .h suffix. + std::stringstream interface_descriptors; + std::string interface_descriptors_file_name = "interface-descriptors-tq.inc"; { - IncludeGuardScope include_guard(new_contents_stream, file_name); - new_contents_stream + IncludeGuardScope builtin_definitions_include_guard( + builtin_definitions, builtin_definitions_file_name); + + builtin_definitions << "\n" "#define BUILTIN_LIST_FROM_TORQUE(CPP, TFJ, TFC, TFS, TFH, " "ASM) " @@ -2684,40 +2695,67 @@ void ImplementationVisitor::GenerateBuiltinDefinitions( for (auto& declarable : GlobalContext::AllDeclarables()) { Builtin* builtin = Builtin::DynamicCast(declarable.get()); if (!builtin || builtin->IsExternal()) continue; - size_t firstParameterIndex = 1; - bool declareParameters = true; if (builtin->IsStub()) { - new_contents_stream << "TFS(" << builtin->ExternalName(); + builtin_definitions << "TFC(" << builtin->ExternalName() << ", " + << builtin->ExternalName(); + std::string descriptor_name = builtin->ExternalName() + "Descriptor"; + constexpr size_t kFirstNonContextParameter = 1; + size_t parameter_count = + builtin->parameter_names().size() - kFirstNonContextParameter; + + interface_descriptors << "class " << descriptor_name + << " : public TorqueInterfaceDescriptor<" + << parameter_count << "> {\n"; + interface_descriptors << " DECLARE_DESCRIPTOR_WITH_BASE(" + << descriptor_name + << ", TorqueInterfaceDescriptor)\n"; + + interface_descriptors << " MachineType ReturnType() override {\n"; + interface_descriptors + << " return " + << MachineTypeString(builtin->signature().return_type) << ";\n"; + interface_descriptors << " }\n"; + + interface_descriptors << " std::array<MachineType, " << parameter_count + << "> ParameterTypes() override {\n"; + interface_descriptors << " return {"; + for (size_t i = kFirstNonContextParameter; + i < builtin->parameter_names().size(); ++i) { + bool last = i + 1 == builtin->parameter_names().size(); + const Type* type = builtin->signature().parameter_types.types[i]; + interface_descriptors << MachineTypeString(type) + << (last ? "" : ", "); + } + interface_descriptors << "};\n"; + + interface_descriptors << " }\n"; + interface_descriptors << "};\n\n"; } else { - new_contents_stream << "TFJ(" << builtin->ExternalName(); + builtin_definitions << "TFJ(" << builtin->ExternalName(); if (builtin->IsVarArgsJavaScript()) { - new_contents_stream + builtin_definitions << ", SharedFunctionInfo::kDontAdaptArgumentsSentinel"; - declareParameters = false; } else { DCHECK(builtin->IsFixedArgsJavaScript()); // FixedArg javascript builtins need to offer the parameter // count. int parameter_count = static_cast<int>(builtin->signature().ExplicitCount()); - new_contents_stream << ", " << parameter_count; + builtin_definitions << ", " << parameter_count; // And the receiver is explicitly declared. - new_contents_stream << ", kReceiver"; - firstParameterIndex = builtin->signature().implicit_count; - } - } - if (declareParameters) { - for (size_t i = firstParameterIndex; - i < builtin->parameter_names().size(); ++i) { - Identifier* parameter = builtin->parameter_names()[i]; - new_contents_stream << ", k" << CamelifyString(parameter->value); + builtin_definitions << ", kReceiver"; + for (size_t i = builtin->signature().implicit_count; + i < builtin->parameter_names().size(); ++i) { + Identifier* parameter = builtin->parameter_names()[i]; + builtin_definitions << ", k" << CamelifyString(parameter->value); + } } } - new_contents_stream << ") \\\n"; + builtin_definitions << ") \\\n"; } - new_contents_stream << "\n"; + builtin_definitions << "\n"; - new_contents_stream + builtin_definitions << "#define TORQUE_FUNCTION_POINTER_TYPE_TO_BUILTIN_MAP(V) \\\n"; for (const BuiltinPointerType* type : TypeOracle::AllBuiltinPointerTypes()) { @@ -2728,13 +2766,15 @@ void ImplementationVisitor::GenerateBuiltinDefinitions( SourcePosition{CurrentSourceFile::Get(), {-1, -1}, {-1, -1}}); ReportError("unable to find any builtin with type \"", *type, "\""); } - new_contents_stream << " V(" << type->function_pointer_type_id() << "," + builtin_definitions << " V(" << type->function_pointer_type_id() << "," << example_builtin->ExternalName() << ")\\\n"; } - new_contents_stream << "\n"; + builtin_definitions << "\n"; } - std::string new_contents(new_contents_stream.str()); - WriteFile(output_directory + "/" + file_name, new_contents); + WriteFile(output_directory + "/" + builtin_definitions_file_name, + builtin_definitions.str()); + WriteFile(output_directory + "/" + interface_descriptors_file_name, + interface_descriptors.str()); } namespace { @@ -2894,40 +2934,8 @@ class MacroFieldOffsetsGenerator : public FieldOffsetsGenerator { private: std::ostream& out_; }; -} // namespace - -void ImplementationVisitor::GenerateInstanceTypes( - const std::string& output_directory) { - std::stringstream header; - std::string file_name = "instance-types-tq.h"; - { - IncludeGuardScope(header, file_name); - header << "#define TORQUE_DEFINED_INSTANCE_TYPES(V) \\\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); - if (type->IsExtern()) continue; - std::string type_name = - CapifyStringWithUnderscores(type->name()) + "_TYPE"; - header << " V(" << type_name << ") \\\n"; - } - header << "\n\n"; - - header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n"; - for (const TypeAlias* alias : GlobalContext::GetClasses()) { - const ClassType* type = ClassType::DynamicCast(alias->type()); - if (type->IsExtern()) continue; - std::string type_name = - CapifyStringWithUnderscores(type->name()) + "_TYPE"; - std::string variable_name = SnakeifyString(type->name()); - header << " V(_, " << type_name << ", " << type->name() << ", " - << variable_name << ") \\\n"; - } - header << "\n"; - } - std::string output_header_path = output_directory + "/" + file_name; - WriteFile(output_header_path, header.str()); -} +} // namespace void ImplementationVisitor::GenerateCppForInternalClasses( const std::string& output_directory) { @@ -3148,7 +3156,7 @@ void CppClassGenerator::GenerateClassConstructors() { if (type_->IsInstantiatedAbstractClass()) { // This is a hack to prevent wrong instance type checks. inl_ << " // Instance check omitted because class is annotated with " - "@dirtyInstantiatedAbstractClass.\n"; + << ANNOTATION_INSTANTIATED_ABSTRACT_CLASS << ".\n"; } else { inl_ << " SLOW_DCHECK(this->Is" << name_ << "());\n"; } @@ -3241,7 +3249,8 @@ void CppClassGenerator::GenerateFieldAccessorForObject(const Field& f) { const std::string offset = "k" + CamelifyString(name) + "Offset"; base::Optional<const ClassType*> class_type = field_type->ClassSupertype(); - std::string type = class_type ? (*class_type)->name() : "Object"; + std::string type = + class_type ? (*class_type)->GetGeneratedTNodeTypeName() : "Object"; // Generate declarations in header. if (!class_type && field_type != TypeOracle::GetObjectType()) { @@ -3302,7 +3311,6 @@ void ImplementationVisitor::GenerateClassDefinitions( { IncludeGuardScope header_guard(header, basename + ".h"); - header << "#include \"src/objects/heap-number.h\"\n"; header << "#include \"src/objects/objects.h\"\n"; header << "#include \"src/objects/smi.h\"\n"; header << "#include \"torque-generated/field-offsets-tq.h\"\n"; @@ -3314,9 +3322,11 @@ void ImplementationVisitor::GenerateClassDefinitions( IncludeGuardScope inline_header_guard(inline_header, basename + "-inl.h"); inline_header << "#include \"torque-generated/class-definitions-tq.h\"\n\n"; inline_header << "#include \"src/objects/js-promise.h\"\n"; + inline_header << "#include \"src/objects/js-weak-refs.h\"\n"; inline_header << "#include \"src/objects/module.h\"\n"; inline_header << "#include \"src/objects/objects-inl.h\"\n"; - inline_header << "#include \"src/objects/script.h\"\n\n"; + inline_header << "#include \"src/objects/script.h\"\n"; + inline_header << "#include \"src/objects/shared-function-info.h\"\n\n"; IncludeObjectMacrosScope inline_header_macros(inline_header); NamespaceScope inline_header_namespaces(inline_header, {"v8", "internal"}); @@ -3328,6 +3338,7 @@ void ImplementationVisitor::GenerateClassDefinitions( implementation << "#include \"src/objects/embedder-data-array-inl.h\"\n"; implementation << "#include \"src/objects/js-generator-inl.h\"\n"; implementation << "#include \"src/objects/js-regexp-inl.h\"\n"; + implementation << "#include \"src/objects/js-weak-refs-inl.h\"\n"; implementation << "#include \"src/objects/js-regexp-string-iterator-inl.h\"\n"; implementation << "#include \"src/objects/literal-objects-inl.h\"\n"; @@ -3346,7 +3357,7 @@ void ImplementationVisitor::GenerateClassDefinitions( // Generate forward declarations for every class. for (const TypeAlias* alias : GlobalContext::GetClasses()) { const ClassType* type = ClassType::DynamicCast(alias->type()); - header << "class " << type->name() << ";\n"; + header << "class " << type->GetGeneratedTNodeTypeName() << ";\n"; } for (const TypeAlias* alias : GlobalContext::GetClasses()) { @@ -3439,13 +3450,13 @@ void GenerateClassFieldVerifier(const std::string& class_name, if (!field_type->IsSubtypeOf(TypeOracle::GetObjectType())) return; if (f.index) { - if ((*f.index)->name_and_type.type != TypeOracle::GetSmiType()) { + if (f.index->type != TypeOracle::GetSmiType()) { ReportError("Non-SMI values are not (yet) supported as indexes."); } // We already verified the index field because it was listed earlier, so we // can assume it's safe to read here. cc_contents << " for (int i = 0; i < TaggedField<Smi, " << class_name - << "::k" << CamelifyString((*f.index)->name_and_type.name) + << "::k" << CamelifyString(f.index->name) << "Offset>::load(o).value(); ++i) {\n"; } else { cc_contents << " {\n"; diff --git a/deps/v8/src/torque/implementation-visitor.h b/deps/v8/src/torque/implementation-visitor.h index eb1a6c4452fde4..e1ebfeeb17654a 100644 --- a/deps/v8/src/torque/implementation-visitor.h +++ b/deps/v8/src/torque/implementation-visitor.h @@ -5,6 +5,7 @@ #ifndef V8_TORQUE_IMPLEMENTATION_VISITOR_H_ #define V8_TORQUE_IMPLEMENTATION_VISITOR_H_ +#include <memory> #include <string> #include "src/base/macros.h" @@ -260,7 +261,7 @@ class BlockBindings { void Add(std::string name, T value, bool mark_as_used = false) { ReportErrorIfAlreadyBound(name); auto binding = - base::make_unique<Binding<T>>(manager_, name, std::move(value)); + std::make_unique<Binding<T>>(manager_, name, std::move(value)); if (mark_as_used) binding->SetUsed(); bindings_.push_back(std::move(binding)); } @@ -268,7 +269,7 @@ class BlockBindings { void Add(const Identifier* name, T value, bool mark_as_used = false) { ReportErrorIfAlreadyBound(name->value); auto binding = - base::make_unique<Binding<T>>(manager_, name, std::move(value)); + std::make_unique<Binding<T>>(manager_, name, std::move(value)); if (mark_as_used) binding->SetUsed(); bindings_.push_back(std::move(binding)); } @@ -342,7 +343,8 @@ bool IsCompatibleSignature(const Signature& sig, const TypeVector& types, class ImplementationVisitor { public: - void GenerateBuiltinDefinitions(const std::string& output_directory); + void GenerateBuiltinDefinitionsAndInterfaceDescriptors( + const std::string& output_directory); void GenerateClassFieldOffsets(const std::string& output_directory); void GeneratePrintDefinitions(const std::string& output_directory); void GenerateClassDefinitions(const std::string& output_directory); diff --git a/deps/v8/src/torque/instance-type-generator.cc b/deps/v8/src/torque/instance-type-generator.cc new file mode 100644 index 00000000000000..275e7064852815 --- /dev/null +++ b/deps/v8/src/torque/instance-type-generator.cc @@ -0,0 +1,376 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/torque/implementation-visitor.h" + +namespace v8 { +namespace internal { +namespace torque { + +namespace { + +// Contains all necessary state for a single class type during the process of +// assigning instance types, and provides a convenient way to access the list of +// types that inherit from this one. +struct InstanceTypeTree { + explicit InstanceTypeTree(const ClassType* type) + : type(type), + parent(nullptr), + start(INT_MAX), + end(INT_MIN), + value(-1), + num_values(0), + num_own_values(0) {} + const ClassType* type; + InstanceTypeTree* parent; + std::vector<std::unique_ptr<InstanceTypeTree>> children; + int start; // Start of range for this and subclasses, or INT_MAX. + int end; // End of range for this and subclasses, or INT_MIN. + int value; // Assigned value for this class itself, or -1 when unassigned. + int num_values; // Number of values assigned for this and subclasses. + int num_own_values; // How many values this needs (not including subclasses). +}; + +// Assembles all class types into a tree, but doesn't yet attempt to assign +// instance types for them. +std::unique_ptr<InstanceTypeTree> BuildInstanceTypeTree() { + // First, build InstanceTypeTree instances for every class but don't try to + // attach them to their subclasses yet. + std::unordered_map<const ClassType*, InstanceTypeTree*> map_by_type; + std::vector<std::unique_ptr<InstanceTypeTree>> unparented_types; + for (auto& p : GlobalContext::AllDeclarables()) { + if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) { + const Type* type = alias->type(); + const ClassType* class_type = ClassType::DynamicCast(type); + if (class_type == nullptr) { + continue; + } + auto& map_slot = map_by_type[class_type]; + if (map_slot != nullptr) { + continue; // We already encountered this type. + } + std::unique_ptr<InstanceTypeTree> type_tree = + std::make_unique<InstanceTypeTree>(class_type); + map_slot = type_tree.get(); + unparented_types.push_back(std::move(type_tree)); + } + } + + // Second, assemble them all into a tree following the inheritance hierarchy. + std::unique_ptr<InstanceTypeTree> root; + for (auto& type_tree : unparented_types) { + const ClassType* parent = type_tree->type->GetSuperClass(); + if (parent == nullptr) { + if (root != nullptr) + Error("Expected only one root class type. Found: ", root->type->name(), + " and ", type_tree->type->name()) + .Position(type_tree->type->GetPosition()); + root = std::move(type_tree); + } else { + map_by_type[parent]->children.push_back(std::move(type_tree)); + } + } + return root; +} + +// Propagates constraints about instance types from children to their parents. +void PropagateInstanceTypeConstraints(InstanceTypeTree* root) { + for (auto& child : root->children) { + PropagateInstanceTypeConstraints(child.get()); + if (child->start < root->start) root->start = child->start; + if (child->end > root->end) root->end = child->end; + root->num_values += child->num_values; + } + const InstanceTypeConstraints& constraints = + root->type->GetInstanceTypeConstraints(); + if ((!root->type->IsAbstract() || + root->type->IsInstantiatedAbstractClass()) && + !root->type->HasSameInstanceTypeAsParent()) { + root->num_own_values = 1; + } + root->num_values += root->num_own_values; + if (constraints.num_flags_bits != -1) { + // Children won't get any types assigned; must be done manually in C++. + root->children.clear(); + root->num_values = 1 << constraints.num_flags_bits; + root->num_own_values = root->num_values; + root->start = 0; + root->end = root->num_values - 1; + } + if (constraints.value != -1) { + if (root->num_own_values != 1) { + Error("Instance type value requested for abstract class ", + root->type->name()) + .Position(root->type->GetPosition()); + } + root->value = constraints.value; + if (constraints.value < root->start) root->start = constraints.value; + if (constraints.value > root->end) root->end = constraints.value; + } +} + +// Assigns values for the type itself, not including any children. Returns the +// next available value. +int SelectOwnValues(InstanceTypeTree* root, int start_value) { + if (root->value == -1) { + root->value = start_value; + } else if (root->value < start_value) { + Error("Failed to assign instance type ", root->value, " to ", + root->type->name()) + .Position(root->type->GetPosition()); + } + return root->value + root->num_own_values; +} + +// Sorting function for types that don't have specific values they must include. +// Prioritizes bigger type ranges (those with more subtypes) first, and +// then sorts alphabetically within each size category. +struct CompareUnconstrainedTypes { + constexpr bool operator()(const InstanceTypeTree* a, + const InstanceTypeTree* b) const { + return (a->num_values > b->num_values) + ? true + : (a->num_values < b->num_values) + ? false + : std::less<std::string>()(a->type->name(), + b->type->name()); + } +}; + +// Assigns concrete values for every instance type range, and sorts the children +// at each layer of the tree into increasing order. Appends the newly-assigned +// tree to the destination vector. Returns the first unassigned value after +// those that have been used. +int SolveInstanceTypeConstraints( + std::unique_ptr<InstanceTypeTree> root, int start_value, + std::vector<std::unique_ptr<InstanceTypeTree>>* destination) { + if (root->start < start_value) { + Error("Failed to assign instance type ", root->start, " to ", + root->type->name()) + .Position(root->type->GetPosition()); + } + + // First, separate the children into four groups: + // - The one child that must go first, if it exists; + // - Children with specific value requirements ("constrained"); + // - Children without specific value requirements ("unconstrained"); + // - The one child that must go last, if it exists. + std::unique_ptr<InstanceTypeTree> lowest_child; + std::unique_ptr<InstanceTypeTree> highest_child; + std::multimap<int, std::unique_ptr<InstanceTypeTree>> + constrained_children_by_start; + // Using std::map because you can't std::move out of a std::set until C++17. + std::map<InstanceTypeTree*, std::unique_ptr<InstanceTypeTree>, + CompareUnconstrainedTypes> + unconstrained_children_by_size; + for (auto& child : root->children) { + if (child->type->IsHighestInstanceTypeWithinParent()) { + if (highest_child) { + Error("Two classes requested to be the highest instance type: ", + highest_child->type->name(), " and ", child->type->name(), + " within range for parent class ", root->type->name()) + .Position(child->type->GetPosition()); + } + if (child->type->IsLowestInstanceTypeWithinParent()) { + Error( + "Class requested to be both highest and lowest instance type " + "within its parent range: ", + child->type->name()) + .Position(child->type->GetPosition()); + } + highest_child = std::move(child); + } else if (child->type->IsLowestInstanceTypeWithinParent()) { + if (lowest_child) { + Error("Two classes requested to be the lowest instance type: ", + lowest_child->type->name(), " and ", child->type->name(), + " within range for parent class ", root->type->name()) + .Position(child->type->GetPosition()); + } + lowest_child = std::move(child); + } else if (child->start > child->end) { + unconstrained_children_by_size.insert( + std::make_pair(child.get(), std::move(child))); + } else { + constrained_children_by_start.insert( + std::make_pair(child->start, std::move(child))); + } + } + root->children.clear(); + + bool own_type_pending = root->num_own_values > 0; + + // Second, iterate and place the children in ascending order. + if (lowest_child != nullptr) { + start_value = SolveInstanceTypeConstraints(std::move(lowest_child), + start_value, &root->children); + } + for (auto& constrained_child_pair : constrained_children_by_start) { + // Select the next constrained child type in ascending order. + std::unique_ptr<InstanceTypeTree> constrained_child = + std::move(constrained_child_pair.second); + + // Try to place the root type before the constrained child type if it fits. + if (own_type_pending) { + if ((root->value != -1 && root->value < constrained_child->start) || + (root->value == -1 && + start_value + root->num_own_values <= constrained_child->start)) { + start_value = SelectOwnValues(root.get(), start_value); + own_type_pending = false; + } + } + + // Try to find any unconstrained children that fit before the constrained + // one. This simple greedy algorithm just puts the biggest unconstrained + // children in first, which might not fill the space as efficiently as + // possible but is good enough for our needs. + for (auto it = unconstrained_children_by_size.begin(); + it != unconstrained_children_by_size.end();) { + if (it->second->num_values + start_value <= constrained_child->start) { + start_value = SolveInstanceTypeConstraints( + std::move(it->second), start_value, &root->children); + it = unconstrained_children_by_size.erase(it); + } else { + ++it; + } + } + + // Place the constrained child type. + start_value = SolveInstanceTypeConstraints(std::move(constrained_child), + start_value, &root->children); + } + if (own_type_pending) { + start_value = SelectOwnValues(root.get(), start_value); + own_type_pending = false; + } + for (auto& child_pair : unconstrained_children_by_size) { + start_value = SolveInstanceTypeConstraints(std::move(child_pair.second), + start_value, &root->children); + } + if (highest_child != nullptr) { + start_value = SolveInstanceTypeConstraints(std::move(highest_child), + start_value, &root->children); + } + + // Finally, set the range for this class to include all placed subclasses. + root->end = start_value - 1; + root->start = + root->children.empty() ? start_value : root->children.front()->start; + if (root->value != -1 && root->value < root->start) { + root->start = root->value; + } + root->num_values = root->end - root->start + 1; + + if (root->num_values > 0) { + destination->push_back(std::move(root)); + } + return start_value; +} + +std::unique_ptr<InstanceTypeTree> SolveInstanceTypeConstraints( + std::unique_ptr<InstanceTypeTree> root) { + std::vector<std::unique_ptr<InstanceTypeTree>> destination; + SolveInstanceTypeConstraints(std::move(root), 0, &destination); + return destination.empty() ? nullptr : std::move(destination.front()); +} + +std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() { + std::unique_ptr<InstanceTypeTree> root = BuildInstanceTypeTree(); + if (root != nullptr) { + PropagateInstanceTypeConstraints(root.get()); + root = SolveInstanceTypeConstraints(std::move(root)); + } + return root; +} + +// Prints items in macro lists for the given type and its descendants. +// - definitions: This list is pairs of instance type name and assigned value, +// such as V(ODDBALL_TYPE, 67). It includes FIRST_* and LAST_* items for each +// type that has more than one associated InstanceType. Items within those +// ranges are indented for readability. +// - values: This list is just instance type names, like V(ODDBALL_TYPE). It +// does not include any FIRST_* and LAST_* range markers. +void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions, + std::ostream& values, const std::string& indent) { + std::string type_name = + CapifyStringWithUnderscores(root->type->name()) + "_TYPE"; + std::string inner_indent = indent; + + if (root->num_values > 1) { + definitions << indent << "V(FIRST_" << type_name << ", " << root->start + << ") \\\n"; + inner_indent += " "; + } + if (root->num_own_values == 1) { + definitions << inner_indent << "V(" << type_name << ", " << root->value + << ") \\\n"; + values << " V(" << type_name << ") \\\n"; + } + for (auto& child : root->children) { + PrintInstanceTypes(child.get(), definitions, values, inner_indent); + } + // We can't emit LAST_STRING_TYPE because it's not a valid flags combination. + // So if the class type has multiple own values, which only happens when using + // ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, then omit the end marker. + if (root->num_values > 1 && root->num_own_values <= 1) { + definitions << indent << "V(LAST_" << type_name << ", " << root->end + << ") \\\n"; + } +} + +} // namespace + +void ImplementationVisitor::GenerateInstanceTypes( + const std::string& output_directory) { + std::stringstream header; + std::string file_name = "instance-types-tq.h"; + { + IncludeGuardScope guard(header, file_name); + + header << "// Instance types for all classes except for those that use " + "InstanceType as flags.\n"; + header << "#define TORQUE_ASSIGNED_INSTANCE_TYPES(V) \\\n"; + std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes(); + std::stringstream values_list; + if (instance_types != nullptr) { + PrintInstanceTypes(instance_types.get(), header, values_list, " "); + } + header << "\n\n"; + + header << "// Instance types for all classes except for those that use " + "InstanceType as flags.\n"; + header << "#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) \\\n"; + header << values_list.str(); + header << "\n\n"; + + header << "// Instance types for Torque-internal classes.\n"; + header << "#define TORQUE_INTERNAL_INSTANCE_TYPES(V) \\\n"; + for (const TypeAlias* alias : GlobalContext::GetClasses()) { + const ClassType* type = ClassType::DynamicCast(alias->type()); + if (type->IsExtern()) continue; + std::string type_name = + CapifyStringWithUnderscores(type->name()) + "_TYPE"; + header << " V(" << type_name << ") \\\n"; + } + header << "\n\n"; + + header << "// Struct list entries for Torque-internal classes.\n"; + header << "#define TORQUE_STRUCT_LIST_GENERATOR(V, _) \\\n"; + for (const TypeAlias* alias : GlobalContext::GetClasses()) { + const ClassType* type = ClassType::DynamicCast(alias->type()); + if (type->IsExtern()) continue; + std::string type_name = + CapifyStringWithUnderscores(type->name()) + "_TYPE"; + std::string variable_name = SnakeifyString(type->name()); + header << " V(_, " << type_name << ", " << type->name() << ", " + << variable_name << ") \\\n"; + } + header << "\n"; + } + std::string output_header_path = output_directory + "/" + file_name; + WriteFile(output_header_path, header.str()); +} + +} // namespace torque +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/torque/ls/json.h b/deps/v8/src/torque/ls/json.h index 43d9f7ab112a49..1a033cf614192d 100644 --- a/deps/v8/src/torque/ls/json.h +++ b/deps/v8/src/torque/ls/json.h @@ -6,11 +6,11 @@ #define V8_TORQUE_LS_JSON_H_ #include <map> +#include <memory> #include <string> #include <vector> #include "src/base/logging.h" -#include "src/base/template-utils.h" namespace v8 { namespace internal { @@ -44,7 +44,7 @@ struct JsonValue { static JsonValue From(JsonObject object) { JsonValue result; result.tag = JsonValue::OBJECT; - result.object_ = base::make_unique<JsonObject>(std::move(object)); + result.object_ = std::make_unique<JsonObject>(std::move(object)); return result; } @@ -65,7 +65,7 @@ struct JsonValue { static JsonValue From(JsonArray array) { JsonValue result; result.tag = JsonValue::ARRAY; - result.array_ = base::make_unique<JsonArray>(std::move(array)); + result.array_ = std::make_unique<JsonArray>(std::move(array)); return result; } diff --git a/deps/v8/src/torque/ls/message-handler.cc b/deps/v8/src/torque/ls/message-handler.cc index 6ec124b5a26b80..becc97c9dc8da6 100644 --- a/deps/v8/src/torque/ls/message-handler.cc +++ b/deps/v8/src/torque/ls/message-handler.cc @@ -87,6 +87,8 @@ void ResetCompilationErrorDiagnostics(MessageWriter writer) { class DiagnosticCollector { public: void AddTorqueMessage(const TorqueMessage& message) { + if (!ShouldAddMessageOfKind(message.kind)) return; + SourceId id = message.position ? message.position->source : SourceId::Invalid(); auto& notification = GetOrCreateNotificationForSource(id); @@ -120,6 +122,20 @@ class DiagnosticCollector { return notification; } + bool ShouldAddMessageOfKind(TorqueMessage::Kind kind) { + // An error can easily cause a lot of false positive lint messages, due to + // unused variables, macros, etc. Thus we suppress subsequent lint messages + // when there are errors. + switch (kind) { + case TorqueMessage::Kind::kError: + suppress_lint_messages_ = true; + return true; + case TorqueMessage::Kind::kLint: + if (suppress_lint_messages_) return false; + return true; + } + } + void PopulateRangeFromSourcePosition(Range range, const SourcePosition& position) { range.start().set_line(position.start.line); @@ -138,6 +154,7 @@ class DiagnosticCollector { } std::map<SourceId, PublishDiagnosticsNotification> notifications_; + bool suppress_lint_messages_ = false; }; void SendCompilationDiagnostics(const TorqueCompilerResult& result, diff --git a/deps/v8/src/torque/server-data.h b/deps/v8/src/torque/server-data.h index 04cd0b317f88b9..b80d1b67f47816 100644 --- a/deps/v8/src/torque/server-data.h +++ b/deps/v8/src/torque/server-data.h @@ -6,6 +6,7 @@ #define V8_TORQUE_SERVER_DATA_H_ #include <map> +#include <memory> #include <vector> #include "src/base/macros.h" @@ -47,12 +48,12 @@ class LanguageServerData : public ContextualClass<LanguageServerData> { static void SetGlobalContext(GlobalContext global_context) { Get().global_context_ = - base::make_unique<GlobalContext>(std::move(global_context)); + std::make_unique<GlobalContext>(std::move(global_context)); Get().PrepareAllDeclarableSymbols(); } static void SetTypeOracle(TypeOracle type_oracle) { - Get().type_oracle_ = base::make_unique<TypeOracle>(std::move(type_oracle)); + Get().type_oracle_ = std::make_unique<TypeOracle>(std::move(type_oracle)); } static const Symbols& SymbolsForSourceId(SourceId id) { diff --git a/deps/v8/src/torque/torque-compiler.cc b/deps/v8/src/torque/torque-compiler.cc index 3968b001fb42f7..6d2b14fc1878a7 100644 --- a/deps/v8/src/torque/torque-compiler.cc +++ b/deps/v8/src/torque/torque-compiler.cc @@ -79,7 +79,8 @@ void CompileCurrentAst(TorqueCompilerOptions options) { ReportAllUnusedMacros(); - implementation_visitor.GenerateBuiltinDefinitions(output_directory); + implementation_visitor.GenerateBuiltinDefinitionsAndInterfaceDescriptors( + output_directory); implementation_visitor.GenerateClassFieldOffsets(output_directory); implementation_visitor.GeneratePrintDefinitions(output_directory); implementation_visitor.GenerateClassDefinitions(output_directory); diff --git a/deps/v8/src/torque/torque-parser.cc b/deps/v8/src/torque/torque-parser.cc index d9973dde3c82d1..3639bef97cc0f3 100644 --- a/deps/v8/src/torque/torque-parser.cc +++ b/deps/v8/src/torque/torque-parser.cc @@ -214,6 +214,10 @@ template <> V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<std::vector<Identifier*>>::id = ParseResultTypeId::kStdVectorOfIdentifierPtr; +template <> +V8_EXPORT_PRIVATE const ParseResultTypeId + ParseResultHolder<base::Optional<ClassBody*>>::id = + ParseResultTypeId::kOptionalClassBody; namespace { @@ -675,7 +679,9 @@ class AnnotationSet { Lint("Annotation ", a.name->value, error_message) .Position(a.name->pos); } - map_[a.name->value].push_back(*a.param); + if (!map_.insert({a.name->value, {*a.param, a.name->pos}}).second) { + Lint("Duplicate annotation ", a.name->value).Position(a.name->pos); + } } else { if (allowed_without_param.find(a.name->value) == allowed_without_param.end()) { @@ -693,41 +699,104 @@ class AnnotationSet { } } - bool Contains(const std::string& s) { return set_.find(s) != set_.end(); } - const std::vector<std::string>& GetParams(const std::string& s) { - return map_[s]; + bool Contains(const std::string& s) const { + return set_.find(s) != set_.end(); + } + base::Optional<std::pair<std::string, SourcePosition>> GetParam( + const std::string& s) const { + auto it = map_.find(s); + return it == map_.end() + ? base::Optional<std::pair<std::string, SourcePosition>>() + : it->second; } private: std::set<std::string> set_; - std::map<std::string, std::vector<std::string>> map_; + std::map<std::string, std::pair<std::string, SourcePosition>> map_; }; +int GetAnnotationValue(const AnnotationSet& annotations, const char* name, + int default_value) { + auto value_and_pos = annotations.GetParam(name); + if (!value_and_pos.has_value()) return default_value; + const std::string& value = value_and_pos->first; + SourcePosition pos = value_and_pos->second; + if (value.empty()) { + Error("Annotation ", name, " requires an integer parameter").Position(pos); + } + size_t num_chars_converted = 0; + int result = default_value; + try { + result = std::stoi(value, &num_chars_converted, 0); + } catch (const std::invalid_argument&) { + Error("Expected an integer for annotation ", name).Position(pos); + return result; + } catch (const std::out_of_range&) { + Error("Integer out of 32-bit range in annotation ", name).Position(pos); + return result; + } + if (num_chars_converted != value.size()) { + Error("Parameter for annotation ", name, + " must be an integer with no trailing characters") + .Position(pos); + } + return result; +} + +InstanceTypeConstraints MakeInstanceTypeConstraints( + const AnnotationSet& annotations) { + InstanceTypeConstraints result; + result.value = + GetAnnotationValue(annotations, ANNOTATION_INSTANCE_TYPE_VALUE, -1); + result.num_flags_bits = GetAnnotationValue( + annotations, ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, -1); + return result; +} + +base::Optional<ParseResult> MakeClassBody(ParseResultIterator* child_results) { + auto methods = child_results->NextAs<std::vector<Declaration*>>(); + auto fields = child_results->NextAs<std::vector<ClassFieldExpression>>(); + base::Optional<ClassBody*> result = + MakeNode<ClassBody>(std::move(methods), std::move(fields)); + return ParseResult(result); +} + base::Optional<ParseResult> MakeClassDeclaration( ParseResultIterator* child_results) { AnnotationSet annotations( child_results, - {"@generatePrint", "@noVerifier", "@abstract", - "@dirtyInstantiatedAbstractClass", "@hasSameInstanceTypeAsParent", - "@generateCppClass"}, - {}); + {ANNOTATION_GENERATE_PRINT, ANNOTATION_NO_VERIFIER, ANNOTATION_ABSTRACT, + ANNOTATION_INSTANTIATED_ABSTRACT_CLASS, + ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT, + ANNOTATION_GENERATE_CPP_CLASS, + ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT, + ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT}, + {ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, + ANNOTATION_INSTANCE_TYPE_VALUE}); ClassFlags flags = ClassFlag::kNone; - bool generate_print = annotations.Contains("@generatePrint"); + bool generate_print = annotations.Contains(ANNOTATION_GENERATE_PRINT); if (generate_print) flags |= ClassFlag::kGeneratePrint; - bool generate_verify = !annotations.Contains("@noVerifier"); + bool generate_verify = !annotations.Contains(ANNOTATION_NO_VERIFIER); if (generate_verify) flags |= ClassFlag::kGenerateVerify; - if (annotations.Contains("@abstract")) { + if (annotations.Contains(ANNOTATION_ABSTRACT)) { flags |= ClassFlag::kAbstract; } - if (annotations.Contains("@dirtyInstantiatedAbstractClass")) { + if (annotations.Contains(ANNOTATION_INSTANTIATED_ABSTRACT_CLASS)) { flags |= ClassFlag::kInstantiatedAbstractClass; } - if (annotations.Contains("@hasSameInstanceTypeAsParent")) { + if (annotations.Contains(ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT)) { flags |= ClassFlag::kHasSameInstanceTypeAsParent; } - if (annotations.Contains("@generateCppClass")) { + if (annotations.Contains(ANNOTATION_GENERATE_CPP_CLASS)) { flags |= ClassFlag::kGenerateCppClassDefinitions; } + if (annotations.Contains(ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT)) { + flags |= ClassFlag::kHighestInstanceTypeWithinParent; + } + if (annotations.Contains(ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT)) { + flags |= ClassFlag::kLowestInstanceTypeWithinParent; + } + auto is_extern = child_results->NextAs<bool>(); if (is_extern) flags |= ClassFlag::kExtern; auto transient = child_results->NextAs<bool>(); @@ -741,8 +810,15 @@ base::Optional<ParseResult> MakeClassDeclaration( ReportError("Expected type name in extends clause."); } auto generates = child_results->NextAs<base::Optional<std::string>>(); - auto methods = child_results->NextAs<std::vector<Declaration*>>(); - auto fields_raw = child_results->NextAs<std::vector<ClassFieldExpression>>(); + auto body = child_results->NextAs<base::Optional<ClassBody*>>(); + std::vector<Declaration*> methods; + std::vector<ClassFieldExpression> fields_raw; + if (body.has_value()) { + methods = (*body)->methods; + fields_raw = (*body)->fields; + } else { + flags |= ClassFlag::kUndefinedLayout; + } // Filter to only include fields that should be present based on decoration. std::vector<ClassFieldExpression> fields; @@ -751,8 +827,9 @@ base::Optional<ParseResult> MakeClassDeclaration( [](const ClassFieldExpression& exp) { for (const ConditionalAnnotation& condition : exp.conditions) { if (condition.type == ConditionalAnnotationType::kPositive - ? !BuildFlags::GetFlag(condition.condition, "@if") - : BuildFlags::GetFlag(condition.condition, "@ifnot")) { + ? !BuildFlags::GetFlag(condition.condition, ANNOTATION_IF) + : BuildFlags::GetFlag(condition.condition, + ANNOTATION_IFNOT)) { return false; } } @@ -761,7 +838,7 @@ base::Optional<ParseResult> MakeClassDeclaration( Declaration* result = MakeNode<ClassDeclaration>( name, flags, std::move(extends), std::move(generates), std::move(methods), - fields); + fields, MakeInstanceTypeConstraints(annotations)); return ParseResult{result}; } @@ -1358,14 +1435,21 @@ base::Optional<ParseResult> MakeAnnotation(ParseResultIterator* child_results) { } base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) { - AnnotationSet annotations(child_results, {"@noVerifier"}, {"@if", "@ifnot"}); - bool generate_verify = !annotations.Contains("@noVerifier"); + AnnotationSet annotations(child_results, {ANNOTATION_NO_VERIFIER}, + {ANNOTATION_IF, ANNOTATION_IFNOT}); + bool generate_verify = !annotations.Contains(ANNOTATION_NO_VERIFIER); std::vector<ConditionalAnnotation> conditions; - for (const std::string& condition : annotations.GetParams("@if")) { - conditions.push_back({condition, ConditionalAnnotationType::kPositive}); + base::Optional<std::pair<std::string, SourcePosition>> if_condition = + annotations.GetParam(ANNOTATION_IF); + base::Optional<std::pair<std::string, SourcePosition>> ifnot_condition = + annotations.GetParam(ANNOTATION_IFNOT); + if (if_condition.has_value()) { + conditions.push_back( + {if_condition->first, ConditionalAnnotationType::kPositive}); } - for (const std::string& condition : annotations.GetParams("@ifnot")) { - conditions.push_back({condition, ConditionalAnnotationType::kNegative}); + if (ifnot_condition.has_value()) { + conditions.push_back( + {ifnot_condition->first, ConditionalAnnotationType::kNegative}); } auto weak = child_results->NextAs<bool>(); auto const_qualified = child_results->NextAs<bool>(); @@ -1892,6 +1976,13 @@ struct TorqueGrammar : Grammar { &block}, MakeMethodDeclaration)}; + // Result: base::Optional<ClassBody*> + Symbol optionalClassBody = { + Rule({Token("{"), List<Declaration*>(&method), + List<ClassFieldExpression>(&classField), Token("}")}, + MakeClassBody), + Rule({Token(";")}, YieldDefaultValue<base::Optional<ClassBody*>>)}; + // Result: std::vector<Declaration*> Symbol declaration = { Rule({Token("const"), &name, Token(":"), &type, Token("="), expression, @@ -1905,8 +1996,7 @@ struct TorqueGrammar : Grammar { Optional<TypeExpression*>(Sequence({Token("extends"), &type})), Optional<std::string>( Sequence({Token("generates"), &externalString})), - Token("{"), List<Declaration*>(&method), - List<ClassFieldExpression>(&classField), Token("}")}, + &optionalClassBody}, AsSingletonVector<Declaration*, MakeClassDeclaration>()), Rule({Token("struct"), &name, TryOrDefault<GenericParameters>(&genericParameters), Token("{"), diff --git a/deps/v8/src/torque/type-oracle.h b/deps/v8/src/torque/type-oracle.h index 643c78c0306577..03aad34d2ae1e5 100644 --- a/deps/v8/src/torque/type-oracle.h +++ b/deps/v8/src/torque/type-oracle.h @@ -5,6 +5,8 @@ #ifndef V8_TORQUE_TYPE_ORACLE_H_ #define V8_TORQUE_TYPE_ORACLE_H_ +#include <memory> + #include "src/torque/contextual.h" #include "src/torque/declarable.h" #include "src/torque/declarations.h" diff --git a/deps/v8/src/torque/type-visitor.cc b/deps/v8/src/torque/type-visitor.cc index 9b5c96ee40196e..b45452058dae60 100644 --- a/deps/v8/src/torque/type-visitor.cc +++ b/deps/v8/src/torque/type-visitor.cc @@ -165,6 +165,12 @@ const ClassType* TypeVisitor::ComputeType(ClassDeclaration* decl) { "class \"", decl->name->value, "\" must extend either Tagged or an already declared class"); } + if (super_class->HasUndefinedLayout() && + !(decl->flags & ClassFlag::kUndefinedLayout)) { + Error("Class \"", decl->name->value, + "\" defines its layout but extends a class which does not") + .Position(decl->pos); + } } std::string generates = decl->name->value; @@ -282,8 +288,9 @@ void TypeVisitor::VisitClassFieldsAndMethods( "only one indexable field is currently supported per class"); } seen_indexed_field = true; - const Field* index_field = - &(class_type->LookupFieldInternal(*field_expression.index)); + const NameAndType& index_field = + class_type->LookupFieldInternal(*field_expression.index) + .name_and_type; class_type->RegisterField( {field_expression.name_and_type.name->pos, class_type, diff --git a/deps/v8/src/torque/types.cc b/deps/v8/src/torque/types.cc index fe792401f6cefc..022649e0657eb8 100644 --- a/deps/v8/src/torque/types.cc +++ b/deps/v8/src/torque/types.cc @@ -50,7 +50,9 @@ bool Type::IsSubtypeOf(const Type* supertype) const { base::Optional<const ClassType*> Type::ClassSupertype() const { for (const Type* t = this; t != nullptr; t = t->parent()) { - if (auto* class_type = ClassType::DynamicCast(t)) return class_type; + if (auto* class_type = ClassType::DynamicCast(t)) { + return class_type; + } } return base::nullopt; } @@ -86,7 +88,7 @@ bool Type::IsAbstractName(const std::string& name) const { std::string Type::GetGeneratedTypeName() const { std::string result = GetGeneratedTypeNameImpl(); - if (result.empty() || result == "compiler::TNode<>") { + if (result.empty() || result == "TNode<>") { ReportError("Generated type is required for type '", ToString(), "'. Use 'generates' clause in definition."); } @@ -382,7 +384,7 @@ std::string ClassType::GetGeneratedTNodeTypeNameImpl() const { std::string ClassType::GetGeneratedTypeNameImpl() const { return IsConstexpr() ? GetGeneratedTNodeTypeName() - : "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">"; + : "TNode<" + GetGeneratedTNodeTypeName() + ">"; } std::string ClassType::ToExplicitString() const { @@ -404,11 +406,11 @@ void ClassType::Finalize() const { if (const ClassType* super_class = ClassType::DynamicCast(parent())) { if (super_class->HasIndexedField()) flags_ |= ClassFlag::kHasIndexedField; if (!super_class->IsAbstract() && !HasSameInstanceTypeAsParent()) { - Error( - "Super class must either be abstract (annotate super class with " - "@abstract) " - "or this class must have the same instance type as the super class " - "(annotate this class with @hasSameInstanceTypeAsParent).") + Error("Super class must either be abstract (annotate super class with ", + ANNOTATION_ABSTRACT, + ") or this class must have the same instance type as the super " + "class (annotate this class with ", + ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT, ").") .Position(this->decl_->name->pos); } } diff --git a/deps/v8/src/torque/types.h b/deps/v8/src/torque/types.h index d2198d50c33afc..0102cf31d5c499 100644 --- a/deps/v8/src/torque/types.h +++ b/deps/v8/src/torque/types.h @@ -156,7 +156,7 @@ struct Field { SourcePosition pos; const AggregateType* aggregate; - base::Optional<const Field*> index; + base::Optional<NameAndType> index; NameAndType name_and_type; size_t offset; bool is_weak; @@ -204,8 +204,7 @@ class AbstractType final : public Type { return "AT" + str; } std::string GetGeneratedTypeNameImpl() const override { - return IsConstexpr() ? generated_type_ - : "compiler::TNode<" + generated_type_ + ">"; + return IsConstexpr() ? generated_type_ : "TNode<" + generated_type_ + ">"; } std::string GetGeneratedTNodeTypeNameImpl() const override; bool IsConstexpr() const override { @@ -316,7 +315,7 @@ class V8_EXPORT_PRIVATE UnionType final : public Type { std::string ToExplicitString() const override; std::string MangledName() const override; std::string GetGeneratedTypeNameImpl() const override { - return "compiler::TNode<" + GetGeneratedTNodeTypeName() + ">"; + return "TNode<" + GetGeneratedTNodeTypeName() + ">"; } std::string GetGeneratedTNodeTypeNameImpl() const override; @@ -514,10 +513,12 @@ class ClassType final : public AggregateType { std::string GetGeneratedTNodeTypeNameImpl() const override; bool IsExtern() const { return flags_ & ClassFlag::kExtern; } bool ShouldGeneratePrint() const { - return flags_ & ClassFlag::kGeneratePrint || !IsExtern(); + return (flags_ & ClassFlag::kGeneratePrint || !IsExtern()) && + !HasUndefinedLayout(); } bool ShouldGenerateVerify() const { - return flags_ & ClassFlag::kGenerateVerify || !IsExtern(); + return (flags_ & ClassFlag::kGenerateVerify || !IsExtern()) && + !HasUndefinedLayout(); } bool IsTransient() const override { return flags_ & ClassFlag::kTransient; } bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; } @@ -549,6 +550,20 @@ class ClassType final : public AggregateType { std::vector<Field> ComputeAllFields() const; + const InstanceTypeConstraints& GetInstanceTypeConstraints() const { + return decl_->instance_type_constraints; + } + bool IsHighestInstanceTypeWithinParent() const { + return flags_ & ClassFlag::kHighestInstanceTypeWithinParent; + } + bool IsLowestInstanceTypeWithinParent() const { + return flags_ & ClassFlag::kLowestInstanceTypeWithinParent; + } + bool HasUndefinedLayout() const { + return flags_ & ClassFlag::kUndefinedLayout; + } + SourcePosition GetPosition() const { return decl_->pos; } + private: friend class TypeOracle; friend class TypeVisitor; diff --git a/deps/v8/src/torque/utils.cc b/deps/v8/src/torque/utils.cc index 38862b31b0efad..4e757ac9e86771 100644 --- a/deps/v8/src/torque/utils.cc +++ b/deps/v8/src/torque/utils.cc @@ -212,19 +212,25 @@ bool IsValidTypeName(const std::string& s) { } std::string CapifyStringWithUnderscores(const std::string& camellified_string) { + // Special case: JSAbc yields JS_ABC, not JSABC, for any Abc. + size_t js_position = camellified_string.find("JS"); + std::string result; - bool previousWasLower = false; - for (auto current : camellified_string) { - if (previousWasLower && isupper(current)) { + bool previousWasLowerOrDigit = false; + for (size_t index = 0; index < camellified_string.size(); ++index) { + char current = camellified_string[index]; + if ((previousWasLowerOrDigit && isupper(current)) || + (js_position != std::string::npos && + index == js_position + strlen("JS"))) { result += "_"; } if (current == '.' || current == '-') { result += "_"; - previousWasLower = false; + previousWasLowerOrDigit = false; continue; } result += toupper(current); - previousWasLower = (islower(current)); + previousWasLowerOrDigit = islower(current) || isdigit(current); } return result; } diff --git a/deps/v8/src/utils/allocation.cc b/deps/v8/src/utils/allocation.cc index f44b3c42ea9dcf..c89f83ba85dc5f 100644 --- a/deps/v8/src/utils/allocation.cc +++ b/deps/v8/src/utils/allocation.cc @@ -10,6 +10,7 @@ #include "src/base/logging.h" #include "src/base/page-allocator.h" #include "src/base/platform/platform.h" +#include "src/flags/flags.h" #include "src/init/v8.h" #include "src/sanitizer/lsan-page-allocator.h" #include "src/utils/memcopy.h" @@ -166,6 +167,9 @@ void* AllocatePages(v8::PageAllocator* page_allocator, void* hint, size_t size, DCHECK_NOT_NULL(page_allocator); DCHECK_EQ(hint, AlignedAddress(hint, alignment)); DCHECK(IsAligned(size, page_allocator->AllocatePageSize())); + if (FLAG_randomize_all_allocations) { + hint = page_allocator->GetRandomMmapAddr(); + } void* result = nullptr; for (int i = 0; i < kAllocationTries; ++i) { result = page_allocator->AllocatePages(hint, size, alignment, access); diff --git a/deps/v8/src/utils/memcopy.cc b/deps/v8/src/utils/memcopy.cc index 1cac2189d08c71..c67d1d359a3786 100644 --- a/deps/v8/src/utils/memcopy.cc +++ b/deps/v8/src/utils/memcopy.cc @@ -25,18 +25,8 @@ V8_EXPORT_PRIVATE void MemMove(void* dest, const void* src, size_t size) { (*memmove_function)(dest, src, size); } #elif V8_OS_POSIX && V8_HOST_ARCH_ARM -void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src, - size_t chars) { - uint16_t* limit = dest + chars; - while (dest < limit) { - *dest++ = static_cast<uint16_t>(*src++); - } -} - V8_EXPORT_PRIVATE MemCopyUint8Function memcopy_uint8_function = &MemCopyUint8Wrapper; -MemCopyUint16Uint8Function memcopy_uint16_uint8_function = - &MemCopyUint16Uint8Wrapper; #elif V8_OS_POSIX && V8_HOST_ARCH_MIPS V8_EXPORT_PRIVATE MemCopyUint8Function memcopy_uint8_function = &MemCopyUint8Wrapper; @@ -54,9 +44,6 @@ void init_memcopy_functions() { EmbeddedData d = EmbeddedData::FromBlob(); memcopy_uint8_function = reinterpret_cast<MemCopyUint8Function>( d.InstructionStartOfBuiltin(Builtins::kMemCopyUint8Uint8)); - memcopy_uint16_uint8_function = - reinterpret_cast<MemCopyUint16Uint8Function>( - d.InstructionStartOfBuiltin(Builtins::kMemCopyUint16Uint8)); } #elif V8_OS_POSIX && V8_HOST_ARCH_MIPS if (Isolate::CurrentEmbeddedBlobIsBinaryEmbedded()) { diff --git a/deps/v8/src/utils/memcopy.h b/deps/v8/src/utils/memcopy.h index c1a0afbcb49f31..7e1b8539df061d 100644 --- a/deps/v8/src/utils/memcopy.h +++ b/deps/v8/src/utils/memcopy.h @@ -8,6 +8,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <algorithm> #include "src/base/logging.h" #include "src/base/macros.h" @@ -55,17 +56,8 @@ V8_EXPORT_PRIVATE V8_INLINE void MemMove(void* dest, const void* src, memmove(dest, src, size); } -using MemCopyUint16Uint8Function = void (*)(uint16_t* dest, const uint8_t* src, - size_t size); -extern MemCopyUint16Uint8Function memcopy_uint16_uint8_function; -void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src, - size_t chars); // For values < 12, the assembler function is slower than the inlined C code. const int kMinComplexConvertMemCopy = 12; -V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src, - size_t size) { - (*memcopy_uint16_uint8_function)(dest, src, size); -} #elif defined(V8_HOST_ARCH_MIPS) using MemCopyUint8Function = void (*)(uint8_t* dest, const uint8_t* src, size_t size); @@ -109,6 +101,7 @@ inline void CopyImpl(T* dst_ptr, const T* src_ptr, size_t count) { DCHECK(((src <= dst) && ((src + count * kTWordSize) <= dst)) || ((dst <= src) && ((dst + count * kTWordSize) <= src))); #endif + if (count == 0) return; // Use block copying MemCopy if the segment we're copying is // enough to justify the extra call/setup overhead. @@ -204,308 +197,32 @@ inline void MemsetPointer(T** dest, U* value, size_t counter) { reinterpret_cast<Address>(value), counter); } -template <typename sourcechar, typename sinkchar> -V8_INLINE static void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, - size_t chars); -#if defined(V8_HOST_ARCH_ARM) -V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, - size_t chars); -V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, - size_t chars); -V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, - size_t chars); -#elif defined(V8_HOST_ARCH_MIPS) -V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, - size_t chars); -V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, - size_t chars); -#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390) -V8_INLINE void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, - size_t chars); -V8_INLINE void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, - size_t chars); -#endif - -// Copy from 8bit/16bit chars to 8bit/16bit chars. -template <typename sourcechar, typename sinkchar> -V8_INLINE void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars); - -template <typename sourcechar, typename sinkchar> -void CopyChars(sinkchar* dest, const sourcechar* src, size_t chars) { - DCHECK_LE(sizeof(sourcechar), 2); - DCHECK_LE(sizeof(sinkchar), 2); - if (sizeof(sinkchar) == 1) { - if (sizeof(sourcechar) == 1) { - CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), - reinterpret_cast<const uint8_t*>(src), chars); - } else { - CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), - reinterpret_cast<const uint16_t*>(src), chars); - } - } else { - if (sizeof(sourcechar) == 1) { - CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest), - reinterpret_cast<const uint8_t*>(src), chars); - } else { - CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest), - reinterpret_cast<const uint16_t*>(src), chars); - } - } -} - -template <typename sourcechar, typename sinkchar> -void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, size_t chars) { - sinkchar* limit = dest + chars; - if ((sizeof(*dest) == sizeof(*src)) && - (chars >= kMinComplexMemCopy / sizeof(*dest))) { - MemCopy(dest, src, chars * sizeof(*dest)); - } else { - while (dest < limit) *dest++ = static_cast<sinkchar>(*src++); - } -} +// Copy from 8bit/16bit chars to 8bit/16bit chars. Values are zero-extended if +// needed. Ranges are not allowed to overlap. +// The separate declaration is needed for the V8_NONNULL, which is not allowed +// on a definition. +template <typename SrcType, typename DstType> +void CopyChars(DstType* dst, const SrcType* src, size_t count) V8_NONNULL(1, 2); -#if defined(V8_HOST_ARCH_ARM) -void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) { - switch (static_cast<unsigned>(chars)) { - case 0: - break; - case 1: - *dest = *src; - break; - case 2: - memcpy(dest, src, 2); - break; - case 3: - memcpy(dest, src, 3); - break; - case 4: - memcpy(dest, src, 4); - break; - case 5: - memcpy(dest, src, 5); - break; - case 6: - memcpy(dest, src, 6); - break; - case 7: - memcpy(dest, src, 7); - break; - case 8: - memcpy(dest, src, 8); - break; - case 9: - memcpy(dest, src, 9); - break; - case 10: - memcpy(dest, src, 10); - break; - case 11: - memcpy(dest, src, 11); - break; - case 12: - memcpy(dest, src, 12); - break; - case 13: - memcpy(dest, src, 13); - break; - case 14: - memcpy(dest, src, 14); - break; - case 15: - memcpy(dest, src, 15); - break; - default: - MemCopy(dest, src, chars); - break; - } -} - -void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, size_t chars) { - if (chars >= static_cast<size_t>(kMinComplexConvertMemCopy)) { - MemCopyUint16Uint8(dest, src, chars); - } else { - MemCopyUint16Uint8Wrapper(dest, src, chars); - } -} +template <typename SrcType, typename DstType> +void CopyChars(DstType* dst, const SrcType* src, size_t count) { + STATIC_ASSERT(std::is_integral<SrcType>::value); + STATIC_ASSERT(std::is_integral<DstType>::value); -void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) { - switch (static_cast<unsigned>(chars)) { - case 0: - break; - case 1: - *dest = *src; - break; - case 2: - memcpy(dest, src, 4); - break; - case 3: - memcpy(dest, src, 6); - break; - case 4: - memcpy(dest, src, 8); - break; - case 5: - memcpy(dest, src, 10); - break; - case 6: - memcpy(dest, src, 12); - break; - case 7: - memcpy(dest, src, 14); - break; - default: - MemCopy(dest, src, chars * sizeof(*dest)); - break; - } -} - -#elif defined(V8_HOST_ARCH_MIPS) -void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) { - if (chars < kMinComplexMemCopy) { - memcpy(dest, src, chars); - } else { - MemCopy(dest, src, chars); - } -} - -void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) { - if (chars < kMinComplexMemCopy) { - memcpy(dest, src, chars * sizeof(*dest)); - } else { - MemCopy(dest, src, chars * sizeof(*dest)); - } -} -#elif defined(V8_HOST_ARCH_PPC) || defined(V8_HOST_ARCH_S390) -#define CASE(n) \ - case n: \ - memcpy(dest, src, n); \ - break -void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, size_t chars) { - switch (static_cast<unsigned>(chars)) { - case 0: - break; - case 1: - *dest = *src; - break; - CASE(2); - CASE(3); - CASE(4); - CASE(5); - CASE(6); - CASE(7); - CASE(8); - CASE(9); - CASE(10); - CASE(11); - CASE(12); - CASE(13); - CASE(14); - CASE(15); - CASE(16); - CASE(17); - CASE(18); - CASE(19); - CASE(20); - CASE(21); - CASE(22); - CASE(23); - CASE(24); - CASE(25); - CASE(26); - CASE(27); - CASE(28); - CASE(29); - CASE(30); - CASE(31); - CASE(32); - CASE(33); - CASE(34); - CASE(35); - CASE(36); - CASE(37); - CASE(38); - CASE(39); - CASE(40); - CASE(41); - CASE(42); - CASE(43); - CASE(44); - CASE(45); - CASE(46); - CASE(47); - CASE(48); - CASE(49); - CASE(50); - CASE(51); - CASE(52); - CASE(53); - CASE(54); - CASE(55); - CASE(56); - CASE(57); - CASE(58); - CASE(59); - CASE(60); - CASE(61); - CASE(62); - CASE(63); - CASE(64); - default: - memcpy(dest, src, chars); - break; - } -} -#undef CASE +#ifdef DEBUG + // Check for no overlap, otherwise {std::copy_n} cannot be used. + Address src_start = reinterpret_cast<Address>(src); + Address src_end = src_start + count * sizeof(SrcType); + Address dst_start = reinterpret_cast<Address>(dst); + Address dst_end = dst_start + count * sizeof(DstType); + DCHECK(src_end <= dst_start || dst_end <= src_start); +#endif -#define CASE(n) \ - case n: \ - memcpy(dest, src, n * 2); \ - break -void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, size_t chars) { - switch (static_cast<unsigned>(chars)) { - case 0: - break; - case 1: - *dest = *src; - break; - CASE(2); - CASE(3); - CASE(4); - CASE(5); - CASE(6); - CASE(7); - CASE(8); - CASE(9); - CASE(10); - CASE(11); - CASE(12); - CASE(13); - CASE(14); - CASE(15); - CASE(16); - CASE(17); - CASE(18); - CASE(19); - CASE(20); - CASE(21); - CASE(22); - CASE(23); - CASE(24); - CASE(25); - CASE(26); - CASE(27); - CASE(28); - CASE(29); - CASE(30); - CASE(31); - CASE(32); - default: - memcpy(dest, src, chars * 2); - break; - } + using SrcTypeUnsigned = typename std::make_unsigned<SrcType>::type; + using DstTypeUnsigned = typename std::make_unsigned<DstType>::type; + std::copy_n(reinterpret_cast<const SrcTypeUnsigned*>(src), count, + reinterpret_cast<DstTypeUnsigned*>(dst)); } -#undef CASE -#endif } // namespace internal } // namespace v8 diff --git a/deps/v8/src/utils/utils-inl.h b/deps/v8/src/utils/utils-inl.h index e88055023ec504..0c8af7cb88a36b 100644 --- a/deps/v8/src/utils/utils-inl.h +++ b/deps/v8/src/utils/utils-inl.h @@ -36,13 +36,30 @@ template <typename Char> bool TryAddIndexChar(uint32_t* index, Char c) { if (!IsDecimalDigit(c)) return false; int d = c - '0'; + // The maximum index is 4294967294; for the computation below to not + // exceed that, the previous index value must be <= 429496729 if d <= 4, + // or <= 429496728 if d >= 5. The (d+3)>>3 computation is a branch-free + // way to express that. if (*index > 429496729U - ((d + 3) >> 3)) return false; *index = (*index) * 10 + d; return true; } -template <typename Stream> -bool StringToArrayIndex(Stream* stream, uint32_t* index) { +template <typename Char> +bool TryAddIndexChar(uint64_t* index, Char c) { + if (!IsDecimalDigit(c)) return false; + int d = c - '0'; + // The maximum uint64_t is 18446744073709551615; for the computation below to + // not exceed that, the previous index value must be <= 1844674407370955161 + // if d <= 5, or <= 1844674407370955160 if d >= 6. The (d+2)>>3 computation + // is a branch-free way to express that. + if (*index > 1844674407370955161ull - ((d + 2) >> 3)) return false; + *index = (*index) * 10 + d; + return true; +} + +template <typename Stream, typename index_t> +bool StringToArrayIndex(Stream* stream, index_t* index) { uint16_t ch = stream->GetNext(); // If the string begins with a '0' character, it must only consist @@ -55,9 +72,20 @@ bool StringToArrayIndex(Stream* stream, uint32_t* index) { // Convert string to uint32 array index; character by character. if (!IsDecimalDigit(ch)) return false; int d = ch - '0'; - uint32_t result = d; + index_t result = d; while (stream->HasMore()) { - if (!TryAddIndexChar(&result, stream->GetNext())) return false; + // Clang on Mac doesn't think that size_t and uint*_t should be + // implicitly convertible. + if (sizeof(index_t) == 8) { + if (!TryAddIndexChar(reinterpret_cast<uint64_t*>(&result), + stream->GetNext())) { + return false; + } + } else { + if (!TryAddIndexChar(reinterpret_cast<uint32_t*>(&result), + stream->GetNext())) + return false; + } } *index = result; diff --git a/deps/v8/src/utils/utils.h b/deps/v8/src/utils/utils.h index 27d3d5ef217bdc..b414a4c52b15ee 100644 --- a/deps/v8/src/utils/utils.h +++ b/deps/v8/src/utils/utils.h @@ -760,13 +760,8 @@ inline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) { return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1); } -inline int32_t signed_bitextract_32(int msb, int lsb, int32_t x) { - return (x << (31 - msb)) >> (lsb + 31 - msb); -} - -inline int signed_bitextract_64(int msb, int lsb, int x) { - // TODO(jbramley): This is broken for big bitfields. - return (x << (63 - msb)) >> (lsb + 63 - msb); +inline int32_t signed_bitextract_32(int msb, int lsb, uint32_t x) { + return static_cast<int32_t>(x << (31 - msb)) >> (lsb + 31 - msb); } // Check number width. @@ -978,8 +973,8 @@ bool DoubleToBoolean(double d); template <typename Char> bool TryAddIndexChar(uint32_t* index, Char c); -template <typename Stream> -bool StringToArrayIndex(Stream* stream, uint32_t* index); +template <typename Stream, typename index_t> +bool StringToArrayIndex(Stream* stream, index_t* index); // Returns the current stack top. Works correctly with ASAN and SafeStack. // GetCurrentStackPosition() should not be inlined, because it works on stack diff --git a/deps/v8/src/utils/vector.h b/deps/v8/src/utils/vector.h index dd5c59e5538cf8..e0c13afc901c52 100644 --- a/deps/v8/src/utils/vector.h +++ b/deps/v8/src/utils/vector.h @@ -8,6 +8,7 @@ #include <algorithm> #include <cstring> #include <iterator> +#include <memory> #include "src/common/checks.h" #include "src/common/globals.h" diff --git a/deps/v8/src/wasm/DEPS b/deps/v8/src/wasm/DEPS index eb0780f5e3dfcd..2d310c631cd17d 100644 --- a/deps/v8/src/wasm/DEPS +++ b/deps/v8/src/wasm/DEPS @@ -1,4 +1,11 @@ specific_include_rules = { + "jump-table-assembler\.(cc|h)": [ + # The JumpTableAssembler should not depend on any wasm-specific headers. + # The only allowed include is 'src/codegen' for assembler headers. + "-src", + "+src/codegen", + "+src/wasm/jump-table-assembler.h", + ], "c-api\.cc": [ "+include/libplatform/libplatform.h", "+third_party/wasm-api/wasm.h", diff --git a/deps/v8/src/wasm/OWNERS b/deps/v8/src/wasm/OWNERS index 8aa6e2473929e3..bc9ec357df47d6 100644 --- a/deps/v8/src/wasm/OWNERS +++ b/deps/v8/src/wasm/OWNERS @@ -1,7 +1,7 @@ ahaas@chromium.org bbudge@chromium.org binji@chromium.org -clemensh@chromium.org +clemensb@chromium.org gdeepti@chromium.org mstarzinger@chromium.org titzer@chromium.org diff --git a/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h b/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h index 834eb181d83e89..e6c46e4a09dba1 100644 --- a/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h +++ b/deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h @@ -46,10 +46,12 @@ constexpr int32_t kConstantStackSpace = kSystemPointerSize; // Three instructions are required to sub a large constant, movw + movt + sub. constexpr int32_t kPatchInstructionsRequired = 3; +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + inline MemOperand GetStackSlot(uint32_t index) { - int32_t offset = - kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; - return MemOperand(fp, -offset); + return MemOperand(fp, -GetStackSlotOffset(index)); } inline MemOperand GetHalfStackSlot(uint32_t index, RegPairHalf half) { @@ -635,6 +637,44 @@ void LiftoffAssembler::FillI64Half(Register reg, uint32_t index, ldr(reg, liftoff::GetHalfStackSlot(index, half)); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + // We need a zero reg. Always use r0 for that, and push it before to restore + // its value afterwards. + push(r0); + mov(r0, Operand(0)); + + if (count <= 5) { + // Special straight-line code for up to five slots. Generates two + // instructions per slot. + for (uint32_t offset = 0; offset < count; ++offset) { + str(r0, liftoff::GetHalfStackSlot(index + offset, kLowWord)); + str(r0, liftoff::GetHalfStackSlot(index + offset, kHighWord)); + } + } else { + // General case for bigger counts (9 instructions). + // Use r1 for start address (inclusive), r2 for end address (exclusive). + push(r1); + push(r2); + sub(r1, fp, Operand(liftoff::GetStackSlotOffset(last_stack_slot))); + sub(r2, fp, Operand(liftoff::GetStackSlotOffset(index) - kStackSlotSize)); + + Label loop; + bind(&loop); + str(r0, MemOperand(r1, /* offset */ kSystemPointerSize, PostIndex)); + cmp(r1, r2); + b(&loop, ne); + + pop(r2); + pop(r1); + } + + pop(r0); +} + #define I32_BINOP(name, instruction) \ void LiftoffAssembler::emit_##name(Register dst, Register lhs, \ Register rhs) { \ diff --git a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h index dc68267825cde1..dede53b7a484ee 100644 --- a/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h +++ b/deps/v8/src/wasm/baseline/arm64/liftoff-assembler-arm64.h @@ -43,10 +43,12 @@ constexpr int32_t kInstanceOffset = 2 * kSystemPointerSize; constexpr int32_t kFirstStackSlotOffset = kInstanceOffset + kSystemPointerSize; constexpr int32_t kConstantStackSpace = 0; +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + inline MemOperand GetStackSlot(uint32_t index) { - int32_t offset = - kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; - return MemOperand(fp, -offset); + return MemOperand(fp, -GetStackSlotOffset(index)); } inline MemOperand GetInstanceOperand() { @@ -398,6 +400,38 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t index, RegPairHalf) { UNREACHABLE(); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + int max_stp_offset = -liftoff::GetStackSlotOffset(index + count - 1); + if (count <= 20 && IsImmLSPair(max_stp_offset, kXRegSizeLog2)) { + // Special straight-line code for up to 20 slots. Generates one + // instruction per two slots (<= 10 instructions total). + for (; count > 1; count -= 2) { + STATIC_ASSERT(kStackSlotSize == kSystemPointerSize); + stp(xzr, xzr, liftoff::GetStackSlot(index + count - 1)); + } + DCHECK(count == 0 || count == 1); + if (count) str(xzr, liftoff::GetStackSlot(index)); + } else { + // General case for bigger counts (7 instructions). + // Use x0 for start address (inclusive), x1 for end address (exclusive). + Push(x1, x0); + Sub(x0, fp, Operand(liftoff::GetStackSlotOffset(last_stack_slot))); + Sub(x1, fp, Operand(liftoff::GetStackSlotOffset(index) - kStackSlotSize)); + + Label loop; + bind(&loop); + str(xzr, MemOperand(x0, /* offset */ kSystemPointerSize, PostIndex)); + cmp(x0, x1); + b(&loop, ne); + + Pop(x0, x1); + } +} + #define I32_BINOP(name, instruction) \ void LiftoffAssembler::emit_##name(Register dst, Register lhs, \ Register rhs) { \ diff --git a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h index 7bc3596d2e7452..fa88d20df63759 100644 --- a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h +++ b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32.h @@ -41,7 +41,7 @@ inline MemOperand GetHalfStackSlot(uint32_t index, RegPairHalf half) { return Operand(ebp, -kFirstStackSlotOffset - offset); } -// TODO(clemensh): Make this a constexpr variable once Operand is constexpr. +// TODO(clemensb): Make this a constexpr variable once Operand is constexpr. inline Operand GetInstanceOperand() { return Operand(ebp, -8); } static constexpr LiftoffRegList kByteRegs = @@ -511,6 +511,37 @@ void LiftoffAssembler::FillI64Half(Register reg, uint32_t index, mov(reg, liftoff::GetHalfStackSlot(index, half)); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + if (count <= 2) { + // Special straight-line code for up to two slots (6-9 bytes per word: + // C7 <1-4 bytes operand> <4 bytes imm>, makes 12-18 bytes per slot). + for (uint32_t offset = 0; offset < count; ++offset) { + mov(liftoff::GetHalfStackSlot(index + offset, kLowWord), Immediate(0)); + mov(liftoff::GetHalfStackSlot(index + offset, kHighWord), Immediate(0)); + } + } else { + // General case for bigger counts. + // This sequence takes 19-22 bytes (3 for pushes, 3-6 for lea, 2 for xor, 5 + // for mov, 3 for repstosq, 3 for pops). + // Note: rep_stos fills ECX doublewords at [EDI] with EAX. + push(eax); + push(ecx); + push(edi); + lea(edi, liftoff::GetStackSlot(last_stack_slot)); + xor_(eax, eax); + // Number of words is number of slots times two. + mov(ecx, Immediate(count * 2)); + rep_stos(); + pop(edi); + pop(ecx); + pop(eax); + } +} + void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) { if (lhs != dst) { lea(dst, Operand(lhs, rhs, times_1, 0)); diff --git a/deps/v8/src/wasm/baseline/liftoff-assembler.cc b/deps/v8/src/wasm/baseline/liftoff-assembler.cc index 0fcfb8dbfcf600..389c0655075b06 100644 --- a/deps/v8/src/wasm/baseline/liftoff-assembler.cc +++ b/deps/v8/src/wasm/baseline/liftoff-assembler.cc @@ -297,7 +297,7 @@ class StackTransferRecipe { // process all remaining moves in that cycle. Repeat for all cycles. uint32_t next_spill_slot = asm_->cache_state()->stack_height(); while (!move_dst_regs_.is_empty()) { - // TODO(clemensh): Use an unused register if available. + // TODO(clemensb): Use an unused register if available. LiftoffRegister dst = move_dst_regs_.GetFirstRegSet(); RegisterMove* move = register_move(dst); LiftoffRegister spill_reg = move->src; @@ -412,7 +412,7 @@ void InitMergeRegion(LiftoffAssembler::CacheState* state, } // namespace -// TODO(clemensh): Don't copy the full parent state (this makes us N^2). +// TODO(clemensb): Don't copy the full parent state (this makes us N^2). void LiftoffAssembler::CacheState::InitMerge(const CacheState& source, uint32_t num_locals, uint32_t arity, @@ -484,7 +484,7 @@ constexpr AssemblerOptions DefaultLiftoffOptions() { } // namespace -// TODO(clemensh): Provide a reasonably sized buffer, based on wasm function +// TODO(clemensb): Provide a reasonably sized buffer, based on wasm function // size. LiftoffAssembler::LiftoffAssembler(std::unique_ptr<AssemblerBuffer> buffer) : TurboAssembler(nullptr, DefaultLiftoffOptions(), CodeObjectRequired::kNo, @@ -526,7 +526,7 @@ LiftoffRegister LiftoffAssembler::PopToRegister(LiftoffRegList pinned) { void LiftoffAssembler::MergeFullStackWith(const CacheState& target, const CacheState& source) { DCHECK_EQ(source.stack_height(), target.stack_height()); - // TODO(clemensh): Reuse the same StackTransferRecipe object to save some + // TODO(clemensb): Reuse the same StackTransferRecipe object to save some // allocations. StackTransferRecipe transfers(this); for (uint32_t i = 0, e = source.stack_height(); i < e; ++i) { diff --git a/deps/v8/src/wasm/baseline/liftoff-assembler.h b/deps/v8/src/wasm/baseline/liftoff-assembler.h index 766ce71db11b62..f0d49a878285d6 100644 --- a/deps/v8/src/wasm/baseline/liftoff-assembler.h +++ b/deps/v8/src/wasm/baseline/liftoff-assembler.h @@ -228,7 +228,7 @@ class LiftoffAssembler : public TurboAssembler { return reg; } - // TODO(clemensh): Don't copy the full parent state (this makes us N^2). + // TODO(clemensb): Don't copy the full parent state (this makes us N^2). void InitMerge(const CacheState& source, uint32_t num_locals, uint32_t arity, uint32_t stack_depth); @@ -386,6 +386,7 @@ class LiftoffAssembler : public TurboAssembler { // Only used on 32-bit systems: Fill a register from a "half stack slot", i.e. // 4 bytes on the stack holding half of a 64-bit value. inline void FillI64Half(Register, uint32_t index, RegPairHalf); + inline void FillStackSlotsWithZero(uint32_t index, uint32_t count); // i32 binops. inline void emit_i32_add(Register dst, Register lhs, Register rhs); diff --git a/deps/v8/src/wasm/baseline/liftoff-compiler.cc b/deps/v8/src/wasm/baseline/liftoff-compiler.cc index 02de06763c10cd..997c8ff52b71d9 100644 --- a/deps/v8/src/wasm/baseline/liftoff-compiler.cc +++ b/deps/v8/src/wasm/baseline/liftoff-compiler.cc @@ -6,7 +6,7 @@ #include "src/base/optional.h" #include "src/codegen/assembler-inl.h" -// TODO(clemensh): Remove dependences on compiler stuff. +// TODO(clemensb): Remove dependences on compiler stuff. #include "src/codegen/interface-descriptors.h" #include "src/codegen/macro-assembler-inl.h" #include "src/compiler/linkage.h" @@ -121,7 +121,7 @@ constexpr Vector<const ValueType> kSupportedTypes = class LiftoffCompiler { public: - // TODO(clemensh): Make this a template parameter. + // TODO(clemensb): Make this a template parameter. static constexpr Decoder::ValidateFlag validate = Decoder::kValidate; using Value = ValueBase; @@ -341,6 +341,24 @@ class LiftoffCompiler { __ bind(ool.continuation.get()); } + bool SpillLocalsInitially(FullDecoder* decoder, uint32_t num_params) { + int actual_locals = __ num_locals() - num_params; + DCHECK_LE(0, actual_locals); + constexpr int kNumCacheRegisters = NumRegs(kLiftoffAssemblerGpCacheRegs); + // If we have many locals, we put them on the stack initially. This avoids + // having to spill them on merge points. Use of these initial values should + // be rare anyway. + if (actual_locals > kNumCacheRegisters / 2) return true; + // If there are locals which are not i32 or i64, we also spill all locals, + // because other types cannot be initialized to constants. + for (uint32_t param_idx = num_params; param_idx < __ num_locals(); + ++param_idx) { + ValueType type = decoder->GetLocalType(param_idx); + if (type != kWasmI32 && type != kWasmI64) return true; + } + return false; + } + void StartFunctionBody(FullDecoder* decoder, Control* block) { for (uint32_t i = 0; i < __ num_locals(); ++i) { if (!CheckSupportedType(decoder, kSupportedTypes, __ local_type(i), @@ -373,6 +391,7 @@ class LiftoffCompiler { // LiftoffAssembler methods. if (DidAssemblerBailout(decoder)) return; + // Process parameters. __ SpillInstance(instance_reg); // Input 0 is the code target, 1 is the instance. First parameter at 2. uint32_t input_idx = kInstanceParameterIndex + 1; @@ -380,32 +399,20 @@ class LiftoffCompiler { input_idx += ProcessParameter(__ local_type(param_idx), input_idx); } DCHECK_EQ(input_idx, descriptor_->InputCount()); - // Set to a gp register, to mark this uninitialized. - LiftoffRegister zero_double_reg = kGpCacheRegList.GetFirstRegSet(); - DCHECK(zero_double_reg.is_gp()); - for (uint32_t param_idx = num_params; param_idx < __ num_locals(); - ++param_idx) { - ValueType type = decoder->GetLocalType(param_idx); - switch (type) { - case kWasmI32: - __ cache_state()->stack_state.emplace_back(kWasmI32, uint32_t{0}); - break; - case kWasmI64: - __ cache_state()->stack_state.emplace_back(kWasmI64, uint32_t{0}); - break; - case kWasmF32: - case kWasmF64: - if (zero_double_reg.is_gp()) { - // Note: This might spill one of the registers used to hold - // parameters. - zero_double_reg = __ GetUnusedRegister(kFpReg); - // Zero is represented by the bit pattern 0 for both f32 and f64. - __ LoadConstant(zero_double_reg, WasmValue(0.)); - } - __ PushRegister(type, zero_double_reg); - break; - default: - UNIMPLEMENTED(); + + // Initialize locals beyond parameters. + if (SpillLocalsInitially(decoder, num_params)) { + __ FillStackSlotsWithZero(num_params, __ num_locals() - num_params); + for (uint32_t param_idx = num_params; param_idx < __ num_locals(); + ++param_idx) { + ValueType type = decoder->GetLocalType(param_idx); + __ cache_state()->stack_state.emplace_back(type); + } + } else { + for (uint32_t param_idx = num_params; param_idx < __ num_locals(); + ++param_idx) { + ValueType type = decoder->GetLocalType(param_idx); + __ cache_state()->stack_state.emplace_back(type, int32_t{0}); } } @@ -488,7 +495,7 @@ class LiftoffCompiler { // Before entering a loop, spill all locals to the stack, in order to free // the cache registers, and to avoid unnecessarily reloading stack values // into registers at branches. - // TODO(clemensh): Come up with a better strategy here, involving + // TODO(clemensb): Come up with a better strategy here, involving // pre-analysis of the function. __ SpillLocals(); @@ -519,7 +526,7 @@ class LiftoffCompiler { } // Allocate the else state. - if_block->else_state = base::make_unique<ElseState>(); + if_block->else_state = std::make_unique<ElseState>(); // Test the condition, jump to else if zero. Register value = __ PopToRegister().gp(); @@ -617,8 +624,8 @@ class LiftoffCompiler { template <ValueType src_type, ValueType result_type, class EmitFn> void EmitUnOp(EmitFn fn) { - static RegClass src_rc = reg_class_for(src_type); - static RegClass result_rc = reg_class_for(result_type); + constexpr RegClass src_rc = reg_class_for(src_type); + constexpr RegClass result_rc = reg_class_for(result_type); LiftoffRegister src = __ PopToRegister(); LiftoffRegister dst = src_rc == result_rc ? __ GetUnusedRegister(result_rc, {src}) @@ -693,45 +700,44 @@ class LiftoffCompiler { void UnOp(FullDecoder* decoder, WasmOpcode opcode, const Value& value, Value* result) { #define CASE_I32_UNOP(opcode, fn) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitUnOp<kWasmI32, kWasmI32>( \ [=](LiftoffRegister dst, LiftoffRegister src) { \ __ emit_##fn(dst.gp(), src.gp()); \ }); \ break; #define CASE_I32_SIGN_EXTENSION(opcode, fn) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitUnOp<kWasmI32, kWasmI32>( \ [=](LiftoffRegister dst, LiftoffRegister src) { \ __ emit_##fn(dst.gp(), src.gp()); \ }); \ break; #define CASE_I64_SIGN_EXTENSION(opcode, fn) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitUnOp<kWasmI64, kWasmI64>( \ [=](LiftoffRegister dst, LiftoffRegister src) { \ __ emit_##fn(dst, src); \ }); \ break; #define CASE_FLOAT_UNOP(opcode, type, fn) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitUnOp<kWasm##type, kWasm##type>( \ [=](LiftoffRegister dst, LiftoffRegister src) { \ __ emit_##fn(dst.fp(), src.fp()); \ }); \ break; #define CASE_FLOAT_UNOP_WITH_CFALLBACK(opcode, type, fn) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitFloatUnOpWithCFallback<kWasm##type>(&LiftoffAssembler::emit_##fn, \ &ExternalReference::wasm_##fn); \ break; #define CASE_TYPE_CONVERSION(opcode, dst_type, src_type, ext_ref, can_trap) \ - case WasmOpcode::kExpr##opcode: \ + case kExpr##opcode: \ EmitTypeConversion<kWasm##dst_type, kWasm##src_type, can_trap>( \ kExpr##opcode, ext_ref, can_trap ? decoder->position() : 0); \ break; switch (opcode) { - CASE_I32_UNOP(I32Eqz, i32_eqz) CASE_I32_UNOP(I32Clz, i32_clz) CASE_I32_UNOP(I32Ctz, i32_ctz) CASE_FLOAT_UNOP(F32Abs, F32, f32_abs) @@ -786,29 +792,41 @@ class LiftoffCompiler { CASE_I64_SIGN_EXTENSION(I64SExtendI8, i64_signextend_i8) CASE_I64_SIGN_EXTENSION(I64SExtendI16, i64_signextend_i16) CASE_I64_SIGN_EXTENSION(I64SExtendI32, i64_signextend_i32) + case kExprI32Eqz: + DCHECK(decoder->lookahead(0, kExprI32Eqz)); + if (decoder->lookahead(1, kExprBrIf)) { + DCHECK(!has_outstanding_op()); + outstanding_op_ = kExprI32Eqz; + break; + } + EmitUnOp<kWasmI32, kWasmI32>( + [=](LiftoffRegister dst, LiftoffRegister src) { + __ emit_i32_eqz(dst.gp(), src.gp()); + }); + break; case kExprI32Popcnt: EmitI32UnOpWithCFallback(&LiftoffAssembler::emit_i32_popcnt, &ExternalReference::wasm_word32_popcnt); break; - case WasmOpcode::kExprI64Eqz: + case kExprI64Eqz: EmitUnOp<kWasmI64, kWasmI32>( [=](LiftoffRegister dst, LiftoffRegister src) { __ emit_i64_eqz(dst.gp(), src); }); break; - case WasmOpcode::kExprI64Clz: - case WasmOpcode::kExprI64Ctz: - case WasmOpcode::kExprI64Popcnt: + case kExprI64Clz: + case kExprI64Ctz: + case kExprI64Popcnt: return unsupported(decoder, kComplexOperation, WasmOpcodes::OpcodeName(opcode)); - case WasmOpcode::kExprI32SConvertSatF32: - case WasmOpcode::kExprI32UConvertSatF32: - case WasmOpcode::kExprI32SConvertSatF64: - case WasmOpcode::kExprI32UConvertSatF64: - case WasmOpcode::kExprI64SConvertSatF32: - case WasmOpcode::kExprI64UConvertSatF32: - case WasmOpcode::kExprI64SConvertSatF64: - case WasmOpcode::kExprI64UConvertSatF64: + case kExprI32SConvertSatF32: + case kExprI32UConvertSatF32: + case kExprI32SConvertSatF64: + case kExprI32UConvertSatF64: + case kExprI64SConvertSatF32: + case kExprI64UConvertSatF32: + case kExprI64SConvertSatF64: + case kExprI64UConvertSatF64: return unsupported(decoder, kNonTrappingFloatToInt, WasmOpcodes::OpcodeName(opcode)); default: @@ -1224,7 +1242,7 @@ class LiftoffCompiler { ReturnImpl(decoder); } - void GetLocal(FullDecoder* decoder, Value* result, + void LocalGet(FullDecoder* decoder, Value* result, const LocalIndexImmediate<validate>& imm) { auto& slot = __ cache_state()->stack_state[imm.index]; DCHECK_EQ(slot.type(), imm.type); @@ -1245,7 +1263,7 @@ class LiftoffCompiler { } } - void SetLocalFromStackSlot(LiftoffAssembler::VarState* dst_slot, + void LocalSetFromStackSlot(LiftoffAssembler::VarState* dst_slot, uint32_t local_index) { auto& state = *__ cache_state(); ValueType type = dst_slot->type(); @@ -1266,7 +1284,7 @@ class LiftoffCompiler { __ cache_state()->inc_used(dst_reg); } - void SetLocal(uint32_t local_index, bool is_tee) { + void LocalSet(uint32_t local_index, bool is_tee) { auto& state = *__ cache_state(); auto& source_slot = state.stack_state.back(); auto& target_slot = state.stack_state[local_index]; @@ -1281,20 +1299,20 @@ class LiftoffCompiler { target_slot = source_slot; break; case kStack: - SetLocalFromStackSlot(&target_slot, local_index); + LocalSetFromStackSlot(&target_slot, local_index); break; } if (!is_tee) __ cache_state()->stack_state.pop_back(); } - void SetLocal(FullDecoder* decoder, const Value& value, + void LocalSet(FullDecoder* decoder, const Value& value, const LocalIndexImmediate<validate>& imm) { - SetLocal(imm.index, false); + LocalSet(imm.index, false); } - void TeeLocal(FullDecoder* decoder, const Value& value, Value* result, + void LocalTee(FullDecoder* decoder, const Value& value, Value* result, const LocalIndexImmediate<validate>& imm) { - SetLocal(imm.index, true); + LocalSet(imm.index, true); } Register GetGlobalBaseAndOffset(const WasmGlobal* global, @@ -1312,7 +1330,7 @@ class LiftoffCompiler { return addr; } - void GetGlobal(FullDecoder* decoder, Value* result, + void GlobalGet(FullDecoder* decoder, Value* result, const GlobalIndexImmediate<validate>& imm) { const auto* global = &env_->module->globals[imm.index]; if (!CheckSupportedType(decoder, kSupportedTypes, global->type, "global")) @@ -1327,7 +1345,7 @@ class LiftoffCompiler { __ PushRegister(global->type, value); } - void SetGlobal(FullDecoder* decoder, const Value& value, + void GlobalSet(FullDecoder* decoder, const Value& value, const GlobalIndexImmediate<validate>& imm) { auto* global = &env_->module->globals[imm.index]; if (!CheckSupportedType(decoder, kSupportedTypes, global->type, "global")) @@ -1402,10 +1420,18 @@ class LiftoffCompiler { } } - void BrIf(FullDecoder* decoder, const Value& cond, uint32_t depth) { + void BrIf(FullDecoder* decoder, const Value& /* cond */, uint32_t depth) { + Condition cond = kEqual; // Unary "equal" means "equals zero". + + if (has_outstanding_op()) { + DCHECK_EQ(kExprI32Eqz, outstanding_op_); + cond = kUnequal; // Unary "unequal" means "not equals zero". + outstanding_op_ = kNoOutstandingOp; + } + Label cont_false; Register value = __ PopToRegister().gp(); - __ emit_cond_jump(kEqual, &cont_false, kWasmI32, value); + __ emit_cond_jump(cond, &cont_false, kWasmI32, value); BrOrRet(decoder, depth); __ bind(&cont_false); @@ -2056,7 +2082,14 @@ class LiftoffCompiler { } private: + static constexpr WasmOpcode kNoOutstandingOp = kExprUnreachable; + LiftoffAssembler asm_; + + // Used for merging code generation of subsequent operations (via look-ahead). + // Set by the first opcode, reset by the second. + WasmOpcode outstanding_op_ = kNoOutstandingOp; + compiler::CallDescriptor* const descriptor_; CompilationEnv* const env_; LiftoffBailoutReason bailout_reason_ = kSuccess; @@ -2072,6 +2105,10 @@ class LiftoffCompiler { // patch the actually needed stack size in the end. uint32_t pc_offset_stack_frame_construction_ = 0; + bool has_outstanding_op() const { + return outstanding_op_ != kNoOutstandingOp; + } + void TraceCacheState(FullDecoder* decoder) const { #ifdef DEBUG if (!FLAG_trace_liftoff || !FLAG_trace_wasm_decoder) return; diff --git a/deps/v8/src/wasm/baseline/liftoff-register.h b/deps/v8/src/wasm/baseline/liftoff-register.h index 267a0055470f6b..b322f7eb68d387 100644 --- a/deps/v8/src/wasm/baseline/liftoff-register.h +++ b/deps/v8/src/wasm/baseline/liftoff-register.h @@ -32,15 +32,18 @@ static inline constexpr bool needs_reg_pair(ValueType type) { return kNeedI64RegPair && type == kWasmI64; } -// TODO(clemensh): Use a switch once we require C++14 support. static inline constexpr RegClass reg_class_for(ValueType type) { - return needs_reg_pair(type) // i64 on 32 bit - ? kGpRegPair - : type == kWasmI32 || type == kWasmI64 // int types - ? kGpReg - : type == kWasmF32 || type == kWasmF64 // float types - ? kFpReg - : kNoReg; // other (unsupported) types + switch (type) { + case kWasmF32: + case kWasmF64: + return kFpReg; + case kWasmI32: + return kGpReg; + case kWasmI64: + return kNeedI64RegPair ? kGpRegPair : kGpReg; + default: + return kNoReg; // unsupported type + } } // Maximum code of a gp cache register. diff --git a/deps/v8/src/wasm/baseline/mips/liftoff-assembler-mips.h b/deps/v8/src/wasm/baseline/mips/liftoff-assembler-mips.h index e82ffe8f67d82b..4c69e423c1aa6f 100644 --- a/deps/v8/src/wasm/baseline/mips/liftoff-assembler-mips.h +++ b/deps/v8/src/wasm/baseline/mips/liftoff-assembler-mips.h @@ -13,6 +13,28 @@ namespace wasm { namespace liftoff { +// half +// slot Frame +// -----+--------------------+--------------------------- +// n+3 | parameter n | +// ... | ... | +// 4 | parameter 1 | or parameter 2 +// 3 | parameter 0 | or parameter 1 +// 2 | (result address) | or parameter 0 +// -----+--------------------+--------------------------- +// 1 | return addr (ra) | +// 0 | previous frame (fp)| +// -----+--------------------+ <-- frame ptr (fp) +// -1 | 0xa: WASM_COMPILED | +// -2 | instance | +// -----+--------------------+--------------------------- +// -3 | slot 0 (high) | ^ +// -4 | slot 0 (low) | | +// -5 | slot 1 (high) | Frame slots +// -6 | slot 1 (low) | | +// | | v +// -----+--------------------+ <-- stack ptr (sp) +// #if defined(V8_TARGET_BIG_ENDIAN) constexpr int32_t kLowWordOffset = 4; constexpr int32_t kHighWordOffset = 0; @@ -27,9 +49,12 @@ constexpr int32_t kConstantStackSpace = 8; constexpr int32_t kFirstStackSlotOffset = kConstantStackSpace + LiftoffAssembler::kStackSlotSize; +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + inline MemOperand GetStackSlot(uint32_t index) { - int32_t offset = index * LiftoffAssembler::kStackSlotSize; - return MemOperand(fp, -kFirstStackSlotOffset - offset); + return MemOperand(fp, -GetStackSlotOffset(index)); } inline MemOperand GetHalfStackSlot(uint32_t index, RegPairHalf half) { @@ -583,6 +608,34 @@ void LiftoffAssembler::FillI64Half(Register reg, uint32_t index, lw(reg, liftoff::GetHalfStackSlot(index, half)); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + if (count <= 12) { + // Special straight-line code for up to 12 slots. Generates one + // instruction per slot (<=12 instructions total). + for (uint32_t offset = 0; offset < count; ++offset) { + Sw(zero_reg, liftoff::GetStackSlot(index + offset)); + } + } else { + // General case for bigger counts (12 instructions). + // Use a0 for start address (inclusive), a1 for end address (exclusive). + Push(a1, a0); + Addu(a0, fp, Operand(-liftoff::GetStackSlotOffset(last_stack_slot))); + Addu(a1, fp, Operand(-liftoff::GetStackSlotOffset(index) + kStackSlotSize)); + + Label loop; + bind(&loop); + Sw(zero_reg, MemOperand(a0, kSystemPointerSize)); + addiu(a0, a0, kSystemPointerSize); + BranchShort(&loop, ne, a0, Operand(a1)); + + Pop(a1, a0); + } +} + void LiftoffAssembler::emit_i32_mul(Register dst, Register lhs, Register rhs) { TurboAssembler::Mul(dst, lhs, rhs); } diff --git a/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64.h b/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64.h index 9c87dca7330c9c..5314a65da5705e 100644 --- a/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64.h +++ b/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64.h @@ -13,15 +13,44 @@ namespace wasm { namespace liftoff { +// Liftoff Frames. +// +// slot Frame +// +--------------------+--------------------------- +// n+4 | optional padding slot to keep the stack 16 byte aligned. +// n+3 | parameter n | +// ... | ... | +// 4 | parameter 1 | or parameter 2 +// 3 | parameter 0 | or parameter 1 +// 2 | (result address) | or parameter 0 +// -----+--------------------+--------------------------- +// 1 | return addr (ra) | +// 0 | previous frame (fp)| +// -----+--------------------+ <-- frame ptr (fp) +// -1 | 0xa: WASM_COMPILED | +// -2 | instance | +// -----+--------------------+--------------------------- +// -3 | slot 0 | ^ +// -4 | slot 1 | | +// | | Frame slots +// | | | +// | | v +// | optional padding slot to keep the stack 16 byte aligned. +// -----+--------------------+ <-- stack ptr (sp) +// + // fp-8 holds the stack marker, fp-16 is the instance parameter, first stack // slot is located at fp-24. constexpr int32_t kConstantStackSpace = 16; constexpr int32_t kFirstStackSlotOffset = kConstantStackSpace + LiftoffAssembler::kStackSlotSize; +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + inline MemOperand GetStackSlot(uint32_t index) { - int32_t offset = index * LiftoffAssembler::kStackSlotSize; - return MemOperand(fp, -kFirstStackSlotOffset - offset); + return MemOperand(fp, -GetStackSlotOffset(index)); } inline MemOperand GetInstanceOperand() { return MemOperand(fp, -16); } @@ -498,6 +527,35 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t index, RegPairHalf) { UNREACHABLE(); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + if (count <= 12) { + // Special straight-line code for up to 12 slots. Generates one + // instruction per slot (<= 12 instructions total). + for (uint32_t offset = 0; offset < count; ++offset) { + Sd(zero_reg, liftoff::GetStackSlot(index + offset)); + } + } else { + // General case for bigger counts (12 instructions). + // Use a0 for start address (inclusive), a1 for end address (exclusive). + Push(a1, a0); + Daddu(a0, fp, Operand(-liftoff::GetStackSlotOffset(last_stack_slot))); + Daddu(a1, fp, + Operand(-liftoff::GetStackSlotOffset(index) + kStackSlotSize)); + + Label loop; + bind(&loop); + Sd(zero_reg, MemOperand(a0, kSystemPointerSize)); + daddiu(a0, a0, kSystemPointerSize); + BranchShort(&loop, ne, a0, Operand(a1)); + + Pop(a1, a0); + } +} + void LiftoffAssembler::emit_i32_mul(Register dst, Register lhs, Register rhs) { TurboAssembler::Mul(dst, lhs, rhs); } diff --git a/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc.h b/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc.h index a690a1c090dd6b..3b436a96d51c5f 100644 --- a/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc.h +++ b/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc.h @@ -12,6 +12,49 @@ namespace v8 { namespace internal { namespace wasm { +namespace liftoff { + +// half +// slot Frame +// -----+--------------------+--------------------------- +// n+3 | parameter n | +// ... | ... | +// 4 | parameter 1 | or parameter 2 +// 3 | parameter 0 | or parameter 1 +// 2 | (result address) | or parameter 0 +// -----+--------------------+--------------------------- +// 1 | return addr (lr) | +// 0 | previous frame (fp)| +// -----+--------------------+ <-- frame ptr (fp) +// -1 | 0xa: WASM_COMPILED | +// -2 | instance | +// -----+--------------------+--------------------------- +// -3 | slot 0 (high) | ^ +// -4 | slot 0 (low) | | +// -5 | slot 1 (high) | Frame slots +// -6 | slot 1 (low) | | +// | | v +// -----+--------------------+ <-- stack ptr (sp) +// + +constexpr int32_t kInstanceOffset = 2 * kSystemPointerSize; +constexpr int32_t kFirstStackSlotOffset = + kInstanceOffset + 2 * kSystemPointerSize; + +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + +inline MemOperand GetHalfStackSlot(uint32_t index, RegPairHalf half) { + int32_t half_offset = + half == kLowWord ? 0 : LiftoffAssembler::kStackSlotSize / 2; + int32_t offset = kFirstStackSlotOffset + + index * LiftoffAssembler::kStackSlotSize - half_offset; + return MemOperand(fp, -offset); +} + +} // namespace liftoff + int LiftoffAssembler::PrepareStackFrame() { bailout(kUnsupportedArchitecture, "PrepareStackFrame"); return 0; @@ -108,6 +151,45 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t index, RegPairHalf) { bailout(kUnsupportedArchitecture, "FillI64Half"); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + // We need a zero reg. Always use r0 for that, and push it before to restore + // its value afterwards. + push(r0); + mov(r0, Operand(0)); + + if (count <= 5) { + // Special straight-line code for up to five slots. Generates two + // instructions per slot. + for (uint32_t offset = 0; offset < count; ++offset) { + StoreP(r0, liftoff::GetHalfStackSlot(index + offset, kLowWord)); + StoreP(r0, liftoff::GetHalfStackSlot(index + offset, kHighWord)); + } + } else { + // General case for bigger counts (9 instructions). + // Use r4 for start address (inclusive), r5 for end address (exclusive). + push(r4); + push(r5); + subi(r4, fp, Operand(liftoff::GetStackSlotOffset(last_stack_slot))); + subi(r5, fp, Operand(liftoff::GetStackSlotOffset(index) + kStackSlotSize)); + + Label loop; + bind(&loop); + StoreP(r0, MemOperand(r0)); + addi(r0, r0, Operand(kSystemPointerSize)); + cmp(r4, r5); + bne(&loop); + + pop(r4); + pop(r5); + } + + pop(r0); +} + #define UNIMPLEMENTED_I32_BINOP(name) \ void LiftoffAssembler::emit_##name(Register dst, Register lhs, \ Register rhs) { \ diff --git a/deps/v8/src/wasm/baseline/s390/liftoff-assembler-s390.h b/deps/v8/src/wasm/baseline/s390/liftoff-assembler-s390.h index d17c7dada1cc57..36267560dda4b7 100644 --- a/deps/v8/src/wasm/baseline/s390/liftoff-assembler-s390.h +++ b/deps/v8/src/wasm/baseline/s390/liftoff-assembler-s390.h @@ -12,6 +12,48 @@ namespace v8 { namespace internal { namespace wasm { +namespace liftoff { + +// half +// slot Frame +// -----+--------------------+--------------------------- +// n+3 | parameter n | +// ... | ... | +// 4 | parameter 1 | or parameter 2 +// 3 | parameter 0 | or parameter 1 +// 2 | (result address) | or parameter 0 +// -----+--------------------+--------------------------- +// 1 | return addr (lr) | +// 0 | previous frame (fp)| +// -----+--------------------+ <-- frame ptr (fp) +// -1 | 0xa: WASM_COMPILED | +// -2 | instance | +// -----+--------------------+--------------------------- +// -3 | slot 0 (high) | ^ +// -4 | slot 0 (low) | | +// -5 | slot 1 (high) | Frame slots +// -6 | slot 1 (low) | | +// | | v +// -----+--------------------+ <-- stack ptr (sp) +// +constexpr int32_t kInstanceOffset = 2 * kSystemPointerSize; +constexpr int32_t kFirstStackSlotOffset = + kInstanceOffset + 2 * kSystemPointerSize; + +inline int GetStackSlotOffset(uint32_t index) { + return kFirstStackSlotOffset + index * LiftoffAssembler::kStackSlotSize; +} + +inline MemOperand GetHalfStackSlot(uint32_t index, RegPairHalf half) { + int32_t half_offset = + half == kLowWord ? 0 : LiftoffAssembler::kStackSlotSize / 2; + int32_t offset = kFirstStackSlotOffset + + index * LiftoffAssembler::kStackSlotSize - half_offset; + return MemOperand(fp, -offset); +} + +} // namespace liftoff + int LiftoffAssembler::PrepareStackFrame() { bailout(kUnsupportedArchitecture, "PrepareStackFrame"); return 0; @@ -108,6 +150,45 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t index, RegPairHalf) { bailout(kUnsupportedArchitecture, "FillI64Half"); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + // We need a zero reg. Always use r0 for that, and push it before to restore + // its value afterwards. + push(r0); + mov(r0, Operand(0)); + + if (count <= 5) { + // Special straight-line code for up to five slots. Generates two + // instructions per slot. + for (uint32_t offset = 0; offset < count; ++offset) { + StoreP(r0, liftoff::GetHalfStackSlot(index + offset, kLowWord)); + StoreP(r0, liftoff::GetHalfStackSlot(index + offset, kHighWord)); + } + } else { + // General case for bigger counts (9 instructions). + // Use r3 for start address (inclusive), r4 for end address (exclusive). + push(r3); + push(r4); + SubP(r3, fp, Operand(liftoff::GetStackSlotOffset(last_stack_slot))); + SubP(r4, fp, Operand(liftoff::GetStackSlotOffset(index) + kStackSlotSize)); + + Label loop; + bind(&loop); + StoreP(r0, MemOperand(r0)); + la(r0, MemOperand(r0, kSystemPointerSize)); + CmpLogicalP(r3, r4); + bne(&loop); + + pop(r4); + pop(r3); + } + + pop(r0); +} + #define UNIMPLEMENTED_I32_BINOP(name) \ void LiftoffAssembler::emit_##name(Register dst, Register lhs, \ Register rhs) { \ diff --git a/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64.h b/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64.h index 43637985d050e3..f4185de0700a37 100644 --- a/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64.h +++ b/deps/v8/src/wasm/baseline/x64/liftoff-assembler-x64.h @@ -47,7 +47,7 @@ inline Operand GetStackSlot(uint32_t index) { return Operand(rbp, -kFirstStackSlotOffset - offset); } -// TODO(clemensh): Make this a constexpr variable once Operand is constexpr. +// TODO(clemensb): Make this a constexpr variable once Operand is constexpr. inline Operand GetInstanceOperand() { return Operand(rbp, -16); } inline Operand GetMemOp(LiftoffAssembler* assm, Register addr, Register offset, @@ -452,6 +452,35 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t index, RegPairHalf) { UNREACHABLE(); } +void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) { + DCHECK_LT(0, count); + uint32_t last_stack_slot = index + count - 1; + RecordUsedSpillSlot(last_stack_slot); + + if (count <= 3) { + // Special straight-line code for up to three slots + // (7-10 bytes per slot: REX C7 <1-4 bytes op> <4 bytes imm>). + for (uint32_t offset = 0; offset < count; ++offset) { + movq(liftoff::GetStackSlot(index + offset), Immediate(0)); + } + } else { + // General case for bigger counts. + // This sequence takes 20-23 bytes (3 for pushes, 4-7 for lea, 2 for xor, 5 + // for mov, 3 for repstosq, 3 for pops). + // From intel manual: repstosq fills RCX quadwords at [RDI] with RAX. + pushq(rax); + pushq(rcx); + pushq(rdi); + leaq(rdi, liftoff::GetStackSlot(last_stack_slot)); + xorl(rax, rax); + movl(rcx, Immediate(count)); + repstosq(); + popq(rdi); + popq(rcx); + popq(rax); + } +} + void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) { if (lhs != dst) { leal(dst, Operand(lhs, rhs, times_1, 0)); diff --git a/deps/v8/src/wasm/c-api.cc b/deps/v8/src/wasm/c-api.cc index e812dd7994fdf7..31b68e9cdc5672 100644 --- a/deps/v8/src/wasm/c-api.cc +++ b/deps/v8/src/wasm/c-api.cc @@ -1692,17 +1692,17 @@ auto Global::type() const -> own<GlobalType> { auto Global::get() const -> Val { i::Handle<i::WasmGlobalObject> v8_global = impl(this)->v8_object(); - switch (type()->content()->kind()) { - case I32: + switch (v8_global->type()) { + case i::wasm::kWasmI32: return Val(v8_global->GetI32()); - case I64: + case i::wasm::kWasmI64: return Val(v8_global->GetI64()); - case F32: + case i::wasm::kWasmF32: return Val(v8_global->GetF32()); - case F64: + case i::wasm::kWasmF64: return Val(v8_global->GetF64()); - case ANYREF: - case FUNCREF: { + case i::wasm::kWasmAnyRef: + case i::wasm::kWasmFuncRef: { StoreImpl* store = impl(this)->store(); i::HandleScope scope(store->i_isolate()); return Val(V8RefValueToWasm(store, v8_global->GetRef())); @@ -1883,9 +1883,10 @@ auto Memory::make(Store* store_abs, const MemoryType* type) -> own<Memory> { if (maximum < minimum) return nullptr; if (maximum > i::wasm::kSpecMaxWasmMemoryPages) return nullptr; } - bool is_shared = false; // TODO(wasm+): Support shared memory. + // TODO(wasm+): Support shared memory. + i::SharedFlag shared = i::SharedFlag::kNotShared; i::Handle<i::WasmMemoryObject> memory_obj; - if (!i::WasmMemoryObject::New(isolate, minimum, maximum, is_shared) + if (!i::WasmMemoryObject::New(isolate, minimum, maximum, shared) .ToHandle(&memory_obj)) { return own<Memory>(); } diff --git a/deps/v8/src/wasm/decoder.h b/deps/v8/src/wasm/decoder.h index abb7b8ee86851e..71c06467f11bcf 100644 --- a/deps/v8/src/wasm/decoder.h +++ b/deps/v8/src/wasm/decoder.h @@ -267,6 +267,12 @@ class Decoder { } const byte* end() const { return end_; } + // Check if the byte at {offset} from the current pc equals {expected}. + bool lookahead(int offset, byte expected) { + DCHECK_LE(pc_, end_); + return end_ - pc_ > offset && pc_[offset] == expected; + } + protected: const byte* start_; const byte* pc_; diff --git a/deps/v8/src/wasm/function-body-decoder-impl.h b/deps/v8/src/wasm/function-body-decoder-impl.h index 582934e19f031b..1f29571e40627a 100644 --- a/deps/v8/src/wasm/function-body-decoder-impl.h +++ b/deps/v8/src/wasm/function-body-decoder-impl.h @@ -714,12 +714,12 @@ struct ControlBase { F(RefFunc, uint32_t function_index, Value* result) \ F(Drop, const Value& value) \ F(DoReturn, Vector<Value> values) \ - F(GetLocal, Value* result, const LocalIndexImmediate<validate>& imm) \ - F(SetLocal, const Value& value, const LocalIndexImmediate<validate>& imm) \ - F(TeeLocal, const Value& value, Value* result, \ + F(LocalGet, Value* result, const LocalIndexImmediate<validate>& imm) \ + F(LocalSet, const Value& value, const LocalIndexImmediate<validate>& imm) \ + F(LocalTee, const Value& value, Value* result, \ const LocalIndexImmediate<validate>& imm) \ - F(GetGlobal, Value* result, const GlobalIndexImmediate<validate>& imm) \ - F(SetGlobal, const Value& value, const GlobalIndexImmediate<validate>& imm) \ + F(GlobalGet, Value* result, const GlobalIndexImmediate<validate>& imm) \ + F(GlobalSet, const Value& value, const GlobalIndexImmediate<validate>& imm) \ F(TableGet, const Value& index, Value* result, \ const TableIndexImmediate<validate>& imm) \ F(TableSet, const Value& index, const Value& value, \ @@ -910,8 +910,8 @@ class WasmDecoder : public Decoder { length = OpcodeLength(decoder, pc); depth++; break; - case kExprSetLocal: // fallthru - case kExprTeeLocal: { + case kExprLocalSet: // fallthru + case kExprLocalTee: { LocalIndexImmediate<validate> imm(decoder, pc); if (assigned->length() > 0 && imm.index < static_cast<uint32_t>(assigned->length())) { @@ -1045,8 +1045,8 @@ class WasmDecoder : public Decoder { bool Validate(const byte* pc, BranchTableImmediate<validate>& imm, size_t block_depth) { - if (!VALIDATE(imm.table_count < kV8MaxWasmFunctionSize)) { - errorf(pc + 1, "invalid table count (> max function size): %u", + if (!VALIDATE(imm.table_count <= kV8MaxWasmFunctionBrTableSize)) { + errorf(pc + 1, "invalid table count (> max br_table size): %u", imm.table_count); return false; } @@ -1069,11 +1069,13 @@ class WasmDecoder : public Decoder { case kExprI32x4ReplaceLane: num_lanes = 4; break; - case kExprI16x8ExtractLane: + case kExprI16x8ExtractLaneS: + case kExprI16x8ExtractLaneU: case kExprI16x8ReplaceLane: num_lanes = 8; break; - case kExprI8x16ExtractLane: + case kExprI8x16ExtractLaneS: + case kExprI8x16ExtractLaneU: case kExprI8x16ReplaceLane: num_lanes = 16; break; @@ -1252,8 +1254,8 @@ class WasmDecoder : public Decoder { BranchDepthImmediate<validate> imm(decoder, pc); return 1 + imm.length; } - case kExprGetGlobal: - case kExprSetGlobal: { + case kExprGlobalGet: + case kExprGlobalSet: { GlobalIndexImmediate<validate> imm(decoder, pc); return 1 + imm.length; } @@ -1291,9 +1293,9 @@ class WasmDecoder : public Decoder { return 1 + imm.length; } - case kExprSetLocal: - case kExprTeeLocal: - case kExprGetLocal: { + case kExprLocalGet: + case kExprLocalSet: + case kExprLocalTee: { LocalIndexImmediate<validate> imm(decoder, pc); return 1 + imm.length; } @@ -1458,19 +1460,19 @@ class WasmDecoder : public Decoder { return {2, 0}; FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) case kExprTableGet: - case kExprTeeLocal: + case kExprLocalTee: case kExprMemoryGrow: return {1, 1}; - case kExprSetLocal: - case kExprSetGlobal: + case kExprLocalSet: + case kExprGlobalSet: case kExprDrop: case kExprBrIf: case kExprBrTable: case kExprIf: case kExprRethrow: return {1, 0}; - case kExprGetLocal: - case kExprGetGlobal: + case kExprLocalGet: + case kExprGlobalGet: case kExprI32Const: case kExprI64Const: case kExprF32Const: @@ -2125,28 +2127,28 @@ class WasmFullDecoder : public WasmDecoder<validate> { len = 1 + imm.length; break; } - case kExprGetLocal: { + case kExprLocalGet: { LocalIndexImmediate<validate> imm(this, this->pc_); if (!this->Validate(this->pc_, imm)) break; auto* value = Push(imm.type); - CALL_INTERFACE_IF_REACHABLE(GetLocal, value, imm); + CALL_INTERFACE_IF_REACHABLE(LocalGet, value, imm); len = 1 + imm.length; break; } - case kExprSetLocal: { + case kExprLocalSet: { LocalIndexImmediate<validate> imm(this, this->pc_); if (!this->Validate(this->pc_, imm)) break; auto value = Pop(0, local_type_vec_[imm.index]); - CALL_INTERFACE_IF_REACHABLE(SetLocal, value, imm); + CALL_INTERFACE_IF_REACHABLE(LocalSet, value, imm); len = 1 + imm.length; break; } - case kExprTeeLocal: { + case kExprLocalTee: { LocalIndexImmediate<validate> imm(this, this->pc_); if (!this->Validate(this->pc_, imm)) break; auto value = Pop(0, local_type_vec_[imm.index]); auto* result = Push(value.type); - CALL_INTERFACE_IF_REACHABLE(TeeLocal, value, result, imm); + CALL_INTERFACE_IF_REACHABLE(LocalTee, value, result, imm); len = 1 + imm.length; break; } @@ -2155,15 +2157,15 @@ class WasmFullDecoder : public WasmDecoder<validate> { CALL_INTERFACE_IF_REACHABLE(Drop, value); break; } - case kExprGetGlobal: { + case kExprGlobalGet: { GlobalIndexImmediate<validate> imm(this, this->pc_); len = 1 + imm.length; if (!this->Validate(this->pc_, imm)) break; auto* result = Push(imm.type); - CALL_INTERFACE_IF_REACHABLE(GetGlobal, result, imm); + CALL_INTERFACE_IF_REACHABLE(GlobalGet, result, imm); break; } - case kExprSetGlobal: { + case kExprGlobalSet: { GlobalIndexImmediate<validate> imm(this, this->pc_); len = 1 + imm.length; if (!this->Validate(this->pc_, imm)) break; @@ -2173,7 +2175,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { break; } auto value = Pop(0, imm.type); - CALL_INTERFACE_IF_REACHABLE(SetGlobal, value, imm); + CALL_INTERFACE_IF_REACHABLE(GlobalSet, value, imm); break; } case kExprTableGet: { @@ -2447,15 +2449,15 @@ class WasmFullDecoder : public WasmDecoder<validate> { TRACE_PART("[%d]", imm.value); break; } - case kExprGetLocal: - case kExprSetLocal: - case kExprTeeLocal: { + case kExprLocalGet: + case kExprLocalSet: + case kExprLocalTee: { LocalIndexImmediate<Decoder::kNoValidate> imm(this, val.pc); TRACE_PART("[%u]", imm.index); break; } - case kExprGetGlobal: - case kExprSetGlobal: { + case kExprGlobalGet: + case kExprGlobalSet: { GlobalIndexImmediate<Decoder::kNoValidate> imm(this, val.pc); TRACE_PART("[%u]", imm.index); break; @@ -2700,8 +2702,10 @@ class WasmFullDecoder : public WasmDecoder<validate> { break; } case kExprI32x4ExtractLane: - case kExprI16x8ExtractLane: - case kExprI8x16ExtractLane: { + case kExprI16x8ExtractLaneS: + case kExprI16x8ExtractLaneU: + case kExprI8x16ExtractLaneS: + case kExprI8x16ExtractLaneU: { len = SimdExtractLane(opcode, kWasmI32); break; } diff --git a/deps/v8/src/wasm/function-compiler.cc b/deps/v8/src/wasm/function-compiler.cc index 4940134d53c657..e89c31d72954a1 100644 --- a/deps/v8/src/wasm/function-compiler.cc +++ b/deps/v8/src/wasm/function-compiler.cc @@ -49,7 +49,7 @@ class WasmInstructionBufferImpl { holder_->old_buffer_ = std::move(holder_->buffer_); holder_->buffer_ = OwnedVector<uint8_t>::New(new_size); - return base::make_unique<View>(holder_->buffer_.as_vector(), holder_); + return std::make_unique<View>(holder_->buffer_.as_vector(), holder_); } private: @@ -59,7 +59,7 @@ class WasmInstructionBufferImpl { std::unique_ptr<AssemblerBuffer> CreateView() { DCHECK_NOT_NULL(buffer_); - return base::make_unique<View>(buffer_.as_vector(), this); + return std::make_unique<View>(buffer_.as_vector(), this); } std::unique_ptr<uint8_t[]> ReleaseBuffer() { @@ -170,7 +170,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteFunctionCompilation( TimedHistogramScope wasm_compile_function_time_scope(timed_histogram); if (FLAG_trace_wasm_compiler) { - PrintF("Compiling wasm function %d with %s\n\n", func_index_, + PrintF("Compiling wasm function %d with %s\n", func_index_, ExecutionTierToString(tier_)); } diff --git a/deps/v8/src/wasm/function-compiler.h b/deps/v8/src/wasm/function-compiler.h index 2da028a047e9e0..bdebfebe14d460 100644 --- a/deps/v8/src/wasm/function-compiler.h +++ b/deps/v8/src/wasm/function-compiler.h @@ -5,6 +5,8 @@ #ifndef V8_WASM_FUNCTION_COMPILER_H_ #define V8_WASM_FUNCTION_COMPILER_H_ +#include <memory> + #include "src/codegen/code-desc.h" #include "src/trap-handler/trap-handler.h" #include "src/wasm/compilation-environment.h" diff --git a/deps/v8/src/wasm/graph-builder-interface.cc b/deps/v8/src/wasm/graph-builder-interface.cc index 923e1154ea09c3..b08aa9215ec275 100644 --- a/deps/v8/src/wasm/graph-builder-interface.cc +++ b/deps/v8/src/wasm/graph-builder-interface.cc @@ -166,7 +166,8 @@ class WasmGraphBuildingInterface { // Wrap input merge into phis. for (uint32_t i = 0; i < block->start_merge.arity; ++i) { Value& val = block->start_merge[i]; - val.node = builder_->Phi(val.type, 1, &val.node, block->end_env->control); + TFNode* inputs[] = {val.node, block->end_env->control}; + val.node = builder_->Phi(val.type, 1, inputs); } } @@ -212,7 +213,10 @@ class WasmGraphBuildingInterface { if (block->is_onearmed_if()) { // Merge the else branch into the end merge. SetEnv(block->false_env); - MergeValuesInto(decoder, block, &block->end_merge); + DCHECK_EQ(block->start_merge.arity, block->end_merge.arity); + Value* values = + block->start_merge.arity > 0 ? &block->start_merge[0] : nullptr; + MergeValuesInto(decoder, block, &block->end_merge, values); } // Now continue with the merged environment. SetEnv(block->end_env); @@ -258,37 +262,38 @@ class WasmGraphBuildingInterface { void Drop(FullDecoder* decoder, const Value& value) {} void DoReturn(FullDecoder* decoder, Vector<Value> values) { - Vector<TFNode*> nodes = GetNodes(values); - BUILD(Return, nodes); + base::SmallVector<TFNode*, 8> nodes(values.size()); + GetNodes(nodes.begin(), values); + BUILD(Return, VectorOf(nodes)); } - void GetLocal(FullDecoder* decoder, Value* result, + void LocalGet(FullDecoder* decoder, Value* result, const LocalIndexImmediate<validate>& imm) { if (!ssa_env_->locals) return; // unreachable result->node = ssa_env_->locals[imm.index]; } - void SetLocal(FullDecoder* decoder, const Value& value, + void LocalSet(FullDecoder* decoder, const Value& value, const LocalIndexImmediate<validate>& imm) { if (!ssa_env_->locals) return; // unreachable ssa_env_->locals[imm.index] = value.node; } - void TeeLocal(FullDecoder* decoder, const Value& value, Value* result, + void LocalTee(FullDecoder* decoder, const Value& value, Value* result, const LocalIndexImmediate<validate>& imm) { result->node = value.node; if (!ssa_env_->locals) return; // unreachable ssa_env_->locals[imm.index] = value.node; } - void GetGlobal(FullDecoder* decoder, Value* result, + void GlobalGet(FullDecoder* decoder, Value* result, const GlobalIndexImmediate<validate>& imm) { - result->node = BUILD(GetGlobal, imm.index); + result->node = BUILD(GlobalGet, imm.index); } - void SetGlobal(FullDecoder* decoder, const Value& value, + void GlobalSet(FullDecoder* decoder, const Value& value, const GlobalIndexImmediate<validate>& imm) { - BUILD(SetGlobal, imm.index, value.node); + BUILD(GlobalSet, imm.index, value.node); } void TableGet(FullDecoder* decoder, const Value& index, Value* result, @@ -310,8 +315,8 @@ class WasmGraphBuildingInterface { TFNode* controls[2]; BUILD(BranchNoHint, cond.node, &controls[0], &controls[1]); TFNode* merge = BUILD(Merge, 2, controls); - TFNode* vals[2] = {tval.node, fval.node}; - TFNode* phi = BUILD(Phi, tval.type, 2, vals, merge); + TFNode* inputs[] = {tval.node, fval.node, merge}; + TFNode* phi = BUILD(Phi, tval.type, 2, inputs); result->node = phi; ssa_env_->control = merge; } @@ -319,10 +324,11 @@ class WasmGraphBuildingInterface { void BrOrRet(FullDecoder* decoder, uint32_t depth) { if (depth == decoder->control_depth() - 1) { uint32_t ret_count = static_cast<uint32_t>(decoder->sig_->return_count()); - Vector<TFNode*> values = - ret_count == 0 ? Vector<TFNode*>{} - : GetNodes(decoder->stack_value(ret_count), ret_count); - BUILD(Return, values); + base::SmallVector<TFNode*, 8> values(ret_count); + if (ret_count > 0) { + GetNodes(values.begin(), decoder->stack_value(ret_count), ret_count); + } + BUILD(Return, VectorOf(values)); } else { Br(decoder, decoder->control_at(depth)); } @@ -431,7 +437,8 @@ class WasmGraphBuildingInterface { void SimdOp(FullDecoder* decoder, WasmOpcode opcode, Vector<Value> args, Value* result) { - Vector<TFNode*> inputs = GetNodes(args); + base::SmallVector<TFNode*, 8> inputs(args.size()); + GetNodes(inputs.begin(), args); TFNode* node = BUILD(SimdOp, opcode, inputs.begin()); if (result) result->node = node; } @@ -439,7 +446,8 @@ class WasmGraphBuildingInterface { void SimdLaneOp(FullDecoder* decoder, WasmOpcode opcode, const SimdLaneImmediate<validate> imm, Vector<Value> inputs, Value* result) { - Vector<TFNode*> nodes = GetNodes(inputs); + base::SmallVector<TFNode*, 8> nodes(inputs.size()); + GetNodes(nodes.begin(), inputs); result->node = BUILD(SimdLaneOp, opcode, imm.lane, nodes.begin()); } @@ -486,12 +494,11 @@ class WasmGraphBuildingInterface { // If the tags match we extract the values from the exception object and // push them onto the operand stack using the passed {values} vector. SetEnv(if_match_env); - // TODO(mstarzinger): Can't use BUILD() here, GetExceptionValues() returns - // TFNode** rather than TFNode*. Fix to add landing pads. - Vector<TFNode*> caught_values = - builder_->GetExceptionValues(exception.node, imm.exception); + base::SmallVector<TFNode*, 8> caught_values(values.size()); + Vector<TFNode*> caught_vector = VectorOf(caught_values); + BUILD(GetExceptionValues, exception.node, imm.exception, caught_vector); for (size_t i = 0, e = values.size(); i < e; ++i) { - values[i].node = caught_values[i]; + values[i].node = caught_vector[i]; } BrOrRet(decoder, depth); @@ -519,7 +526,8 @@ class WasmGraphBuildingInterface { void AtomicOp(FullDecoder* decoder, WasmOpcode opcode, Vector<Value> args, const MemoryAccessImmediate<validate>& imm, Value* result) { - Vector<TFNode*> inputs = GetNodes(args); + base::SmallVector<TFNode*, 8> inputs(args.size()); + GetNodes(inputs.begin(), args); TFNode* node = BUILD(AtomicOp, opcode, inputs.begin(), imm.alignment, imm.offset, decoder->position()); if (result) result->node = node; @@ -591,16 +599,14 @@ class WasmGraphBuildingInterface { ->try_info; } - Vector<TFNode*> GetNodes(Value* values, size_t count) { - Vector<TFNode*> nodes = builder_->Buffer(count); + void GetNodes(TFNode** nodes, Value* values, size_t count) { for (size_t i = 0; i < count; ++i) { nodes[i] = values[i].node; } - return nodes; } - Vector<TFNode*> GetNodes(Vector<Value> values) { - return GetNodes(values.begin(), values.size()); + void GetNodes(TFNode** nodes, Vector<Value> values) { + GetNodes(nodes, values.begin(), values.size()); } void SetEnv(SsaEnv* env) { @@ -656,10 +662,10 @@ class WasmGraphBuildingInterface { SsaEnv* exception_env = Split(decoder, success_env); exception_env->control = if_exception; + exception_env->effect = if_exception; TryInfo* try_info = current_try_info(decoder); Goto(decoder, exception_env, try_info->catch_env); - TFNode* exception = try_info->exception; - if (exception == nullptr) { + if (try_info->exception == nullptr) { DCHECK_EQ(SsaEnv::kReached, try_info->catch_env->state); try_info->exception = if_exception; } else { @@ -694,7 +700,8 @@ class WasmGraphBuildingInterface { } } - void MergeValuesInto(FullDecoder* decoder, Control* c, Merge<Value>* merge) { + void MergeValuesInto(FullDecoder* decoder, Control* c, Merge<Value>* merge, + Value* values) { DCHECK(merge == &c->start_merge || merge == &c->end_merge); SsaEnv* target = c->end_env; @@ -703,13 +710,8 @@ class WasmGraphBuildingInterface { if (merge->arity == 0) return; - uint32_t avail = - decoder->stack_size() - decoder->control_at(0)->stack_depth; - DCHECK_GE(avail, merge->arity); - uint32_t start = avail >= merge->arity ? 0 : merge->arity - avail; - Value* stack_values = decoder->stack_value(merge->arity); - for (uint32_t i = start; i < merge->arity; ++i) { - Value& val = stack_values[i]; + for (uint32_t i = 0; i < merge->arity; ++i) { + Value& val = values[i]; Value& old = (*merge)[i]; DCHECK_NOT_NULL(val.node); DCHECK(val.type == kWasmBottom || @@ -722,6 +724,17 @@ class WasmGraphBuildingInterface { } } + void MergeValuesInto(FullDecoder* decoder, Control* c, Merge<Value>* merge) { +#ifdef DEBUG + uint32_t avail = + decoder->stack_size() - decoder->control_at(0)->stack_depth; + DCHECK_GE(avail, merge->arity); +#endif + Value* stack_values = + merge->arity > 0 ? decoder->stack_value(merge->arity) : nullptr; + MergeValuesInto(decoder, c, merge, stack_values); + } + void Goto(FullDecoder* decoder, SsaEnv* from, SsaEnv* to) { DCHECK_NOT_NULL(to); switch (to->state) { @@ -741,17 +754,16 @@ class WasmGraphBuildingInterface { to->control = merge; // Merge effects. if (from->effect != to->effect) { - TFNode* effects[] = {to->effect, from->effect, merge}; - to->effect = builder_->EffectPhi(2, effects, merge); + TFNode* inputs[] = {to->effect, from->effect, merge}; + to->effect = builder_->EffectPhi(2, inputs); } // Merge SSA values. for (int i = decoder->num_locals() - 1; i >= 0; i--) { TFNode* a = to->locals[i]; TFNode* b = from->locals[i]; if (a != b) { - TFNode* vals[] = {a, b}; - to->locals[i] = - builder_->Phi(decoder->GetLocalType(i), 2, vals, merge); + TFNode* inputs[] = {a, b, merge}; + to->locals[i] = builder_->Phi(decoder->GetLocalType(i), 2, inputs); } } // Start a new merge from the instance cache. @@ -787,7 +799,8 @@ class WasmGraphBuildingInterface { env->state = SsaEnv::kMerged; env->control = builder_->Loop(env->control); - env->effect = builder_->EffectPhi(1, &env->effect, env->control); + TFNode* effect_inputs[] = {env->effect, env->control}; + env->effect = builder_->EffectPhi(1, effect_inputs); builder_->TerminateLoop(env->effect, env->control); // The '+ 1' here is to be able to set the instance cache as assigned. BitVector* assigned = WasmDecoder<validate>::AnalyzeLoopAssignment( @@ -798,8 +811,8 @@ class WasmGraphBuildingInterface { int instance_cache_index = decoder->total_locals(); for (int i = decoder->num_locals() - 1; i >= 0; i--) { if (!assigned->Contains(i)) continue; - env->locals[i] = builder_->Phi(decoder->GetLocalType(i), 1, - &env->locals[i], env->control); + TFNode* inputs[] = {env->locals[i], env->control}; + env->locals[i] = builder_->Phi(decoder->GetLocalType(i), 1, inputs); } // Introduce phis for instance cache pointers if necessary. if (assigned->Contains(instance_cache_index)) { @@ -815,8 +828,8 @@ class WasmGraphBuildingInterface { // Conservatively introduce phis for all local variables. for (int i = decoder->num_locals() - 1; i >= 0; i--) { - env->locals[i] = builder_->Phi(decoder->GetLocalType(i), 1, - &env->locals[i], env->control); + TFNode* inputs[] = {env->locals[i], env->control}; + env->locals[i] = builder_->Phi(decoder->GetLocalType(i), 1, inputs); } // Conservatively introduce phis for instance cache. @@ -877,22 +890,22 @@ class WasmGraphBuildingInterface { void DoCall(FullDecoder* decoder, uint32_t table_index, TFNode* index_node, FunctionSig* sig, uint32_t sig_index, const Value args[], Value returns[]) { - int param_count = static_cast<int>(sig->parameter_count()); - Vector<TFNode*> arg_nodes = builder_->Buffer(param_count + 1); - TFNode** return_nodes = nullptr; + size_t param_count = sig->parameter_count(); + size_t return_count = sig->return_count(); + base::SmallVector<TFNode*, 16> arg_nodes(param_count + 1); + base::SmallVector<TFNode*, 1> return_nodes(return_count); arg_nodes[0] = index_node; - for (int i = 0; i < param_count; ++i) { + for (size_t i = 0; i < param_count; ++i) { arg_nodes[i + 1] = args[i].node; } if (index_node) { - BUILD(CallIndirect, table_index, sig_index, arg_nodes.begin(), - &return_nodes, decoder->position()); + BUILD(CallIndirect, table_index, sig_index, VectorOf(arg_nodes), + VectorOf(return_nodes), decoder->position()); } else { - BUILD(CallDirect, sig_index, arg_nodes.begin(), &return_nodes, + BUILD(CallDirect, sig_index, VectorOf(arg_nodes), VectorOf(return_nodes), decoder->position()); } - int return_count = static_cast<int>(sig->return_count()); - for (int i = 0; i < return_count; ++i) { + for (size_t i = 0; i < return_count; ++i) { returns[i].node = return_nodes[i]; } // The invoked function could have used grow_memory, so we need to @@ -903,17 +916,17 @@ class WasmGraphBuildingInterface { void DoReturnCall(FullDecoder* decoder, uint32_t table_index, TFNode* index_node, FunctionSig* sig, uint32_t sig_index, const Value args[]) { - int arg_count = static_cast<int>(sig->parameter_count()); - Vector<TFNode*> arg_nodes = builder_->Buffer(arg_count + 1); + size_t arg_count = sig->parameter_count(); + base::SmallVector<TFNode*, 16> arg_nodes(arg_count + 1); arg_nodes[0] = index_node; - for (int i = 0; i < arg_count; ++i) { + for (size_t i = 0; i < arg_count; ++i) { arg_nodes[i + 1] = args[i].node; } if (index_node) { - BUILD(ReturnCallIndirect, table_index, sig_index, arg_nodes.begin(), + BUILD(ReturnCallIndirect, table_index, sig_index, VectorOf(arg_nodes), decoder->position()); } else { - BUILD(ReturnCall, sig_index, arg_nodes.begin(), decoder->position()); + BUILD(ReturnCall, sig_index, VectorOf(arg_nodes), decoder->position()); } } }; diff --git a/deps/v8/src/wasm/jump-table-assembler.cc b/deps/v8/src/wasm/jump-table-assembler.cc index 7c41c0a209cd75..adb7e19158a04e 100644 --- a/deps/v8/src/wasm/jump-table-assembler.cc +++ b/deps/v8/src/wasm/jump-table-assembler.cc @@ -21,17 +21,37 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, EmitJumpSlot(lazy_compile_target); // 5 bytes } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); -} - -void JumpTableAssembler::EmitJumpSlot(Address target) { - // On x64, all code is allocated within a single code section, so we can use - // relative jumps. - static_assert(kMaxWasmCodeMemory <= size_t{2} * GB, "can use relative jump"); +bool JumpTableAssembler::EmitJumpSlot(Address target) { intptr_t displacement = static_cast<intptr_t>( reinterpret_cast<byte*>(target) - pc_ - kNearJmpInstrSize); - near_jmp(displacement, RelocInfo::NONE); + if (!is_int32(displacement)) return false; + near_jmp(displacement, RelocInfo::NONE); // 5 bytes + return true; +} + +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + Label data; + int start_offset = pc_offset(); + jmp(Operand(&data)); // 6 bytes + Nop(2); // 2 bytes + // The data must be properly aligned, so it can be patched atomically (see + // {PatchFarJumpSlot}). + DCHECK_EQ(start_offset + kSystemPointerSize, pc_offset()); + USE(start_offset); + bind(&data); + dq(target); // 8 bytes +} + +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + // The slot needs to be pointer-size aligned so we can atomically update it. + DCHECK(IsAligned(slot, kSystemPointerSize)); + // Offset of the target is at 8 bytes, see {EmitFarJumpSlot}. + reinterpret_cast<std::atomic<Address>*>(slot + kSystemPointerSize) + ->store(target, std::memory_order_relaxed); + // The update is atomic because the address is properly aligned. + // Because of cache coherence, the data update will eventually be seen by all + // cores. It's ok if they temporarily jump to the old target. } void JumpTableAssembler::NopBytes(int bytes) { @@ -46,14 +66,20 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, jmp(lazy_compile_target, RelocInfo::NONE); // 5 bytes } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); +bool JumpTableAssembler::EmitJumpSlot(Address target) { + jmp(target, RelocInfo::NONE); + return true; } -void JumpTableAssembler::EmitJumpSlot(Address target) { +void JumpTableAssembler::EmitFarJumpSlot(Address target) { jmp(target, RelocInfo::NONE); } +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + UNREACHABLE(); +} + void JumpTableAssembler::NopBytes(int bytes) { DCHECK_LE(0, bytes); Nop(bytes); @@ -74,16 +100,26 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, EmitJumpSlot(lazy_compile_target); } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); - CheckConstPool(true, false); // force emit of const pool -} - -void JumpTableAssembler::EmitJumpSlot(Address target) { +bool JumpTableAssembler::EmitJumpSlot(Address target) { // Note that {Move32BitImmediate} emits [ldr, constant] for the relocation // mode used below, we need this to allow concurrent patching of this slot. Move32BitImmediate(pc, Operand(target, RelocInfo::WASM_CALL)); CheckConstPool(true, false); // force emit of const pool + return true; +} + +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + // Load from [pc + kInstrSize] to pc. Note that {pc} points two instructions + // after the currently executing one. + ldr_pcrel(pc, -kInstrSize); // 1 instruction + dd(target); // 4 bytes (== 1 instruction) + STATIC_ASSERT(kInstrSize == kInt32Size); + STATIC_ASSERT(kFarJumpTableSlotSize == 2 * kInstrSize); +} + +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + UNREACHABLE(); } void JumpTableAssembler::NopBytes(int bytes) { @@ -105,19 +141,43 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, if (nop_bytes) nop(); } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); - ForceConstantPoolEmissionWithoutJump(); +bool JumpTableAssembler::EmitJumpSlot(Address target) { + if (!TurboAssembler::IsNearCallOffset( + (reinterpret_cast<byte*>(target) - pc_) / kInstrSize)) { + return false; + } + + Jump(target, RelocInfo::NONE); + return true; } -void JumpTableAssembler::EmitJumpSlot(Address target) { - // TODO(wasm): Currently this is guaranteed to be a {near_call} and hence is - // patchable concurrently. Once {kMaxWasmCodeMemory} is raised on ARM64, make - // sure concurrent patching is still supported. - DCHECK(TurboAssembler::IsNearCallOffset( - (reinterpret_cast<byte*>(target) - pc_) / kInstrSize)); +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + // This code uses hard-coded registers and instructions (and avoids + // {UseScratchRegisterScope} or {InstructionAccurateScope}) because this code + // will only be called for the very specific runtime slot table, and we want + // to have maximum control over the generated code. + // Do not reuse this code without validating that the same assumptions hold. + constexpr Register kTmpReg = x16; + DCHECK(TmpList()->IncludesAliasOf(kTmpReg)); + // Load from [pc + 2 * kInstrSize] to {kTmpReg}, then branch there. + ldr_pcrel(kTmpReg, 2); // 1 instruction + br(kTmpReg); // 1 instruction + dq(target); // 8 bytes (== 2 instructions) + STATIC_ASSERT(2 * kInstrSize == kSystemPointerSize); + STATIC_ASSERT(kFarJumpTableSlotSize == 4 * kInstrSize); +} - Jump(target, RelocInfo::NONE); +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + // The slot needs to be pointer-size aligned so we can atomically update it. + DCHECK(IsAligned(slot, kSystemPointerSize)); + // Offset of the target is at 8 bytes, see {EmitFarJumpSlot}. + reinterpret_cast<std::atomic<Address>*>(slot + kSystemPointerSize) + ->store(target, std::memory_order_relaxed); + // The data update is guaranteed to be atomic since it's a properly aligned + // and stores a single machine word. This update will eventually be observed + // by any concurrent [ldr] on the same address because of the data cache + // coherence. It's ok if other cores temporarily jump to the old target. } void JumpTableAssembler::NopBytes(int bytes) { @@ -138,13 +198,19 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, b(r1); // 2 bytes } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); -} - -void JumpTableAssembler::EmitJumpSlot(Address target) { +bool JumpTableAssembler::EmitJumpSlot(Address target) { mov(r1, Operand(target)); b(r1); + return true; +} + +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + JumpToInstructionStream(target); +} + +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + UNREACHABLE(); } void JumpTableAssembler::NopBytes(int bytes) { @@ -168,12 +234,18 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, for (int i = 0; i < nop_bytes; i += kInstrSize) nop(); } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); +bool JumpTableAssembler::EmitJumpSlot(Address target) { + Jump(target, RelocInfo::NONE); + return true; } -void JumpTableAssembler::EmitJumpSlot(Address target) { - Jump(target, RelocInfo::NONE); +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + JumpToInstructionStream(target); +} + +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + UNREACHABLE(); } void JumpTableAssembler::NopBytes(int bytes) { @@ -199,14 +271,20 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, for (int i = 0; i < nop_bytes; i += kInstrSize) nop(); } -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - JumpToInstructionStream(builtin_target); -} - -void JumpTableAssembler::EmitJumpSlot(Address target) { +bool JumpTableAssembler::EmitJumpSlot(Address target) { mov(r0, Operand(target)); mtctr(r0); bctr(); + return true; +} + +void JumpTableAssembler::EmitFarJumpSlot(Address target) { + JumpToInstructionStream(target); +} + +// static +void JumpTableAssembler::PatchFarJumpSlot(Address slot, Address target) { + UNREACHABLE(); } void JumpTableAssembler::NopBytes(int bytes) { @@ -218,21 +296,7 @@ void JumpTableAssembler::NopBytes(int bytes) { } #else -void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index, - Address lazy_compile_target) { - UNIMPLEMENTED(); -} - -void JumpTableAssembler::EmitRuntimeStubSlot(Address builtin_target) { - UNIMPLEMENTED(); -} - -void JumpTableAssembler::EmitJumpSlot(Address target) { UNIMPLEMENTED(); } - -void JumpTableAssembler::NopBytes(int bytes) { - DCHECK_LE(0, bytes); - UNIMPLEMENTED(); -} +#error Unknown architecture. #endif } // namespace wasm diff --git a/deps/v8/src/wasm/jump-table-assembler.h b/deps/v8/src/wasm/jump-table-assembler.h index 8889c18e9c5192..2100e44199f39a 100644 --- a/deps/v8/src/wasm/jump-table-assembler.h +++ b/deps/v8/src/wasm/jump-table-assembler.h @@ -6,7 +6,6 @@ #define V8_WASM_JUMP_TABLE_ASSEMBLER_H_ #include "src/codegen/macro-assembler.h" -#include "src/wasm/wasm-code-manager.h" namespace v8 { namespace internal { @@ -19,9 +18,11 @@ namespace wasm { // // Additionally to this main jump table, there exist special jump tables for // other purposes: -// - the runtime stub table contains one entry per wasm runtime stub (see +// - the far stub table contains one entry per wasm runtime stub (see // {WasmCode::RuntimeStubId}, which jumps to the corresponding embedded -// builtin. +// builtin, plus (if {FLAG_wasm_far_jump_table} is enabled and not the full +// address space can be reached via the jump table) one entry per wasm +// function. // - the lazy compile table contains one entry per wasm function which jumps to // the common {WasmCompileLazy} builtin and passes the function index that was // invoked. @@ -73,16 +74,28 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { // Determine the size of a jump table containing the given number of slots. static constexpr uint32_t SizeForNumberOfSlots(uint32_t slot_count) { - // TODO(wasm): Once the {RoundUp} utility handles non-powers of two values, - // use: {RoundUp<kJumpTableSlotsPerLine>(slot_count) * kJumpTableLineSize} return ((slot_count + kJumpTableSlotsPerLine - 1) / kJumpTableSlotsPerLine) * kJumpTableLineSize; } - // Translate a stub slot index to an offset into the continuous jump table. - static uint32_t StubSlotIndexToOffset(uint32_t slot_index) { - return slot_index * kJumpTableStubSlotSize; + // Translate a far jump table index to an offset into the table. + static uint32_t FarJumpSlotIndexToOffset(uint32_t slot_index) { + return slot_index * kFarJumpTableSlotSize; + } + + // Translate a far jump table offset to the index into the table. + static uint32_t FarJumpSlotOffsetToIndex(uint32_t offset) { + DCHECK_EQ(0, offset % kFarJumpTableSlotSize); + return offset / kFarJumpTableSlotSize; + } + + // Determine the size of a far jump table containing the given number of + // slots. + static constexpr uint32_t SizeForNumberOfFarJumpSlots( + int num_runtime_slots, int num_function_slots) { + int num_entries = num_runtime_slots + num_function_slots; + return num_entries * kFarJumpTableSlotSize; } // Translate a slot index to an offset into the lazy compile table. @@ -90,11 +103,6 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { return slot_index * kLazyCompileTableSlotSize; } - // Determine the size of a jump table containing only runtime stub slots. - static constexpr uint32_t SizeForNumberOfStubSlots(uint32_t slot_count) { - return slot_count * kJumpTableStubSlotSize; - } - // Determine the size of a lazy compile table. static constexpr uint32_t SizeForNumberOfLazyFunctions(uint32_t slot_count) { return slot_count * kLazyCompileTableSlotSize; @@ -115,32 +123,41 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { FlushInstructionCache(base, lazy_compile_table_size); } - static void GenerateRuntimeStubTable(Address base, Address* targets, - int num_stubs) { - uint32_t table_size = num_stubs * kJumpTableStubSlotSize; + static void GenerateFarJumpTable(Address base, Address* stub_targets, + int num_runtime_slots, + int num_function_slots) { + uint32_t table_size = + SizeForNumberOfFarJumpSlots(num_runtime_slots, num_function_slots); // Assume enough space, so the Assembler does not try to grow the buffer. JumpTableAssembler jtasm(base, table_size + 256); int offset = 0; - for (int index = 0; index < num_stubs; ++index) { - DCHECK_EQ(offset, StubSlotIndexToOffset(index)); + for (int index = 0; index < num_runtime_slots + num_function_slots; + ++index) { + DCHECK_EQ(offset, FarJumpSlotIndexToOffset(index)); + // Functions slots initially jump to themselves. They are patched before + // being used. + Address target = + index < num_runtime_slots ? stub_targets[index] : base + offset; + jtasm.EmitFarJumpSlot(target); + offset += kFarJumpTableSlotSize; DCHECK_EQ(offset, jtasm.pc_offset()); - jtasm.EmitRuntimeStubSlot(targets[index]); - offset += kJumpTableStubSlotSize; - jtasm.NopBytes(offset - jtasm.pc_offset()); } FlushInstructionCache(base, table_size); } - static void PatchJumpTableSlot(Address base, uint32_t slot_index, - Address new_target, - WasmCode::FlushICache flush_i_cache) { - Address slot = base + JumpSlotIndexToOffset(slot_index); - JumpTableAssembler jtasm(slot); - jtasm.EmitJumpSlot(new_target); - jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset()); - if (flush_i_cache) { - FlushInstructionCache(slot, kJumpTableSlotSize); + static void PatchJumpTableSlot(Address jump_table_slot, + Address far_jump_table_slot, Address target) { + // First, try to patch the jump table slot. + JumpTableAssembler jtasm(jump_table_slot); + if (!jtasm.EmitJumpSlot(target)) { + // If that fails, we need to patch the far jump table slot, and then + // update the jump table slot to jump to this far jump table slot. + DCHECK_NE(kNullAddress, far_jump_table_slot); + JumpTableAssembler::PatchFarJumpSlot(far_jump_table_slot, target); + CHECK(jtasm.EmitJumpSlot(far_jump_table_slot)); } + jtasm.NopBytes(kJumpTableSlotSize - jtasm.pc_offset()); + FlushInstructionCache(jump_table_slot, kJumpTableSlotSize); } private: @@ -157,48 +174,45 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { #if V8_TARGET_ARCH_X64 static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableSlotSize = 5; + static constexpr int kFarJumpTableSlotSize = 16; static constexpr int kLazyCompileTableSlotSize = 10; - static constexpr int kJumpTableStubSlotSize = 18; #elif V8_TARGET_ARCH_IA32 static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableSlotSize = 5; + static constexpr int kFarJumpTableSlotSize = 5; static constexpr int kLazyCompileTableSlotSize = 10; - static constexpr int kJumpTableStubSlotSize = 10; #elif V8_TARGET_ARCH_ARM static constexpr int kJumpTableLineSize = 3 * kInstrSize; static constexpr int kJumpTableSlotSize = 3 * kInstrSize; + static constexpr int kFarJumpTableSlotSize = 2 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 5 * kInstrSize; - static constexpr int kJumpTableStubSlotSize = 5 * kInstrSize; #elif V8_TARGET_ARCH_ARM64 static constexpr int kJumpTableLineSize = 1 * kInstrSize; static constexpr int kJumpTableSlotSize = 1 * kInstrSize; + static constexpr int kFarJumpTableSlotSize = 4 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 3 * kInstrSize; - static constexpr int kJumpTableStubSlotSize = 6 * kInstrSize; #elif V8_TARGET_ARCH_S390X static constexpr int kJumpTableLineSize = 128; static constexpr int kJumpTableSlotSize = 14; + static constexpr int kFarJumpTableSlotSize = 14; static constexpr int kLazyCompileTableSlotSize = 20; - static constexpr int kJumpTableStubSlotSize = 14; #elif V8_TARGET_ARCH_PPC64 static constexpr int kJumpTableLineSize = 64; static constexpr int kJumpTableSlotSize = 7 * kInstrSize; + static constexpr int kFarJumpTableSlotSize = 7 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 12 * kInstrSize; - static constexpr int kJumpTableStubSlotSize = 7 * kInstrSize; #elif V8_TARGET_ARCH_MIPS static constexpr int kJumpTableLineSize = 6 * kInstrSize; static constexpr int kJumpTableSlotSize = 4 * kInstrSize; + static constexpr int kFarJumpTableSlotSize = 4 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 6 * kInstrSize; - static constexpr int kJumpTableStubSlotSize = 4 * kInstrSize; #elif V8_TARGET_ARCH_MIPS64 static constexpr int kJumpTableLineSize = 8 * kInstrSize; static constexpr int kJumpTableSlotSize = 6 * kInstrSize; + static constexpr int kFarJumpTableSlotSize = 6 * kInstrSize; static constexpr int kLazyCompileTableSlotSize = 8 * kInstrSize; - static constexpr int kJumpTableStubSlotSize = 6 * kInstrSize; #else - static constexpr int kJumpTableLineSize = 1; - static constexpr int kJumpTableSlotSize = 1; - static constexpr int kLazyCompileTableSlotSize = 1; - static constexpr int kJumpTableStubSlotSize = 1; +#error Unknown architecture. #endif static constexpr int kJumpTableSlotsPerLine = @@ -218,9 +232,15 @@ class V8_EXPORT_PRIVATE JumpTableAssembler : public MacroAssembler { void EmitLazyCompileJumpSlot(uint32_t func_index, Address lazy_compile_target); - void EmitRuntimeStubSlot(Address builtin_target); + // Returns {true} if the jump fits in the jump table slot, {false} otherwise. + bool EmitJumpSlot(Address target); + + // Initially emit a far jump slot. + void EmitFarJumpSlot(Address target); - void EmitJumpSlot(Address target); + // Patch an existing far jump slot, and make sure that this updated eventually + // becomes available to all execution units that might execute this code. + static void PatchFarJumpSlot(Address slot, Address target); void NopBytes(int bytes); }; diff --git a/deps/v8/src/wasm/memory-tracing.cc b/deps/v8/src/wasm/memory-tracing.cc index b11a557195d3d2..300c7afcf9e56c 100644 --- a/deps/v8/src/wasm/memory-tracing.cc +++ b/deps/v8/src/wasm/memory-tracing.cc @@ -16,7 +16,7 @@ namespace wasm { void TraceMemoryOperation(ExecutionTier tier, const MemoryTracingInfo* info, int func_index, int position, uint8_t* mem_start) { - EmbeddedVector<char, 64> value; + EmbeddedVector<char, 91> value; auto mem_rep = static_cast<MachineRepresentation>(info->mem_rep); switch (mem_rep) { #define TRACE_TYPE(rep, str, format, ctype1, ctype2) \ @@ -34,6 +34,25 @@ void TraceMemoryOperation(ExecutionTier tier, const MemoryTracingInfo* info, TRACE_TYPE(kFloat32, "f32", "%f / %08x", float, uint32_t) TRACE_TYPE(kFloat64, "f64", "%f / %016" PRIx64, double, uint64_t) #undef TRACE_TYPE + case MachineRepresentation::kSimd128: + SNPrintF(value, "s128:%d %d %d %d / %08x %08x %08x %08x", + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 4), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 8), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 12), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 4), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 8), + base::ReadLittleEndianValue<uint32_t>( + reinterpret_cast<Address>(mem_start) + info->address + 12)); + break; default: SNPrintF(value, "???"); } diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc index 2847b02c643d0b..9e08f8d1090e7a 100644 --- a/deps/v8/src/wasm/module-compiler.cc +++ b/deps/v8/src/wasm/module-compiler.cc @@ -14,7 +14,6 @@ #include "src/base/platform/mutex.h" #include "src/base/platform/semaphore.h" #include "src/base/platform/time.h" -#include "src/base/template-utils.h" #include "src/base/utils/random-number-generator.h" #include "src/compiler/wasm-compiler.h" #include "src/heap/heap-inl.h" // For CodeSpaceMemoryModificationScope. @@ -31,7 +30,6 @@ #include "src/wasm/wasm-import-wrapper-cache.h" #include "src/wasm/wasm-js.h" #include "src/wasm/wasm-limits.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-opcodes.h" #include "src/wasm/wasm-result.h" @@ -152,6 +150,9 @@ class CompilationUnitQueues { for (int task_id = 0; task_id < max_tasks; ++task_id) { queues_[task_id].next_steal_task_id = next_task_id(task_id); } + for (auto& atomic_counter : num_units_) { + std::atomic_init(&atomic_counter, size_t{0}); + } } base::Optional<WasmCompilationUnit> GetNextUnit( @@ -254,15 +255,14 @@ class CompilationUnitQueues { }; struct BigUnitsQueue { - BigUnitsQueue() = default; + BigUnitsQueue() { + for (auto& atomic : has_units) std::atomic_init(&atomic, false); + } base::Mutex mutex; // Can be read concurrently to check whether any elements are in the queue. - std::atomic_bool has_units[kNumTiers] = { - ATOMIC_VAR_INIT(false), - ATOMIC_VAR_INIT(false) - }; + std::atomic<bool> has_units[kNumTiers]; // Protected by {mutex}: std::priority_queue<BigUnit> units[kNumTiers]; @@ -271,11 +271,8 @@ class CompilationUnitQueues { std::vector<Queue> queues_; BigUnitsQueue big_units_queue_; - std::atomic_size_t num_units_[kNumTiers] = { - ATOMIC_VAR_INIT(0), - ATOMIC_VAR_INIT(0) - }; - std::atomic_int next_queue_to_add{0}; + std::atomic<size_t> num_units_[kNumTiers]; + std::atomic<int> next_queue_to_add{0}; int next_task_id(int task_id) const { int next = task_id + 1; @@ -482,7 +479,7 @@ class CompilationStateImpl { // Compilation error, atomically updated. This flag can be updated and read // using relaxed semantics. - std::atomic_bool compile_failed_{false}; + std::atomic<bool> compile_failed_{false}; const int max_background_tasks_ = 0; @@ -967,6 +964,10 @@ bool ExecuteJSToWasmWrapperCompilationUnits( return true; } +bool NeedsDeterministicCompile() { + return FLAG_trace_wasm_decoder || FLAG_wasm_num_compilation_tasks <= 1; +} + // Run by the main thread and background tasks to take part in compilation. // Returns whether any units were executed. bool ExecuteCompilationUnits( @@ -994,6 +995,7 @@ bool ExecuteCompilationUnits( // These fields are initialized in a {BackgroundCompileScope} before // starting compilation. double deadline = 0; + const bool deterministic = NeedsDeterministicCompile(); base::Optional<CompilationEnv> env; std::shared_ptr<WireBytesStorage> wire_bytes; std::shared_ptr<const WasmModule> module; @@ -1087,7 +1089,7 @@ bool ExecuteCompilationUnits( } // Get next unit. - if (deadline < platform->MonotonicallyIncreasingTime()) { + if (deterministic || deadline < platform->MonotonicallyIncreasingTime()) { unit = {}; } else { unit = compile_scope.compilation_state()->GetNextCompilationUnit( @@ -1199,10 +1201,6 @@ void InitializeCompilationUnits(Isolate* isolate, NativeModule* native_module) { builder.Commit(); } -bool NeedsDeterministicCompile() { - return FLAG_trace_wasm_decoder || FLAG_wasm_num_compilation_tasks <= 1; -} - bool MayCompriseLazyFunctions(const WasmModule* module, const WasmFeatures& enabled_features, bool lazy_module) { @@ -1373,7 +1371,6 @@ std::shared_ptr<NativeModule> CompileToNativeModule( auto native_module = isolate->wasm_engine()->NewNativeModule( isolate, enabled, std::move(module)); native_module->SetWireBytes(std::move(wire_bytes_copy)); - native_module->SetRuntimeStubs(isolate); CompileNativeModule(isolate, thrower, wasm_module, native_module.get()); if (thrower->error()) return {}; @@ -1468,7 +1465,7 @@ class AsyncStreamingProcessor final : public StreamingProcessor { std::shared_ptr<StreamingDecoder> AsyncCompileJob::CreateStreamingDecoder() { DCHECK_NULL(stream_); stream_.reset( - new StreamingDecoder(base::make_unique<AsyncStreamingProcessor>(this))); + new StreamingDecoder(std::make_unique<AsyncStreamingProcessor>(this))); return stream_; } @@ -1504,7 +1501,7 @@ void AsyncCompileJob::CreateNativeModule( // Create the module object and populate with compiled functions and // information needed at instantiation time. - // TODO(clemensh): For the same module (same bytes / same hash), we should + // TODO(clemensb): For the same module (same bytes / same hash), we should // only have one {WasmModuleObject}. Otherwise, we might only set // breakpoints on a (potentially empty) subset of the instances. // Create the module object. @@ -1512,7 +1509,6 @@ void AsyncCompileJob::CreateNativeModule( native_module_ = isolate_->wasm_engine()->NewNativeModule( isolate_, enabled_features_, std::move(module)); native_module_->SetWireBytes({std::move(bytes_copy_), wire_bytes_.length()}); - native_module_->SetRuntimeStubs(isolate_); if (stream_) stream_->NotifyNativeModuleCreated(native_module_); } @@ -1707,7 +1703,7 @@ class AsyncCompileJob::CompileTask : public CancelableTask { void AsyncCompileJob::StartForegroundTask() { DCHECK_NULL(pending_foreground_task_); - auto new_task = base::make_unique<CompileTask>(this, true); + auto new_task = std::make_unique<CompileTask>(this, true); pending_foreground_task_ = new_task.get(); foreground_task_runner_->PostTask(std::move(new_task)); } @@ -1715,7 +1711,7 @@ void AsyncCompileJob::StartForegroundTask() { void AsyncCompileJob::ExecuteForegroundTaskImmediately() { DCHECK_NULL(pending_foreground_task_); - auto new_task = base::make_unique<CompileTask>(this, true); + auto new_task = std::make_unique<CompileTask>(this, true); pending_foreground_task_ = new_task.get(); new_task->Run(); } @@ -1727,7 +1723,7 @@ void AsyncCompileJob::CancelPendingForegroundTask() { } void AsyncCompileJob::StartBackgroundTask() { - auto task = base::make_unique<CompileTask>(this, false); + auto task = std::make_unique<CompileTask>(this, false); // If --wasm-num-compilation-tasks=0 is passed, do only spawn foreground // tasks. This is used to make timing deterministic. @@ -2210,11 +2206,9 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes, } int GetMaxBackgroundTasks() { - if (NeedsDeterministicCompile()) return 1; + if (NeedsDeterministicCompile()) return 0; int num_worker_threads = V8::GetCurrentPlatform()->NumberOfWorkerThreads(); - int num_compile_tasks = - std::min(FLAG_wasm_num_compilation_tasks, num_worker_threads); - return std::max(1, num_compile_tasks); + return std::min(FLAG_wasm_num_compilation_tasks, num_worker_threads); } CompilationStateImpl::CompilationStateImpl( @@ -2228,7 +2222,7 @@ CompilationStateImpl::CompilationStateImpl( ? CompileMode::kTiering : CompileMode::kRegular), async_counters_(std::move(async_counters)), - max_background_tasks_(GetMaxBackgroundTasks()), + max_background_tasks_(std::max(GetMaxBackgroundTasks(), 1)), compilation_unit_queues_(max_background_tasks_), available_task_ids_(max_background_tasks_) { for (int i = 0; i < max_background_tasks_; ++i) { @@ -2617,7 +2611,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module, auto& function = module->functions[exp.index]; JSToWasmWrapperKey key(function.imported, *function.sig); if (queue.insert(key)) { - auto unit = base::make_unique<JSToWasmWrapperCompilationUnit>( + auto unit = std::make_unique<JSToWasmWrapperCompilationUnit>( isolate, isolate->wasm_engine(), function.sig, function.imported, enabled_features); compilation_units.emplace(key, std::move(unit)); @@ -2628,7 +2622,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module, CancelableTaskManager task_manager; const int max_background_tasks = GetMaxBackgroundTasks(); for (int i = 0; i < max_background_tasks; ++i) { - auto task = base::make_unique<CompileJSToWasmWrapperTask>( + auto task = std::make_unique<CompileJSToWasmWrapperTask>( &task_manager, &queue, &compilation_units); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task)); } @@ -2699,12 +2693,21 @@ Handle<Script> CreateWasmScript(Isolate* isolate, const int kBufferSize = 32; char buffer[kBufferSize]; + Handle<String> url_prefix = + isolate->factory()->InternalizeString(StaticCharVector("wasm://wasm/")); + int name_chars = SNPrintF(ArrayVector(buffer), "wasm-%08x", hash); DCHECK(name_chars >= 0 && name_chars < kBufferSize); - MaybeHandle<String> name_str = isolate->factory()->NewStringFromOneByte( - VectorOf(reinterpret_cast<uint8_t*>(buffer), name_chars), - AllocationType::kOld); - script->set_name(*name_str.ToHandleChecked()); + Handle<String> name_str = + isolate->factory() + ->NewStringFromOneByte( + VectorOf(reinterpret_cast<uint8_t*>(buffer), name_chars), + AllocationType::kOld) + .ToHandleChecked(); + script->set_name(*name_str); + MaybeHandle<String> url_str = + isolate->factory()->NewConsString(url_prefix, name_str); + script->set_source_url(*url_str.ToHandleChecked()); if (source_map_url.size() != 0) { MaybeHandle<String> src_map_str = isolate->factory()->NewStringFromUtf8( diff --git a/deps/v8/src/wasm/module-decoder.cc b/deps/v8/src/wasm/module-decoder.cc index 56712977b18095..b89d06b881cde0 100644 --- a/deps/v8/src/wasm/module-decoder.cc +++ b/deps/v8/src/wasm/module-decoder.cc @@ -6,7 +6,6 @@ #include "src/base/functional.h" #include "src/base/platform/platform.h" -#include "src/base/template-utils.h" #include "src/flags/flags.h" #include "src/init/v8.h" #include "src/logging/counters.h" @@ -31,6 +30,7 @@ namespace { constexpr char kNameString[] = "name"; constexpr char kSourceMappingURLString[] = "sourceMappingURL"; constexpr char kCompilationHintsString[] = "compilationHints"; +constexpr char kDebugInfoString[] = ".debug_info"; template <size_t N> constexpr size_t num_chars(const char (&)[N]) { @@ -89,6 +89,8 @@ const char* SectionName(SectionCode code) { return kNameString; case kSourceMappingURLSectionCode: return kSourceMappingURLString; + case kDebugInfoSectionCode: + return kDebugInfoString; case kCompilationHintsSectionCode: return kCompilationHintsString; default: @@ -304,7 +306,7 @@ class ModuleDecoderImpl : public Decoder { CHECK_NULL(module_); SetCounters(counters); module_.reset( - new WasmModule(base::make_unique<Zone>(allocator, "signatures"))); + new WasmModule(std::make_unique<Zone>(allocator, "signatures"))); module_->initial_pages = 0; module_->maximum_pages = 0; module_->mem_export = false; @@ -399,6 +401,10 @@ class ModuleDecoderImpl : public Decoder { // sourceMappingURL is a custom section and currently can occur anywhere // in the module. In case of multiple sourceMappingURL sections, all // except the first occurrence are ignored. + case kDebugInfoSectionCode: + // .debug_info is a custom section containing core DWARF information + // if produced by compiler. Its presence likely means that Wasm was + // built in a debug mode. case kCompilationHintsSectionCode: // TODO(frgossen): report out of place compilation hints section as a // warning. @@ -453,6 +459,13 @@ class ModuleDecoderImpl : public Decoder { case kSourceMappingURLSectionCode: DecodeSourceMappingURLSection(); break; + case kDebugInfoSectionCode: + // If there is an explicit source map, prefer it over DWARF info. + if (!has_seen_unordered_section(kSourceMappingURLSectionCode)) { + module_->source_map_url.assign("wasm://dwarf"); + } + consume_bytes(static_cast<uint32_t>(end_ - start_), ".debug_info"); + break; case kCompilationHintsSectionCode: if (enabled_features_.compilation_hints) { DecodeCompilationHintsSection(); @@ -798,9 +811,11 @@ class ModuleDecoderImpl : public Decoder { const byte* pos = pc(); bool is_active; + bool functions_as_elements; uint32_t table_index; WasmInitExpr offset; - consume_segment_header("table index", &is_active, &table_index, &offset); + consume_element_segment_header(&is_active, &functions_as_elements, + &table_index, &offset); if (failed()) return; if (is_active) { @@ -815,12 +830,6 @@ class ModuleDecoderImpl : public Decoder { table_index); break; } - } else { - ValueType type = consume_reference_type(); - if (!ValueTypes::IsSubType(kWasmFuncRef, type)) { - error(pc_ - 1, "invalid element segment type"); - break; - } } uint32_t num_elem = @@ -833,8 +842,8 @@ class ModuleDecoderImpl : public Decoder { WasmElemSegment* init = &module_->elem_segments.back(); for (uint32_t j = 0; j < num_elem; j++) { - uint32_t index = is_active ? consume_element_func_index() - : consume_passive_element(); + uint32_t index = functions_as_elements ? consume_element_expr() + : consume_element_func_index(); if (failed()) break; init->entries.push_back(index); } @@ -911,8 +920,7 @@ class ModuleDecoderImpl : public Decoder { bool is_active; uint32_t memory_index; WasmInitExpr dest_addr; - consume_segment_header("memory index", &is_active, &memory_index, - &dest_addr); + consume_data_segment_header(&is_active, &memory_index, &dest_addr); if (failed()) break; if (is_active && memory_index != 0) { @@ -1483,7 +1491,7 @@ class ModuleDecoderImpl : public Decoder { WasmInitExpr expr; uint32_t len = 0; switch (opcode) { - case kExprGetGlobal: { + case kExprGlobalGet: { GlobalIndexImmediate<Decoder::kValidate> imm(this, pc() - 1); if (module->globals.size() <= imm.index) { error("global index is out of bounds"); @@ -1544,6 +1552,10 @@ class ModuleDecoderImpl : public Decoder { case kExprRefFunc: { if (enabled_features_.anyref) { FunctionIndexImmediate<Decoder::kValidate> imm(this, pc() - 1); + if (module->functions.size() <= imm.index) { + errorf(pc() - 1, "invalid function index: %u", imm.index); + break; + } expr.kind = WasmInitExpr::kRefFuncConst; expr.val.function_index = imm.index; len = imm.length; @@ -1678,8 +1690,103 @@ class ModuleDecoderImpl : public Decoder { return attribute; } - void consume_segment_header(const char* name, bool* is_active, - uint32_t* index, WasmInitExpr* offset) { + void consume_element_segment_header(bool* is_active, + bool* functions_as_elements, + uint32_t* table_index, + WasmInitExpr* offset) { + const byte* pos = pc(); + uint8_t flag; + if (enabled_features_.bulk_memory || enabled_features_.anyref) { + flag = consume_u8("flag"); + } else { + uint32_t table_index = consume_u32v("table index"); + // The only valid flag value without bulk_memory or anyref is '0'. + if (table_index != 0) { + error( + "Element segments with table indices require " + "--experimental-wasm-bulk-memory or --experimental-wasm-anyref"); + return; + } + flag = 0; + } + + // The mask for the bit in the flag which indicates if the segment is + // active or not. + constexpr uint8_t kIsPassiveMask = 0x01; + // The mask for the bit in the flag which indicates if the segment has an + // explicit table index field. + constexpr uint8_t kHasTableIndexMask = 0x02; + // The mask for the bit in the flag which indicates if the functions of this + // segment are defined as function indices (=0) or elements(=1). + constexpr uint8_t kFunctionsAsElementsMask = 0x04; + constexpr uint8_t kFullMask = + kIsPassiveMask | kHasTableIndexMask | kFunctionsAsElementsMask; + + bool is_passive = flag & kIsPassiveMask; + *is_active = !is_passive; + *functions_as_elements = flag & kFunctionsAsElementsMask; + bool has_table_index = flag & kHasTableIndexMask; + + if (is_passive && !enabled_features_.bulk_memory) { + error("Passive element segments require --experimental-wasm-bulk-memory"); + return; + } + if (*functions_as_elements && !enabled_features_.bulk_memory) { + error( + "Illegal segment flag. Did you forget " + "--experimental-wasm-bulk-memory?"); + return; + } + if (flag != 0 && !enabled_features_.bulk_memory && + !enabled_features_.anyref) { + error( + "Invalid segment flag. Did you forget " + "--experimental-wasm-bulk-memory or --experimental-wasm-anyref?"); + return; + } + if ((flag & kFullMask) != flag || (!(*is_active) && has_table_index)) { + errorf(pos, "illegal flag value %u. Must be 0, 1, 2, 4, 5 or 6", flag); + } + + if (has_table_index) { + *table_index = consume_u32v("table index"); + } else { + *table_index = 0; + } + + if (*is_active) { + *offset = consume_init_expr(module_.get(), kWasmI32); + } + + if (*is_active && !has_table_index) { + // Active segments without table indices are a special case for backwards + // compatibility. These cases have an implicit element kind or element + // type, so we are done already with the segment header. + return; + } + + if (*functions_as_elements) { + // We have to check that there is an element type of type FuncRef. All + // other element types are not valid yet. + ValueType type = consume_reference_type(); + if (!ValueTypes::IsSubType(kWasmFuncRef, type)) { + error(pc_ - 1, "invalid element segment type"); + return; + } + } else { + // We have to check that there is an element kind of type Function. All + // other element kinds are not valid yet. + uint8_t val = consume_u8("element kind"); + ImportExportKindCode kind = static_cast<ImportExportKindCode>(val); + if (kind != kExternalFunction) { + errorf(pos, "illegal element kind %x. Must be 0x00", val); + return; + } + } + } + + void consume_data_segment_header(bool* is_active, uint32_t* index, + WasmInitExpr* offset) { const byte* pos = pc(); uint32_t flag = consume_u32v("flag"); @@ -1715,7 +1822,7 @@ class ModuleDecoderImpl : public Decoder { } if (flag == SegmentFlags::kActiveWithIndex) { *is_active = true; - *index = consume_u32v(name); + *index = consume_u32v("memory index"); *offset = consume_init_expr(module_.get(), kWasmI32); } } @@ -1731,7 +1838,7 @@ class ModuleDecoderImpl : public Decoder { return index; } - uint32_t consume_passive_element() { + uint32_t consume_element_expr() { uint32_t index = WasmElemSegment::kNullIndex; uint8_t opcode = consume_u8("element opcode"); if (failed()) return index; @@ -1857,6 +1964,10 @@ SectionCode ModuleDecoder::IdentifyUnknownSection(Decoder* decoder, kCompilationHintsString, num_chars(kCompilationHintsString)) == 0) { return kCompilationHintsSectionCode; + } else if (string.length() == num_chars(kDebugInfoString) && + strncmp(reinterpret_cast<const char*>(section_name_start), + kDebugInfoString, num_chars(kDebugInfoString)) == 0) { + return kDebugInfoSectionCode; } return kUnknownSectionCode; } @@ -1895,7 +2006,7 @@ FunctionResult DecodeWasmFunctionForTesting( ModuleDecoderImpl decoder(enabled, function_start, function_end, kWasmOrigin); decoder.SetCounters(counters); return decoder.DecodeSingleFunction(zone, wire_bytes, module, - base::make_unique<WasmFunction>()); + std::make_unique<WasmFunction>()); } AsmJsOffsetsResult DecodeAsmJsOffsets(const byte* tables_start, diff --git a/deps/v8/src/wasm/module-decoder.h b/deps/v8/src/wasm/module-decoder.h index 8e121c9d3063f2..5ee324b109e690 100644 --- a/deps/v8/src/wasm/module-decoder.h +++ b/deps/v8/src/wasm/module-decoder.h @@ -5,6 +5,8 @@ #ifndef V8_WASM_MODULE_DECODER_H_ #define V8_WASM_MODULE_DECODER_H_ +#include <memory> + #include "src/common/globals.h" #include "src/wasm/function-body-decoder.h" #include "src/wasm/wasm-constants.h" diff --git a/deps/v8/src/wasm/module-instantiate.cc b/deps/v8/src/wasm/module-instantiate.cc index 976c3cde00154e..95d892ab505961 100644 --- a/deps/v8/src/wasm/module-instantiate.cc +++ b/deps/v8/src/wasm/module-instantiate.cc @@ -93,7 +93,7 @@ class InstanceBuilder { InstanceBuilder(Isolate* isolate, ErrorThrower* thrower, Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> ffi, - MaybeHandle<JSArrayBuffer> memory); + MaybeHandle<JSArrayBuffer> memory_buffer); // Build an instance, in all of its glory. MaybeHandle<WasmInstanceObject> Build(); @@ -114,7 +114,8 @@ class InstanceBuilder { ErrorThrower* thrower_; Handle<WasmModuleObject> module_object_; MaybeHandle<JSReceiver> ffi_; - MaybeHandle<JSArrayBuffer> memory_; + MaybeHandle<JSArrayBuffer> memory_buffer_; + Handle<WasmMemoryObject> memory_object_; Handle<JSArrayBuffer> untagged_globals_; Handle<FixedArray> tagged_globals_; std::vector<Handle<WasmExceptionObject>> exception_wrappers_; @@ -165,9 +166,11 @@ class InstanceBuilder { void SanitizeImports(); - // Find the imported memory buffer if there is one. This is used to see if we - // need to recompile with bounds checks before creating the instance. - MaybeHandle<JSArrayBuffer> FindImportedMemoryBuffer() const; + // Find the imported memory if there is one. + bool FindImportedMemory(); + + // Allocate the memory. + bool AllocateMemory(); // Processes a single imported function. bool ProcessImportedFunction(Handle<WasmInstanceObject> instance, @@ -221,9 +224,6 @@ class InstanceBuilder { // Process initialization of globals. void InitGlobals(Handle<WasmInstanceObject> instance); - // Allocate memory for a module instance as a new JSArrayBuffer. - Handle<JSArrayBuffer> AllocateMemory(uint32_t initial_pages, - uint32_t maximum_pages); bool NeedsWrappers() const; @@ -243,8 +243,9 @@ class InstanceBuilder { MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject( Isolate* isolate, ErrorThrower* thrower, Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> imports, - MaybeHandle<JSArrayBuffer> memory) { - InstanceBuilder builder(isolate, thrower, module_object, imports, memory); + MaybeHandle<JSArrayBuffer> memory_buffer) { + InstanceBuilder builder(isolate, thrower, module_object, imports, + memory_buffer); auto instance = builder.Build(); if (!instance.is_null() && builder.ExecuteStartFunction()) { return instance; @@ -256,14 +257,14 @@ MaybeHandle<WasmInstanceObject> InstantiateToInstanceObject( InstanceBuilder::InstanceBuilder(Isolate* isolate, ErrorThrower* thrower, Handle<WasmModuleObject> module_object, MaybeHandle<JSReceiver> ffi, - MaybeHandle<JSArrayBuffer> memory) + MaybeHandle<JSArrayBuffer> memory_buffer) : isolate_(isolate), enabled_(module_object->native_module()->enabled_features()), module_(module_object->module()), thrower_(thrower), module_object_(module_object), ffi_(ffi), - memory_(memory) { + memory_buffer_(memory_buffer) { sanitized_imports_.reserve(module_->import_table.size()); } @@ -289,7 +290,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { NativeModule* native_module = module_object_->native_module(); //-------------------------------------------------------------------------- - // Allocate the memory array buffer. + // Set up the memory buffer and memory objects. //-------------------------------------------------------------------------- uint32_t initial_pages = module_->initial_pages; auto initial_pages_counter = SELECT_WASM_COUNTER( @@ -301,29 +302,41 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { isolate_->counters()->wasm_wasm_max_mem_pages_count(); max_pages_counter->AddSample(module_->maximum_pages); } - // Asm.js has memory_ already set at this point, so we don't want to - // overwrite it. - if (memory_.is_null()) { - memory_ = FindImportedMemoryBuffer(); - } - if (!memory_.is_null()) { - // Set externally passed ArrayBuffer non detachable. - Handle<JSArrayBuffer> memory = memory_.ToHandleChecked(); - memory->set_is_detachable(false); - - DCHECK_IMPLIES(native_module->use_trap_handler(), - is_asmjs_module(module_) || memory->is_wasm_memory() || - memory->backing_store() == nullptr); - } else if (initial_pages > 0 || native_module->use_trap_handler()) { - // We need to unconditionally create a guard region if using trap handlers, - // even when the size is zero to prevent null-dereference issues - // (e.g. https://crbug.com/769637). - // Allocate memory if the initial size is more than 0 pages. - memory_ = AllocateMemory(initial_pages, module_->maximum_pages); - if (memory_.is_null()) { - // failed to allocate memory - DCHECK(isolate_->has_pending_exception() || thrower_->error()); - return {}; + + if (is_asmjs_module(module_)) { + Handle<JSArrayBuffer> buffer; + if (memory_buffer_.ToHandle(&buffer)) { + // asm.js instantiation should have changed the state of the buffer. + CHECK(!buffer->is_detachable()); + CHECK(buffer->is_asmjs_memory()); + } else { + // Use an empty JSArrayBuffer for degenerate asm.js modules. + memory_buffer_ = isolate_->factory()->NewJSArrayBufferAndBackingStore( + 0, InitializedFlag::kUninitialized); + if (!memory_buffer_.ToHandle(&buffer)) { + thrower_->RangeError("Out of memory: asm.js memory"); + return {}; + } + buffer->set_is_asmjs_memory(true); + buffer->set_is_detachable(false); + } + + // The maximum number of pages isn't strictly necessary for memory + // objects used for asm.js, as they are never visible, but we might + // as well make it accurate. + auto maximum_pages = static_cast<uint32_t>( + RoundUp(buffer->byte_length(), wasm::kWasmPageSize) / + wasm::kWasmPageSize); + memory_object_ = + WasmMemoryObject::New(isolate_, memory_buffer_, maximum_pages); + } else { + // Actual wasm module must have either imported or created memory. + CHECK(memory_buffer_.is_null()); + if (!FindImportedMemory()) { + if (module_->has_memory && !AllocateMemory()) { + DCHECK(isolate_->has_pending_exception() || thrower_->error()); + return {}; + } } } @@ -333,33 +346,42 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { TRACE("New module instantiation for %p\n", native_module); Handle<WasmInstanceObject> instance = WasmInstanceObject::New(isolate_, module_object_); - NativeModuleModificationScope native_modification_scope(native_module); + + //-------------------------------------------------------------------------- + // Attach the memory to the instance. + //-------------------------------------------------------------------------- + if (module_->has_memory) { + DCHECK(!memory_object_.is_null()); + if (!instance->has_memory_object()) { + instance->set_memory_object(*memory_object_); + } + // Add the instance object to the list of instances for this memory. + WasmMemoryObject::AddInstance(isolate_, memory_object_, instance); + + // Double-check the {memory} array buffer matches the instance. + Handle<JSArrayBuffer> memory = memory_buffer_.ToHandleChecked(); + CHECK_EQ(instance->memory_size(), memory->byte_length()); + CHECK_EQ(instance->memory_start(), memory->backing_store()); + } //-------------------------------------------------------------------------- // Set up the globals for the new instance. //-------------------------------------------------------------------------- uint32_t untagged_globals_buffer_size = module_->untagged_globals_buffer_size; if (untagged_globals_buffer_size > 0) { - void* backing_store = isolate_->array_buffer_allocator()->Allocate( - untagged_globals_buffer_size); - if (backing_store == nullptr) { - thrower_->RangeError("Out of memory: wasm globals"); - return {}; - } - untagged_globals_ = isolate_->factory()->NewJSArrayBuffer( - SharedFlag::kNotShared, AllocationType::kOld); - constexpr bool is_external = false; - constexpr bool is_wasm_memory = false; - JSArrayBuffer::Setup(untagged_globals_, isolate_, is_external, - backing_store, untagged_globals_buffer_size, - SharedFlag::kNotShared, is_wasm_memory); - if (untagged_globals_.is_null()) { + MaybeHandle<JSArrayBuffer> result = + isolate_->factory()->NewJSArrayBufferAndBackingStore( + untagged_globals_buffer_size, InitializedFlag::kZeroInitialized, + AllocationType::kOld); + + if (!result.ToHandle(&untagged_globals_)) { thrower_->RangeError("Out of memory: wasm globals"); return {}; } + + instance->set_untagged_globals_buffer(*untagged_globals_); instance->set_globals_start( reinterpret_cast<byte*>(untagged_globals_->backing_store())); - instance->set_untagged_globals_buffer(*untagged_globals_); } uint32_t tagged_globals_buffer_size = module_->tagged_globals_buffer_size; @@ -425,6 +447,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { instance->set_indirect_function_tables(*tables); } + NativeModuleModificationScope native_modification_scope(native_module); + //-------------------------------------------------------------------------- // Process the imports for the module. //-------------------------------------------------------------------------- @@ -450,30 +474,6 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { InitializeExceptions(instance); } - //-------------------------------------------------------------------------- - // Create the WebAssembly.Memory object. - //-------------------------------------------------------------------------- - if (module_->has_memory) { - if (!instance->has_memory_object()) { - // No memory object exists. Create one. - Handle<WasmMemoryObject> memory_object = WasmMemoryObject::New( - isolate_, memory_, - module_->maximum_pages != 0 ? module_->maximum_pages : -1); - instance->set_memory_object(*memory_object); - } - - // Add the instance object to the list of instances for this memory. - Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate_); - WasmMemoryObject::AddInstance(isolate_, memory_object, instance); - - if (!memory_.is_null()) { - // Double-check the {memory} array buffer matches the instance. - Handle<JSArrayBuffer> memory = memory_.ToHandleChecked(); - CHECK_EQ(instance->memory_size(), memory->byte_length()); - CHECK_EQ(instance->memory_start(), memory->backing_store()); - } - } - // The bulk memory proposal changes the MVP behavior here; the segments are // written as if `memory.init` and `table.init` are executed directly, and // not bounds checked ahead of time. @@ -536,7 +536,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { // Debugging support. //-------------------------------------------------------------------------- // Set all breakpoints that were set on the shared module. - WasmModuleObject::SetBreakpointsOnNewInstance(module_object_, instance); + WasmModuleObject::SetBreakpointsOnNewInstance( + handle(module_object_->script(), isolate_), instance); //-------------------------------------------------------------------------- // Create a wrapper for the start function. @@ -547,7 +548,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { Handle<Code> wrapper_code = JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper( isolate_, function.sig, function.imported); - // TODO(clemensh): Don't generate an exported function for the start + // TODO(clemensb): Don't generate an exported function for the start // function. Use CWasmEntry instead. start_function_ = WasmExportedFunction::New( isolate_, instance, start_index, @@ -807,22 +808,21 @@ void InstanceBuilder::SanitizeImports() { } } -MaybeHandle<JSArrayBuffer> InstanceBuilder::FindImportedMemoryBuffer() const { +bool InstanceBuilder::FindImportedMemory() { DCHECK_EQ(module_->import_table.size(), sanitized_imports_.size()); for (size_t index = 0; index < module_->import_table.size(); index++) { - const WasmImport& import = module_->import_table[index]; + WasmImport import = module_->import_table[index]; if (import.kind == kExternalMemory) { - const auto& value = sanitized_imports_[index].value; - if (!value->IsWasmMemoryObject()) { - return {}; - } - auto memory = Handle<WasmMemoryObject>::cast(value); - Handle<JSArrayBuffer> buffer(memory->array_buffer(), isolate_); - return buffer; + auto& value = sanitized_imports_[index].value; + if (!value->IsWasmMemoryObject()) return false; + memory_object_ = Handle<WasmMemoryObject>::cast(value); + memory_buffer_ = + Handle<JSArrayBuffer>(memory_object_->array_buffer(), isolate_); + return true; } } - return {}; + return false; } bool InstanceBuilder::ProcessImportedFunction( @@ -1016,19 +1016,19 @@ bool InstanceBuilder::ProcessImportedMemory(Handle<WasmInstanceObject> instance, Handle<String> module_name, Handle<String> import_name, Handle<Object> value) { - // Validation should have failed if more than one memory object was - // provided. - DCHECK(!instance->has_memory_object()); if (!value->IsWasmMemoryObject()) { ReportLinkError("memory import must be a WebAssembly.Memory object", import_index, module_name, import_name); return false; } - auto memory = Handle<WasmMemoryObject>::cast(value); - instance->set_memory_object(*memory); - Handle<JSArrayBuffer> buffer(memory->array_buffer(), isolate_); + auto memory_object = Handle<WasmMemoryObject>::cast(value); + + // The imported memory should have been already set up early. + CHECK_EQ(instance->memory_object(), *memory_object); + + Handle<JSArrayBuffer> buffer(memory_object_->array_buffer(), isolate_); // memory_ should have already been assigned in Build(). - DCHECK_EQ(*memory_.ToHandleChecked(), *buffer); + DCHECK_EQ(*memory_buffer_.ToHandleChecked(), *buffer); uint32_t imported_cur_pages = static_cast<uint32_t>(buffer->byte_length() / kWasmPageSize); if (imported_cur_pages < module_->initial_pages) { @@ -1037,7 +1037,7 @@ bool InstanceBuilder::ProcessImportedMemory(Handle<WasmInstanceObject> instance, imported_cur_pages); return false; } - int32_t imported_maximum_pages = memory->maximum_pages(); + int32_t imported_maximum_pages = memory_object_->maximum_pages(); if (module_->has_maximum_pages) { if (imported_maximum_pages < 0) { thrower_->LinkError( @@ -1186,13 +1186,8 @@ bool InstanceBuilder::ProcessImportedGlobal(Handle<WasmInstanceObject> instance, return true; } - if (enabled_.bigint && global.type == kWasmI64) { - Handle<BigInt> bigint; - - if (!BigInt::FromObject(isolate_, value).ToHandle(&bigint)) { - return false; - } - WriteGlobalValue(global, bigint->AsInt64()); + if (enabled_.bigint && global.type == kWasmI64 && value->IsBigInt()) { + WriteGlobalValue(global, BigInt::cast(*value).AsInt64()); return true; } @@ -1241,7 +1236,7 @@ void InstanceBuilder::CompileImportWrappers( CancelableTaskManager task_manager; const int max_background_tasks = GetMaxBackgroundTasks(); for (int i = 0; i < max_background_tasks; ++i) { - auto task = base::make_unique<CompileImportWrapperTask>( + auto task = std::make_unique<CompileImportWrapperTask>( &task_manager, isolate_->wasm_engine(), isolate_->counters(), native_module, &import_wrapper_queue, &cache_scope); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task)); @@ -1411,27 +1406,28 @@ void InstanceBuilder::InitGlobals(Handle<WasmInstanceObject> instance) { } // Allocate memory for a module instance as a new JSArrayBuffer. -Handle<JSArrayBuffer> InstanceBuilder::AllocateMemory(uint32_t initial_pages, - uint32_t maximum_pages) { +bool InstanceBuilder::AllocateMemory() { + auto initial_pages = module_->initial_pages; + auto maximum_pages = module_->has_maximum_pages ? module_->maximum_pages + : wasm::max_mem_pages(); if (initial_pages > max_mem_pages()) { thrower_->RangeError("Out of memory: wasm memory too large"); - return Handle<JSArrayBuffer>::null(); - } - const bool is_shared_memory = module_->has_shared_memory && enabled_.threads; - Handle<JSArrayBuffer> mem_buffer; - if (is_shared_memory) { - if (!NewSharedArrayBuffer(isolate_, initial_pages * kWasmPageSize, - maximum_pages * kWasmPageSize) - .ToHandle(&mem_buffer)) { - thrower_->RangeError("Out of memory: wasm shared memory"); - } - } else { - if (!NewArrayBuffer(isolate_, initial_pages * kWasmPageSize) - .ToHandle(&mem_buffer)) { - thrower_->RangeError("Out of memory: wasm memory"); - } + return false; } - return mem_buffer; + auto shared = (module_->has_shared_memory && enabled_.threads) + ? SharedFlag::kShared + : SharedFlag::kNotShared; + + MaybeHandle<WasmMemoryObject> result = + WasmMemoryObject::New(isolate_, initial_pages, maximum_pages, shared); + + if (!result.ToHandle(&memory_object_)) { + thrower_->RangeError("Out of memory: wasm memory"); + return false; + } + memory_buffer_ = + Handle<JSArrayBuffer>(memory_object_->array_buffer(), isolate_); + return true; } bool InstanceBuilder::NeedsWrappers() const { diff --git a/deps/v8/src/wasm/streaming-decoder.cc b/deps/v8/src/wasm/streaming-decoder.cc index 94945ea58a88e9..37aaf056056d25 100644 --- a/deps/v8/src/wasm/streaming-decoder.cc +++ b/deps/v8/src/wasm/streaming-decoder.cc @@ -4,7 +4,6 @@ #include "src/wasm/streaming-decoder.h" -#include "src/base/template-utils.h" #include "src/handles/handles.h" #include "src/objects/descriptor-array.h" #include "src/objects/dictionary.h" @@ -364,14 +363,14 @@ StreamingDecoder::DecodeModuleHeader::Next(StreamingDecoder* streaming) { TRACE_STREAMING("DecodeModuleHeader\n"); streaming->ProcessModuleHeader(); if (!streaming->ok()) return nullptr; - return base::make_unique<DecodeSectionID>(streaming->module_offset()); + return std::make_unique<DecodeSectionID>(streaming->module_offset()); } std::unique_ptr<StreamingDecoder::DecodingState> StreamingDecoder::DecodeSectionID::Next(StreamingDecoder* streaming) { TRACE_STREAMING("DecodeSectionID: %s section\n", SectionName(static_cast<SectionCode>(id_))); - return base::make_unique<DecodeSectionLength>(id_, module_offset_); + return std::make_unique<DecodeSectionLength>(id_, module_offset_); } std::unique_ptr<StreamingDecoder::DecodingState> @@ -391,7 +390,7 @@ StreamingDecoder::DecodeSectionLength::NextWithValue( streaming->ProcessSection(buf); if (!streaming->ok()) return nullptr; // There is no payload, we go to the next section immediately. - return base::make_unique<DecodeSectionID>(streaming->module_offset_); + return std::make_unique<DecodeSectionID>(streaming->module_offset_); } else { if (section_id_ == SectionCode::kCodeSectionCode) { // Explicitly check for multiple code sections as module decoder never @@ -404,9 +403,9 @@ StreamingDecoder::DecodeSectionLength::NextWithValue( streaming->code_section_processed_ = true; // We reached the code section. All functions of the code section are put // into the same SectionBuffer. - return base::make_unique<DecodeNumberOfFunctions>(buf); + return std::make_unique<DecodeNumberOfFunctions>(buf); } - return base::make_unique<DecodeSectionPayload>(buf); + return std::make_unique<DecodeSectionPayload>(buf); } } @@ -415,7 +414,7 @@ StreamingDecoder::DecodeSectionPayload::Next(StreamingDecoder* streaming) { TRACE_STREAMING("DecodeSectionPayload\n"); streaming->ProcessSection(section_buffer_); if (!streaming->ok()) return nullptr; - return base::make_unique<DecodeSectionID>(streaming->module_offset()); + return std::make_unique<DecodeSectionID>(streaming->module_offset()); } std::unique_ptr<StreamingDecoder::DecodingState> @@ -434,14 +433,14 @@ StreamingDecoder::DecodeNumberOfFunctions::NextWithValue( if (payload_buf.size() != bytes_consumed_) { return streaming->Error("not all code section bytes were used"); } - return base::make_unique<DecodeSectionID>(streaming->module_offset()); + return std::make_unique<DecodeSectionID>(streaming->module_offset()); } DCHECK_GE(kMaxInt, value_); streaming->StartCodeSection(static_cast<int>(value_), streaming->section_buffers_.back()); if (!streaming->ok()) return nullptr; - return base::make_unique<DecodeFunctionLength>( + return std::make_unique<DecodeFunctionLength>( section_buffer_, section_buffer_->payload_offset() + bytes_consumed_, value_); } @@ -464,7 +463,7 @@ StreamingDecoder::DecodeFunctionLength::NextWithValue( return streaming->Error("not enough code section bytes"); } - return base::make_unique<DecodeFunctionBody>( + return std::make_unique<DecodeFunctionBody>( section_buffer_, buffer_offset_ + bytes_consumed_, value_, num_remaining_functions_, streaming->module_offset()); } @@ -477,14 +476,14 @@ StreamingDecoder::DecodeFunctionBody::Next(StreamingDecoder* streaming) { size_t end_offset = buffer_offset_ + function_body_length_; if (num_remaining_functions_ > 0) { - return base::make_unique<DecodeFunctionLength>(section_buffer_, end_offset, - num_remaining_functions_); + return std::make_unique<DecodeFunctionLength>(section_buffer_, end_offset, + num_remaining_functions_); } // We just read the last function body. Continue with the next section. if (end_offset != section_buffer_->length()) { return streaming->Error("not all code section bytes were used"); } - return base::make_unique<DecodeSectionID>(streaming->module_offset()); + return std::make_unique<DecodeSectionID>(streaming->module_offset()); } StreamingDecoder::StreamingDecoder( diff --git a/deps/v8/src/wasm/value-type.h b/deps/v8/src/wasm/value-type.h index bca5c2b941cd01..49f348b714a361 100644 --- a/deps/v8/src/wasm/value-type.h +++ b/deps/v8/src/wasm/value-type.h @@ -44,7 +44,7 @@ using FunctionSig = Signature<ValueType>; inline size_t hash_value(ValueType type) { return static_cast<size_t>(type); } -// TODO(clemensh): Compute memtype and size from ValueType once we have c++14 +// TODO(clemensb): Compute memtype and size from ValueType once we have c++14 // constexpr support. #define FOREACH_LOAD_TYPE(V) \ V(I32, , Int32, 2) \ diff --git a/deps/v8/src/wasm/wasm-code-manager.cc b/deps/v8/src/wasm/wasm-code-manager.cc index 91cfc01ceae649..df70b1ac06902b 100644 --- a/deps/v8/src/wasm/wasm-code-manager.cc +++ b/deps/v8/src/wasm/wasm-code-manager.cc @@ -6,7 +6,7 @@ #include <iomanip> -#include "src/base/adapters.h" +#include "src/base/iterator.h" #include "src/base/macros.h" #include "src/base/platform/platform.h" #include "src/base/small-vector.h" @@ -192,7 +192,7 @@ void WasmCode::LogCode(Isolate* isolate) const { Local<v8::String> source_map_str = load_wasm_source_map(v8_isolate, source_map_url.c_str()); native_module()->SetWasmSourceMap( - base::make_unique<WasmModuleSourceMap>(v8_isolate, source_map_str)); + std::make_unique<WasmModuleSourceMap>(v8_isolate, source_map_str)); } if (!name_vec.empty()) { @@ -235,7 +235,10 @@ void WasmCode::Validate() const { switch (mode) { case RelocInfo::WASM_CALL: { Address target = it.rinfo()->wasm_call_address(); - DCHECK(native_module_->is_jump_table_slot(target)); + WasmCode* code = native_module_->Lookup(target); + CHECK_NOT_NULL(code); + CHECK_EQ(WasmCode::kJumpTable, code->kind()); + CHECK(code->contains(target)); break; } case RelocInfo::WASM_STUB_CALL: { @@ -244,7 +247,6 @@ void WasmCode::Validate() const { CHECK_NOT_NULL(code); #ifdef V8_EMBEDDED_BUILTINS CHECK_EQ(WasmCode::kJumpTable, code->kind()); - CHECK_EQ(native_module()->runtime_stub_table_, code); CHECK(code->contains(target)); #else CHECK_EQ(WasmCode::kRuntimeStub, code->kind()); @@ -385,8 +387,6 @@ const char* GetWasmCodeKindAsString(WasmCode::Kind kind) { return "wasm-to-capi"; case WasmCode::kWasmToJsWrapper: return "wasm-to-js"; - case WasmCode::kRuntimeStub: - return "runtime-stub"; case WasmCode::kInterpreterEntry: return "interpreter entry"; case WasmCode::kJumpTable: @@ -430,6 +430,16 @@ void WasmCode::DecrementRefCount(Vector<WasmCode* const> code_vec) { if (engine) engine->FreeDeadCode(dead_code); } +WasmCodeAllocator::OptionalLock::~OptionalLock() { + if (allocator_) allocator_->mutex_.Unlock(); +} + +void WasmCodeAllocator::OptionalLock::Lock(WasmCodeAllocator* allocator) { + DCHECK(!is_locked()); + allocator_ = allocator; + allocator->mutex_.Lock(); +} + WasmCodeAllocator::WasmCodeAllocator(WasmCodeManager* code_manager, VirtualMemory code_space, bool can_request_more, @@ -448,6 +458,11 @@ WasmCodeAllocator::~WasmCodeAllocator() { committed_code_space()); } +void WasmCodeAllocator::Init(NativeModule* native_module) { + DCHECK_EQ(1, owned_code_space_.size()); + native_module->AddCodeSpace(owned_code_space_[0].region(), {}); +} + namespace { // On Windows, we cannot commit a region that straddles different reservations // of virtual memory. Because we bump-allocate, and because, if we need more @@ -487,17 +502,70 @@ base::SmallVector<base::AddressRegion, 1> SplitRangeByReservationsIfNeeded( #endif return split_ranges; } + +int NumWasmFunctionsInFarJumpTable(uint32_t num_declared_functions) { + return NativeModule::kNeedsFarJumpsBetweenCodeSpaces && + FLAG_wasm_far_jump_table + ? static_cast<int>(num_declared_functions) + : 0; +} + +// Returns an overapproximation of the code size overhead per new code space +// created by the jump tables. +size_t OverheadPerCodeSpace(uint32_t num_declared_functions) { + // Overhead for the jump table. + size_t overhead = RoundUp<kCodeAlignment>( + JumpTableAssembler::SizeForNumberOfSlots(num_declared_functions)); + +#if defined(V8_OS_WIN64) + // On Win64, we need to reserve some pages at the beginning of an executable + // space. See {AddCodeSpace}. + overhead += Heap::GetCodeRangeReservedAreaSize(); +#endif // V8_OS_WIN64 + + // Overhead for the far jump table. + overhead += + RoundUp<kCodeAlignment>(JumpTableAssembler::SizeForNumberOfFarJumpSlots( + WasmCode::kRuntimeStubCount, + NumWasmFunctionsInFarJumpTable(num_declared_functions))); + + return overhead; +} + +size_t ReservationSize(size_t code_size_estimate, int num_declared_functions, + size_t total_reserved) { + size_t overhead = OverheadPerCodeSpace(num_declared_functions); + + // Reserve a power of two at least as big as any of + // a) needed size + overhead (this is the minimum needed) + // b) 2 * overhead (to not waste too much space by overhead) + // c) 1/4 of current total reservation size (to grow exponentially) + size_t reserve_size = base::bits::RoundUpToPowerOfTwo( + std::max(std::max(RoundUp<kCodeAlignment>(code_size_estimate) + overhead, + 2 * overhead), + total_reserved / 4)); + + // Limit by the maximum supported code space size. + return std::min(kMaxWasmCodeSpaceSize, reserve_size); +} + } // namespace Vector<byte> WasmCodeAllocator::AllocateForCode(NativeModule* native_module, size_t size) { return AllocateForCodeInRegion( - native_module, size, {kNullAddress, std::numeric_limits<size_t>::max()}); + native_module, size, {kNullAddress, std::numeric_limits<size_t>::max()}, + WasmCodeAllocator::OptionalLock{}); } Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion( - NativeModule* native_module, size_t size, base::AddressRegion region) { - base::MutexGuard lock(&mutex_); + NativeModule* native_module, size_t size, base::AddressRegion region, + const WasmCodeAllocator::OptionalLock& optional_lock) { + OptionalLock new_lock; + if (!optional_lock.is_locked()) new_lock.Lock(this); + const auto& locked_lock = + optional_lock.is_locked() ? optional_lock : new_lock; + DCHECK(locked_lock.is_locked()); DCHECK_EQ(code_manager_, native_module->engine()->code_manager()); DCHECK_LT(0, size); v8::PageAllocator* page_allocator = GetPlatformPageAllocator(); @@ -517,12 +585,10 @@ Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion( Address hint = owned_code_space_.empty() ? kNullAddress : owned_code_space_.back().end(); - // Reserve at least 20% of the total generated code size so far, and of - // course at least {size}. Round up to the next power of two. size_t total_reserved = 0; for (auto& vmem : owned_code_space_) total_reserved += vmem.size(); - size_t reserve_size = - base::bits::RoundUpToPowerOfTwo(std::max(size, total_reserved / 5)); + size_t reserve_size = ReservationSize( + size, native_module->module()->num_declared_functions, total_reserved); VirtualMemory new_mem = code_manager_->TryAllocate(reserve_size, reinterpret_cast<void*>(hint)); if (!new_mem.IsReserved()) { @@ -534,7 +600,7 @@ Vector<byte> WasmCodeAllocator::AllocateForCodeInRegion( code_manager_->AssignRange(new_region, native_module); free_code_space_.Merge(new_region); owned_code_space_.emplace_back(std::move(new_mem)); - native_module->AddCodeSpace(new_region); + native_module->AddCodeSpace(new_region, locked_lock); code_space = free_code_space_.Allocate(size); DCHECK(!code_space.is_empty()); @@ -660,10 +726,9 @@ void WasmCodeAllocator::FreeCode(Vector<WasmCode* const> codes) { } } -base::AddressRegion WasmCodeAllocator::GetSingleCodeRegion() const { +size_t WasmCodeAllocator::GetNumCodeSpaces() const { base::MutexGuard lock(&mutex_); - DCHECK_EQ(1, owned_code_space_.size()); - return owned_code_space_[0].region(); + return owned_code_space_.size(); } NativeModule::NativeModule(WasmEngine* engine, const WasmFeatures& enabled, @@ -689,27 +754,34 @@ NativeModule::NativeModule(WasmEngine* engine, const WasmFeatures& enabled, CompilationState::New(*shared_this, std::move(async_counters)); DCHECK_NOT_NULL(module_); if (module_->num_declared_functions > 0) { - code_table_.reset(new WasmCode* [module_->num_declared_functions] {}); + code_table_ = + std::make_unique<WasmCode*[]>(module_->num_declared_functions); } - AddCodeSpace(code_allocator_.GetSingleCodeRegion()); + code_allocator_.Init(this); } void NativeModule::ReserveCodeTableForTesting(uint32_t max_functions) { WasmCodeRefScope code_ref_scope; - DCHECK_LE(num_functions(), max_functions); - WasmCode** new_table = new WasmCode* [max_functions] {}; + DCHECK_LE(module_->num_declared_functions, max_functions); + auto new_table = std::make_unique<WasmCode*[]>(max_functions); if (module_->num_declared_functions > 0) { - memcpy(new_table, code_table_.get(), - module_->num_declared_functions * sizeof(*new_table)); + memcpy(new_table.get(), code_table_.get(), + module_->num_declared_functions * sizeof(WasmCode*)); } - code_table_.reset(new_table); + code_table_ = std::move(new_table); - CHECK_EQ(1, code_space_data_.size()); + base::AddressRegion single_code_space_region; + { + base::MutexGuard guard(&allocation_mutex_); + CHECK_EQ(1, code_space_data_.size()); + single_code_space_region = code_space_data_[0].region; + } // Re-allocate jump table. - code_space_data_[0].jump_table = CreateEmptyJumpTableInRegion( + main_jump_table_ = CreateEmptyJumpTableInRegion( JumpTableAssembler::SizeForNumberOfSlots(max_functions), - code_space_data_[0].region); - main_jump_table_ = code_space_data_[0].jump_table; + single_code_space_region, WasmCodeAllocator::OptionalLock{}); + base::MutexGuard guard(&allocation_mutex_); + code_space_data_[0].jump_table = main_jump_table_; } void NativeModule::LogWasmCodes(Isolate* isolate) { @@ -731,89 +803,6 @@ CompilationEnv NativeModule::CreateCompilationEnv() const { } WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) { - return AddAndPublishAnonymousCode(code, WasmCode::kFunction); -} - -void NativeModule::UseLazyStub(uint32_t func_index) { - DCHECK_LE(module_->num_imported_functions, func_index); - DCHECK_LT(func_index, - module_->num_imported_functions + module_->num_declared_functions); - - if (!lazy_compile_table_) { - uint32_t num_slots = module_->num_declared_functions; - WasmCodeRefScope code_ref_scope; - DCHECK_EQ(1, code_space_data_.size()); - lazy_compile_table_ = CreateEmptyJumpTableInRegion( - JumpTableAssembler::SizeForNumberOfLazyFunctions(num_slots), - code_space_data_[0].region); - JumpTableAssembler::GenerateLazyCompileTable( - lazy_compile_table_->instruction_start(), num_slots, - module_->num_imported_functions, - runtime_stub_entry(WasmCode::kWasmCompileLazy)); - } - - // Add jump table entry for jump to the lazy compile stub. - uint32_t slot_index = func_index - module_->num_imported_functions; - DCHECK_NE(runtime_stub_entry(WasmCode::kWasmCompileLazy), kNullAddress); - Address lazy_compile_target = - lazy_compile_table_->instruction_start() + - JumpTableAssembler::LazyCompileSlotIndexToOffset(slot_index); - JumpTableAssembler::PatchJumpTableSlot(main_jump_table_->instruction_start(), - slot_index, lazy_compile_target, - WasmCode::kFlushICache); -} - -// TODO(mstarzinger): Remove {Isolate} parameter once {V8_EMBEDDED_BUILTINS} -// was removed and embedded builtins are no longer optional. -void NativeModule::SetRuntimeStubs(Isolate* isolate) { - DCHECK_EQ(kNullAddress, runtime_stub_entries_[0]); // Only called once. -#ifdef V8_EMBEDDED_BUILTINS - WasmCodeRefScope code_ref_scope; - DCHECK_EQ(1, code_space_data_.size()); - WasmCode* jump_table = CreateEmptyJumpTableInRegion( - JumpTableAssembler::SizeForNumberOfStubSlots(WasmCode::kRuntimeStubCount), - code_space_data_[0].region); - Address base = jump_table->instruction_start(); - EmbeddedData embedded_data = EmbeddedData::FromBlob(); -#define RUNTIME_STUB(Name) Builtins::k##Name, -#define RUNTIME_STUB_TRAP(Name) RUNTIME_STUB(ThrowWasm##Name) - Builtins::Name wasm_runtime_stubs[WasmCode::kRuntimeStubCount] = { - WASM_RUNTIME_STUB_LIST(RUNTIME_STUB, RUNTIME_STUB_TRAP)}; -#undef RUNTIME_STUB -#undef RUNTIME_STUB_TRAP - Address builtin_address[WasmCode::kRuntimeStubCount]; - for (int i = 0; i < WasmCode::kRuntimeStubCount; ++i) { - Builtins::Name builtin = wasm_runtime_stubs[i]; - CHECK(embedded_data.ContainsBuiltin(builtin)); - builtin_address[i] = embedded_data.InstructionStartOfBuiltin(builtin); - runtime_stub_entries_[i] = - base + JumpTableAssembler::StubSlotIndexToOffset(i); - } - JumpTableAssembler::GenerateRuntimeStubTable(base, builtin_address, - WasmCode::kRuntimeStubCount); - DCHECK_NULL(runtime_stub_table_); - runtime_stub_table_ = jump_table; -#else // V8_EMBEDDED_BUILTINS - HandleScope scope(isolate); - WasmCodeRefScope code_ref_scope; - USE(runtime_stub_table_); // Actually unused, but avoids ifdef's in header. -#define COPY_BUILTIN(Name) \ - runtime_stub_entries_[WasmCode::k##Name] = \ - AddAndPublishAnonymousCode( \ - isolate->builtins()->builtin_handle(Builtins::k##Name), \ - WasmCode::kRuntimeStub, #Name) \ - ->instruction_start(); -#define COPY_BUILTIN_TRAP(Name) COPY_BUILTIN(ThrowWasm##Name) - WASM_RUNTIME_STUB_LIST(COPY_BUILTIN, COPY_BUILTIN_TRAP) -#undef COPY_BUILTIN_TRAP -#undef COPY_BUILTIN -#endif // V8_EMBEDDED_BUILTINS - DCHECK_NE(kNullAddress, runtime_stub_entries_[0]); -} - -WasmCode* NativeModule::AddAndPublishAnonymousCode(Handle<Code> code, - WasmCode::Kind kind, - const char* name) { // For off-heap builtins, we create a copy of the off-heap instruction stream // instead of the on-heap code object containing the trampoline. Ensure that // we do not apply the on-heap reloc info to the off-heap instructions. @@ -859,8 +848,10 @@ WasmCode* NativeModule::AddAndPublishAnonymousCode(Handle<Code> code, code->InstructionStart(); int mode_mask = RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL); - Address constant_pool_start = - reinterpret_cast<Address>(dst_code_bytes.begin()) + constant_pool_offset; + auto jump_tables_ref = + FindJumpTablesForCode(reinterpret_cast<Address>(dst_code_bytes.begin())); + Address dst_code_addr = reinterpret_cast<Address>(dst_code_bytes.begin()); + Address constant_pool_start = dst_code_addr + constant_pool_offset; RelocIterator orig_it(*code, mode_mask); for (RelocIterator it(dst_code_bytes, reloc_info.as_vector(), constant_pool_start, mode_mask); @@ -869,8 +860,8 @@ WasmCode* NativeModule::AddAndPublishAnonymousCode(Handle<Code> code, if (RelocInfo::IsWasmStubCall(mode)) { uint32_t stub_call_tag = orig_it.rinfo()->wasm_call_tag(); DCHECK_LT(stub_call_tag, WasmCode::kRuntimeStubCount); - Address entry = runtime_stub_entry( - static_cast<WasmCode::RuntimeStubId>(stub_call_tag)); + Address entry = GetNearRuntimeStubEntry( + static_cast<WasmCode::RuntimeStubId>(stub_call_tag), jump_tables_ref); it.rinfo()->set_wasm_stub_call_address(entry, SKIP_ICACHE_FLUSH); } else { it.rinfo()->apply(delta); @@ -880,7 +871,6 @@ WasmCode* NativeModule::AddAndPublishAnonymousCode(Handle<Code> code, // Flush the i-cache after relocation. FlushInstructionCache(dst_code_bytes.begin(), dst_code_bytes.size()); - DCHECK_NE(kind, WasmCode::Kind::kInterpreterEntry); std::unique_ptr<WasmCode> new_code{new WasmCode{ this, // native_module kAnonymousFuncIndex, // index @@ -895,24 +885,63 @@ WasmCode* NativeModule::AddAndPublishAnonymousCode(Handle<Code> code, OwnedVector<ProtectedInstructionData>{}, // protected_instructions std::move(reloc_info), // reloc_info std::move(source_pos), // source positions - kind, // kind + WasmCode::kFunction, // kind ExecutionTier::kNone}}; // tier - new_code->MaybePrint(name); + new_code->MaybePrint(nullptr); new_code->Validate(); return PublishCode(std::move(new_code)); } +void NativeModule::UseLazyStub(uint32_t func_index) { + DCHECK_LE(module_->num_imported_functions, func_index); + DCHECK_LT(func_index, + module_->num_imported_functions + module_->num_declared_functions); + + if (!lazy_compile_table_) { + uint32_t num_slots = module_->num_declared_functions; + WasmCodeRefScope code_ref_scope; + base::AddressRegion single_code_space_region; + { + base::MutexGuard guard(&allocation_mutex_); + DCHECK_EQ(1, code_space_data_.size()); + single_code_space_region = code_space_data_[0].region; + } + lazy_compile_table_ = CreateEmptyJumpTableInRegion( + JumpTableAssembler::SizeForNumberOfLazyFunctions(num_slots), + single_code_space_region, WasmCodeAllocator::OptionalLock{}); + JumpTableAssembler::GenerateLazyCompileTable( + lazy_compile_table_->instruction_start(), num_slots, + module_->num_imported_functions, + GetNearRuntimeStubEntry( + WasmCode::kWasmCompileLazy, + FindJumpTablesForCode(lazy_compile_table_->instruction_start()))); + } + + // Add jump table entry for jump to the lazy compile stub. + uint32_t slot_index = func_index - module_->num_imported_functions; + DCHECK_NULL(code_table_[slot_index]); + Address lazy_compile_target = + lazy_compile_table_->instruction_start() + + JumpTableAssembler::LazyCompileSlotIndexToOffset(slot_index); + base::MutexGuard guard(&allocation_mutex_); + PatchJumpTablesLocked(slot_index, lazy_compile_target); +} + std::unique_ptr<WasmCode> NativeModule::AddCode( uint32_t index, const CodeDesc& desc, uint32_t stack_slots, uint32_t tagged_parameter_slots, OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions, OwnedVector<const byte> source_position_table, WasmCode::Kind kind, ExecutionTier tier) { - return AddCodeWithCodeSpace( - index, desc, stack_slots, tagged_parameter_slots, - std::move(protected_instructions), std::move(source_position_table), kind, - tier, code_allocator_.AllocateForCode(this, desc.instr_size)); + Vector<byte> code_space = + code_allocator_.AllocateForCode(this, desc.instr_size); + auto jump_table_ref = + FindJumpTablesForCode(reinterpret_cast<Address>(code_space.begin())); + return AddCodeWithCodeSpace(index, desc, stack_slots, tagged_parameter_slots, + std::move(protected_instructions), + std::move(source_position_table), kind, tier, + code_space, jump_table_ref); } std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( @@ -920,7 +949,8 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( uint32_t tagged_parameter_slots, OwnedVector<ProtectedInstructionData> protected_instructions, OwnedVector<const byte> source_position_table, WasmCode::Kind kind, - ExecutionTier tier, Vector<uint8_t> dst_code_bytes) { + ExecutionTier tier, Vector<uint8_t> dst_code_bytes, + const JumpTablesRef& jump_tables_ref) { OwnedVector<byte> reloc_info; if (desc.reloc_size > 0) { reloc_info = OwnedVector<byte>::New(desc.reloc_size); @@ -949,21 +979,21 @@ std::unique_ptr<WasmCode> NativeModule::AddCodeWithCodeSpace( int mode_mask = RelocInfo::kApplyMask | RelocInfo::ModeMask(RelocInfo::WASM_CALL) | RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL); - Address constant_pool_start = - reinterpret_cast<Address>(dst_code_bytes.begin()) + constant_pool_offset; + Address code_start = reinterpret_cast<Address>(dst_code_bytes.begin()); + Address constant_pool_start = code_start + constant_pool_offset; for (RelocIterator it(dst_code_bytes, reloc_info.as_vector(), constant_pool_start, mode_mask); !it.done(); it.next()) { RelocInfo::Mode mode = it.rinfo()->rmode(); if (RelocInfo::IsWasmCall(mode)) { uint32_t call_tag = it.rinfo()->wasm_call_tag(); - Address target = GetCallTargetForFunction(call_tag); + Address target = GetNearCallTargetForFunction(call_tag, jump_tables_ref); it.rinfo()->set_wasm_call_address(target, SKIP_ICACHE_FLUSH); } else if (RelocInfo::IsWasmStubCall(mode)) { uint32_t stub_call_tag = it.rinfo()->wasm_call_tag(); DCHECK_LT(stub_call_tag, WasmCode::kRuntimeStubCount); - Address entry = runtime_stub_entry( - static_cast<WasmCode::RuntimeStubId>(stub_call_tag)); + Address entry = GetNearRuntimeStubEntry( + static_cast<WasmCode::RuntimeStubId>(stub_call_tag), jump_tables_ref); it.rinfo()->set_wasm_stub_call_address(entry, SKIP_ICACHE_FLUSH); } else { it.rinfo()->apply(delta); @@ -1036,12 +1066,9 @@ WasmCode* NativeModule::PublishCodeLocked(std::unique_ptr<WasmCode> code) { // Populate optimized code to the jump table unless there is an active // redirection to the interpreter that should be preserved. - DCHECK_IMPLIES( - main_jump_table_ == nullptr, - engine_->code_manager()->IsImplicitAllocationsDisabledForTesting()); - bool update_jump_table = update_code_table && - !has_interpreter_redirection(code->index()) && - main_jump_table_; + DCHECK_NOT_NULL(main_jump_table_); + bool update_jump_table = + update_code_table && !has_interpreter_redirection(code->index()); // Ensure that interpreter entries always populate to the jump table. if (code->kind_ == WasmCode::Kind::kInterpreterEntry) { @@ -1050,9 +1077,7 @@ WasmCode* NativeModule::PublishCodeLocked(std::unique_ptr<WasmCode> code) { } if (update_jump_table) { - JumpTableAssembler::PatchJumpTableSlot( - main_jump_table_->instruction_start(), slot_idx, - code->instruction_start(), WasmCode::kFlushICache); + PatchJumpTablesLocked(slot_idx, code->instruction_start()); } } WasmCodeRefScope::AddRef(code.get()); @@ -1120,11 +1145,12 @@ WasmModuleSourceMap* NativeModule::GetWasmSourceMap() const { } WasmCode* NativeModule::CreateEmptyJumpTableInRegion( - uint32_t jump_table_size, base::AddressRegion region) { + uint32_t jump_table_size, base::AddressRegion region, + const WasmCodeAllocator::OptionalLock& allocator_lock) { // Only call this if we really need a jump table. DCHECK_LT(0, jump_table_size); - Vector<uint8_t> code_space = - code_allocator_.AllocateForCodeInRegion(this, jump_table_size, region); + Vector<uint8_t> code_space = code_allocator_.AllocateForCodeInRegion( + this, jump_table_size, region, allocator_lock); DCHECK(!code_space.empty()); ZapCode(reinterpret_cast<Address>(code_space.begin()), code_space.size()); std::unique_ptr<WasmCode> code{new WasmCode{ @@ -1146,12 +1172,63 @@ WasmCode* NativeModule::CreateEmptyJumpTableInRegion( return PublishCode(std::move(code)); } -void NativeModule::AddCodeSpace(base::AddressRegion region) { +void NativeModule::PatchJumpTablesLocked(uint32_t slot_index, Address target) { + // The caller must hold the {allocation_mutex_}, thus we fail to lock it here. + DCHECK(!allocation_mutex_.TryLock()); + + for (auto& code_space_data : code_space_data_) { + DCHECK_IMPLIES(code_space_data.jump_table, code_space_data.far_jump_table); + if (!code_space_data.jump_table) continue; + PatchJumpTableLocked(code_space_data, slot_index, target); + } +} + +void NativeModule::PatchJumpTableLocked(const CodeSpaceData& code_space_data, + uint32_t slot_index, Address target) { + // The caller must hold the {allocation_mutex_}, thus we fail to lock it here. + DCHECK(!allocation_mutex_.TryLock()); + + DCHECK_NOT_NULL(code_space_data.jump_table); + DCHECK_NOT_NULL(code_space_data.far_jump_table); + + DCHECK_LT(slot_index, module_->num_declared_functions); + Address jump_table_slot = + code_space_data.jump_table->instruction_start() + + JumpTableAssembler::JumpSlotIndexToOffset(slot_index); + uint32_t far_jump_table_offset = JumpTableAssembler::FarJumpSlotIndexToOffset( + WasmCode::kRuntimeStubCount + slot_index); + // Only pass the far jump table start if the far jump table actually has a + // slot for this function index (i.e. does not only contain runtime stubs). + bool has_far_jump_slot = + far_jump_table_offset < + code_space_data.far_jump_table->instructions().size(); + Address far_jump_table_start = + code_space_data.far_jump_table->instruction_start(); + Address far_jump_table_slot = + has_far_jump_slot ? far_jump_table_start + far_jump_table_offset + : kNullAddress; + JumpTableAssembler::PatchJumpTableSlot(jump_table_slot, far_jump_table_slot, + target); +} + +void NativeModule::AddCodeSpace( + base::AddressRegion region, + const WasmCodeAllocator::OptionalLock& allocator_lock) { +#ifndef V8_EMBEDDED_BUILTINS + // The far jump table contains far jumps to the embedded builtins. This + // requires a build with embedded builtins enabled. + FATAL( + "WebAssembly is not supported in no-embed builds. no-embed builds are " + "deprecated. See\n" + " - https://groups.google.com/d/msg/v8-users/9F53xqBjpkI/9WmKSbcWBAAJ\n" + " - https://crbug.com/v8/8519\n" + " - https://crbug.com/v8/8531\n"); +#endif // V8_EMBEDDED_BUILTINS + // Each code space must be at least twice as large as the overhead per code // space. Otherwise, we are wasting too much memory. - const bool is_first_code_space = code_space_data_.empty(); - const bool implicit_alloc_disabled = - engine_->code_manager()->IsImplicitAllocationsDisabledForTesting(); + DCHECK_GE(region.size(), + 2 * OverheadPerCodeSpace(module()->num_declared_functions)); #if defined(V8_OS_WIN64) // On some platforms, specifically Win64, we need to reserve some pages at @@ -1160,32 +1237,82 @@ void NativeModule::AddCodeSpace(base::AddressRegion region) { // https://cs.chromium.org/chromium/src/components/crash/content/app/crashpad_win.cc?rcl=fd680447881449fba2edcf0589320e7253719212&l=204 // for details. if (engine_->code_manager() - ->CanRegisterUnwindInfoForNonABICompliantCodeRange() && - !implicit_alloc_disabled) { + ->CanRegisterUnwindInfoForNonABICompliantCodeRange()) { size_t size = Heap::GetCodeRangeReservedAreaSize(); DCHECK_LT(0, size); - Vector<byte> padding = code_allocator_.AllocateForCode(this, size); - CHECK(region.contains(reinterpret_cast<Address>(padding.begin()), - padding.size())); + Vector<byte> padding = code_allocator_.AllocateForCodeInRegion( + this, size, region, allocator_lock); + CHECK_EQ(reinterpret_cast<Address>(padding.begin()), region.begin()); + win64_unwindinfo::RegisterNonABICompliantCodeRange( + reinterpret_cast<void*>(region.begin()), region.size()); } #endif // V8_OS_WIN64 WasmCodeRefScope code_ref_scope; WasmCode* jump_table = nullptr; + WasmCode* far_jump_table = nullptr; const uint32_t num_wasm_functions = module_->num_declared_functions; const bool has_functions = num_wasm_functions > 0; + const bool is_first_code_space = code_space_data_.empty(); + // TODO(clemensb): Avoid additional jump table if the code space is close + // enough to another existing code space. const bool needs_jump_table = - has_functions && is_first_code_space && !implicit_alloc_disabled; + has_functions && (kNeedsFarJumpsBetweenCodeSpaces || is_first_code_space); if (needs_jump_table) { jump_table = CreateEmptyJumpTableInRegion( - JumpTableAssembler::SizeForNumberOfSlots(num_wasm_functions), region); + JumpTableAssembler::SizeForNumberOfSlots(num_wasm_functions), region, + allocator_lock); CHECK(region.contains(jump_table->instruction_start())); } + // Always allocate a far jump table, because it contains the runtime stubs. + int num_function_slots = NumWasmFunctionsInFarJumpTable(num_wasm_functions); + far_jump_table = CreateEmptyJumpTableInRegion( + JumpTableAssembler::SizeForNumberOfFarJumpSlots( + WasmCode::kRuntimeStubCount, num_function_slots), + region, allocator_lock); + CHECK(region.contains(far_jump_table->instruction_start())); + EmbeddedData embedded_data = EmbeddedData::FromBlob(); +#define RUNTIME_STUB(Name) Builtins::k##Name, +#define RUNTIME_STUB_TRAP(Name) RUNTIME_STUB(ThrowWasm##Name) + Builtins::Name stub_names[WasmCode::kRuntimeStubCount] = { + WASM_RUNTIME_STUB_LIST(RUNTIME_STUB, RUNTIME_STUB_TRAP)}; +#undef RUNTIME_STUB +#undef RUNTIME_STUB_TRAP + Address builtin_addresses[WasmCode::kRuntimeStubCount]; + for (int i = 0; i < WasmCode::kRuntimeStubCount; ++i) { + Builtins::Name builtin = stub_names[i]; + CHECK(embedded_data.ContainsBuiltin(builtin)); + builtin_addresses[i] = embedded_data.InstructionStartOfBuiltin(builtin); + } + JumpTableAssembler::GenerateFarJumpTable( + far_jump_table->instruction_start(), builtin_addresses, + WasmCode::kRuntimeStubCount, num_function_slots); + if (is_first_code_space) main_jump_table_ = jump_table; - code_space_data_.push_back(CodeSpaceData{region, jump_table}); + base::MutexGuard guard(&allocation_mutex_); + code_space_data_.push_back(CodeSpaceData{region, jump_table, far_jump_table}); + + if (jump_table && !is_first_code_space) { + // Patch the new jump table(s) with existing functions. If this is the first + // code space, there cannot be any functions that have been compiled yet. + const CodeSpaceData& new_code_space_data = code_space_data_.back(); + for (uint32_t slot_index = 0; slot_index < num_wasm_functions; + ++slot_index) { + if (code_table_[slot_index]) { + PatchJumpTableLocked(new_code_space_data, slot_index, + code_table_[slot_index]->instruction_start()); + } else if (lazy_compile_table_) { + Address lazy_compile_target = + lazy_compile_table_->instruction_start() + + JumpTableAssembler::LazyCompileSlotIndexToOffset(slot_index); + PatchJumpTableLocked(new_code_space_data, slot_index, + lazy_compile_target); + } + } + } } namespace { @@ -1241,26 +1368,86 @@ Address NativeModule::GetCallTargetForFunction(uint32_t func_index) const { return main_jump_table_->instruction_start() + slot_offset; } +NativeModule::JumpTablesRef NativeModule::FindJumpTablesForCode( + Address code_addr) const { + base::MutexGuard guard(&allocation_mutex_); + for (auto& code_space_data : code_space_data_) { + const bool jump_table_reachable = + !kNeedsFarJumpsBetweenCodeSpaces || + code_space_data.region.contains(code_addr); + if (jump_table_reachable && code_space_data.far_jump_table) { + // We might not have a jump table if we have no functions. + return {code_space_data.jump_table + ? code_space_data.jump_table->instruction_start() + : kNullAddress, + code_space_data.far_jump_table->instruction_start()}; + } + } + FATAL("code_addr is not part of a code space"); +} + +Address NativeModule::GetNearCallTargetForFunction( + uint32_t func_index, const JumpTablesRef& jump_tables) const { + uint32_t slot_offset = GetJumpTableOffset(func_index); + return jump_tables.jump_table_start + slot_offset; +} + +Address NativeModule::GetNearRuntimeStubEntry( + WasmCode::RuntimeStubId index, const JumpTablesRef& jump_tables) const { + auto offset = JumpTableAssembler::FarJumpSlotIndexToOffset(index); + return jump_tables.far_jump_table_start + offset; +} + uint32_t NativeModule::GetFunctionIndexFromJumpTableSlot( Address slot_address) const { - DCHECK(is_jump_table_slot(slot_address)); - uint32_t slot_offset = static_cast<uint32_t>( - slot_address - main_jump_table_->instruction_start()); + WasmCodeRefScope code_refs; + WasmCode* code = Lookup(slot_address); + DCHECK_NOT_NULL(code); + DCHECK_EQ(WasmCode::kJumpTable, code->kind()); + uint32_t slot_offset = + static_cast<uint32_t>(slot_address - code->instruction_start()); uint32_t slot_idx = JumpTableAssembler::SlotOffsetToIndex(slot_offset); DCHECK_LT(slot_idx, module_->num_declared_functions); + DCHECK_EQ(slot_address, + code->instruction_start() + + JumpTableAssembler::JumpSlotIndexToOffset(slot_idx)); return module_->num_imported_functions + slot_idx; } -const char* NativeModule::GetRuntimeStubName(Address runtime_stub_entry) const { -#define RETURN_NAME(Name) \ - if (runtime_stub_entries_[WasmCode::k##Name] == runtime_stub_entry) { \ - return #Name; \ +WasmCode::RuntimeStubId NativeModule::GetRuntimeStubId(Address target) const { + base::MutexGuard guard(&allocation_mutex_); + + for (auto& code_space_data : code_space_data_) { + if (code_space_data.far_jump_table->contains(target)) { + uint32_t offset = static_cast<uint32_t>( + target - code_space_data.far_jump_table->instruction_start()); + uint32_t index = JumpTableAssembler::FarJumpSlotOffsetToIndex(offset); + if (index >= WasmCode::kRuntimeStubCount) continue; + if (JumpTableAssembler::FarJumpSlotIndexToOffset(index) != offset) { + continue; + } + return static_cast<WasmCode::RuntimeStubId>(index); + } } -#define RETURN_NAME_TRAP(Name) RETURN_NAME(ThrowWasm##Name) - WASM_RUNTIME_STUB_LIST(RETURN_NAME, RETURN_NAME_TRAP) -#undef RETURN_NAME_TRAP -#undef RETURN_NAME - return "<unknown>"; + + // Invalid address. + return WasmCode::kRuntimeStubCount; +} + +const char* NativeModule::GetRuntimeStubName(Address target) const { + WasmCode::RuntimeStubId stub_id = GetRuntimeStubId(target); + +#define RUNTIME_STUB_NAME(Name) #Name, +#define RUNTIME_STUB_NAME_TRAP(Name) "ThrowWasm" #Name, + constexpr const char* runtime_stub_names[] = {WASM_RUNTIME_STUB_LIST( + RUNTIME_STUB_NAME, RUNTIME_STUB_NAME_TRAP) "<unknown>"}; +#undef RUNTIME_STUB_NAME +#undef RUNTIME_STUB_NAME_TRAP + STATIC_ASSERT(arraysize(runtime_stub_names) == + WasmCode::kRuntimeStubCount + 1); + + DCHECK_GT(arraysize(runtime_stub_names), stub_id); + return runtime_stub_names[stub_id]; } NativeModule::~NativeModule() { @@ -1275,10 +1462,8 @@ NativeModule::~NativeModule() { import_wrapper_cache_.reset(); } -WasmCodeManager::WasmCodeManager(WasmMemoryTracker* memory_tracker, - size_t max_committed) - : memory_tracker_(memory_tracker), - max_committed_code_space_(max_committed), +WasmCodeManager::WasmCodeManager(size_t max_committed) + : max_committed_code_space_(max_committed), critical_committed_code_space_(max_committed / 2) { DCHECK_LE(max_committed, kMaxWasmCodeMemory); } @@ -1350,12 +1535,12 @@ VirtualMemory WasmCodeManager::TryAllocate(size_t size, void* hint) { DCHECK_GT(size, 0); size_t allocate_page_size = page_allocator->AllocatePageSize(); size = RoundUp(size, allocate_page_size); - if (!memory_tracker_->ReserveAddressSpace(size)) return {}; + if (!BackingStore::ReserveAddressSpace(size)) return {}; if (hint == nullptr) hint = page_allocator->GetRandomMmapAddr(); VirtualMemory mem(page_allocator, size, hint, allocate_page_size); if (!mem.IsReserved()) { - memory_tracker_->ReleaseReservation(size); + BackingStore::ReleaseReservation(size); return {}; } TRACE_HEAP("VMem alloc: 0x%" PRIxPTR ":0x%" PRIxPTR " (%zu)\n", mem.address(), @@ -1369,13 +1554,6 @@ VirtualMemory WasmCodeManager::TryAllocate(size_t size, void* hint) { return mem; } -void WasmCodeManager::SetMaxCommittedMemoryForTesting(size_t limit) { - // This has to be set before committing any memory. - DCHECK_EQ(0, total_committed_code_space_.load()); - max_committed_code_space_ = limit; - critical_committed_code_space_.store(limit / 2); -} - // static size_t WasmCodeManager::EstimateNativeModuleCodeSize(const WasmModule* module) { constexpr size_t kCodeSizeMultiplier = 4; @@ -1387,8 +1565,6 @@ size_t WasmCodeManager::EstimateNativeModuleCodeSize(const WasmModule* module) { for (auto& function : module->functions) { estimate += kCodeOverhead + kCodeSizeMultiplier * function.code.length(); } - estimate += - JumpTableAssembler::SizeForNumberOfSlots(module->num_declared_functions); estimate += kImportSize * module->num_imported_functions; return estimate; @@ -1425,9 +1601,20 @@ std::shared_ptr<NativeModule> WasmCodeManager::NewNativeModule( committed + (max_committed_code_space_ - committed) / 2); } - // If the code must be contiguous, reserve enough address space up front. + // If we cannot add code space later, reserve enough address space up front. size_t code_vmem_size = - kRequiresCodeRange ? kMaxWasmCodeMemory : code_size_estimate; + can_request_more ? ReservationSize(code_size_estimate, + module->num_declared_functions, 0) + : kMaxWasmCodeSpaceSize; + + // The '--wasm-max-code-space-reservation' testing flag can be used to reduce + // the maximum size of the initial code space reservation (in MB). + if (FLAG_wasm_max_initial_code_space_reservation > 0) { + size_t flag_max_bytes = + static_cast<size_t>(FLAG_wasm_max_initial_code_space_reservation) * MB; + if (flag_max_bytes < code_vmem_size) code_vmem_size = flag_max_bytes; + } + // Try up to two times; getting rid of dead JSArrayBuffer allocations might // require two GCs because the first GC maybe incremental and may have // floating garbage. @@ -1456,14 +1643,6 @@ std::shared_ptr<NativeModule> WasmCodeManager::NewNativeModule( TRACE_HEAP("New NativeModule %p: Mem: %" PRIuPTR ",+%zu\n", ret.get(), start, size); -#if defined(V8_OS_WIN64) - if (CanRegisterUnwindInfoForNonABICompliantCodeRange() && - !implicit_allocations_disabled_for_testing_) { - win64_unwindinfo::RegisterNonABICompliantCodeRange( - reinterpret_cast<void*>(start), size); - } -#endif // V8_OS_WIN64 - base::MutexGuard lock(&native_modules_mutex_); lookup_map_.insert(std::make_pair(start, std::make_pair(end, ret.get()))); return ret; @@ -1519,6 +1698,9 @@ std::vector<WasmCode*> NativeModule::AddCompiledCode( } Vector<byte> code_space = code_allocator_.AllocateForCode(this, total_code_space); + // Lookup the jump tables to use once, then use for all code objects. + auto jump_tables_ref = + FindJumpTablesForCode(reinterpret_cast<Address>(code_space.begin())); std::vector<std::unique_ptr<WasmCode>> generated_code; generated_code.reserve(results.size()); @@ -1533,7 +1715,7 @@ std::vector<WasmCode*> NativeModule::AddCompiledCode( result.func_index, result.code_desc, result.frame_slot_count, result.tagged_parameter_slots, std::move(result.protected_instructions), std::move(result.source_positions), GetCodeKind(result), - result.result_tier, this_code_space)); + result.result_tier, this_code_space, jump_tables_ref)); } DCHECK_EQ(0, code_space.size()); @@ -1567,6 +1749,10 @@ void NativeModule::FreeCode(Vector<WasmCode* const> codes) { } } +size_t NativeModule::GetNumberOfCodeSpacesForTesting() const { + return code_allocator_.GetNumCodeSpaces(); +} + void WasmCodeManager::FreeNativeModule(Vector<VirtualMemory> owned_code_space, size_t committed_size) { base::MutexGuard lock(&native_modules_mutex_); @@ -1576,15 +1762,14 @@ void WasmCodeManager::FreeNativeModule(Vector<VirtualMemory> owned_code_space, code_space.address(), code_space.end(), code_space.size()); #if defined(V8_OS_WIN64) - if (CanRegisterUnwindInfoForNonABICompliantCodeRange() && - !implicit_allocations_disabled_for_testing_) { + if (CanRegisterUnwindInfoForNonABICompliantCodeRange()) { win64_unwindinfo::UnregisterNonABICompliantCodeRange( reinterpret_cast<void*>(code_space.address())); } #endif // V8_OS_WIN64 lookup_map_.erase(code_space.address()); - memory_tracker_->ReleaseReservation(code_space.size()); + BackingStore::ReleaseReservation(code_space.size()); code_space.Free(); DCHECK(!code_space.IsReserved()); } diff --git a/deps/v8/src/wasm/wasm-code-manager.h b/deps/v8/src/wasm/wasm-code-manager.h index c2e5249e5ee75d..7deea9032a5c65 100644 --- a/deps/v8/src/wasm/wasm-code-manager.h +++ b/deps/v8/src/wasm/wasm-code-manager.h @@ -39,7 +39,6 @@ class NativeModule; class WasmCodeManager; struct WasmCompilationResult; class WasmEngine; -class WasmMemoryTracker; class WasmImportWrapperCache; struct WasmModule; @@ -79,7 +78,6 @@ class V8_EXPORT_PRIVATE WasmCode final { kFunction, kWasmToCapiWrapper, kWasmToJsWrapper, - kRuntimeStub, kInterpreterEntry, kJumpTable }; @@ -282,11 +280,33 @@ const char* GetWasmCodeKindAsString(WasmCode::Kind); // Manages the code reservations and allocations of a single {NativeModule}. class WasmCodeAllocator { public: + // {OptionalLock} is passed between {WasmCodeAllocator} and {NativeModule} to + // indicate that the lock on the {WasmCodeAllocator} is already taken. It's + // optional to allow to also call methods without holding the lock. + class OptionalLock { + public: + // External users can only instantiate a non-locked {OptionalLock}. + OptionalLock() = default; + ~OptionalLock(); + bool is_locked() const { return allocator_ != nullptr; } + + private: + friend class WasmCodeAllocator; + // {Lock} is called from the {WasmCodeAllocator} if no locked {OptionalLock} + // is passed. + void Lock(WasmCodeAllocator*); + + WasmCodeAllocator* allocator_ = nullptr; + }; + WasmCodeAllocator(WasmCodeManager*, VirtualMemory code_space, bool can_request_more, std::shared_ptr<Counters> async_counters); ~WasmCodeAllocator(); + // Call before use, after the {NativeModule} is set up completely. + void Init(NativeModule*); + size_t committed_code_space() const { return committed_code_space_.load(std::memory_order_acquire); } @@ -303,7 +323,8 @@ class WasmCodeAllocator { // Allocate code space within a specific region. Returns a valid buffer or // fails with OOM (crash). Vector<byte> AllocateForCodeInRegion(NativeModule*, size_t size, - base::AddressRegion); + base::AddressRegion, + const WasmCodeAllocator::OptionalLock&); // Sets permissions of all owned code space to executable, or read-write (if // {executable} is false). Returns true on success. @@ -312,9 +333,8 @@ class WasmCodeAllocator { // Free memory pages of all given code objects. Used for wasm code GC. void FreeCode(Vector<WasmCode* const>); - // Returns the region of the single code space managed by this code allocator. - // Will fail if more than one code space has been created. - base::AddressRegion GetSingleCodeRegion() const; + // Retrieve the number of separately reserved code spaces. + size_t GetNumCodeSpaces() const; private: // The engine-wide wasm code manager. @@ -344,6 +364,8 @@ class WasmCodeAllocator { bool is_executable_ = false; + // TODO(clemensb): Remove this field once multiple code spaces are supported + // everywhere. const bool can_request_more_memory_; std::shared_ptr<Counters> async_counters_; @@ -352,9 +374,9 @@ class WasmCodeAllocator { class V8_EXPORT_PRIVATE NativeModule final { public: #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64 - static constexpr bool kCanAllocateMoreMemory = false; + static constexpr bool kNeedsFarJumpsBetweenCodeSpaces = true; #else - static constexpr bool kCanAllocateMoreMemory = true; + static constexpr bool kNeedsFarJumpsBetweenCodeSpaces = false; #endif // {AddCode} is thread safe w.r.t. other calls to {AddCode} or methods adding @@ -394,11 +416,6 @@ class V8_EXPORT_PRIVATE NativeModule final { // table with trampolines accordingly. void UseLazyStub(uint32_t func_index); - // Initializes all runtime stubs by setting up entry addresses in the runtime - // stub table. It must be called exactly once per native module before adding - // other WasmCode so that runtime stub ids can be resolved during relocation. - void SetRuntimeStubs(Isolate* isolate); - // Creates a snapshot of the current state of the code table. This is useful // to get a consistent view of the table (e.g. used by the serializer). std::vector<WasmCode*> SnapshotCodeTable() const; @@ -409,13 +426,6 @@ class V8_EXPORT_PRIVATE NativeModule final { void SetWasmSourceMap(std::unique_ptr<WasmModuleSourceMap> source_map); WasmModuleSourceMap* GetWasmSourceMap() const; - Address runtime_stub_entry(WasmCode::RuntimeStubId index) const { - DCHECK_LT(index, WasmCode::kRuntimeStubCount); - Address entry_address = runtime_stub_entries_[index]; - DCHECK_NE(kNullAddress, entry_address); - return entry_address; - } - Address jump_table_start() const { return main_jump_table_ ? main_jump_table_->instruction_start() : kNullAddress; @@ -423,16 +433,33 @@ class V8_EXPORT_PRIVATE NativeModule final { uint32_t GetJumpTableOffset(uint32_t func_index) const; - bool is_jump_table_slot(Address address) const { - return main_jump_table_->contains(address); - } - // Returns the canonical target to call for the given function (the slot in // the first jump table). Address GetCallTargetForFunction(uint32_t func_index) const; - // Reverse lookup from a given call target (i.e. a jump table slot as the - // above {GetCallTargetForFunction} returns) to a function index. + struct JumpTablesRef { + const Address jump_table_start; + const Address far_jump_table_start; + }; + + // Finds the jump tables that should be used for the code at {code_addr}. This + // information is then passed to {GetNearCallTargetForFunction} and + // {GetNearRuntimeStubEntry} to avoid the overhead of looking this information + // up there. + JumpTablesRef FindJumpTablesForCode(Address code_addr) const; + + // Similarly to {GetCallTargetForFunction}, but uses the jump table previously + // looked up via {FindJumpTablesForCode}. + Address GetNearCallTargetForFunction(uint32_t func_index, + const JumpTablesRef&) const; + + // Get a runtime stub entry (which is a far jump table slot) in the jump table + // previously looked up via {FindJumpTablesForCode}. + Address GetNearRuntimeStubEntry(WasmCode::RuntimeStubId index, + const JumpTablesRef&) const; + + // Reverse lookup from a given call target (which must be a jump table slot) + // to a function index. uint32_t GetFunctionIndexFromJumpTableSlot(Address slot_address) const; bool SetExecutable(bool executable) { @@ -481,7 +508,11 @@ class V8_EXPORT_PRIVATE NativeModule final { const WasmFeatures& enabled_features() const { return enabled_features_; } - const char* GetRuntimeStubName(Address runtime_stub_entry) const; + // Returns the runtime stub id that corresponds to the given address (which + // must be a far jump table slot). Returns {kRuntimeStubCount} on failure. + WasmCode::RuntimeStubId GetRuntimeStubId(Address runtime_stub_target) const; + + const char* GetRuntimeStubName(Address runtime_stub_target) const; // Sample the current code size of this modules to the given counters. enum CodeSamplingTime : int8_t { kAfterBaseline, kAfterTopTier, kSampling }; @@ -501,6 +532,9 @@ class V8_EXPORT_PRIVATE NativeModule final { // its accounting. void FreeCode(Vector<WasmCode* const>); + // Retrieve the number of separately reserved code spaces for this module. + size_t GetNumberOfCodeSpacesForTesting() const; + private: friend class WasmCode; friend class WasmCodeAllocator; @@ -510,6 +544,7 @@ class V8_EXPORT_PRIVATE NativeModule final { struct CodeSpaceData { base::AddressRegion region; WasmCode* jump_table; + WasmCode* far_jump_table; }; // Private constructor, called via {WasmCodeManager::NewNativeModule()}. @@ -525,17 +560,23 @@ class V8_EXPORT_PRIVATE NativeModule final { OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions, OwnedVector<const byte> source_position_table, WasmCode::Kind kind, - ExecutionTier tier, Vector<uint8_t> code_space); + ExecutionTier tier, Vector<uint8_t> code_space, + const JumpTablesRef& jump_tables_ref); - // Add and publish anonymous code. - WasmCode* AddAndPublishAnonymousCode(Handle<Code>, WasmCode::Kind kind, - const char* name = nullptr); + WasmCode* CreateEmptyJumpTableInRegion( + uint32_t jump_table_size, base::AddressRegion, + const WasmCodeAllocator::OptionalLock&); - WasmCode* CreateEmptyJumpTableInRegion(uint32_t jump_table_size, - base::AddressRegion); + // Hold the {allocation_mutex_} when calling one of these methods. + // {slot_index} is the index in the declared functions, i.e. function index + // minus the number of imported functions. + void PatchJumpTablesLocked(uint32_t slot_index, Address target); + void PatchJumpTableLocked(const CodeSpaceData&, uint32_t slot_index, + Address target); // Called by the {WasmCodeAllocator} to register a new code space. - void AddCodeSpace(base::AddressRegion); + void AddCodeSpace(base::AddressRegion, + const WasmCodeAllocator::OptionalLock&); // Hold the {allocation_mutex_} when calling this method. bool has_interpreter_redirection(uint32_t func_index) { @@ -580,12 +621,6 @@ class V8_EXPORT_PRIVATE NativeModule final { // {WireBytesStorage}, held by background compile tasks. std::shared_ptr<OwnedVector<const uint8_t>> wire_bytes_; - // Contains entry points for runtime stub calls via {WASM_STUB_CALL}. - Address runtime_stub_entries_[WasmCode::kRuntimeStubCount] = {kNullAddress}; - - // Jump table used for runtime stubs (i.e. trampolines to embedded builtins). - WasmCode* runtime_stub_table_ = nullptr; - // Jump table used by external calls (from JS). Wasm calls use one of the jump // tables stored in {code_space_data_}. WasmCode* main_jump_table_ = nullptr; @@ -612,7 +647,11 @@ class V8_EXPORT_PRIVATE NativeModule final { // instruction start address of the value. std::map<Address, std::unique_ptr<WasmCode>> owned_code_; - std::unique_ptr<WasmCode* []> code_table_; + // Table of the latest code object per function, updated on initial + // compilation and tier up. The number of entries is + // {WasmModule::num_declared_functions}, i.e. there are no entries for + // imported functions. + std::unique_ptr<WasmCode*[]> code_table_; // Null if no redirections exist, otherwise a bitset over all functions in // this module marking those functions that have been redirected. @@ -634,8 +673,7 @@ class V8_EXPORT_PRIVATE NativeModule final { class V8_EXPORT_PRIVATE WasmCodeManager final { public: - explicit WasmCodeManager(WasmMemoryTracker* memory_tracker, - size_t max_committed); + explicit WasmCodeManager(size_t max_committed); #ifdef DEBUG ~WasmCodeManager() { @@ -654,16 +692,6 @@ class V8_EXPORT_PRIVATE WasmCodeManager final { return total_committed_code_space_.load(); } - void SetMaxCommittedMemoryForTesting(size_t limit); - - void DisableImplicitAllocationsForTesting() { - implicit_allocations_disabled_for_testing_ = true; - } - - bool IsImplicitAllocationsDisabledForTesting() const { - return implicit_allocations_disabled_for_testing_; - } - static size_t EstimateNativeModuleCodeSize(const WasmModule* module); static size_t EstimateNativeModuleNonCodeSize(const WasmModule* module); @@ -686,11 +714,7 @@ class V8_EXPORT_PRIVATE WasmCodeManager final { void AssignRange(base::AddressRegion, NativeModule*); - WasmMemoryTracker* const memory_tracker_; - - size_t max_committed_code_space_; - - bool implicit_allocations_disabled_for_testing_ = false; + const size_t max_committed_code_space_; std::atomic<size_t> total_committed_code_space_{0}; // If the committed code space exceeds {critical_committed_code_space_}, then diff --git a/deps/v8/src/wasm/wasm-constants.h b/deps/v8/src/wasm/wasm-constants.h index fbbe19396cb254..2b5cb6c9ec7995 100644 --- a/deps/v8/src/wasm/wasm-constants.h +++ b/deps/v8/src/wasm/wasm-constants.h @@ -81,6 +81,7 @@ enum SectionCode : int8_t { // to be consistent. kNameSectionCode, // Name section (encoded as a string) kSourceMappingURLSectionCode, // Source Map URL section + kDebugInfoSectionCode, // DWARF section .debug_info kCompilationHintsSectionCode, // Compilation hints section // Helper values diff --git a/deps/v8/src/wasm/wasm-debug.cc b/deps/v8/src/wasm/wasm-debug.cc index 2955bc602f6a20..f3580e4427d7a4 100644 --- a/deps/v8/src/wasm/wasm-debug.cc +++ b/deps/v8/src/wasm/wasm-debug.cc @@ -97,7 +97,6 @@ MaybeHandle<String> GetLocalName(Isolate* isolate, } class InterpreterHandle { - MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(InterpreterHandle); Isolate* isolate_; const WasmModule* module_; WasmInterpreter interpreter_; @@ -184,7 +183,7 @@ class InterpreterHandle { argument_values.begin()); bool finished = false; while (!finished) { - // TODO(clemensh): Add occasional StackChecks. + // TODO(clemensb): Add occasional StackChecks. WasmInterpreter::State state = ContinueExecution(thread); switch (state) { case WasmInterpreter::State::PAUSED: @@ -277,9 +276,10 @@ class InterpreterHandle { if (isolate_->debug()->break_points_active()) { Handle<WasmModuleObject> module_object( GetInstanceObject()->module_object(), isolate_); + Handle<Script> script(module_object->script(), isolate_); int position = GetTopPosition(module_object); Handle<FixedArray> breakpoints; - if (WasmModuleObject::CheckBreakPoints(isolate_, module_object, position) + if (WasmModuleObject::CheckBreakPoints(isolate_, script, position) .ToHandle(&breakpoints)) { // We hit one or several breakpoints. Clear stepping, notify the // listeners and return. @@ -318,7 +318,8 @@ class InterpreterHandle { DCHECK_LT(0, thread->GetFrameCount()); auto frame = thread->GetFrame(thread->GetFrameCount() - 1); - return module_object->GetFunctionOffset(frame->function()->func_index) + + return GetWasmFunctionOffset(module_object->module(), + frame->function()->func_index) + frame->pc(); } @@ -459,6 +460,9 @@ class InterpreterHandle { } return local_scope_object; } + + private: + DISALLOW_COPY_AND_ASSIGN(InterpreterHandle); }; } // namespace @@ -502,9 +506,11 @@ wasm::InterpreterHandle* GetInterpreterHandleOrNull(WasmDebugInfo debug_info) { Handle<WasmDebugInfo> WasmDebugInfo::New(Handle<WasmInstanceObject> instance) { DCHECK(!instance->has_debug_info()); Factory* factory = instance->GetIsolate()->factory(); + Handle<Cell> stack_cell = factory->NewCell(factory->empty_fixed_array()); Handle<WasmDebugInfo> debug_info = Handle<WasmDebugInfo>::cast( factory->NewStruct(WASM_DEBUG_INFO_TYPE, AllocationType::kOld)); debug_info->set_wasm_instance(*instance); + debug_info->set_interpreter_reference_stack(*stack_cell); instance->set_debug_info(*debug_info); return debug_info; } @@ -524,6 +530,7 @@ wasm::WasmInterpreter* WasmDebugInfo::SetupForTesting( return interp_handle->raw()->interpreter(); } +// static void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info, int func_index, int offset) { Isolate* isolate = debug_info->GetIsolate(); @@ -533,6 +540,18 @@ void WasmDebugInfo::SetBreakpoint(Handle<WasmDebugInfo> debug_info, handle->interpreter()->SetBreakpoint(func, offset, true); } +// static +void WasmDebugInfo::ClearBreakpoint(Handle<WasmDebugInfo> debug_info, + int func_index, int offset) { + Isolate* isolate = debug_info->GetIsolate(); + auto* handle = GetOrCreateInterpreterHandle(isolate, debug_info); + // TODO(leese): If there are no more breakpoints left it would be good to + // undo redirecting to the interpreter. + const wasm::WasmFunction* func = &handle->module()->functions[func_index]; + handle->interpreter()->SetBreakpoint(func, offset, false); +} + +// static void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info, Vector<int> func_indexes) { Isolate* isolate = debug_info->GetIsolate(); @@ -635,8 +654,8 @@ Handle<Code> WasmDebugInfo::GetCWasmEntry(Handle<WasmDebugInfo> debug_info, if (index == -1) { index = static_cast<int32_t>(map->FindOrInsert(*sig)); if (index == entries->length()) { - entries = isolate->factory()->CopyFixedArrayAndGrow( - entries, entries->length(), AllocationType::kOld); + entries = + isolate->factory()->CopyFixedArrayAndGrow(entries, entries->length()); debug_info->set_c_wasm_entries(*entries); } DCHECK(entries->get(index).IsUndefined(isolate)); diff --git a/deps/v8/src/wasm/wasm-engine.cc b/deps/v8/src/wasm/wasm-engine.cc index 97111f8349735a..adb566cb41835f 100644 --- a/deps/v8/src/wasm/wasm-engine.cc +++ b/deps/v8/src/wasm/wasm-engine.cc @@ -211,8 +211,7 @@ struct WasmEngine::NativeModuleInfo { int8_t num_code_gcs_triggered = 0; }; -WasmEngine::WasmEngine() - : code_manager_(&memory_tracker_, FLAG_wasm_max_code_space * MB) {} +WasmEngine::WasmEngine() : code_manager_(FLAG_wasm_max_code_space * MB) {} WasmEngine::~WasmEngine() { // Synchronize on all background compile tasks. @@ -307,7 +306,7 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile( CreateWasmScript(isolate, bytes, native_module->module()->source_map_url); // Create the module object. - // TODO(clemensh): For the same module (same bytes / same hash), we should + // TODO(clemensb): For the same module (same bytes / same hash), we should // only have one WasmModuleObject. Otherwise, we might only set // breakpoints on a (potentially empty) subset of the instances. @@ -337,7 +336,7 @@ void WasmEngine::AsyncInstantiate( ErrorThrower thrower(isolate, "WebAssembly.instantiate()"); // Instantiate a TryCatch so that caught exceptions won't progagate out. // They will still be set as pending exceptions on the isolate. - // TODO(clemensh): Avoid TryCatch, use Execution::TryCall internally to invoke + // TODO(clemensb): Avoid TryCatch, use Execution::TryCall internally to invoke // start function and report thrown exception explicitly via out argument. v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate)); catcher.SetVerbose(false); @@ -567,7 +566,7 @@ int GetGCTimeMicros(base::TimeTicks start) { void WasmEngine::AddIsolate(Isolate* isolate) { base::MutexGuard guard(&mutex_); DCHECK_EQ(0, isolates_.count(isolate)); - isolates_.emplace(isolate, base::make_unique<IsolateInfo>(isolate)); + isolates_.emplace(isolate, std::make_unique<IsolateInfo>(isolate)); // Install sampling GC callback. // TODO(v8:7424): For now we sample module sizes in a GC callback. This will @@ -631,7 +630,7 @@ void WasmEngine::LogCode(WasmCode* code) { IsolateInfo* info = isolates_[isolate].get(); if (info->log_codes == false) continue; if (info->log_codes_task == nullptr) { - auto new_task = base::make_unique<LogCodesTask>( + auto new_task = std::make_unique<LogCodesTask>( &mutex_, &info->log_codes_task, isolate, this); info->log_codes_task = new_task.get(); info->foreground_task_runner->PostTask(std::move(new_task)); @@ -676,7 +675,8 @@ std::shared_ptr<NativeModule> WasmEngine::NewNativeModule( size_t code_size_estimate = wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get()); return NewNativeModule(isolate, enabled, code_size_estimate, - wasm::NativeModule::kCanAllocateMoreMemory, + !wasm::NativeModule::kNeedsFarJumpsBetweenCodeSpaces || + FLAG_wasm_far_jump_table, std::move(module)); } @@ -688,7 +688,7 @@ std::shared_ptr<NativeModule> WasmEngine::NewNativeModule( can_request_more, std::move(module)); base::MutexGuard lock(&mutex_); auto pair = native_modules_.insert(std::make_pair( - native_module.get(), base::make_unique<NativeModuleInfo>())); + native_module.get(), std::make_unique<NativeModuleInfo>())); DCHECK(pair.second); // inserted new entry. pair.first->second.get()->isolates.insert(isolate); isolates_[isolate]->native_modules.insert(native_module.get()); @@ -768,7 +768,7 @@ void WasmEngine::SampleTopTierCodeSizeInAllIsolates( DCHECK_EQ(1, isolates_.count(isolate)); IsolateInfo* info = isolates_[isolate].get(); info->foreground_task_runner->PostTask( - base::make_unique<SampleTopTierCodeSizeTask>(isolate, native_module)); + std::make_unique<SampleTopTierCodeSizeTask>(isolate, native_module)); } } @@ -880,7 +880,7 @@ void WasmEngine::TriggerGC(int8_t gc_sequence_index) { for (auto* isolate : native_modules_[entry.first]->isolates) { auto& gc_task = current_gc_info_->outstanding_isolates[isolate]; if (!gc_task) { - auto new_task = base::make_unique<WasmGCForegroundTask>(isolate); + auto new_task = std::make_unique<WasmGCForegroundTask>(isolate); gc_task = new_task.get(); DCHECK_EQ(1, isolates_.count(isolate)); isolates_[isolate]->foreground_task_runner->PostTask( diff --git a/deps/v8/src/wasm/wasm-engine.h b/deps/v8/src/wasm/wasm-engine.h index 401cf2b8805984..424f85fa7988be 100644 --- a/deps/v8/src/wasm/wasm-engine.h +++ b/deps/v8/src/wasm/wasm-engine.h @@ -10,7 +10,6 @@ #include "src/tasks/cancelable-task.h" #include "src/wasm/wasm-code-manager.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-tier.h" #include "src/zone/accounting-allocator.h" @@ -23,6 +22,7 @@ class CompilationStatistics; class HeapNumber; class WasmInstanceObject; class WasmModuleObject; +class JSArrayBuffer; namespace wasm { @@ -120,8 +120,6 @@ class V8_EXPORT_PRIVATE WasmEngine { WasmCodeManager* code_manager() { return &code_manager_; } - WasmMemoryTracker* memory_tracker() { return &memory_tracker_; } - AccountingAllocator* allocator() { return &allocator_; } // Compilation statistics for TurboFan compilations. @@ -156,8 +154,8 @@ class V8_EXPORT_PRIVATE WasmEngine { template <typename T, typename... Args> std::unique_ptr<T> NewBackgroundCompileTask(Args&&... args) { - return base::make_unique<T>(&background_compile_task_manager_, - std::forward<Args>(args)...); + return std::make_unique<T>(&background_compile_task_manager_, + std::forward<Args>(args)...); } // Trigger code logging for this WasmCode in all Isolates which have access to @@ -243,7 +241,6 @@ class V8_EXPORT_PRIVATE WasmEngine { // calling this method. void PotentiallyFinishCurrentGC(); - WasmMemoryTracker memory_tracker_; WasmCodeManager code_manager_; AccountingAllocator allocator_; diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc index 9ca45183ef628a..13c159c0efc2ab 100644 --- a/deps/v8/src/wasm/wasm-external-refs.cc +++ b/deps/v8/src/wasm/wasm-external-refs.cc @@ -247,6 +247,10 @@ int32_t int64_mod_wrapper(Address data) { if (divisor == 0) { return 0; } + if (divisor == -1 && dividend == std::numeric_limits<int64_t>::min()) { + WriteUnalignedValue<int64_t>(data, 0); + return 1; + } WriteUnalignedValue<int64_t>(data, dividend % divisor); return 1; } diff --git a/deps/v8/src/wasm/wasm-feature-flags.h b/deps/v8/src/wasm/wasm-feature-flags.h index 36f9ebd8a46a54..b18fa90acf7002 100644 --- a/deps/v8/src/wasm/wasm-feature-flags.h +++ b/deps/v8/src/wasm/wasm-feature-flags.h @@ -10,12 +10,12 @@ V(eh, "exception handling opcodes", false) \ V(threads, "thread opcodes", false) \ V(simd, "SIMD opcodes", false) \ - V(bigint, "JS BigInt support", false) \ V(return_call, "return call opcodes", false) \ V(compilation_hints, "compilation hints section", false) #define FOREACH_WASM_STAGING_FEATURE_FLAG(V) \ V(anyref, "anyref opcodes", false) \ + V(bigint, "JS BigInt support", false) \ V(type_reflection, "wasm type reflection in JS", false) #define FOREACH_WASM_SHIPPED_FEATURE_FLAG(V) \ diff --git a/deps/v8/src/wasm/wasm-interpreter.cc b/deps/v8/src/wasm/wasm-interpreter.cc index 299128860dafb4..7c41f6a8e02125 100644 --- a/deps/v8/src/wasm/wasm-interpreter.cc +++ b/deps/v8/src/wasm/wasm-interpreter.cc @@ -1128,13 +1128,41 @@ class ThreadImpl { }; public: + // The {ReferenceStackScope} sets up the reference stack in the interpreter. + // The handle to the reference stack has to be re-initialized everytime we + // call into the interpreter because there is no HandleScope that could + // contain that handle. A global handle is not an option because it can lead + // to a memory leak if a reference to the {WasmInstanceObject} is put onto the + // reference stack and thereby transitively keeps the interpreter alive. + class ReferenceStackScope { + public: + explicit ReferenceStackScope(ThreadImpl* impl) : impl_(impl) { + // The reference stack is already initialized, we don't have to do + // anything. + if (!impl_->reference_stack_cell_.is_null()) return; + impl_->reference_stack_cell_ = handle( + impl_->instance_object_->debug_info().interpreter_reference_stack(), + impl_->isolate_); + // We initialized the reference stack, so we also have to reset it later. + do_reset_stack_ = true; + } + + ~ReferenceStackScope() { + if (do_reset_stack_) { + impl_->reference_stack_cell_ = Handle<Cell>(); + } + } + + private: + ThreadImpl* impl_; + bool do_reset_stack_ = false; + }; + ThreadImpl(Zone* zone, CodeMap* codemap, - Handle<WasmInstanceObject> instance_object, - Handle<Cell> reference_stack_cell) + Handle<WasmInstanceObject> instance_object) : codemap_(codemap), isolate_(instance_object->GetIsolate()), instance_object_(instance_object), - reference_stack_cell_(reference_stack_cell), frames_(zone), activations_(zone) {} @@ -1394,6 +1422,7 @@ class ThreadImpl { }; friend class InterpretedFrameImpl; + friend class ReferenceStackScope; CodeMap* codemap_; Isolate* isolate_; @@ -1663,9 +1692,15 @@ class ThreadImpl { template <typename ctype, typename mtype> bool ExecuteLoad(Decoder* decoder, InterpreterCode* code, pc_t pc, - int* const len, MachineRepresentation rep) { - MemoryAccessImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc), - sizeof(ctype)); + int* const len, MachineRepresentation rep, + int prefix_len = 0) { + // Some opcodes have a prefix byte, and MemoryAccessImmediate assumes that + // the memarg is 1 byte from pc. We don't increment pc at the caller, + // because we want to keep pc to the start of the operation to keep trap + // reporting and tracing accurate, otherwise those will report at the middle + // of an opcode. + MemoryAccessImmediate<Decoder::kNoValidate> imm( + decoder, code->at(pc + prefix_len), sizeof(ctype)); uint32_t index = Pop().to<uint32_t>(); Address addr = BoundsCheckMem<mtype>(imm.offset, index); if (!addr) { @@ -1690,9 +1725,15 @@ class ThreadImpl { template <typename ctype, typename mtype> bool ExecuteStore(Decoder* decoder, InterpreterCode* code, pc_t pc, - int* const len, MachineRepresentation rep) { - MemoryAccessImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc), - sizeof(ctype)); + int* const len, MachineRepresentation rep, + int prefix_len = 0) { + // Some opcodes have a prefix byte, and MemoryAccessImmediate assumes that + // the memarg is 1 byte from pc. We don't increment pc at the caller, + // because we want to keep pc to the start of the operation to keep trap + // reporting and tracing accurate, otherwise those will report at the middle + // of an opcode. + MemoryAccessImmediate<Decoder::kNoValidate> imm( + decoder, code->at(pc + prefix_len), sizeof(ctype)); ctype val = Pop().to<ctype>(); uint32_t index = Pop().to<uint32_t>(); @@ -2223,9 +2264,22 @@ class ThreadImpl { EXTRACT_LANE_CASE(F32x4, f32x4) EXTRACT_LANE_CASE(I64x2, i64x2) EXTRACT_LANE_CASE(I32x4, i32x4) - EXTRACT_LANE_CASE(I16x8, i16x8) - EXTRACT_LANE_CASE(I8x16, i8x16) #undef EXTRACT_LANE_CASE +#define EXTRACT_LANE_EXTEND_CASE(format, name, sign, type) \ + case kExpr##format##ExtractLane##sign: { \ + SimdLaneImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc)); \ + *len += 1; \ + WasmValue val = Pop(); \ + Simd128 s = val.to_s128(); \ + auto ss = s.to_##name(); \ + Push(WasmValue(static_cast<type>(ss.val[LANE(imm.lane, ss)]))); \ + return true; \ + } + EXTRACT_LANE_EXTEND_CASE(I16x8, i16x8, S, int32_t) + EXTRACT_LANE_EXTEND_CASE(I16x8, i16x8, U, uint32_t) + EXTRACT_LANE_EXTEND_CASE(I8x16, i8x16, S, int32_t) + EXTRACT_LANE_EXTEND_CASE(I8x16, i8x16, U, uint32_t) +#undef EXTRACT_LANE_EXTEND_CASE #define BINOP_CASE(op, name, stype, count, expr) \ case kExpr##op: { \ WasmValue v2 = Pop(); \ @@ -2317,8 +2371,10 @@ class ThreadImpl { } UNOP_CASE(F64x2Abs, f64x2, float2, 2, std::abs(a)) UNOP_CASE(F64x2Neg, f64x2, float2, 2, -a) + UNOP_CASE(F64x2Sqrt, f64x2, float2, 2, std::sqrt(a)) UNOP_CASE(F32x4Abs, f32x4, float4, 4, std::abs(a)) UNOP_CASE(F32x4Neg, f32x4, float4, 4, -a) + UNOP_CASE(F32x4Sqrt, f32x4, float4, 4, std::sqrt(a)) UNOP_CASE(F32x4RecipApprox, f32x4, float4, 4, base::Recip(a)) UNOP_CASE(F32x4RecipSqrtApprox, f32x4, float4, 4, base::RecipSqrt(a)) UNOP_CASE(I64x2Neg, i64x2, int2, 2, base::NegateWithWraparound(a)) @@ -2431,10 +2487,12 @@ class ThreadImpl { #undef REPLACE_LANE_CASE case kExprS128LoadMem: return ExecuteLoad<Simd128, Simd128>(decoder, code, pc, len, - MachineRepresentation::kSimd128); + MachineRepresentation::kSimd128, + /*prefix_len=*/1); case kExprS128StoreMem: return ExecuteStore<Simd128, Simd128>(decoder, code, pc, len, - MachineRepresentation::kSimd128); + MachineRepresentation::kSimd128, + /*prefix_len=*/1); #define SHIFT_CASE(op, name, stype, count, expr) \ case kExpr##op: { \ uint32_t shift = Pop().to<uint32_t>(); \ @@ -2448,19 +2506,26 @@ class ThreadImpl { Push(WasmValue(Simd128(res))); \ return true; \ } - SHIFT_CASE(I64x2Shl, i64x2, int2, 2, static_cast<uint64_t>(a) << shift) - SHIFT_CASE(I64x2ShrS, i64x2, int2, 2, a >> shift) - SHIFT_CASE(I64x2ShrU, i64x2, int2, 2, static_cast<uint64_t>(a) >> shift) - SHIFT_CASE(I32x4Shl, i32x4, int4, 4, static_cast<uint32_t>(a) << shift) - SHIFT_CASE(I32x4ShrS, i32x4, int4, 4, a >> shift) - SHIFT_CASE(I32x4ShrU, i32x4, int4, 4, static_cast<uint32_t>(a) >> shift) - SHIFT_CASE(I16x8Shl, i16x8, int8, 8, static_cast<uint16_t>(a) << shift) - SHIFT_CASE(I16x8ShrS, i16x8, int8, 8, a >> shift) - SHIFT_CASE(I16x8ShrU, i16x8, int8, 8, static_cast<uint16_t>(a) >> shift) - SHIFT_CASE(I8x16Shl, i8x16, int16, 16, static_cast<uint8_t>(a) << shift) - SHIFT_CASE(I8x16ShrS, i8x16, int16, 16, a >> shift) + SHIFT_CASE(I64x2Shl, i64x2, int2, 2, + static_cast<uint64_t>(a) << (shift % 64)) + SHIFT_CASE(I64x2ShrS, i64x2, int2, 2, a >> (shift % 64)) + SHIFT_CASE(I64x2ShrU, i64x2, int2, 2, + static_cast<uint64_t>(a) >> (shift % 64)) + SHIFT_CASE(I32x4Shl, i32x4, int4, 4, + static_cast<uint32_t>(a) << (shift % 32)) + SHIFT_CASE(I32x4ShrS, i32x4, int4, 4, a >> (shift % 32)) + SHIFT_CASE(I32x4ShrU, i32x4, int4, 4, + static_cast<uint32_t>(a) >> (shift % 32)) + SHIFT_CASE(I16x8Shl, i16x8, int8, 8, + static_cast<uint16_t>(a) << (shift % 16)) + SHIFT_CASE(I16x8ShrS, i16x8, int8, 8, a >> (shift % 16)) + SHIFT_CASE(I16x8ShrU, i16x8, int8, 8, + static_cast<uint16_t>(a) >> (shift % 16)) + SHIFT_CASE(I8x16Shl, i8x16, int16, 16, + static_cast<uint8_t>(a) << (shift % 8)) + SHIFT_CASE(I8x16ShrS, i8x16, int16, 16, a >> (shift % 8)) SHIFT_CASE(I8x16ShrU, i8x16, int16, 16, - static_cast<uint8_t>(a) >> shift) + static_cast<uint8_t>(a) >> (shift % 8)) #undef SHIFT_CASE #define CONVERT_CASE(op, src_type, name, dst_type, count, start_index, ctype, \ expr) \ @@ -2564,6 +2629,18 @@ class ThreadImpl { ADD_HORIZ_CASE(F32x4AddHoriz, f32x4, float4, 4) ADD_HORIZ_CASE(I16x8AddHoriz, i16x8, int8, 8) #undef ADD_HORIZ_CASE + case kExprS8x16Swizzle: { + int16 v2 = Pop().to_s128().to_i8x16(); + int16 v1 = Pop().to_s128().to_i8x16(); + int16 res; + for (size_t i = 0; i < kSimd128Size; ++i) { + int lane = v2.val[LANE(i, v1)]; + res.val[LANE(i, v1)] = + lane < kSimd128Size && lane >= 0 ? v1.val[LANE(lane, v1)] : 0; + } + Push(WasmValue(Simd128(res))); + return true; + } case kExprS8x16Shuffle: { Simd8x16ShuffleImmediate<Decoder::kNoValidate> imm(decoder, code->at(pc)); @@ -2604,6 +2681,23 @@ class ThreadImpl { REDUCTION_CASE(S1x8AllTrue, i16x8, int8, 8, &) REDUCTION_CASE(S1x16AllTrue, i8x16, int16, 16, &) #undef REDUCTION_CASE +#define QFM_CASE(op, name, stype, count, operation) \ + case kExpr##op: { \ + stype c = Pop().to_s128().to_##name(); \ + stype b = Pop().to_s128().to_##name(); \ + stype a = Pop().to_s128().to_##name(); \ + stype res; \ + for (size_t i = 0; i < count; i++) { \ + res.val[i] = a.val[i] operation(b.val[i] * c.val[i]); \ + } \ + Push(WasmValue(Simd128(res))); \ + return true; \ + } + QFM_CASE(F32x4Qfma, f32x4, float4, 4, +) + QFM_CASE(F32x4Qfms, f32x4, float4, 4, -) + QFM_CASE(F64x2Qfma, f64x2, float2, 2, +) + QFM_CASE(F64x2Qfms, f64x2, float2, 2, -) +#undef QFM_CASE default: return false; } @@ -2658,7 +2752,7 @@ class ThreadImpl { WasmExceptionTag::cast(instance_object_->exceptions_table().get(index)), isolate_); uint32_t encoded_size = WasmExceptionPackage::GetEncodedSize(exception); - Handle<Object> exception_object = + Handle<WasmExceptionPackage> exception_object = WasmExceptionPackage::New(isolate_, exception_tag, encoded_size); Handle<FixedArray> encoded_values = Handle<FixedArray>::cast( WasmExceptionPackage::GetExceptionValues(isolate_, exception_object)); @@ -2727,8 +2821,9 @@ class ThreadImpl { // Determines whether the given exception has a tag matching the expected tag // for the given index within the exception table of the current instance. bool MatchingExceptionTag(Handle<Object> exception_object, uint32_t index) { - Handle<Object> caught_tag = - WasmExceptionPackage::GetExceptionTag(isolate_, exception_object); + if (!exception_object->IsWasmExceptionPackage(isolate_)) return false; + Handle<Object> caught_tag = WasmExceptionPackage::GetExceptionTag( + isolate_, Handle<WasmExceptionPackage>::cast(exception_object)); Handle<Object> expected_tag = handle(instance_object_->exceptions_table().get(index), isolate_); DCHECK(expected_tag->IsWasmExceptionTag()); @@ -2755,8 +2850,9 @@ class ThreadImpl { // the encoded values match the expected signature of the exception. void DoUnpackException(const WasmException* exception, Handle<Object> exception_object) { - Handle<FixedArray> encoded_values = Handle<FixedArray>::cast( - WasmExceptionPackage::GetExceptionValues(isolate_, exception_object)); + Handle<FixedArray> encoded_values = + Handle<FixedArray>::cast(WasmExceptionPackage::GetExceptionValues( + isolate_, Handle<WasmExceptionPackage>::cast(exception_object))); // Decode the exception values from the given exception package and push // them onto the operand stack. This encoding has to be in sync with other // backends so that exceptions can be passed between them. @@ -3054,14 +3150,14 @@ class ThreadImpl { len = 1 + imm.length; break; } - case kExprGetLocal: { + case kExprLocalGet: { LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder, code->at(pc)); HandleScope handle_scope(isolate_); // Avoid leaking handles. Push(GetStackValue(frames_.back().sp + imm.index)); len = 1 + imm.length; break; } - case kExprSetLocal: { + case kExprLocalSet: { LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder, code->at(pc)); HandleScope handle_scope(isolate_); // Avoid leaking handles. WasmValue val = Pop(); @@ -3069,7 +3165,7 @@ class ThreadImpl { len = 1 + imm.length; break; } - case kExprTeeLocal: { + case kExprLocalTee: { LocalIndexImmediate<Decoder::kNoValidate> imm(&decoder, code->at(pc)); HandleScope handle_scope(isolate_); // Avoid leaking handles. WasmValue val = Pop(); @@ -3231,7 +3327,7 @@ class ThreadImpl { } } break; - case kExprGetGlobal: { + case kExprGlobalGet: { GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder, code->at(pc)); HandleScope handle_scope(isolate_); @@ -3239,7 +3335,7 @@ class ThreadImpl { len = 1 + imm.length; break; } - case kExprSetGlobal: { + case kExprGlobalSet: { GlobalIndexImmediate<Decoder::kNoValidate> imm(&decoder, code->at(pc)); const WasmGlobal* global = &module()->globals[imm.index]; @@ -3770,7 +3866,8 @@ class ThreadImpl { static WasmCode* GetTargetCode(Isolate* isolate, Address target) { WasmCodeManager* code_manager = isolate->wasm_engine()->code_manager(); NativeModule* native_module = code_manager->LookupNativeModule(target); - if (native_module->is_jump_table_slot(target)) { + WasmCode* code = native_module->Lookup(target); + if (code->kind() == WasmCode::kJumpTable) { uint32_t func_index = native_module->GetFunctionIndexFromJumpTableSlot(target); @@ -3784,7 +3881,6 @@ class ThreadImpl { return native_module->GetCode(func_index); } - WasmCode* code = native_module->Lookup(target); DCHECK_EQ(code->instruction_start(), target); return code; } @@ -3888,12 +3984,14 @@ class InterpretedFrameImpl { } WasmValue GetLocalValue(int index) const { + ThreadImpl::ReferenceStackScope stack_scope(thread_); DCHECK_LE(0, index); DCHECK_GT(GetLocalCount(), index); return thread_->GetStackValue(static_cast<int>(frame()->sp) + index); } WasmValue GetStackValue(int index) const { + ThreadImpl::ReferenceStackScope stack_scope(thread_); DCHECK_LE(0, index); // Index must be within the number of stack values of this frame. DCHECK_GT(GetStackHeight(), index); @@ -3941,21 +4039,33 @@ const InterpretedFrameImpl* ToImpl(const InterpretedFrame* frame) { // translation unit anyway. //============================================================================ WasmInterpreter::State WasmInterpreter::Thread::state() { - return ToImpl(this)->state(); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->state(); } void WasmInterpreter::Thread::InitFrame(const WasmFunction* function, WasmValue* args) { - ToImpl(this)->InitFrame(function, args); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + impl->InitFrame(function, args); } WasmInterpreter::State WasmInterpreter::Thread::Run(int num_steps) { - return ToImpl(this)->Run(num_steps); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->Run(num_steps); } void WasmInterpreter::Thread::Pause() { return ToImpl(this)->Pause(); } -void WasmInterpreter::Thread::Reset() { return ToImpl(this)->Reset(); } +void WasmInterpreter::Thread::Reset() { + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->Reset(); +} WasmInterpreter::Thread::ExceptionHandlingResult WasmInterpreter::Thread::RaiseException(Isolate* isolate, Handle<Object> exception) { - return ToImpl(this)->RaiseException(isolate, exception); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->RaiseException(isolate, exception); } pc_t WasmInterpreter::Thread::GetBreakpointPc() { return ToImpl(this)->GetBreakpointPc(); @@ -3969,7 +4079,9 @@ WasmInterpreter::FramePtr WasmInterpreter::Thread::GetFrame(int index) { return FramePtr(ToFrame(new InterpretedFrameImpl(ToImpl(this), index))); } WasmValue WasmInterpreter::Thread::GetReturnValue(int index) { - return ToImpl(this)->GetReturnValue(index); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->GetReturnValue(index); } TrapReason WasmInterpreter::Thread::GetTrapReason() { return ToImpl(this)->GetTrapReason(); @@ -3996,41 +4108,38 @@ uint32_t WasmInterpreter::Thread::NumActivations() { return ToImpl(this)->NumActivations(); } uint32_t WasmInterpreter::Thread::StartActivation() { - return ToImpl(this)->StartActivation(); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->StartActivation(); } void WasmInterpreter::Thread::FinishActivation(uint32_t id) { - ToImpl(this)->FinishActivation(id); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + impl->FinishActivation(id); } uint32_t WasmInterpreter::Thread::ActivationFrameBase(uint32_t id) { - return ToImpl(this)->ActivationFrameBase(id); + ThreadImpl* impl = ToImpl(this); + ThreadImpl::ReferenceStackScope stack_scope(impl); + return impl->ActivationFrameBase(id); } //============================================================================ // The implementation details of the interpreter. //============================================================================ -class WasmInterpreterInternals : public ZoneObject { +class WasmInterpreterInternals { public: // Create a copy of the module bytes for the interpreter, since the passed // pointer might be invalidated after constructing the interpreter. const ZoneVector<uint8_t> module_bytes_; CodeMap codemap_; - ZoneVector<ThreadImpl> threads_; + std::vector<ThreadImpl> threads_; WasmInterpreterInternals(Zone* zone, const WasmModule* module, const ModuleWireBytes& wire_bytes, Handle<WasmInstanceObject> instance_object) : module_bytes_(wire_bytes.start(), wire_bytes.end(), zone), - codemap_(module, module_bytes_.data(), zone), - threads_(zone) { - Isolate* isolate = instance_object->GetIsolate(); - Handle<Cell> reference_stack = isolate->global_handles()->Create( - *isolate->factory()->NewCell(isolate->factory()->empty_fixed_array())); - threads_.emplace_back(zone, &codemap_, instance_object, reference_stack); - } - - ~WasmInterpreterInternals() { - DCHECK_EQ(1, threads_.size()); - GlobalHandles::Destroy(threads_[0].reference_stack_cell().location()); + codemap_(module, module_bytes_.data(), zone) { + threads_.emplace_back(zone, &codemap_, instance_object); } }; @@ -4059,10 +4168,12 @@ WasmInterpreter::WasmInterpreter(Isolate* isolate, const WasmModule* module, const ModuleWireBytes& wire_bytes, Handle<WasmInstanceObject> instance_object) : zone_(isolate->allocator(), ZONE_NAME), - internals_(new (&zone_) WasmInterpreterInternals( + internals_(new WasmInterpreterInternals( &zone_, module, wire_bytes, MakeWeak(isolate, instance_object))) {} -WasmInterpreter::~WasmInterpreter() { internals_->~WasmInterpreterInternals(); } +// The destructor is here so we can forward declare {WasmInterpreterInternals} +// used in the {unique_ptr} in the header. +WasmInterpreter::~WasmInterpreter() {} void WasmInterpreter::Run() { internals_->threads_[0].Run(); } diff --git a/deps/v8/src/wasm/wasm-interpreter.h b/deps/v8/src/wasm/wasm-interpreter.h index da0ce01835c417..e0a32c71d65dcb 100644 --- a/deps/v8/src/wasm/wasm-interpreter.h +++ b/deps/v8/src/wasm/wasm-interpreter.h @@ -5,6 +5,8 @@ #ifndef V8_WASM_WASM_INTERPRETER_H_ #define V8_WASM_WASM_INTERPRETER_H_ +#include <memory> + #include "src/wasm/wasm-opcodes.h" #include "src/wasm/wasm-value.h" #include "src/zone/zone-containers.h" @@ -131,7 +133,7 @@ class V8_EXPORT_PRIVATE WasmInterpreter { // Stack inspection and modification. pc_t GetBreakpointPc(); - // TODO(clemensh): Make this uint32_t. + // TODO(clemensb): Make this uint32_t. int GetFrameCount(); // The InterpretedFrame is only valid as long as the Thread is paused. FramePtr GetFrame(int index); @@ -173,6 +175,7 @@ class V8_EXPORT_PRIVATE WasmInterpreter { WasmInterpreter(Isolate* isolate, const WasmModule* module, const ModuleWireBytes& wire_bytes, Handle<WasmInstanceObject> instance); + ~WasmInterpreter(); //========================================================================== @@ -214,7 +217,9 @@ class V8_EXPORT_PRIVATE WasmInterpreter { private: Zone zone_; - WasmInterpreterInternals* internals_; + std::unique_ptr<WasmInterpreterInternals> internals_; + + DISALLOW_COPY_AND_ASSIGN(WasmInterpreter); }; } // namespace wasm diff --git a/deps/v8/src/wasm/wasm-js.cc b/deps/v8/src/wasm/wasm-js.cc index f10f5ff2bfecb8..80d2fcb0590328 100644 --- a/deps/v8/src/wasm/wasm-js.cc +++ b/deps/v8/src/wasm/wasm-js.cc @@ -26,7 +26,6 @@ #include "src/wasm/streaming-decoder.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-limits.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-serialization.h" @@ -207,20 +206,20 @@ i::wasm::ModuleWireBytes GetFirstArgumentAsBytes( if (source->IsArrayBuffer()) { // A raw array buffer was passed. Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); - ArrayBuffer::Contents contents = buffer->GetContents(); + auto backing_store = buffer->GetBackingStore(); - start = reinterpret_cast<const uint8_t*>(contents.Data()); - length = contents.ByteLength(); + start = reinterpret_cast<const uint8_t*>(backing_store->Data()); + length = backing_store->ByteLength(); *is_shared = buffer->IsSharedArrayBuffer(); } else if (source->IsTypedArray()) { // A TypedArray was passed. Local<TypedArray> array = Local<TypedArray>::Cast(source); Local<ArrayBuffer> buffer = array->Buffer(); - ArrayBuffer::Contents contents = buffer->GetContents(); + auto backing_store = buffer->GetBackingStore(); - start = - reinterpret_cast<const uint8_t*>(contents.Data()) + array->ByteOffset(); + start = reinterpret_cast<const uint8_t*>(backing_store->Data()) + + array->ByteOffset(); length = array->ByteLength(); *is_shared = buffer->IsSharedArrayBuffer(); } else { @@ -434,8 +433,8 @@ class AsyncInstantiateCompileResultResolver finished_ = true; isolate_->wasm_engine()->AsyncInstantiate( isolate_, - base::make_unique<InstantiateBytesResultResolver>(isolate_, promise_, - result), + std::make_unique<InstantiateBytesResultResolver>(isolate_, promise_, + result), result, maybe_imports_); } @@ -597,7 +596,7 @@ void WebAssemblyCompileStreaming( i::Handle<i::Managed<WasmStreaming>> data = i::Managed<WasmStreaming>::Allocate( i_isolate, 0, - base::make_unique<WasmStreaming::WasmStreamingImpl>( + std::make_unique<WasmStreaming::WasmStreamingImpl>( isolate, kAPIMethodName, resolver)); DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback()); @@ -876,7 +875,7 @@ void WebAssemblyInstantiateStreaming( i::Handle<i::Managed<WasmStreaming>> data = i::Managed<WasmStreaming>::Allocate( i_isolate, 0, - base::make_unique<WasmStreaming::WasmStreamingImpl>( + std::make_unique<WasmStreaming::WasmStreamingImpl>( isolate, kAPIMethodName, compilation_resolver)); DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback()); @@ -1156,7 +1155,7 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { return; } - bool is_shared_memory = false; + auto shared = i::SharedFlag::kNotShared; auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate); if (enabled_features.threads) { // Shared property of descriptor @@ -1165,10 +1164,11 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { descriptor->Get(context, shared_key); v8::Local<v8::Value> value; if (maybe_value.ToLocal(&value)) { - is_shared_memory = value->BooleanValue(isolate); + shared = value->BooleanValue(isolate) ? i::SharedFlag::kShared + : i::SharedFlag::kNotShared; } // Throw TypeError if shared is true, and the descriptor has no "maximum" - if (is_shared_memory && maximum == -1) { + if (shared == i::SharedFlag::kShared && maximum == -1) { thrower.TypeError( "If shared is true, maximum property should be defined."); return; @@ -1177,13 +1177,12 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { i::Handle<i::JSObject> memory_obj; if (!i::WasmMemoryObject::New(i_isolate, static_cast<uint32_t>(initial), - static_cast<uint32_t>(maximum), - is_shared_memory) + static_cast<uint32_t>(maximum), shared) .ToHandle(&memory_obj)) { thrower.RangeError("could not allocate memory"); return; } - if (is_shared_memory) { + if (shared == i::SharedFlag::kShared) { i::Handle<i::JSArrayBuffer> buffer( i::Handle<i::WasmMemoryObject>::cast(memory_obj)->array_buffer(), i_isolate); @@ -2034,8 +2033,8 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { JSFunction::EnsureHasInitialMap(module_constructor); Handle<JSObject> module_proto( JSObject::cast(module_constructor->instance_prototype()), isolate); - Handle<Map> module_map = - isolate->factory()->NewMap(i::WASM_MODULE_TYPE, WasmModuleObject::kSize); + Handle<Map> module_map = isolate->factory()->NewMap( + i::WASM_MODULE_OBJECT_TYPE, WasmModuleObject::kSize); JSFunction::SetInitialMap(module_constructor, module_map, module_proto); InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports, 1); @@ -2055,7 +2054,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { Handle<JSObject> instance_proto( JSObject::cast(instance_constructor->instance_prototype()), isolate); Handle<Map> instance_map = isolate->factory()->NewMap( - i::WASM_INSTANCE_TYPE, WasmInstanceObject::kSize); + i::WASM_INSTANCE_OBJECT_TYPE, WasmInstanceObject::kSize); JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto); InstallGetter(isolate, instance_proto, "exports", WebAssemblyInstanceGetExports); @@ -2075,8 +2074,8 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { JSFunction::EnsureHasInitialMap(table_constructor); Handle<JSObject> table_proto( JSObject::cast(table_constructor->instance_prototype()), isolate); - Handle<Map> table_map = - isolate->factory()->NewMap(i::WASM_TABLE_TYPE, WasmTableObject::kSize); + Handle<Map> table_map = isolate->factory()->NewMap(i::WASM_TABLE_OBJECT_TYPE, + WasmTableObject::kSize); JSFunction::SetInitialMap(table_constructor, table_map, table_proto); InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1); @@ -2096,8 +2095,8 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { JSFunction::EnsureHasInitialMap(memory_constructor); Handle<JSObject> memory_proto( JSObject::cast(memory_constructor->instance_prototype()), isolate); - Handle<Map> memory_map = - isolate->factory()->NewMap(i::WASM_MEMORY_TYPE, WasmMemoryObject::kSize); + Handle<Map> memory_map = isolate->factory()->NewMap( + i::WASM_MEMORY_OBJECT_TYPE, WasmMemoryObject::kSize); JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto); InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1); InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); @@ -2115,8 +2114,8 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { JSFunction::EnsureHasInitialMap(global_constructor); Handle<JSObject> global_proto( JSObject::cast(global_constructor->instance_prototype()), isolate); - Handle<Map> global_map = - isolate->factory()->NewMap(i::WASM_GLOBAL_TYPE, WasmGlobalObject::kSize); + Handle<Map> global_map = isolate->factory()->NewMap( + i::WASM_GLOBAL_OBJECT_TYPE, WasmGlobalObject::kSize); JSFunction::SetInitialMap(global_constructor, global_map, global_proto); InstallFunc(isolate, global_proto, "valueOf", WebAssemblyGlobalValueOf, 0); InstallGetterSetter(isolate, global_proto, "value", WebAssemblyGlobalGetValue, @@ -2137,7 +2136,7 @@ void WasmJs::Install(Isolate* isolate, bool exposed_on_global_object) { Handle<JSObject> exception_proto( JSObject::cast(exception_constructor->instance_prototype()), isolate); Handle<Map> exception_map = isolate->factory()->NewMap( - i::WASM_EXCEPTION_TYPE, WasmExceptionObject::kSize); + i::WASM_EXCEPTION_OBJECT_TYPE, WasmExceptionObject::kSize); JSFunction::SetInitialMap(exception_constructor, exception_map, exception_proto); } diff --git a/deps/v8/src/wasm/wasm-limits.h b/deps/v8/src/wasm/wasm-limits.h index c7c95aca26bec8..6dc652aba2da8d 100644 --- a/deps/v8/src/wasm/wasm-limits.h +++ b/deps/v8/src/wasm/wasm-limits.h @@ -36,6 +36,7 @@ constexpr size_t kV8MaxWasmFunctionLocals = 50000; constexpr size_t kV8MaxWasmFunctionParams = 1000; constexpr size_t kV8MaxWasmFunctionMultiReturns = 1000; constexpr size_t kV8MaxWasmFunctionReturns = 1; +constexpr size_t kV8MaxWasmFunctionBrTableSize = 65520; // Don't use this limit directly, but use the value of FLAG_wasm_max_table_size. constexpr size_t kV8MaxWasmTableSize = 10000000; constexpr size_t kV8MaxWasmTableInitEntries = 10000000; diff --git a/deps/v8/src/wasm/wasm-memory.cc b/deps/v8/src/wasm/wasm-memory.cc index f2036495425059..bbb0d67f9c3f42 100644 --- a/deps/v8/src/wasm/wasm-memory.cc +++ b/deps/v8/src/wasm/wasm-memory.cc @@ -566,7 +566,7 @@ MaybeHandle<JSArrayBuffer> AllocateAndSetupArrayBuffer(Isolate* isolate, WasmMemoryTracker* memory_tracker = isolate->wasm_engine()->memory_tracker(); - // Set by TryAllocateBackingStore or GetEmptyBackingStore + // Set by TryAllocateBackingStore. void* allocation_base = nullptr; size_t allocation_length = 0; diff --git a/deps/v8/src/wasm/wasm-memory.h b/deps/v8/src/wasm/wasm-memory.h deleted file mode 100644 index ecb6203ac5aba5..00000000000000 --- a/deps/v8/src/wasm/wasm-memory.h +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2017 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_WASM_WASM_MEMORY_H_ -#define V8_WASM_WASM_MEMORY_H_ - -#include <atomic> -#include <unordered_map> -#include <unordered_set> - -#include "src/base/platform/mutex.h" -#include "src/flags/flags.h" -#include "src/handles/handles.h" -#include "src/objects/js-array-buffer.h" - -namespace v8 { -namespace internal { -namespace wasm { - -// The {WasmMemoryTracker} tracks reservations and allocations for wasm memory -// and wasm code. There is an upper limit on the total reserved memory which is -// checked by this class. Allocations are stored so we can look them up when an -// array buffer dies and figure out the reservation and allocation bounds for -// that buffer. -class WasmMemoryTracker { - public: - WasmMemoryTracker() = default; - V8_EXPORT_PRIVATE ~WasmMemoryTracker(); - - // ReserveAddressSpace attempts to increase the reserved address space counter - // by {num_bytes}. Returns true if successful (meaning it is okay to go ahead - // and reserve {num_bytes} bytes), false otherwise. - bool ReserveAddressSpace(size_t num_bytes); - - void RegisterAllocation(Isolate* isolate, void* allocation_base, - size_t allocation_length, void* buffer_start, - size_t buffer_length); - - struct SharedMemoryObjectState { - Handle<WasmMemoryObject> memory_object; - Isolate* isolate; - - SharedMemoryObjectState() = default; - SharedMemoryObjectState(Handle<WasmMemoryObject> memory_object, - Isolate* isolate) - : memory_object(memory_object), isolate(isolate) {} - }; - - struct AllocationData { - void* allocation_base = nullptr; - size_t allocation_length = 0; - void* buffer_start = nullptr; - size_t buffer_length = 0; - bool is_shared = false; - // Wasm memories are growable by default, this will be false only when - // shared with an asmjs module. - bool is_growable = true; - - // Track Wasm Memory instances across isolates, this is populated on - // PostMessage using persistent handles for memory objects. - std::vector<WasmMemoryTracker::SharedMemoryObjectState> - memory_object_vector; - - private: - AllocationData() = default; - AllocationData(void* allocation_base, size_t allocation_length, - void* buffer_start, size_t buffer_length) - : allocation_base(allocation_base), - allocation_length(allocation_length), - buffer_start(buffer_start), - buffer_length(buffer_length) { - DCHECK_LE(reinterpret_cast<uintptr_t>(allocation_base), - reinterpret_cast<uintptr_t>(buffer_start)); - DCHECK_GE( - reinterpret_cast<uintptr_t>(allocation_base) + allocation_length, - reinterpret_cast<uintptr_t>(buffer_start)); - DCHECK_GE( - reinterpret_cast<uintptr_t>(allocation_base) + allocation_length, - reinterpret_cast<uintptr_t>(buffer_start) + buffer_length); - } - - friend WasmMemoryTracker; - }; - - // Allow tests to allocate a backing store the same way as we do it for - // WebAssembly memory. This is used in unit tests for trap handler to - // generate the same signals/exceptions for invalid memory accesses as - // we would get with WebAssembly memory. - V8_EXPORT_PRIVATE void* TryAllocateBackingStoreForTesting( - Heap* heap, size_t size, void** allocation_base, - size_t* allocation_length); - - // Free memory allocated with TryAllocateBackingStoreForTesting. - V8_EXPORT_PRIVATE void FreeBackingStoreForTesting(base::AddressRegion memory, - void* buffer_start); - - // Decreases the amount of reserved address space. - void ReleaseReservation(size_t num_bytes); - - V8_EXPORT_PRIVATE bool IsWasmMemory(const void* buffer_start); - - bool IsWasmSharedMemory(const void* buffer_start); - - // Returns a pointer to a Wasm buffer's allocation data, or nullptr if the - // buffer is not tracked. - V8_EXPORT_PRIVATE const AllocationData* FindAllocationData( - const void* buffer_start); - - // Free Memory allocated by the Wasm memory tracker - bool FreeWasmMemory(Isolate* isolate, const void* buffer_start); - - void MarkWasmMemoryNotGrowable(Handle<JSArrayBuffer> buffer); - - bool IsWasmMemoryGrowable(Handle<JSArrayBuffer> buffer); - - // When WebAssembly.Memory is transferred over PostMessage, register the - // allocation as shared and track the memory objects that will need - // updating if memory is resized. - void RegisterWasmMemoryAsShared(Handle<WasmMemoryObject> object, - Isolate* isolate); - - // This method is called when the underlying backing store is grown, but - // instances that share the backing_store have not yet been updated. - void SetPendingUpdateOnGrow(Handle<JSArrayBuffer> old_buffer, - size_t new_size); - - // Interrupt handler for GROW_SHARED_MEMORY interrupt. Update memory objects - // and instances that share the memory objects after a Grow call. - void UpdateSharedMemoryInstances(Isolate* isolate); - - // Due to timing of when buffers are garbage collected, vs. when isolate - // object handles are destroyed, it is possible to leak global handles. To - // avoid this, cleanup any global handles on isolate destruction if any exist. - void DeleteSharedMemoryObjectsOnIsolate(Isolate* isolate); - - // Allocation results are reported to UMA - // - // See wasm_memory_allocation_result in counters.h - enum class AllocationStatus { - kSuccess, // Succeeded on the first try - - kSuccessAfterRetry, // Succeeded after garbage collection - - kAddressSpaceLimitReachedFailure, // Failed because Wasm is at its address - // space limit - - kOtherFailure // Failed for an unknown reason - }; - - private: - // Helper methods to free memory only if not shared by other isolates, memory - // objects. - void FreeMemoryIfNotShared_Locked(Isolate* isolate, - const void* backing_store); - bool CanFreeSharedMemory_Locked(const void* backing_store); - void RemoveSharedBufferState_Locked(Isolate* isolate, - const void* backing_store); - - // Registers the allocation as shared, and tracks all the memory objects - // associates with this allocation across isolates. - void RegisterSharedWasmMemory_Locked(Handle<WasmMemoryObject> object, - Isolate* isolate); - - // Map the new size after grow to the buffer backing store, so that instances - // and memory objects that share the WebAssembly.Memory across isolates can - // be updated.. - void AddBufferToGrowMap_Locked(Handle<JSArrayBuffer> old_buffer, - size_t new_size); - - // Trigger a GROW_SHARED_MEMORY interrupt on all the isolates that have memory - // objects that share this buffer. - void TriggerSharedGrowInterruptOnAllIsolates_Locked( - Handle<JSArrayBuffer> old_buffer); - - // When isolates hit a stack check, update the memory objects associated with - // that isolate. - void UpdateSharedMemoryStateOnInterrupt_Locked(Isolate* isolate, - void* backing_store, - size_t new_size); - - // Check if all the isolates that share a backing_store have hit a stack - // check. If a stack check is hit, and the backing store is pending grow, - // this isolate will have updated memory objects. - bool AreAllIsolatesUpdated_Locked(const void* backing_store); - - // If a grow call is made to a buffer with a pending grow, and all the - // isolates that share this buffer have not hit a StackCheck, clear the set of - // already updated instances so they can be updated with the new size on the - // most recent grow call. - void ClearUpdatedInstancesOnPendingGrow_Locked(const void* backing_store); - - // Helper functions to update memory objects on grow, and maintain state for - // which isolates hit a stack check. - void UpdateMemoryObjectsForIsolate_Locked(Isolate* isolate, - void* backing_store, - size_t new_size); - bool MemoryObjectsNeedUpdate_Locked(Isolate* isolate, - const void* backing_store); - - // Destroy global handles to memory objects, and remove backing store from - // isolates_per_buffer on Free. - void DestroyMemoryObjectsAndRemoveIsolateEntry_Locked( - Isolate* isolate, const void* backing_store); - void DestroyMemoryObjectsAndRemoveIsolateEntry_Locked( - const void* backing_store); - - void RemoveIsolateFromBackingStore_Locked(Isolate* isolate, - const void* backing_store); - - // Removes an allocation from the tracker. - AllocationData ReleaseAllocation_Locked(Isolate* isolate, - const void* buffer_start); - - // Clients use a two-part process. First they "reserve" the address space, - // which signifies an intent to actually allocate it. This determines whether - // doing the allocation would put us over our limit. Once there is a - // reservation, clients can do the allocation and register the result. - // - // We should always have: - // allocated_address_space_ <= reserved_address_space_ <= kAddressSpaceLimit - std::atomic<size_t> reserved_address_space_{0}; - - // Used to protect access to the allocated address space counter and - // allocation map. This is needed because Wasm memories can be freed on - // another thread by the ArrayBufferTracker. - base::Mutex mutex_; - - size_t allocated_address_space_ = 0; - - ////////////////////////////////////////////////////////////////////////////// - // Protected by {mutex_}: - - // Track Wasm memory allocation information. This is keyed by the start of the - // buffer, rather than by the start of the allocation. - std::unordered_map<const void*, AllocationData> allocations_; - - // Maps each buffer to the isolates that share the backing store. - std::unordered_map<const void*, std::unordered_set<Isolate*>> - isolates_per_buffer_; - - // Maps which isolates have had a grow interrupt handled on the buffer. This - // is maintained to ensure that the instances are updated with the right size - // on Grow. - std::unordered_map<const void*, std::unordered_set<Isolate*>> - isolates_updated_on_grow_; - - // Maps backing stores(void*) to the size of the underlying memory in - // (size_t). An entry to this map is made on a grow call to the corresponding - // backing store. On consecutive grow calls to the same backing store, - // the size entry is updated. This entry is made right after the mprotect - // call to change the protections on a backing_store, so the memory objects - // have not been updated yet. The backing store entry in this map is erased - // when all the memory objects, or instances that share this backing store - // have their bounds updated. - std::unordered_map<void*, size_t> grow_update_map_; - - // End of fields protected by {mutex_}. - ////////////////////////////////////////////////////////////////////////////// - - DISALLOW_COPY_AND_ASSIGN(WasmMemoryTracker); -}; - -// Attempts to allocate an array buffer with guard regions suitable for trap -// handling. If address space is not available, it will return a buffer with -// mini-guards that will require bounds checks. -V8_EXPORT_PRIVATE MaybeHandle<JSArrayBuffer> NewArrayBuffer(Isolate*, - size_t size); - -// Attempts to allocate a SharedArrayBuffer with guard regions suitable for -// trap handling. If address space is not available, it will try to reserve -// up to the maximum for that memory. If all else fails, it will return a -// buffer with mini-guards of initial size. -V8_EXPORT_PRIVATE MaybeHandle<JSArrayBuffer> NewSharedArrayBuffer( - Isolate*, size_t initial_size, size_t max_size); - -Handle<JSArrayBuffer> SetupArrayBuffer( - Isolate*, void* backing_store, size_t size, bool is_external, - SharedFlag shared = SharedFlag::kNotShared); - -V8_EXPORT_PRIVATE void DetachMemoryBuffer(Isolate* isolate, - Handle<JSArrayBuffer> buffer, - bool free_memory); - -} // namespace wasm -} // namespace internal -} // namespace v8 - -#endif // V8_WASM_WASM_MEMORY_H_ diff --git a/deps/v8/src/wasm/wasm-module-builder.cc b/deps/v8/src/wasm/wasm-module-builder.cc index d3874e1a3447d3..0bbc104070d5b0 100644 --- a/deps/v8/src/wasm/wasm-module-builder.cc +++ b/deps/v8/src/wasm/wasm-module-builder.cc @@ -71,15 +71,15 @@ uint32_t WasmFunctionBuilder::AddLocal(ValueType type) { } void WasmFunctionBuilder::EmitGetLocal(uint32_t local_index) { - EmitWithU32V(kExprGetLocal, local_index); + EmitWithU32V(kExprLocalGet, local_index); } void WasmFunctionBuilder::EmitSetLocal(uint32_t local_index) { - EmitWithU32V(kExprSetLocal, local_index); + EmitWithU32V(kExprLocalSet, local_index); } void WasmFunctionBuilder::EmitTeeLocal(uint32_t local_index) { - EmitWithU32V(kExprTeeLocal, local_index); + EmitWithU32V(kExprLocalTee, local_index); } void WasmFunctionBuilder::EmitCode(const byte* code, uint32_t code_size) { @@ -505,7 +505,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer* buffer) const { buffer->write_f64(global.init.val.f64_const); break; case WasmInitExpr::kGlobalIndex: - buffer->write_u8(kExprGetGlobal); + buffer->write_u8(kExprGlobalGet); buffer->write_u32v(global.init.val.global_index); break; case WasmInitExpr::kRefNullConst: diff --git a/deps/v8/src/wasm/wasm-module.cc b/deps/v8/src/wasm/wasm-module.cc index 5a10368a8b6f16..033f12ae24154a 100644 --- a/deps/v8/src/wasm/wasm-module.cc +++ b/deps/v8/src/wasm/wasm-module.cc @@ -22,6 +22,7 @@ #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-result.h" +#include "src/wasm/wasm-text.h" namespace v8 { namespace internal { @@ -58,6 +59,57 @@ int GetExportWrapperIndex(const WasmModule* module, const FunctionSig* sig, return result; } +// static +int GetWasmFunctionOffset(const WasmModule* module, uint32_t func_index) { + const std::vector<WasmFunction>& functions = module->functions; + if (static_cast<uint32_t>(func_index) >= functions.size()) return -1; + DCHECK_GE(kMaxInt, functions[func_index].code.offset()); + return static_cast<int>(functions[func_index].code.offset()); +} + +// static +int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset) { + const std::vector<WasmFunction>& functions = module->functions; + + // Binary search for a function containing the given position. + int left = 0; // inclusive + int right = static_cast<int>(functions.size()); // exclusive + if (right == 0) return false; + while (right - left > 1) { + int mid = left + (right - left) / 2; + if (functions[mid].code.offset() <= byte_offset) { + left = mid; + } else { + right = mid; + } + } + // If the found function does not contains the given position, return -1. + const WasmFunction& func = functions[left]; + if (byte_offset < func.code.offset() || + byte_offset >= func.code.end_offset()) { + return -1; + } + + return left; +} + +// static +v8::debug::WasmDisassembly DisassembleWasmFunction( + const WasmModule* module, const ModuleWireBytes& wire_bytes, + int func_index) { + if (func_index < 0 || + static_cast<uint32_t>(func_index) >= module->functions.size()) + return {}; + + std::ostringstream disassembly_os; + v8::debug::WasmDisassembly::OffsetTable offset_table; + + PrintWasmText(module, wire_bytes, static_cast<uint32_t>(func_index), + disassembly_os, &offset_table); + + return {disassembly_os.str(), std::move(offset_table)}; +} + void WasmModule::AddFunctionNameForTesting(int function_index, WireBytesRef name) { if (!function_names) { @@ -475,21 +527,19 @@ Handle<JSArray> GetCustomSections(Isolate* isolate, // Make a copy of the payload data in the section. size_t size = section.payload.length(); - void* memory = - size == 0 ? nullptr : isolate->array_buffer_allocator()->Allocate(size); - - if (size && !memory) { + MaybeHandle<JSArrayBuffer> result = + isolate->factory()->NewJSArrayBufferAndBackingStore( + size, InitializedFlag::kUninitialized); + Handle<JSArrayBuffer> array_buffer; + if (!result.ToHandle(&array_buffer)) { thrower->RangeError("out of memory allocating custom section data"); return Handle<JSArray>(); } - Handle<JSArrayBuffer> buffer = - isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - constexpr bool is_external = false; - JSArrayBuffer::Setup(buffer, isolate, is_external, memory, size); - memcpy(memory, wire_bytes.begin() + section.payload.offset(), + memcpy(array_buffer->backing_store(), + wire_bytes.begin() + section.payload.offset(), section.payload.length()); - matching_sections.push_back(buffer); + matching_sections.push_back(array_buffer); } int num_custom_sections = static_cast<int>(matching_sections.size()); diff --git a/deps/v8/src/wasm/wasm-module.h b/deps/v8/src/wasm/wasm-module.h index 69c57725de3c87..79c3b23a33298f 100644 --- a/deps/v8/src/wasm/wasm-module.h +++ b/deps/v8/src/wasm/wasm-module.h @@ -16,9 +16,13 @@ #include "src/wasm/wasm-opcodes.h" namespace v8 { + +namespace debug { +struct WasmDisassembly; +} + namespace internal { -class WasmDebugInfo; class WasmModuleObject; namespace wasm { @@ -240,6 +244,25 @@ V8_EXPORT_PRIVATE int MaxNumExportWrappers(const WasmModule* module); int GetExportWrapperIndex(const WasmModule* module, const FunctionSig* sig, bool is_import); +// Return the byte offset of the function identified by the given index. +// The offset will be relative to the start of the module bytes. +// Returns -1 if the function index is invalid. +int GetWasmFunctionOffset(const WasmModule* module, uint32_t func_index); + +// Returns the function containing the given byte offset. +// Returns -1 if the byte offset is not contained in any function of this +// module. +int GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset); + +// Compute the disassembly of a wasm function. +// Returns the disassembly string and a list of <byte_offset, line, column> +// entries, mapping wasm byte offsets to line and column in the disassembly. +// The list is guaranteed to be ordered by the byte_offset. +// Returns an empty string and empty vector if the function index is invalid. +V8_EXPORT_PRIVATE debug::WasmDisassembly DisassembleWasmFunction( + const WasmModule* module, const ModuleWireBytes& wire_bytes, + int func_index); + // Interface to the storage (wire bytes) of a wasm module. // It is illegal for anyone receiving a ModuleWireBytes to store pointers based // on module_bytes, as this storage is only guaranteed to be alive as long as @@ -290,15 +313,6 @@ struct WasmFunctionName { std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name); -// Get the debug info associated with the given wasm object. -// If no debug info exists yet, it is created automatically. -Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm); - -V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes( - Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower, - ModuleOrigin origin, Handle<Script> asm_js_script, - Vector<const byte> asm_offset_table); - V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate, Handle<Context> context); diff --git a/deps/v8/src/wasm/wasm-objects-inl.h b/deps/v8/src/wasm/wasm-objects-inl.h index 66d3a2716e99b0..a7f74381ae9c70 100644 --- a/deps/v8/src/wasm/wasm-objects-inl.h +++ b/deps/v8/src/wasm/wasm-objects-inl.h @@ -88,12 +88,8 @@ ACCESSORS(WasmModuleObject, managed_native_module, Managed<wasm::NativeModule>, kNativeModuleOffset) ACCESSORS(WasmModuleObject, export_wrappers, FixedArray, kExportWrappersOffset) ACCESSORS(WasmModuleObject, script, Script, kScriptOffset) -ACCESSORS(WasmModuleObject, weak_instance_list, WeakArrayList, - kWeakInstanceListOffset) OPTIONAL_ACCESSORS(WasmModuleObject, asm_js_offset_table, ByteArray, kAsmJsOffsetTableOffset) -OPTIONAL_ACCESSORS(WasmModuleObject, breakpoint_infos, FixedArray, - kBreakPointInfosOffset) wasm::NativeModule* WasmModuleObject::native_module() const { return managed_native_module().raw(); } @@ -102,13 +98,9 @@ WasmModuleObject::shared_native_module() const { return managed_native_module().get(); } const wasm::WasmModule* WasmModuleObject::module() const { - // TODO(clemensh): Remove this helper (inline in callers). + // TODO(clemensb): Remove this helper (inline in callers). return native_module()->module(); } -void WasmModuleObject::reset_breakpoint_infos() { - WRITE_FIELD(*this, kBreakPointInfosOffset, - GetReadOnlyRoots().undefined_value()); -} bool WasmModuleObject::is_asm_js() { bool asm_js = is_asmjs_module(module()); DCHECK_EQ(asm_js, script().IsUserJavaScript()); @@ -309,6 +301,10 @@ ACCESSORS(WasmExceptionObject, serialized_signature, PodArray<wasm::ValueType>, kSerializedSignatureOffset) ACCESSORS(WasmExceptionObject, exception_tag, HeapObject, kExceptionTagOffset) +// WasmExceptionPackage +OBJECT_CONSTRUCTORS_IMPL(WasmExceptionPackage, JSReceiver) +CAST_ACCESSOR(WasmExceptionPackage) + // WasmExportedFunction WasmExportedFunction::WasmExportedFunction(Address ptr) : JSFunction(ptr) { SLOW_DCHECK(IsWasmExportedFunction(*this)); @@ -382,6 +378,8 @@ ACCESSORS(WasmIndirectFunctionTable, refs, FixedArray, kRefsOffset) // WasmDebugInfo ACCESSORS(WasmDebugInfo, wasm_instance, WasmInstanceObject, kInstanceOffset) ACCESSORS(WasmDebugInfo, interpreter_handle, Object, kInterpreterHandleOffset) +ACCESSORS(WasmDebugInfo, interpreter_reference_stack, Cell, + kInterpreterReferenceStackOffset) OPTIONAL_ACCESSORS(WasmDebugInfo, locals_names, FixedArray, kLocalsNamesOffset) OPTIONAL_ACCESSORS(WasmDebugInfo, c_wasm_entries, FixedArray, kCWasmEntriesOffset) diff --git a/deps/v8/src/wasm/wasm-objects.cc b/deps/v8/src/wasm/wasm-objects.cc index d9417943a843ed..93ce345a5fb06a 100644 --- a/deps/v8/src/wasm/wasm-objects.cc +++ b/deps/v8/src/wasm/wasm-objects.cc @@ -25,10 +25,8 @@ #include "src/wasm/wasm-code-manager.h" #include "src/wasm/wasm-engine.h" #include "src/wasm/wasm-limits.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" -#include "src/wasm/wasm-text.h" #define TRACE(...) \ do { \ @@ -244,37 +242,40 @@ Handle<WasmModuleObject> WasmModuleObject::New( isolate->factory()->NewJSObject(isolate->wasm_module_constructor())); module_object->set_export_wrappers(*export_wrappers); if (script->type() == Script::TYPE_WASM) { - script->set_wasm_module_object(*module_object); + script->set_wasm_breakpoint_infos( + ReadOnlyRoots(isolate).empty_fixed_array()); + script->set_wasm_managed_native_module(*managed_native_module); + script->set_wasm_weak_instance_list( + ReadOnlyRoots(isolate).empty_weak_array_list()); } module_object->set_script(*script); - module_object->set_weak_instance_list( - ReadOnlyRoots(isolate).empty_weak_array_list()); module_object->set_managed_native_module(*managed_native_module); return module_object; } -bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object, - int* position, +// static +bool WasmModuleObject::SetBreakPoint(Handle<Script> script, int* position, Handle<BreakPoint> break_point) { - Isolate* isolate = module_object->GetIsolate(); + Isolate* isolate = script->GetIsolate(); // Find the function for this breakpoint. - int func_index = module_object->GetContainingFunction(*position); + const WasmModule* module = script->wasm_native_module()->module(); + int func_index = GetContainingWasmFunction(module, *position); if (func_index < 0) return false; - const WasmFunction& func = module_object->module()->functions[func_index]; + const WasmFunction& func = module->functions[func_index]; int offset_in_func = *position - func.code.offset(); // According to the current design, we should only be called with valid // breakable positions. - DCHECK(IsBreakablePosition(module_object->native_module(), func_index, + DCHECK(IsBreakablePosition(script->wasm_native_module(), func_index, offset_in_func)); // Insert new break point into break_positions of module object. - WasmModuleObject::AddBreakpoint(module_object, *position, break_point); + WasmModuleObject::AddBreakpointToInfo(script, *position, break_point); - // Iterate over all instances of this module and tell them to set this new - // breakpoint. We do this using the weak list of all instances. - Handle<WeakArrayList> weak_instance_list(module_object->weak_instance_list(), + // Iterate over all instances and tell them to set this new breakpoint. + // We do this using the weak list of all instances from the script. + Handle<WeakArrayList> weak_instance_list(script->wasm_weak_instance_list(), isolate); for (int i = 0; i < weak_instance_list->length(); ++i) { MaybeObject maybe_instance = weak_instance_list->Get(i); @@ -291,6 +292,42 @@ bool WasmModuleObject::SetBreakPoint(Handle<WasmModuleObject> module_object, return true; } +// static +bool WasmModuleObject::ClearBreakPoint(Handle<Script> script, int position, + Handle<BreakPoint> break_point) { + Isolate* isolate = script->GetIsolate(); + + // Find the function for this breakpoint. + const WasmModule* module = script->wasm_native_module()->module(); + int func_index = GetContainingWasmFunction(module, position); + if (func_index < 0) return false; + const WasmFunction& func = module->functions[func_index]; + int offset_in_func = position - func.code.offset(); + + if (!WasmModuleObject::RemoveBreakpointFromInfo(script, position, + break_point)) { + return false; + } + + // Iterate over all instances and tell them to remove this breakpoint. + // We do this using the weak list of all instances from the script. + Handle<WeakArrayList> weak_instance_list(script->wasm_weak_instance_list(), + isolate); + for (int i = 0; i < weak_instance_list->length(); ++i) { + MaybeObject maybe_instance = weak_instance_list->Get(i); + if (maybe_instance->IsWeak()) { + Handle<WasmInstanceObject> instance( + WasmInstanceObject::cast(maybe_instance->GetHeapObjectAssumeWeak()), + isolate); + Handle<WasmDebugInfo> debug_info = + WasmInstanceObject::GetOrCreateDebugInfo(instance); + WasmDebugInfo::ClearBreakpoint(debug_info, func_index, offset_in_func); + } + } + + return true; +} + namespace { int GetBreakpointPos(Isolate* isolate, Object break_point_info_or_undef) { @@ -323,17 +360,17 @@ int FindBreakpointInfoInsertPos(Isolate* isolate, } // namespace -void WasmModuleObject::AddBreakpoint(Handle<WasmModuleObject> module_object, - int position, - Handle<BreakPoint> break_point) { - Isolate* isolate = module_object->GetIsolate(); +// static +void WasmModuleObject::AddBreakpointToInfo(Handle<Script> script, int position, + Handle<BreakPoint> break_point) { + Isolate* isolate = script->GetIsolate(); Handle<FixedArray> breakpoint_infos; - if (module_object->has_breakpoint_infos()) { - breakpoint_infos = handle(module_object->breakpoint_infos(), isolate); + if (script->has_wasm_breakpoint_infos()) { + breakpoint_infos = handle(script->wasm_breakpoint_infos(), isolate); } else { breakpoint_infos = isolate->factory()->NewFixedArray(4, AllocationType::kOld); - module_object->set_breakpoint_infos(*breakpoint_infos); + script->set_wasm_breakpoint_infos(*breakpoint_infos); } int insert_pos = @@ -357,7 +394,7 @@ void WasmModuleObject::AddBreakpoint(Handle<WasmModuleObject> module_object, if (need_realloc) { new_breakpoint_infos = isolate->factory()->NewFixedArray( 2 * breakpoint_infos->length(), AllocationType::kOld); - module_object->set_breakpoint_infos(*new_breakpoint_infos); + script->set_wasm_breakpoint_infos(*new_breakpoint_infos); // Copy over the entries [0, insert_pos). for (int i = 0; i < insert_pos; ++i) new_breakpoint_infos->set(i, breakpoint_infos->get(i)); @@ -379,16 +416,45 @@ void WasmModuleObject::AddBreakpoint(Handle<WasmModuleObject> module_object, new_breakpoint_infos->set(insert_pos, *breakpoint_info); } +// static +bool WasmModuleObject::RemoveBreakpointFromInfo( + Handle<Script> script, int position, Handle<BreakPoint> break_point) { + if (!script->has_wasm_breakpoint_infos()) return false; + + Isolate* isolate = script->GetIsolate(); + Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate); + + int pos = FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); + + // Does a BreakPointInfo object already exist for this position? + if (pos == breakpoint_infos->length()) return false; + + Handle<BreakPointInfo> info(BreakPointInfo::cast(breakpoint_infos->get(pos)), + isolate); + BreakPointInfo::ClearBreakPoint(isolate, info, break_point); + + // Check if there are no more breakpoints at this location. + if (info->GetBreakPointCount(isolate) == 0) { + // Update array by moving breakpoints up one position. + for (int i = pos; i < breakpoint_infos->length() - 1; i++) { + Object entry = breakpoint_infos->get(i + 1); + breakpoint_infos->set(i, entry); + if (entry.IsUndefined(isolate)) break; + } + // Make sure last array element is empty as a result. + breakpoint_infos->set_undefined(breakpoint_infos->length() - 1); + } + return true; +} + void WasmModuleObject::SetBreakpointsOnNewInstance( - Handle<WasmModuleObject> module_object, - Handle<WasmInstanceObject> instance) { - if (!module_object->has_breakpoint_infos()) return; - Isolate* isolate = module_object->GetIsolate(); + Handle<Script> script, Handle<WasmInstanceObject> instance) { + if (!script->has_wasm_breakpoint_infos()) return; + Isolate* isolate = script->GetIsolate(); Handle<WasmDebugInfo> debug_info = WasmInstanceObject::GetOrCreateDebugInfo(instance); - Handle<FixedArray> breakpoint_infos(module_object->breakpoint_infos(), - isolate); + Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate); // If the array exists, it should not be empty. DCHECK_LT(0, breakpoint_infos->length()); @@ -404,9 +470,10 @@ void WasmModuleObject::SetBreakpointsOnNewInstance( int position = breakpoint_info->source_position(); // Find the function for this breakpoint, and set the breakpoint. - int func_index = module_object->GetContainingFunction(position); + const WasmModule* module = script->wasm_native_module()->module(); + int func_index = GetContainingWasmFunction(module, position); DCHECK_LE(0, func_index); - const WasmFunction& func = module_object->module()->functions[func_index]; + const WasmFunction& func = module->functions[func_index]; int offset_in_func = position - func.code.offset(); WasmDebugInfo::SetBreakpoint(debug_info, func_index, offset_in_func); } @@ -497,7 +564,7 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object, if (module->origin == wasm::kWasmOrigin) { // for non-asm.js modules, we just add the function's start offset // to make a module-relative position. - return byte_offset + module_object->GetFunctionOffset(func_index); + return byte_offset + GetWasmFunctionOffset(module, func_index); } // asm.js modules have an additional offset table that must be searched. @@ -529,31 +596,15 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object, return offset_table->get_int(kOTESize * left + idx); } -v8::debug::WasmDisassembly WasmModuleObject::DisassembleFunction( - int func_index) { - DisallowHeapAllocation no_gc; - - if (func_index < 0 || - static_cast<uint32_t>(func_index) >= module()->functions.size()) - return {}; - - wasm::ModuleWireBytes wire_bytes(native_module()->wire_bytes()); - - std::ostringstream disassembly_os; - v8::debug::WasmDisassembly::OffsetTable offset_table; - - PrintWasmText(module(), wire_bytes, static_cast<uint32_t>(func_index), - disassembly_os, &offset_table); - - return {disassembly_os.str(), std::move(offset_table)}; -} - +// static bool WasmModuleObject::GetPossibleBreakpoints( - const v8::debug::Location& start, const v8::debug::Location& end, + wasm::NativeModule* native_module, const v8::debug::Location& start, + const v8::debug::Location& end, std::vector<v8::debug::BreakLocation>* locations) { DisallowHeapAllocation no_gc; - const std::vector<WasmFunction>& functions = module()->functions; + const std::vector<WasmFunction>& functions = + native_module->module()->functions; if (start.GetLineNumber() < 0 || start.GetColumnNumber() < 0 || (!end.IsEmpty() && (end.GetLineNumber() < 0 || end.GetColumnNumber() < 0))) @@ -595,7 +646,7 @@ bool WasmModuleObject::GetPossibleBreakpoints( AccountingAllocator alloc; Zone tmp(&alloc, ZONE_NAME); - const byte* module_start = native_module()->wire_bytes().begin(); + const byte* module_start = native_module->wire_bytes().begin(); for (uint32_t func_idx = start_func_index; func_idx <= end_func_index; ++func_idx) { @@ -620,12 +671,12 @@ bool WasmModuleObject::GetPossibleBreakpoints( return true; } +// static MaybeHandle<FixedArray> WasmModuleObject::CheckBreakPoints( - Isolate* isolate, Handle<WasmModuleObject> module_object, int position) { - if (!module_object->has_breakpoint_infos()) return {}; + Isolate* isolate, Handle<Script> script, int position) { + if (!script->has_wasm_breakpoint_infos()) return {}; - Handle<FixedArray> breakpoint_infos(module_object->breakpoint_infos(), - isolate); + Handle<FixedArray> breakpoint_infos(script->wasm_breakpoint_infos(), isolate); int insert_pos = FindBreakpointInfoInsertPos(isolate, breakpoint_infos, position); if (insert_pos >= breakpoint_infos->length()) return {}; @@ -709,60 +760,6 @@ Vector<const uint8_t> WasmModuleObject::GetRawFunctionName( return Vector<const uint8_t>::cast(name); } -int WasmModuleObject::GetFunctionOffset(uint32_t func_index) { - const std::vector<WasmFunction>& functions = module()->functions; - if (static_cast<uint32_t>(func_index) >= functions.size()) return -1; - DCHECK_GE(kMaxInt, functions[func_index].code.offset()); - return static_cast<int>(functions[func_index].code.offset()); -} - -int WasmModuleObject::GetContainingFunction(uint32_t byte_offset) { - const std::vector<WasmFunction>& functions = module()->functions; - - // Binary search for a function containing the given position. - int left = 0; // inclusive - int right = static_cast<int>(functions.size()); // exclusive - if (right == 0) return false; - while (right - left > 1) { - int mid = left + (right - left) / 2; - if (functions[mid].code.offset() <= byte_offset) { - left = mid; - } else { - right = mid; - } - } - // If the found function does not contains the given position, return -1. - const WasmFunction& func = functions[left]; - if (byte_offset < func.code.offset() || - byte_offset >= func.code.end_offset()) { - return -1; - } - - return left; -} - -bool WasmModuleObject::GetPositionInfo(uint32_t position, - Script::PositionInfo* info) { - if (script().source_mapping_url().IsString()) { - if (module()->functions.size() == 0) return false; - info->line = 0; - info->column = position; - info->line_start = module()->functions[0].code.offset(); - info->line_end = module()->functions.back().code.end_offset(); - return true; - } - int func_index = GetContainingFunction(position); - if (func_index < 0) return false; - - const WasmFunction& function = module()->functions[func_index]; - - info->line = func_index; - info->column = position - function.code.offset(); - info->line_start = function.code.offset(); - info->line_end = function.code.end_offset(); - return true; -} - Handle<WasmTableObject> WasmTableObject::New(Isolate* isolate, wasm::ValueType type, uint32_t initial, bool has_maximum, @@ -1217,66 +1214,17 @@ void WasmIndirectFunctionTable::Resize(Isolate* isolate, } namespace { -bool AdjustBufferPermissions(Isolate* isolate, Handle<JSArrayBuffer> old_buffer, - size_t new_size) { - if (new_size > old_buffer->allocation_length()) return false; - void* old_mem_start = old_buffer->backing_store(); - size_t old_size = old_buffer->byte_length(); - if (old_size != new_size) { - DCHECK_NOT_NULL(old_mem_start); - DCHECK_GE(new_size, old_size); - // If adjusting permissions fails, propagate error back to return - // failure to grow. - if (!i::SetPermissions(GetPlatformPageAllocator(), old_mem_start, new_size, - PageAllocator::kReadWrite)) { - return false; - } - reinterpret_cast<v8::Isolate*>(isolate) - ->AdjustAmountOfExternalAllocatedMemory(new_size - old_size); - } - return true; -} -MaybeHandle<JSArrayBuffer> MemoryGrowBuffer(Isolate* isolate, - Handle<JSArrayBuffer> old_buffer, - size_t new_size) { - CHECK_EQ(0, new_size % wasm::kWasmPageSize); - // Reusing the backing store from externalized buffers causes problems with - // Blink's array buffers. The connection between the two is lost, which can - // lead to Blink not knowing about the other reference to the buffer and - // freeing it too early. - if (old_buffer->is_external() || new_size > old_buffer->allocation_length()) { - // We couldn't reuse the old backing store, so create a new one and copy the - // old contents in. - Handle<JSArrayBuffer> new_buffer; - if (!wasm::NewArrayBuffer(isolate, new_size).ToHandle(&new_buffer)) { - return {}; - } - void* old_mem_start = old_buffer->backing_store(); - size_t old_size = old_buffer->byte_length(); - if (old_size == 0) return new_buffer; - memcpy(new_buffer->backing_store(), old_mem_start, old_size); - DCHECK(old_buffer.is_null() || !old_buffer->is_shared()); - constexpr bool free_memory = true; - i::wasm::DetachMemoryBuffer(isolate, old_buffer, free_memory); - return new_buffer; - } else { - if (!AdjustBufferPermissions(isolate, old_buffer, new_size)) return {}; - // NOTE: We must allocate a new array buffer here because the spec - // assumes that ArrayBuffers do not change size. - void* backing_store = old_buffer->backing_store(); - bool is_external = old_buffer->is_external(); - // Disconnect buffer early so GC won't free it. - i::wasm::DetachMemoryBuffer(isolate, old_buffer, false); - Handle<JSArrayBuffer> new_buffer = - wasm::SetupArrayBuffer(isolate, backing_store, new_size, is_external); - return new_buffer; - } -} - -// May GC, because SetSpecializationMemInfoFrom may GC void SetInstanceMemory(Handle<WasmInstanceObject> instance, Handle<JSArrayBuffer> buffer) { + bool is_wasm_module = instance->module()->origin == wasm::kWasmOrigin; + bool use_trap_handler = + instance->module_object().native_module()->use_trap_handler(); + // Wasm modules compiled to use the trap handler don't have bounds checks, + // so they must have a memory that has guard regions. + CHECK_IMPLIES(is_wasm_module && use_trap_handler, + buffer->GetBackingStore()->has_guard_regions()); + instance->SetRawMemory(reinterpret_cast<byte*>(buffer->backing_store()), buffer->byte_length()); #if DEBUG @@ -1294,7 +1242,6 @@ void SetInstanceMemory(Handle<WasmInstanceObject> instance, } #endif } - } // namespace Handle<WasmMemoryObject> WasmMemoryObject::New( @@ -1302,44 +1249,54 @@ Handle<WasmMemoryObject> WasmMemoryObject::New( uint32_t maximum) { Handle<JSArrayBuffer> buffer; if (!maybe_buffer.ToHandle(&buffer)) { - // If no buffer was provided, create a 0-length one. - buffer = wasm::SetupArrayBuffer(isolate, nullptr, 0, false); + // If no buffer was provided, create a zero-length one. + auto backing_store = + BackingStore::AllocateWasmMemory(isolate, 0, 0, SharedFlag::kNotShared); + buffer = isolate->factory()->NewJSArrayBuffer(std::move(backing_store)); } - // TODO(kschimpf): Do we need to add an argument that defines the - // style of memory the user prefers (with/without trap handling), so - // that the memory will match the style of the compiled wasm module. - // See issue v8:7143 Handle<JSFunction> memory_ctor( isolate->native_context()->wasm_memory_constructor(), isolate); - auto memory_obj = Handle<WasmMemoryObject>::cast( + auto memory_object = Handle<WasmMemoryObject>::cast( isolate->factory()->NewJSObject(memory_ctor, AllocationType::kOld)); - memory_obj->set_array_buffer(*buffer); - memory_obj->set_maximum_pages(maximum); + memory_object->set_array_buffer(*buffer); + memory_object->set_maximum_pages(maximum); - return memory_obj; + if (buffer->is_shared()) { + auto backing_store = buffer->GetBackingStore(); + backing_store->AttachSharedWasmMemoryObject(isolate, memory_object); + } + + return memory_object; } MaybeHandle<WasmMemoryObject> WasmMemoryObject::New(Isolate* isolate, uint32_t initial, uint32_t maximum, - bool is_shared_memory) { - Handle<JSArrayBuffer> buffer; - size_t size = static_cast<size_t>(i::wasm::kWasmPageSize) * - static_cast<size_t>(initial); - if (is_shared_memory) { - size_t max_size = static_cast<size_t>(i::wasm::kWasmPageSize) * - static_cast<size_t>(maximum); - if (!i::wasm::NewSharedArrayBuffer(isolate, size, max_size) - .ToHandle(&buffer)) { - return {}; - } - } else { - if (!i::wasm::NewArrayBuffer(isolate, size).ToHandle(&buffer)) { - return {}; - } + SharedFlag shared) { + auto heuristic_maximum = maximum; +#ifdef V8_TARGET_ARCH_32_BIT + // TODO(wasm): use a better heuristic for reserving more than the initial + // number of pages on 32-bit systems. Being too greedy in reserving capacity + // limits the number of memories that can be allocated, causing OOMs in many + // tests. For now, on 32-bit we never reserve more than initial, unless the + // memory is shared. + if (shared == SharedFlag::kNotShared || !FLAG_wasm_grow_shared_memory) { + heuristic_maximum = initial; } +#endif + + auto backing_store = BackingStore::AllocateWasmMemory( + isolate, initial, heuristic_maximum, shared); + + if (!backing_store) return {}; + + Handle<JSArrayBuffer> buffer = + (shared == SharedFlag::kShared) + ? isolate->factory()->NewJSSharedArrayBuffer(std::move(backing_store)) + : isolate->factory()->NewJSArrayBuffer(std::move(backing_store)); + return New(isolate, buffer, maximum); } @@ -1383,11 +1340,11 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, uint32_t pages) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "GrowMemory"); Handle<JSArrayBuffer> old_buffer(memory_object->array_buffer(), isolate); - if (old_buffer->is_shared() && !FLAG_wasm_grow_shared_memory) return -1; - auto* memory_tracker = isolate->wasm_engine()->memory_tracker(); - if (!memory_tracker->IsWasmMemoryGrowable(old_buffer)) return -1; + // Any buffer used as an asmjs memory cannot be detached, and + // therefore this memory cannot be grown. + if (old_buffer->is_asmjs_memory()) return -1; - // Checks for maximum memory size, compute new size. + // Checks for maximum memory size. uint32_t maximum_pages = wasm::max_mem_pages(); if (memory_object->has_maximum_pages()) { maximum_pages = std::min( @@ -1402,47 +1359,54 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, (pages > wasm::max_mem_pages() - old_pages)) { // exceeds limit return -1; } - size_t new_size = - static_cast<size_t>(old_pages + pages) * wasm::kWasmPageSize; + std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore(); + if (!backing_store) return -1; + + // Compute new size. + size_t new_pages = old_pages + pages; + size_t new_byte_length = new_pages * wasm::kWasmPageSize; - // Memory is grown, but the memory objects and instances are not yet updated. - // Handle this in the interrupt handler so that it's safe for all the isolates - // that share this buffer to be updated safely. - Handle<JSArrayBuffer> new_buffer; + // Try to handle shared memory first. if (old_buffer->is_shared()) { - // Adjust protections for the buffer. - if (!AdjustBufferPermissions(isolate, old_buffer, new_size)) { - return -1; - } - void* backing_store = old_buffer->backing_store(); - if (memory_tracker->IsWasmSharedMemory(backing_store)) { - // This memory is shared between different isolates. - DCHECK(old_buffer->is_shared()); - // Update pending grow state, and trigger a grow interrupt on all the - // isolates that share this buffer. - memory_tracker->SetPendingUpdateOnGrow(old_buffer, new_size); - // Handle interrupts for this isolate so that the instances with this - // isolate are updated. - isolate->stack_guard()->HandleInterrupts(); - // Failure to allocate, or adjust pemissions already handled here, and - // updates to instances handled in the interrupt handler safe to return. - return static_cast<uint32_t>(old_size / wasm::kWasmPageSize); + if (FLAG_wasm_grow_shared_memory) { + // Shared memories can only be grown in place; no copying. + if (backing_store->GrowWasmMemoryInPlace(isolate, pages, maximum_pages)) { + BackingStore::BroadcastSharedWasmMemoryGrow(isolate, backing_store, + new_pages); + // Broadcasting the update should update this memory object too. + CHECK_NE(*old_buffer, memory_object->array_buffer()); + // This is a less than check, as it is not guaranteed that the SAB + // length here will be equal to the stashed length above as calls to + // grow the same memory object can come in from different workers. + // It is also possible that a call to Grow was in progress when + // handling this call. + CHECK_LE(new_byte_length, memory_object->array_buffer().byte_length()); + return static_cast<int32_t>(old_pages); // success + } } - // SharedArrayBuffer, but not shared across isolates. Setup a new buffer - // with updated permissions and update the instances. - new_buffer = - wasm::SetupArrayBuffer(isolate, backing_store, new_size, - old_buffer->is_external(), SharedFlag::kShared); + return -1; + } + + // Try to grow non-shared memory in-place. + if (backing_store->GrowWasmMemoryInPlace(isolate, pages, maximum_pages)) { + // Detach old and create a new one with the grown backing store. + old_buffer->Detach(true); + Handle<JSArrayBuffer> new_buffer = + isolate->factory()->NewJSArrayBuffer(std::move(backing_store)); memory_object->update_instances(isolate, new_buffer); - } else { - if (!MemoryGrowBuffer(isolate, old_buffer, new_size) - .ToHandle(&new_buffer)) { - return -1; - } + return static_cast<int32_t>(old_pages); // success } - // Update instances if any. + // Try allocating a new backing store and copying. + std::unique_ptr<BackingStore> new_backing_store = + backing_store->CopyWasmMemory(isolate, new_pages); + if (!new_backing_store) return -1; + + // Detach old and create a new one with the new backing store. + old_buffer->Detach(true); + Handle<JSArrayBuffer> new_buffer = + isolate->factory()->NewJSArrayBuffer(std::move(new_backing_store)); memory_object->update_instances(isolate, new_buffer); - return static_cast<uint32_t>(old_size / wasm::kWasmPageSize); + return static_cast<int32_t>(old_pages); // success } // static @@ -1476,18 +1440,15 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New( global_obj->set_tagged_buffer(*tagged_buffer); } else { DCHECK(maybe_tagged_buffer.is_null()); - Handle<JSArrayBuffer> untagged_buffer; uint32_t type_size = wasm::ValueTypes::ElementSizeInBytes(type); + + Handle<JSArrayBuffer> untagged_buffer; if (!maybe_untagged_buffer.ToHandle(&untagged_buffer)) { - // If no buffer was provided, create one long enough for the given type. - untagged_buffer = isolate->factory()->NewJSArrayBuffer( - SharedFlag::kNotShared, AllocationType::kOld); - - const bool initialize = true; - if (!JSArrayBuffer::SetupAllocatingData(untagged_buffer, isolate, - type_size, initialize)) { - return {}; - } + MaybeHandle<JSArrayBuffer> result = + isolate->factory()->NewJSArrayBufferAndBackingStore( + offset + type_size, InitializedFlag::kZeroInitialized); + + if (!result.ToHandle(&untagged_buffer)) return {}; } // Check that the offset is in bounds. @@ -1725,13 +1686,16 @@ Handle<WasmInstanceObject> WasmInstanceObject::New( instance->set_jump_table_start( module_object->native_module()->jump_table_start()); - // Insert the new instance into the modules weak list of instances. + // Insert the new instance into the scripts weak list of instances. This list + // is used for breakpoints affecting all instances belonging to the script. // TODO(mstarzinger): Allow to reuse holes in the {WeakArrayList} below. - Handle<WeakArrayList> weak_instance_list(module_object->weak_instance_list(), - isolate); - weak_instance_list = WeakArrayList::AddToEnd( - isolate, weak_instance_list, MaybeObjectHandle::Weak(instance)); - module_object->set_weak_instance_list(*weak_instance_list); + if (module_object->script().type() == Script::TYPE_WASM) { + Handle<WeakArrayList> weak_instance_list( + module_object->script().wasm_weak_instance_list(), isolate); + weak_instance_list = WeakArrayList::AddToEnd( + isolate, weak_instance_list, MaybeObjectHandle::Weak(instance)); + module_object->script().set_wasm_weak_instance_list(*weak_instance_list); + } InitDataSegmentArrays(instance, module_object); InitElemSegmentArrays(instance, module_object); @@ -2040,7 +2004,7 @@ bool WasmCapiFunction::IsSignatureEqual(const wasm::FunctionSig* sig) const { } // static -Handle<JSReceiver> WasmExceptionPackage::New( +Handle<WasmExceptionPackage> WasmExceptionPackage::New( Isolate* isolate, Handle<WasmExceptionTag> exception_tag, int size) { Handle<Object> exception = isolate->factory()->NewWasmRuntimeError( MessageTemplate::kWasmExceptionError); @@ -2055,37 +2019,31 @@ Handle<JSReceiver> WasmExceptionPackage::New( values, StoreOrigin::kMaybeKeyed, Just(ShouldThrow::kThrowOnError)) .is_null()); - return Handle<JSReceiver>::cast(exception); + return Handle<WasmExceptionPackage>::cast(exception); } // static Handle<Object> WasmExceptionPackage::GetExceptionTag( - Isolate* isolate, Handle<Object> exception_object) { - if (exception_object->IsJSReceiver()) { - Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object); - Handle<Object> tag; - if (JSReceiver::GetProperty(isolate, exception, - isolate->factory()->wasm_exception_tag_symbol()) - .ToHandle(&tag)) { - return tag; - } + Isolate* isolate, Handle<WasmExceptionPackage> exception_package) { + Handle<Object> tag; + if (JSReceiver::GetProperty(isolate, exception_package, + isolate->factory()->wasm_exception_tag_symbol()) + .ToHandle(&tag)) { + return tag; } return ReadOnlyRoots(isolate).undefined_value_handle(); } // static Handle<Object> WasmExceptionPackage::GetExceptionValues( - Isolate* isolate, Handle<Object> exception_object) { - if (exception_object->IsJSReceiver()) { - Handle<JSReceiver> exception = Handle<JSReceiver>::cast(exception_object); - Handle<Object> values; - if (JSReceiver::GetProperty( - isolate, exception, - isolate->factory()->wasm_exception_values_symbol()) - .ToHandle(&values)) { - DCHECK(values->IsFixedArray()); - return values; - } + Isolate* isolate, Handle<WasmExceptionPackage> exception_package) { + Handle<Object> values; + if (JSReceiver::GetProperty( + isolate, exception_package, + isolate->factory()->wasm_exception_values_symbol()) + .ToHandle(&values)) { + DCHECK(values->IsFixedArray()); + return values; } return ReadOnlyRoots(isolate).undefined_value_handle(); } diff --git a/deps/v8/src/wasm/wasm-objects.h b/deps/v8/src/wasm/wasm-objects.h index c198a9bc637de5..23c13c4329942e 100644 --- a/deps/v8/src/wasm/wasm-objects.h +++ b/deps/v8/src/wasm/wasm-objects.h @@ -5,13 +5,13 @@ #ifndef V8_WASM_WASM_OBJECTS_H_ #define V8_WASM_WASM_OBJECTS_H_ +#include <memory> + #include "src/base/bits.h" #include "src/codegen/signature.h" #include "src/debug/debug.h" -#include "src/debug/interface-types.h" #include "src/heap/heap.h" #include "src/objects/objects.h" -#include "src/objects/script.h" #include "src/wasm/value-type.h" // Has to be the last include (doesn't have include guards) @@ -47,6 +47,8 @@ class WasmJSFunction; class WasmModuleObject; class WasmIndirectFunctionTable; +enum class SharedFlag : uint8_t; + template <class CppType> class Managed; @@ -124,14 +126,11 @@ class WasmModuleObject : public JSObject { DECL_ACCESSORS(managed_native_module, Managed<wasm::NativeModule>) DECL_ACCESSORS(export_wrappers, FixedArray) DECL_ACCESSORS(script, Script) - DECL_ACCESSORS(weak_instance_list, WeakArrayList) DECL_OPTIONAL_ACCESSORS(asm_js_offset_table, ByteArray) - DECL_OPTIONAL_ACCESSORS(breakpoint_infos, FixedArray) inline wasm::NativeModule* native_module() const; inline const std::shared_ptr<wasm::NativeModule>& shared_native_module() const; inline const wasm::WasmModule* module() const; - inline void reset_breakpoint_infos(); // Dispatched behavior. DECL_PRINTER(WasmModuleObject) @@ -153,23 +152,28 @@ class WasmModuleObject : public JSObject { Handle<Script> script, Handle<FixedArray> export_wrappers, size_t code_size_estimate); + // TODO(mstarzinger): The below breakpoint handling methods taking a {Script} + // instead of a {WasmModuleObject} as first argument should be moved onto a + // separate {WasmScript} class, implementation move to wasm-debug.cc then. + // Set a breakpoint on the given byte position inside the given module. // This will affect all live and future instances of the module. // The passed position might be modified to point to the next breakable // location inside the same function. // If it points outside a function, or behind the last breakable location, // this function returns false and does not set any breakpoint. - V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<WasmModuleObject>, - int* position, + V8_EXPORT_PRIVATE static bool SetBreakPoint(Handle<Script>, int* position, Handle<BreakPoint> break_point); + // Remove a previously set breakpoint at the given byte position inside the + // given module. If this breakpoint is not found this function returns false. + V8_EXPORT_PRIVATE static bool ClearBreakPoint(Handle<Script>, int position, + Handle<BreakPoint> break_point); + // Check whether this module was generated from asm.js source. inline bool is_asm_js(); - static void AddBreakpoint(Handle<WasmModuleObject>, int position, - Handle<BreakPoint> break_point); - - static void SetBreakpointsOnNewInstance(Handle<WasmModuleObject>, + static void SetBreakpointsOnNewInstance(Handle<Script>, Handle<WasmInstanceObject>); // Get the module name, if set. Returns an empty handle otherwise. @@ -195,34 +199,12 @@ class WasmModuleObject : public JSObject { // Does not allocate, hence gc-safe. Vector<const uint8_t> GetRawFunctionName(uint32_t func_index); - // Return the byte offset of the function identified by the given index. - // The offset will be relative to the start of the module bytes. - // Returns -1 if the function index is invalid. - int GetFunctionOffset(uint32_t func_index); - - // Returns the function containing the given byte offset. - // Returns -1 if the byte offset is not contained in any function of this - // module. - int GetContainingFunction(uint32_t byte_offset); - - // Translate from byte offset in the module to function number and byte offset - // within that function, encoded as line and column in the position info. - // Returns true if the position is valid inside this module, false otherwise. - bool GetPositionInfo(uint32_t position, Script::PositionInfo* info); - // Get the source position from a given function index and byte offset, // for either asm.js or pure Wasm modules. static int GetSourcePosition(Handle<WasmModuleObject>, uint32_t func_index, uint32_t byte_offset, bool is_at_number_conversion); - // Compute the disassembly of a wasm function. - // Returns the disassembly string and a list of <byte_offset, line, column> - // entries, mapping wasm byte offsets to line and column in the disassembly. - // The list is guaranteed to be ordered by the byte_offset. - // Returns an empty string and empty vector if the function index is invalid. - V8_EXPORT_PRIVATE debug::WasmDisassembly DisassembleFunction(int func_index); - // Extract a portion of the wire bytes as UTF-8 string. // Returns a null handle if the respective bytes do not form a valid UTF-8 // string. @@ -233,17 +215,24 @@ class WasmModuleObject : public JSObject { wasm::WireBytesRef ref); // Get a list of all possible breakpoints within a given range of this module. - V8_EXPORT_PRIVATE bool GetPossibleBreakpoints( - const debug::Location& start, const debug::Location& end, - std::vector<debug::BreakLocation>* locations); + V8_EXPORT_PRIVATE static bool GetPossibleBreakpoints( + wasm::NativeModule* native_module, const debug::Location& start, + const debug::Location& end, std::vector<debug::BreakLocation>* locations); // Return an empty handle if no breakpoint is hit at that location, or a // FixedArray with all hit breakpoint objects. - static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, - Handle<WasmModuleObject>, + static MaybeHandle<FixedArray> CheckBreakPoints(Isolate*, Handle<Script>, int position); OBJECT_CONSTRUCTORS(WasmModuleObject, JSObject); + + private: + // Helper functions that update the breakpoint info list. + static void AddBreakpointToInfo(Handle<Script>, int position, + Handle<BreakPoint> break_point); + + static bool RemoveBreakpointFromInfo(Handle<Script>, int position, + Handle<BreakPoint> break_point); }; // Representation of a WebAssembly.Table JavaScript-level object. @@ -354,9 +343,10 @@ class WasmMemoryObject : public JSObject { V8_EXPORT_PRIVATE static Handle<WasmMemoryObject> New( Isolate* isolate, MaybeHandle<JSArrayBuffer> buffer, uint32_t maximum); - V8_EXPORT_PRIVATE static MaybeHandle<WasmMemoryObject> New( - Isolate* isolate, uint32_t initial, uint32_t maximum, - bool is_shared_memory); + V8_EXPORT_PRIVATE static MaybeHandle<WasmMemoryObject> New(Isolate* isolate, + uint32_t initial, + uint32_t maximum, + SharedFlag shared); void update_instances(Isolate* isolate, Handle<JSArrayBuffer> buffer); @@ -645,20 +635,22 @@ class WasmExceptionObject : public JSObject { // A Wasm exception that has been thrown out of Wasm code. class WasmExceptionPackage : public JSReceiver { public: - // TODO(mstarzinger): Ideally this interface would use {WasmExceptionPackage} - // instead of {JSReceiver} throughout. For now a type-check implies doing a - // property lookup however, which would result in casts being handlified. - static Handle<JSReceiver> New(Isolate* isolate, - Handle<WasmExceptionTag> exception_tag, - int encoded_size); + static Handle<WasmExceptionPackage> New( + Isolate* isolate, Handle<WasmExceptionTag> exception_tag, + int encoded_size); // The below getters return {undefined} in case the given exception package // does not carry the requested values (i.e. is of a different type). - static Handle<Object> GetExceptionTag(Isolate*, Handle<Object> exception); - static Handle<Object> GetExceptionValues(Isolate*, Handle<Object> exception); + static Handle<Object> GetExceptionTag( + Isolate* isolate, Handle<WasmExceptionPackage> exception_package); + static Handle<Object> GetExceptionValues( + Isolate* isolate, Handle<WasmExceptionPackage> exception_package); // Determines the size of the array holding all encoded exception values. static uint32_t GetEncodedSize(const wasm::WasmException* exception); + + DECL_CAST(WasmExceptionPackage) + OBJECT_CONSTRUCTORS(WasmExceptionPackage, JSReceiver); }; // A Wasm function that is wrapped and exported to JavaScript. @@ -801,7 +793,7 @@ class WasmExportedFunctionData : public Struct { DECL_PRINTER(WasmExportedFunctionData) DECL_VERIFIER(WasmExportedFunctionData) -// Layout description. + // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS( HeapObject::kHeaderSize, TORQUE_GENERATED_WASM_EXPORTED_FUNCTION_DATA_FIELDS) @@ -828,7 +820,7 @@ class WasmJSFunctionData : public Struct { // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, - TORQUE_GENERATED_WASM_JSFUNCTION_DATA_FIELDS) + TORQUE_GENERATED_WASM_JS_FUNCTION_DATA_FIELDS) OBJECT_CONSTRUCTORS(WasmJSFunctionData, Struct); }; @@ -838,6 +830,7 @@ class WasmDebugInfo : public Struct { NEVER_READ_ONLY_SPACE DECL_ACCESSORS(wasm_instance, WasmInstanceObject) DECL_ACCESSORS(interpreter_handle, Object) // Foreign or undefined + DECL_ACCESSORS(interpreter_reference_stack, Cell) DECL_OPTIONAL_ACCESSORS(locals_names, FixedArray) DECL_OPTIONAL_ACCESSORS(c_wasm_entries, FixedArray) DECL_OPTIONAL_ACCESSORS(c_wasm_entry_map, Managed<wasm::SignatureMap>) @@ -848,7 +841,7 @@ class WasmDebugInfo : public Struct { DECL_PRINTER(WasmDebugInfo) DECL_VERIFIER(WasmDebugInfo) -// Layout description. + // Layout description. DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, TORQUE_GENERATED_WASM_DEBUG_INFO_FIELDS) @@ -867,6 +860,11 @@ class WasmDebugInfo : public Struct { V8_EXPORT_PRIVATE static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset); + // Clear a previously set breakpoint in the given function at the given byte + // offset within that function. + V8_EXPORT_PRIVATE static void ClearBreakpoint(Handle<WasmDebugInfo>, + int func_index, int offset); + // Make a set of functions always execute in the interpreter without setting // breakpoints. V8_EXPORT_PRIVATE static void RedirectToInterpreter(Handle<WasmDebugInfo>, diff --git a/deps/v8/src/wasm/wasm-opcodes.cc b/deps/v8/src/wasm/wasm-opcodes.cc index 879da1445ba17c..3bd76ae43b8c08 100644 --- a/deps/v8/src/wasm/wasm-opcodes.cc +++ b/deps/v8/src/wasm/wasm-opcodes.cc @@ -147,11 +147,11 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { CASE_OP(Drop, "drop") CASE_OP(Select, "select") CASE_OP(SelectWithType, "select") - CASE_OP(GetLocal, "local.get") - CASE_OP(SetLocal, "local.set") - CASE_OP(TeeLocal, "local.tee") - CASE_OP(GetGlobal, "global.get") - CASE_OP(SetGlobal, "global.set") + CASE_OP(LocalGet, "local.get") + CASE_OP(LocalSet, "local.set") + CASE_OP(LocalTee, "local.tee") + CASE_OP(GlobalGet, "global.get") + CASE_OP(GlobalSet, "global.set") CASE_OP(TableGet, "table.get") CASE_OP(TableSet, "table.set") CASE_ALL_OP(Const, "const") @@ -222,6 +222,8 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { CASE_SIMD_OP(Splat, "splat") CASE_SIMD_OP(Neg, "neg") CASE_F64x2_OP(Neg, "neg") + CASE_F64x2_OP(Sqrt, "sqrt") + CASE_F32x4_OP(Sqrt, "sqrt") CASE_I64x2_OP(Neg, "neg") CASE_SIMD_OP(Eq, "eq") CASE_F64x2_OP(Eq, "eq") @@ -272,7 +274,9 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { CASE_F32x4_OP(ReplaceLane, "replace_lane") CASE_I64x2_OP(ExtractLane, "extract_lane") CASE_I64x2_OP(ReplaceLane, "replace_lane") - CASE_SIMDI_OP(ExtractLane, "extract_lane") + CASE_I32x4_OP(ExtractLane, "extract_lane") + CASE_SIGN_OP(I16x8, ExtractLane, "extract_lane") + CASE_SIGN_OP(I8x16, ExtractLane, "extract_lane") CASE_SIMDI_OP(ReplaceLane, "replace_lane") CASE_SIGN_OP(SIMDI, Min, "min") CASE_SIGN_OP(I64x2, Min, "min") @@ -302,6 +306,7 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { CASE_S128_OP(Xor, "xor") CASE_S128_OP(Not, "not") CASE_S128_OP(Select, "select") + CASE_S8x16_OP(Swizzle, "swizzle") CASE_S8x16_OP(Shuffle, "shuffle") CASE_S1x2_OP(AnyTrue, "any_true") CASE_S1x2_OP(AllTrue, "all_true") @@ -311,6 +316,10 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) { CASE_S1x8_OP(AllTrue, "all_true") CASE_S1x16_OP(AnyTrue, "any_true") CASE_S1x16_OP(AllTrue, "all_true") + CASE_F64x2_OP(Qfma, "qfma") + CASE_F64x2_OP(Qfms, "qfms") + CASE_F32x4_OP(Qfma, "qfma") + CASE_F32x4_OP(Qfms, "qfms") // Atomic operations. CASE_OP(AtomicNotify, "atomic.notify") @@ -489,7 +498,7 @@ constexpr const FunctionSig* kCachedSigs[] = { // gcc 4.7 - 4.9 has a bug which causes the constexpr attribute to get lost when // passing functions (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892). Hence // encapsulate these constexpr functions in functors. -// TODO(clemensh): Remove this once we require gcc >= 5.0. +// TODO(clemensb): Remove this once we require gcc >= 5.0. struct GetShortOpcodeSigIndex { constexpr WasmOpcodeSig operator()(byte opcode) const { diff --git a/deps/v8/src/wasm/wasm-opcodes.h b/deps/v8/src/wasm/wasm-opcodes.h index 0b19d7452c352f..f37f7f05207aec 100644 --- a/deps/v8/src/wasm/wasm-opcodes.h +++ b/deps/v8/src/wasm/wasm-opcodes.h @@ -48,11 +48,11 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&); V(Drop, 0x1a, _) \ V(Select, 0x1b, _) \ V(SelectWithType, 0x1c, _) \ - V(GetLocal, 0x20, _) \ - V(SetLocal, 0x21, _) \ - V(TeeLocal, 0x22, _) \ - V(GetGlobal, 0x23, _) \ - V(SetGlobal, 0x24, _) \ + V(LocalGet, 0x20, _) \ + V(LocalSet, 0x21, _) \ + V(LocalTee, 0x22, _) \ + V(GlobalGet, 0x23, _) \ + V(GlobalSet, 0x24, _) \ V(TableGet, 0x25, _) \ V(TableSet, 0x26, _) \ V(I32Const, 0x41, _) \ @@ -396,8 +396,9 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&); V(I64x2MaxU, 0xfd91, s_ss) \ V(F32x4Abs, 0xfd95, s_s) \ V(F32x4Neg, 0xfd96, s_s) \ - V(F32x4RecipApprox, 0xfd98, s_s) \ - V(F32x4RecipSqrtApprox, 0xfd99, s_s) \ + V(F32x4Sqrt, 0xfd97, s_s) \ + V(F32x4Qfma, 0xfd98, s_sss) \ + V(F32x4Qfms, 0xfd99, s_sss) \ V(F32x4Add, 0xfd9a, s_ss) \ V(F32x4Sub, 0xfd9b, s_ss) \ V(F32x4Mul, 0xfd9c, s_ss) \ @@ -406,6 +407,9 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&); V(F32x4Max, 0xfd9f, s_ss) \ V(F64x2Abs, 0xfda0, s_s) \ V(F64x2Neg, 0xfda1, s_s) \ + V(F64x2Sqrt, 0xfda2, s_s) \ + V(F64x2Qfma, 0xfda3, s_sss) \ + V(F64x2Qfms, 0xfda4, s_sss) \ V(F64x2Add, 0xfda5, s_ss) \ V(F64x2Sub, 0xfda6, s_ss) \ V(F64x2Mul, 0xfda7, s_ss) \ @@ -416,6 +420,7 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&); V(I32x4UConvertF32x4, 0xfdac, s_s) \ V(F32x4SConvertI32x4, 0xfdaf, s_s) \ V(F32x4UConvertI32x4, 0xfdb0, s_s) \ + V(S8x16Swizzle, 0xfdc0, s_ss) \ V(I8x16SConvertI16x8, 0xfdc6, s_ss) \ V(I8x16UConvertI16x8, 0xfdc7, s_ss) \ V(I16x8SConvertI32x4, 0xfdc8, s_ss) \ @@ -430,11 +435,15 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&); V(I32x4UConvertI16x8High, 0xfdd1, s_s) \ V(I16x8AddHoriz, 0xfdbd, s_ss) \ V(I32x4AddHoriz, 0xfdbe, s_ss) \ - V(F32x4AddHoriz, 0xfdbf, s_ss) + V(F32x4AddHoriz, 0xfdbf, s_ss) \ + V(F32x4RecipApprox, 0xfde0, s_s) \ + V(F32x4RecipSqrtApprox, 0xfde1, s_s) #define FOREACH_SIMD_1_OPERAND_1_PARAM_OPCODE(V) \ - V(I8x16ExtractLane, 0xfd05, _) \ - V(I16x8ExtractLane, 0xfd09, _) \ + V(I8x16ExtractLaneS, 0xfd05, _) \ + V(I8x16ExtractLaneU, 0xfd06, _) \ + V(I16x8ExtractLaneS, 0xfd09, _) \ + V(I16x8ExtractLaneU, 0xfd0a, _) \ V(I32x4ExtractLane, 0xfd0d, _) \ V(I64x2ExtractLane, 0xfd10, _) \ V(F32x4ExtractLane, 0xfd13, _) \ diff --git a/deps/v8/src/wasm/wasm-serialization.cc b/deps/v8/src/wasm/wasm-serialization.cc index 81460b9fe29912..f1fa76b98a8443 100644 --- a/deps/v8/src/wasm/wasm-serialization.cc +++ b/deps/v8/src/wasm/wasm-serialization.cc @@ -289,9 +289,6 @@ class V8_EXPORT_PRIVATE NativeModuleSerializer { Vector<WasmCode* const> code_table_; bool write_called_; - // Reverse lookup tables for embedded addresses. - std::map<Address, uint32_t> wasm_stub_targets_lookup_; - DISALLOW_COPY_AND_ASSIGN(NativeModuleSerializer); }; @@ -301,11 +298,6 @@ NativeModuleSerializer::NativeModuleSerializer( DCHECK_NOT_NULL(native_module_); // TODO(mtrofin): persist the export wrappers. Ideally, we'd only persist // the unique ones, i.e. the cache. - for (uint32_t i = 0; i < WasmCode::kRuntimeStubCount; ++i) { - Address addr = native_module_->runtime_stub_entry( - static_cast<WasmCode::RuntimeStubId>(i)); - wasm_stub_targets_lookup_.insert(std::make_pair(addr, i)); - } } size_t NativeModuleSerializer::MeasureCode(const WasmCode* code) const { @@ -367,7 +359,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) { writer->WriteVector(code->source_positions()); writer->WriteVector(Vector<byte>::cast(code->protected_instructions())); #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM || \ - V8_TARGET_ARCH_PPC + V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390X // On platforms that don't support misaligned word stores, copy to an aligned // buffer if necessary so we can relocate the serialized code. std::unique_ptr<byte[]> aligned_buffer; @@ -400,10 +392,9 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) { SetWasmCalleeTag(iter.rinfo(), tag); } break; case RelocInfo::WASM_STUB_CALL: { - Address orig_target = orig_iter.rinfo()->wasm_stub_call_address(); - auto stub_iter = wasm_stub_targets_lookup_.find(orig_target); - DCHECK(stub_iter != wasm_stub_targets_lookup_.end()); - uint32_t tag = stub_iter->second; + Address target = orig_iter.rinfo()->wasm_stub_call_address(); + uint32_t tag = native_module_->GetRuntimeStubId(target); + DCHECK_GT(WasmCode::kRuntimeStubCount, tag); SetWasmCalleeTag(iter.rinfo(), tag); } break; case RelocInfo::EXTERNAL_REFERENCE: { @@ -550,6 +541,8 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) { RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED); + auto jump_tables_ref = + native_module_->FindJumpTablesForCode(code->instruction_start()); for (RelocIterator iter(code->instructions(), code->reloc_info(), code->constant_pool(), mask); !iter.done(); iter.next()) { @@ -557,15 +550,16 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) { switch (mode) { case RelocInfo::WASM_CALL: { uint32_t tag = GetWasmCalleeTag(iter.rinfo()); - Address target = native_module_->GetCallTargetForFunction(tag); + Address target = + native_module_->GetNearCallTargetForFunction(tag, jump_tables_ref); iter.rinfo()->set_wasm_call_address(target, SKIP_ICACHE_FLUSH); break; } case RelocInfo::WASM_STUB_CALL: { uint32_t tag = GetWasmCalleeTag(iter.rinfo()); DCHECK_LT(tag, WasmCode::kRuntimeStubCount); - Address target = native_module_->runtime_stub_entry( - static_cast<WasmCode::RuntimeStubId>(tag)); + Address target = native_module_->GetNearRuntimeStubEntry( + static_cast<WasmCode::RuntimeStubId>(tag), jump_tables_ref); iter.rinfo()->set_wasm_stub_call_address(target, SKIP_ICACHE_FLUSH); break; } @@ -628,7 +622,6 @@ MaybeHandle<WasmModuleObject> DeserializeNativeModule( auto shared_native_module = isolate->wasm_engine()->NewNativeModule( isolate, enabled_features, std::move(decode_result.value())); shared_native_module->SetWireBytes(OwnedVector<uint8_t>::Of(wire_bytes_vec)); - shared_native_module->SetRuntimeStubs(isolate); Handle<FixedArray> export_wrappers; CompileJsToWasmWrappers(isolate, shared_native_module->module(), diff --git a/deps/v8/src/wasm/wasm-text.cc b/deps/v8/src/wasm/wasm-text.cc index 44abd7144596a5..fedd37ccd384d9 100644 --- a/deps/v8/src/wasm/wasm-text.cc +++ b/deps/v8/src/wasm/wasm-text.cc @@ -154,9 +154,9 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes, os << WasmOpcodes::OpcodeName(opcode) << ' ' << imm.index; break; } - case kExprGetLocal: - case kExprSetLocal: - case kExprTeeLocal: { + case kExprLocalGet: + case kExprLocalSet: + case kExprLocalTee: { LocalIndexImmediate<Decoder::kNoValidate> imm(&i, i.pc()); os << WasmOpcodes::OpcodeName(opcode) << ' ' << imm.index; break; @@ -166,8 +166,8 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes, os << WasmOpcodes::OpcodeName(opcode) << ' ' << imm.index; break; } - case kExprGetGlobal: - case kExprSetGlobal: { + case kExprGlobalGet: + case kExprGlobalSet: { GlobalIndexImmediate<Decoder::kNoValidate> imm(&i, i.pc()); os << WasmOpcodes::OpcodeName(opcode) << ' ' << imm.index; break; @@ -304,8 +304,10 @@ void PrintWasmText(const WasmModule* module, const ModuleWireBytes& wire_bytes, break; } - case kExprI8x16ExtractLane: - case kExprI16x8ExtractLane: + case kExprI8x16ExtractLaneS: + case kExprI8x16ExtractLaneU: + case kExprI16x8ExtractLaneS: + case kExprI16x8ExtractLaneU: case kExprI32x4ExtractLane: case kExprI64x2ExtractLane: case kExprF32x4ExtractLane: diff --git a/deps/v8/src/zone/OWNERS b/deps/v8/src/zone/OWNERS index 01c515ab90f287..e4e653da5bac7f 100644 --- a/deps/v8/src/zone/OWNERS +++ b/deps/v8/src/zone/OWNERS @@ -1,3 +1,3 @@ -clemensh@chromium.org +clemensb@chromium.org sigurds@chromium.org verwaest@chromium.org diff --git a/deps/v8/test/benchmarks/benchmarks.status b/deps/v8/test/benchmarks/benchmarks.status index d176e35312f032..4941ac2be6f9ab 100644 --- a/deps/v8/test/benchmarks/benchmarks.status +++ b/deps/v8/test/benchmarks/benchmarks.status @@ -35,6 +35,7 @@ # Slow tests. 'kraken/imaging-gaussian-blur': [PASS, SLOW], 'octane/typescript': [PASS, SLOW], + 'octane/box2d': [PASS, SLOW], }], # ALWAYS # Slow variants. @@ -42,7 +43,6 @@ # Slow tests. 'kraken/ai-astar': [PASS, SLOW], 'kraken/imaging-desaturate': [PASS, SLOW], - 'octane/box2d': [PASS, SLOW], 'octane/code-load': [PASS, SLOW], 'octane/crypto': [PASS, SLOW], 'octane/gbemu-part1': [PASS, SLOW], @@ -64,6 +64,12 @@ 'octane/zlib': [SKIP], }], +['variant == stress_incremental_marking', { + # Too slow for stress_incremental_marking. + 'octane/box2d': [SKIP], + 'octane/typescript': [SKIP], +}], + ['gc_fuzzer', { # Too slow for gc fuzzing. 'octane/earley-boyer' : [PASS, SLOW, ['mode == debug', SKIP]], diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn index d0934c99773456..6d6bcdcd67fce4 100644 --- a/deps/v8/test/cctest/BUILD.gn +++ b/deps/v8/test/cctest/BUILD.gn @@ -161,6 +161,7 @@ v8_source_set("cctest_sources") { "interpreter/test-source-positions.cc", "libplatform/test-tracing.cc", "libsampler/test-sampler.cc", + "manually-externalized-buffer.h", "parsing/test-parse-decision.cc", "parsing/test-preparser.cc", "parsing/test-scanner-streams.cc", @@ -185,6 +186,7 @@ v8_source_set("cctest_sources") { "test-api.h", "test-array-list.cc", "test-atomicops.cc", + "test-backing-store.cc", "test-bignum-dtoa.cc", "test-bignum.cc", "test-bit-vector.cc", @@ -267,6 +269,7 @@ v8_source_set("cctest_sources") { "unicode-helpers.cc", "unicode-helpers.h", "wasm/test-c-wasm-entry.cc", + "wasm/test-grow-memory.cc", "wasm/test-jump-table-assembler.cc", "wasm/test-run-wasm-64.cc", "wasm/test-run-wasm-asmjs.cc", diff --git a/deps/v8/test/cctest/DEPS b/deps/v8/test/cctest/DEPS index 7373012870d578..06ae6f87f66203 100644 --- a/deps/v8/test/cctest/DEPS +++ b/deps/v8/test/cctest/DEPS @@ -1,6 +1,7 @@ include_rules = [ + "+perfetto", + "+protos/perfetto", "+src", "+tools", "+torque-generated", - "+perfetto", -] \ No newline at end of file +] diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index dcfca2b2df419d..6adf2041cf0630 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -327,9 +327,9 @@ int main(int argc, char* argv[]) { CcTest::set_array_buffer_allocator( v8::ArrayBuffer::Allocator::NewDefaultAllocator()); - v8::RegisterExtension(v8::base::make_unique<i::PrintExtension>()); - v8::RegisterExtension(v8::base::make_unique<i::ProfilerExtension>()); - v8::RegisterExtension(v8::base::make_unique<i::TraceExtension>()); + v8::RegisterExtension(std::make_unique<i::PrintExtension>()); + v8::RegisterExtension(std::make_unique<i::ProfilerExtension>()); + v8::RegisterExtension(std::make_unique<i::TraceExtension>()); int tests_run = 0; bool print_run_count = true; diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index b1a7b5c1012225..430ca647b745d8 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -151,6 +151,8 @@ # Pass but take too long with the simulator. 'test-api/ExternalArrays': [PASS, SLOW], 'test-api/Threading*': [SKIP], + 'test-cpu-profiler/MultipleIsolates': [PASS, SLOW], + 'test-debug/DebugBreakStackTrace': [PASS, SLOW], }], # 'arch == arm64 and simulator_run' ############################################################################## @@ -227,6 +229,7 @@ # operations. 'test-run-wasm-atomics/*': [SKIP], 'test-run-wasm-atomics64/*': [SKIP], + 'test-regexp/Peephole*': [SKIP], }], # 'byteorder == big' ############################################################################## @@ -259,6 +262,7 @@ ['arch == arm and simulator_run', { # Pass but take too long with the simulator. 'test-api/Threading*': [SKIP], + 'test-cpu-profiler/MultipleIsolates': [PASS, SLOW], }], # 'arch == arm and simulator_run' ############################################################################## @@ -471,8 +475,10 @@ 'test-api/WasmI32AtomicWaitCallback': [SKIP], 'test-api/WasmI64AtomicWaitCallback': [SKIP], 'test-api/WasmStreaming*': [SKIP], + 'test-backing-store/Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree': [SKIP], 'test-c-wasm-entry/*': [SKIP], 'test-jump-table-assembler/*': [SKIP], + 'test-grow-memory/*': [SKIP], 'test-run-wasm-64/*': [SKIP], 'test-run-wasm-asmjs/*': [SKIP], 'test-run-wasm-atomics64/*': [SKIP], @@ -610,4 +616,12 @@ '*': [SKIP], }], # variant == jitless and not embedded_builtins +############################################################################## +['variant == turboprop', { + # Require inlining. + 'test-cpu-profiler/DeoptAtFirstLevelInlinedSource': [SKIP], + 'test-cpu-profiler/DeoptAtSecondLevelInlinedSource': [SKIP], + 'test-cpu-profiler/DeoptUntrackedFunction': [SKIP], +}], # variant == turboprop + ] diff --git a/deps/v8/test/cctest/compiler/serializer-tester.cc b/deps/v8/test/cctest/compiler/serializer-tester.cc index 338d1bcbfb1d2c..01979a220104d7 100644 --- a/deps/v8/test/cctest/compiler/serializer-tester.cc +++ b/deps/v8/test/cctest/compiler/serializer-tester.cc @@ -52,17 +52,19 @@ SerializerTester::SerializerTester(const char* source) TEST(SerializeEmptyFunction) { SerializerTester tester( "function f() {}; %EnsureFeedbackVectorForFunction(f); return f;"); - CHECK(tester.function().IsSerializedForCompilation()); + JSFunctionRef function = tester.function(); + CHECK( + function.shared().IsSerializedForCompilation(function.feedback_vector())); } -// This helper function allows for testing weather an inlinee candidate +// This helper function allows for testing whether an inlinee candidate // was properly serialized. It expects that the top-level function (that is // run through the SerializerTester) will return its inlinee candidate. void CheckForSerializedInlinee(const char* source, int argc = 0, Handle<Object> argv[] = {}) { SerializerTester tester(source); JSFunctionRef f = tester.function(); - CHECK(f.IsSerializedForCompilation()); + CHECK(f.shared().IsSerializedForCompilation(f.feedback_vector())); MaybeHandle<Object> g_obj = Execution::Call( tester.isolate(), tester.function().object(), diff --git a/deps/v8/test/cctest/compiler/serializer-tester.h b/deps/v8/test/cctest/compiler/serializer-tester.h index 7c8016ef810ffa..fe5f93895f00a1 100644 --- a/deps/v8/test/cctest/compiler/serializer-tester.h +++ b/deps/v8/test/cctest/compiler/serializer-tester.h @@ -5,6 +5,8 @@ #ifndef V8_CCTEST_COMPILER_SERIALIZER_TESTER_H_ #define V8_CCTEST_COMPILER_SERIALIZER_TESTER_H_ +#include <memory> + #include "src/compiler/js-heap-broker.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/compiler/test-code-assembler.cc b/deps/v8/test/cctest/compiler/test-code-assembler.cc index 9e6318ee88808a..56628ffde40313 100644 --- a/deps/v8/test/cctest/compiler/test-code-assembler.cc +++ b/deps/v8/test/cctest/compiler/test-code-assembler.cc @@ -18,38 +18,33 @@ namespace compiler { namespace { -using Label = CodeAssemblerLabel; using Variable = CodeAssemblerVariable; -Node* SmiTag(CodeAssembler& m, // NOLINT(runtime/references) - Node* value) { +Node* SmiTag(CodeAssembler* m, Node* value) { int32_t constant_value; - if (m.ToInt32Constant(value, &constant_value) && + if (m->ToInt32Constant(value, &constant_value) && Smi::IsValid(constant_value)) { - return m.SmiConstant(Smi::FromInt(constant_value)); + return m->SmiConstant(Smi::FromInt(constant_value)); } - return m.WordShl(value, m.IntPtrConstant(kSmiShiftSize + kSmiTagSize)); + return m->WordShl(value, m->IntPtrConstant(kSmiShiftSize + kSmiTagSize)); } -Node* UndefinedConstant(CodeAssembler& m) { // NOLINT(runtime/references) - return m.LoadRoot(RootIndex::kUndefinedValue); +Node* UndefinedConstant(CodeAssembler* m) { + return m->LoadRoot(RootIndex::kUndefinedValue); } -Node* SmiFromInt32(CodeAssembler& m, // NOLINT(runtime/references) - Node* value) { - value = m.ChangeInt32ToIntPtr(value); - return m.BitcastWordToTaggedSigned( - m.WordShl(value, kSmiShiftSize + kSmiTagSize)); +Node* SmiFromInt32(CodeAssembler* m, Node* value) { + value = m->ChangeInt32ToIntPtr(value); + return m->BitcastWordToTaggedSigned( + m->WordShl(value, kSmiShiftSize + kSmiTagSize)); } -Node* LoadObjectField(CodeAssembler& m, // NOLINT(runtime/references) - Node* object, int offset, +Node* LoadObjectField(CodeAssembler* m, Node* object, int offset, MachineType type = MachineType::AnyTagged()) { - return m.Load(type, object, m.IntPtrConstant(offset - kHeapObjectTag)); + return m->Load(type, object, m->IntPtrConstant(offset - kHeapObjectTag)); } -Node* LoadMap(CodeAssembler& m, // NOLINT(runtime/references) - Node* object) { +Node* LoadMap(CodeAssembler* m, Node* object) { return LoadObjectField(m, object, JSObject::kMapOffset); } @@ -59,7 +54,7 @@ TEST(SimpleSmiReturn) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - m.Return(SmiTag(m, m.Int32Constant(37))); + m.Return(SmiTag(&m, m.Int32Constant(37))); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(37, ft.CallChecked<Smi>()->value()); } @@ -91,7 +86,7 @@ TEST(SimpleCallRuntime1Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* b = SmiTag(m, m.Int32Constant(0)); + Node* b = SmiTag(&m, m.Int32Constant(0)); m.Return(m.CallRuntime(Runtime::kIsSmi, context, b)); FunctionTester ft(asm_tester.GenerateCode()); CHECK(ft.CallChecked<Oddball>().is_identical_to( @@ -104,7 +99,7 @@ TEST(SimpleTailCallRuntime1Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* b = SmiTag(m, m.Int32Constant(0)); + Node* b = SmiTag(&m, m.Int32Constant(0)); m.TailCallRuntime(Runtime::kIsSmi, context, b); FunctionTester ft(asm_tester.GenerateCode()); CHECK(ft.CallChecked<Oddball>().is_identical_to( @@ -117,8 +112,8 @@ TEST(SimpleCallRuntime2Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* a = SmiTag(m, m.Int32Constant(2)); - Node* b = SmiTag(m, m.Int32Constant(4)); + Node* a = SmiTag(&m, m.Int32Constant(2)); + Node* b = SmiTag(&m, m.Int32Constant(4)); m.Return(m.CallRuntime(Runtime::kAdd, context, a, b)); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(6, ft.CallChecked<Smi>()->value()); @@ -130,8 +125,8 @@ TEST(SimpleTailCallRuntime2Arg) { CodeAssembler m(asm_tester.state()); TNode<Context> context = m.HeapConstant(Handle<Context>(isolate->native_context())); - Node* a = SmiTag(m, m.Int32Constant(2)); - Node* b = SmiTag(m, m.Int32Constant(4)); + Node* a = SmiTag(&m, m.Int32Constant(2)); + Node* b = SmiTag(&m, m.Int32Constant(4)); m.TailCallRuntime(Runtime::kAdd, context, a, b); FunctionTester ft(asm_tester.GenerateCode()); CHECK_EQ(6, ft.CallChecked<Smi>()->value()); @@ -139,8 +134,7 @@ TEST(SimpleTailCallRuntime2Arg) { namespace { -Handle<JSFunction> CreateSumAllArgumentsFunction( - FunctionTester& ft) { // NOLINT(runtime/references) +Handle<JSFunction> CreateSumAllArgumentsFunction(FunctionTester* ft) { const char* source = "(function() {\n" " var sum = 0 + this;\n" @@ -149,7 +143,7 @@ Handle<JSFunction> CreateSumAllArgumentsFunction( " }\n" " return sum;\n" "})"; - return ft.NewFunction(source); + return ft->NewFunction(source); } } // namespace @@ -163,7 +157,7 @@ TEST(SimpleCallJSFunction0Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(kNumParams + 2); - Node* receiver = SmiTag(m, m.Int32Constant(42)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver); @@ -171,7 +165,7 @@ TEST(SimpleCallJSFunction0Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(42), *result.ToHandleChecked()); } @@ -185,8 +179,8 @@ TEST(SimpleCallJSFunction1Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(1); - Node* receiver = SmiTag(m, m.Int32Constant(42)); - Node* a = SmiTag(m, m.Int32Constant(13)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); + Node* a = SmiTag(&m, m.Int32Constant(13)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver, a); @@ -194,7 +188,7 @@ TEST(SimpleCallJSFunction1Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(55), *result.ToHandleChecked()); } @@ -208,9 +202,9 @@ TEST(SimpleCallJSFunction2Arg) { Node* function = m.Parameter(0); Node* context = m.Parameter(1); - Node* receiver = SmiTag(m, m.Int32Constant(42)); - Node* a = SmiTag(m, m.Int32Constant(13)); - Node* b = SmiTag(m, m.Int32Constant(153)); + Node* receiver = SmiTag(&m, m.Int32Constant(42)); + Node* a = SmiTag(&m, m.Int32Constant(13)); + Node* b = SmiTag(&m, m.Int32Constant(153)); Callable callable = CodeFactory::Call(isolate); Node* result = m.CallJS(callable, context, function, receiver, a, b); @@ -218,7 +212,7 @@ TEST(SimpleCallJSFunction2Arg) { } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); - Handle<JSFunction> sum = CreateSumAllArgumentsFunction(ft); + Handle<JSFunction> sum = CreateSumAllArgumentsFunction(&ft); MaybeHandle<Object> result = ft.Call(sum); CHECK_EQ(Smi::FromInt(208), *result.ToHandleChecked()); } @@ -228,7 +222,7 @@ TEST(VariableMerge1) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -247,7 +241,7 @@ TEST(VariableMerge2) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -269,7 +263,7 @@ TEST(VariableMerge3) { CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); Variable var2(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); var2.Bind(temp); @@ -293,7 +287,7 @@ TEST(VariableMergeBindFirst) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), merge(&m, &var1), end(&m); + CodeAssemblerLabel l1(&m), l2(&m), merge(&m, &var1), end(&m); TNode<Int32T> temp = m.Int32Constant(0); var1.Bind(temp); m.Branch(m.Int32Constant(1), &l1, &l2); @@ -319,8 +313,8 @@ TEST(VariableMergeSwitch) { CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); Variable var1(&m, MachineRepresentation::kTagged); - Label l1(&m), l2(&m), default_label(&m); - Label* labels[] = {&l1, &l2}; + CodeAssemblerLabel l1(&m), l2(&m), default_label(&m); + CodeAssemblerLabel* labels[] = {&l1, &l2}; int32_t values[] = {1, 2}; TNode<Smi> temp1 = m.SmiConstant(0); var1.Bind(temp1); @@ -345,7 +339,7 @@ TEST(SplitEdgeBranchMerge) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label l1(&m), merge(&m); + CodeAssemblerLabel l1(&m), merge(&m); m.Branch(m.Int32Constant(1), &l1, &merge); m.Bind(&l1); m.Goto(&merge); @@ -357,8 +351,8 @@ TEST(SplitEdgeSwitchMerge) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label l1(&m), l2(&m), l3(&m), default_label(&m); - Label* labels[] = {&l1, &l2}; + CodeAssemblerLabel l1(&m), l2(&m), l3(&m), default_label(&m); + CodeAssemblerLabel* labels[] = {&l1, &l2}; int32_t values[] = {1, 2}; m.Branch(m.Int32Constant(1), &l3, &l1); m.Bind(&l3); @@ -389,11 +383,11 @@ TEST(TestToConstant) { CHECK(m.ToInt32Constant(a, &value32)); CHECK(m.ToInt64Constant(a, &value64)); - a = UndefinedConstant(m); + a = UndefinedConstant(&m); CHECK(!m.ToInt32Constant(a, &value32)); CHECK(!m.ToInt64Constant(a, &value64)); - a = UndefinedConstant(m); + a = UndefinedConstant(&m); CHECK(!m.ToInt32Constant(a, &value32)); CHECK(!m.ToInt64Constant(a, &value64)); } @@ -402,17 +396,17 @@ TEST(DeferredCodePhiHints) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label block1(&m, Label::kDeferred); + CodeAssemblerLabel block1(&m, CodeAssemblerLabel::kDeferred); m.Goto(&block1); m.Bind(&block1); { Variable var_object(&m, MachineRepresentation::kTagged); - Label loop(&m, &var_object); + CodeAssemblerLabel loop(&m, &var_object); var_object.Bind(m.SmiConstant(0)); m.Goto(&loop); m.Bind(&loop); { - Node* map = LoadMap(m, var_object.value()); + Node* map = LoadMap(&m, var_object.value()); var_object.Bind(map); m.Goto(&loop); } @@ -424,10 +418,10 @@ TEST(TestOutOfScopeVariable) { Isolate* isolate(CcTest::InitIsolateOnce()); CodeAssemblerTester asm_tester(isolate); CodeAssembler m(asm_tester.state()); - Label block1(&m); - Label block2(&m); - Label block3(&m); - Label block4(&m); + CodeAssemblerLabel block1(&m); + CodeAssemblerLabel block2(&m); + CodeAssemblerLabel block3(&m); + CodeAssemblerLabel block4(&m); m.Branch(m.WordEqual(m.UncheckedCast<IntPtrT>(m.Parameter(0)), m.IntPtrConstant(0)), &block1, &block4); @@ -463,7 +457,7 @@ TEST(GotoIfException) { m.HeapConstant(isolate->factory()->to_string_tag_symbol()); Variable exception(&m, MachineRepresentation::kTagged); - Label exception_handler(&m); + CodeAssemblerLabel exception_handler(&m); Callable to_string = Builtins::CallableFor(isolate, Builtins::kToString); TNode<Object> string = m.CallStub(to_string, context, to_string_tag); m.GotoIfException(string, &exception_handler, &exception); @@ -498,9 +492,9 @@ TEST(GotoIfExceptionMultiple) { Node* second_value = m.Parameter(1); Node* third_value = m.Parameter(2); - Label exception_handler1(&m); - Label exception_handler2(&m); - Label exception_handler3(&m); + CodeAssemblerLabel exception_handler1(&m); + CodeAssemblerLabel exception_handler2(&m); + CodeAssemblerLabel exception_handler3(&m); Variable return_value(&m, MachineRepresentation::kWord32); Variable error(&m, MachineRepresentation::kTagged); @@ -515,20 +509,20 @@ TEST(GotoIfExceptionMultiple) { // try { ToString(param2); return 7 } catch (e) { ... } m.Bind(&exception_handler1); return_value.Bind(m.Int32Constant(7)); - error.Bind(UndefinedConstant(m)); + error.Bind(UndefinedConstant(&m)); string = m.CallStub(to_string, context, second_value); m.GotoIfException(string, &exception_handler2, &error); - m.Return(SmiFromInt32(m, return_value.value())); + m.Return(SmiFromInt32(&m, return_value.value())); // try { ToString(param3); return 7 & ~2; } catch (e) { return e; } m.Bind(&exception_handler2); // Return returnValue & ~2 - error.Bind(UndefinedConstant(m)); + error.Bind(UndefinedConstant(&m)); string = m.CallStub(to_string, context, third_value); m.GotoIfException(string, &exception_handler3, &error); m.Return(SmiFromInt32( - m, m.Word32And(return_value.value(), - m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1))))); + &m, m.Word32And(return_value.value(), + m.Word32Xor(m.Int32Constant(2), m.Int32Constant(-1))))); m.Bind(&exception_handler3); m.Return(error.value()); @@ -578,7 +572,7 @@ TEST(ExceptionHandler) { CodeAssembler m(asm_tester.state()); CodeAssembler::TVariable<Object> var(m.SmiConstant(0), &m); - Label exception(&m, {&var}, Label::kDeferred); + CodeAssemblerLabel exception(&m, {&var}, CodeAssemblerLabel::kDeferred); { CodeAssemblerScopedExceptionHandler handler(&m, &exception, &var); TNode<Context> context = diff --git a/deps/v8/test/cctest/compiler/test-gap-resolver.cc b/deps/v8/test/cctest/compiler/test-gap-resolver.cc index ca26e0b49f6bf9..a7b6514c1f2dd5 100644 --- a/deps/v8/test/cctest/compiler/test-gap-resolver.cc +++ b/deps/v8/test/cctest/compiler/test-gap-resolver.cc @@ -353,7 +353,7 @@ class ParallelMoveCreator : public HandleAndZoneScope { }; int index = rng_->NextInt(kMaxIndex); // destination can't be Constant. - switch (rng_->NextInt(is_source ? 5 : 4)) { + switch (rng_->NextInt(is_source ? 3 : 2)) { case 0: return AllocatedOperand(LocationOperand::STACK_SLOT, rep, GetValidSlotIndex(rep, index)); @@ -361,12 +361,6 @@ class ParallelMoveCreator : public HandleAndZoneScope { return AllocatedOperand(LocationOperand::REGISTER, rep, GetValidRegisterCode(rep, index)); case 2: - return ExplicitOperand(LocationOperand::REGISTER, rep, - GetValidRegisterCode(rep, 1)); - case 3: - return ExplicitOperand(LocationOperand::STACK_SLOT, rep, - GetValidSlotIndex(rep, index)); - case 4: return ConstantOperand(index); } UNREACHABLE(); diff --git a/deps/v8/test/cctest/compiler/test-jump-threading.cc b/deps/v8/test/cctest/compiler/test-jump-threading.cc index 44bee022b352c2..7440da7fb02f02 100644 --- a/deps/v8/test/cctest/compiler/test-jump-threading.cc +++ b/deps/v8/test/cctest/compiler/test-jump-threading.cc @@ -109,16 +109,16 @@ class TestCode : public HandleAndZoneScope { } }; -void VerifyForwarding(TestCode& code, // NOLINT(runtime/references) - int count, int* expected) { +void VerifyForwarding(TestCode* code, int count, int* expected) { v8::internal::AccountingAllocator allocator; Zone local_zone(&allocator, ZONE_NAME); ZoneVector<RpoNumber> result(&local_zone); - JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_, true); + JumpThreading::ComputeForwarding(&local_zone, &result, &code->sequence_, + true); CHECK(count == static_cast<int>(result.size())); for (int i = 0; i < count; i++) { - CHECK(expected[i] == result[i].ToInt()); + CHECK_EQ(expected[i], result[i].ToInt()); } } @@ -133,7 +133,7 @@ TEST(FwEmpty1) { code.End(); static int expected[] = {2, 2, 2}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -150,7 +150,7 @@ TEST(FwEmptyN) { code.End(); static int expected[] = {2, 2, 2}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } } @@ -162,7 +162,7 @@ TEST(FwNone1) { code.End(); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -174,7 +174,7 @@ TEST(FwMoves1) { code.End(); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -188,7 +188,7 @@ TEST(FwMoves2) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -202,7 +202,7 @@ TEST(FwMoves2b) { code.End(); static int expected[] = {0, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -216,7 +216,7 @@ TEST(FwOther2) { code.End(); static int expected[] = {0, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -229,7 +229,7 @@ TEST(FwNone2a) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -242,7 +242,7 @@ TEST(FwNone2b) { code.End(); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -253,7 +253,7 @@ TEST(FwLoop1) { code.Jump(0); static int expected[] = {0}; - VerifyForwarding(code, 1, expected); + VerifyForwarding(&code, 1, expected); } @@ -266,7 +266,7 @@ TEST(FwLoop2) { code.Jump(0); static int expected[] = {0, 0}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -281,7 +281,7 @@ TEST(FwLoop3) { code.Jump(0); static int expected[] = {0, 0, 0}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -294,7 +294,7 @@ TEST(FwLoop1b) { code.Jump(1); static int expected[] = {1, 1}; - VerifyForwarding(code, 2, expected); + VerifyForwarding(&code, 2, expected); } @@ -309,7 +309,7 @@ TEST(FwLoop2b) { code.Jump(1); static int expected[] = {1, 1, 1}; - VerifyForwarding(code, 3, expected); + VerifyForwarding(&code, 3, expected); } @@ -326,7 +326,7 @@ TEST(FwLoop3b) { code.Jump(1); static int expected[] = {1, 1, 1, 1}; - VerifyForwarding(code, 4, expected); + VerifyForwarding(&code, 4, expected); } @@ -345,7 +345,7 @@ TEST(FwLoop2_1a) { code.Jump(2); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -364,7 +364,7 @@ TEST(FwLoop2_1b) { code.Jump(2); static int expected[] = {2, 2, 2, 2, 2}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -383,7 +383,7 @@ TEST(FwLoop2_1c) { code.Jump(1); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -402,7 +402,7 @@ TEST(FwLoop2_1d) { code.Jump(1); static int expected[] = {1, 1, 1, 1, 1}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } @@ -423,7 +423,7 @@ TEST(FwLoop3_1a) { code.Jump(0); static int expected[] = {2, 2, 2, 2, 2, 2}; - VerifyForwarding(code, 6, expected); + VerifyForwarding(&code, 6, expected); } @@ -443,7 +443,7 @@ TEST(FwDiamonds) { code.End(); int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3}; - VerifyForwarding(code, 4, expected); + VerifyForwarding(&code, 4, expected); } } } @@ -470,7 +470,7 @@ TEST(FwDiamonds2) { int merge = k ? 3 : 4; int expected[] = {0, i ? 1 : merge, j ? 2 : merge, merge, 4}; - VerifyForwarding(code, 5, expected); + VerifyForwarding(&code, 5, expected); } } } @@ -504,7 +504,7 @@ TEST(FwDoubleDiamonds) { int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3, x ? 4 : 6, y ? 5 : 6, 6}; - VerifyForwarding(code, 7, expected); + VerifyForwarding(&code, 7, expected); } } } @@ -568,7 +568,7 @@ void RunPermutedChain(int* permutation, int size) { int expected[] = {size + 1, size + 1, size + 1, size + 1, size + 1, size + 1, size + 1}; - VerifyForwarding(code, size + 2, expected); + VerifyForwarding(&code, size + 2, expected); } @@ -604,55 +604,50 @@ void RunPermutedDiamond(int* permutation, int size) { int expected[] = {br, 5, 5, 5, 5, 5}; expected[br] = br; - VerifyForwarding(code, 6, expected); + VerifyForwarding(&code, 6, expected); } TEST(FwPermuted_diamond) { RunAllPermutations<4>(RunPermutedDiamond); } -void ApplyForwarding(TestCode& code, // NOLINT(runtime/references) - int size, int* forward) { - code.sequence_.RecomputeAssemblyOrderForTesting(); - ZoneVector<RpoNumber> vector(code.main_zone()); +void ApplyForwarding(TestCode* code, int size, int* forward) { + code->sequence_.RecomputeAssemblyOrderForTesting(); + ZoneVector<RpoNumber> vector(code->main_zone()); for (int i = 0; i < size; i++) { vector.push_back(RpoNumber::FromInt(forward[i])); } - JumpThreading::ApplyForwarding(code.main_zone(), vector, &code.sequence_); + JumpThreading::ApplyForwarding(code->main_zone(), vector, &code->sequence_); } -void CheckJump(TestCode& code, // NOLINT(runtime/references) - int pos, int target) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckJump(TestCode* code, int pos, int target) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(kArchJmp, instr->arch_opcode()); CHECK_EQ(1, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); - CHECK_EQ(target, code.sequence_.InputRpo(instr, 0).ToInt()); + CHECK_EQ(target, code->sequence_.InputRpo(instr, 0).ToInt()); } -void CheckNop(TestCode& code, // NOLINT(runtime/references) - int pos) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckNop(TestCode* code, int pos) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(kArchNop, instr->arch_opcode()); CHECK_EQ(0, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); } -void CheckBranch(TestCode& code, // NOLINT(runtime/references) - int pos, int t1, int t2) { - Instruction* instr = code.sequence_.InstructionAt(pos); +void CheckBranch(TestCode* code, int pos, int t1, int t2) { + Instruction* instr = code->sequence_.InstructionAt(pos); CHECK_EQ(2, static_cast<int>(instr->InputCount())); CHECK_EQ(0, static_cast<int>(instr->OutputCount())); CHECK_EQ(0, static_cast<int>(instr->TempCount())); - CHECK_EQ(t1, code.sequence_.InputRpo(instr, 0).ToInt()); - CHECK_EQ(t2, code.sequence_.InputRpo(instr, 1).ToInt()); + CHECK_EQ(t1, code->sequence_.InputRpo(instr, 0).ToInt()); + CHECK_EQ(t2, code->sequence_.InputRpo(instr, 1).ToInt()); } -void CheckAssemblyOrder(TestCode& code, // NOLINT(runtime/references) - int size, int* expected) { +void CheckAssemblyOrder(TestCode* code, int size, int* expected) { int i = 0; - for (auto const block : code.sequence_.instruction_blocks()) { + for (auto const block : code->sequence_.instruction_blocks()) { CHECK_EQ(expected[i++], block->ao_number().ToInt()); } } @@ -668,12 +663,12 @@ TEST(Rewire1) { code.End(); static int forward[] = {2, 2, 2}; - ApplyForwarding(code, 3, forward); - CheckJump(code, j1, 2); - CheckNop(code, j2); + ApplyForwarding(&code, 3, forward); + CheckJump(&code, j1, 2); + CheckNop(&code, j2); static int assembly[] = {0, 1, 1}; - CheckAssemblyOrder(code, 3, assembly); + CheckAssemblyOrder(&code, 3, assembly); } @@ -691,13 +686,13 @@ TEST(Rewire1_deferred) { code.End(); static int forward[] = {3, 3, 3, 3}; - ApplyForwarding(code, 4, forward); - CheckJump(code, j1, 3); - CheckNop(code, j2); - CheckNop(code, j3); + ApplyForwarding(&code, 4, forward); + CheckJump(&code, j1, 3); + CheckNop(&code, j2); + CheckNop(&code, j3); static int assembly[] = {0, 1, 2, 1}; - CheckAssemblyOrder(code, 4, assembly); + CheckAssemblyOrder(&code, 4, assembly); } @@ -717,12 +712,12 @@ TEST(Rewire2_deferred) { code.End(); static int forward[] = {0, 1, 2, 3}; - ApplyForwarding(code, 4, forward); - CheckJump(code, j1, 1); - CheckJump(code, j2, 3); + ApplyForwarding(&code, 4, forward); + CheckJump(&code, j1, 1); + CheckJump(&code, j2, 3); static int assembly[] = {0, 2, 3, 1}; - CheckAssemblyOrder(code, 4, assembly); + CheckAssemblyOrder(&code, 4, assembly); } @@ -742,18 +737,18 @@ TEST(Rewire_diamond) { code.End(); int forward[] = {0, 1, i ? 4 : 2, j ? 4 : 3, 4}; - ApplyForwarding(code, 5, forward); - CheckJump(code, j1, 1); - CheckBranch(code, b1, i ? 4 : 2, j ? 4 : 3); + ApplyForwarding(&code, 5, forward); + CheckJump(&code, j1, 1); + CheckBranch(&code, b1, i ? 4 : 2, j ? 4 : 3); if (i) { - CheckNop(code, j2); + CheckNop(&code, j2); } else { - CheckJump(code, j2, 4); + CheckJump(&code, j2, 4); } if (j) { - CheckNop(code, j3); + CheckNop(&code, j3); } else { - CheckJump(code, j3, 4); + CheckJump(&code, j3, 4); } int assembly[] = {0, 1, 2, 3, 4}; @@ -763,7 +758,7 @@ TEST(Rewire_diamond) { if (j) { for (int k = 4; k < 5; k++) assembly[k]--; } - CheckAssemblyOrder(code, 5, assembly); + CheckAssemblyOrder(&code, 5, assembly); } } } diff --git a/deps/v8/test/cctest/compiler/test-loop-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-analysis.cc index 231a3ada5af9db..38ce2f3463020b 100644 --- a/deps/v8/test/cctest/compiler/test-loop-analysis.cc +++ b/deps/v8/test/cctest/compiler/test-loop-analysis.cc @@ -201,9 +201,9 @@ struct While { } void chain(Node* control) { loop->ReplaceInput(0, control); } - void nest(While& that) { // NOLINT(runtime/references) - that.loop->ReplaceInput(1, exit); - this->loop->ReplaceInput(0, that.if_true); + void nest(While* that) { + that->loop->ReplaceInput(1, exit); + this->loop->ReplaceInput(0, that->if_true); } }; @@ -214,17 +214,17 @@ struct Counter { Node* phi; Node* add; - Counter(While& w, // NOLINT(runtime/references) - int32_t b, int32_t k) - : base(w.t.jsgraph.Int32Constant(b)), inc(w.t.jsgraph.Int32Constant(k)) { + Counter(While* w, int32_t b, int32_t k) + : base(w->t.jsgraph.Int32Constant(b)), + inc(w->t.jsgraph.Int32Constant(k)) { Build(w); } - Counter(While& w, Node* b, Node* k) : base(b), inc(k) { Build(w); } + Counter(While* w, Node* b, Node* k) : base(b), inc(k) { Build(w); } - void Build(While& w) { - phi = w.t.graph.NewNode(w.t.op(2, false), base, base, w.loop); - add = w.t.graph.NewNode(&kIntAdd, phi, inc); + void Build(While* w) { + phi = w->t.graph.NewNode(w->t.op(2, false), base, base, w->loop); + add = w->t.graph.NewNode(&kIntAdd, phi, inc); phi->ReplaceInput(1, add); } }; @@ -236,16 +236,16 @@ struct StoreLoop { Node* phi; Node* store; - explicit StoreLoop(While& w) // NOLINT(runtime/references) - : base(w.t.graph.start()), val(w.t.jsgraph.Int32Constant(13)) { + explicit StoreLoop(While* w) + : base(w->t.graph.start()), val(w->t.jsgraph.Int32Constant(13)) { Build(w); } - StoreLoop(While& w, Node* b, Node* v) : base(b), val(v) { Build(w); } + StoreLoop(While* w, Node* b, Node* v) : base(b), val(v) { Build(w); } - void Build(While& w) { - phi = w.t.graph.NewNode(w.t.op(2, true), base, base, w.loop); - store = w.t.graph.NewNode(&kStore, val, phi, w.loop); + void Build(While* w) { + phi = w->t.graph.NewNode(w->t.op(2, true), base, base, w->loop); + store = w->t.graph.NewNode(&kStore, val, phi, w->loop); phi->ReplaceInput(1, store); } }; @@ -287,7 +287,7 @@ TEST(LaLoop1c) { // One loop with a counter. LoopFinderTester t; While w(t, t.p0); - Counter c(w, 0, 1); + Counter c(&w, 0, 1); t.Return(c.phi, t.start, w.exit); Node* chain[] = {w.loop}; @@ -303,7 +303,7 @@ TEST(LaLoop1e) { // One loop with an effect phi. LoopFinderTester t; While w(t, t.p0); - StoreLoop c(w); + StoreLoop c(&w); t.Return(t.p0, c.phi, w.exit); Node* chain[] = {w.loop}; @@ -319,8 +319,8 @@ TEST(LaLoop1d) { // One loop with two counters. LoopFinderTester t; While w(t, t.p0); - Counter c1(w, 0, 1); - Counter c2(w, 1, 1); + Counter c1(&w, 0, 1); + Counter c2(&w, 1, 1); t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w.exit); Node* chain[] = {w.loop}; @@ -365,8 +365,8 @@ TEST(LaLoop2c) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); - Counter c2(w2, 0, 1); + Counter c1(&w1, 0, 1); + Counter c2(&w2, 0, 1); w2.chain(w1.exit); t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w2.exit); @@ -396,10 +396,10 @@ TEST(LaLoop2cc) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); + Counter c1(&w1, 0, 1); // various usage scenarios for the second loop. - Counter c2(w2, i & 1 ? t.p0 : c1.phi, i & 2 ? t.p0 : c1.phi); + Counter c2(&w2, i & 1 ? t.p0 : c1.phi, i & 2 ? t.p0 : c1.phi); if (i & 3) w2.branch->ReplaceInput(0, c1.phi); w2.chain(w1.exit); @@ -431,7 +431,7 @@ TEST(LaNestedLoop1) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - w2.nest(w1); + w2.nest(&w1); t.Return(t.p0, t.start, w1.exit); Node* chain[] = {w1.loop, w2.loop}; @@ -452,10 +452,10 @@ TEST(LaNestedLoop1c) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - Counter c1(w1, 0, 1); - Counter c2(w2, 0, 1); + Counter c1(&w1, 0, 1); + Counter c2(&w2, 0, 1); w2.branch->ReplaceInput(0, c2.phi); - w2.nest(w1); + w2.nest(&w1); t.Return(c1.phi, t.start, w1.exit); Node* chain[] = {w1.loop, w2.loop}; @@ -477,7 +477,7 @@ TEST(LaNestedLoop1x) { LoopFinderTester t; While w1(t, t.p0); While w2(t, t.p0); - w2.nest(w1); + w2.nest(&w1); const Operator* op = t.common.Phi(MachineRepresentation::kWord32, 2); Node* p1a = t.graph.NewNode(op, t.p0, t.p0, w1.loop); @@ -513,8 +513,8 @@ TEST(LaNestedLoop2) { While w1(t, t.p0); While w2(t, t.p0); While w3(t, t.p0); - w2.nest(w1); - w3.nest(w1); + w2.nest(&w1); + w3.nest(&w1); w3.chain(w2.exit); t.Return(t.p0, t.start, w1.exit); @@ -573,11 +573,11 @@ TEST(LaNestedLoop3c) { // Three nested loops with counters. LoopFinderTester t; While w1(t, t.p0); - Counter c1(w1, 0, 1); + Counter c1(&w1, 0, 1); While w2(t, t.p0); - Counter c2(w2, 0, 1); + Counter c2(&w2, 0, 1); While w3(t, t.p0); - Counter c3(w3, 0, 1); + Counter c3(&w3, 0, 1); w2.loop->ReplaceInput(0, w1.if_true); w3.loop->ReplaceInput(0, w2.if_true); w2.loop->ReplaceInput(1, w3.exit); diff --git a/deps/v8/test/cctest/compiler/test-multiple-return.cc b/deps/v8/test/cctest/compiler/test-multiple-return.cc index c054e7654a0fc1..ad1c7efbd71dec 100644 --- a/deps/v8/test/cctest/compiler/test-multiple-return.cc +++ b/deps/v8/test/cctest/compiler/test-multiple-return.cc @@ -43,81 +43,76 @@ CallDescriptor* CreateCallDescriptor(Zone* zone, int return_count, return compiler::GetWasmCallDescriptor(zone, builder.Build()); } -Node* MakeConstant(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, int value) { +Node* MakeConstant(RawMachineAssembler* m, MachineType type, int value) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Constant(static_cast<int32_t>(value)); + return m->Int32Constant(static_cast<int32_t>(value)); case MachineRepresentation::kWord64: - return m.Int64Constant(static_cast<int64_t>(value)); + return m->Int64Constant(static_cast<int64_t>(value)); case MachineRepresentation::kFloat32: - return m.Float32Constant(static_cast<float>(value)); + return m->Float32Constant(static_cast<float>(value)); case MachineRepresentation::kFloat64: - return m.Float64Constant(static_cast<double>(value)); + return m->Float64Constant(static_cast<double>(value)); default: UNREACHABLE(); } } -Node* Add(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Add(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Add(a, b); + return m->Int32Add(a, b); case MachineRepresentation::kWord64: - return m.Int64Add(a, b); + return m->Int64Add(a, b); case MachineRepresentation::kFloat32: - return m.Float32Add(a, b); + return m->Float32Add(a, b); case MachineRepresentation::kFloat64: - return m.Float64Add(a, b); + return m->Float64Add(a, b); default: UNREACHABLE(); } } -Node* Sub(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Sub(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Sub(a, b); + return m->Int32Sub(a, b); case MachineRepresentation::kWord64: - return m.Int64Sub(a, b); + return m->Int64Sub(a, b); case MachineRepresentation::kFloat32: - return m.Float32Sub(a, b); + return m->Float32Sub(a, b); case MachineRepresentation::kFloat64: - return m.Float64Sub(a, b); + return m->Float64Sub(a, b); default: UNREACHABLE(); } } -Node* Mul(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a, Node* b) { +Node* Mul(RawMachineAssembler* m, MachineType type, Node* a, Node* b) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Mul(a, b); + return m->Int32Mul(a, b); case MachineRepresentation::kWord64: - return m.Int64Mul(a, b); + return m->Int64Mul(a, b); case MachineRepresentation::kFloat32: - return m.Float32Mul(a, b); + return m->Float32Mul(a, b); case MachineRepresentation::kFloat64: - return m.Float64Mul(a, b); + return m->Float64Mul(a, b); default: UNREACHABLE(); } } -Node* ToInt32(RawMachineAssembler& m, // NOLINT(runtime/references) - MachineType type, Node* a) { +Node* ToInt32(RawMachineAssembler* m, MachineType type, Node* a) { switch (type.representation()) { case MachineRepresentation::kWord32: return a; case MachineRepresentation::kWord64: - return m.TruncateInt64ToInt32(a); + return m->TruncateInt64ToInt32(a); case MachineRepresentation::kFloat32: - return m.TruncateFloat32ToInt32(a); + return m->TruncateFloat32ToInt32(a); case MachineRepresentation::kFloat64: - return m.RoundFloat64ToInt32(a); + return m->RoundFloat64ToInt32(a); default: UNREACHABLE(); } @@ -159,9 +154,9 @@ void TestReturnMultipleValues(MachineType type) { using Node_ptr = Node*; std::unique_ptr<Node_ptr[]> returns(new Node_ptr[count]); for (int i = 0; i < count; ++i) { - if (i % 3 == 0) returns[i] = Add(m, type, p0, p1); - if (i % 3 == 1) returns[i] = Sub(m, type, p0, p1); - if (i % 3 == 2) returns[i] = Mul(m, type, p0, p1); + if (i % 3 == 0) returns[i] = Add(&m, type, p0, p1); + if (i % 3 == 1) returns[i] = Sub(&m, type, p0, p1); + if (i % 3 == 2) returns[i] = Mul(&m, type, p0, p1); } m.Return(count, returns.get()); @@ -175,7 +170,7 @@ void TestReturnMultipleValues(MachineType type) { #ifdef ENABLE_DISASSEMBLER if (FLAG_print_code) { StdoutStream os; - code->Disassemble("multi_value", os); + code->Disassemble("multi_value", os, handles.main_isolate()); } #endif @@ -201,29 +196,29 @@ void TestReturnMultipleValues(MachineType type) { // WasmContext dummy call_inputs[1] = mt.PointerConstant(nullptr); // Special inputs for the test. - call_inputs[2] = MakeConstant(mt, type, a); - call_inputs[3] = MakeConstant(mt, type, b); + call_inputs[2] = MakeConstant(&mt, type, a); + call_inputs[3] = MakeConstant(&mt, type, b); for (int i = 2; i < param_count; i++) { - call_inputs[2 + i] = MakeConstant(mt, type, i); + call_inputs[2 + i] = MakeConstant(&mt, type, i); } Node* ret_multi = mt.AddNode(mt.common()->Call(desc), input_count, call_inputs); - Node* ret = MakeConstant(mt, type, 0); + Node* ret = MakeConstant(&mt, type, 0); bool sign = false; for (int i = 0; i < count; ++i) { Node* x = (count == 1) ? ret_multi : mt.AddNode(mt.common()->Projection(i), ret_multi); - ret = sign ? Sub(mt, type, ret, x) : Add(mt, type, ret, x); + ret = sign ? Sub(&mt, type, ret, x) : Add(&mt, type, ret, x); if (i % 4 == 0) sign = !sign; } - mt.Return(ToInt32(mt, type, ret)); + mt.Return(ToInt32(&mt, type, ret)); #ifdef ENABLE_DISASSEMBLER Handle<Code> code2 = mt.GetCode(); if (FLAG_print_code) { StdoutStream os; - code2->Disassemble("multi_value_call", os); + code2->Disassemble("multi_value_call", os, handles.main_isolate()); } #endif CHECK_EQ(expect, mt.Call()); @@ -265,7 +260,7 @@ void ReturnLastValue(MachineType type) { std::unique_ptr<Node* []> returns(new Node*[return_count]); for (int i = 0; i < return_count; ++i) { - returns[i] = MakeConstant(m, type, i); + returns[i] = MakeConstant(&m, type, i); } m.Return(return_count, returns.get()); @@ -292,8 +287,9 @@ void ReturnLastValue(MachineType type) { Node* call = mt.AddNode(mt.common()->Call(desc), 2, inputs); - mt.Return(ToInt32( - mt, type, mt.AddNode(mt.common()->Projection(return_count - 1), call))); + mt.Return( + ToInt32(&mt, type, + mt.AddNode(mt.common()->Projection(return_count - 1), call))); CHECK_EQ(expect, mt.Call()); } @@ -327,7 +323,7 @@ void ReturnSumOfReturns(MachineType type) { std::unique_ptr<Node* []> returns(new Node*[return_count]); for (int i = 0; i < return_count; ++i) { - returns[i] = MakeConstant(m, type, i); + returns[i] = MakeConstant(&m, type, i); } m.Return(return_count, returns.get()); @@ -360,7 +356,7 @@ void ReturnSumOfReturns(MachineType type) { expect += i; result = mt.Int32Add( result, - ToInt32(mt, type, mt.AddNode(mt.common()->Projection(i), call))); + ToInt32(&mt, type, mt.AddNode(mt.common()->Projection(i), call))); } mt.Return(result); diff --git a/deps/v8/test/cctest/compiler/test-run-load-store.cc b/deps/v8/test/cctest/compiler/test-run-load-store.cc index 3a8e9d61d494f0..6f52f339f38425 100644 --- a/deps/v8/test/cctest/compiler/test-run-load-store.cc +++ b/deps/v8/test/cctest/compiler/test-run-load-store.cc @@ -37,6 +37,11 @@ enum TestAlignment { #define A_GIG (1024ULL * 1024ULL * 1024ULL) namespace { +byte* ComputeOffset(void* real_address, int32_t offset) { + return reinterpret_cast<byte*>(reinterpret_cast<Address>(real_address) - + offset); +} + void RunLoadInt32(const TestAlignment t) { RawMachineAssemblerTester<int32_t> m; @@ -65,7 +70,7 @@ void RunLoadInt32Offset(TestAlignment t) { for (size_t i = 0; i < arraysize(offsets); i++) { RawMachineAssemblerTester<int32_t> m; int32_t offset = offsets[i]; - byte* pointer = reinterpret_cast<byte*>(&p1) - offset; + byte* pointer = ComputeOffset(&p1, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { @@ -93,8 +98,8 @@ void RunLoadStoreFloat32Offset(TestAlignment t) { base::AddWithWraparound(0x2342AABB, base::MulWithWraparound(i, 3)); RawMachineAssemblerTester<int32_t> m; int32_t offset = i; - byte* from = reinterpret_cast<byte*>(&p1) - offset; - byte* to = reinterpret_cast<byte*>(&p2) - offset; + byte* from = ComputeOffset(&p1, offset); + byte* to = ComputeOffset(&p2, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), @@ -131,8 +136,8 @@ void RunLoadStoreFloat64Offset(TestAlignment t) { base::AddWithWraparound(0x2342AABB, base::MulWithWraparound(i, 3)); RawMachineAssemblerTester<int32_t> m; int32_t offset = i; - byte* from = reinterpret_cast<byte*>(&p1) - offset; - byte* to = reinterpret_cast<byte*>(&p2) - offset; + byte* from = ComputeOffset(&p1, offset); + byte* to = ComputeOffset(&p2, offset); // generate load [#base + #index] if (t == TestAlignment::kAligned) { Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), @@ -259,7 +264,7 @@ void RunLoadImmIndex(MachineType type, TestAlignment t) { for (int offset = -1; offset <= 200000; offset *= -5) { for (int i = 0; i < kNumElems; i++) { BufferedRawMachineAssemblerTester<CType> m; - void* base_pointer = &buffer[0] - offset; + void* base_pointer = ComputeOffset(&buffer[0], offset * sizeof(CType)); #ifdef V8_COMPRESS_POINTERS if (type.IsTagged()) { // When pointer compression is enabled then we need to access only diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc index 1e5a73389e15d0..ccc05ce11b67b0 100644 --- a/deps/v8/test/cctest/compiler/test-run-machops.cc +++ b/deps/v8/test/cctest/compiler/test-run-machops.cc @@ -10,9 +10,10 @@ #include "src/base/ieee754.h" #include "src/base/overflowing-math.h" #include "src/base/utils/random-number-generator.h" +#include "src/common/ptr-compr-inl.h" +#include "src/objects/objects-inl.h" #include "src/utils/boxed-float.h" #include "src/utils/utils.h" -#include "src/objects/objects-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/value-helper.h" @@ -410,12 +411,15 @@ TEST(CompressDecompressTaggedAnyPointer) { } TEST(CompressDecompressTaggedAnySigned) { - RawMachineAssemblerTester<int64_t> m; + RawMachineAssemblerTester<void*> m; Smi smi = Smi::FromInt(123); - int64_t smiPointer = static_cast<int64_t>(smi.ptr()); - Node* node = m.Int64Constant(smiPointer); + Node* node = m.Int64Constant(static_cast<int64_t>(smi.ptr())); m.Return(m.ChangeCompressedToTagged(m.ChangeTaggedToCompressed(node))); - CHECK_EQ(smiPointer, m.Call()); + + Object result = Object(reinterpret_cast<Address>(m.Call())); + Address smiPointer = + DecompressTaggedAny(m.isolate(), CompressTagged(smi.ptr())); + CHECK_EQ(smiPointer, result.ptr()); } TEST(CompressDecompressTaggedPointer) { @@ -432,13 +436,15 @@ TEST(CompressDecompressTaggedPointer) { } TEST(CompressDecompressTaggedSigned) { - RawMachineAssemblerTester<int64_t> m; + RawMachineAssemblerTester<void*> m; Smi smi = Smi::FromInt(123); - int64_t smiPointer = static_cast<int64_t>(smi.ptr()); - Node* node = m.Int64Constant(smiPointer); + Address smiPointer = smi.ptr(); + Node* node = m.Int64Constant(static_cast<int64_t>(smiPointer)); m.Return(m.ChangeCompressedSignedToTaggedSigned( m.ChangeTaggedSignedToCompressedSigned(node))); - CHECK_EQ(smiPointer, m.Call()); + + Object result = Object(reinterpret_cast<Address>(m.Call())); + CHECK_EQ(smiPointer, result.ptr()); } #endif // V8_COMPRESS_POINTERS diff --git a/deps/v8/test/cctest/compiler/test-run-native-calls.cc b/deps/v8/test/cctest/compiler/test-run-native-calls.cc index 026e8307aec213..6ab480743b10c5 100644 --- a/deps/v8/test/cctest/compiler/test-run-native-calls.cc +++ b/deps/v8/test/cctest/compiler/test-run-native-calls.cc @@ -254,7 +254,7 @@ Handle<Code> CompileGraph(const char* name, CallDescriptor* call_descriptor, #ifdef ENABLE_DISASSEMBLER if (FLAG_print_opt_code) { StdoutStream os; - code->Disassemble(name, os); + code->Disassemble(name, os, isolate); } #endif return code; @@ -327,38 +327,32 @@ class ArgsBuffer { return kTypes; } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - int32_t value) { - return raw.Int32Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, int32_t value) { + return raw->Int32Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - int64_t value) { - return raw.Int64Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, int64_t value) { + return raw->Int64Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - float32 value) { - return raw.Float32Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, float32 value) { + return raw->Float32Constant(value); } - Node* MakeConstant(RawMachineAssembler& raw, // NOLINT(runtime/references) - float64 value) { - return raw.Float64Constant(value); + Node* MakeConstant(RawMachineAssembler* raw, float64 value) { + return raw->Float64Constant(value); } - Node* LoadInput(RawMachineAssembler& raw, // NOLINT(runtime/references) - Node* base, int index) { - Node* offset = raw.Int32Constant(index * sizeof(CType)); - return raw.Load(MachineTypeForC<CType>(), base, offset); + Node* LoadInput(RawMachineAssembler* raw, Node* base, int index) { + Node* offset = raw->Int32Constant(index * sizeof(CType)); + return raw->Load(MachineTypeForC<CType>(), base, offset); } - Node* StoreOutput(RawMachineAssembler& raw, // NOLINT(runtime/references) - Node* value) { - Node* base = raw.PointerConstant(&output); - Node* offset = raw.Int32Constant(0); - return raw.Store(MachineTypeForC<CType>().representation(), base, offset, - value, kNoWriteBarrier); + Node* StoreOutput(RawMachineAssembler* raw, Node* value) { + Node* base = raw->PointerConstant(&output); + Node* offset = raw->Int32Constant(0); + return raw->Store(MachineTypeForC<CType>().representation(), base, offset, + value, kNoWriteBarrier); } // Computes the next set of inputs by updating the {input} array. @@ -425,7 +419,7 @@ template <typename CType> class Computer { public: static void Run(CallDescriptor* desc, - void (*build)(CallDescriptor*, RawMachineAssembler&), + void (*build)(CallDescriptor*, RawMachineAssembler*), CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { int num_params = ParamCount(desc); @@ -438,7 +432,7 @@ class Computer { Zone zone(isolate->allocator(), ZONE_NAME); Graph graph(&zone); RawMachineAssembler raw(isolate, &graph, desc); - build(desc, raw); + build(desc, &raw); inner = CompileGraph("Compute", desc, &graph, raw.ExportForTest()); } @@ -459,11 +453,11 @@ class Computer { int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = io.MakeConstant(raw, io.input[i]); + inputs[input_count++] = io.MakeConstant(&raw, io.input[i]); } Node* call = raw.CallN(desc, input_count, inputs); - Node* store = io.StoreOutput(raw, call); + Node* store = io.StoreOutput(&raw, call); USE(store); raw.Return(raw.Int32Constant(seed)); wrapper = CompileGraph("Compute-wrapper-const", cdesc, &graph, @@ -494,11 +488,11 @@ class Computer { int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = io.LoadInput(raw, base, i); + inputs[input_count++] = io.LoadInput(&raw, base, i); } Node* call = raw.CallN(desc, input_count, inputs); - Node* store = io.StoreOutput(raw, call); + Node* store = io.StoreOutput(&raw, call); USE(store); raw.Return(raw.Int32Constant(seed)); wrapper = @@ -704,28 +698,25 @@ TEST(Run_CopyTwentyInt32_all_allocatable_pairs) { } } - template <typename CType> static void Run_Computation( - CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&), + CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler*), CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { Computer<CType>::Run(desc, build, compute, seed); } - static uint32_t coeff[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113}; -static void Build_Int32_WeightedSum( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) - Node* result = raw.Int32Constant(0); +static void Build_Int32_WeightedSum(CallDescriptor* desc, + RawMachineAssembler* raw) { + Node* result = raw->Int32Constant(0); for (int i = 0; i < ParamCount(desc); i++) { - Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i])); - result = raw.Int32Add(result, term); + Node* term = raw->Int32Mul(raw->Parameter(i), raw->Int32Constant(coeff[i])); + result = raw->Int32Add(result, term); } - raw.Return(result); + raw->Return(result); } static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) { @@ -774,10 +765,8 @@ TEST_INT32_WEIGHTEDSUM(17) TEST_INT32_WEIGHTEDSUM(19) template <int which> -static void Build_Select( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) - raw.Return(raw.Parameter(which)); +static void Build_Select(CallDescriptor* desc, RawMachineAssembler* raw) { + raw->Return(raw->Parameter(which)); } template <typename CType, int which> @@ -950,9 +939,8 @@ TEST(Float64Select_stack_params_return_reg) { } template <typename CType, int which> -static void Build_Select_With_Call( - CallDescriptor* desc, - RawMachineAssembler& raw) { // NOLINT(runtime/references) +static void Build_Select_With_Call(CallDescriptor* desc, + RawMachineAssembler* raw) { Handle<Code> inner = Handle<Code>::null(); int num_params = ParamCount(desc); CHECK_LE(num_params, kMaxParamCount); @@ -971,16 +959,16 @@ static void Build_Select_With_Call( { // Build a call to the function that does the select. - Node* target = raw.HeapConstant(inner); - Node** inputs = raw.zone()->NewArray<Node*>(num_params + 1); + Node* target = raw->HeapConstant(inner); + Node** inputs = raw->zone()->NewArray<Node*>(num_params + 1); int input_count = 0; inputs[input_count++] = target; for (int i = 0; i < num_params; i++) { - inputs[input_count++] = raw.Parameter(i); + inputs[input_count++] = raw->Parameter(i); } - Node* call = raw.CallN(desc, input_count, inputs); - raw.Return(call); + Node* call = raw->CallN(desc, input_count, inputs); + raw->Return(call); } } diff --git a/deps/v8/test/cctest/heap/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h index 6f6cfb46b5c256..0b47665a781d3d 100644 --- a/deps/v8/test/cctest/heap/heap-tester.h +++ b/deps/v8/test/cctest/heap/heap-tester.h @@ -14,6 +14,7 @@ V(CompactionFullAbortedPage) \ V(CompactionPartiallyAbortedPage) \ V(CompactionPartiallyAbortedPageIntraAbortedPointers) \ + V(CompactionPartiallyAbortedPageWithInvalidatedSlots) \ V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \ V(CompactionSpaceDivideMultiplePages) \ V(CompactionSpaceDivideSinglePage) \ @@ -102,6 +103,7 @@ class HeapTester { // test-heap.cc static AllocationResult AllocateByteArrayForTest(Heap* heap, int length, AllocationType allocation); + static bool CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes); // test-mark-compact.cc static AllocationResult AllocateMapForTest(v8::internal::Isolate* isolate); diff --git a/deps/v8/test/cctest/heap/heap-utils.cc b/deps/v8/test/cctest/heap/heap-utils.cc index 8b53dab9c5dbba..3fa2714a61beb2 100644 --- a/deps/v8/test/cctest/heap/heap-utils.cc +++ b/deps/v8/test/cctest/heap/heap-utils.cc @@ -98,11 +98,15 @@ std::vector<Handle<FixedArray>> CreatePadding(Heap* heap, int padding_size, allocate_memory = free_memory; length = FixedArrayLenFromSize(allocate_memory); if (length <= 0) { - // Not enough room to create another fixed array. Let's create a filler. - if (free_memory > (2 * kTaggedSize)) { + // Not enough room to create another FixedArray, so create a filler. + if (allocation == i::AllocationType::kOld) { heap->CreateFillerObjectAt( *heap->old_space()->allocation_top_address(), free_memory, ClearRecordedSlots::kNo); + } else { + heap->CreateFillerObjectAt( + *heap->new_space()->allocation_top_address(), free_memory, + ClearRecordedSlots::kNo); } break; } @@ -127,8 +131,9 @@ void AllocateAllButNBytes(v8::internal::NewSpace* space, int extra_bytes, if (new_linear_size == 0) return; std::vector<Handle<FixedArray>> handles = heap::CreatePadding( space->heap(), new_linear_size, i::AllocationType::kYoung); - if (out_handles != nullptr) + if (out_handles != nullptr) { out_handles->insert(out_handles->end(), handles.begin(), handles.end()); + } } void FillCurrentPage(v8::internal::NewSpace* space, @@ -144,8 +149,9 @@ bool FillUpOnePage(v8::internal::NewSpace* space, if (space_remaining == 0) return false; std::vector<Handle<FixedArray>> handles = heap::CreatePadding( space->heap(), space_remaining, i::AllocationType::kYoung); - if (out_handles != nullptr) + if (out_handles != nullptr) { out_handles->insert(out_handles->end(), handles.begin(), handles.end()); + } return true; } diff --git a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc index b4122c9619ac3e..66354cab7f1c1e 100644 --- a/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc +++ b/deps/v8/test/cctest/heap/test-array-buffer-tracker.cc @@ -193,8 +193,8 @@ TEST(ArrayBuffer_UnregisterDuringSweep) { // barriers and proper synchronization this will trigger a data race on // TSAN. v8::ArrayBuffer::Contents contents = ab->Externalize(); - heap->isolate()->array_buffer_allocator()->Free(contents.Data(), - contents.ByteLength()); + contents.Deleter()(contents.Data(), contents.ByteLength(), + contents.DeleterData()); } } diff --git a/deps/v8/test/cctest/heap/test-compaction.cc b/deps/v8/test/cctest/heap/test-compaction.cc index 35bd9225ea85af..96eca0f5aecbe2 100644 --- a/deps/v8/test/cctest/heap/test-compaction.cc +++ b/deps/v8/test/cctest/heap/test-compaction.cc @@ -6,6 +6,7 @@ #include "src/heap/factory.h" #include "src/heap/heap-inl.h" #include "src/heap/mark-compact.h" +#include "src/heap/remembered-set.h" #include "src/objects/objects-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/heap/heap-tester.h" @@ -31,9 +32,8 @@ void CheckInvariantsOfAbortedPage(Page* page) { CHECK(!page->IsFlagSet(Page::COMPACTION_WAS_ABORTED)); } -void CheckAllObjectsOnPage( - std::vector<Handle<FixedArray>>& handles, // NOLINT(runtime/references) - Page* page) { +void CheckAllObjectsOnPage(const std::vector<Handle<FixedArray>>& handles, + Page* page) { for (Handle<FixedArray> fixed_array : handles) { CHECK(Page::FromHeapObject(*fixed_array) == page); } @@ -85,6 +85,18 @@ HEAP_TEST(CompactionFullAbortedPage) { } } +namespace { + +int GetObjectSize(int objects_per_page) { + int allocatable = + static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()); + // Make sure that object_size is a multiple of kTaggedSize. + int object_size = + ((allocatable / kTaggedSize) / objects_per_page) * kTaggedSize; + return Min(kMaxRegularHeapObjectSize, object_size); +} + +} // namespace HEAP_TEST(CompactionPartiallyAbortedPage) { if (FLAG_never_compact) return; @@ -97,10 +109,7 @@ HEAP_TEST(CompactionPartiallyAbortedPage) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -163,6 +172,81 @@ HEAP_TEST(CompactionPartiallyAbortedPage) { } } +HEAP_TEST(CompactionPartiallyAbortedPageWithInvalidatedSlots) { + if (FLAG_never_compact) return; + // Test evacuating a page partially when it contains recorded + // slots and invalidated objects. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + ManualGCScope manual_gc_scope; + FLAG_manual_evacuation_candidates_selection = true; + + const int objects_per_page = 10; + const int object_size = GetObjectSize(objects_per_page); + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + + heap::SealCurrentObjects(heap); + + { + HandleScope scope2(isolate); + // Fill another page with objects of size {object_size} (last one is + // properly adjusted). + CHECK(heap->old_space()->Expand()); + auto compaction_page_handles = heap::CreatePadding( + heap, + static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()), + AllocationType::kOld, object_size); + Page* to_be_aborted_page = + Page::FromHeapObject(*compaction_page_handles.front()); + for (Handle<FixedArray> object : compaction_page_handles) { + CHECK_EQ(Page::FromHeapObject(*object), to_be_aborted_page); + + for (int i = 0; i < object->length(); i++) { + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>( + to_be_aborted_page, object->RawFieldOfElementAt(i).address()); + } + } + // First object is going to be evacuated. + to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>( + *compaction_page_handles.front()); + // Last object is NOT going to be evacuated. + // This happens since not all objects fit on the only other page in the + // old space, the GC isn't allowed to allocate another page. + to_be_aborted_page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>( + *compaction_page_handles.back()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + + { + // Add another page that is filled with {num_objects} objects of size + // {object_size}. + HandleScope scope3(isolate); + CHECK(heap->old_space()->Expand()); + const int num_objects = 3; + std::vector<Handle<FixedArray>> page_to_fill_handles = + heap::CreatePadding(heap, object_size * num_objects, + AllocationType::kOld, object_size); + Page* page_to_fill = + Page::FromAddress(page_to_fill_handles.front()->address()); + + heap->set_force_oom(true); + CcTest::CollectAllGarbage(); + heap->mark_compact_collector()->EnsureSweepingCompleted(); + + CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.front()), + page_to_fill); + CHECK_EQ(Page::FromHeapObject(*compaction_page_handles.back()), + to_be_aborted_page); + } + } + } +} HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) { if (FLAG_never_compact) return; @@ -177,10 +261,7 @@ HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -271,10 +352,7 @@ HEAP_TEST(CompactionPartiallyAbortedPageWithStoreBufferEntries) { FLAG_manual_evacuation_candidates_selection = true; const int objects_per_page = 10; - const int object_size = - Min(kMaxRegularHeapObjectSize, - static_cast<int>(MemoryChunkLayout::AllocatableMemoryInDataPage()) / - objects_per_page); + const int object_size = GetObjectSize(objects_per_page); CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); diff --git a/deps/v8/test/cctest/heap/test-embedder-tracing.cc b/deps/v8/test/cctest/heap/test-embedder-tracing.cc index 28553266ff2ed0..11f154f936f9d3 100644 --- a/deps/v8/test/cctest/heap/test-embedder-tracing.cc +++ b/deps/v8/test/cctest/heap/test-embedder-tracing.cc @@ -17,12 +17,6 @@ namespace v8 { -// See test below: TracedGlobalNoDestructor. -template <> -struct TracedGlobalTrait<v8::TracedGlobal<v8::Value>> { - static constexpr bool kRequiresExplicitDestruction = false; -}; - namespace internal { namespace heap { @@ -293,13 +287,14 @@ void ConstructJSObject(v8::Isolate* isolate, v8::Local<v8::Context> context, CHECK(!global->IsEmpty()); } +template <typename T> void ConstructJSApiObject(v8::Isolate* isolate, v8::Local<v8::Context> context, - v8::TracedGlobal<v8::Object>* global) { + T* global) { v8::HandleScope scope(isolate); v8::Local<v8::Object> object( ConstructTraceableJSApiObject(context, nullptr, nullptr)); CHECK(!object.IsEmpty()); - *global = v8::TracedGlobal<v8::Object>(isolate, object); + *global = T(isolate, object); CHECK(!global->IsEmpty()); } @@ -360,10 +355,6 @@ TEST(TracedGlobalCopyWithDestructor) { v8::HandleScope scope(isolate); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); - const size_t initial_count = global_handles->handles_count(); v8::TracedGlobal<v8::Object> global1; { @@ -401,18 +392,14 @@ TEST(TracedGlobalCopyNoDestructor) { v8::HandleScope scope(isolate); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); - const size_t initial_count = global_handles->handles_count(); - v8::TracedGlobal<v8::Value> global1; + v8::TracedReference<v8::Value> global1; { v8::HandleScope scope(isolate); global1.Reset(isolate, v8::Object::New(isolate)); } - v8::TracedGlobal<v8::Value> global2(global1); - v8::TracedGlobal<v8::Value> global3; + v8::TracedReference<v8::Value> global2(global1); + v8::TracedReference<v8::Value> global3; global3 = global2; CHECK_EQ(initial_count + 3, global_handles->handles_count()); CHECK(!global1.IsEmpty()); @@ -500,7 +487,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectSurvivesScavengePerDefault) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(true); TracedGlobalTest( - CcTest::isolate(), ConstructJSApiObject, + CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>, [](const TracedGlobal<v8::Object>& global) {}, InvokeScavenge, SurvivalMode::kSurvives); } @@ -513,7 +500,7 @@ TEST(TracedGlobalToUnmodifiedJSApiObjectDiesOnScavengeWhenExcludedFromRoots) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); tracer.ConsiderTracedGlobalAsRoot(false); TracedGlobalTest( - CcTest::isolate(), ConstructJSApiObject, + CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>, [](const TracedGlobal<v8::Object>& global) {}, InvokeScavenge, SurvivalMode::kDies); } @@ -671,9 +658,6 @@ TEST(TracedGlobalWithDestructor) { CHECK(!traced->IsEmpty()); CHECK_EQ(initial_count + 1, global_handles->handles_count()); } - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); delete traced; CHECK_EQ(initial_count, global_handles->handles_count()); // GC should not need to clear the handle. @@ -691,21 +675,18 @@ TEST(TracedGlobalNoDestructor) { i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); const size_t initial_count = global_handles->handles_count(); - char* memory = new char[sizeof(v8::TracedGlobal<v8::Value>)]; - auto* traced = new (memory) v8::TracedGlobal<v8::Value>(); + char* memory = new char[sizeof(v8::TracedReference<v8::Value>)]; + auto* traced = new (memory) v8::TracedReference<v8::Value>(); { v8::HandleScope scope(isolate); v8::Local<v8::Value> object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), nullptr, nullptr)); CHECK(traced->IsEmpty()); - *traced = v8::TracedGlobal<v8::Value>(isolate, object); + *traced = v8::TracedReference<v8::Value>(isolate, object); CHECK(!traced->IsEmpty()); CHECK_EQ(initial_count + 1, global_handles->handles_count()); } - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); - traced->~TracedGlobal<v8::Value>(); + traced->~TracedReference<v8::Value>(); CHECK_EQ(initial_count + 1, global_handles->handles_count()); // GC should clear the handle. heap::InvokeMarkSweep(); @@ -759,18 +740,19 @@ class EmbedderHeapTracerNoDestructorNonTracingClearing final uint16_t class_id_to_optimize) : class_id_to_optimize_(class_id_to_optimize) {} - bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) final { + bool IsRootForNonTracingGC( + const v8::TracedReference<v8::Value>& handle) final { return handle.WrapperClassId() != class_id_to_optimize_; } void ResetHandleInNonTracingGC( - const v8::TracedGlobal<v8::Value>& handle) final { + const v8::TracedReference<v8::Value>& handle) final { if (handle.WrapperClassId() != class_id_to_optimize_) return; // Convention (for test): Objects that are optimized have their first field // set as a back pointer. - TracedGlobal<v8::Value>* original_handle = - reinterpret_cast<TracedGlobal<v8::Value>*>( + TracedReferenceBase<v8::Value>* original_handle = + reinterpret_cast<TracedReferenceBase<v8::Value>*>( v8::Object::GetAlignedPointerFromInternalField( handle.As<v8::Object>(), 0)); original_handle->Reset(); @@ -781,23 +763,23 @@ class EmbedderHeapTracerNoDestructorNonTracingClearing final }; template <typename T> -void SetupOptimizedAndNonOptimizedHandle( - v8::Isolate* isolate, uint16_t optimized_class_id, - v8::TracedGlobal<T>* optimized_handle, - v8::TracedGlobal<T>* non_optimized_handle) { +void SetupOptimizedAndNonOptimizedHandle(v8::Isolate* isolate, + uint16_t optimized_class_id, + T* optimized_handle, + T* non_optimized_handle) { v8::HandleScope scope(isolate); v8::Local<v8::Object> optimized_object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), optimized_handle, nullptr)); CHECK(optimized_handle->IsEmpty()); - *optimized_handle = v8::TracedGlobal<T>(isolate, optimized_object); + *optimized_handle = T(isolate, optimized_object); CHECK(!optimized_handle->IsEmpty()); optimized_handle->SetWrapperClassId(optimized_class_id); v8::Local<v8::Object> non_optimized_object(ConstructTraceableJSApiObject( isolate->GetCurrentContext(), nullptr, nullptr)); CHECK(non_optimized_handle->IsEmpty()); - *non_optimized_handle = v8::TracedGlobal<T>(isolate, non_optimized_object); + *non_optimized_handle = T(isolate, non_optimized_object); CHECK(!non_optimized_handle->IsEmpty()); } @@ -813,9 +795,6 @@ TEST(TracedGlobalDestructorReclaimedOnScavenge) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(TracedGlobalTrait< - v8::TracedGlobal<v8::Object>>::kRequiresExplicitDestruction, - "destructor expected"); const size_t initial_count = global_handles->handles_count(); auto* optimized_handle = new v8::TracedGlobal<v8::Object>(); auto* non_optimized_handle = new v8::TracedGlobal<v8::Object>(); @@ -841,12 +820,9 @@ TEST(TracedGlobalNoDestructorReclaimedOnScavenge) { heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer); i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles(); - static_assert(!TracedGlobalTrait< - v8::TracedGlobal<v8::Value>>::kRequiresExplicitDestruction, - "no destructor expected"); const size_t initial_count = global_handles->handles_count(); - auto* optimized_handle = new v8::TracedGlobal<v8::Value>(); - auto* non_optimized_handle = new v8::TracedGlobal<v8::Value>(); + auto* optimized_handle = new v8::TracedReference<v8::Value>(); + auto* non_optimized_handle = new v8::TracedReference<v8::Value>(); SetupOptimizedAndNonOptimizedHandle(isolate, kClassIdToOptimize, optimized_handle, non_optimized_handle); CHECK_EQ(initial_count + 2, global_handles->handles_count()); diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc index fd17c0f063b5b4..03f98c64537f22 100644 --- a/deps/v8/test/cctest/heap/test-heap.cc +++ b/deps/v8/test/cctest/heap/test-heap.cc @@ -1791,7 +1791,7 @@ TEST(HeapNumberAlignment) { AlignOldSpace(required_alignment, offset); Handle<Object> number_old = - factory->NewNumber(1.000321, AllocationType::kOld); + factory->NewNumber<AllocationType::kOld>(1.000321); CHECK(number_old->IsHeapNumber()); CHECK(heap->InOldSpace(*number_old)); CHECK_EQ(0, Heap::GetFillToAlign(HeapObject::cast(*number_old).address(), @@ -3663,9 +3663,58 @@ TEST(DeferredHandles) { DeferredHandleScope deferred(isolate); DummyVisitor visitor; isolate->handle_scope_implementer()->Iterate(&visitor); - delete deferred.Detach(); + deferred.Detach(); } +static void TestFillersFromDeferredHandles(bool promote) { + // We assume that the fillers can only arise when left-trimming arrays. + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate)); + + const size_t n = 10; + Handle<FixedArray> array = isolate->factory()->NewFixedArray(n); + + if (promote) { + // Age the array so it's ready for promotion on next GC. + CcTest::CollectGarbage(NEW_SPACE); + } + CHECK(Heap::InYoungGeneration(*array)); + + DeferredHandleScope deferred_scope(isolate); + + // Trim the array three times to different sizes so all kinds of fillers are + // created and tracked by the deferred handles. + Handle<FixedArrayBase> filler_1 = Handle<FixedArrayBase>(*array, isolate); + Handle<FixedArrayBase> filler_2 = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_1, 1), isolate); + Handle<FixedArrayBase> filler_3 = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_2, 2), isolate); + Handle<FixedArrayBase> tail = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*filler_3, 3), isolate); + + std::unique_ptr<DeferredHandles> deferred_handles(deferred_scope.Detach()); + + // GC should retain the trimmed array but drop all of the three fillers. + CcTest::CollectGarbage(NEW_SPACE); + if (promote) { + CHECK(heap->InOldSpace(*tail)); + } else { + CHECK(Heap::InYoungGeneration(*tail)); + } + CHECK_EQ(n - 6, (*tail).length()); + CHECK(!filler_1->IsHeapObject()); + CHECK(!filler_2->IsHeapObject()); + CHECK(!filler_3->IsHeapObject()); +} + +TEST(DoNotEvacuateFillersFromDeferredHandles) { + TestFillersFromDeferredHandles(false /*promote*/); +} + +TEST(DoNotPromoteFillersFromDeferredHandles) { + TestFillersFromDeferredHandles(true /*promote*/); +} TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { if (!FLAG_incremental_marking) return; @@ -5269,34 +5318,6 @@ TEST(ScriptIterator) { CHECK_EQ(0, script_count); } - -TEST(SharedFunctionInfoIterator) { - CcTest::InitializeVM(); - v8::HandleScope scope(CcTest::isolate()); - Isolate* isolate = CcTest::i_isolate(); - Heap* heap = CcTest::heap(); - LocalContext context; - - CcTest::CollectAllGarbage(); - CcTest::CollectAllGarbage(); - - int sfi_count = 0; - { - HeapObjectIterator it(heap); - for (HeapObject obj = it.Next(); !obj.is_null(); obj = it.Next()) { - if (!obj.IsSharedFunctionInfo()) continue; - sfi_count++; - } - } - - { - SharedFunctionInfo::GlobalIterator iterator(isolate); - while (!iterator.Next().is_null()) sfi_count--; - } - - CHECK_EQ(0, sfi_count); -} - // This is the same as Factory::NewByteArray, except it doesn't retry on // allocation failure. AllocationResult HeapTester::AllocateByteArrayForTest( @@ -5316,6 +5337,11 @@ AllocationResult HeapTester::AllocateByteArrayForTest( return result; } +bool HeapTester::CodeEnsureLinearAllocationArea(Heap* heap, int size_in_bytes) { + return heap->code_space()->EnsureLinearAllocationArea( + size_in_bytes, AllocationOrigin::kRuntime); +} + HEAP_TEST(Regress587004) { ManualGCScope manual_gc_scope; #ifdef VERIFY_HEAP @@ -5995,6 +6021,173 @@ TEST(UncommitUnusedLargeObjectMemory) { CHECK_EQ(shrinked_size, chunk->CommittedPhysicalMemory()); } +template <RememberedSetType direction> +static size_t GetRememberedSetSize(HeapObject obj) { + size_t count = 0; + auto chunk = MemoryChunk::FromHeapObject(obj); + RememberedSet<direction>::Iterate( + chunk, + [&count](MaybeObjectSlot slot) { + count++; + return KEEP_SLOT; + }, + SlotSet::KEEP_EMPTY_BUCKETS); + return count; +} + +TEST(RememberedSet_InsertOnWriteBarrier) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in old space. + Handle<FixedArray> arr = factory->NewFixedArray(3, AllocationType::kOld); + + // Add into 'arr' references to young objects. + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + arr->set(1, *number); + arr->set(2, *number); + Handle<Object> number_other = factory->NewHeapNumber(24); + arr->set(2, *number_other); + } + // Remembered sets track *slots* pages with cross-generational pointers, so + // must have recorded three of them each exactly once. + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_InsertInLargePage) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in Large space. + const int count = Max(FixedArray::kMaxRegularLength + 1, 128 * KB); + Handle<FixedArray> arr = factory->NewFixedArray(count, AllocationType::kOld); + CHECK(heap->lo_space()->Contains(*arr)); + CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*arr)); + + // Create OLD_TO_NEW references from the large object so that the + // corresponding slots end up in different SlotSets. + { + HandleScope short_lived(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + arr->set(count - 1, *number); + } + CHECK_EQ(2, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_InsertOnPromotingObjectToOld) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Create a young object and age it one generation inside the new space. + Handle<FixedArray> arr = factory->NewFixedArray(1); + CcTest::CollectGarbage(i::NEW_SPACE); + CHECK(Heap::InYoungGeneration(*arr)); + + // Add into 'arr' a reference to an object one generation younger. + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); + } + + // Promote 'arr' into old, its element is still in new, the old to new + // refs are inserted into the remembered sets during GC. + CcTest::CollectGarbage(i::NEW_SPACE); + + CHECK(heap->InOldSpace(*arr)); + CHECK_EQ(1, GetRememberedSetSize<OLD_TO_NEW>(*arr)); +} + +TEST(RememberedSet_RemoveStaleOnScavenge) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + // Allocate an object in old space and add into it references to young. + Handle<FixedArray> arr = factory->NewFixedArray(3, AllocationType::kOld); + { + HandleScope scope_inner(isolate); + Handle<Object> number = factory->NewHeapNumber(42); + arr->set(0, *number); // will be trimmed away + arr->set(1, *number); // will be replaced with #undefined + arr->set(2, *number); // will be promoted into old + } + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr)); + + // Run scavenger once so the young object becomes ready for promotion on the + // next pass. + CcTest::CollectGarbage(i::NEW_SPACE); + arr->set(1, ReadOnlyRoots(CcTest::heap()).undefined_value()); + Handle<FixedArrayBase> tail = + Handle<FixedArrayBase>(heap->LeftTrimFixedArray(*arr, 1), isolate); + + // None of the actions above should have updated the remembered set. + CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*tail)); + + // Run GC to promote the remaining young object and fixup the stale entries in + // the remembered set. + CcTest::CollectGarbage(i::NEW_SPACE); + CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*tail)); +} + +// The OLD_TO_OLD remembered set is created temporary by GC and is cleared at +// the end of the pass. There is no way to observe it so the test only checks +// that compaction has happened and otherwise relies on code's self-validation. +TEST(RememberedSet_OldToOld) { + if (FLAG_stress_incremental_marking) return; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Heap* heap = isolate->heap(); + heap::SealCurrentObjects(heap); + HandleScope scope(isolate); + + Handle<FixedArray> arr = factory->NewFixedArray(10, AllocationType::kOld); + { + HandleScope short_lived(isolate); + factory->NewFixedArray(100, AllocationType::kOld); + } + Handle<Object> ref = factory->NewFixedArray(100, AllocationType::kOld); + arr->set(0, *ref); + + // To force compaction of the old space, fill it with garbage and start a new + // page (so that the page with 'arr' becomes subject to compaction). + { + HandleScope short_lived(isolate); + heap::SimulateFullSpace(heap->old_space()); + factory->NewFixedArray(100, AllocationType::kOld); + } + + FLAG_manual_evacuation_candidates_selection = true; + heap::ForceEvacuationCandidate(Page::FromHeapObject(*arr)); + const auto prev_location = *arr; + + // This GC pass will evacuate the page with 'arr'/'ref' so it will have to + // create OLD_TO_OLD remembered set to track the reference. + CcTest::CollectAllGarbage(); + CHECK_NE(prev_location, *arr); +} + TEST(RememberedSetRemoveRange) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); @@ -6016,59 +6209,64 @@ TEST(RememberedSetRemoveRange) { slots[chunk->area_end() - kTaggedSize] = true; for (auto x : slots) { - RememberedSet<OLD_TO_NEW>::Insert(chunk, x.first); + RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(chunk, x.first); } - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + kTaggedSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start + kTaggedSize, start + Page::kPageSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start + kTaggedSize] = false; slots[start + Page::kPageSize - kTaggedSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + Page::kPageSize + kTaggedSize, SlotSet::FREE_EMPTY_BUCKETS); slots[start + Page::kPageSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, chunk->area_end() - kTaggedSize, chunk->area_end(), SlotSet::FREE_EMPTY_BUCKETS); slots[chunk->area_end() - kTaggedSize] = false; - RememberedSet<OLD_TO_NEW>::Iterate(chunk, - [&slots](MaybeObjectSlot slot) { - CHECK(slots[slot.address()]); - return KEEP_SLOT; - }, - SlotSet::PREFREE_EMPTY_BUCKETS); + RememberedSet<OLD_TO_NEW>::Iterate( + chunk, + [&slots](MaybeObjectSlot slot) { + CHECK(slots[slot.address()]); + return KEEP_SLOT; + }, + SlotSet::FREE_EMPTY_BUCKETS); } HEAP_TEST(Regress670675) { @@ -6164,53 +6362,6 @@ HEAP_TEST(Regress5831) { CHECK(chunk->NeverEvacuate()); } -TEST(Regress6800) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope handle_scope(isolate); - - const int kRootLength = 1000; - Handle<FixedArray> root = - isolate->factory()->NewFixedArray(kRootLength, AllocationType::kOld); - { - HandleScope inner_scope(isolate); - Handle<FixedArray> new_space_array = isolate->factory()->NewFixedArray(1); - for (int i = 0; i < kRootLength; i++) { - root->set(i, *new_space_array); - } - for (int i = 0; i < kRootLength; i++) { - root->set(i, ReadOnlyRoots(CcTest::heap()).undefined_value()); - } - } - CcTest::CollectGarbage(NEW_SPACE); - CHECK_EQ(0, RememberedSet<OLD_TO_NEW>::NumberOfPreFreedEmptyBuckets( - MemoryChunk::FromHeapObject(*root))); -} - -TEST(Regress6800LargeObject) { - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - HandleScope handle_scope(isolate); - - const int kRootLength = i::kMaxRegularHeapObjectSize / kTaggedSize; - Handle<FixedArray> root = - isolate->factory()->NewFixedArray(kRootLength, AllocationType::kOld); - CcTest::heap()->lo_space()->Contains(*root); - { - HandleScope inner_scope(isolate); - Handle<FixedArray> new_space_array = isolate->factory()->NewFixedArray(1); - for (int i = 0; i < kRootLength; i++) { - root->set(i, *new_space_array); - } - for (int i = 0; i < kRootLength; i++) { - root->set(i, ReadOnlyRoots(CcTest::heap()).undefined_value()); - } - } - CcTest::CollectGarbage(OLD_SPACE); - CHECK_EQ(0, RememberedSet<OLD_TO_NEW>::NumberOfPreFreedEmptyBuckets( - MemoryChunk::FromHeapObject(*root))); -} - HEAP_TEST(RegressMissingWriteBarrierInAllocate) { if (!FLAG_incremental_marking) return; ManualGCScope manual_gc_scope; @@ -6631,6 +6782,19 @@ HEAP_TEST(MemoryReducerActivationForSmallHeaps) { CHECK_EQ(heap->memory_reducer()->state_.action, MemoryReducer::Action::kWait); } +TEST(AllocateExternalBackingStore) { + ManualGCScope manual_gc_scope; + LocalContext env; + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + int initial_ms_count = heap->ms_count(); + void* result = + heap->AllocateExternalBackingStore([](size_t) { return nullptr; }, 10); + CHECK_NULL(result); + // At least two GCs should happen. + CHECK_LE(2, heap->ms_count() - initial_ms_count); +} + TEST(CodeObjectRegistry) { // We turn off compaction to ensure that code is not moving. FLAG_never_compact = true; @@ -6642,11 +6806,13 @@ TEST(CodeObjectRegistry) { HandleScope outer_scope(heap->isolate()); Address code2_address; { + // Ensure that both code objects end up on the same page. + CHECK(HeapTester::CodeEnsureLinearAllocationArea( + heap, kMaxRegularHeapObjectSize)); code1 = DummyOptimizedCode(isolate); Handle<Code> code2 = DummyOptimizedCode(isolate); code2_address = code2->address(); - // If this check breaks, change the allocation to ensure that both code - // objects are on the same page. + CHECK_EQ(MemoryChunk::FromHeapObject(*code1), MemoryChunk::FromHeapObject(*code2)); CHECK(MemoryChunk::FromHeapObject(*code1)->Contains(code1->address())); diff --git a/deps/v8/test/cctest/heap/test-invalidated-slots.cc b/deps/v8/test/cctest/heap/test-invalidated-slots.cc index af42503f864a87..861c48d69d3150 100644 --- a/deps/v8/test/cctest/heap/test-invalidated-slots.cc +++ b/deps/v8/test/cctest/heap/test-invalidated-slots.cc @@ -70,8 +70,7 @@ HEAP_TEST(InvalidatedSlotsSomeInvalidatedRanges) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register every second byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i += 2) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); for (size_t i = 0; i < byte_arrays.size(); i++) { @@ -95,8 +94,7 @@ HEAP_TEST(InvalidatedSlotsAllInvalidatedRanges) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); for (size_t i = 0; i < byte_arrays.size(); i++) { @@ -117,8 +115,7 @@ HEAP_TEST(InvalidatedSlotsAfterTrimming) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // Trim byte arrays and check that the slots outside the byte arrays are // considered invalid if the old space page was swept. @@ -145,8 +142,7 @@ HEAP_TEST(InvalidatedSlotsEvacuationCandidate) { // This should be no-op because the page is marked as evacuation // candidate. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // All slots must still be valid. InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); @@ -169,8 +165,7 @@ HEAP_TEST(InvalidatedSlotsResetObjectRegression) { heap->RightTrimFixedArray(byte_arrays[0], byte_arrays[0].length() - 8); // Register the all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_OLD>(byte_arrays[i]); } // All slots must still be invalid. InvalidatedSlotsFilter filter = InvalidatedSlotsFilter::OldToOld(page); @@ -359,8 +354,7 @@ HEAP_TEST(InvalidatedSlotsCleanupFull) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i]); } // Mark full page as free @@ -379,8 +373,7 @@ HEAP_TEST(InvalidatedSlotsCleanupEachObject) { Page* page = AllocateByteArraysOnPage(heap, &byte_arrays); // Register all byte arrays as invalidated. for (size_t i = 0; i < byte_arrays.size(); i++) { - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i], - byte_arrays[i].Size()); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(byte_arrays[i]); } // Mark each object as free on page @@ -405,11 +398,9 @@ HEAP_TEST(InvalidatedSlotsCleanupRightTrim) { CHECK_GT(byte_arrays.size(), 1); ByteArray& invalidated = byte_arrays[1]; - int invalidated_size = invalidated.Size(); heap->RightTrimFixedArray(invalidated, invalidated.length() - 8); - page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(invalidated, - invalidated_size); + page->RegisterObjectWithInvalidatedSlots<OLD_TO_NEW>(invalidated); // Free memory at end of invalidated object InvalidatedSlotsCleanup cleanup = InvalidatedSlotsCleanup::OldToNew(page); @@ -418,8 +409,6 @@ HEAP_TEST(InvalidatedSlotsCleanupRightTrim) { // After cleanup the invalidated object should be smaller InvalidatedSlots* invalidated_slots = page->invalidated_slots<OLD_TO_NEW>(); - CHECK_GE((*invalidated_slots)[HeapObject::FromAddress(invalidated.address())], - invalidated.Size()); CHECK_EQ(invalidated_slots->size(), 1); } diff --git a/deps/v8/test/cctest/heap/test-page-promotion.cc b/deps/v8/test/cctest/heap/test-page-promotion.cc index df6211826e5bdd..c31fc39c2e45b8 100644 --- a/deps/v8/test/cctest/heap/test-page-promotion.cc +++ b/deps/v8/test/cctest/heap/test-page-promotion.cc @@ -43,8 +43,7 @@ v8::Isolate* NewIsolateForPagePromotion(int min_semi_space_size = 8, return isolate; } -Page* FindLastPageInNewSpace( - std::vector<Handle<FixedArray>>& handles) { // NOLINT(runtime/references) +Page* FindLastPageInNewSpace(const std::vector<Handle<FixedArray>>& handles) { for (auto rit = handles.rbegin(); rit != handles.rend(); ++rit) { // One deref gets the Handle, the second deref gets the FixedArray. Page* candidate = Page::FromHeapObject(**rit); @@ -146,8 +145,10 @@ UNINITIALIZED_TEST(PagePromotion_NewToNewJSArrayBuffer) { heap::FillCurrentPage(heap->new_space()); // Allocate a buffer we would like to check against. Handle<JSArrayBuffer> buffer = - i_isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - CHECK(JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, 100)); + i_isolate->factory() + ->NewJSArrayBufferAndBackingStore(100, + InitializedFlag::kZeroInitialized) + .ToHandleChecked(); std::vector<Handle<FixedArray>> handles; // Simulate a full space, filling the interesting page with live objects. heap::SimulateFullSpace(heap->new_space(), &handles); @@ -188,8 +189,10 @@ UNINITIALIZED_TEST(PagePromotion_NewToOldJSArrayBuffer) { heap::FillCurrentPage(heap->new_space()); // Allocate a buffer we would like to check against. Handle<JSArrayBuffer> buffer = - i_isolate->factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - CHECK(JSArrayBuffer::SetupAllocatingData(buffer, i_isolate, 100)); + i_isolate->factory() + ->NewJSArrayBufferAndBackingStore(100, + InitializedFlag::kZeroInitialized) + .ToHandleChecked(); std::vector<Handle<FixedArray>> handles; // Simulate a full space, filling the interesting page with live objects. heap::SimulateFullSpace(heap->new_space(), &handles); diff --git a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc index 370c5d81312079..a271df4f6746c8 100644 --- a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc +++ b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.cc @@ -132,24 +132,24 @@ BytecodeExpectationsPrinter::GetBytecodeArrayOfCallee( } void BytecodeExpectationsPrinter::PrintEscapedString( - std::ostream& stream, const std::string& string) const { + std::ostream* stream, const std::string& string) const { for (char c : string) { switch (c) { case '"': - stream << "\\\""; + *stream << "\\\""; break; case '\\': - stream << "\\\\"; + *stream << "\\\\"; break; default: - stream << c; + *stream << c; break; } } } void BytecodeExpectationsPrinter::PrintBytecodeOperand( - std::ostream& stream, const BytecodeArrayIterator& bytecode_iterator, + std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, const Bytecode& bytecode, int op_index, int parameter_count) const { OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index); OperandSize op_size = Bytecodes::GetOperandSize( @@ -172,207 +172,207 @@ void BytecodeExpectationsPrinter::PrintBytecodeOperand( if (Bytecodes::IsRegisterOperandType(op_type)) { Register register_value = bytecode_iterator.GetRegisterOperand(op_index); - stream << 'R'; - if (op_size != OperandSize::kByte) stream << size_tag; + *stream << 'R'; + if (op_size != OperandSize::kByte) *stream << size_tag; if (register_value.is_current_context()) { - stream << "(context)"; + *stream << "(context)"; } else if (register_value.is_function_closure()) { - stream << "(closure)"; + *stream << "(closure)"; } else if (register_value.is_parameter()) { int parameter_index = register_value.ToParameterIndex(parameter_count); if (parameter_index == 0) { - stream << "(this)"; + *stream << "(this)"; } else { - stream << "(arg" << (parameter_index - 1) << ')'; + *stream << "(arg" << (parameter_index - 1) << ')'; } } else { - stream << '(' << register_value.index() << ')'; + *stream << '(' << register_value.index() << ')'; } } else { switch (op_type) { case OperandType::kFlag8: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetFlagOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetFlagOperand(op_index); break; case OperandType::kIdx: { - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetIndexOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetIndexOperand(op_index); break; } case OperandType::kUImm: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetUnsignedImmediateOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetUnsignedImmediateOperand(op_index); break; case OperandType::kImm: - stream << 'I' << size_tag << '('; - stream << bytecode_iterator.GetImmediateOperand(op_index); + *stream << 'I' << size_tag << '('; + *stream << bytecode_iterator.GetImmediateOperand(op_index); break; case OperandType::kRegCount: - stream << 'U' << size_tag << '('; - stream << bytecode_iterator.GetRegisterCountOperand(op_index); + *stream << 'U' << size_tag << '('; + *stream << bytecode_iterator.GetRegisterCountOperand(op_index); break; case OperandType::kRuntimeId: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; Runtime::FunctionId id = bytecode_iterator.GetRuntimeIdOperand(op_index); - stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; + *stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; break; } case OperandType::kIntrinsicId: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; Runtime::FunctionId id = bytecode_iterator.GetIntrinsicIdOperand(op_index); - stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; + *stream << "Runtime::k" << i::Runtime::FunctionForId(id)->name; break; } case OperandType::kNativeContextIndex: { - stream << 'U' << size_tag << '('; + *stream << 'U' << size_tag << '('; uint32_t idx = bytecode_iterator.GetNativeContextIndexOperand(op_index); - stream << "%" << NameForNativeContextIntrinsicIndex(idx); + *stream << "%" << NameForNativeContextIntrinsicIndex(idx); break; } default: UNREACHABLE(); } - stream << ')'; + *stream << ')'; } } void BytecodeExpectationsPrinter::PrintBytecode( - std::ostream& stream, const BytecodeArrayIterator& bytecode_iterator, + std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, int parameter_count) const { Bytecode bytecode = bytecode_iterator.current_bytecode(); OperandScale operand_scale = bytecode_iterator.current_operand_scale(); if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) { Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); - stream << "B(" << Bytecodes::ToString(prefix) << "), "; + *stream << "B(" << Bytecodes::ToString(prefix) << "), "; } - stream << "B(" << Bytecodes::ToString(bytecode) << ')'; + *stream << "B(" << Bytecodes::ToString(bytecode) << ')'; int operands_count = Bytecodes::NumberOfOperands(bytecode); for (int op_index = 0; op_index < operands_count; ++op_index) { - stream << ", "; + *stream << ", "; PrintBytecodeOperand(stream, bytecode_iterator, bytecode, op_index, parameter_count); } } void BytecodeExpectationsPrinter::PrintSourcePosition( - std::ostream& stream, SourcePositionTableIterator& source_iterator, + std::ostream* stream, SourcePositionTableIterator* source_iterator, int bytecode_offset) const { static const size_t kPositionWidth = 4; - if (!source_iterator.done() && - source_iterator.code_offset() == bytecode_offset) { - stream << "/* " << std::setw(kPositionWidth) - << source_iterator.source_position().ScriptOffset(); - if (source_iterator.is_statement()) { - stream << " S> */ "; + if (!source_iterator->done() && + source_iterator->code_offset() == bytecode_offset) { + *stream << "/* " << std::setw(kPositionWidth) + << source_iterator->source_position().ScriptOffset(); + if (source_iterator->is_statement()) { + *stream << " S> */ "; } else { - stream << " E> */ "; + *stream << " E> */ "; } - source_iterator.Advance(); + source_iterator->Advance(); } else { - stream << " " << std::setw(kPositionWidth) << ' ' << " "; + *stream << " " << std::setw(kPositionWidth) << ' ' << " "; } } -void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream, +void BytecodeExpectationsPrinter::PrintV8String(std::ostream* stream, i::String string) const { - stream << '"'; + *stream << '"'; for (int i = 0, length = string.length(); i < length; ++i) { - stream << i::AsEscapedUC16ForJSON(string.Get(i)); + *stream << i::AsEscapedUC16ForJSON(string.Get(i)); } - stream << '"'; + *stream << '"'; } void BytecodeExpectationsPrinter::PrintConstant( - std::ostream& stream, i::Handle<i::Object> constant) const { + std::ostream* stream, i::Handle<i::Object> constant) const { if (constant->IsSmi()) { - stream << "Smi ["; - i::Smi::cast(*constant).SmiPrint(stream); - stream << "]"; + *stream << "Smi ["; + i::Smi::cast(*constant).SmiPrint(*stream); + *stream << "]"; } else { - stream << i::HeapObject::cast(*constant).map().instance_type(); + *stream << i::HeapObject::cast(*constant).map().instance_type(); if (constant->IsHeapNumber()) { - stream << " ["; - i::HeapNumber::cast(*constant).HeapNumberPrint(stream); - stream << "]"; + *stream << " ["; + i::HeapNumber::cast(*constant).HeapNumberPrint(*stream); + *stream << "]"; } else if (constant->IsString()) { - stream << " ["; + *stream << " ["; PrintV8String(stream, i::String::cast(*constant)); - stream << "]"; + *stream << "]"; } } } void BytecodeExpectationsPrinter::PrintFrameSize( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { int32_t frame_size = bytecode_array->frame_size(); DCHECK(IsAligned(frame_size, kSystemPointerSize)); - stream << "frame size: " << frame_size / kSystemPointerSize - << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; + *stream << "frame size: " << frame_size / kSystemPointerSize + << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; } void BytecodeExpectationsPrinter::PrintBytecodeSequence( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { - stream << "bytecode array length: " << bytecode_array->length() - << "\nbytecodes: [\n"; + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { + *stream << "bytecode array length: " << bytecode_array->length() + << "\nbytecodes: [\n"; SourcePositionTableIterator source_iterator( bytecode_array->SourcePositionTable()); BytecodeArrayIterator bytecode_iterator(bytecode_array); for (; !bytecode_iterator.done(); bytecode_iterator.Advance()) { - stream << kIndent; - PrintSourcePosition(stream, source_iterator, + *stream << kIndent; + PrintSourcePosition(stream, &source_iterator, bytecode_iterator.current_offset()); PrintBytecode(stream, bytecode_iterator, bytecode_array->parameter_count()); - stream << ",\n"; + *stream << ",\n"; } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintConstantPool( - std::ostream& stream, i::FixedArray constant_pool) const { - stream << "constant pool: [\n"; + std::ostream* stream, i::FixedArray constant_pool) const { + *stream << "constant pool: [\n"; int num_constants = constant_pool.length(); if (num_constants > 0) { for (int i = 0; i < num_constants; ++i) { - stream << kIndent; + *stream << kIndent; PrintConstant(stream, i::FixedArray::get(constant_pool, i, i_isolate())); - stream << ",\n"; + *stream << ",\n"; } } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintCodeSnippet( - std::ostream& stream, const std::string& body) const { - stream << "snippet: \"\n"; + std::ostream* stream, const std::string& body) const { + *stream << "snippet: \"\n"; std::stringstream body_stream(body); std::string body_line; while (std::getline(body_stream, body_line)) { - stream << kIndent; + *stream << kIndent; PrintEscapedString(stream, body_line); - stream << '\n'; + *stream << '\n'; } - stream << "\"\n"; + *stream << "\"\n"; } void BytecodeExpectationsPrinter::PrintHandlers( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { - stream << "handlers: [\n"; + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { + *stream << "handlers: [\n"; HandlerTable table(*bytecode_array); for (int i = 0, num_entries = table.NumberOfRangeEntries(); i < num_entries; ++i) { - stream << " [" << table.GetRangeStart(i) << ", " << table.GetRangeEnd(i) - << ", " << table.GetRangeHandler(i) << "],\n"; + *stream << " [" << table.GetRangeStart(i) << ", " << table.GetRangeEnd(i) + << ", " << table.GetRangeHandler(i) << "],\n"; } - stream << "]\n"; + *stream << "]\n"; } void BytecodeExpectationsPrinter::PrintBytecodeArray( - std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { + std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const { PrintFrameSize(stream, bytecode_array); PrintBytecodeSequence(stream, bytecode_array); PrintConstantPool(stream, bytecode_array->constant_pool()); @@ -380,7 +380,7 @@ void BytecodeExpectationsPrinter::PrintBytecodeArray( } void BytecodeExpectationsPrinter::PrintExpectation( - std::ostream& stream, const std::string& snippet) const { + std::ostream* stream, const std::string& snippet) const { std::string source_code = wrap_ ? WrapCodeInFunction(test_function_name_.c_str(), snippet) : snippet; @@ -404,10 +404,10 @@ void BytecodeExpectationsPrinter::PrintExpectation( } } - stream << "---\n"; + *stream << "---\n"; PrintCodeSnippet(stream, snippet); PrintBytecodeArray(stream, bytecode_array); - stream << '\n'; + *stream << '\n'; } } // namespace interpreter diff --git a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h index dc51e5fb7a4fff..6a469461d5c850 100644 --- a/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h +++ b/deps/v8/test/cctest/interpreter/bytecode-expectations-printer.h @@ -36,8 +36,7 @@ class BytecodeExpectationsPrinter final { oneshot_opt_(false), test_function_name_(kDefaultTopFunctionName) {} - void PrintExpectation(std::ostream& stream, // NOLINT - const std::string& snippet) const; + void PrintExpectation(std::ostream* stream, const std::string& snippet) const; void set_module(bool module) { module_ = module; } bool module() const { return module_; } @@ -60,34 +59,30 @@ class BytecodeExpectationsPrinter final { std::string test_function_name() const { return test_function_name_; } private: - void PrintEscapedString(std::ostream& stream, // NOLINT + void PrintEscapedString(std::ostream* stream, const std::string& string) const; - void PrintBytecodeOperand(std::ostream& stream, // NOLINT + void PrintBytecodeOperand(std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, const Bytecode& bytecode, int op_index, int parameter_count) const; - void PrintBytecode(std::ostream& stream, // NOLINT + void PrintBytecode(std::ostream* stream, const BytecodeArrayIterator& bytecode_iterator, int parameter_count) const; - void PrintSourcePosition(std::ostream& stream, // NOLINT - SourcePositionTableIterator& - source_iterator, // NOLINT(runtime/references) + void PrintSourcePosition(std::ostream* stream, + SourcePositionTableIterator* source_iterator, int bytecode_offset) const; - void PrintV8String(std::ostream& stream, // NOLINT - i::String string) const; - void PrintConstant(std::ostream& stream, // NOLINT - i::Handle<i::Object> constant) const; - void PrintFrameSize(std::ostream& stream, // NOLINT + void PrintV8String(std::ostream* stream, i::String string) const; + void PrintConstant(std::ostream* stream, i::Handle<i::Object> constant) const; + void PrintFrameSize(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintBytecodeSequence(std::ostream& stream, // NOLINT + void PrintBytecodeSequence(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintConstantPool(std::ostream& stream, // NOLINT + void PrintConstantPool(std::ostream* stream, i::FixedArray constant_pool) const; - void PrintCodeSnippet(std::ostream& stream, // NOLINT - const std::string& body) const; - void PrintBytecodeArray(std::ostream& stream, // NOLINT + void PrintCodeSnippet(std::ostream* stream, const std::string& body) const; + void PrintBytecodeArray(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; - void PrintHandlers(std::ostream& stream, // NOLINT + void PrintHandlers(std::ostream* stream, i::Handle<i::BytecodeArray> bytecode_array) const; v8::Local<v8::String> V8StringFromUTF8(const char* data) const; diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden index d6097e938df258..7b1de53911fb3e 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ArrayLiterals.golden @@ -141,9 +141,9 @@ handlers: [ snippet: " var a = [ 1, 2 ]; return [ 0, ...a ]; " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 80 +bytecode array length: 68 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), @@ -152,11 +152,7 @@ bytecodes: [ B(Star), R(2), B(LdaConstant), U8(2), /* 67 S> */ B(Star), R(1), - B(GetIterator), R(0), U8(2), - B(Star), R(6), - B(CallProperty0), R(6), R(0), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(0), U8(2), U8(4), B(Star), R(4), B(LdaNamedProperty), R(4), U8(3), U8(6), B(Star), R(3), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden index 1dbb999371f190..0e7cac1ad906f0 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncGenerators.golden @@ -214,7 +214,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 369 +bytecode array length: 357 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -238,11 +238,7 @@ bytecodes: [ B(JumpConstant), U8(15), /* 36 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), B(Star), R(10), - B(GetIterator), R(10), U8(1), - B(Star), R(11), - B(CallProperty0), R(11), R(10), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(10), U8(1), U8(3), B(Star), R(9), B(LdaNamedProperty), R(9), U8(5), U8(5), B(Star), R(8), @@ -376,7 +372,7 @@ bytecodes: [ ] constant pool: [ Smi [30], - Smi [148], + Smi [136], Smi [16], Smi [7], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, @@ -390,16 +386,16 @@ constant pool: [ Smi [6], Smi [9], SCOPE_INFO_TYPE, - Smi [274], + Smi [262], Smi [6], Smi [9], Smi [23], ] handlers: [ - [20, 315, 323], - [23, 279, 281], - [92, 179, 187], - [211, 244, 246], + [20, 303, 311], + [23, 267, 269], + [80, 167, 175], + [199, 232, 234], ] --- @@ -410,7 +406,7 @@ snippet: " " frame size: 17 parameter count: 1 -bytecode array length: 466 +bytecode array length: 467 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(5), B(Mov), R(closure), R(1), @@ -431,7 +427,7 @@ bytecodes: [ B(LdaSmi), I8(1), B(Star), R(1), B(Mov), R(5), R(2), - B(JumpConstant), U8(17), + B(JumpConstant), U8(18), /* 49 S> */ B(LdaGlobal), U8(7), U8(0), B(Star), R(9), /* 56 E> */ B(CallUndefinedReceiver0), R(9), U8(2), @@ -440,25 +436,25 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(11), B(CallProperty0), R(11), R(10), U8(6), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(10), U8(8), + B(LdaNamedProperty), R(10), U8(9), U8(8), B(Star), R(11), B(CallProperty0), R(11), R(10), U8(10), B(Star), R(11), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(11), U8(1), B(Star), R(7), - B(LdaNamedProperty), R(7), U8(9), U8(12), + B(LdaNamedProperty), R(7), U8(10), U8(12), B(Star), R(9), B(LdaUndefined), B(Star), R(8), B(LdaZero), B(Star), R(6), B(Ldar), R(6), - B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(1), + B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(1), B(CallProperty1), R(9), R(7), R(8), U8(14), B(Jump), U8(140), - B(LdaNamedProperty), R(7), U8(12), U8(16), + B(LdaNamedProperty), R(7), U8(13), U8(16), B(JumpIfUndefinedOrNull), U8(11), B(Star), R(10), B(CallProperty1), R(10), R(7), R(8), U8(18), @@ -480,12 +476,12 @@ bytecodes: [ B(Star), R(1), B(Mov), R(10), R(2), B(Jump), U8(241), - B(LdaNamedProperty), R(7), U8(13), U8(20), + B(LdaNamedProperty), R(7), U8(14), U8(20), B(JumpIfUndefinedOrNull), U8(11), B(Star), R(12), B(CallProperty1), R(12), R(7), R(8), U8(22), B(Jump), U8(66), - B(LdaNamedProperty), R(7), U8(12), U8(24), + B(LdaNamedProperty), R(7), U8(13), U8(24), B(JumpIfUndefinedOrNull), U8(55), B(Star), R(12), B(CallProperty0), R(12), R(7), U8(26), @@ -525,9 +521,9 @@ bytecodes: [ B(Mov), R(12), R(5), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), - B(LdaNamedProperty), R(5), U8(14), U8(28), + B(LdaNamedProperty), R(5), U8(15), U8(28), B(JumpIfToBooleanTrue), U8(38), - B(LdaNamedProperty), R(5), U8(15), U8(30), + B(LdaNamedProperty), R(5), U8(16), U8(30), B(Star), R(15), B(LdaFalse), B(Star), R(16), @@ -539,7 +535,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), B(Star), R(6), B(JumpLoop), U8(236), I8(0), - B(LdaNamedProperty), R(5), U8(15), U8(32), + B(LdaNamedProperty), R(5), U8(16), U8(32), B(Star), R(7), B(LdaSmi), I8(1), B(TestReferenceEqual), R(6), @@ -551,7 +547,7 @@ bytecodes: [ B(Ldar), R(7), B(Jump), U8(36), B(Star), R(5), - B(CreateCatchContext), R(5), U8(16), + B(CreateCatchContext), R(5), U8(17), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -580,7 +576,7 @@ bytecodes: [ B(Ldar), R(3), B(SetPendingMessage), B(Ldar), R(1), - B(SwitchOnSmiNoFeedback), U8(18), U8(3), I8(0), + B(SwitchOnSmiNoFeedback), U8(19), U8(3), I8(0), B(Jump), U8(22), B(Ldar), R(2), B(ReThrow), @@ -597,14 +593,15 @@ bytecodes: [ ] constant pool: [ Smi [30], - Smi [157], - Smi [229], - Smi [279], - Smi [338], + Smi [158], + Smi [230], + Smi [280], + Smi [339], Smi [16], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], Smi [11], Smi [70], @@ -613,13 +610,13 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], SCOPE_INFO_TYPE, - Smi [371], + Smi [372], Smi [6], Smi [9], Smi [23], ] handlers: [ - [20, 412, 420], - [23, 374, 378], + [20, 413, 421], + [23, 375, 379], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden new file mode 100644 index 00000000000000..ccef4fca8f03ec --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/AsyncModules.golden @@ -0,0 +1,348 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: no +module: yes +top level: yes +top level await: yes + +--- +snippet: " + await 42; +" +frame size: 8 +parameter count: 2 +bytecode array length: 142 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(3), + B(Mov), R(arg0), R(2), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(2), + B(PushContext), R(2), + B(Mov), R(closure), R(3), + B(Mov), R(this), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(3), U8(2), + B(Star), R(0), + /* 0 E> */ B(StackCheck), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(3), U8(0), + B(ResumeGenerator), R(0), R(0), U8(3), + B(Star), R(3), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(3), + /* 0 E> */ B(Throw), + B(Ldar), R(3), + /* 10 S> */ B(Return), + B(Mov), R(3), R(1), + B(Ldar), R(1), + B(Mov), R(context), R(3), + /* 0 S> */ B(LdaSmi), I8(42), + B(Star), R(5), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(4), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(1), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(5), + B(LdaZero), + B(TestReferenceEqual), R(5), + B(JumpIfTrue), U8(5), + B(Ldar), R(4), + B(ReThrow), + B(LdaUndefined), + B(Star), R(5), + B(LdaTrue), + B(Star), R(6), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3), + /* 10 S> */ B(Return), + B(Star), R(4), + B(CreateCatchContext), R(4), U8(5), + B(Star), R(3), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(3), + B(PushContext), R(4), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3), + /* 10 S> */ B(Return), +] +constant pool: [ + Smi [36], + Smi [80], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + SCOPE_INFO_TYPE, +] +handlers: [ + [64, 114, 114], +] + +--- +snippet: " + await import(\"foo\"); +" +frame size: 8 +parameter count: 2 +bytecode array length: 152 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(3), + B(Mov), R(arg0), R(2), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(2), U8(2), + B(PushContext), R(2), + B(Mov), R(closure), R(3), + B(Mov), R(this), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(3), U8(2), + B(Star), R(0), + /* 0 E> */ B(StackCheck), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(3), U8(0), + B(ResumeGenerator), R(0), R(0), U8(3), + B(Star), R(3), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(3), + /* 0 E> */ B(Throw), + B(Ldar), R(3), + /* 21 S> */ B(Return), + B(Mov), R(3), R(1), + B(Ldar), R(1), + B(Mov), R(context), R(3), + /* 0 S> */ B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(closure), R(4), + B(CallRuntime), U16(Runtime::kDynamicImportCall), R(4), U8(2), + B(Star), R(5), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(4), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(1), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(5), + B(LdaZero), + B(TestReferenceEqual), R(5), + B(JumpIfTrue), U8(5), + B(Ldar), R(4), + B(ReThrow), + B(LdaUndefined), + B(Star), R(5), + B(LdaTrue), + B(Star), R(6), + B(Mov), R(0), R(4), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(4), U8(3), + /* 21 S> */ B(Return), + B(Star), R(4), + B(CreateCatchContext), R(4), U8(6), + B(Star), R(3), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(3), + B(PushContext), R(4), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(5), U8(3), + /* 21 S> */ B(Return), +] +constant pool: [ + Smi [36], + Smi [90], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + ONE_BYTE_INTERNALIZED_STRING_TYPE ["foo"], + SCOPE_INFO_TYPE, +] +handlers: [ + [64, 124, 124], +] + +--- +snippet: " + await 42; + async function foo() { + await 42; + } + foo(); +" +frame size: 9 +parameter count: 2 +bytecode array length: 153 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(Mov), R(arg0), R(3), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(2), + B(PushContext), R(3), + B(Mov), R(closure), R(4), + B(Mov), R(this), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(4), U8(2), + B(Star), R(0), + B(CreateClosure), U8(3), U8(0), U8(0), + B(Star), R(1), + /* 0 E> */ B(StackCheck), + B(Ldar), R(0), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(0), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(4), U8(2), I8(0), + B(Ldar), R(4), + /* 0 E> */ B(Throw), + B(Ldar), R(4), + /* 54 S> */ B(Return), + B(Mov), R(4), R(2), + B(Ldar), R(2), + B(Mov), R(context), R(4), + /* 0 S> */ B(LdaSmi), I8(42), + B(Star), R(6), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(5), U8(2), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(5), U8(1), + B(ResumeGenerator), R(0), R(0), U8(5), + B(Star), R(5), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(6), + B(LdaZero), + B(TestReferenceEqual), R(6), + B(JumpIfTrue), U8(5), + B(Ldar), R(5), + B(ReThrow), + /* 47 S> */ B(CallUndefinedReceiver0), R(1), U8(0), + B(LdaUndefined), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), + /* 54 S> */ B(Return), + B(Star), R(5), + B(CreateCatchContext), R(5), U8(6), + B(Star), R(4), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(4), + B(PushContext), R(5), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(7), + B(LdaTrue), + B(Star), R(8), + B(Mov), R(0), R(6), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3), + /* 54 S> */ B(Return), +] +constant pool: [ + Smi [44], + Smi [88], + SCOPE_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + Smi [10], + Smi [7], + SCOPE_INFO_TYPE, +] +handlers: [ + [72, 125, 125], +] + +--- +snippet: " + import * as foo from \"bar\"; + await import(\"goo\"); +" +frame size: 9 +parameter count: 2 +bytecode array length: 164 +bytecodes: [ + B(SwitchOnGeneratorState), R(0), U8(0), U8(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(Mov), R(arg0), R(3), + B(CallRuntime), U16(Runtime::kPushModuleContext), R(3), U8(2), + B(PushContext), R(3), + B(Mov), R(closure), R(4), + B(Mov), R(this), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionEnter), R(4), U8(2), + B(Star), R(0), + B(LdaZero), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kGetModuleNamespace), R(4), U8(1), + B(Star), R(1), + /* 0 E> */ B(StackCheck), + B(Ldar), R(0), + /* 0 E> */ B(SuspendGenerator), R(0), R(0), U8(4), U8(0), + B(ResumeGenerator), R(0), R(0), U8(4), + B(Star), R(4), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), + B(Ldar), R(4), + /* 0 E> */ B(Throw), + B(Ldar), R(4), + /* 49 S> */ B(Return), + B(Mov), R(4), R(2), + B(Ldar), R(2), + B(Mov), R(context), R(4), + /* 28 S> */ B(LdaConstant), U8(5), + B(Star), R(6), + B(Mov), R(closure), R(5), + B(CallRuntime), U16(Runtime::kDynamicImportCall), R(5), U8(2), + B(Star), R(6), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionAwaitUncaught), R(5), U8(2), + /* 28 E> */ B(SuspendGenerator), R(0), R(0), U8(5), U8(1), + B(ResumeGenerator), R(0), R(0), U8(5), + B(Star), R(5), + B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), + B(Star), R(6), + B(LdaZero), + B(TestReferenceEqual), R(6), + B(JumpIfTrue), U8(5), + B(Ldar), R(5), + B(ReThrow), + B(LdaUndefined), + B(Star), R(6), + B(LdaTrue), + B(Star), R(7), + B(Mov), R(0), R(5), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), + /* 49 S> */ B(Return), + B(Star), R(5), + B(CreateCatchContext), R(5), U8(6), + B(Star), R(4), + B(LdaTheHole), + B(SetPendingMessage), + B(Ldar), R(4), + B(PushContext), R(5), + B(LdaImmutableCurrentContextSlot), U8(4), + B(Star), R(7), + B(LdaTrue), + B(Star), R(8), + B(Mov), R(0), R(6), + B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionReject), R(6), U8(3), + /* 49 S> */ B(Return), +] +constant pool: [ + Smi [48], + Smi [102], + SCOPE_INFO_TYPE, + Smi [10], + Smi [7], + ONE_BYTE_INTERNALIZED_STRING_TYPE ["goo"], + SCOPE_INFO_TYPE, +] +handlers: [ + [76, 136, 136], +] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden index 963cbee018735a..b86d4e61b1f7a8 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/CallAndSpread.golden @@ -65,9 +65,9 @@ handlers: [ snippet: " Math.max(0, ...[1, 2, 3], 4); " -frame size: 9 +frame size: 8 parameter count: 1 -bytecode array length: 106 +bytecode array length: 94 bytecodes: [ /* 30 E> */ B(StackCheck), /* 34 S> */ B(LdaGlobal), U8(0), U8(0), @@ -80,14 +80,10 @@ bytecodes: [ B(Star), R(3), /* 49 S> */ B(CreateArrayLiteral), U8(4), U8(5), U8(37), B(Star), R(7), - B(GetIterator), R(7), U8(6), - B(Star), R(8), - B(CallProperty0), R(8), R(7), U8(8), - B(Mov), R(0), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(7), U8(6), U8(8), B(Star), R(6), B(LdaNamedProperty), R(6), U8(5), U8(10), + B(Mov), R(0), R(2), B(Star), R(5), B(CallProperty0), R(5), R(6), U8(19), B(Star), R(7), diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden index be635a2ed0e77b..cd439d5d141ed3 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ClassDeclarations.golden @@ -12,27 +12,26 @@ snippet: " speak() { console.log(this.name + ' is speaking.'); } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 44 +bytecode array length: 41 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 149 S> */ B(Return), ] @@ -52,27 +51,26 @@ snippet: " speak() { console.log(this.name + ' is speaking.'); } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 44 +bytecode array length: 41 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 149 S> */ B(Return), ] @@ -94,43 +92,42 @@ snippet: " static [n1]() { return n1; } } " -frame size: 12 +frame size: 11 parameter count: 1 -bytecode array length: 87 +bytecode array length: 84 bytecodes: [ B(CreateFunctionContext), U8(0), U8(2), - B(PushContext), R(2), + B(PushContext), R(1), /* 30 E> */ B(StackCheck), /* 43 S> */ B(LdaConstant), U8(1), /* 43 E> */ B(StaCurrentContextSlot), U8(4), /* 57 S> */ B(LdaConstant), U8(2), /* 57 E> */ B(StaCurrentContextSlot), U8(5), B(CreateBlockContext), U8(3), - B(PushContext), R(3), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(7), + B(Star), R(6), B(CreateClosure), U8(5), U8(0), U8(2), - B(Star), R(4), + B(Star), R(3), B(LdaConstant), U8(4), - B(Star), R(5), - /* 75 S> */ B(LdaImmutableContextSlot), R(3), U8(4), U8(0), - B(ToName), R(8), + B(Star), R(4), + /* 75 S> */ B(LdaImmutableContextSlot), R(2), U8(4), U8(0), + B(ToName), R(7), B(CreateClosure), U8(6), U8(1), U8(2), - B(Star), R(9), - /* 106 S> */ B(LdaImmutableContextSlot), R(3), U8(5), U8(0), - B(ToName), R(10), + B(Star), R(8), + /* 106 S> */ B(LdaImmutableContextSlot), R(2), U8(5), U8(0), + B(ToName), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(4), R(6), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(7), - B(Star), R(5), - B(Mov), R(4), R(1), - B(PopContext), R(3), - B(Mov), R(1), R(0), + B(Star), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(7), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(3), R(0), B(LdaUndefined), /* 129 S> */ B(Return), ] @@ -154,29 +151,28 @@ snippet: " class C { constructor() { count++; }} return new C(); " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 52 +bytecode array length: 49 bytecodes: [ B(CreateFunctionContext), U8(0), U8(1), - B(PushContext), R(2), + B(PushContext), R(1), /* 30 E> */ B(StackCheck), /* 46 S> */ B(LdaZero), /* 46 E> */ B(StaCurrentContextSlot), U8(4), B(CreateBlockContext), U8(1), - B(PushContext), R(3), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(7), + B(Star), R(6), B(CreateClosure), U8(3), U8(0), U8(2), - B(Star), R(4), + B(Star), R(3), B(LdaConstant), U8(2), - B(Star), R(5), - B(Mov), R(4), R(6), - B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), - B(Star), R(5), - B(Mov), R(6), R(1), - B(PopContext), R(3), - B(Mov), R(1), R(0), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), /* 87 S> */ B(Ldar), R(0), /* 94 E> */ B(Construct), R(0), R(0), U8(0), U8(0), /* 102 S> */ B(Return), @@ -195,39 +191,38 @@ snippet: " (class {}) class E { static name () {}} " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 73 +bytecode array length: 70 bytecodes: [ /* 30 E> */ B(StackCheck), /* 34 S> */ B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(PopContext), R(2), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), B(CreateBlockContext), U8(3), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(5), U8(1), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(4), - B(Star), R(4), + B(Star), R(3), B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(7), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(6), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), B(LdaUndefined), /* 74 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden index e26b79a9fb80ce..b4c9a75ef1cbe5 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/DestructuringAssignment.golden @@ -12,21 +12,17 @@ snippet: " " frame size: 14 parameter count: 1 -bytecode array length: 172 +bytecode array length: 160 bytecodes: [ /* 30 E> */ B(StackCheck), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(1), - /* 60 S> */ B(GetIterator), R(1), U8(1), - B(Star), R(6), - B(CallProperty0), R(6), R(1), U8(3), - B(Mov), R(1), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 60 S> */ B(GetIterator), R(1), U8(1), U8(3), B(Star), R(4), B(LdaNamedProperty), R(4), U8(1), U8(5), B(Star), R(3), B(LdaFalse), + B(Mov), R(1), R(2), B(Star), R(5), B(Mov), R(context), R(8), /* 57 S> */ B(Ldar), R(5), @@ -101,8 +97,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [40, 82, 90], - [114, 147, 149], + [28, 70, 78], + [102, 135, 137], ] --- @@ -112,21 +108,17 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(2), - /* 69 S> */ B(GetIterator), R(2), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(2), U8(3), - B(Mov), R(2), R(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 69 S> */ B(GetIterator), R(2), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(1), U8(5), B(Star), R(4), B(LdaFalse), + B(Mov), R(2), R(3), B(Star), R(6), B(Mov), R(context), R(9), B(Ldar), R(6), @@ -235,8 +227,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [40, 168, 176], - [200, 233, 235], + [28, 156, 164], + [188, 221, 223], ] --- @@ -246,23 +238,19 @@ snippet: " " frame size: 16 parameter count: 1 -bytecode array length: 223 +bytecode array length: 211 bytecodes: [ /* 30 E> */ B(StackCheck), /* 40 S> */ B(CreateEmptyObjectLiteral), B(Star), R(0), /* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(2), - /* 68 S> */ B(GetIterator), R(2), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(2), U8(3), - B(Mov), R(2), R(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 68 S> */ B(GetIterator), R(2), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(1), U8(5), B(Star), R(4), B(LdaFalse), + B(Mov), R(2), R(3), B(Star), R(6), B(Mov), R(context), R(9), /* 59 S> */ B(Ldar), R(6), @@ -357,8 +345,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [43, 133, 141], - [165, 198, 200], + [31, 121, 129], + [153, 186, 188], ] --- diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden index f60e591040b948..43b6c0ed229b3a 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForAwaitOf.golden @@ -16,7 +16,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 320 +bytecode array length: 321 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -31,15 +31,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -64,9 +64,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(23), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -87,7 +87,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(17), + B(LdaNamedProperty), R(6), U8(8), U8(17), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -95,7 +95,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -139,7 +139,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 57 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(9), + B(CreateCatchContext), R(5), U8(10), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -154,10 +154,11 @@ bytecodes: [ /* 57 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [224], + Smi [96], + Smi [225], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -166,9 +167,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 292, 292], - [74, 154, 162], - [186, 255, 257], + [20, 293, 293], + [75, 155, 163], + [187, 256, 258], ] --- @@ -180,7 +181,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 341 +bytecode array length: 342 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -195,15 +196,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -228,9 +229,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(27), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -253,7 +254,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(17), + B(LdaNamedProperty), R(6), U8(8), U8(17), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -261,7 +262,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -293,7 +294,7 @@ bytecodes: [ B(Ldar), R(10), B(SetPendingMessage), B(Ldar), R(8), - B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0), + B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0), B(Jump), U8(19), B(Ldar), R(9), B(ReThrow), @@ -311,7 +312,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 68 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(11), + B(CreateCatchContext), R(5), U8(12), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -326,10 +327,11 @@ bytecodes: [ /* 68 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [228], + Smi [96], + Smi [229], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -340,9 +342,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 313, 313], - [74, 158, 166], - [190, 259, 261], + [20, 314, 314], + [75, 159, 167], + [191, 260, 262], ] --- @@ -357,7 +359,7 @@ snippet: " " frame size: 19 parameter count: 1 -bytecode array length: 336 +bytecode array length: 337 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -372,15 +374,15 @@ bytecodes: [ B(JumpIfUndefinedOrNull), U8(15), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(3), - B(JumpIfJSReceiver), U8(22), + B(JumpIfJSReceiver), U8(23), B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0), - B(GetIterator), R(7), U8(5), + B(LdaNamedProperty), R(7), U8(4), U8(5), B(Star), R(8), B(CallProperty0), R(8), R(7), U8(7), B(Star), R(8), B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(8), U8(1), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(4), U8(9), + B(LdaNamedProperty), R(6), U8(5), U8(9), B(Star), R(5), B(LdaFalse), B(Star), R(7), @@ -405,9 +407,9 @@ bytecodes: [ B(Mov), R(12), R(11), B(JumpIfJSReceiver), U8(7), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1), - B(LdaNamedProperty), R(11), U8(5), U8(13), + B(LdaNamedProperty), R(11), U8(6), U8(13), B(JumpIfToBooleanTrue), U8(39), - B(LdaNamedProperty), R(11), U8(6), U8(15), + B(LdaNamedProperty), R(11), U8(7), U8(15), B(Star), R(11), B(LdaFalse), B(Star), R(7), @@ -435,7 +437,7 @@ bytecodes: [ B(Star), R(10), B(Ldar), R(7), B(JumpIfToBooleanTrue), U8(94), - B(LdaNamedProperty), R(6), U8(7), U8(19), + B(LdaNamedProperty), R(6), U8(8), U8(19), B(Star), R(14), B(JumpIfUndefinedOrNull), U8(86), B(Mov), R(context), R(15), @@ -443,7 +445,7 @@ bytecodes: [ B(JumpIfTrue), U8(18), B(Wide), B(LdaSmi), I16(159), B(Star), R(16), - B(LdaConstant), U8(8), + B(LdaConstant), U8(9), B(Star), R(17), B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2), B(Throw), @@ -487,7 +489,7 @@ bytecodes: [ B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(5), U8(3), /* 114 S> */ B(Return), B(Star), R(5), - B(CreateCatchContext), R(5), U8(9), + B(CreateCatchContext), R(5), U8(10), B(Star), R(4), B(LdaTheHole), B(SetPendingMessage), @@ -502,10 +504,11 @@ bytecodes: [ /* 114 S> */ B(Return), ] constant pool: [ - Smi [95], - Smi [240], + Smi [96], + Smi [241], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, SYMBOL_TYPE, + SYMBOL_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -514,9 +517,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 308, 308], - [74, 170, 178], - [202, 271, 273], + [20, 309, 309], + [75, 171, 179], + [203, 272, 274], ] --- @@ -529,7 +532,7 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(Mov), R(closure), R(2), B(Mov), R(this), R(3), @@ -541,11 +544,7 @@ bytecodes: [ B(Star), R(1), /* 68 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), B(Star), R(5), - B(GetIterator), R(5), U8(2), - B(Star), R(6), - B(CallProperty0), R(6), R(5), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(5), U8(2), U8(4), B(Star), R(4), B(LdaNamedProperty), R(4), U8(2), U8(6), B(Star), R(3), @@ -657,8 +656,8 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [16, 230, 230], - [58, 111, 119], - [143, 176, 178], + [16, 218, 218], + [46, 99, 107], + [131, 164, 166], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden index 1557e8d2a8ba57..6c599df00cc6e8 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOf.golden @@ -11,16 +11,12 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 170 +bytecode array length: 158 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(4), - B(GetIterator), R(4), U8(1), - B(Star), R(5), - B(CallProperty0), R(5), R(4), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(4), U8(1), U8(3), B(Star), R(3), B(LdaNamedProperty), R(3), U8(1), U8(5), B(Star), R(2), @@ -98,8 +94,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [37, 80, 88], - [112, 145, 147], + [25, 68, 76], + [100, 133, 135], ] --- @@ -109,16 +105,12 @@ snippet: " " frame size: 14 parameter count: 1 -bytecode array length: 178 +bytecode array length: 166 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(LdaConstant), U8(0), B(Star), R(0), - /* 68 S> */ B(GetIterator), R(0), U8(0), - B(Star), R(6), - B(CallProperty0), R(6), R(0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 68 S> */ B(GetIterator), R(0), U8(0), U8(2), B(Star), R(4), B(LdaNamedProperty), R(4), U8(1), U8(4), B(Star), R(3), @@ -202,8 +194,8 @@ constant pool: [ Smi [9], ] handlers: [ - [35, 82, 90], - [114, 147, 149], + [23, 70, 78], + [102, 135, 137], ] --- @@ -215,16 +207,12 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 186 +bytecode array length: 174 bytecodes: [ /* 30 E> */ B(StackCheck), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), B(Star), R(4), - B(GetIterator), R(4), U8(1), - B(Star), R(5), - B(CallProperty0), R(5), R(4), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(4), U8(1), U8(3), B(Star), R(3), B(LdaNamedProperty), R(3), U8(1), U8(5), B(Star), R(2), @@ -309,8 +297,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [37, 96, 104], - [128, 161, 163], + [25, 84, 92], + [116, 149, 151], ] --- @@ -320,18 +308,14 @@ snippet: " " frame size: 13 parameter count: 1 -bytecode array length: 192 +bytecode array length: 180 bytecodes: [ /* 30 E> */ B(StackCheck), /* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), B(Star), R(0), /* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), B(Star), R(3), - B(GetIterator), R(3), U8(2), - B(Star), R(4), - B(CallProperty0), R(4), R(3), U8(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(3), U8(2), U8(4), B(Star), R(2), B(LdaNamedProperty), R(2), U8(2), U8(6), B(Star), R(1), @@ -419,7 +403,7 @@ constant pool: [ Smi [9], ] handlers: [ - [43, 96, 104], - [128, 161, 163], + [31, 84, 92], + [116, 149, 151], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden index f50891172ecc8b..c643232d4bae92 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/ForOfLoop.golden @@ -15,14 +15,10 @@ snippet: " " frame size: 15 parameter count: 2 -bytecode array length: 167 +bytecode array length: 155 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 34 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(0), U8(4), B(Star), R(4), @@ -100,8 +96,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 77, 85], - [109, 142, 144], + [19, 65, 73], + [97, 130, 132], ] --- @@ -113,7 +109,7 @@ snippet: " " frame size: 20 parameter count: 2 -bytecode array length: 251 +bytecode array length: 239 bytecodes: [ B(CreateFunctionContext), U8(0), U8(4), B(PushContext), R(2), @@ -132,11 +128,7 @@ bytecodes: [ B(StaCurrentContextSlot), U8(4), /* 34 S> */ B(LdaContextSlot), R(3), U8(4), U8(0), B(Star), R(6), - B(GetIterator), R(6), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(2), U8(4), B(Star), R(4), @@ -241,8 +233,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [64, 159, 167], - [191, 224, 226], + [52, 147, 155], + [179, 212, 214], ] --- @@ -254,14 +246,10 @@ snippet: " " frame size: 14 parameter count: 2 -bytecode array length: 184 +bytecode array length: 172 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 34 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(5), - B(CallProperty0), R(5), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 34 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(3), B(LdaNamedProperty), R(3), U8(0), U8(4), B(Star), R(2), @@ -349,8 +337,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 94, 102], - [126, 159, 161], + [19, 82, 90], + [114, 147, 149], ] --- @@ -362,14 +350,10 @@ snippet: " " frame size: 17 parameter count: 2 -bytecode array length: 178 +bytecode array length: 166 bytecodes: [ /* 10 E> */ B(StackCheck), - /* 41 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(9), - B(CallProperty0), R(9), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 41 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(7), B(LdaNamedProperty), R(7), U8(0), U8(4), B(Star), R(6), @@ -453,8 +437,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [31, 88, 96], - [120, 153, 155], + [19, 76, 84], + [108, 141, 143], ] --- @@ -466,7 +450,7 @@ snippet: " " frame size: 16 parameter count: 2 -bytecode array length: 208 +bytecode array length: 196 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(Mov), R(closure), R(5), @@ -483,11 +467,7 @@ bytecodes: [ /* 11 E> */ B(Throw), B(Ldar), R(5), /* 55 S> */ B(Return), - /* 35 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(8), - B(CallProperty0), R(8), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(6), B(LdaNamedProperty), R(6), U8(3), U8(4), B(Star), R(5), @@ -568,8 +548,8 @@ constant pool: [ ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ] handlers: [ - [72, 118, 126], - [150, 183, 185], + [60, 106, 114], + [138, 171, 173], ] --- @@ -581,7 +561,7 @@ snippet: " " frame size: 15 parameter count: 2 -bytecode array length: 252 +bytecode array length: 240 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -598,11 +578,7 @@ bytecodes: [ /* 11 E> */ B(Throw), B(Ldar), R(4), /* 49 S> */ B(Return), - /* 35 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(7), - B(CallProperty0), R(7), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 35 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(5), B(LdaNamedProperty), R(5), U8(4), U8(4), B(Star), R(4), @@ -690,7 +666,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [125], + Smi [113], Smi [10], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], @@ -704,8 +680,8 @@ constant pool: [ Smi [9], ] handlers: [ - [72, 156, 164], - [188, 221, 223], + [60, 144, 152], + [176, 209, 211], ] --- @@ -717,7 +693,7 @@ snippet: " " frame size: 17 parameter count: 2 -bytecode array length: 222 +bytecode array length: 210 bytecodes: [ B(Mov), R(closure), R(5), B(Mov), R(this), R(6), @@ -725,11 +701,7 @@ bytecodes: [ B(Star), R(0), /* 16 E> */ B(StackCheck), B(Mov), R(context), R(5), - /* 40 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(9), - B(CallProperty0), R(9), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(7), B(LdaNamedProperty), R(7), U8(0), U8(4), B(Star), R(6), @@ -827,9 +799,9 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [16, 194, 194], - [46, 92, 100], - [124, 157, 159], + [16, 182, 182], + [34, 80, 88], + [112, 145, 147], ] --- @@ -841,7 +813,7 @@ snippet: " " frame size: 16 parameter count: 2 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(1), B(Mov), R(closure), R(4), @@ -850,11 +822,7 @@ bytecodes: [ B(Star), R(0), /* 16 E> */ B(StackCheck), B(Mov), R(context), R(4), - /* 40 S> */ B(GetIterator), R(arg0), U8(0), - B(Star), R(8), - B(CallProperty0), R(8), R(arg0), U8(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + /* 40 S> */ B(GetIterator), R(arg0), U8(0), U8(2), B(Star), R(6), B(LdaNamedProperty), R(6), U8(1), U8(4), B(Star), R(5), @@ -956,7 +924,7 @@ bytecodes: [ /* 54 S> */ B(Return), ] constant pool: [ - Smi [103], + Smi [91], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], @@ -965,8 +933,8 @@ constant pool: [ SCOPE_INFO_TYPE, ] handlers: [ - [20, 230, 230], - [50, 128, 136], - [160, 193, 195], + [20, 218, 218], + [38, 116, 124], + [148, 181, 183], ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden index 157b58d81d2753..ca3ef0bef309f5 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/Generators.golden @@ -100,7 +100,7 @@ snippet: " " frame size: 15 parameter count: 1 -bytecode array length: 258 +bytecode array length: 246 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(4), @@ -119,11 +119,7 @@ bytecodes: [ /* 44 S> */ B(Return), /* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37), B(Star), R(6), - B(GetIterator), R(6), U8(1), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(3), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(1), U8(3), B(Star), R(5), B(LdaNamedProperty), R(5), U8(5), U8(5), B(Star), R(4), @@ -211,7 +207,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [131], + Smi [119], Smi [10], Smi [7], ARRAY_BOILERPLATE_DESCRIPTION_TYPE, @@ -226,8 +222,8 @@ constant pool: [ Smi [9], ] handlers: [ - [78, 162, 170], - [194, 227, 229], + [66, 150, 158], + [182, 215, 217], ] --- @@ -236,9 +232,9 @@ snippet: " function* f() { yield* g() } f(); " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 210 +bytecode array length: 198 bytecodes: [ B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(Mov), R(closure), R(1), @@ -259,11 +255,7 @@ bytecodes: [ B(Star), R(5), /* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2), B(Star), R(6), - B(GetIterator), R(6), U8(4), - B(Star), R(7), - B(CallProperty0), R(7), R(6), U8(6), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(6), U8(4), U8(6), B(Star), R(3), B(LdaNamedProperty), R(3), U8(5), U8(8), B(Star), R(5), @@ -320,7 +312,7 @@ bytecodes: [ ] constant pool: [ Smi [22], - Smi [178], + Smi [166], Smi [10], Smi [7], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden index dce8d7ac8c294f..c29b74c0e29b8d 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/NewAndSpread.golden @@ -10,29 +10,28 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(...[1, 2, 3]); " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 51 +bytecode array length: 48 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), - /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), + /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), + B(Star), R(2), B(Ldar), R(0), - /* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(1), U8(1), + /* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(1), U8(1), B(LdaUndefined), /* 110 S> */ B(Return), ] @@ -50,31 +49,30 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(0, ...[1, 2, 3]); " -frame size: 7 +frame size: 6 parameter count: 1 -bytecode array length: 54 +bytecode array length: 51 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), - /* 89 S> */ B(LdaZero), B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), + /* 89 S> */ B(LdaZero), + B(Star), R(2), B(CreateArrayLiteral), U8(3), U8(0), U8(37), - B(Star), R(4), + B(Star), R(3), B(Ldar), R(0), - /* 89 E> */ B(ConstructWithSpread), R(0), R(3), U8(2), U8(1), + /* 89 E> */ B(ConstructWithSpread), R(0), R(2), U8(2), U8(1), B(LdaUndefined), /* 113 S> */ B(Return), ] @@ -92,56 +90,51 @@ snippet: " class A { constructor(...args) { this.args = args; } } new A(0, ...[1, 2, 3], 4); " -frame size: 9 +frame size: 7 parameter count: 1 -bytecode array length: 130 +bytecode array length: 115 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), B(LdaTheHole), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(Star), R(2), B(LdaConstant), U8(1), - B(Star), R(4), - B(Mov), R(3), R(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), - B(Star), R(4), - B(Mov), R(5), R(1), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(PopContext), R(1), + B(Mov), R(4), R(0), /* 89 S> */ B(CreateArrayLiteral), U8(3), U8(0), U8(37), - B(Star), R(4), - B(LdaConstant), U8(4), B(Star), R(3), + B(LdaConstant), U8(4), + B(Star), R(2), /* 101 S> */ B(CreateArrayLiteral), U8(5), U8(1), U8(37), - B(Star), R(7), - B(GetIterator), R(7), U8(2), - B(Star), R(8), - B(CallProperty0), R(8), R(7), U8(4), - B(Mov), R(5), R(2), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(Star), R(6), - B(LdaNamedProperty), R(6), U8(6), U8(6), + B(GetIterator), R(6), U8(2), U8(4), B(Star), R(5), - B(CallProperty0), R(5), R(6), U8(15), - B(Star), R(7), + B(LdaNamedProperty), R(5), U8(6), U8(6), + B(Star), R(4), + B(Mov), R(0), R(1), + B(CallProperty0), R(4), R(5), U8(15), + B(Star), R(6), B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1), - B(LdaNamedProperty), R(7), U8(7), U8(17), + B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), + B(LdaNamedProperty), R(6), U8(7), U8(17), B(JumpIfToBooleanTrue), U8(19), - B(LdaNamedProperty), R(7), U8(8), U8(8), - B(StaInArrayLiteral), R(4), R(3), U8(13), - B(Ldar), R(3), + B(LdaNamedProperty), R(6), U8(8), U8(8), + B(StaInArrayLiteral), R(3), R(2), U8(13), + B(Ldar), R(2), B(Inc), U8(12), - B(Star), R(3), + B(Star), R(2), B(JumpLoop), U8(33), I8(0), B(LdaSmi), I8(4), - B(StaInArrayLiteral), R(4), R(3), U8(13), - B(Mov), R(4), R(3), - B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2), + B(StaInArrayLiteral), R(3), R(2), U8(13), + B(Mov), R(3), R(2), + B(CallJSRuntime), U8(%reflect_construct), R(1), U8(2), B(LdaUndefined), /* 116 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden index aceee552b5d531..2c0af93787ef71 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateAccessorDeclaration.golden @@ -15,45 +15,44 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 68 +bytecode array length: 65 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(5), U8(2), U8(2), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 101 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -66,44 +65,43 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 65 +bytecode array length: 62 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(6), + B(Star), R(5), B(LdaNull), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 81 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["B"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -116,44 +114,43 @@ snippet: " } } " -frame size: 8 +frame size: 7 parameter count: 1 -bytecode array length: 65 +bytecode array length: 62 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(3), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), B(LdaNull), - B(Star), R(6), + B(Star), R(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), + B(Star), R(6), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(5), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(PopContext), R(1), + B(Mov), R(2), R(0), B(LdaUndefined), /* 74 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -172,74 +169,72 @@ snippet: " } } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 133 +bytecode array length: 127 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), - B(LdaConstant), U8(1), - B(Star), R(6), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(3), - B(LdaConstant), U8(3), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), + B(LdaConstant), U8(1), + B(Star), R(5), + B(Mov), R(3), R(6), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(5), U8(2), U8(2), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), - /* 118 E> */ B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(5), - B(LdaConstant), U8(7), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(9), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(PushContext), R(2), + B(LdaConstant), U8(8), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 118 E> */ B(CreateClosure), U8(9), U8(3), U8(2), + B(Star), R(3), + B(LdaConstant), U8(7), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(10), U8(4), U8(2), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(11), U8(5), U8(2), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), B(LdaUndefined), /* 175 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, ] handlers: [ ] @@ -254,52 +249,50 @@ snippet: " new C(); } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 119 +bytecode array length: 113 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), - /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), - B(LdaConstant), U8(5), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(7), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), + /* 38 E> */ B(CreateBlockContext), U8(4), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 77 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), + B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(8), - B(Ldar), R(6), - B(StaNamedProperty), R(8), U8(9), U8(0), + B(Star), R(6), + B(Ldar), R(5), + B(StaNamedProperty), R(6), U8(9), U8(0), B(LdaNull), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 122 S> */ B(Ldar), R(1), /* 122 E> */ B(Construct), R(1), R(0), U8(0), U8(2), B(LdaUndefined), @@ -312,9 +305,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, ] handlers: [ @@ -330,52 +323,50 @@ snippet: " new C(); } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 119 +bytecode array length: 113 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), - /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 80 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), - B(LdaConstant), U8(5), - B(Star), R(6), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(7), B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), + /* 38 E> */ B(CreateBlockContext), U8(4), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(5), + /* 80 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), + B(LdaConstant), U8(5), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(LdaNull), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(3), U8(2), - B(Star), R(9), - B(Ldar), R(6), - B(StaNamedProperty), R(9), U8(9), U8(0), - B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(8), U8(2), + B(Star), R(7), + B(Ldar), R(5), + B(StaNamedProperty), R(7), U8(9), U8(0), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(6), U8(2), B(StaCurrentContextSlot), U8(4), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 126 S> */ B(Ldar), R(1), /* 126 E> */ B(Construct), R(1), R(0), U8(0), U8(2), B(LdaUndefined), @@ -388,9 +379,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, ] handlers: [ diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden index dbe688f814db94..62603a93f84c90 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden @@ -22,70 +22,68 @@ snippet: " new B; } " -frame size: 10 +frame size: 7 parameter count: 1 -bytecode array length: 137 +bytecode array length: 131 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), - B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), - B(LdaConstant), U8(1), - B(Star), R(6), - B(LdaConstant), U8(3), - B(Star), R(9), - B(LdaConstant), U8(3), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), + B(LdaTheHole), B(Star), R(6), - B(Mov), R(7), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), + B(LdaConstant), U8(1), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(0), - B(PopContext), R(4), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(0), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(7), - B(Star), R(6), - B(LdaConstant), U8(3), - B(Star), R(9), - B(LdaConstant), U8(3), - B(Star), R(9), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(9), U8(1), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), + B(Star), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), B(CreateClosure), U8(9), U8(3), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(2), - B(PopContext), R(4), - B(Mov), R(2), R(1), - /* 136 S> */ B(Ldar), R(3), - /* 136 E> */ B(Construct), R(3), R(0), U8(0), U8(4), - /* 145 S> */ B(Ldar), R(2), - /* 145 E> */ B(Construct), R(2), R(0), U8(0), U8(6), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(2), + B(PopContext), R(2), + B(Mov), R(3), R(1), + /* 136 S> */ B(Ldar), R(0), + /* 136 E> */ B(Construct), R(0), R(0), U8(0), U8(4), + /* 145 S> */ B(Ldar), R(1), + /* 145 E> */ B(Construct), R(1), R(0), U8(0), U8(6), B(LdaUndefined), /* 154 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, - SHARED_FUNCTION_INFO_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, @@ -130,129 +128,126 @@ snippet: " new C; }; " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 277 +bytecode array length: 268 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), - B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), - B(Star), R(11), + B(PushContext), R(3), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), - B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), - B(LdaConstant), U8(1), - B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), B(StaCurrentContextSlot), U8(4), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3), + B(LdaTheHole), + B(Star), R(11), + B(CreateClosure), U8(4), U8(0), U8(2), B(Star), R(8), - B(Mov), R(9), R(5), - B(CreateClosure), U8(6), U8(2), U8(2), + B(LdaConstant), U8(3), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(0), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(CreateClosure), U8(5), U8(1), U8(2), + B(Star), R(4), + B(LdaConstant), U8(1), + B(Star), R(5), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(6), U8(2), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(0), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(8), - B(PushContext), R(6), + B(PushContext), R(3), + B(LdaConstant), U8(2), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(4), + B(LdaConstant), U8(10), + B(Star), R(5), + B(LdaConstant), U8(10), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(11), U8(3), U8(2), B(Star), R(11), - B(LdaConstant), U8(10), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), - B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), - B(LdaConstant), U8(9), + B(CreateClosure), U8(12), U8(3), U8(2), B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(4), - B(LdaConstant), U8(13), - B(Star), R(11), - B(LdaConstant), U8(13), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(5), + B(LdaConstant), U8(11), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), + B(CreateClosure), U8(13), U8(4), U8(2), + B(Star), R(4), + B(LdaConstant), U8(9), + B(Star), R(5), B(CreateClosure), U8(14), U8(5), U8(2), - B(Star), R(11), - B(CreateClosure), U8(15), U8(6), U8(2), - B(Star), R(12), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), B(Star), R(8), - B(Mov), R(9), R(4), - B(CreateClosure), U8(16), U8(7), U8(2), + B(CreateClosure), U8(15), U8(6), U8(2), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(2), - B(PopContext), R(6), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), + B(CreateClosure), U8(16), U8(7), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(2), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 140 E> */ B(CreateBlockContext), U8(17), - B(PushContext), R(6), + B(PushContext), R(3), + B(LdaConstant), U8(2), + B(Star), R(5), + B(LdaConstant), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), + B(StaCurrentContextSlot), U8(4), /* 356 E> */ B(CreateClosure), U8(19), U8(8), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(18), - B(Star), R(8), - B(LdaConstant), U8(5), - B(Star), R(11), - B(LdaConstant), U8(5), - B(Star), R(11), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(11), U8(1), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(7), R(9), - B(Mov), R(4), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(3), - B(Star), R(8), - B(Mov), R(9), R(3), + B(Star), R(5), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), B(CreateClosure), U8(20), U8(9), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(4), - B(PopContext), R(6), - B(Mov), R(3), R(2), - /* 430 S> */ B(Ldar), R(5), - /* 430 E> */ B(Construct), R(5), R(0), U8(0), U8(6), - /* 439 S> */ B(Ldar), R(4), - /* 439 E> */ B(Construct), R(4), R(0), U8(0), U8(8), - /* 448 S> */ B(Ldar), R(3), - /* 448 E> */ B(Construct), R(3), R(0), U8(0), U8(10), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(4), + B(PopContext), R(3), + B(Mov), R(4), R(2), + /* 430 S> */ B(Ldar), R(0), + /* 430 E> */ B(Construct), R(0), R(0), U8(0), U8(6), + /* 439 S> */ B(Ldar), R(1), + /* 439 E> */ B(Construct), R(1), R(0), U8(0), U8(8), + /* 448 S> */ B(Ldar), R(2), + /* 448 E> */ B(Construct), R(2), R(0), U8(0), U8(10), B(LdaUndefined), /* 458 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], FIXED_ARRAY_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], SHARED_FUNCTION_INFO_TYPE, SYMBOL_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], FIXED_ARRAY_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden index d1aab34fda7992..6456245741fa69 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PrivateMethodDeclaration.golden @@ -16,38 +16,37 @@ snippet: " " frame size: 7 parameter count: 1 -bytecode array length: 55 +bytecode array length: 52 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(2), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), B(Star), R(6), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(3), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), B(LdaConstant), U8(1), B(Star), R(4), - B(CreateClosure), U8(3), U8(1), U8(2), - B(StaCurrentContextSlot), U8(4), - B(Mov), R(3), R(5), + B(Mov), R(2), R(5), B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), B(Star), R(4), - B(Mov), R(5), R(1), - B(LdaConstant), U8(4), - B(Star), R(5), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(2), - B(Mov), R(1), R(0), + B(CreateClosure), U8(4), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(5), R(0), B(LdaUndefined), /* 77 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], ] handlers: [ ] @@ -63,64 +62,62 @@ snippet: " } } " -frame size: 9 +frame size: 8 parameter count: 1 -bytecode array length: 107 +bytecode array length: 101 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), + B(LdaConstant), U8(2), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), - B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(7), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), - B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(4), U8(1), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(3), - B(LdaConstant), U8(4), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(4), - B(Mov), R(3), R(0), + B(PopContext), R(2), + B(Mov), R(6), R(0), /* 38 E> */ B(CreateBlockContext), U8(5), - B(PushContext), R(4), - /* 93 E> */ B(CreateClosure), U8(7), U8(2), U8(2), - B(Star), R(5), + B(PushContext), R(2), + B(LdaConstant), U8(7), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), + /* 93 E> */ B(CreateClosure), U8(8), U8(2), U8(2), + B(Star), R(3), B(LdaConstant), U8(6), - B(Star), R(6), - B(CreateClosure), U8(8), U8(3), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(9), U8(3), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), - B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(9), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(PopContext), R(2), + B(Mov), R(6), R(1), B(LdaUndefined), /* 126 S> */ B(Return), ] constant pool: [ SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["D"], SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["E"], ] handlers: [ ] @@ -134,50 +131,47 @@ snippet: " } } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 106 +bytecode array length: 98 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), B(CreateClosure), U8(3), U8(1), U8(2), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(PopContext), R(4), - B(Mov), R(3), R(0), + B(Star), R(7), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(PopContext), R(2), + B(Mov), R(5), R(0), /* 38 E> */ B(CreateBlockContext), U8(4), - B(PushContext), R(4), - /* 77 E> */ B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(5), + B(PushContext), R(2), + B(LdaConstant), U8(6), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1), + B(StaCurrentContextSlot), U8(5), + /* 77 E> */ B(CreateClosure), U8(7), U8(2), U8(2), + B(Star), R(3), B(LdaConstant), U8(5), - B(Star), R(6), - B(CreateClosure), U8(7), U8(3), U8(2), + B(Star), R(5), + B(Mov), R(3), R(6), + B(Mov), R(0), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3), + B(Star), R(5), + B(CreateClosure), U8(8), U8(3), U8(2), B(StaCurrentContextSlot), U8(4), - B(Mov), R(5), R(7), - B(Mov), R(3), R(8), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3), B(Star), R(6), - B(Mov), R(7), R(2), - B(LdaConstant), U8(8), - B(Star), R(7), - B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(7), U8(1), - B(StaCurrentContextSlot), U8(5), - B(LdaCurrentContextSlot), U8(4), - B(Star), R(8), - B(Ldar), R(6), - B(StaNamedProperty), R(8), U8(9), U8(0), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(Ldar), R(5), + B(StaNamedProperty), R(6), U8(9), U8(0), + B(PopContext), R(2), + B(Mov), R(3), R(1), B(LdaUndefined), /* 118 S> */ B(Return), ] @@ -188,9 +182,9 @@ constant pool: [ SHARED_FUNCTION_INFO_TYPE, SCOPE_INFO_TYPE, FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE, - ONE_BYTE_INTERNALIZED_STRING_TYPE ["C"], SYMBOL_TYPE, ] handlers: [ diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden index c91e7b06aa7b18..4b893861bf09cc 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/PublicClassFields.golden @@ -21,59 +21,57 @@ snippet: " new B; } " -frame size: 10 +frame size: 8 parameter count: 1 -bytecode array length: 125 +bytecode array length: 119 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), /* 60 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(3), - B(CreateClosure), U8(4), U8(1), U8(2), B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(0), - B(PopContext), R(4), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(CreateClosure), U8(4), U8(1), U8(2), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(0), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(6), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(7), - B(Star), R(6), + B(Star), R(4), /* 99 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), - B(Mov), R(5), R(7), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(4), - B(Star), R(6), - B(Mov), R(7), R(2), - B(CreateClosure), U8(9), U8(3), U8(2), B(Star), R(7), - B(StaNamedProperty), R(5), U8(5), U8(2), - B(PopContext), R(4), - B(Mov), R(2), R(1), - /* 120 S> */ B(Ldar), R(3), - /* 120 E> */ B(Construct), R(3), R(0), U8(0), U8(4), - /* 129 S> */ B(Ldar), R(2), - /* 129 E> */ B(Construct), R(2), R(0), U8(0), U8(6), + B(Mov), R(3), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(4), + B(Star), R(4), + B(CreateClosure), U8(9), U8(3), U8(2), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(5), U8(2), + B(PopContext), R(2), + B(Mov), R(3), R(1), + /* 120 S> */ B(Ldar), R(0), + /* 120 E> */ B(Construct), R(0), R(0), U8(0), U8(4), + /* 129 S> */ B(Ldar), R(1), + /* 129 E> */ B(Construct), R(1), R(0), U8(0), U8(6), B(LdaUndefined), /* 138 S> */ B(Return), ] @@ -122,100 +120,97 @@ snippet: " new C; } " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 238 +bytecode array length: 229 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), B(Star), R(11), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(8), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(1), - B(Star), R(8), + B(Star), R(5), /* 77 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4), B(Star), R(8), - B(Mov), R(9), R(5), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4), + B(Star), R(5), B(CreateClosure), U8(6), U8(2), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(0), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(0), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(8), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(11), U8(3), U8(2), B(Star), R(11), + B(CreateClosure), U8(11), U8(3), U8(2), + B(Star), R(8), B(LdaConstant), U8(10), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(9), - B(Star), R(8), + B(Star), R(5), /* 133 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(CreateClosure), U8(13), U8(5), U8(2), - B(Star), R(12), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), B(Star), R(8), - B(Mov), R(9), R(4), - B(CreateClosure), U8(14), U8(6), U8(2), + B(CreateClosure), U8(13), U8(5), U8(2), B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(2), - B(PopContext), R(6), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), + B(CreateClosure), U8(14), U8(6), U8(2), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(2), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 90 E> */ B(CreateBlockContext), U8(15), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), /* 236 E> */ B(CreateClosure), U8(17), U8(7), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(16), - B(Star), R(8), + B(Star), R(5), /* 256 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), - B(Mov), R(7), R(9), - B(Mov), R(4), R(10), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(4), B(Star), R(8), - B(Mov), R(9), R(3), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(4), + B(Star), R(5), B(CreateClosure), U8(18), U8(8), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(7), U8(4), - B(PopContext), R(6), - B(Mov), R(3), R(2), - /* 329 S> */ B(Ldar), R(5), - /* 329 E> */ B(Construct), R(5), R(0), U8(0), U8(6), - /* 338 S> */ B(Ldar), R(4), - /* 338 E> */ B(Construct), R(4), R(0), U8(0), U8(8), - /* 347 S> */ B(Ldar), R(3), - /* 347 E> */ B(Construct), R(3), R(0), U8(0), U8(10), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(7), U8(4), + B(PopContext), R(3), + B(Mov), R(4), R(2), + /* 329 S> */ B(Ldar), R(0), + /* 329 E> */ B(Construct), R(0), R(0), U8(0), U8(6), + /* 338 S> */ B(Ldar), R(1), + /* 338 E> */ B(Construct), R(1), R(0), U8(0), U8(8), + /* 347 S> */ B(Ldar), R(2), + /* 347 E> */ B(Construct), R(2), R(0), U8(0), U8(10), B(LdaUndefined), /* 356 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden index f03337e4aaed77..f47a70135848ca 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticClassFields.golden @@ -25,85 +25,83 @@ snippet: " new B; } " -frame size: 11 +frame size: 9 parameter count: 1 -bytecode array length: 191 +bytecode array length: 185 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(2), U8(0), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(1), - B(Star), R(6), + B(Star), R(4), /* 60 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), + B(Star), R(7), /* 92 S> */ B(LdaConstant), U8(4), - B(Star), R(10), + B(Star), R(8), B(LdaConstant), U8(5), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(5), R(7), + B(TestEqualStrict), R(8), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(10), + B(Ldar), R(8), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5), - B(Star), R(6), - B(Mov), R(5), R(3), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5), + B(Star), R(4), B(CreateClosure), U8(6), U8(1), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(7), U8(1), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(7), U8(1), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(9), - B(CallProperty0), R(9), R(3), U8(3), - B(PopContext), R(4), + B(Star), R(7), + B(CallProperty0), R(7), R(3), U8(3), + B(PopContext), R(2), B(Mov), R(3), R(0), /* 38 E> */ B(CreateBlockContext), U8(9), - B(PushContext), R(4), + B(PushContext), R(2), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(8), + B(Star), R(6), B(CreateClosure), U8(11), U8(3), U8(2), - B(Star), R(5), + B(Star), R(3), B(LdaConstant), U8(10), - B(Star), R(6), + B(Star), R(4), /* 131 S> */ B(LdaConstant), U8(3), B(StaCurrentContextSlot), U8(4), - B(Star), R(9), + B(Star), R(7), /* 176 S> */ B(LdaConstant), U8(4), - B(Star), R(10), + B(Star), R(8), B(LdaConstant), U8(5), - B(TestEqualStrict), R(10), U8(0), - B(Mov), R(5), R(7), + B(TestEqualStrict), R(8), U8(0), + B(Mov), R(3), R(5), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(10), + B(Ldar), R(8), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(5), - B(Star), R(6), - B(Mov), R(5), R(2), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(5), + B(Star), R(4), B(CreateClosure), U8(12), U8(4), U8(2), - B(Star), R(7), - B(StaNamedProperty), R(5), U8(7), U8(5), + B(Star), R(5), + B(StaNamedProperty), R(3), U8(7), U8(5), B(CreateClosure), U8(13), U8(5), U8(2), - B(Star), R(9), - B(CallProperty0), R(9), R(2), U8(7), - B(PopContext), R(4), - B(Mov), R(2), R(1), + B(Star), R(7), + B(CallProperty0), R(7), R(3), U8(7), + B(PopContext), R(2), + B(Mov), R(3), R(1), /* 197 S> */ B(Ldar), R(0), /* 197 E> */ B(Construct), R(0), R(0), U8(0), U8(9), - /* 206 S> */ B(Ldar), R(2), - /* 206 E> */ B(Construct), R(2), R(0), U8(0), U8(11), + /* 206 S> */ B(Ldar), R(1), + /* 206 E> */ B(Construct), R(1), R(0), U8(0), U8(11), B(LdaUndefined), /* 215 S> */ B(Return), ] @@ -162,141 +160,138 @@ snippet: " new C; } " -frame size: 15 +frame size: 12 parameter count: 1 -bytecode array length: 343 +bytecode array length: 334 bytecodes: [ /* 30 E> */ B(StackCheck), B(CreateBlockContext), U8(0), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(3), U8(0), U8(2), B(Star), R(11), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(8), B(LdaConstant), U8(2), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(4), U8(1), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(1), - B(Star), R(8), + B(Star), R(5), /* 77 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 109 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(13), R(10), - B(Mov), R(7), R(9), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(10), R(7), + B(Mov), R(4), R(6), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), - B(Star), R(8), - B(Mov), R(7), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), B(CreateClosure), U8(8), U8(2), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(1), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(1), B(CreateClosure), U8(10), U8(3), U8(2), - B(Star), R(11), - B(CallProperty0), R(11), R(5), U8(3), - B(PopContext), R(6), - B(Mov), R(5), R(0), + B(Star), R(8), + B(CallProperty0), R(8), R(4), U8(3), + B(PopContext), R(3), + B(Mov), R(4), R(0), /* 38 E> */ B(CreateBlockContext), U8(11), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), B(LdaTheHole), - B(Star), R(14), - B(CreateClosure), U8(14), U8(4), U8(2), B(Star), R(11), + B(CreateClosure), U8(14), U8(4), U8(2), + B(Star), R(8), B(LdaConstant), U8(13), - B(Star), R(12), - B(Mov), R(11), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(12), U8(3), - B(Star), R(12), + B(Star), R(9), + B(Mov), R(8), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3), + B(Star), R(9), B(CreateClosure), U8(15), U8(5), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(12), - B(Star), R(8), + B(Star), R(5), /* 165 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 210 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(7), R(9), - B(Mov), R(13), R(10), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(4), R(6), + B(Mov), R(10), R(7), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), B(CreateClosure), U8(16), U8(6), U8(2), - B(Star), R(13), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(6), - B(Star), R(8), - B(Mov), R(7), R(4), + B(Star), R(10), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(6), + B(Star), R(5), B(CreateClosure), U8(17), U8(7), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(5), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(5), B(CreateClosure), U8(18), U8(8), U8(2), - B(Star), R(11), - B(CallProperty0), R(11), R(4), U8(7), - B(PopContext), R(6), + B(Star), R(8), + B(CallProperty0), R(8), R(4), U8(7), + B(PopContext), R(3), B(Mov), R(4), R(1), /* 122 E> */ B(CreateBlockContext), U8(19), - B(PushContext), R(6), + B(PushContext), R(3), B(LdaTheHole), B(StaCurrentContextSlot), U8(4), B(LdaTheHole), B(StaCurrentContextSlot), U8(5), /* 313 E> */ B(CreateClosure), U8(21), U8(9), U8(2), - B(Star), R(7), + B(Star), R(4), B(LdaConstant), U8(20), - B(Star), R(8), + B(Star), R(5), /* 333 S> */ B(LdaConstant), U8(5), B(StaCurrentContextSlot), U8(4), - B(Star), R(11), + B(Star), R(8), /* 378 S> */ B(LdaConstant), U8(6), - B(Star), R(12), + B(Star), R(9), B(LdaConstant), U8(7), - B(TestEqualStrict), R(12), U8(0), - B(Mov), R(4), R(10), - B(Mov), R(7), R(9), + B(TestEqualStrict), R(9), U8(0), + B(Mov), R(4), R(6), + B(Mov), R(1), R(7), B(JumpIfFalse), U8(7), B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0), - B(Ldar), R(12), + B(Ldar), R(9), B(StaCurrentContextSlot), U8(5), - B(CallRuntime), U16(Runtime::kDefineClass), R(8), U8(5), - B(Star), R(8), - B(Mov), R(7), R(3), + B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5), + B(Star), R(5), B(CreateClosure), U8(22), U8(10), U8(2), - B(Star), R(9), - B(StaNamedProperty), R(7), U8(9), U8(9), + B(Star), R(6), + B(StaNamedProperty), R(4), U8(9), U8(9), B(CreateClosure), U8(23), U8(11), U8(2), - B(Star), R(11), - B(Ldar), R(3), - B(StaNamedProperty), R(11), U8(24), U8(11), - B(CallProperty0), R(11), R(3), U8(13), - B(PopContext), R(6), - B(Mov), R(3), R(2), + B(Star), R(8), + B(Ldar), R(4), + B(StaNamedProperty), R(8), U8(24), U8(11), + B(CallProperty0), R(8), R(4), U8(13), + B(PopContext), R(3), + B(Mov), R(4), R(2), /* 456 S> */ B(Ldar), R(0), /* 456 E> */ B(Construct), R(0), R(0), U8(0), U8(15), /* 465 S> */ B(Ldar), R(1), /* 465 E> */ B(Construct), R(1), R(0), U8(0), U8(17), - /* 474 S> */ B(Ldar), R(3), - /* 474 E> */ B(Construct), R(3), R(0), U8(0), U8(19), + /* 474 S> */ B(Ldar), R(2), + /* 474 E> */ B(Construct), R(2), R(0), U8(0), U8(19), B(LdaUndefined), /* 483 S> */ B(Return), ] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden new file mode 100644 index 00000000000000..1b9e573253c09f --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden @@ -0,0 +1,289 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: no +test function name: test +private methods: yes + +--- +snippet: " + class A { + static #a() { return 1; } + static test() { return this.#a(); } + } + + var test = A.test; + test(); +" +frame size: 4 +parameter count: 1 +bytecode array length: 36 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(LdaCurrentContextSlot), U8(5), + B(TestReferenceEqual), R(this), + B(Mov), R(this), R(1), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(LdaCurrentContextSlot), U8(4), + B(Star), R(0), + /* 70 E> */ B(CallAnyReceiver), R(0), R(1), U8(1), U8(0), + /* 73 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"], +] +handlers: [ +] + +--- +snippet: " + class B { + static #b() { return 1; } + static test() { this.#b = 1; } + } + + var test = B.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(Wide), B(LdaSmi), I16(261), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + /* 64 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"], +] +handlers: [ +] + +--- +snippet: " + class C { + static #c() { return 1; } + static test() { this.#c++; } + } + + var test = C.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 51 E> */ B(StackCheck), + /* 56 S> */ B(Wide), B(LdaSmi), I16(261), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#c"], +] +handlers: [ +] + +--- +snippet: " + class D { + static get #d() { return 1; } + static set #d(val) { } + + static test() { + this.#d++; + this.#d = 1; + return this.#d; + } + } + + var test = D.test; + test(); +" +frame size: 5 +parameter count: 1 +bytecode array length: 143 +bytecodes: [ + /* 81 E> */ B(StackCheck), + /* 90 S> */ B(LdaCurrentContextSlot), U8(4), + B(Star), R(1), + B(LdaCurrentContextSlot), U8(5), + /* 94 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(0), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1), + B(Star), R(2), + B(CallProperty0), R(2), R(0), U8(0), + B(Inc), U8(2), + B(Star), R(2), + /* 97 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(1), U8(1), + B(Star), R(3), + B(CallProperty1), R(3), R(0), R(2), U8(3), + /* 105 S> */ B(LdaSmi), I8(1), + B(Star), R(0), + B(LdaCurrentContextSlot), U8(4), + B(Star), R(2), + B(LdaCurrentContextSlot), U8(5), + /* 109 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(1), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(260), + B(Star), R(3), + B(LdaConstant), U8(0), + B(Star), R(4), + B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), U8(1), + B(Star), R(3), + B(CallProperty1), R(3), R(1), R(0), U8(5), + /* 122 S> */ B(LdaCurrentContextSlot), U8(4), + B(Star), R(1), + B(LdaCurrentContextSlot), U8(5), + /* 133 E> */ B(TestReferenceEqual), R(this), + B(Mov), R(this), R(0), + B(JumpIfTrue), U8(18), + B(Wide), B(LdaSmi), I16(259), + B(Star), R(2), + B(LdaConstant), U8(0), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), + B(Throw), + B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), U8(1), + B(Star), R(2), + B(CallProperty0), R(2), R(0), U8(7), + /* 137 S> */ B(Return), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"], +] +handlers: [ +] + +--- +snippet: " + class E { + static get #e() { return 1; } + static test() { this.#e++; } + } + var test = E.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 55 E> */ B(StackCheck), + /* 60 S> */ B(Wide), B(LdaSmi), I16(263), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#e"], +] +handlers: [ +] + +--- +snippet: " + class F { + static set #f(val) { } + static test() { this.#f++; } + } + var test = F.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 48 E> */ B(StackCheck), + /* 53 S> */ B(Wide), B(LdaSmi), I16(262), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#f"], +] +handlers: [ +] + +--- +snippet: " + class G { + static get #d() { return 1; } + static test() { this.#d = 1; } + } + var test = G.test; + test(); +" +frame size: 2 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 55 E> */ B(StackCheck), + /* 60 S> */ B(Wide), B(LdaSmi), I16(263), + B(Star), R(0), + B(LdaConstant), U8(0), + B(Star), R(1), + /* 68 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(0), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#d"], +] +handlers: [ +] + +--- +snippet: " + class H { + set #h(val) { } + static test() { this.#h; } + } + var test = H.test; + test(); +" +frame size: 3 +parameter count: 1 +bytecode array length: 17 +bytecodes: [ + /* 41 E> */ B(StackCheck), + /* 46 S> */ B(Wide), B(LdaSmi), I16(262), + B(Star), R(1), + B(LdaConstant), U8(0), + B(Star), R(2), + B(CallRuntime), U16(Runtime::kNewTypeError), R(1), U8(2), + B(Throw), +] +constant pool: [ + ONE_BYTE_INTERNALIZED_STRING_TYPE ["#h"], +] +handlers: [ +] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden new file mode 100644 index 00000000000000..0f49e047309a73 --- /dev/null +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/StaticPrivateMethodDeclaration.golden @@ -0,0 +1,230 @@ +# +# Autogenerated by generate-bytecode-expectations. +# + +--- +wrap: yes +private methods: yes + +--- +snippet: " + { + class A { + static #a() { return 1; } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 41 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(4), R(0), + B(LdaUndefined), + /* 84 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static get #a() { return 1; } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 51 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(4), + B(LdaNull), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 88 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static set #a(val) { } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 51 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(LdaNull), + B(Star), R(4), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 81 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static get #a() { return 1; } + static set #a(val) { } + } + } +" +frame size: 6 +parameter count: 1 +bytecode array length: 54 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaTheHole), + B(Star), R(5), + B(CreateClosure), U8(2), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(3), + B(Mov), R(2), R(4), + B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3), + B(Star), R(3), + B(CreateClosure), U8(3), U8(1), U8(2), + B(Star), R(4), + B(CreateClosure), U8(4), U8(2), U8(2), + B(Star), R(5), + B(CallRuntime), U16(Runtime::kCreatePrivateAccessors), R(4), U8(2), + B(StaCurrentContextSlot), U8(4), + B(PopContext), R(1), + B(Mov), R(2), R(0), + B(LdaUndefined), + /* 115 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] + +--- +snippet: " + { + class A { + static #a() { } + #b() { } + } + } +" +frame size: 7 +parameter count: 1 +bytecode array length: 58 +bytecodes: [ + /* 30 E> */ B(StackCheck), + B(CreateBlockContext), U8(0), + B(PushContext), R(1), + B(LdaConstant), U8(2), + B(Star), R(3), + B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(3), U8(1), + B(StaCurrentContextSlot), U8(6), + B(LdaTheHole), + B(Star), R(6), + B(CreateClosure), U8(3), U8(0), U8(2), + B(Star), R(2), + B(LdaConstant), U8(1), + B(Star), R(4), + B(Mov), R(2), R(5), + B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3), + B(Star), R(4), + B(CreateClosure), U8(4), U8(1), U8(2), + B(StaCurrentContextSlot), U8(4), + B(CreateClosure), U8(5), U8(2), U8(2), + B(StaCurrentContextSlot), U8(5), + B(PopContext), R(1), + B(Mov), R(5), R(0), + B(LdaUndefined), + /* 87 S> */ B(Return), +] +constant pool: [ + SCOPE_INFO_TYPE, + FIXED_ARRAY_TYPE, + ONE_BYTE_INTERNALIZED_STRING_TYPE ["A"], + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, + SHARED_FUNCTION_INFO_TYPE, +] +handlers: [ +] diff --git a/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden index e3eed68138158e..2ec0a8baa5e757 100644 --- a/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden +++ b/deps/v8/test/cctest/interpreter/bytecode_expectations/SuperCallAndSpread.golden @@ -91,9 +91,9 @@ snippet: " test = new B(1, 2, 3).constructor; })(); " -frame size: 12 +frame size: 11 parameter count: 1 -bytecode array length: 124 +bytecode array length: 112 bytecodes: [ B(CreateRestParameter), B(Star), R(3), @@ -111,15 +111,11 @@ bytecodes: [ B(Ldar), R(6), B(Inc), U8(3), /* 152 S> */ B(Star), R(6), - B(GetIterator), R(3), U8(4), - B(Star), R(11), - B(CallProperty0), R(11), R(3), U8(6), - B(Mov), R(1), R(4), - B(JumpIfJSReceiver), U8(7), - B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), + B(GetIterator), R(3), U8(4), U8(6), B(Star), R(9), B(LdaNamedProperty), R(9), U8(0), U8(8), B(Star), R(8), + B(Mov), R(1), R(4), B(CallProperty0), R(8), R(9), U8(14), B(Star), R(10), B(JumpIfJSReceiver), U8(7), diff --git a/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc b/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc index 746c5540878491..2fe36588134db5 100644 --- a/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc +++ b/deps/v8/test/cctest/interpreter/generate-bytecode-expectations.cc @@ -47,11 +47,12 @@ class ProgramOptions final { oneshot_opt_(false), async_iteration_(false), private_methods_(false), + top_level_await_(false), verbose_(false) {} bool Validate() const; - void UpdateFromHeader(std::istream& stream); // NOLINT - void PrintHeader(std::ostream& stream) const; // NOLINT + void UpdateFromHeader(std::istream* stream); + void PrintHeader(std::ostream* stream) const; bool parsing_failed() const { return parsing_failed_; } bool print_help() const { return print_help_; } @@ -70,6 +71,7 @@ class ProgramOptions final { bool oneshot_opt() const { return oneshot_opt_; } bool async_iteration() const { return async_iteration_; } bool private_methods() const { return private_methods_; } + bool top_level_await() const { return top_level_await_; } bool verbose() const { return verbose_; } bool suppress_runtime_errors() const { return baseline() && !verbose_; } std::vector<std::string> input_filenames() const { return input_filenames_; } @@ -90,6 +92,7 @@ class ProgramOptions final { bool oneshot_opt_; bool async_iteration_; bool private_methods_; + bool top_level_await_; bool verbose_; std::vector<std::string> input_filenames_; std::string output_filename_; @@ -196,6 +199,8 @@ ProgramOptions ProgramOptions::FromCommandLine(int argc, char** argv) { options.async_iteration_ = true; } else if (strcmp(argv[i], "--private-methods") == 0) { options.private_methods_ = true; + } else if (strcmp(argv[i], "--harmony-top-level-await") == 0) { + options.top_level_await_ = true; } else if (strcmp(argv[i], "--verbose") == 0) { options.verbose_ = true; } else if (strncmp(argv[i], "--output=", 9) == 0) { @@ -291,17 +296,17 @@ bool ProgramOptions::Validate() const { return true; } -void ProgramOptions::UpdateFromHeader(std::istream& stream) { +void ProgramOptions::UpdateFromHeader(std::istream* stream) { std::string line; const char* kPrintCallee = "print callee: "; const char* kOneshotOpt = "oneshot opt: "; // Skip to the beginning of the options header - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "---") break; } - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line.compare(0, 8, "module: ") == 0) { module_ = ParseBoolean(line.c_str() + 8); } else if (line.compare(0, 6, "wrap: ") == 0) { @@ -318,6 +323,8 @@ void ProgramOptions::UpdateFromHeader(std::istream& stream) { async_iteration_ = ParseBoolean(line.c_str() + 17); } else if (line.compare(0, 17, "private methods: ") == 0) { private_methods_ = ParseBoolean(line.c_str() + 17); + } else if (line.compare(0, 17, "top level await: ") == 0) { + top_level_await_ = ParseBoolean(line.c_str() + 17); } else if (line == "---") { break; } else if (line.empty()) { @@ -328,22 +335,23 @@ void ProgramOptions::UpdateFromHeader(std::istream& stream) { } } -void ProgramOptions::PrintHeader(std::ostream& stream) const { // NOLINT - stream << "---" - << "\nwrap: " << BooleanToString(wrap_); +void ProgramOptions::PrintHeader(std::ostream* stream) const { + *stream << "---" + << "\nwrap: " << BooleanToString(wrap_); if (!test_function_name_.empty()) { - stream << "\ntest function name: " << test_function_name_; + *stream << "\ntest function name: " << test_function_name_; } - if (module_) stream << "\nmodule: yes"; - if (top_level_) stream << "\ntop level: yes"; - if (print_callee_) stream << "\nprint callee: yes"; - if (oneshot_opt_) stream << "\noneshot opt: yes"; - if (async_iteration_) stream << "\nasync iteration: yes"; - if (private_methods_) stream << "\nprivate methods: yes"; + if (module_) *stream << "\nmodule: yes"; + if (top_level_) *stream << "\ntop level: yes"; + if (print_callee_) *stream << "\nprint callee: yes"; + if (oneshot_opt_) *stream << "\noneshot opt: yes"; + if (async_iteration_) *stream << "\nasync iteration: yes"; + if (private_methods_) *stream << "\nprivate methods: yes"; + if (top_level_await_) *stream << "\ntop level await: yes"; - stream << "\n\n"; + *stream << "\n\n"; } V8InitializationScope::V8InitializationScope(const char* exec_path) @@ -370,17 +378,17 @@ V8InitializationScope::~V8InitializationScope() { v8::V8::ShutdownPlatform(); } -std::string ReadRawJSSnippet(std::istream& stream) { // NOLINT +std::string ReadRawJSSnippet(std::istream* stream) { std::stringstream body_buffer; - CHECK(body_buffer << stream.rdbuf()); + CHECK(body_buffer << stream->rdbuf()); return body_buffer.str(); } -bool ReadNextSnippet(std::istream& stream, std::string* string_out) { // NOLINT +bool ReadNextSnippet(std::istream* stream, std::string* string_out) { std::string line; bool found_begin_snippet = false; string_out->clear(); - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "snippet: \"") { found_begin_snippet = true; continue; @@ -420,8 +428,7 @@ std::string UnescapeString(const std::string& escaped_string) { } void ExtractSnippets(std::vector<std::string>* snippet_list, - std::istream& body_stream, // NOLINT - bool read_raw_js_snippet) { + std::istream* body_stream, bool read_raw_js_snippet) { if (read_raw_js_snippet) { snippet_list->push_back(ReadRawJSSnippet(body_stream)); } else { @@ -432,7 +439,7 @@ void ExtractSnippets(std::vector<std::string>* snippet_list, } } -void GenerateExpectationsFile(std::ostream& stream, // NOLINT +void GenerateExpectationsFile(std::ostream* stream, const std::vector<std::string>& snippet_list, const V8InitializationScope& platform, const ProgramOptions& options) { @@ -452,14 +459,16 @@ void GenerateExpectationsFile(std::ostream& stream, // NOLINT } if (options.private_methods()) i::FLAG_harmony_private_methods = true; + if (options.top_level_await()) i::FLAG_harmony_top_level_await = true; - stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; + *stream << "#\n# Autogenerated by generate-bytecode-expectations.\n#\n\n"; options.PrintHeader(stream); for (const std::string& snippet : snippet_list) { printer.PrintExpectation(stream, snippet); } i::FLAG_harmony_private_methods = false; + i::FLAG_harmony_top_level_await = false; } bool WriteExpectationsFile(const std::vector<std::string>& snippet_list, @@ -477,7 +486,7 @@ bool WriteExpectationsFile(const std::vector<std::string>& snippet_list, std::ostream& output_stream = options.write_to_stdout() ? std::cout : output_file_handle; - GenerateExpectationsFile(output_stream, snippet_list, platform, options); + GenerateExpectationsFile(&output_stream, snippet_list, platform, options); return true; } @@ -487,7 +496,7 @@ std::string WriteExpectationsToString( const V8InitializationScope& platform, const ProgramOptions& options) { std::stringstream output_string; - GenerateExpectationsFile(output_string, snippet_list, platform, options); + GenerateExpectationsFile(&output_string, snippet_list, platform, options); return output_string.str(); } @@ -520,6 +529,7 @@ void PrintUsage(const char* exec_path) { "Specify the name of the test function.\n" " --top-level Process top level code, not the top-level function.\n" " --private-methods Enable harmony_private_methods flag.\n" + " --top-level-await Enable await at the module level.\n" " --output=file.name\n" " Specify the output file. If not specified, output goes to " "stdout.\n" @@ -612,7 +622,7 @@ int main(int argc, char** argv) { // Rebaseline will never get here, so we will always take the // GenerateExpectationsFile at the end of this function. DCHECK(!options.rebaseline() && !options.check_baseline()); - ExtractSnippets(&snippet_list, std::cin, options.read_raw_js_snippet()); + ExtractSnippets(&snippet_list, &std::cin, options.read_raw_js_snippet()); } else { bool check_failed = false; for (const std::string& input_filename : options.input_filenames()) { @@ -628,11 +638,11 @@ int main(int argc, char** argv) { ProgramOptions updated_options = options; if (options.baseline()) { - updated_options.UpdateFromHeader(input_stream); + updated_options.UpdateFromHeader(&input_stream); CHECK(updated_options.Validate()); } - ExtractSnippets(&snippet_list, input_stream, + ExtractSnippets(&snippet_list, &input_stream, options.read_raw_js_snippet()); input_stream.close(); diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc index fda02933aa04ee..be0b129418707b 100644 --- a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc +++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc @@ -95,10 +95,10 @@ class InitializedIgnitionHandleScope : public InitializedHandleScope { } }; -void SkipGoldenFileHeader(std::istream& stream) { // NOLINT +void SkipGoldenFileHeader(std::istream* stream) { std::string line; int separators_seen = 0; - while (std::getline(stream, line)) { + while (std::getline(*stream, line)) { if (line == "---") separators_seen += 1; if (separators_seen == 2) return; } @@ -107,7 +107,7 @@ void SkipGoldenFileHeader(std::istream& stream) { // NOLINT std::string LoadGolden(const std::string& golden_filename) { std::ifstream expected_file((kGoldenFileDirectory + golden_filename).c_str()); CHECK(expected_file.is_open()); - SkipGoldenFileHeader(expected_file); + SkipGoldenFileHeader(&expected_file); std::ostringstream expected_stream; // Restore the first separator, which was consumed by SkipGoldenFileHeader expected_stream << "---\n" << expected_file.rdbuf(); @@ -125,31 +125,30 @@ std::string BuildActual(const BytecodeExpectationsPrinter& printer, if (prologue) source_code += prologue; source_code += snippet; if (epilogue) source_code += epilogue; - printer.PrintExpectation(actual_stream, source_code); + printer.PrintExpectation(&actual_stream, source_code); } return actual_stream.str(); } // inplace left trim -static inline void ltrim(std::string& str) { // NOLINT(runtime/references) - str.erase(str.begin(), - std::find_if(str.begin(), str.end(), - [](unsigned char ch) { return !std::isspace(ch); })); +static inline void ltrim(std::string* str) { + str->erase(str->begin(), + std::find_if(str->begin(), str->end(), + [](unsigned char ch) { return !std::isspace(ch); })); } // inplace right trim -static inline void rtrim(std::string& str) { // NOLINT(runtime/references) - str.erase(std::find_if(str.rbegin(), str.rend(), - [](unsigned char ch) { return !std::isspace(ch); }) - .base(), - str.end()); +static inline void rtrim(std::string* str) { + str->erase(std::find_if(str->rbegin(), str->rend(), + [](unsigned char ch) { return !std::isspace(ch); }) + .base(), + str->end()); } -static inline std::string trim( - std::string& str) { // NOLINT(runtime/references) +static inline std::string trim(std::string* str) { ltrim(str); rtrim(str); - return str; + return *str; } bool CompareTexts(const std::string& generated, const std::string& expected) { @@ -181,7 +180,7 @@ bool CompareTexts(const std::string& generated, const std::string& expected) { return false; } - if (trim(generated_line) != trim(expected_line)) { + if (trim(&generated_line) != trim(&expected_line)) { std::cerr << "Inputs differ at line " << line_number << "\n"; std::cerr << " Generated: '" << generated_line << "'\n"; std::cerr << " Expected: '" << expected_line << "'\n"; @@ -2885,6 +2884,130 @@ TEST(PrivateAccessorAccess) { i::FLAG_harmony_private_methods = old_methods_flag; } +TEST(StaticPrivateMethodDeclaration) { + bool old_methods_flag = i::FLAG_harmony_private_methods; + i::FLAG_harmony_private_methods = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + + const char* snippets[] = { + "{\n" + " class A {\n" + " static #a() { return 1; }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static get #a() { return 1; }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static set #a(val) { }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static get #a() { return 1; }\n" + " static set #a(val) { }\n" + " }\n" + "}\n", + + "{\n" + " class A {\n" + " static #a() { }\n" + " #b() { }\n" + " }\n" + "}\n"}; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("StaticPrivateMethodDeclaration.golden"))); + i::FLAG_harmony_private_methods = old_methods_flag; +} + +TEST(StaticPrivateMethodAccess) { + bool old_methods_flag = i::FLAG_harmony_private_methods; + i::FLAG_harmony_private_methods = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + printer.set_wrap(false); + printer.set_test_function_name("test"); + + const char* snippets[] = { + "class A {\n" + " static #a() { return 1; }\n" + " static test() { return this.#a(); }\n" + "}\n" + "\n" + "var test = A.test;\n" + "test();\n", + + "class B {\n" + " static #b() { return 1; }\n" + " static test() { this.#b = 1; }\n" + "}\n" + "\n" + "var test = B.test;\n" + "test();\n", + + "class C {\n" + " static #c() { return 1; }\n" + " static test() { this.#c++; }\n" + "}\n" + "\n" + "var test = C.test;\n" + "test();\n", + + "class D {\n" + " static get #d() { return 1; }\n" + " static set #d(val) { }\n" + "\n" + " static test() {\n" + " this.#d++;\n" + " this.#d = 1;\n" + " return this.#d;\n" + " }\n" + "}\n" + "\n" + "var test = D.test;\n" + "test();\n", + + "class E {\n" + " static get #e() { return 1; }\n" + " static test() { this.#e++; }\n" + "}\n" + "var test = E.test;\n" + "test();\n", + + "class F {\n" + " static set #f(val) { }\n" + " static test() { this.#f++; }\n" + "}\n" + "var test = F.test;\n" + "test();\n", + + "class G {\n" + " static get #d() { return 1; }\n" + " static test() { this.#d = 1; }\n" + "}\n" + "var test = G.test;\n" + "test();\n", + + "class H {\n" + " set #h(val) { }\n" + " static test() { this.#h; }\n" + "}\n" + "var test = H.test;\n" + "test();\n"}; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("StaticPrivateMethodAccess.golden"))); + i::FLAG_harmony_private_methods = old_methods_flag; +} + TEST(PrivateAccessorDeclaration) { bool old_methods_flag = i::FLAG_harmony_private_methods; i::FLAG_harmony_private_methods = true; @@ -3099,6 +3222,35 @@ TEST(Modules) { LoadGolden("Modules.golden"))); } +TEST(AsyncModules) { + bool previous_top_level_await_flag = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; + InitializedIgnitionHandleScope scope; + BytecodeExpectationsPrinter printer(CcTest::isolate()); + printer.set_wrap(false); + printer.set_module(true); + printer.set_top_level(true); + + const char* snippets[] = { + "await 42;\n", + + "await import(\"foo\");\n", + + "await 42;\n" + "async function foo() {\n" + " await 42;\n" + "}\n" + "foo();\n", + + "import * as foo from \"bar\";\n" + "await import(\"goo\");\n", + }; + + CHECK(CompareTexts(BuildActual(printer, snippets), + LoadGolden("AsyncModules.golden"))); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag; +} + TEST(SuperCallAndSpread) { InitializedIgnitionHandleScope scope; BytecodeExpectationsPrinter printer(CcTest::isolate()); diff --git a/deps/v8/test/cctest/interpreter/test-interpreter.cc b/deps/v8/test/cctest/interpreter/test-interpreter.cc index 466e768d7ded5b..0ddc8fe6087b13 100644 --- a/deps/v8/test/cctest/interpreter/test-interpreter.cc +++ b/deps/v8/test/cctest/interpreter/test-interpreter.cc @@ -1485,19 +1485,20 @@ TEST(InterpreterCall) { } } -static BytecodeArrayBuilder& SetRegister( - BytecodeArrayBuilder& builder, // NOLINT(runtime/references) - Register reg, int value, Register scratch) { - return builder.StoreAccumulatorInRegister(scratch) +static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder* builder, + Register reg, int value, + Register scratch) { + return builder->StoreAccumulatorInRegister(scratch) .LoadLiteral(Smi::FromInt(value)) .StoreAccumulatorInRegister(reg) .LoadAccumulatorWithRegister(scratch); } -static BytecodeArrayBuilder& IncrementRegister( - BytecodeArrayBuilder& builder, // NOLINT(runtime/references) - Register reg, int value, Register scratch, int slot_index) { - return builder.StoreAccumulatorInRegister(scratch) +static BytecodeArrayBuilder& IncrementRegister(BytecodeArrayBuilder* builder, + Register reg, int value, + Register scratch, + int slot_index) { + return builder->StoreAccumulatorInRegister(scratch) .LoadLiteral(Smi::FromInt(value)) .BinaryOperation(Token::Value::ADD, reg, slot_index) .StoreAccumulatorInRegister(reg) @@ -1525,13 +1526,13 @@ TEST(InterpreterJumps) { builder.LoadLiteral(Smi::zero()) .StoreAccumulatorInRegister(reg) .Jump(&label[0]); - SetRegister(builder, reg, 1024, scratch).Bind(&loop_header); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[1]); - SetRegister(builder, reg, 2048, scratch).Bind(&label[0]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot1)) + SetRegister(&builder, reg, 1024, scratch).Bind(&loop_header); + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[1]); + SetRegister(&builder, reg, 2048, scratch).Bind(&label[0]); + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot1)) .JumpLoop(&loop_header, 0); - SetRegister(builder, reg, 4096, scratch).Bind(&label[1]); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot2)) + SetRegister(&builder, reg, 4096, scratch).Bind(&label[1]); + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot2)) .LoadAccumulatorWithRegister(reg) .Return(); @@ -1566,19 +1567,19 @@ TEST(InterpreterConditionalJumps) { .StoreAccumulatorInRegister(reg) .LoadFalse() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]); - IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) + IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot)) .Bind(&label[0]) .LoadTrue() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1)) .LoadTrue() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]); - IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) + IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2)) .Bind(&label[1]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3)) .LoadFalse() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4)) .LoadAccumulatorWithRegister(reg) .Bind(&done) .Bind(&done1) @@ -1616,19 +1617,19 @@ TEST(InterpreterConditionalJumps2) { .StoreAccumulatorInRegister(reg) .LoadFalse() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &label[0]); - IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) + IncrementRegister(&builder, reg, 1024, scratch, GetIndex(slot)) .Bind(&label[0]) .LoadTrue() .JumpIfFalse(ToBooleanMode::kAlreadyBoolean, &done); - IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) + IncrementRegister(&builder, reg, 1, scratch, GetIndex(slot1)) .LoadTrue() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &label[1]); - IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) + IncrementRegister(&builder, reg, 2048, scratch, GetIndex(slot2)) .Bind(&label[1]); - IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) + IncrementRegister(&builder, reg, 2, scratch, GetIndex(slot3)) .LoadFalse() .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &done1); - IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) + IncrementRegister(&builder, reg, 4, scratch, GetIndex(slot4)) .LoadAccumulatorWithRegister(reg) .Bind(&done) .Bind(&done1) diff --git a/deps/v8/test/cctest/libplatform/DEPS b/deps/v8/test/cctest/libplatform/DEPS index b2bee408ab7804..54415e157b8c02 100644 --- a/deps/v8/test/cctest/libplatform/DEPS +++ b/deps/v8/test/cctest/libplatform/DEPS @@ -1,3 +1,3 @@ include_rules = [ - "+perfetto", + "+protos/perfetto", ] diff --git a/deps/v8/test/cctest/libplatform/test-tracing.cc b/deps/v8/test/cctest/libplatform/test-tracing.cc index a98445be978f27..1f1cb55f9ba65a 100644 --- a/deps/v8/test/cctest/libplatform/test-tracing.cc +++ b/deps/v8/test/cctest/libplatform/test-tracing.cc @@ -10,11 +10,11 @@ #include "test/cctest/cctest.h" #ifdef V8_USE_PERFETTO -#include "perfetto/trace/chrome/chrome_trace_event.pb.h" -#include "perfetto/trace/chrome/chrome_trace_event.pbzero.h" -#include "perfetto/trace/chrome/chrome_trace_packet.pb.h" -#include "perfetto/trace/trace.pb.h" #include "perfetto/tracing.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pb.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h" +#include "protos/perfetto/trace/chrome/chrome_trace_packet.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #include "src/libplatform/tracing/json-trace-event-listener.h" #include "src/libplatform/tracing/trace-event-listener.h" #endif // V8_USE_PERFETTO @@ -157,7 +157,7 @@ void PopulateJSONWriter(TraceWriter* writer) { std::unique_ptr<v8::Platform> default_platform( v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -242,7 +242,7 @@ TEST(TestTracingController) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -301,8 +301,7 @@ TEST(TestTracingControllerMultipleArgsAndCopy) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = - base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) @@ -424,7 +423,7 @@ TEST(TracingObservers) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -517,7 +516,7 @@ TEST(AddTraceEventMultiThreaded) { v8::platform::NewDefaultPlatform()); i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); v8::platform::tracing::TracingController* tracing_controller = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform.get()) ->SetTracingController(std::move(tracing)); @@ -576,8 +575,7 @@ class TracingTestHarness { default_platform_ = v8::platform::NewDefaultPlatform(); i::V8::SetPlatformForTesting(default_platform_.get()); - auto tracing = - base::make_unique<v8::platform::tracing::TracingController>(); + auto tracing = std::make_unique<v8::platform::tracing::TracingController>(); tracing_controller_ = tracing.get(); static_cast<v8::platform::DefaultPlatform*>(default_platform_.get()) ->SetTracingController(std::move(tracing)); diff --git a/deps/v8/test/cctest/manually-externalized-buffer.h b/deps/v8/test/cctest/manually-externalized-buffer.h new file mode 100644 index 00000000000000..b5eeed7382fe70 --- /dev/null +++ b/deps/v8/test/cctest/manually-externalized-buffer.h @@ -0,0 +1,34 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ +#define V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ + +#include "src/api/api-inl.h" + +namespace v8 { +namespace internal { +namespace testing { + +// Utility to free the allocated memory for a buffer that is manually +// externalized in a test. +struct ManuallyExternalizedBuffer { + Handle<JSArrayBuffer> buffer_; + v8::ArrayBuffer::Contents contents_; + + explicit ManuallyExternalizedBuffer(Handle<JSArrayBuffer> buffer) + : buffer_(buffer), + contents_(v8::Utils::ToLocal(buffer_)->Externalize()) {} + ~ManuallyExternalizedBuffer() { + contents_.Deleter()(contents_.Data(), contents_.ByteLength(), + contents_.DeleterData()); + } + void* backing_store() { return contents_.Data(); } +}; + +} // namespace testing +} // namespace internal +} // namespace v8 + +#endif // V8_CCTEST_MANUALLY_EXTERNALIZED_BUFFER_H_ diff --git a/deps/v8/test/cctest/test-accessor-assembler.cc b/deps/v8/test/cctest/test-accessor-assembler.cc index c88c85b5860108..6183ef970c551e 100644 --- a/deps/v8/test/cctest/test-accessor-assembler.cc +++ b/deps/v8/test/cctest/test-accessor-assembler.cc @@ -18,7 +18,6 @@ namespace internal { using compiler::CodeAssemblerTester; using compiler::FunctionTester; using compiler::Node; -using compiler::TNode; namespace { diff --git a/deps/v8/test/cctest/test-api-accessors.cc b/deps/v8/test/cctest/test-api-accessors.cc index 8c2f92d665b579..5f82d787116dfc 100644 --- a/deps/v8/test/cctest/test-api-accessors.cc +++ b/deps/v8/test/cctest/test-api-accessors.cc @@ -287,21 +287,30 @@ TEST(AccessorSetHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetAccessor(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetAccessor(context, v8_str("foo"), Getter, nullptr, v8::MaybeLocal<v8::Value>(), v8::AccessControl::DEFAULT, v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -323,12 +332,16 @@ TEST(SetAccessorSetSideEffectReceiverCheck1) { v8::SideEffectType::kHasNoSideEffect, v8::SideEffectType::kHasSideEffectToReceiver) .ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked() ->Equals(env.local(), v8_str("return value")) .FromJust()); v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); CHECK_EQ(0, set_accessor_call_count); @@ -357,11 +370,15 @@ TEST(SetAccessorSetSideEffectReceiverCheck2) { ->Set(env.local(), v8_str("f"), templ->GetFunction(env.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f().bar"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked() ->Equals(env.local(), v8_str("return value")) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("new f().bar = 1"), true) + v8::debug::EvaluateGlobal( + isolate, v8_str("new f().bar = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); CHECK_EQ(1, set_accessor_call_count); } @@ -377,20 +394,29 @@ TEST(AccessorSetNativeDataPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetNativeDataProperty(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetNativeDataProperty( context, v8_str("foo"), Getter, nullptr, v8::Local<v8::Value>(), v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -407,20 +433,29 @@ TEST(AccessorSetLazyDataPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); obj->SetLazyDataProperty(context, v8_str("foo"), Getter).ToChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); obj->SetLazyDataProperty(context, v8_str("foo"), Getter, v8::Local<v8::Value>(), v8::PropertyAttribute::None, v8::SideEffectType::kHasNoSideEffect) .ToChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -440,15 +475,24 @@ TEST(ObjectTemplateSetAccessorHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -468,15 +512,24 @@ TEST(ObjectTemplateSetNativePropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); @@ -495,15 +548,24 @@ TEST(ObjectTemplateSetLazyPropertyHasNoSideEffect) { v8::Local<v8::Object> obj = templ->NewInstance(env.local()).ToLocalChecked(); CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), true).ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that setter is not whitelisted. v8::TryCatch try_catch(isolate); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2 = 1"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.foo2 = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); CHECK(try_catch.HasCaught()); - CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), false) + CHECK_NE(1, v8::debug::EvaluateGlobal(isolate, v8_str("obj.foo2"), + v8::debug::EvaluateGlobalMode::kDefault) .ToLocalChecked() ->Int32Value(env.local()) .FromJust()); diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc index 5b8433a6a26bd7..fea80dfa42e022 100644 --- a/deps/v8/test/cctest/test-api-array-buffer.cc +++ b/deps/v8/test/cctest/test-api-array-buffer.cc @@ -13,43 +13,6 @@ using ::v8::Value; namespace { -class ScopedArrayBufferContents { - public: - explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::ArrayBuffer::Contents contents_; -}; - -class ScopedSharedArrayBufferContents { - public: - explicit ScopedSharedArrayBufferContents( - const v8::SharedArrayBuffer::Contents& contents) - : contents_(contents) {} - ~ScopedSharedArrayBufferContents() { free(contents_.AllocationBase()); } - void* Data() const { return contents_.Data(); } - size_t ByteLength() const { return contents_.ByteLength(); } - - void* AllocationBase() const { return contents_.AllocationBase(); } - size_t AllocationLength() const { return contents_.AllocationLength(); } - v8::ArrayBuffer::Allocator::AllocationMode AllocationMode() const { - return contents_.AllocationMode(); - } - - private: - const v8::SharedArrayBuffer::Contents contents_; -}; - void CheckDataViewIsDetached(v8::Local<v8::DataView> dv) { CHECK_EQ(0, static_cast<int>(dv->ByteLength())); CHECK_EQ(0, static_cast<int>(dv->ByteOffset())); @@ -83,6 +46,20 @@ Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, int byteOffset, return ta; } +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::ArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + +std::shared_ptr<v8::BackingStore> Externalize(Local<v8::SharedArrayBuffer> ab) { + std::shared_ptr<v8::BackingStore> backing_store = ab->GetBackingStore(); + ab->Externalize(backing_store); + CHECK(ab->IsExternal()); + return backing_store; +} + } // namespace THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { @@ -92,15 +69,14 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); + CHECK_EQ(1024, backing_store->ByteLength()); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -133,10 +109,9 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -152,8 +127,8 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -172,7 +147,7 @@ THREADED_TEST(ArrayBuffer_External) { Local<v8::ArrayBuffer> ab3 = v8::ArrayBuffer::New(isolate, my_data.begin(), 100); CheckInternalFieldsAreZero(ab3); - CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); + CHECK_EQ(100, ab3->ByteLength()); CHECK(ab3->IsExternal()); CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust()); @@ -242,12 +217,12 @@ THREADED_TEST(ArrayBuffer_DetachingApi) { v8::Local<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); - CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); - CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); + CHECK_EQ(1, dv->ByteOffset()); + CHECK_EQ(1023, dv->ByteLength()); - ScopedArrayBufferContents contents(buffer->Externalize()); + Externalize(buffer); buffer->Detach(); - CHECK_EQ(0, static_cast<int>(buffer->ByteLength())); + CHECK_EQ(0, buffer->ByteLength()); CheckIsDetached(u8a); CheckIsDetached(u8c); CheckIsDetached(i8a); @@ -283,9 +258,9 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { v8::Local<v8::DataView> dv = v8::Local<v8::DataView>::Cast(CompileRun("dv")); - ScopedArrayBufferContents contents(ab->Externalize()); + Externalize(ab); ab->Detach(); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(0, ab->ByteLength()); CHECK_EQ(0, v8_run_int32value(v8_compile("ab.byteLength"))); CheckIsTypedArrayVarDetached("u8a"); @@ -302,6 +277,7 @@ THREADED_TEST(ArrayBuffer_DetachingScript) { CheckDataViewIsDetached(dv); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(ArrayBuffer_AllocationInformation) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -309,7 +285,7 @@ THREADED_TEST(ArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, ab_size); - ScopedArrayBufferContents contents(ab->Externalize()); + v8::ArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -329,13 +305,13 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 0); + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 2); CheckInternalFieldsAreZero(ab); - CHECK_EQ(0, static_cast<int>(ab->ByteLength())); + CHECK_EQ(2, ab->ByteLength()); CHECK(!ab->IsExternal()); // Externalize the buffer (taking ownership of the backing store memory). - ScopedArrayBufferContents ab_contents(ab->Externalize()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); Local<v8::Uint8Array> u8a = v8::Uint8Array::New(ab, 0, 0); // Calling Buffer() will materialize the ArrayBuffer (transitioning it from @@ -344,6 +320,7 @@ THREADED_TEST(ArrayBuffer_ExternalizeEmpty) { USE(u8a->Buffer()); CHECK(ab->IsExternal()); + CHECK_EQ(2, backing_store->ByteLength()); } THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { @@ -354,15 +331,14 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024); CheckInternalFieldsAreZero(ab); - CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); + CHECK_EQ(1024, ab->ByteLength()); CHECK(!ab->IsExternal()); CcTest::CollectAllGarbage(); - ScopedSharedArrayBufferContents ab_contents(ab->Externalize()); - CHECK(ab->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab); - CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); - uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); + CHECK_EQ(1024, backing_store->ByteLength()); + uint8_t* data = static_cast<uint8_t*>(backing_store->Data()); CHECK_NOT_NULL(data); CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); @@ -383,6 +359,35 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +THREADED_TEST(ArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + ab1->Detach(); + Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + +THREADED_TEST(SharedArrayBuffer_ExternalReused) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + i::ScopedVector<uint8_t> data(100); + Local<v8::SharedArrayBuffer> ab1 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs1 = ab1->GetBackingStore(); + Local<v8::SharedArrayBuffer> ab2 = + v8::SharedArrayBuffer::New(isolate, data.begin(), 100); + std::shared_ptr<v8::BackingStore> bs2 = ab2->GetBackingStore(); + CHECK_EQ(bs1->Data(), bs2->Data()); +} + THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -396,10 +401,9 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { "u8_a[1] = 0xFF; u8_a.buffer"); Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result); CheckInternalFieldsAreZero(ab1); - CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); + CHECK_EQ(2, ab1->ByteLength()); CHECK(!ab1->IsExternal()); - ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize()); - CHECK(ab1->IsExternal()); + std::shared_ptr<v8::BackingStore> backing_store = Externalize(ab1); result = CompileRun("ab1.byteLength"); CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); @@ -415,8 +419,8 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { result = CompileRun("u8_b[1]"); CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); - CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); - uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); + CHECK_EQ(2, backing_store->ByteLength()); + uint8_t* ab1_data = static_cast<uint8_t*>(backing_store->Data()); CHECK_EQ(0xBB, ab1_data[0]); CHECK_EQ(0xFF, ab1_data[1]); ab1_data[0] = 0xCC; @@ -458,6 +462,7 @@ THREADED_TEST(SharedArrayBuffer_External) { CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } +// TODO(v8:9380) the Contents data structure should be deprecated. THREADED_TEST(SharedArrayBuffer_AllocationInformation) { i::FLAG_harmony_sharedarraybuffer = true; LocalContext env; @@ -467,7 +472,7 @@ THREADED_TEST(SharedArrayBuffer_AllocationInformation) { const size_t ab_size = 1024; Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, ab_size); - ScopedSharedArrayBufferContents contents(ab->Externalize()); + v8::SharedArrayBuffer::Contents contents(ab->GetContents()); // Array buffers should have normal allocation mode. CHECK_EQ(contents.AllocationMode(), @@ -500,7 +505,7 @@ THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) { CcTest::CollectAllGarbage(); // Should not move the pointer - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); } THREADED_TEST(SkipArrayBufferDuringScavenge) { @@ -525,5 +530,107 @@ THREADED_TEST(SkipArrayBufferDuringScavenge) { CcTest::CollectGarbage(i::NEW_SPACE); // in old gen now // Use `ab` to silence compiler warning - CHECK_EQ(ab->GetContents().Data(), store_ptr); + CHECK_EQ(ab->GetBackingStore()->Data(), store_ptr); +} + +THREADED_TEST(Regress1006600) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + + Local<v8::Value> ab = CompileRunChecked(isolate, "new ArrayBuffer()"); + for (int i = 0; i < v8::ArrayBuffer::kEmbedderFieldCount; i++) { + CHECK_NULL(ab.As<v8::Object>()->GetAlignedPointerFromInternalField(i)); + } +} + +THREADED_TEST(ArrayBuffer_NewBackingStore) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + std::shared_ptr<v8::BackingStore> backing_store = + v8::ArrayBuffer::NewBackingStore(isolate, 100); + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, backing_store); + CHECK_EQ(backing_store.get(), ab->GetBackingStore().get()); +} + +THREADED_TEST(SharedArrayBuffer_NewBackingStore) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope handle_scope(isolate); + std::shared_ptr<v8::BackingStore> backing_store = + v8::SharedArrayBuffer::NewBackingStore(isolate, 100); + Local<v8::SharedArrayBuffer> ab = + v8::SharedArrayBuffer::New(isolate, backing_store); + CHECK_EQ(backing_store.get(), ab->GetBackingStore().get()); +} + +static void* backing_store_custom_data = nullptr; +static size_t backing_store_custom_length = 0; +static bool backing_store_custom_called = false; +const intptr_t backing_store_custom_deleter_data = 1234567; + +static void BackingStoreCustomDeleter(void* data, size_t length, + void* deleter_data) { + CHECK(!backing_store_custom_called); + CHECK_EQ(backing_store_custom_data, data); + CHECK_EQ(backing_store_custom_length, length); + CHECK_EQ(backing_store_custom_deleter_data, + reinterpret_cast<intptr_t>(deleter_data)); + free(data); + backing_store_custom_called = true; } + +TEST(ArrayBuffer_NewBackingStore_CustomDeleter) { + { + // Create and destroy a backing store. + backing_store_custom_called = false; + backing_store_custom_data = malloc(100); + backing_store_custom_length = 100; + v8::ArrayBuffer::NewBackingStore( + backing_store_custom_data, backing_store_custom_length, + BackingStoreCustomDeleter, + reinterpret_cast<void*>(backing_store_custom_deleter_data)); + } + CHECK(backing_store_custom_called); +} + +TEST(SharedArrayBuffer_NewBackingStore_CustomDeleter) { + { + // Create and destroy a backing store. + backing_store_custom_called = false; + backing_store_custom_data = malloc(100); + backing_store_custom_length = 100; + v8::SharedArrayBuffer::NewBackingStore( + backing_store_custom_data, backing_store_custom_length, + BackingStoreCustomDeleter, + reinterpret_cast<void*>(backing_store_custom_deleter_data)); + } + CHECK(backing_store_custom_called); +} + +class DummyAllocator final : public v8::ArrayBuffer::Allocator { + public: + DummyAllocator() : allocator_(NewDefaultAllocator()) {} + + ~DummyAllocator() override { CHECK_EQ(allocation_count(), 0); } + + void* Allocate(size_t length) override { + allocation_count_++; + return allocator_->Allocate(length); + } + void* AllocateUninitialized(size_t length) override { + allocation_count_++; + return allocator_->AllocateUninitialized(length); + } + void Free(void* data, size_t length) override { + allocation_count_--; + allocator_->Free(data, length); + } + + uint64_t allocation_count() const { return allocation_count_; } + + private: + std::unique_ptr<v8::ArrayBuffer::Allocator> allocator_; + uint64_t allocation_count_ = 0; +}; diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc index e331d1a26ad84f..cbf9f75be59603 100644 --- a/deps/v8/test/cctest/test-api-interceptors.cc +++ b/deps/v8/test/cctest/test-api-interceptors.cc @@ -2712,16 +2712,26 @@ THREADED_TEST(NoSideEffectPropertyHandler) { templ->NewInstance(context.local()).ToLocalChecked(); context->Global()->Set(context.local(), v8_str("obj"), object).FromJust(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj.x"), true).IsEmpty()); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("obj.x = 1"), true).IsEmpty()); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("'x' in obj"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("delete obj.x"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj.x = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("'x' in obj"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("delete obj.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); // Wrap the variable declaration since declaring globals is a side effect. CHECK(v8::debug::EvaluateGlobal( - isolate, v8_str("(function() { for (var p in obj) ; })()"), true) + isolate, v8_str("(function() { for (var p in obj) ; })()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); // Side-effect-free version. @@ -2734,15 +2744,25 @@ THREADED_TEST(NoSideEffectPropertyHandler) { templ2->NewInstance(context.local()).ToLocalChecked(); context->Global()->Set(context.local(), v8_str("obj2"), object2).FromJust(); - v8::debug::EvaluateGlobal(isolate, v8_str("obj2.x"), true).ToLocalChecked(); - CHECK( - v8::debug::EvaluateGlobal(isolate, v8_str("obj2.x = 1"), true).IsEmpty()); - v8::debug::EvaluateGlobal(isolate, v8_str("'x' in obj2"), true) + v8::debug::EvaluateGlobal( + isolate, v8_str("obj2.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj2.x = 1"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + v8::debug::EvaluateGlobal( + isolate, v8_str("'x' in obj2"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("delete obj2.x"), true) + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("delete obj2.x"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .IsEmpty()); v8::debug::EvaluateGlobal( - isolate, v8_str("(function() { for (var p in obj2) ; })()"), true) + isolate, v8_str("(function() { for (var p in obj2) ; })()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) .ToLocalChecked(); } diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 345ee0bfc9de97..12faaff39cbfcb 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -46,6 +46,7 @@ #include "src/execution/arguments.h" #include "src/execution/execution.h" #include "src/execution/futex-emulation.h" +#include "src/execution/protectors-inl.h" #include "src/execution/vm-state.h" #include "src/handles/global-handles.h" #include "src/heap/heap-inl.h" @@ -7064,7 +7065,7 @@ static const char* kSimpleExtensionSource = TEST(SimpleExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("simpletest", kSimpleExtensionSource)); + std::make_unique<Extension>("simpletest", kSimpleExtensionSource)); const char* extension_names[] = {"simpletest"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7086,7 +7087,7 @@ static const char* kStackTraceFromExtensionSource = TEST(StackTraceInExtension) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( + v8::RegisterExtension(std::make_unique<Extension>( "stacktracetest", kStackTraceFromExtensionSource)); const char* extension_names[] = {"stacktracetest"}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7104,7 +7105,7 @@ TEST(StackTraceInExtension) { TEST(NullExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>("nulltest", nullptr)); + v8::RegisterExtension(std::make_unique<Extension>("nulltest", nullptr)); const char* extension_names[] = {"nulltest"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7122,8 +7123,8 @@ static const int kEmbeddedExtensionSourceValidLen = 34; TEST(ExtensionMissingSourceLength) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "srclentest_fail", kEmbeddedExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("srclentest_fail", kEmbeddedExtensionSource)); const char* extension_names[] = {"srclentest_fail"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7137,9 +7138,9 @@ TEST(ExtensionWithSourceLength) { v8::HandleScope handle_scope(CcTest::isolate()); i::ScopedVector<char> extension_name(32); i::SNPrintF(extension_name, "ext #%d", source_len); - v8::RegisterExtension(v8::base::make_unique<Extension>( - extension_name.begin(), kEmbeddedExtensionSource, 0, nullptr, - source_len)); + v8::RegisterExtension(std::make_unique<Extension>(extension_name.begin(), + kEmbeddedExtensionSource, + 0, nullptr, source_len)); const char* extension_names[1] = {extension_name.begin()}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7177,9 +7178,9 @@ static const char* kEvalExtensionSource2 = TEST(UseEvalFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("evaltest1", kEvalExtensionSource1)); + std::make_unique<Extension>("evaltest1", kEvalExtensionSource1)); v8::RegisterExtension( - v8::base::make_unique<Extension>("evaltest2", kEvalExtensionSource2)); + std::make_unique<Extension>("evaltest2", kEvalExtensionSource2)); const char* extension_names[] = {"evaltest1", "evaltest2"}; v8::ExtensionConfiguration extensions(2, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7213,9 +7214,9 @@ static const char* kWithExtensionSource2 = TEST(UseWithFromExtension) { v8::HandleScope handle_scope(CcTest::isolate()); v8::RegisterExtension( - v8::base::make_unique<Extension>("withtest1", kWithExtensionSource1)); + std::make_unique<Extension>("withtest1", kWithExtensionSource1)); v8::RegisterExtension( - v8::base::make_unique<Extension>("withtest2", kWithExtensionSource2)); + std::make_unique<Extension>("withtest2", kWithExtensionSource2)); const char* extension_names[] = {"withtest1", "withtest2"}; v8::ExtensionConfiguration extensions(2, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7232,7 +7233,7 @@ TEST(UseWithFromExtension) { TEST(AutoExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); auto extension = - v8::base::make_unique<Extension>("autotest", kSimpleExtensionSource); + std::make_unique<Extension>("autotest", kSimpleExtensionSource); extension->set_auto_enable(true); v8::RegisterExtension(std::move(extension)); v8::Local<Context> context = Context::New(CcTest::isolate()); @@ -7250,7 +7251,7 @@ static const char* kSyntaxErrorInExtensionSource = "["; // error but results in an empty context. TEST(SyntaxErrorExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( + v8::RegisterExtension(std::make_unique<Extension>( "syntaxerror", kSyntaxErrorInExtensionSource)); const char* extension_names[] = {"syntaxerror"}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7266,8 +7267,8 @@ static const char* kExceptionInExtensionSource = "throw 42"; // a fatal error but results in an empty context. TEST(ExceptionExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "exception", kExceptionInExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("exception", kExceptionInExtensionSource)); const char* extension_names[] = {"exception"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7285,8 +7286,8 @@ static const char* kNativeCallTest = // Test that a native runtime calls are supported in extensions. TEST(NativeCallInExtensions) { v8::HandleScope handle_scope(CcTest::isolate()); - v8::RegisterExtension(v8::base::make_unique<Extension>( - "nativecall", kNativeCallInExtensionSource)); + v8::RegisterExtension( + std::make_unique<Extension>("nativecall", kNativeCallInExtensionSource)); const char* extension_names[] = {"nativecall"}; v8::ExtensionConfiguration extensions(1, extension_names); v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); @@ -7320,7 +7321,7 @@ class NativeFunctionExtension : public Extension { TEST(NativeFunctionDeclaration) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedecl"; - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "native function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7336,7 +7337,7 @@ TEST(NativeFunctionDeclarationError) { v8::HandleScope handle_scope(CcTest::isolate()); const char* name = "nativedeclerr"; // Syntax error in extension code. - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "native\nfunction foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7350,7 +7351,7 @@ TEST(NativeFunctionDeclarationErrorEscape) { const char* name = "nativedeclerresc"; // Syntax error in extension code - escape code in "native" means that // it's not treated as a keyword. - v8::RegisterExtension(v8::base::make_unique<NativeFunctionExtension>( + v8::RegisterExtension(std::make_unique<NativeFunctionExtension>( name, "nativ\\u0065 function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); @@ -7382,17 +7383,17 @@ static void CheckDependencies(const char* name, const char* expected) { THREADED_TEST(ExtensionDependency) { static const char* kEDeps[] = {"D"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("E", "this.loaded += 'E';", 1, kEDeps)); + std::make_unique<Extension>("E", "this.loaded += 'E';", 1, kEDeps)); static const char* kDDeps[] = {"B", "C"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("D", "this.loaded += 'D';", 2, kDDeps)); + std::make_unique<Extension>("D", "this.loaded += 'D';", 2, kDDeps)); static const char* kBCDeps[] = {"A"}; v8::RegisterExtension( - v8::base::make_unique<Extension>("B", "this.loaded += 'B';", 1, kBCDeps)); + std::make_unique<Extension>("B", "this.loaded += 'B';", 1, kBCDeps)); v8::RegisterExtension( - v8::base::make_unique<Extension>("C", "this.loaded += 'C';", 1, kBCDeps)); + std::make_unique<Extension>("C", "this.loaded += 'C';", 1, kBCDeps)); v8::RegisterExtension( - v8::base::make_unique<Extension>("A", "this.loaded += 'A';")); + std::make_unique<Extension>("A", "this.loaded += 'A';")); CheckDependencies("A", "undefinedA"); CheckDependencies("B", "undefinedAB"); CheckDependencies("C", "undefinedAC"); @@ -7464,7 +7465,7 @@ v8::Local<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( THREADED_TEST(FunctionLookup) { - v8::RegisterExtension(v8::base::make_unique<FunctionExtension>()); + v8::RegisterExtension(std::make_unique<FunctionExtension>()); v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = {"functiontest"}; v8::ExtensionConfiguration config(1, exts); @@ -7483,7 +7484,7 @@ THREADED_TEST(FunctionLookup) { THREADED_TEST(NativeFunctionConstructCall) { - v8::RegisterExtension(v8::base::make_unique<FunctionExtension>()); + v8::RegisterExtension(std::make_unique<FunctionExtension>()); v8::HandleScope handle_scope(CcTest::isolate()); static const char* exts[1] = {"functiontest"}; v8::ExtensionConfiguration config(1, exts); @@ -7520,9 +7521,9 @@ void StoringErrorCallback(const char* location, const char* message) { TEST(ErrorReporting) { CcTest::isolate()->SetFatalErrorHandler(StoringErrorCallback); static const char* aDeps[] = {"B"}; - v8::RegisterExtension(v8::base::make_unique<Extension>("A", "", 1, aDeps)); + v8::RegisterExtension(std::make_unique<Extension>("A", "", 1, aDeps)); static const char* bDeps[] = {"A"}; - v8::RegisterExtension(v8::base::make_unique<Extension>("B", "", 1, bDeps)); + v8::RegisterExtension(std::make_unique<Extension>("B", "", 1, bDeps)); last_location = nullptr; v8::ExtensionConfiguration config(1, bDeps); v8::Local<Context> context = Context::New(CcTest::isolate(), &config); @@ -10625,7 +10626,6 @@ THREADED_TEST(ShadowObjectAndDataProperty) { i::FeedbackSlot slot = i::FeedbackVector::ToSlot(0); i::FeedbackNexus nexus(foo->feedback_vector(), slot); CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind()); - CHECK_EQ(i::PREMONOMORPHIC, nexus.ic_state()); CompileRun("foo(1)"); CHECK_EQ(i::MONOMORPHIC, nexus.ic_state()); // We go a bit further, checking that the form of monomorphism is @@ -10676,7 +10676,6 @@ THREADED_TEST(ShadowObjectAndDataPropertyTurbo) { i::FeedbackSlot slot = i::FeedbackVector::ToSlot(0); i::FeedbackNexus nexus(foo->feedback_vector(), slot); CHECK_EQ(i::FeedbackSlotKind::kStoreGlobalSloppy, nexus.kind()); - CHECK_EQ(i::PREMONOMORPHIC, nexus.ic_state()); CompileRun("%OptimizeFunctionOnNextCall(foo); foo(1)"); CHECK_EQ(i::MONOMORPHIC, nexus.ic_state()); i::HeapObject heap_object; @@ -12310,8 +12309,14 @@ TEST(CallHandlerHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(isolate); @@ -12321,8 +12326,14 @@ TEST(CallHandlerHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionTemplateNewHasNoSideEffect) { @@ -12337,8 +12348,14 @@ TEST(FunctionTemplateNewHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New( @@ -12348,8 +12365,14 @@ TEST(FunctionTemplateNewHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { @@ -12366,8 +12389,14 @@ TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { ->Set(context.local(), v8_str("f"), templ->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::NewWithCache( @@ -12377,8 +12406,14 @@ TEST(FunctionTemplateNewWithCacheHasNoSideEffect) { ->Set(context.local(), v8_str("f2"), templ2->GetFunction(context.local()).ToLocalChecked()) .FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } TEST(FunctionNewHasNoSideEffect) { @@ -12390,8 +12425,14 @@ TEST(FunctionNewHasNoSideEffect) { Local<Function> func = Function::New(context.local(), EmptyHandler).ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("new f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("new f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version. Local<Function> func2 = @@ -12401,8 +12442,14 @@ TEST(FunctionNewHasNoSideEffect) { .ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f2"), func2).FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); - v8::debug::EvaluateGlobal(isolate, v8_str("new f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("new f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); } // These handlers instantiate a function the embedder considers safe in some @@ -12461,7 +12508,10 @@ TEST(FunctionNewInstanceHasNoSideEffect) { v8::SideEffectType::kHasNoSideEffect) .ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func0).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // A whitelisted function that creates a new object. Should throw. Local<Function> func = @@ -12470,7 +12520,10 @@ TEST(FunctionNewInstanceHasNoSideEffect) { v8::SideEffectType::kHasNoSideEffect) .ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("f"), func).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // A whitelisted function that creates a new object with explicit intent to // have no side-effects (e.g. building an "object wrapper"). Should not throw. @@ -12481,18 +12534,26 @@ TEST(FunctionNewInstanceHasNoSideEffect) { .ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f2"), func2).FromJust()); - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), true).ToLocalChecked(); + v8::debug::EvaluateGlobal( + isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .ToLocalChecked(); // Check that side effect skipping did not leak outside to future evaluations. Local<Function> func3 = Function::New(context.local(), EmptyHandler).ToLocalChecked(); CHECK( context->Global()->Set(context.local(), v8_str("f3"), func3).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("f3()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("f3()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Check that using side effect free NewInstance works in normal evaluation // (without throwOnSideEffect). - v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), false).ToLocalChecked(); + v8::debug::EvaluateGlobal(isolate, v8_str("f2()"), + v8::debug::EvaluateGlobalMode::kDefault) + .ToLocalChecked(); } TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { @@ -12505,7 +12566,10 @@ TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { templ->SetCallAsFunctionHandler(EmptyHandler); Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); CHECK(context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); // Side-effect-free version is not supported. i::FunctionTemplateInfo cons = i::FunctionTemplateInfo::cast( @@ -12516,7 +12580,10 @@ TEST(CallHandlerAsFunctionHasNoSideEffectNotSupported) { CHECK(!handler_info.IsSideEffectFreeCallHandlerInfo()); handler_info.set_map( i::ReadOnlyRoots(heap).side_effect_free_call_handler_info_map()); - CHECK(v8::debug::EvaluateGlobal(isolate, v8_str("obj()"), true).IsEmpty()); + CHECK(v8::debug::EvaluateGlobal( + isolate, v8_str("obj()"), + v8::debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) + .IsEmpty()); } static void IsConstructHandler( @@ -18192,10 +18259,10 @@ static void BreakArrayGuarantees(const char* script) { v8::Context::Scope context_scope(context); v8::internal::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate1); - CHECK(i_isolate->IsNoElementsProtectorIntact()); + CHECK(v8::internal::Protectors::IsNoElementsIntact(i_isolate)); // Run something in new isolate. CompileRun(script); - CHECK(!i_isolate->IsNoElementsProtectorIntact()); + CHECK(!v8::internal::Protectors::IsNoElementsIntact(i_isolate)); } isolate1->Exit(); isolate1->Dispose(); @@ -23170,7 +23237,7 @@ void RunStreamingTest(const char** chunks, v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), encoding); + std::make_unique<TestSourceStream>(chunks), encoding); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23441,7 +23508,7 @@ TEST(StreamingWithDebuggingEnabledLate) { v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), + std::make_unique<TestSourceStream>(chunks), v8::ScriptCompiler::StreamedSource::ONE_BYTE); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23549,7 +23616,7 @@ TEST(StreamingWithHarmonyScopes) { v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( - v8::base::make_unique<TestSourceStream>(chunks), + std::make_unique<TestSourceStream>(chunks), v8::ScriptCompiler::StreamedSource::ONE_BYTE); v8::ScriptCompiler::ScriptStreamingTask* task = v8::ScriptCompiler::StartStreamingScript(isolate, &source); @@ -23771,7 +23838,13 @@ TEST(ModuleCodeCache) { // Evaluate for possible lazy compilation. Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } // Now create the cache. Note that it is freed, obscurely, when // ScriptCompiler::Source goes out of scope below. @@ -23802,7 +23875,13 @@ TEST(ModuleCodeCache) { Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } isolate->Dispose(); } @@ -24011,7 +24090,13 @@ TEST(ImportFromSyntheticModule) { .ToChecked(); Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } TEST(ImportFromSyntheticModuleThrow) { @@ -24041,7 +24126,15 @@ TEST(ImportFromSyntheticModuleThrow) { CHECK_EQ(module->GetStatus(), Module::kInstantiated); TryCatch try_catch(isolate); v8::MaybeLocal<Value> completion_value = module->Evaluate(context); - CHECK(completion_value.IsEmpty()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise( + Local<v8::Promise>::Cast(completion_value.ToLocalChecked())); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK_EQ(promise->Result(), try_catch.Exception()); + } else { + CHECK(completion_value.IsEmpty()); + } + CHECK_EQ(module->GetStatus(), Module::kErrored); CHECK(try_catch.HasCaught()); } @@ -24074,7 +24167,13 @@ TEST(CodeCacheModuleScriptMismatch) { // Evaluate for possible lazy compilation. Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } // Now create the cache. Note that it is freed, obscurely, when // ScriptCompiler::Source goes out of scope below. @@ -24170,7 +24269,13 @@ TEST(CodeCacheScriptModuleMismatch) { Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); - CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } isolate->Dispose(); } @@ -24206,10 +24311,14 @@ TEST(InvalidCodeCacheDataInCompileModule) { .ToChecked(); CHECK(cached_data->rejected); - CHECK_EQ(42, module->Evaluate(context) - .ToLocalChecked() - ->Int32Value(context) - .FromJust()); + Local<Value> completion_value = module->Evaluate(context).ToLocalChecked(); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK_EQ(42, completion_value->Int32Value(context).FromJust()); + } } void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) { @@ -24403,280 +24512,6 @@ TEST(SealHandleScopeNested) { } } - -static void ExtrasBindingTestRuntimeFunction( - const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ( - 3, - args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust()); - args.GetReturnValue().Set(v8_num(7)); -} - -TEST(ExtrasFunctionSource) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - LocalContext env; - - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - // Functions defined in extras do not expose source code. - auto func = binding->Get(env.local(), v8_str("testFunctionToString")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::String>(); - CHECK(result->StrictEquals(v8_str("function foo() { [native code] }"))); - - // Functions defined in extras do not show up in the stack trace. - auto wrapper = binding->Get(env.local(), v8_str("testStackTrace")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("wrapper"), wrapper).FromJust()); - ExpectString( - "function f(x) { return wrapper(x) }" - "function g() { return new Error().stack; }" - "f(g)", - "Error\n" - " at g (<anonymous>:1:58)\n" - " at f (<anonymous>:1:24)\n" - " at <anonymous>:1:78"); -} - -TEST(ExtrasBindingObject) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - LocalContext env; - - // standalone.gypi ensures we include the test-extra.js file, which should - // export the tested functions. - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testExtraShouldReturnFive")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Number>(); - CHECK_EQ(5, result->Int32Value(env.local()).FromJust()); - - v8::Local<v8::FunctionTemplate> runtimeFunction = - v8::FunctionTemplate::New(isolate, ExtrasBindingTestRuntimeFunction); - binding->Set(env.local(), v8_str("runtime"), - runtimeFunction->GetFunction(env.local()).ToLocalChecked()) - .FromJust(); - func = binding->Get(env.local(), v8_str("testExtraShouldCallToRuntime")) - .ToLocalChecked() - .As<v8::Function>(); - result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Number>(); - CHECK_EQ(7, result->Int32Value(env.local()).FromJust()); -} - - -TEST(ExtrasCreatePromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testCreatePromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto promise = CompileRun( - "%PrepareFunctionForOptimization(func);\n" - "func();\n" - "func();\n" - "%OptimizeFunctionOnNextCall(func);\n" - "func()\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, promise->State()); -} - -TEST(ExtrasCreatePromiseWithParent) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testCreatePromiseWithParent")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto promise = CompileRun( - "var parent = new Promise((a, b) => {});\n" - "%PrepareFunctionForOptimization(func);\n" - "func(parent);\n" - "func(parent);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "func(parent)\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, promise->State()); -} - -TEST(ExtrasRejectPromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testRejectPromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto rejected_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), 1);\n" - "func(newPromise(), 1);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, 1);\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kRejected, rejected_promise->State()); - CHECK_EQ(1, rejected_promise->Result()->Int32Value(env.local()).FromJust()); -} - -TEST(ExtrasResolvePromise) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testResolvePromise")) - .ToLocalChecked() - .As<v8::Function>(); - CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); - - auto pending_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), newPromise());\n" - "func(newPromise(), newPromise());\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, newPromise());\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kPending, pending_promise->State()); - - auto fulfilled_promise = CompileRun( - "function newPromise() {\n" - " return new Promise((a, b) => {});\n" - "}\n" - "%PrepareFunctionForOptimization(func);\n" - "func(newPromise(), 1);\n" - "func(newPromise(), 1);\n" - "%OptimizeFunctionOnNextCall(func);\n" - "var promise = newPromise();\n" - "func(promise, 1);\n" - "promise;\n") - .As<v8::Promise>(); - CHECK_EQ(v8::Promise::kFulfilled, fulfilled_promise->State()); - CHECK_EQ(1, fulfilled_promise->Result()->Int32Value(env.local()).FromJust()); -} - -TEST(ExtrasUtilsObject) { - LocalContext context; - v8::Isolate* isolate = context->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - LocalContext env; - v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - - auto func = binding->Get(env.local(), v8_str("testExtraCanUseUtils")) - .ToLocalChecked() - .As<v8::Function>(); - auto undefined = v8::Undefined(isolate); - auto result = func->Call(env.local(), undefined, 0, {}) - .ToLocalChecked() - .As<v8::Object>(); - - auto private_symbol = result->Get(env.local(), v8_str("privateSymbol")) - .ToLocalChecked() - .As<v8::Symbol>(); - i::Handle<i::Symbol> ips = v8::Utils::OpenHandle(*private_symbol); - CHECK(ips->IsPrivate()); - - CompileRun("var result = 0; function store(x) { result = x; }"); - auto store = CompileRun("store").As<v8::Function>(); - - auto fulfilled_promise = result->Get(env.local(), v8_str("fulfilledPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - fulfilled_promise->Then(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(1, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto fulfilled_promise_2 = - result->Get(env.local(), v8_str("fulfilledPromise2")) - .ToLocalChecked() - .As<v8::Promise>(); - fulfilled_promise_2->Then(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(2, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto rejected_promise = result->Get(env.local(), v8_str("rejectedPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - rejected_promise->Catch(env.local(), store).ToLocalChecked(); - isolate->RunMicrotasks(); - CHECK_EQ(3, CompileRun("result")->Int32Value(env.local()).FromJust()); - - auto rejected_but_handled_promise = - result->Get(env.local(), v8_str("rejectedButHandledPromise")) - .ToLocalChecked() - .As<v8::Promise>(); - CHECK(rejected_but_handled_promise->HasHandler()); - - auto promise_states = result->Get(env.local(), v8_str("promiseStates")) - .ToLocalChecked() - .As<v8::String>(); - String::Utf8Value promise_states_string(isolate, promise_states); - CHECK_EQ(0, strcmp(*promise_states_string, "pending fulfilled rejected")); - - auto promise_is_promise = result->Get(env.local(), v8_str("promiseIsPromise")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(true, promise_is_promise->Value()); - - auto thenable_is_promise = - result->Get(env.local(), v8_str("thenableIsPromise")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(false, thenable_is_promise->Value()); - - auto uncurry_this = result->Get(env.local(), v8_str("uncurryThis")) - .ToLocalChecked() - .As<v8::Boolean>(); - CHECK_EQ(true, uncurry_this->Value()); -} - - TEST(Map) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); @@ -25854,7 +25689,14 @@ TEST(ImportMeta) { module->InstantiateModule(context.local(), UnexpectedModuleResolveCallback) .ToChecked(); Local<Value> result = module->Evaluate(context.local()).ToLocalChecked(); - CHECK(result->StrictEquals(Local<v8::Value>::Cast(v8::Utils::ToLocal(meta)))); + if (i::FLAG_harmony_top_level_await) { + Local<v8::Promise> promise(Local<v8::Promise>::Cast(result)); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK( + result->StrictEquals(Local<v8::Value>::Cast(v8::Utils::ToLocal(meta)))); + } } TEST(GetModuleNamespace) { @@ -26180,7 +26022,7 @@ void AtomicsWaitCallbackForTesting( wake_handle->Wake(); break; case AtomicsWaitCallbackAction::StopFromThreadAndThrow: - info->stop_thread = v8::base::make_unique<StopAtomicsWaitThread>(info); + info->stop_thread = std::make_unique<StopAtomicsWaitThread>(info); CHECK(info->stop_thread->Start()); break; case AtomicsWaitCallbackAction::KeepWaiting: diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index c96a0199bbad23..bae39ba2aded77 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -3391,7 +3391,9 @@ TEST(ARMv8_vminmax_f32) { template <typename T, typename Inputs, typename Results> static GeneratedCode<F_ppiii> GenerateMacroFloatMinMax( - MacroAssembler& assm) { // NOLINT(runtime/references) + MacroAssembler* assm_ptr) { + MacroAssembler& assm = *assm_ptr; + T a = T::from_code(0); // d0/s0 T b = T::from_code(1); // d1/s1 T c = T::from_code(2); // d2/s2 @@ -3509,7 +3511,7 @@ TEST(macro_float_minmax_f64) { double max_aba_; }; - auto f = GenerateMacroFloatMinMax<DwVfpRegister, Inputs, Results>(assm); + auto f = GenerateMacroFloatMinMax<DwVfpRegister, Inputs, Results>(&assm); #define CHECK_MINMAX(left, right, min, max) \ do { \ @@ -3574,7 +3576,7 @@ TEST(macro_float_minmax_f32) { float max_aba_; }; - auto f = GenerateMacroFloatMinMax<SwVfpRegister, Inputs, Results>(assm); + auto f = GenerateMacroFloatMinMax<SwVfpRegister, Inputs, Results>(&assm); #define CHECK_MINMAX(left, right, min, max) \ do { \ diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc index 4fdf30ef6461ee..44ee286587ccc4 100644 --- a/deps/v8/test/cctest/test-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-assembler-arm64.cc @@ -2019,17 +2019,19 @@ TEST(far_branch_backward) { START(); Label done, fail; - Label near, far, in_range, out_of_range; + // Avoid using near and far as variable name because both are defined as + // macro in minwindef.h from Windows SDK. + Label near_label, far_label, in_range, out_of_range; __ Mov(x0, 0); __ Mov(x1, 1); __ Mov(x10, 0); - __ B(&near); + __ B(&near_label); __ Bind(&in_range); __ Orr(x0, x0, 1 << 0); - __ B(&far); + __ B(&far_label); __ Bind(&out_of_range); __ Orr(x0, x0, 1 << 1); @@ -2053,19 +2055,19 @@ TEST(far_branch_backward) { // close to the limit. GenerateLandingNops(&masm, budget - kSlack, &fail); - __ Bind(&near); + __ Bind(&near_label); switch (type) { case TestBranchType: __ Tbz(x10, 3, &in_range); // This should be: // TBZ <in_range> - CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; case CompareBranchType: __ Cbz(x10, &in_range); // This should be: // CBZ <in_range> - CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(1 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; case CondBranchType: __ Cmp(x10, 0); @@ -2073,7 +2075,7 @@ TEST(far_branch_backward) { // This should be: // CMP // B.EQ <in_range> - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&near)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&near_label)); break; default: UNREACHABLE(); @@ -2083,7 +2085,7 @@ TEST(far_branch_backward) { // Now go past the limit so that branches are now out of range. GenerateLandingNops(&masm, kSlack * 2, &fail); - __ Bind(&far); + __ Bind(&far_label); switch (type) { case TestBranchType: __ Tbz(x10, 5, &out_of_range); @@ -2091,7 +2093,7 @@ TEST(far_branch_backward) { // TBNZ <skip> // B <out_of_range> // skip: - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; case CompareBranchType: __ Cbz(x10, &out_of_range); @@ -2099,7 +2101,7 @@ TEST(far_branch_backward) { // CBNZ <skip> // B <out_of_range> // skip: - CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(2 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; case CondBranchType: __ Cmp(x10, 0); @@ -2109,7 +2111,7 @@ TEST(far_branch_backward) { // B.NE <skip> // B <out_of_range> // skip: - CHECK_EQ(3 * kInstrSize, __ SizeOfCodeGeneratedSince(&far)); + CHECK_EQ(3 * kInstrSize, __ SizeOfCodeGeneratedSince(&far_label)); break; default: UNREACHABLE(); diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index 1cc1aa32139b6c..dd0c05636981d5 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -3206,7 +3206,7 @@ TEST(jump_tables3) { Handle<Object> values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { double value = isolate->random_number_generator()->NextDouble(); - values[i] = isolate->factory()->NewHeapNumber(value, AllocationType::kOld); + values[i] = isolate->factory()->NewHeapNumber<AllocationType::kOld>(value); } Label labels[kNumCases]; Object obj; @@ -4825,9 +4825,10 @@ TEST(r6_beqzc) { } } -void load_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - const uint64_t elements[], MSARegister w, Register t0, Register t1) { +void load_elements_of_vector(MacroAssembler* assm_ptr, + const uint64_t elements[], MSARegister w, + Register t0, Register t1) { + MacroAssembler& assm = *assm_ptr; __ li(t0, static_cast<uint32_t>(elements[0] & 0xFFFFFFFF)); __ li(t1, static_cast<uint32_t>((elements[0] >> 32) & 0xFFFFFFFF)); __ insert_w(w, 0, t0); @@ -4838,9 +4839,9 @@ void load_elements_of_vector( __ insert_w(w, 3, t1); } -inline void store_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - MSARegister w, Register a) { +inline void store_elements_of_vector(MacroAssembler* assm_ptr, MSARegister w, + Register a) { + MacroAssembler& assm = *assm_ptr; __ st_d(w, MemOperand(a, 0)); } @@ -4876,15 +4877,15 @@ void run_bz_bnz(TestCaseMsaBranch* input, Branch GenerateBranch, msa_reg_t res; Label do_not_move_w0_to_w2; - load_elements_of_vector(assm, &t.ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t.wd_lo, w2, t0, t1); - load_elements_of_vector(assm, &input->wt_lo, w1, t0, t1); + load_elements_of_vector(&assm, &t.ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t.wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &input->wt_lo, w1, t0, t1); GenerateBranch(assm, do_not_move_w0_to_w2); __ nop(); __ move_v(w2, w0); __ bind(&do_not_move_w0_to_w2); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -5841,7 +5842,7 @@ void run_msa_insert(int32_t rs_value, int n, msa_reg_t* w) { UNREACHABLE(); } - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -5937,10 +5938,10 @@ TEST(MSA_move_v) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); __ move_v(w2, w0); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -5981,10 +5982,10 @@ void run_msa_sldi(OperFunc GenerateOperation, for (unsigned i = 0; i < arraysize(t); ++i) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); GenerateOperation(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6175,7 +6176,7 @@ void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi, UNREACHABLE(); } - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6460,11 +6461,11 @@ void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext, int32_t i5 = i5_sign_ext ? static_cast<int32_t>(input->i5 << 27) >> 27 : input->i5; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); GenerateI5InstructionFunc(assm, i5); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6880,10 +6881,10 @@ void run_msa_2r(const struct TestCaseMsa2R* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, reinterpret_cast<const uint64_t*>(input), w0, + load_elements_of_vector(&assm, reinterpret_cast<const uint64_t*>(input), w0, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7926,13 +7927,13 @@ void run_msa_vector(struct TestCaseMsaVector* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wt_lo), w2, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w4, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w4, t0, t1); GenerateVectorInstructionFunc(assm); - store_elements_of_vector(assm, w4, a0); + store_elements_of_vector(&assm, w4, a0); __ jr(ra); __ nop(); @@ -8014,12 +8015,12 @@ void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateInstructionFunc(assm, input->m); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -8491,7 +8492,7 @@ void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc, GenerateVectorInstructionFunc(assm, input); - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -8640,13 +8641,13 @@ void run_msa_3r(struct TestCaseMsa3R* input, InstFunc GenerateI5InstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->wt_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->ws_lo), w1, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w1, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateI5InstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -9645,13 +9646,13 @@ void run_msa_3rf(const struct TestCaseMsa3RF* input, msa_reg_t res; load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc index f337fdfcac0b39..35e81cb46f6ae5 100644 --- a/deps/v8/test/cctest/test-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-assembler-mips64.cc @@ -3330,7 +3330,7 @@ TEST(jump_tables3) { Handle<Object> values[kNumCases]; for (int i = 0; i < kNumCases; ++i) { double value = isolate->random_number_generator()->NextDouble(); - values[i] = isolate->factory()->NewHeapNumber(value, AllocationType::kOld); + values[i] = isolate->factory()->NewHeapNumber<AllocationType::kOld>(value); } Label labels[kNumCases]; Object obj; @@ -5430,9 +5430,10 @@ TEST(r6_beqzc) { } } -void load_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - const uint64_t elements[], MSARegister w, Register t0, Register t1) { +void load_elements_of_vector(MacroAssembler* assm_ptr, + const uint64_t elements[], MSARegister w, + Register t0, Register t1) { + MacroAssembler& assm = *assm_ptr; __ li(t0, static_cast<uint32_t>(elements[0] & 0xFFFFFFFF)); __ li(t1, static_cast<uint32_t>((elements[0] >> 32) & 0xFFFFFFFF)); __ insert_w(w, 0, t0); @@ -5443,9 +5444,9 @@ void load_elements_of_vector( __ insert_w(w, 3, t1); } -inline void store_elements_of_vector( - MacroAssembler& assm, // NOLINT(runtime/references) - MSARegister w, Register a) { +inline void store_elements_of_vector(MacroAssembler* assm_ptr, MSARegister w, + Register a) { + MacroAssembler& assm = *assm_ptr; __ st_d(w, MemOperand(a, 0)); } @@ -5481,15 +5482,15 @@ void run_bz_bnz(TestCaseMsaBranch* input, Branch GenerateBranch, msa_reg_t res; Label do_not_move_w0_to_w2; - load_elements_of_vector(assm, &t.ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t.wd_lo, w2, t0, t1); - load_elements_of_vector(assm, &input->wt_lo, w1, t0, t1); + load_elements_of_vector(&assm, &t.ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t.wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &input->wt_lo, w1, t0, t1); GenerateBranch(assm, do_not_move_w0_to_w2); __ nop(); __ move_v(w2, w0); __ bind(&do_not_move_w0_to_w2); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6799,7 +6800,7 @@ void run_msa_insert(int64_t rs_value, int n, msa_reg_t* w) { UNREACHABLE(); } - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -6953,10 +6954,10 @@ TEST(MSA_move_v) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); __ move_v(w2, w0); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -6997,10 +6998,10 @@ void run_msa_sldi(OperFunc GenerateOperation, for (unsigned i = 0; i < arraysize(t); ++i) { MacroAssembler assm(isolate, v8::internal::CodeObjectRequired::kYes); CpuFeatureScope fscope(&assm, MIPS_SIMD); - load_elements_of_vector(assm, &t[i].ws_lo, w0, t0, t1); - load_elements_of_vector(assm, &t[i].wd_lo, w2, t0, t1); + load_elements_of_vector(&assm, &t[i].ws_lo, w0, t0, t1); + load_elements_of_vector(&assm, &t[i].wd_lo, w2, t0, t1); GenerateOperation(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7157,7 +7158,7 @@ void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi, UNREACHABLE(); } - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7358,11 +7359,11 @@ void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext, int32_t i5 = i5_sign_ext ? static_cast<int32_t>(input->i5 << 27) >> 27 : input->i5; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); GenerateI5InstructionFunc(assm, i5); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -7784,10 +7785,10 @@ void run_msa_2r(const struct TestCaseMsa2R* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, reinterpret_cast<const uint64_t*>(input), w0, + load_elements_of_vector(&assm, reinterpret_cast<const uint64_t*>(input), w0, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -8830,13 +8831,13 @@ void run_msa_vector(struct TestCaseMsaVector* input, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wt_lo), w2, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w4, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w4, t0, t1); GenerateVectorInstructionFunc(assm); - store_elements_of_vector(assm, w4, a0); + store_elements_of_vector(&assm, w4, a0); __ jr(ra); __ nop(); @@ -8918,12 +8919,12 @@ void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->ws_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateInstructionFunc(assm, input->m); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -9395,7 +9396,7 @@ void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc, GenerateVectorInstructionFunc(assm, input); - store_elements_of_vector(assm, w0, a0); + store_elements_of_vector(&assm, w0, a0); __ jr(ra); __ nop(); @@ -9544,13 +9545,13 @@ void run_msa_3r(struct TestCaseMsa3R* input, InstFunc GenerateI5InstructionFunc, CpuFeatureScope fscope(&assm, MIPS_SIMD); msa_reg_t res; - load_elements_of_vector(assm, &(input->wt_lo), w0, t0, t1); - load_elements_of_vector(assm, &(input->ws_lo), w1, t0, t1); - load_elements_of_vector(assm, &(input->wd_lo), w2, t0, t1); + load_elements_of_vector(&assm, &(input->wt_lo), w0, t0, t1); + load_elements_of_vector(&assm, &(input->ws_lo), w1, t0, t1); + load_elements_of_vector(&assm, &(input->wd_lo), w2, t0, t1); GenerateI5InstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); @@ -10548,13 +10549,13 @@ void run_msa_3rf(const struct TestCaseMsa3RF* input, msa_reg_t res; load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->ws_lo), w0, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wt_lo), w1, t0, t1); load_elements_of_vector( - assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); + &assm, reinterpret_cast<const uint64_t*>(&input->wd_lo), w2, t0, t1); Generate2RInstructionFunc(assm); - store_elements_of_vector(assm, w2, a0); + store_elements_of_vector(&assm, w2, a0); __ jr(ra); __ nop(); diff --git a/deps/v8/test/cctest/test-backing-store.cc b/deps/v8/test/cctest/test-backing-store.cc new file mode 100644 index 00000000000000..f8010d30319b9b --- /dev/null +++ b/deps/v8/test/cctest/test-backing-store.cc @@ -0,0 +1,85 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/api/api-inl.h" +#include "src/objects/backing-store.h" +#include "src/wasm/wasm-objects.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/manually-externalized-buffer.h" + +namespace v8 { +namespace internal { + +using testing::ManuallyExternalizedBuffer; + +TEST(Run_WasmModule_Buffer_Externalized_Detach) { + { + // Regression test for + // https://bugs.chromium.org/p/chromium/issues/detail?id=731046 + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + MaybeHandle<JSArrayBuffer> result = + isolate->factory()->NewJSArrayBufferAndBackingStore( + wasm::kWasmPageSize, InitializedFlag::kZeroInitialized); + Handle<JSArrayBuffer> buffer = result.ToHandleChecked(); + + // Embedder requests contents. + ManuallyExternalizedBuffer external(buffer); + + buffer->Detach(); + CHECK(buffer->was_detached()); + + // Make sure we can write to the buffer without crashing + uint32_t* int_buffer = + reinterpret_cast<uint32_t*>(external.backing_store()); + int_buffer[0] = 0; + // Embedder frees contents. + } + CcTest::CollectAllAvailableGarbage(); +} + +TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) { + { + // Regression test for https://crbug.com/813876 + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + MaybeHandle<WasmMemoryObject> result = + WasmMemoryObject::New(isolate, 1, 1, SharedFlag::kNotShared); + Handle<WasmMemoryObject> memory_object = result.ToHandleChecked(); + Handle<JSArrayBuffer> buffer(memory_object->array_buffer(), isolate); + + { + // Embedder requests contents. + ManuallyExternalizedBuffer external(buffer); + + // Growing (even by 0) detaches the old buffer. + WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK(buffer->was_detached()); + + // Embedder frees contents. + } + + // Make sure the memory object has a new buffer that can be written to. + uint32_t* int_buffer = reinterpret_cast<uint32_t*>( + memory_object->array_buffer().backing_store()); + int_buffer[0] = 0; + } + CcTest::CollectAllAvailableGarbage(); +} + +#if V8_TARGET_ARCH_64_BIT +TEST(BackingStore_Reclaim) { + // Make sure we can allocate memories without running out of address space. + Isolate* isolate = CcTest::InitIsolateOnce(); + for (int i = 0; i < 256; ++i) { + auto backing_store = + BackingStore::AllocateWasmMemory(isolate, 1, 1, SharedFlag::kNotShared); + CHECK(backing_store); + } +} +#endif + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc index 3a4f11e1265e1c..45512eaf5698a9 100644 --- a/deps/v8/test/cctest/test-code-stub-assembler.cc +++ b/deps/v8/test/cctest/test-code-stub-assembler.cc @@ -123,6 +123,62 @@ TEST(CallCFunctionWithCallerSavedRegisters) { CHECK_EQ(3, Handle<Smi>::cast(result)->value()); } +TEST(NumberToString) { + Isolate* isolate(CcTest::InitIsolateOnce()); + Factory* factory = isolate->factory(); + + const int kNumParams = 1; + CodeAssemblerTester asm_tester(isolate, kNumParams); + CodeStubAssembler m(asm_tester.state()); + + { + TNode<Number> input = m.CAST(m.Parameter(0)); + + Label bailout(&m); + m.Return(m.NumberToString(input, &bailout)); + + m.BIND(&bailout); + m.Return(m.UndefinedConstant()); + } + + FunctionTester ft(asm_tester.GenerateCode(), kNumParams); + + // clang-format off + double inputs[] = { + 1, 2, 42, 153, -1, -100, 0, 51095154, -1241950, + std::nan("-1"), std::nan("1"), std::nan("2"), + -std::numeric_limits<double>::infinity(), + std::numeric_limits<double>::infinity(), + -0.0, -0.001, -0.5, -0.999, -1.0, + 0.0, 0.001, 0.5, 0.999, 1.0, + -2147483647.9, -2147483648.0, -2147483648.5, -2147483648.9, // SmiMin. + 2147483646.9, 2147483647.0, 2147483647.5, 2147483647.9, // SmiMax. + -4294967295.9, -4294967296.0, -4294967296.5, -4294967297.0, // - 2^32. + 4294967295.9, 4294967296.0, 4294967296.5, 4294967297.0, // 2^32. + }; + // clang-format on + + const int kFullCacheSize = isolate->heap()->MaxNumberToStringCacheSize(); + const int test_count = arraysize(inputs); + for (int i = 0; i < test_count; i++) { + int cache_length_before_addition = factory->number_string_cache()->length(); + Handle<Object> input = factory->NewNumber(inputs[i]); + Handle<String> expected = factory->NumberToString(input); + + Handle<Object> result = ft.Call(input).ToHandleChecked(); + if (result->IsUndefined(isolate)) { + // Query may fail if cache was resized, in which case the entry is not + // added to the cache. + CHECK_LT(cache_length_before_addition, kFullCacheSize); + CHECK_EQ(factory->number_string_cache()->length(), kFullCacheSize); + expected = factory->NumberToString(input); + result = ft.Call(input).ToHandleChecked(); + } + CHECK(!result->IsUndefined(isolate)); + CHECK_EQ(*expected, *result); + } +} + namespace { void CheckToUint32Result(uint32_t expected, Handle<Object> result) { @@ -439,7 +495,7 @@ TEST(TryToName) { Label if_keyisindex(&m), if_keyisunique(&m), if_bailout(&m); { TYPED_VARIABLE_DEF(IntPtrT, var_index, &m); - TYPED_VARIABLE_DEF(Object, var_unique, &m); + TYPED_VARIABLE_DEF(Name, var_unique, &m); m.TryToName(key, &if_keyisindex, &var_index, &if_keyisunique, &var_unique, &if_bailout); @@ -1568,8 +1624,8 @@ TEST(TryLookupElement) { v8::ArrayBuffer::Contents contents = buffer->Externalize(); buffer->Detach(); - isolate->array_buffer_allocator()->Free(contents.Data(), - contents.ByteLength()); + contents.Deleter()(contents.Data(), contents.ByteLength(), + contents.DeleterData()); CHECK_ABSENT(object, 0); CHECK_ABSENT(object, 1); @@ -1809,7 +1865,7 @@ TEST(OneToTwoByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1841,7 +1897,7 @@ TEST(OneToOneByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1873,7 +1929,7 @@ TEST(OneToOneByteStringCopyNonZeroStart) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(3), m.IntPtrConstant(2), @@ -1902,7 +1958,7 @@ TEST(TwoToTwoByteStringCopy) { const int kNumParams = 2; CodeAssemblerTester asm_tester(isolate, kNumParams); - CodeStubAssembler m(asm_tester.state()); + StringBuiltinsAssembler m(asm_tester.state()); m.CopyStringCharacters(m.Parameter(0), m.Parameter(1), m.IntPtrConstant(0), m.IntPtrConstant(0), m.IntPtrConstant(5), @@ -1941,12 +1997,9 @@ TEST(Arguments) { CodeStubArguments arguments(&m, m.IntPtrConstant(3)); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(0), m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(1), m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT( - &m, m.TaggedEqual(arguments.AtIndex(2), m.SmiConstant(Smi::FromInt(14)))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(0), m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(1), m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(2), m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -1966,21 +2019,14 @@ TEST(ArgumentsWithSmiConstantIndices) { CodeAssemblerTester asm_tester(isolate, kNumParams); CodeStubAssembler m(asm_tester.state()); - CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr, - CodeStubAssembler::SMI_PARAMETERS); - - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(0), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(1), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(m.SmiConstant(2), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(14)))); + CodeStubArguments arguments(&m, m.SmiConstant(3)); + + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(0)), + m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(1)), + m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(m.SmiConstant(2)), + m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -2019,21 +2065,14 @@ TEST(ArgumentsWithSmiIndices) { CodeAssemblerTester asm_tester(isolate, kNumParams); CodeStubAssembler m(asm_tester.state()); - CodeStubArguments arguments(&m, m.SmiConstant(3), nullptr, - CodeStubAssembler::SMI_PARAMETERS); - - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 0), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(12)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 1), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(13)))); - CSA_ASSERT(&m, - m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 2), - CodeStubAssembler::SMI_PARAMETERS), - m.SmiConstant(Smi::FromInt(14)))); + CodeStubArguments arguments(&m, m.SmiConstant(3)); + + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 0)), + m.SmiConstant(12))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 1)), + m.SmiConstant(13))); + CSA_ASSERT(&m, m.TaggedEqual(arguments.AtIndex(NonConstantSmi(&m, 2)), + m.SmiConstant(14))); arguments.PopAndReturn(arguments.GetReceiver()); @@ -2060,7 +2099,7 @@ TEST(ArgumentsForEach) { sum = m.SmiConstant(0); - arguments.ForEach(list, [&m, &sum](Node* arg) { + arguments.ForEach(list, [&](TNode<Object> arg) { sum = m.SmiAdd(sum.value(), m.CAST(arg)); }); @@ -2130,8 +2169,8 @@ class AppendJSArrayCodeStubAssembler : public CodeStubAssembler { TVariable<IntPtrT> arg_index(this); Label bailout(this); arg_index = IntPtrConstant(0); - Node* length = BuildAppendJSArray(kind_, HeapConstant(array), &args, - &arg_index, &bailout); + TNode<Smi> length = BuildAppendJSArray(kind_, HeapConstant(array), &args, + &arg_index, &bailout); Return(length); BIND(&bailout); @@ -2281,7 +2320,7 @@ TEST(AllocateAndInitJSPromise) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = m.AllocateAndInitJSPromise(context); + TNode<JSPromise> const promise = m.AllocateAndInitJSPromise(m.CAST(context)); m.Return(promise); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2298,8 +2337,8 @@ TEST(AllocateAndSetJSPromise) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = m.AllocateAndSetJSPromise( - context, v8::Promise::kRejected, m.SmiConstant(1)); + TNode<JSPromise> const promise = m.AllocateAndSetJSPromise( + m.CAST(context), v8::Promise::kRejected, m.SmiConstant(1)); m.Return(promise); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2361,8 +2400,8 @@ TEST(PromiseHasHandler) { PromiseBuiltinsAssembler m(asm_tester.state()); Node* const context = m.Parameter(kNumParams + 2); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); + TNode<JSPromise> const promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); m.Return(m.SelectBooleanConstant(m.PromiseHasHandler(promise))); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2380,10 +2419,11 @@ TEST(CreatePromiseResolvingFunctionsContext) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); - Node* const promise_context = m.CreatePromiseResolvingFunctionsContext( - promise, m.BooleanConstant(false), native_context); + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); + TNode<Context> const promise_context = + m.CreatePromiseResolvingFunctionsContext( + promise, m.BooleanConstant(false), native_context); m.Return(promise_context); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -2408,8 +2448,8 @@ TEST(CreatePromiseResolvingFunctions) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); Node *resolve, *reject; std::tie(resolve, reject) = m.CreatePromiseResolvingFunctions( promise, m.BooleanConstant(false), native_context); @@ -2498,17 +2538,17 @@ TEST(AllocateFunctionWithMapAndContext) { Node* const context = m.Parameter(kNumParams + 2); TNode<NativeContext> const native_context = m.LoadNativeContext(context); - Node* const promise = - m.AllocateAndInitJSPromise(context, m.UndefinedConstant()); - Node* promise_context = m.CreatePromiseResolvingFunctionsContext( + const TNode<JSPromise> promise = + m.AllocateAndInitJSPromise(m.CAST(context), m.UndefinedConstant()); + TNode<Context> promise_context = m.CreatePromiseResolvingFunctionsContext( promise, m.BooleanConstant(false), native_context); TNode<Object> resolve_info = m.LoadContextElement( native_context, Context::PROMISE_CAPABILITY_DEFAULT_RESOLVE_SHARED_FUN_INDEX); TNode<Object> const map = m.LoadContextElement( native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX); - Node* const resolve = - m.AllocateFunctionWithMapAndContext(map, resolve_info, promise_context); + TNode<JSFunction> const resolve = m.AllocateFunctionWithMapAndContext( + m.CAST(map), m.CAST(resolve_info), promise_context); m.Return(resolve); FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3122,7 +3162,7 @@ TEST(CloneEmptyFixedArray) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3139,7 +3179,7 @@ TEST(CloneFixedArray) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3161,7 +3201,7 @@ TEST(CloneFixedArrayCOW) { CodeAssemblerTester asm_tester(isolate, kNumParams); { CodeStubAssembler m(asm_tester.state()); - m.Return(m.CloneFixedArray(m.Parameter(0))); + m.Return(m.CloneFixedArray(m.CAST(m.Parameter(0)))); } FunctionTester ft(asm_tester.GenerateCode(), kNumParams); @@ -3542,37 +3582,6 @@ TEST(TestCallBuiltinIndirectLoad) { Handle<String>::cast(result.ToHandleChecked()))); } -TEST(TestGotoIfDebugExecutionModeChecksSideEffects) { - Isolate* isolate(CcTest::InitIsolateOnce()); - CodeAssemblerTester asm_tester(isolate, 0); - { - CodeStubAssembler m(asm_tester.state()); - Label is_true(&m), is_false(&m); - m.GotoIfDebugExecutionModeChecksSideEffects(&is_true); - m.Goto(&is_false); - m.BIND(&is_false); - m.Return(m.BooleanConstant(false)); - - m.BIND(&is_true); - m.Return(m.BooleanConstant(true)); - } - - FunctionTester ft(asm_tester.GenerateCode(), 0); - - CHECK(isolate->debug_execution_mode() != DebugInfo::kSideEffects); - - Handle<Object> result = ft.Call().ToHandleChecked(); - CHECK(result->IsBoolean()); - CHECK_EQ(false, result->BooleanValue(isolate)); - - isolate->debug()->StartSideEffectCheckMode(); - CHECK(isolate->debug_execution_mode() == DebugInfo::kSideEffects); - - result = ft.Call().ToHandleChecked(); - CHECK(result->IsBoolean()); - CHECK_EQ(true, result->BooleanValue(isolate)); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index b961da943759b7..bd2766518b8dee 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -907,7 +907,7 @@ TEST(DeepEagerCompilationPeakMemory) { " }" "}"); v8::ScriptCompiler::Source script_source(source); - CcTest::i_isolate()->compilation_cache()->Disable(); + CcTest::i_isolate()->compilation_cache()->DisableScriptAndEval(); v8::HeapStatistics heap_statistics; CcTest::isolate()->GetHeapStatistics(&heap_statistics); diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index 6d0ee0e512856a..c0d43b21a1a8b5 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -54,8 +54,8 @@ #include "src/tracing/trace-event.h" #ifdef V8_USE_PERFETTO -#include "perfetto/trace/chrome/chrome_trace_event.pb.h" -#include "perfetto/trace/trace.pb.h" +#include "protos/perfetto/trace/chrome/chrome_trace_event.pb.h" +#include "protos/perfetto/trace/trace.pb.h" #endif namespace v8 { diff --git a/deps/v8/test/cctest/test-debug-helper.cc b/deps/v8/test/cctest/test-debug-helper.cc index 67236e5a311ca4..560db1b0d21217 100644 --- a/deps/v8/test/cctest/test-debug-helper.cc +++ b/deps/v8/test/cctest/test-debug-helper.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "src/api/api-inl.h" +#include "src/flags/flags.h" #include "src/heap/spaces.h" #include "test/cctest/cctest.h" #include "tools/debug_helper/debug-helper.h" @@ -61,6 +62,10 @@ void CheckProp(const d::ObjectProperty& property, const char* expected_type, CHECK(*reinterpret_cast<TValue*>(property.address) == expected_value); } +bool StartsWith(std::string full_string, std::string prefix) { + return full_string.substr(0, prefix.size()) == prefix; +} + } // namespace TEST(GetObjectProperties) { @@ -68,12 +73,13 @@ TEST(GetObjectProperties) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext context; - d::Roots roots{0, 0, 0, 0}; // We don't know the heap roots. + // Claim we don't know anything about the heap layout. + d::HeapAddresses heap_addresses{0, 0, 0, 0}; v8::Local<v8::Value> v = CompileRun("42"); Handle<Object> o = v8::Utils::OpenHandle(*v); d::ObjectPropertiesResultPtr props = - d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kSmi); CHECK(props->brief == std::string("42 (0x2a)")); CHECK(props->type == std::string("v8::internal::Smi")); @@ -81,7 +87,7 @@ TEST(GetObjectProperties) { v = CompileRun("[\"a\", \"bc\"]"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::JSArray")); CHECK_EQ(props->num_properties, 4); @@ -92,9 +98,9 @@ TEST(GetObjectProperties) { CheckProp(*props->properties[3], "v8::internal::Object", "length", static_cast<i::Tagged_t>(IntToSmi(2))); - // We need to supply a root address for decompression before reading the + // We need to supply some valid address for decompression before reading the // elements from the JSArray. - roots.any_heap_pointer = o->ptr(); + heap_addresses.any_heap_pointer = o->ptr(); i::Tagged_t properties_or_hash = *reinterpret_cast<i::Tagged_t*>(props->properties[1]->address); @@ -106,32 +112,39 @@ TEST(GetObjectProperties) { // any ability to read memory. { MemoryFailureRegion failure(0, UINTPTR_MAX); - props = d::GetObjectProperties(properties_or_hash, &ReadMemory, roots); + props = + d::GetObjectProperties(properties_or_hash, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kObjectPointerValidButInaccessible); CHECK(props->type == std::string("v8::internal::HeapObject")); CHECK_EQ(props->num_properties, 1); CheckProp(*props->properties[0], "v8::internal::Map", "map"); - CHECK(std::string(props->brief).substr(0, 21) == - std::string("maybe EmptyFixedArray")); + // "maybe" prefix indicates that GetObjectProperties recognized the offset + // within the page as matching a known object, but didn't know whether the + // object is on the right page. This response can only happen in builds + // without pointer compression, because otherwise heap addresses would be at + // deterministic locations within the heap reservation. + CHECK(COMPRESS_POINTERS_BOOL + ? StartsWith(props->brief, "EmptyFixedArray") + : StartsWith(props->brief, "maybe EmptyFixedArray")); - // Provide a heap root so the API can be more sure. - roots.read_only_space = + // Provide a heap first page so the API can be more sure. + heap_addresses.read_only_space_first_page = reinterpret_cast<uintptr_t>(reinterpret_cast<i::Isolate*>(isolate) ->heap() ->read_only_space() ->first_page()); - props = d::GetObjectProperties(properties_or_hash, &ReadMemory, roots); + props = + d::GetObjectProperties(properties_or_hash, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kObjectPointerValidButInaccessible); CHECK(props->type == std::string("v8::internal::HeapObject")); CHECK_EQ(props->num_properties, 1); CheckProp(*props->properties[0], "v8::internal::Map", "map"); - CHECK(std::string(props->brief).substr(0, 15) == - std::string("EmptyFixedArray")); + CHECK(StartsWith(props->brief, "EmptyFixedArray")); } - props = d::GetObjectProperties(elements, &ReadMemory, roots); + props = d::GetObjectProperties(elements, &ReadMemory, heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::FixedArray")); CHECK_EQ(props->num_properties, 3); @@ -142,9 +155,10 @@ TEST(GetObjectProperties) { d::PropertyKind::kArrayOfKnownSize, 2); // Get the second string value from the FixedArray. - i::Tagged_t second_string_address = *reinterpret_cast<i::Tagged_t*>( - props->properties[2]->address + sizeof(i::Tagged_t)); - props = d::GetObjectProperties(second_string_address, &ReadMemory, roots); + i::Tagged_t second_string_address = + reinterpret_cast<i::Tagged_t*>(props->properties[2]->address)[1]; + props = d::GetObjectProperties(second_string_address, &ReadMemory, + heap_addresses); CHECK(props->type_check_result == d::TypeCheckResult::kUsedMap); CHECK(props->type == std::string("v8::internal::SeqOneByteString")); CHECK_EQ(props->num_properties, 4); @@ -162,18 +176,38 @@ TEST(GetObjectProperties) { // its properties should match what we read last time. d::ObjectPropertiesResultPtr props2; { + heap_addresses.read_only_space_first_page = 0; uintptr_t map_address = d::GetObjectProperties( *reinterpret_cast<i::Tagged_t*>(props->properties[0]->address), - &ReadMemory, roots) + &ReadMemory, heap_addresses) ->properties[0] ->address; MemoryFailureRegion failure(map_address, map_address + i::Map::kSize); - props2 = d::GetObjectProperties(second_string_address, &ReadMemory, roots, - "v8::internal::String"); - CHECK(props2->type_check_result == d::TypeCheckResult::kUsedTypeHint); - CHECK(props2->type == std::string("v8::internal::String")); - CHECK_EQ(props2->num_properties, 3); + props2 = d::GetObjectProperties(second_string_address, &ReadMemory, + heap_addresses, "v8::internal::String"); + if (COMPRESS_POINTERS_BOOL) { + // The first page of each heap space can be automatically detected when + // pointer compression is active, so we expect to use known maps instead + // of the type hint. + CHECK_EQ(props2->type_check_result, d::TypeCheckResult::kKnownMapPointer); + CHECK(props2->type == std::string("v8::internal::SeqOneByteString")); + CHECK_EQ(props2->num_properties, 4); + CheckProp(*props2->properties[3], "char", "chars", + d::PropertyKind::kArrayOfKnownSize, 2); + CHECK_EQ(props2->num_guessed_types, 0); + } else { + CHECK_EQ(props2->type_check_result, d::TypeCheckResult::kUsedTypeHint); + CHECK(props2->type == std::string("v8::internal::String")); + CHECK_EQ(props2->num_properties, 3); + + // The type hint we provided was the abstract class String, but + // GetObjectProperties should have recognized that the Map pointer looked + // like the right value for a SeqOneByteString. + CHECK_EQ(props2->num_guessed_types, 1); + CHECK(std::string(props2->guessed_types[0]) == + std::string("v8::internal::SeqOneByteString")); + } CheckProp(*props2->properties[0], "v8::internal::Map", "map", *reinterpret_cast<i::Tagged_t*>(props->properties[0]->address)); CheckProp(*props2->properties[1], "uint32_t", "hash_field", @@ -183,7 +217,7 @@ TEST(GetObjectProperties) { // Try a weak reference. props2 = d::GetObjectProperties(second_string_address | kWeakHeapObjectMask, - &ReadMemory, roots); + &ReadMemory, heap_addresses); std::string weak_ref_prefix = "weak ref to "; CHECK(weak_ref_prefix + props->brief == props2->brief); CHECK(props2->type_check_result == d::TypeCheckResult::kUsedMap); @@ -201,9 +235,8 @@ TEST(GetObjectProperties) { const alphabet = "abcdefghijklmnopqrstuvwxyz"; alphabet.substr(3,20) + alphabet.toUpperCase().substr(5,15) + "7")"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); - CHECK(std::string(props->brief).substr(0, 38) == - std::string("\"defghijklmnopqrstuvwFGHIJKLMNOPQRST7\"")); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); + CHECK(StartsWith(props->brief, "\"defghijklmnopqrstuvwFGHIJKLMNOPQRST7\"")); // Cause a failure when reading the "second" pointer within the top-level // ConsString. @@ -211,15 +244,15 @@ TEST(GetObjectProperties) { CheckProp(*props->properties[4], "v8::internal::String", "second"); uintptr_t second_address = props->properties[4]->address; MemoryFailureRegion failure(second_address, second_address + 4); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); - CHECK(std::string(props->brief).substr(0, 40) == - std::string("\"defghijklmnopqrstuvwFGHIJKLMNOPQRST...\"")); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); + CHECK( + StartsWith(props->brief, "\"defghijklmnopqrstuvwFGHIJKLMNOPQRST...\"")); } // Build a very long string. v = CompileRun("'a'.repeat(1000)"); o = v8::Utils::OpenHandle(*v); - props = d::GetObjectProperties(o->ptr(), &ReadMemory, roots); + props = d::GetObjectProperties(o->ptr(), &ReadMemory, heap_addresses); CHECK(std::string(props->brief).substr(79, 7) == std::string("aa...\" ")); } diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index 4ad55ef6b5fc4d..c76f922d8616c3 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -893,7 +893,6 @@ TEST(BreakPointInlineBoundBuiltin) { TEST(BreakPointInlinedConstructorBuiltin) { i::FLAG_allow_natives_syntax = true; - i::FLAG_experimental_inline_promise_constructor = true; LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -1032,8 +1031,6 @@ TEST(BreakPointBuiltinNewContext) { i::Handle<i::BreakPoint> bp; // === Test builtin from a new context === -// This does not work with no-snapshot build. -#ifdef V8_USE_SNAPSHOT break_point_hit_count = 0; builtin = CompileRun("String.prototype.repeat").As<v8::Function>(); CompileRun("'a'.repeat(10)"); @@ -1059,7 +1056,6 @@ TEST(BreakPointBuiltinNewContext) { CompileRun("'b'.repeat(10)"); CHECK_EQ(2, break_point_hit_count); } -#endif v8::debug::SetDebugDelegate(env->GetIsolate(), nullptr); CheckDebuggerUnloaded(); @@ -3135,8 +3131,8 @@ TEST(NoBreakWhenBootstrapping) { { // Create a context with an extension to make sure that some JavaScript // code is executed during bootstrapping. - v8::RegisterExtension(v8::base::make_unique<v8::Extension>( - "simpletest", kSimpleExtensionSource)); + v8::RegisterExtension( + std::make_unique<v8::Extension>("simpletest", kSimpleExtensionSource)); const char* extension_names[] = { "simpletest" }; v8::ExtensionConfiguration extensions(1, extension_names); v8::HandleScope handle_scope(isolate); @@ -4510,7 +4506,7 @@ UNINITIALIZED_TEST(LoadedAtStartupScripts) { } } CHECK_EQ(count_by_type[i::Script::TYPE_NATIVE], 0); - CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 2); + CHECK_EQ(count_by_type[i::Script::TYPE_EXTENSION], 1); CHECK_EQ(count_by_type[i::Script::TYPE_NORMAL], 1); CHECK_EQ(count_by_type[i::Script::TYPE_WASM], 0); CHECK_EQ(count_by_type[i::Script::TYPE_INSPECTOR], 0); diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc index 76e06df47e31bd..16dee03f506338 100644 --- a/deps/v8/test/cctest/test-disasm-arm.cc +++ b/deps/v8/test/cctest/test-disasm-arm.cc @@ -1166,6 +1166,12 @@ TEST(Neon) { "f2dae550 vshl.i16 q15, q0, #10"); COMPARE(vshl(NeonS32, q15, q0, 17), "f2f1e550 vshl.i32 q15, q0, #17"); + COMPARE(vshl(NeonS8, q15, q0, q1), + "f242e440 vshl.s8 q15, q0, q1"); + COMPARE(vshl(NeonU16, q15, q2, q3), + "f356e444 vshl.u16 q15, q2, q3"); + COMPARE(vshl(NeonS32, q15, q4, q5), + "f26ae448 vshl.s32 q15, q4, q5"); COMPARE(vshr(NeonS8, q15, q0, 6), "f2cae050 vshr.s8 q15, q0, #6"); COMPARE(vshr(NeonU16, q15, q0, 10), diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc index ba4d92d3a2c447..2b46d7ed1111cb 100644 --- a/deps/v8/test/cctest/test-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-disasm-arm64.cc @@ -1888,6 +1888,8 @@ TEST(system_pauth) { COMPARE(paciasp(), "paciasp"); COMPARE(autia1716(), "autia1716"); COMPARE(autiasp(), "autiasp"); + + CLEANUP(); } TEST_(debug) { diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index 4078bd429c9b3d..563d3a87cf6703 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -435,6 +435,8 @@ TEST(DisasmIa320) { __ maxps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ rcpps(xmm1, xmm0); __ rcpps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ sqrtps(xmm1, xmm0); + __ sqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ rsqrtps(xmm1, xmm0); __ rsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); @@ -444,6 +446,8 @@ TEST(DisasmIa320) { __ cmpltps(xmm5, Operand(ebx, ecx, times_4, 10000)); __ cmpleps(xmm5, xmm1); __ cmpleps(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpunordps(xmm5, xmm1); + __ cmpunordps(xmm5, Operand(ebx, ecx, times_4, 10000)); __ cmpneqps(xmm5, xmm1); __ cmpneqps(xmm5, Operand(ebx, ecx, times_4, 10000)); @@ -467,6 +471,9 @@ TEST(DisasmIa320) { __ movdqu(xmm0, Operand(ebx, ecx, times_4, 10000)); __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0); + __ movapd(xmm0, xmm1); + __ movapd(xmm0, Operand(edx, 4)); + __ movd(xmm0, edi); __ movd(xmm0, Operand(ebx, ecx, times_4, 10000)); __ movd(eax, xmm1); @@ -490,6 +497,36 @@ TEST(DisasmIa320) { __ cmpltsd(xmm0, xmm1); __ andpd(xmm0, xmm1); + __ andpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ andnpd(xmm0, xmm1); + __ andnpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ orpd(xmm0, xmm1); + __ orpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ xorpd(xmm0, xmm1); + __ xorpd(xmm0, Operand(ebx, ecx, times_4, 10000)); + __ addpd(xmm1, xmm0); + __ addpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ subpd(xmm1, xmm0); + __ subpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ mulpd(xmm1, xmm0); + __ mulpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ divpd(xmm1, xmm0); + __ divpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ minpd(xmm1, xmm0); + __ minpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ maxpd(xmm1, xmm0); + __ maxpd(xmm1, Operand(ebx, ecx, times_4, 10000)); + + __ cmpeqpd(xmm5, xmm1); + __ cmpeqpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpltpd(xmm5, xmm1); + __ cmpltpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmplepd(xmm5, xmm1); + __ cmplepd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpunordpd(xmm5, xmm1); + __ cmpunordpd(xmm5, Operand(ebx, ecx, times_4, 10000)); + __ cmpneqpd(xmm5, xmm1); + __ cmpneqpd(xmm5, Operand(ebx, ecx, times_4, 10000)); __ psllw(xmm0, 17); __ pslld(xmm0, 17); @@ -623,6 +660,8 @@ TEST(DisasmIa320) { __ vandps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vandnps(xmm0, xmm1, xmm2); __ vandnps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vorps(xmm0, xmm1, xmm2); + __ vorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vxorps(xmm0, xmm1, xmm2); __ vxorps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vaddps(xmm0, xmm1, xmm2); @@ -639,9 +678,13 @@ TEST(DisasmIa320) { __ vmaxps(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vrcpps(xmm1, xmm0); __ vrcpps(xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vsqrtps(xmm1, xmm0); + __ vsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ vrsqrtps(xmm1, xmm0); __ vrsqrtps(xmm1, Operand(ebx, ecx, times_4, 10000)); __ vmovaps(xmm0, xmm1); + __ vmovapd(xmm0, xmm1); + __ vmovapd(xmm0, Operand(ebx, ecx, times_4, 10000)); __ vshufps(xmm0, xmm1, xmm2, 3); __ vshufps(xmm0, xmm1, Operand(edx, 4), 3); __ vhaddps(xmm0, xmm1, xmm2); @@ -653,11 +696,17 @@ TEST(DisasmIa320) { __ vcmpltps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vcmpleps(xmm5, xmm4, xmm1); __ vcmpleps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpunordps(xmm5, xmm4, xmm1); + __ vcmpunordps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vcmpneqps(xmm5, xmm4, xmm1); __ vcmpneqps(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); __ vandpd(xmm0, xmm1, xmm2); __ vandpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vandnpd(xmm0, xmm1, xmm2); + __ vandnpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vorpd(xmm0, xmm1, xmm2); + __ vorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vxorpd(xmm0, xmm1, xmm2); __ vxorpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); __ vaddpd(xmm0, xmm1, xmm2); @@ -673,10 +722,22 @@ TEST(DisasmIa320) { __ vmaxpd(xmm0, xmm1, xmm2); __ vmaxpd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000)); + __ vcmpeqpd(xmm5, xmm4, xmm1); + __ vcmpeqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpltpd(xmm5, xmm4, xmm1); + __ vcmpltpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmplepd(xmm5, xmm4, xmm1); + __ vcmplepd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpunordpd(xmm5, xmm4, xmm1); + __ vcmpunordpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vcmpneqpd(xmm5, xmm4, xmm1); + __ vcmpneqpd(xmm5, xmm4, Operand(ebx, ecx, times_4, 10000)); + __ vpsllw(xmm0, xmm7, 21); __ vpslld(xmm0, xmm7, 21); __ vpsrlw(xmm0, xmm7, 21); __ vpsrld(xmm0, xmm7, 21); + __ vpsrlq(xmm0, xmm7, 21); __ vpsraw(xmm0, xmm7, 21); __ vpsrad(xmm0, xmm7, 21); diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index 08793fba4a0852..86d98d8daf97bb 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -182,6 +182,8 @@ TEST(DisasmX64) { __ decq(rdx); __ cdq(); + __ repstosq(); + __ nop(); __ idivq(rdx); __ mull(rdx); diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc index 512bf2a9c6f3d1..9eb9071d77c7b4 100644 --- a/deps/v8/test/cctest/test-field-type-tracking.cc +++ b/deps/v8/test/cctest/test-field-type-tracking.cc @@ -249,21 +249,22 @@ class Expectations { } } - bool Check(DescriptorArray descriptors, int descriptor) const { + bool Check(DescriptorArray descriptors, InternalIndex descriptor) const { PropertyDetails details = descriptors.GetDetails(descriptor); - if (details.kind() != kinds_[descriptor]) return false; - if (details.location() != locations_[descriptor]) return false; - if (details.constness() != constnesses_[descriptor]) return false; + if (details.kind() != kinds_[descriptor.as_int()]) return false; + if (details.location() != locations_[descriptor.as_int()]) return false; + if (details.constness() != constnesses_[descriptor.as_int()]) return false; - PropertyAttributes expected_attributes = attributes_[descriptor]; + PropertyAttributes expected_attributes = attributes_[descriptor.as_int()]; if (details.attributes() != expected_attributes) return false; - Representation expected_representation = representations_[descriptor]; + Representation expected_representation = + representations_[descriptor.as_int()]; if (!details.representation().Equals(expected_representation)) return false; - Object expected_value = *values_[descriptor]; + Object expected_value = *values_[descriptor.as_int()]; if (details.location() == kField) { if (details.kind() == kData) { FieldType type = descriptors.GetFieldType(descriptor); @@ -278,7 +279,7 @@ class Expectations { if (value == expected_value) return true; if (!value.IsAccessorPair()) return false; AccessorPair pair = AccessorPair::cast(value); - return pair.Equals(expected_value, *setter_values_[descriptor]); + return pair.Equals(expected_value, *setter_values_[descriptor.as_int()]); } UNREACHABLE(); } @@ -291,13 +292,12 @@ class Expectations { DescriptorArray descriptors = map.instance_descriptors(); CHECK(expected_nof <= number_of_properties_); - for (int i = 0; i < expected_nof; i++) { + for (InternalIndex i : InternalIndex::Range(expected_nof)) { if (!Check(descriptors, i)) { Print(); #ifdef OBJECT_PRINT descriptors.Print(); #endif - Check(descriptors, i); return false; } } @@ -459,7 +459,7 @@ class Expectations { Handle<Object> getter(pair->getter(), isolate); Handle<Object> setter(pair->setter(), isolate); - int descriptor = + InternalIndex descriptor = map->instance_descriptors().SearchWithCache(isolate, *name, *map); map = Map::TransitionToAccessorProperty(isolate, map, name, descriptor, getter, setter, attributes); @@ -495,8 +495,9 @@ TEST(ReconfigureAccessorToNonExistingDataField) { CHECK(map->is_stable()); CHECK(expectations.Check(*map)); + InternalIndex first(0); Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::None(), none_type); + isolate, map, first, kData, NONE, Representation::None(), none_type); // |map| did not change except marked unstable. CHECK(!map->is_deprecated()); CHECK(!map->is_stable()); @@ -511,12 +512,12 @@ TEST(ReconfigureAccessorToNonExistingDataField) { CHECK(expectations.Check(*new_map)); Handle<Map> new_map2 = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::None(), none_type); + isolate, map, first, kData, NONE, Representation::None(), none_type); CHECK_EQ(*new_map, *new_map2); Handle<Object> value(Smi::kZero, isolate); Handle<Map> prepared_map = Map::PrepareForDataProperty( - isolate, new_map, 0, PropertyConstness::kConst, value); + isolate, new_map, first, PropertyConstness::kConst, value); // None to Smi generalization is trivial, map does not change. CHECK_EQ(*new_map, *prepared_map); @@ -530,7 +531,7 @@ TEST(ReconfigureAccessorToNonExistingDataField) { Factory* factory = isolate->factory(); Handle<JSObject> obj = factory->NewJSObjectFromMap(map); JSObject::MigrateToMap(isolate, obj, prepared_map); - FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, 0); + FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, first); CHECK(obj->RawFastPropertyAt(index).IsUninitialized(isolate)); #ifdef VERIFY_HEAP obj->ObjectVerify(isolate); @@ -565,14 +566,16 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) { Handle<JSObject> obj = Handle<JSObject>::cast(obj_value); CHECK_EQ(1, obj->map().NumberOfOwnDescriptors()); - CHECK(obj->map().instance_descriptors().GetStrongValue(0).IsAccessorPair()); + InternalIndex first(0); + CHECK( + obj->map().instance_descriptors().GetStrongValue(first).IsAccessorPair()); Handle<Object> value(Smi::FromInt(42), isolate); JSObject::SetOwnPropertyIgnoreAttributes(obj, foo_str, value, NONE).Check(); // Check that the property contains |value|. CHECK_EQ(1, obj->map().NumberOfOwnDescriptors()); - FieldIndex index = FieldIndex::ForDescriptor(obj->map(), 0); + FieldIndex index = FieldIndex::ForDescriptor(obj->map(), first); Object the_value = obj->RawFastPropertyAt(index); CHECK(the_value.IsSmi()); CHECK_EQ(42, Smi::ToInt(the_value)); @@ -641,7 +644,7 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, from.representation, from.type); } else { map = expectations.AddDataField(map, NONE, PropertyConstness::kConst, - Representation::Double(), any_type); + Representation::Smi(), any_type); if (i == detach_property_at_index) { detach_point_map = map; } @@ -653,11 +656,11 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, if (is_detached_map) { detach_point_map = Map::ReconfigureProperty( - isolate, detach_point_map, detach_property_at_index, kData, NONE, - Representation::Tagged(), any_type); + isolate, detach_point_map, InternalIndex(detach_property_at_index), + kData, NONE, Representation::Double(), any_type); expectations.SetDataField(detach_property_at_index, PropertyConstness::kConst, - Representation::Tagged(), any_type); + Representation::Double(), any_type); CHECK(map->is_deprecated()); CHECK(expectations.Check(*detach_point_map, detach_point_map->NumberOfOwnDescriptors())); @@ -666,16 +669,17 @@ void TestGeneralizeField(int detach_property_at_index, int property_index, // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, property_index), - isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(property_index)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); CHECK(!code->marked_for_deoptimization()); // Create new maps by generalizing representation of propX field. - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, property_index, kData, NONE, to.representation, to.type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(property_index), + kData, NONE, to.representation, to.type); expectations.SetDataField(property_index, expected.constness, expected.representation, expected.type); @@ -814,7 +818,9 @@ TEST(GeneralizeDoubleFieldToTagged) { TestGeneralizeField( {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace, + !FLAG_unbox_double_fields && FLAG_modify_field_representation_inplace); } TEST(GeneralizeHeapObjectFieldToTagged) { @@ -965,8 +971,9 @@ TEST(GeneralizeFieldWithAccessorProperties) { maps[i] = maps[i - 1]; continue; } - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, i, kData, NONE, Representation::Double(), any_type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(i), kData, NONE, + Representation::Double(), any_type); maps[i] = new_map; expectations.SetDataField(i, PropertyConstness::kMutable, @@ -1053,7 +1060,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeField( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kSplitProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kSplitProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -1061,8 +1069,9 @@ void TestReconfigureDataFieldAttribute_GeneralizeField( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1141,7 +1150,8 @@ void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kSplitProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kSplitProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -1149,8 +1159,9 @@ void TestReconfigureDataFieldAttribute_GeneralizeFieldTrivial( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1436,8 +1447,7 @@ struct CheckNormalize { // template <typename TestConfig, typename Checker> static void TestReconfigureProperty_CustomPropertyAfterTargetMap( - TestConfig& config, // NOLINT(runtime/references) - Checker& checker) { // NOLINT(runtime/references) + TestConfig* config, Checker* checker) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -1469,7 +1479,7 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( map1 = expectations1.AddDataField(map1, NONE, constness, representation, any_type); } - map1 = config.AddPropertyAtBranch(1, expectations1, map1); + map1 = config->AddPropertyAtBranch(1, &expectations1, map1); for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { map1 = expectations1.AddDataField(map1, NONE, constness, representation, any_type); @@ -1489,7 +1499,7 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( map2 = expectations2.AddDataField(map2, NONE, constness, representation, any_type); } - map2 = config.AddPropertyAtBranch(2, expectations2, map2); + map2 = config->AddPropertyAtBranch(2, &expectations2, map2); for (int i = kCustomPropIndex + 1; i < kPropCount; i++) { map2 = expectations2.AddDataField(map2, NONE, constness, representation, any_type); @@ -1501,8 +1511,9 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( // Reconfigure attributes of property |kSplitProp| of |map2| to NONE, which // should generalize representations in |map1|. - Handle<Map> new_map = Map::ReconfigureExistingProperty( - isolate, map2, kSplitProp, kData, NONE, PropertyConstness::kConst); + Handle<Map> new_map = + Map::ReconfigureExistingProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, PropertyConstness::kConst); // |map2| should be left unchanged but marked unstable. CHECK(!map2->is_stable()); @@ -1510,8 +1521,8 @@ static void TestReconfigureProperty_CustomPropertyAfterTargetMap( CHECK_NE(*map2, *new_map); CHECK(expectations2.Check(*map2)); - config.UpdateExpectations(kCustomPropIndex, expectations1); - checker.Check(isolate, map1, new_map, expectations1); + config->UpdateExpectations(kCustomPropIndex, &expectations1); + checker->Check(isolate, map1, new_map, expectations1); } TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { @@ -1526,18 +1537,14 @@ TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { js_func_ = factory->NewFunctionForTest(factory->empty_string()); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); // Add the same data constant property at both transition tree branches. - return expectations.AddDataConstant(map, NONE, js_func_); + return expectations->AddDataConstant(map, NONE, js_func_); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { // Expectations stay the same. } }; @@ -1545,7 +1552,7 @@ TEST(ReconfigureDataFieldAttribute_SameDataConstantAfterTargetMap) { TestConfig config; // Two branches are "compatible" so the |map1| should NOT be deprecated. CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1575,26 +1582,22 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) { factory->NewFunction(sloppy_map, info, isolate->native_context()); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); Handle<JSFunction> js_func = branch_id == 1 ? js_func1_ : js_func2_; - return expectations.AddDataConstant(map, NONE, js_func); + return expectations->AddDataConstant(map, NONE, js_func); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) - expectations.SetDataField(property_index, PropertyConstness::kConst, - Representation::HeapObject(), function_type_); + void UpdateExpectations(int property_index, Expectations* expectations) { + expectations->SetDataField(property_index, PropertyConstness::kConst, + Representation::HeapObject(), function_type_); } }; TestConfig config; CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1612,28 +1615,23 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToAccConstantAfterTargetMap) { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); if (branch_id == 1) { - return expectations.AddDataConstant(map, NONE, js_func_); + return expectations->AddDataConstant(map, NONE, js_func_); } else { - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } } - void UpdateExpectations( - int property_index, - Expectations& expectations // NOLINT(runtime/references) - ) {} + void UpdateExpectations(int property_index, Expectations* expectations) {} }; TestConfig config; // These are completely separate branches in transition tree. CheckUnrelated checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1645,26 +1643,22 @@ TEST(ReconfigureDataFieldAttribute_SameAccessorConstantAfterTargetMap) { Handle<AccessorPair> pair_; TestConfig() { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); // Add the same accessor constant property at both transition tree // branches. - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { // Two branches are "compatible" so the |map1| should NOT be deprecated. } }; TestConfig config; CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1680,24 +1674,20 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { pair2_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); Handle<AccessorPair> pair = branch_id == 1 ? pair1_ : pair2_; - return expectations.AddAccessorConstant(map, NONE, pair); + return expectations->AddAccessorConstant(map, NONE, pair); } - void UpdateExpectations( - int property_index, - Expectations& expectations) { // NOLINT(runtime/references) + void UpdateExpectations(int property_index, Expectations* expectations) { if (IS_ACCESSOR_FIELD_SUPPORTED) { - expectations.SetAccessorField(property_index); + expectations->SetAccessorField(property_index); } else { // Currently we have a normalize case and ACCESSOR property becomes // ACCESSOR_CONSTANT. - expectations.SetAccessorConstant(property_index, pair2_); + expectations->SetAccessorConstant(property_index, pair2_); } } }; @@ -1705,11 +1695,11 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToAccFieldAfterTargetMap) { TestConfig config; if (IS_ACCESSOR_FIELD_SUPPORTED) { CheckSameMap checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } else { // Currently we have a normalize case. CheckNormalize checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } } @@ -1722,31 +1712,26 @@ TEST(ReconfigureDataFieldAttribute_AccConstantToDataFieldAfterTargetMap) { Handle<AccessorPair> pair_; TestConfig() { pair_ = CreateAccessorPair(true, true); } - Handle<Map> AddPropertyAtBranch( - int branch_id, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { + Handle<Map> AddPropertyAtBranch(int branch_id, Expectations* expectations, + Handle<Map> map) { CHECK(branch_id == 1 || branch_id == 2); if (branch_id == 1) { - return expectations.AddAccessorConstant(map, NONE, pair_); + return expectations->AddAccessorConstant(map, NONE, pair_); } else { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); - return expectations.AddDataField(map, NONE, PropertyConstness::kConst, - Representation::Smi(), any_type); + return expectations->AddDataField(map, NONE, PropertyConstness::kConst, + Representation::Smi(), any_type); } } - void UpdateExpectations( - int property_index, - Expectations& expectations // NOLINT(runtime/references) - ) {} + void UpdateExpectations(int property_index, Expectations* expectations) {} }; TestConfig config; // These are completely separate branches in transition tree. CheckUnrelated checker; - TestReconfigureProperty_CustomPropertyAfterTargetMap(config, checker); + TestReconfigureProperty_CustomPropertyAfterTargetMap(&config, &checker); } @@ -1811,7 +1796,8 @@ static void TestReconfigureElementsKind_GeneralizeFieldTrivial( // Create dummy optimized code object to test correct dependencies // on the field owner. Handle<Code> code = CreateDummyOptimizedCode(isolate); - Handle<Map> field_owner(map->FindFieldOwner(isolate, kDiffProp), isolate); + Handle<Map> field_owner( + map->FindFieldOwner(isolate, InternalIndex(kDiffProp)), isolate); DependentCode::InstallDependency(isolate, MaybeObjectHandle::Weak(code), field_owner, DependentCode::kFieldOwnerGroup); @@ -2084,8 +2070,9 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { map2 = handle(target, isolate); } - map2 = Map::ReconfigureProperty(isolate, map2, kSplitProp, kData, NONE, - Representation::Double(), any_type); + map2 = Map::ReconfigureProperty(isolate, map2, InternalIndex(kSplitProp), + kData, NONE, Representation::Double(), + any_type); expectations.SetDataField(kSplitProp, PropertyConstness::kMutable, Representation::Double(), any_type); @@ -2141,9 +2128,8 @@ TEST(ReconfigurePropertySplitMapTransitionsOverflow) { // fixed. template <typename TestConfig> static void TestGeneralizeFieldWithSpecialTransition( - TestConfig& config, // NOLINT(runtime/references) - const CRFTData& from, const CRFTData& to, const CRFTData& expected, - bool expected_deprecation) { + TestConfig* config, const CRFTData& from, const CRFTData& to, + const CRFTData& expected, bool expected_deprecation) { Isolate* isolate = CcTest::i_isolate(); Expectations expectations(isolate); @@ -2163,13 +2149,13 @@ static void TestGeneralizeFieldWithSpecialTransition( // Apply some special transition to |map|. CHECK(map->owns_descriptors()); - Handle<Map> map2 = config.Transition(map, expectations2); + Handle<Map> map2 = config->Transition(map, &expectations2); // |map| should still match expectations. CHECK(!map->is_deprecated()); CHECK(expectations.Check(*map)); - if (config.generalizes_representations()) { + if (config->generalizes_representations()) { for (int i = 0; i < kPropCount; i++) { expectations2.GeneralizeField(i); } @@ -2182,8 +2168,9 @@ static void TestGeneralizeFieldWithSpecialTransition( // Create new maps by generalizing representation of propX field. Handle<Map> maps[kPropCount]; for (int i = 0; i < kPropCount; i++) { - Handle<Map> new_map = Map::ReconfigureProperty(isolate, map, i, kData, NONE, - to.representation, to.type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(i), kData, NONE, + to.representation, to.type); maps[i] = new_map; expectations.SetDataField(i, expected.constness, expected.representation, @@ -2206,10 +2193,10 @@ static void TestGeneralizeFieldWithSpecialTransition( CHECK_EQ(*new_map2, *tmp_map); } else { // Equivalent transitions should always find the updated map. - CHECK(config.is_non_equivalent_transition()); + CHECK(config->is_non_equivalent_transition()); } - if (config.is_non_equivalent_transition()) { + if (config->is_non_equivalent_transition()) { // In case of non-equivalent transition currently we generalize all // representations. for (int i = 0; i < kPropCount; i++) { @@ -2260,9 +2247,9 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) { ElementsKind kind) : attributes(attributes), symbol(symbol), elements_kind(kind) {} - Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { - expectations.SetElementsKind(elements_kind); - expectations.ChangeAttributesForAllProperties(attributes); + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { + expectations->SetElementsKind(elements_kind); + expectations->ChangeAttributesForAllProperties(attributes); return Map::CopyForPreventExtensions(CcTest::i_isolate(), map, attributes, symbol, "CopyForPreventExtensions"); } @@ -2287,17 +2274,17 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) { : DICTIONARY_ELEMENTS}}; for (size_t i = 0; i < arraysize(configs); i++) { TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, - true); + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } } @@ -2316,7 +2303,7 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { ElementsKind kind) : attributes(attributes), symbol(symbol), elements_kind(kind) {} - Handle<Map> Transition(Handle<Map> map, Expectations& expectations) { + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2329,8 +2316,8 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { .ToHandleChecked(); CHECK(!map->owns_descriptors()); - expectations.SetElementsKind(elements_kind); - expectations.ChangeAttributesForAllProperties(attributes); + expectations->SetElementsKind(elements_kind); + expectations->ChangeAttributesForAllProperties(attributes); return Map::CopyForPreventExtensions(isolate, map, attributes, symbol, "CopyForPreventExtensions"); } @@ -2355,17 +2342,17 @@ TEST(ElementsKindTransitionFromMapNotOwningDescriptor) { : DICTIONARY_ELEMENTS}}; for (size_t i = 0; i < arraysize(configs); i++) { TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - configs[i], + &configs[i], {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, - true); + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } } @@ -2388,9 +2375,7 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) { prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); } - Handle<Map> Transition( - Handle<Map> map, - Expectations& expectations) { // NOLINT(runtime/references) + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { return Map::TransitionToPrototype(CcTest::i_isolate(), map, prototype_); } // TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed. @@ -2401,14 +2386,16 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) { }; TestConfig config; TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, + &config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Double(), any_type}, + &config, + {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}, true); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } TEST(PrototypeTransitionFromMapNotOwningDescriptor) { @@ -2429,9 +2416,7 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) { prototype_ = factory->NewJSObjectFromMap(Map::Create(isolate, 0)); } - Handle<Map> Transition( - Handle<Map> map, - Expectations& expectations) { // NOLINT(runtime/references) + Handle<Map> Transition(Handle<Map> map, Expectations* expectations) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2454,14 +2439,16 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) { }; TestConfig config; TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, + &config, {PropertyConstness::kMutable, Representation::Smi(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, {PropertyConstness::kMutable, Representation::Tagged(), any_type}, !FLAG_modify_field_representation_inplace); TestGeneralizeFieldWithSpecialTransition( - config, {PropertyConstness::kMutable, Representation::Double(), any_type}, + &config, + {PropertyConstness::kMutable, Representation::Double(), any_type}, {PropertyConstness::kMutable, Representation::HeapObject(), value_type}, - {PropertyConstness::kMutable, Representation::Tagged(), any_type}, true); + {PropertyConstness::kMutable, Representation::Tagged(), any_type}, + FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace); } //////////////////////////////////////////////////////////////////////////////// @@ -2486,10 +2473,8 @@ struct TransitionToDataFieldOperator { heap_type_(heap_type), value_(value) {} - Handle<Map> DoTransition( - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { - return expectations.TransitionToDataField( + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToDataField( map, attributes_, constness_, representation_, heap_type_, value_); } }; @@ -2503,8 +2488,8 @@ struct TransitionToDataConstantOperator { PropertyAttributes attributes = NONE) : attributes_(attributes), value_(value) {} - Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { - return expectations.TransitionToDataConstant(map, attributes_, value_); + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToDataConstant(map, attributes_, value_); } }; @@ -2517,14 +2502,14 @@ struct TransitionToAccessorConstantOperator { PropertyAttributes attributes = NONE) : attributes_(attributes), pair_(pair) {} - Handle<Map> DoTransition(Expectations& expectations, Handle<Map> map) { - return expectations.TransitionToAccessorConstant(map, attributes_, pair_); + Handle<Map> DoTransition(Expectations* expectations, Handle<Map> map) { + return expectations->TransitionToAccessorConstant(map, attributes_, pair_); } }; struct ReconfigureAsDataPropertyOperator { - int descriptor_; + InternalIndex descriptor_; Representation representation_; PropertyAttributes attributes_; Handle<FieldType> heap_type_; @@ -2538,12 +2523,11 @@ struct ReconfigureAsDataPropertyOperator { attributes_(attributes), heap_type_(heap_type) {} - Handle<Map> DoTransition( - Isolate* isolate, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map) { - expectations.SetDataField(descriptor_, PropertyConstness::kMutable, - representation_, heap_type_); + Handle<Map> DoTransition(Isolate* isolate, Expectations* expectations, + Handle<Map> map) { + expectations->SetDataField(descriptor_.as_int(), + PropertyConstness::kMutable, representation_, + heap_type_); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, kData, attributes_, PropertyConstness::kConst); @@ -2552,16 +2536,16 @@ struct ReconfigureAsDataPropertyOperator { struct ReconfigureAsAccessorPropertyOperator { - int descriptor_; + InternalIndex descriptor_; PropertyAttributes attributes_; ReconfigureAsAccessorPropertyOperator(int descriptor, PropertyAttributes attributes = NONE) : descriptor_(descriptor), attributes_(attributes) {} - Handle<Map> DoTransition(Isolate* isolate, Expectations& expectations, + Handle<Map> DoTransition(Isolate* isolate, Expectations* expectations, Handle<Map> map) { - expectations.SetAccessorField(descriptor_); + expectations->SetAccessorField(descriptor_.as_int()); return Map::ReconfigureExistingProperty(isolate, map, descriptor_, kAccessor, attributes_, PropertyConstness::kConst); @@ -2586,9 +2570,8 @@ struct FieldGeneralizationChecker { attributes_(attributes), heap_type_(heap_type) {} - void Check(Isolate* isolate, - Expectations& expectations2, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Isolate* isolate, Expectations* expectations, Handle<Map> map1, + Handle<Map> map2) { CHECK(!map2->is_deprecated()); CHECK(map1->is_deprecated()); @@ -2597,21 +2580,20 @@ struct FieldGeneralizationChecker { CHECK_EQ(*map2, *updated_map); CheckMigrationTarget(isolate, *map1, *updated_map); - expectations2.SetDataField(descriptor_, attributes_, constness_, + expectations->SetDataField(descriptor_, attributes_, constness_, representation_, heap_type_); - CHECK(expectations2.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; // Checks that existing transition was taken as is. struct SameMapChecker { - void Check(Isolate* isolate, - Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Isolate* isolate, Expectations* expectations, Handle<Map> map1, + Handle<Map> map2) { CHECK(!map2->is_deprecated()); CHECK_EQ(*map1, *map2); - CHECK(expectations.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; @@ -2619,12 +2601,11 @@ struct SameMapChecker { // Checks that both |map1| and |map2| should stays non-deprecated, this is // the case when property kind is change. struct PropertyKindReconfigurationChecker { - void Check(Expectations& expectations, // NOLINT(runtime/references) - Handle<Map> map1, Handle<Map> map2) { + void Check(Expectations* expectations, Handle<Map> map1, Handle<Map> map2) { CHECK(!map1->is_deprecated()); CHECK(!map2->is_deprecated()); CHECK_NE(*map1, *map2); - CHECK(expectations.Check(*map2)); + CHECK(expectations->Check(*map2)); } }; @@ -2645,10 +2626,8 @@ struct PropertyKindReconfigurationChecker { // where "p4A" and "p4B" differ only in the attributes. // template <typename TransitionOp1, typename TransitionOp2, typename Checker> -static void TestTransitionTo( - TransitionOp1& transition_op1, // NOLINT(runtime/references) - TransitionOp2& transition_op2, // NOLINT(runtime/references) - Checker& checker) { // NOLINT(runtime/references) +static void TestTransitionTo(TransitionOp1* transition_op1, + TransitionOp2* transition_op2, Checker* checker) { Isolate* isolate = CcTest::i_isolate(); Handle<FieldType> any_type = FieldType::Any(isolate); @@ -2664,14 +2643,14 @@ static void TestTransitionTo( CHECK(expectations.Check(*map)); Expectations expectations1 = expectations; - Handle<Map> map1 = transition_op1.DoTransition(expectations1, map); + Handle<Map> map1 = transition_op1->DoTransition(&expectations1, map); CHECK(expectations1.Check(*map1)); Expectations expectations2 = expectations; - Handle<Map> map2 = transition_op2.DoTransition(expectations2, map); + Handle<Map> map2 = transition_op2->DoTransition(&expectations2, map); // Let the test customization do the check. - checker.Check(isolate, expectations2, map1, map2); + checker->Check(isolate, &expectations2, map1, map2); } TEST(TransitionDataFieldToDataField) { @@ -2692,7 +2671,7 @@ TEST(TransitionDataFieldToDataField) { FieldGeneralizationChecker checker(kPropCount - 1, PropertyConstness::kMutable, Representation::Double(), any_type); - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } TEST(TransitionDataConstantToSameDataConstant) { @@ -2706,7 +2685,7 @@ TEST(TransitionDataConstantToSameDataConstant) { TransitionToDataConstantOperator transition_op(js_func); SameMapChecker checker; - TestTransitionTo(transition_op, transition_op, checker); + TestTransitionTo(&transition_op, &transition_op, &checker); } @@ -2732,7 +2711,7 @@ TEST(TransitionDataConstantToAnotherDataConstant) { TransitionToDataConstantOperator transition_op2(js_func2); SameMapChecker checker; - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } @@ -2754,12 +2733,12 @@ TEST(TransitionDataConstantToDataField) { if (FLAG_modify_field_representation_inplace) { SameMapChecker checker; - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } else { FieldGeneralizationChecker checker(kPropCount - 1, PropertyConstness::kMutable, Representation::Tagged(), any_type); - TestTransitionTo(transition_op1, transition_op2, checker); + TestTransitionTo(&transition_op1, &transition_op2, &checker); } } @@ -2772,7 +2751,7 @@ TEST(TransitionAccessorConstantToSameAccessorConstant) { TransitionToAccessorConstantOperator transition_op(pair); SameMapChecker checker; - TestTransitionTo(transition_op, transition_op, checker); + TestTransitionTo(&transition_op, &transition_op, &checker); } // TODO(ishell): add this test once IS_ACCESSOR_FIELD_SUPPORTED is supported. @@ -2840,11 +2819,11 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_dictionary_map()); CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + InternalIndex first(0); + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(PropertyConstness::kConst, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); // Store value2 to obj2 and check that it got same map and property details // did not change. @@ -2856,10 +2835,10 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(PropertyConstness::kConst, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); // Store value2 to obj1 and check that property became mutable. Call(isolate, store_func, obj1, value2).Check(); @@ -2869,10 +2848,10 @@ void TestStoreToConstantField(const char* store_func_source, CHECK(!map->is_deprecated()); CHECK_EQ(1, map->NumberOfOwnDescriptors()); - CHECK(map->instance_descriptors().GetDetails(0).representation().Equals( + CHECK(map->instance_descriptors().GetDetails(first).representation().Equals( expected_rep)); CHECK_EQ(expected_constness, - map->instance_descriptors().GetDetails(0).constness()); + map->instance_descriptors().GetDetails(first).constness()); } void TestStoreToConstantField_PlusMinusZero(const char* store_func_source, diff --git a/deps/v8/test/cctest/test-flags.cc b/deps/v8/test/cctest/test-flags.cc index 4e5fcffa62de78..93c7048f8142c0 100644 --- a/deps/v8/test/cctest/test-flags.cc +++ b/deps/v8/test/cctest/test-flags.cc @@ -209,11 +209,5 @@ TEST(FlagsJitlessImplications) { } } -TEST(FlagsRegexpInterpretAllImplications) { - if (FLAG_regexp_interpret_all) { - CHECK(!FLAG_regexp_tier_up); - } -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index 417679432bf2d5..98a66bf535084e 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -49,7 +49,7 @@ class NonRootingEmbedderHeapTracer final : public v8::EmbedderHeapTracer { const std::vector<std::pair<void*, void*>>& embedder_fields) final {} bool AdvanceTracing(double deadline_in_ms) final { return true; } bool IsTracingDone() final { return true; } - void TracePrologue() final {} + void TracePrologue(TraceFlags) final {} void TraceEpilogue() final {} void EnterFinalPause(EmbedderStackState) final {} diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 3aec4ae0039607..7784a7f855f715 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -3062,7 +3062,8 @@ TEST(ArrayBufferSharedBackingStore) { CHECK(ab2_data); CHECK_EQ(ab1_data, ab2_data); CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data)); - free(data); + ab_contents.Deleter()(ab_contents.Data(), ab_contents.ByteLength(), + ab_contents.DeleterData()); } @@ -3577,10 +3578,9 @@ TEST(AddressToTraceMap) { } static const v8::AllocationProfile::Node* FindAllocationProfileNode( - v8::Isolate* isolate, - v8::AllocationProfile& profile, // NOLINT(runtime/references) + v8::Isolate* isolate, v8::AllocationProfile* profile, const Vector<const char*>& names) { - v8::AllocationProfile::Node* node = profile.GetRootNode(); + v8::AllocationProfile::Node* node = profile->GetRootNode(); for (int i = 0; node != nullptr && i < names.length(); ++i) { const char* name = names[i]; auto children = node->children; @@ -3650,7 +3650,7 @@ TEST(SamplingHeapProfiler) { CHECK(profile); const char* names[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node_bar); @@ -3674,12 +3674,12 @@ TEST(SamplingHeapProfiler) { CHECK(profile); const char* names1[] = {"", "start", "f_0_0", "f_0_1", "f_0_2"}; - auto node1 = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node1 = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names1)); CHECK(node1); const char* names2[] = {"", "generateFunctions"}; - auto node2 = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node2 = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names2)); CHECK(node2); @@ -3737,11 +3737,11 @@ TEST(SamplingHeapProfilerRateAgnosticEstimates) { CHECK(profile); const char* path_to_foo[] = {"", "foo"}; - auto node_foo = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_foo = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_foo)); CHECK(node_foo); const char* path_to_bar[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_bar)); CHECK(node_bar); @@ -3761,11 +3761,11 @@ TEST(SamplingHeapProfilerRateAgnosticEstimates) { CHECK(profile); const char* path_to_foo[] = {"", "foo"}; - auto node_foo = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_foo = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_foo)); CHECK(node_foo); const char* path_to_bar[] = {"", "foo", "bar"}; - auto node_bar = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_bar = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(path_to_bar)); CHECK(node_bar); @@ -3804,7 +3804,7 @@ TEST(SamplingHeapProfilerApiAllocation) { heap_profiler->GetAllocationProfile()); CHECK(profile); const char* names[] = {"(V8 API)"}; - auto node = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node); @@ -3944,7 +3944,7 @@ TEST(SamplingHeapProfilerPretenuredInlineAllocations) { heap_profiler->StopSamplingHeapProfiler(); const char* names[] = {"f"}; - auto node_f = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node_f = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node_f); @@ -3974,7 +3974,7 @@ TEST(SamplingHeapProfilerLargeInterval) { heap_profiler->GetAllocationProfile()); CHECK(profile); const char* names[] = {"(EXTERNAL)"}; - auto node = FindAllocationProfileNode(env->GetIsolate(), *profile, + auto node = FindAllocationProfileNode(env->GetIsolate(), profile.get(), ArrayVector(names)); CHECK(node); diff --git a/deps/v8/test/cctest/test-inobject-slack-tracking.cc b/deps/v8/test/cctest/test-inobject-slack-tracking.cc index 6a25536dd544ba..e2de4df4fbd174 100644 --- a/deps/v8/test/cctest/test-inobject-slack-tracking.cc +++ b/deps/v8/test/cctest/test-inobject-slack-tracking.cc @@ -1112,7 +1112,7 @@ TEST(SubclassRegExpBuiltin) { v8::HandleScope scope(CcTest::isolate()); const int first_field = 1; - TestSubclassBuiltin("A1", JS_REGEXP_TYPE, "RegExp", "'o(..)h', 'g'", + TestSubclassBuiltin("A1", JS_REG_EXP_TYPE, "RegExp", "'o(..)h', 'g'", first_field); } diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index 092c1078413a29..4ed00e0a11e059 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -944,7 +944,7 @@ TEST(ExtensionsRegistration) { "test4", "test5", "test6", "test7"}; for (const char* name : extension_names) { v8::RegisterExtension( - v8::base::make_unique<v8::Extension>(name, kSimpleExtensionSource)); + std::make_unique<v8::Extension>(name, kSimpleExtensionSource)); } std::vector<JoinableThread*> threads; threads.reserve(kNThreads); diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 1344c0e9d1839d..e238c8c021ba2e 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -242,37 +242,37 @@ TEST(SmiTag) { __ movq(rax, Immediate(1)); // Test number. __ movq(rcx, Immediate(0)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::kZero.ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(2)); // Test number. __ movq(rcx, Immediate(1024)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(1024).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(3)); // Test number. __ movq(rcx, Immediate(-1)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(-1).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(4)); // Test number. __ movq(rcx, Immediate(Smi::kMaxValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(Smi::kMaxValue).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(5)); // Test number. __ movq(rcx, Immediate(Smi::kMinValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); __ Set(rdx, Smi::FromInt(Smi::kMinValue).ptr()); - __ cmpq(rcx, rdx); + __ cmp_tagged(rcx, rdx); __ j(not_equal, &exit); // Different target register. @@ -281,35 +281,35 @@ TEST(SmiTag) { __ movq(rcx, Immediate(0)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::zero().ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(7)); // Test number. __ movq(rcx, Immediate(1024)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(1024).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(8)); // Test number. __ movq(rcx, Immediate(-1)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(-1).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(9)); // Test number. __ movq(rcx, Immediate(Smi::kMaxValue)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(Smi::kMaxValue).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); __ movq(rax, Immediate(10)); // Test number. __ movq(rcx, Immediate(Smi::kMinValue)); __ SmiTag(r8, rcx); __ Set(rdx, Smi::FromInt(Smi::kMinValue).ptr()); - __ cmpq(r8, rdx); + __ cmp_tagged(r8, rdx); __ j(not_equal, &exit); @@ -344,7 +344,7 @@ TEST(SmiCheck) { // CheckSmi __ movl(rcx, Immediate(0)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -355,7 +355,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(-1)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -366,7 +366,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(Smi::kMaxValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); @@ -377,7 +377,7 @@ TEST(SmiCheck) { __ incq(rax); __ movl(rcx, Immediate(Smi::kMinValue)); - __ SmiTag(rcx, rcx); + __ SmiTag(rcx); cond = masm->CheckSmi(rcx); __ j(NegateCondition(cond), &exit); diff --git a/deps/v8/test/cctest/test-modules.cc b/deps/v8/test/cctest/test-modules.cc index 0f2bfd2a5fd491..d7cb6e610e5530 100644 --- a/deps/v8/test/cctest/test-modules.cc +++ b/deps/v8/test/cctest/test-modules.cc @@ -14,6 +14,7 @@ using v8::Isolate; using v8::Local; using v8::MaybeLocal; using v8::Module; +using v8::Promise; using v8::ScriptCompiler; using v8::ScriptOrigin; using v8::String; @@ -196,99 +197,480 @@ static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback( } TEST(ModuleEvaluation) { - Isolate* isolate = CcTest::isolate(); - HandleScope scope(isolate); - LocalContext env; - v8::TryCatch try_catch(isolate); + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; - Local<String> source_text = v8_str( - "import 'Object.expando = 5';" - "import 'Object.expando *= 2';"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(!module->Evaluate(env.local()).IsEmpty()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - ExpectInt32("Object.expando", 10); + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); - CHECK(!try_catch.HasCaught()); + Local<String> source_text = v8_str( + "import 'Object.expando = 5';" + "import 'Object.expando *= 2';"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + MaybeLocal<Value> result = module->Evaluate(env.local()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result.ToLocalChecked()); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + } else { + CHECK(!result.IsEmpty()); + ExpectInt32("Object.expando", 10); + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; } -TEST(ModuleEvaluationError) { - Isolate* isolate = CcTest::isolate(); - HandleScope scope(isolate); - LocalContext env; - v8::TryCatch try_catch(isolate); +TEST(ModuleEvaluationError1) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; - Local<String> source_text = - v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); - { - v8::TryCatch inner_try_catch(isolate); - CHECK(module->Evaluate(env.local()).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); - CHECK_EQ(Module::kErrored, module->GetStatus()); - Local<Value> exception = module->GetException(); - CHECK(exception->StrictEquals(v8_str("boom"))); - ExpectInt32("Object.x", 1); + Local<String> source_text = + v8_str("Object.x = (Object.x || 0) + 1; throw 'boom';"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + MaybeLocal<Value> result_1; + { + v8::TryCatch inner_try_catch(isolate); + result_1 = module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + Local<Value> exception = module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + ExpectInt32("Object.x", 1); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + + MaybeLocal<Value> result_2; + { + v8::TryCatch inner_try_catch(isolate); + result_2 = module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + Local<Value> exception = module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + ExpectInt32("Object.x", 1); + + if (i::FLAG_harmony_top_level_await) { + // With top level await we do not rethrow the exception. + CHECK(!inner_try_catch.HasCaught()); + } else { + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + } + if (i::FLAG_harmony_top_level_await) { + // With top level await, errored evaluation returns a rejected promise + // with the exception. + Local<Promise> promise_1 = + Local<Promise>::Cast(result_1.ToLocalChecked()); + Local<Promise> promise_2 = + Local<Promise>::Cast(result_2.ToLocalChecked()); + CHECK_EQ(promise_1->State(), v8::Promise::kRejected); + CHECK_EQ(promise_2->State(), v8::Promise::kRejected); + CHECK_EQ(promise_1->Result(), module->GetException()); + CHECK_EQ(promise_2->Result(), module->GetException()); + } else { + CHECK(result_1.IsEmpty() && result_2.IsEmpty()); + } + + CHECK(!try_catch.HasCaught()); } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} - { - v8::TryCatch inner_try_catch(isolate); - CHECK(module->Evaluate(env.local()).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); - CHECK_EQ(Module::kErrored, module->GetStatus()); - Local<Value> exception = module->GetException(); - CHECK(exception->StrictEquals(v8_str("boom"))); - ExpectInt32("Object.x", 1); +static Local<Module> failure_module; +static Local<Module> dependent_module; +MaybeLocal<Module> ResolveCallbackForModuleEvaluationError2( + Local<Context> context, Local<String> specifier, Local<Module> referrer) { + if (specifier->StrictEquals(v8_str("./failure.js"))) { + return failure_module; + } else { + CHECK(specifier->StrictEquals(v8_str("./dependent.js"))); + return dependent_module; } +} - CHECK(!try_catch.HasCaught()); +TEST(ModuleEvaluationError2) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + Local<String> failure_text = v8_str("throw 'boom';"); + ScriptOrigin failure_origin = + ModuleOrigin(v8_str("failure.js"), CcTest::isolate()); + ScriptCompiler::Source failure_source(failure_text, failure_origin); + failure_module = ScriptCompiler::CompileModule(isolate, &failure_source) + .ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, failure_module->GetStatus()); + CHECK(failure_module + ->InstantiateModule(env.local(), + ResolveCallbackForModuleEvaluationError2) + .FromJust()); + CHECK_EQ(Module::kInstantiated, failure_module->GetStatus()); + + MaybeLocal<Value> result_1; + { + v8::TryCatch inner_try_catch(isolate); + result_1 = failure_module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, failure_module->GetStatus()); + Local<Value> exception = failure_module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + + Local<String> dependent_text = + v8_str("import './failure.js'; export const c = 123;"); + ScriptOrigin dependent_origin = + ModuleOrigin(v8_str("dependent.js"), CcTest::isolate()); + ScriptCompiler::Source dependent_source(dependent_text, dependent_origin); + dependent_module = ScriptCompiler::CompileModule(isolate, &dependent_source) + .ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, dependent_module->GetStatus()); + CHECK(dependent_module + ->InstantiateModule(env.local(), + ResolveCallbackForModuleEvaluationError2) + .FromJust()); + CHECK_EQ(Module::kInstantiated, dependent_module->GetStatus()); + + MaybeLocal<Value> result_2; + { + v8::TryCatch inner_try_catch(isolate); + result_2 = dependent_module->Evaluate(env.local()); + CHECK_EQ(Module::kErrored, dependent_module->GetStatus()); + Local<Value> exception = dependent_module->GetException(); + CHECK(exception->StrictEquals(v8_str("boom"))); + CHECK_EQ(exception, failure_module->GetException()); + + if (i::FLAG_harmony_top_level_await) { + // With top level await we do not rethrow the exception. + CHECK(!inner_try_catch.HasCaught()); + } else { + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception()->StrictEquals(v8_str("boom"))); + } + } + + if (i::FLAG_harmony_top_level_await) { + // With top level await, errored evaluation returns a rejected promise + // with the exception. + Local<Promise> promise_1 = + Local<Promise>::Cast(result_1.ToLocalChecked()); + Local<Promise> promise_2 = + Local<Promise>::Cast(result_2.ToLocalChecked()); + CHECK_EQ(promise_1->State(), v8::Promise::kRejected); + CHECK_EQ(promise_2->State(), v8::Promise::kRejected); + CHECK_EQ(promise_1->Result(), failure_module->GetException()); + CHECK_EQ(promise_2->Result(), failure_module->GetException()); + } else { + CHECK(result_1.IsEmpty() && result_2.IsEmpty()); + } + + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; } TEST(ModuleEvaluationCompletion1) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + const char* sources[] = { + "", + "var a = 1", + "import '42'", + "export * from '42'", + "export {} from '42'", + "export {}", + "var a = 1; export {a}", + "export function foo() {}", + "export class C extends null {}", + "export let a = 1", + "export default 1", + "export default function foo() {}", + "export default function () {}", + "export default (function () {})", + "export default class C extends null {}", + "export default (class C extends null {})", + "for (var i = 0; i < 5; ++i) {}", + }; + + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + // Evaluate twice. + Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result_1); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + + // Second evaluation should return the same promise. + Local<Promise> promise_too = Local<Promise>::Cast(result_2); + CHECK_EQ(promise, promise_too); + CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled); + CHECK(promise_too->Result()->IsUndefined()); + } else { + CHECK(result_1->IsUndefined()); + CHECK(result_2->IsUndefined()); + } + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleEvaluationCompletion2) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + const char* sources[] = { + "'gaga'; ", + "'gaga'; var a = 1", + "'gaga'; import '42'", + "'gaga'; export * from '42'", + "'gaga'; export {} from '42'", + "'gaga'; export {}", + "'gaga'; var a = 1; export {a}", + "'gaga'; export function foo() {}", + "'gaga'; export class C extends null {}", + "'gaga'; export let a = 1", + "'gaga'; export default 1", + "'gaga'; export default function foo() {}", + "'gaga'; export default function () {}", + "'gaga'; export default (function () {})", + "'gaga'; export default class C extends null {}", + "'gaga'; export default (class C extends null {})", + }; + + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + + Local<Value> result_1 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + Local<Value> result_2 = module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + if (i::FLAG_harmony_top_level_await) { + Local<Promise> promise = Local<Promise>::Cast(result_1); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + + // Second Evaluation should return the same promise. + Local<Promise> promise_too = Local<Promise>::Cast(result_2); + CHECK_EQ(promise, promise_too); + CHECK_EQ(promise_too->State(), v8::Promise::kFulfilled); + CHECK(promise_too->Result()->IsUndefined()); + } else { + CHECK(result_1->StrictEquals(v8_str("gaga"))); + CHECK(result_2->IsUndefined()); + } + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleNamespace) { + bool prev_top_level_await = i::FLAG_harmony_top_level_await; + for (auto top_level_await : {true, false}) { + i::FLAG_harmony_top_level_await = top_level_await; + + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + LocalContext env; + v8::TryCatch try_catch(isolate); + + Local<v8::Object> ReferenceError = + CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked(); + + Local<String> source_text = v8_str( + "import {a, b} from 'export var a = 1; export let b = 2';" + "export function geta() {return a};" + "export function getb() {return b};" + "export let radio = 3;" + "export var gaga = 4;"); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Local<Value> ns = module->GetModuleNamespace(); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked(); + CHECK_EQ(nsobj->CreationContext(), env.local()); + + // a, b + CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined()); + CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined()); + + // geta + { + auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); + auto a = geta.As<v8::Function>() + ->Call(env.local(), geta, 0, nullptr) + .ToLocalChecked(); + CHECK(a->IsUndefined()); + } + + // getb + { + v8::TryCatch inner_try_catch(isolate); + auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); + CHECK(getb.As<v8::Function>() + ->Call(env.local(), getb, 0, nullptr) + .IsEmpty()); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception() + ->InstanceOf(env.local(), ReferenceError) + .FromJust()); + } + + // radio + { + v8::TryCatch inner_try_catch(isolate); + // https://bugs.chromium.org/p/v8/issues/detail?id=7235 + // CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty()); + CHECK(nsobj->Get(env.local(), v8_str("radio")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(inner_try_catch.HasCaught()); + CHECK(inner_try_catch.Exception() + ->InstanceOf(env.local(), ReferenceError) + .FromJust()); + } + + // gaga + { + auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); + CHECK(gaga->IsUndefined()); + } + + CHECK(!try_catch.HasCaught()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); + module->Evaluate(env.local()).ToLocalChecked(); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + + // geta + { + auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); + auto a = geta.As<v8::Function>() + ->Call(env.local(), geta, 0, nullptr) + .ToLocalChecked(); + CHECK_EQ(1, a->Int32Value(env.local()).FromJust()); + } + + // getb + { + auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); + auto b = getb.As<v8::Function>() + ->Call(env.local(), getb, 0, nullptr) + .ToLocalChecked(); + CHECK_EQ(2, b->Int32Value(env.local()).FromJust()); + } + + // radio + { + auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked(); + CHECK_EQ(3, radio->Int32Value(env.local()).FromJust()); + } + + // gaga + { + auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); + CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust()); + } + CHECK(!try_catch.HasCaught()); + } + i::FLAG_harmony_top_level_await = prev_top_level_await; +} + +TEST(ModuleEvaluationTopLevelAwait) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext env; v8::TryCatch try_catch(isolate); - const char* sources[] = { - "", - "var a = 1", - "import '42'", - "export * from '42'", - "export {} from '42'", - "export {}", - "var a = 1; export {a}", - "export function foo() {}", - "export class C extends null {}", - "export let a = 1", - "export default 1", - "export default function foo() {}", - "export default function () {}", - "export default (function () {})", - "export default class C extends null {}", - "export default (class C extends null {})", - "for (var i = 0; i < 5; ++i) {}", + "await 42", + "import 'await 42';", + "import '42'; import 'await 42';", }; for (auto src : sources) { @@ -303,41 +685,30 @@ TEST(ModuleEvaluationCompletion1) { CompileSpecifierAsModuleResolveCallback) .FromJust()); CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); + CHECK(promise->Result()->IsUndefined()); + CHECK(!try_catch.HasCaught()); } - - CHECK(!try_catch.HasCaught()); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; } -TEST(ModuleEvaluationCompletion2) { +TEST(ModuleEvaluationTopLevelAwaitError) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + i::FLAG_harmony_top_level_await = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext env; - v8::TryCatch try_catch(isolate); - const char* sources[] = { - "'gaga'; ", - "'gaga'; var a = 1", - "'gaga'; import '42'", - "'gaga'; export * from '42'", - "'gaga'; export {} from '42'", - "'gaga'; export {}", - "'gaga'; var a = 1; export {a}", - "'gaga'; export function foo() {}", - "'gaga'; export class C extends null {}", - "'gaga'; export let a = 1", - "'gaga'; export default 1", - "'gaga'; export default function foo() {}", - "'gaga'; export default function () {}", - "'gaga'; export default (function () {})", - "'gaga'; export default class C extends null {}", - "'gaga'; export default (class C extends null {})", + "await 42; throw 'boom';", + "import 'await 42; throw \"boom\";';", + "import '42'; import 'await 42; throw \"boom\";';", }; for (auto src : sources) { + v8::TryCatch try_catch(isolate); Local<String> source_text = v8_str(src); ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); ScriptCompiler::Source source(source_text, origin); @@ -349,126 +720,170 @@ TEST(ModuleEvaluationCompletion2) { CompileSpecifierAsModuleResolveCallback) .FromJust()); CHECK_EQ(Module::kInstantiated, module->GetStatus()); - CHECK(module->Evaluate(env.local()) - .ToLocalChecked() - ->StrictEquals(v8_str("gaga"))); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - CHECK(module->Evaluate(env.local()).ToLocalChecked()->IsUndefined()); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kErrored, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK(promise->Result()->StrictEquals(v8_str("boom"))); + CHECK(module->GetException()->StrictEquals(v8_str("boom"))); + + // TODO(joshualitt) I am not sure, but this might not be supposed to throw + // because it is async. + CHECK(!try_catch.HasCaught()); } + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; +} - CHECK(!try_catch.HasCaught()); +namespace { +struct DynamicImportData { + DynamicImportData(Isolate* isolate_, Local<Promise::Resolver> resolver_, + Local<Context> context_, bool should_resolve_) + : isolate(isolate_), should_resolve(should_resolve_) { + resolver.Reset(isolate, resolver_); + context.Reset(isolate, context_); + } + + Isolate* isolate; + v8::Global<Promise::Resolver> resolver; + v8::Global<Context> context; + bool should_resolve; +}; + +void DoHostImportModuleDynamically(void* import_data) { + std::unique_ptr<DynamicImportData> import_data_( + static_cast<DynamicImportData*>(import_data)); + Isolate* isolate(import_data_->isolate); + HandleScope handle_scope(isolate); + + Local<Promise::Resolver> resolver(import_data_->resolver.Get(isolate)); + Local<Context> realm(import_data_->context.Get(isolate)); + Context::Scope context_scope(realm); + + if (import_data_->should_resolve) { + resolver->Resolve(realm, True(isolate)).ToChecked(); + } else { + resolver->Reject(realm, v8_str("boom")).ToChecked(); + } } -TEST(ModuleNamespace) { +v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackResolve( + Local<Context> context, Local<v8::ScriptOrModule> referrer, + Local<String> specifier) { + Isolate* isolate = context->GetIsolate(); + Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + + DynamicImportData* data = + new DynamicImportData(isolate, resolver, context, true); + isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data); + return resolver->GetPromise(); +} + +v8::MaybeLocal<v8::Promise> HostImportModuleDynamicallyCallbackReject( + Local<Context> context, Local<v8::ScriptOrModule> referrer, + Local<String> specifier) { + Isolate* isolate = context->GetIsolate(); + Local<v8::Promise::Resolver> resolver = + v8::Promise::Resolver::New(context).ToLocalChecked(); + + DynamicImportData* data = + new DynamicImportData(isolate, resolver, context, false); + isolate->EnqueueMicrotask(DoHostImportModuleDynamically, data); + return resolver->GetPromise(); +} + +} // namespace + +TEST(ModuleEvaluationTopLevelAwaitDynamicImport) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + bool previous_dynamic_import_flag_value = i::FLAG_harmony_dynamic_import; + i::FLAG_harmony_top_level_await = true; + i::FLAG_harmony_dynamic_import = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); + isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); + isolate->SetHostImportModuleDynamicallyCallback( + HostImportModuleDynamicallyCallbackResolve); LocalContext env; v8::TryCatch try_catch(isolate); + const char* sources[] = { + "await import('foo');", + "import 'await import(\"foo\");';", + "import '42'; import 'await import(\"foo\");';", + }; - Local<v8::Object> ReferenceError = - CompileRun("ReferenceError")->ToObject(env.local()).ToLocalChecked(); - - Local<String> source_text = v8_str( - "import {a, b} from 'export var a = 1; export let b = 2';" - "export function geta() {return a};" - "export function getb() {return b};" - "export let radio = 3;" - "export var gaga = 4;"); - ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); - ScriptCompiler::Source source(source_text, origin); - Local<Module> module = - ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); - CHECK_EQ(Module::kUninstantiated, module->GetStatus()); - CHECK(module - ->InstantiateModule(env.local(), - CompileSpecifierAsModuleResolveCallback) - .FromJust()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - Local<Value> ns = module->GetModuleNamespace(); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - Local<v8::Object> nsobj = ns->ToObject(env.local()).ToLocalChecked(); - - // a, b - CHECK(nsobj->Get(env.local(), v8_str("a")).ToLocalChecked()->IsUndefined()); - CHECK(nsobj->Get(env.local(), v8_str("b")).ToLocalChecked()->IsUndefined()); - - // geta - { - auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); - auto a = geta.As<v8::Function>() - ->Call(env.local(), geta, 0, nullptr) - .ToLocalChecked(); - CHECK(a->IsUndefined()); - } - - // getb - { - v8::TryCatch inner_try_catch(isolate); - auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); - CHECK( - getb.As<v8::Function>()->Call(env.local(), getb, 0, nullptr).IsEmpty()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception() - ->InstanceOf(env.local(), ReferenceError) + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) .FromJust()); - } + CHECK_EQ(Module::kInstantiated, module->GetStatus()); - // radio - { - v8::TryCatch inner_try_catch(isolate); - // https://bugs.chromium.org/p/v8/issues/detail?id=7235 - // CHECK(nsobj->Get(env.local(), v8_str("radio")).IsEmpty()); - CHECK(nsobj->Get(env.local(), v8_str("radio")) - .ToLocalChecked() - ->IsUndefined()); - CHECK(inner_try_catch.HasCaught()); - CHECK(inner_try_catch.Exception() - ->InstanceOf(env.local(), ReferenceError) - .FromJust()); - } + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kPending); + CHECK(!try_catch.HasCaught()); - // gaga - { - auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); - CHECK(gaga->IsUndefined()); + isolate->RunMicrotasks(); + CHECK_EQ(promise->State(), v8::Promise::kFulfilled); } + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; + i::FLAG_harmony_dynamic_import = previous_dynamic_import_flag_value; +} - CHECK(!try_catch.HasCaught()); - CHECK_EQ(Module::kInstantiated, module->GetStatus()); - module->Evaluate(env.local()).ToLocalChecked(); - CHECK_EQ(Module::kEvaluated, module->GetStatus()); - - // geta - { - auto geta = nsobj->Get(env.local(), v8_str("geta")).ToLocalChecked(); - auto a = geta.As<v8::Function>() - ->Call(env.local(), geta, 0, nullptr) - .ToLocalChecked(); - CHECK_EQ(1, a->Int32Value(env.local()).FromJust()); - } +TEST(ModuleEvaluationTopLevelAwaitDynamicImportError) { + bool previous_top_level_await_flag_value = i::FLAG_harmony_top_level_await; + bool previous_dynamic_import_flag_value = i::FLAG_harmony_dynamic_import; + i::FLAG_harmony_top_level_await = true; + i::FLAG_harmony_dynamic_import = true; + Isolate* isolate = CcTest::isolate(); + HandleScope scope(isolate); + isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit); + isolate->SetHostImportModuleDynamicallyCallback( + HostImportModuleDynamicallyCallbackReject); + LocalContext env; + v8::TryCatch try_catch(isolate); + const char* sources[] = { + "await import('foo');", + "import 'await import(\"foo\");';", + "import '42'; import 'await import(\"foo\");';", + }; - // getb - { - auto getb = nsobj->Get(env.local(), v8_str("getb")).ToLocalChecked(); - auto b = getb.As<v8::Function>() - ->Call(env.local(), getb, 0, nullptr) - .ToLocalChecked(); - CHECK_EQ(2, b->Int32Value(env.local()).FromJust()); - } + for (auto src : sources) { + Local<String> source_text = v8_str(src); + ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate()); + ScriptCompiler::Source source(source_text, origin); + Local<Module> module = + ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked(); + CHECK_EQ(Module::kUninstantiated, module->GetStatus()); + CHECK(module + ->InstantiateModule(env.local(), + CompileSpecifierAsModuleResolveCallback) + .FromJust()); + CHECK_EQ(Module::kInstantiated, module->GetStatus()); - // radio - { - auto radio = nsobj->Get(env.local(), v8_str("radio")).ToLocalChecked(); - CHECK_EQ(3, radio->Int32Value(env.local()).FromJust()); - } + Local<Promise> promise = + Local<Promise>::Cast(module->Evaluate(env.local()).ToLocalChecked()); + CHECK_EQ(Module::kEvaluated, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kPending); + CHECK(!try_catch.HasCaught()); - // gaga - { - auto gaga = nsobj->Get(env.local(), v8_str("gaga")).ToLocalChecked(); - CHECK_EQ(4, gaga->Int32Value(env.local()).FromJust()); + isolate->RunMicrotasks(); + CHECK_EQ(Module::kErrored, module->GetStatus()); + CHECK_EQ(promise->State(), v8::Promise::kRejected); + CHECK(promise->Result()->StrictEquals(v8_str("boom"))); + CHECK(module->GetException()->StrictEquals(v8_str("boom"))); + CHECK(!try_catch.HasCaught()); } - - CHECK(!try_catch.HasCaught()); + i::FLAG_harmony_top_level_await = previous_top_level_await_flag_value; + i::FLAG_harmony_dynamic_import = previous_dynamic_import_flag_value; } + } // anonymous namespace diff --git a/deps/v8/test/cctest/test-orderedhashtable.cc b/deps/v8/test/cctest/test-orderedhashtable.cc index 44a845eb7446e9..189f950b2ee9b2 100644 --- a/deps/v8/test/cctest/test-orderedhashtable.cc +++ b/deps/v8/test/cctest/test-orderedhashtable.cc @@ -1262,6 +1262,7 @@ TEST(OrderedHashMapHandlerInsertion) { Verify(isolate, map); CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); CHECK(SmallOrderedHashMap::Is(map)); + for (int i = 0; i < 1024; i++) { Handle<Smi> key_i(Smi::FromInt(i), isolate); Handle<Smi> value_i(Smi::FromInt(i), isolate); @@ -1276,6 +1277,83 @@ TEST(OrderedHashMapHandlerInsertion) { CHECK(OrderedHashMap::Is(map)); } +TEST(OrderedHashSetHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> set = + OrderedHashSetHandler::Allocate(isolate, 4).ToHandleChecked(); + Verify(isolate, set); + + // Add a new key. + Handle<Smi> key1(Smi::FromInt(1), isolate); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key1)); + set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked(); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + + // Add existing key. + set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked(); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(SmallOrderedHashSet::Is(set)); + + // Remove a non-existing key. + Handle<Smi> key2(Smi::FromInt(2), isolate); + OrderedHashSetHandler::Delete(isolate, set, key2); + Verify(isolate, set); + CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key2)); + CHECK(SmallOrderedHashSet::Is(set)); + + // Remove an existing key. + OrderedHashSetHandler::Delete(isolate, set, key1); + Verify(isolate, set); + CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key1)); + CHECK(SmallOrderedHashSet::Is(set)); +} + +TEST(OrderedHashMapHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> map = + OrderedHashMapHandler::Allocate(isolate, 4).ToHandleChecked(); + Verify(isolate, map); + + // Add a new key. + Handle<Smi> key1(Smi::FromInt(1), isolate); + Handle<Smi> value1(Smi::FromInt(1), isolate); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key1)); + map = + OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked(); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + + // Add existing key. + map = + OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked(); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(SmallOrderedHashMap::Is(map)); + + // Remove a non-existing key. + Handle<Smi> key2(Smi::FromInt(2), isolate); + OrderedHashMapHandler::Delete(isolate, map, key2); + Verify(isolate, map); + CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key2)); + CHECK(SmallOrderedHashMap::Is(map)); + + // Remove an existing key. + OrderedHashMapHandler::Delete(isolate, map, key1); + Verify(isolate, map); + CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key1)); + CHECK(SmallOrderedHashMap::Is(map)); +} + TEST(OrderedNameDictionaryInsertion) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); @@ -1798,6 +1876,49 @@ TEST(OrderedNameDictionaryHandlerInsertion) { CHECK(table->IsOrderedNameDictionary()); } +TEST(OrderedNameDictionaryHandlerDeletion) { + LocalContext context; + Isolate* isolate = GetIsolateFrom(&context); + HandleScope scope(isolate); + + Handle<HeapObject> table = + OrderedNameDictionaryHandler::Allocate(isolate, 4).ToHandleChecked(); + CHECK(table->IsSmallOrderedNameDictionary()); + Verify(isolate, table); + + // Add a new key. + Handle<String> value = isolate->factory()->InternalizeUtf8String("bar"); + Handle<String> key = isolate->factory()->InternalizeUtf8String("foo"); + Handle<String> key2 = isolate->factory()->InternalizeUtf8String("foo2"); + PropertyDetails details = PropertyDetails::Empty(); + + table = OrderedNameDictionaryHandler::Add(isolate, table, key, value, details) + .ToHandleChecked(); + DCHECK(key->IsUniqueName()); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_NE(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + // Remove a non-existing key. + OrderedNameDictionaryHandler::Delete(isolate, table, key2); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_EQ(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key2)); + CHECK_NE(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + // Remove an existing key. + OrderedNameDictionaryHandler::Delete(isolate, table, key); + Verify(isolate, table); + CHECK(table->IsSmallOrderedNameDictionary()); + CHECK_EQ(OrderedNameDictionaryHandler::kNotFound, + OrderedNameDictionaryHandler::FindEntry(isolate, *table, *key)); + + CHECK(table->IsSmallOrderedNameDictionary()); +} + TEST(OrderedNameDictionarySetEntry) { LocalContext context; Isolate* isolate = GetIsolateFrom(&context); diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index 857bd7a45462b0..18f15af477f6e6 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -1506,8 +1506,11 @@ TEST(DiscardFunctionBody) { fun = exp->AsObjectLiteral()->properties()->at(0)->value()-> AsFunctionLiteral(); } else { - fun = exp->AsClassLiteral()->properties()->at(0)->value()-> - AsFunctionLiteral(); + fun = exp->AsClassLiteral() + ->public_members() + ->at(0) + ->value() + ->AsFunctionLiteral(); } } CHECK(!fun->ShouldEagerCompile()); @@ -3608,6 +3611,14 @@ TEST(MaybeAssignedParameters) { "g(arg)}"}, {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"}, {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"}, + + // default values + {false, "function f({x:arg = 1}) {}"}, + {true, "function f({x:arg = 1}, {y:b=(arg=2)}) {}"}, + {true, "function f({x:arg = (arg = 2)}) {}"}, + {false, "var f = ({x:arg = 1}) => {}"}, + {true, "var f = ({x:arg = 1}, {y:b=(arg=2)}) => {}"}, + {true, "var f = ({x:arg = (arg = 2)}) => {}"}, }; const char* suffix = "; f"; @@ -5877,6 +5888,70 @@ TEST(PrivateMembersWrongAccessNoEarlyErrors) { private_methods, arraysize(private_methods)); } +TEST(PrivateStaticClassMethodsAndAccessorsNoErrors) { + // clang-format off + // Tests proposed class fields syntax. + const char* context_data[][2] = {{"(class {", "});"}, + {"(class extends Base {", "});"}, + {"class C {", "}"}, + {"class C extends Base {", "}"}, + {nullptr, nullptr}}; + const char* class_body_data[] = { + "static #a() { }", + "static get #a() { }", + "static set #a(val) { }", + "static get #a() { } static set #a(val) { }", + "static *#a() { }", + "static async #a() { }", + "static async *#a() { }", + nullptr + }; + // clang-format on + + RunParserSyncTest(context_data, class_body_data, kError); + + static const ParserFlag private_methods[] = {kAllowHarmonyPrivateMethods}; + RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0, + private_methods, arraysize(private_methods)); +} + +TEST(PrivateStaticClassMethodsAndAccessorsDuplicateErrors) { + // clang-format off + // Tests proposed class fields syntax. + const char* context_data[][2] = {{"(class {", "});"}, + {"(class extends Base {", "});"}, + {"class C {", "}"}, + {"class C extends Base {", "}"}, + {nullptr, nullptr}}; + const char* class_body_data[] = { + "static get #a() {} static get #a() {}", + "static get #a() {} static #a() {}", + "static get #a() {} get #a() {}", + "static get #a() {} set #a(val) {}", + "static get #a() {} #a() {}", + + "static set #a(val) {} static set #a(val) {}", + "static set #a(val) {} static #a() {}", + "static set #a(val) {} get #a() {}", + "static set #a(val) {} set #a(val) {}", + "static set #a(val) {} #a() {}", + + "static #a() {} static #a() {}", + "static #a() {} #a(val) {}", + "static #a() {} set #a(val) {}", + "static #a() {} get #a() {}", + + nullptr + }; + // clang-format on + + RunParserSyncTest(context_data, class_body_data, kError); + + static const ParserFlag private_methods[] = {kAllowHarmonyPrivateMethods}; + RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0, + private_methods, arraysize(private_methods)); +} + TEST(PrivateClassFieldsNoErrors) { // clang-format off // Tests proposed class fields syntax. @@ -6216,14 +6291,6 @@ TEST(PrivateStaticClassFieldsErrors) { "#a; static #a", "static #a; #a", - // TODO(joyee): support static private methods - "static #a() { }", - "static get #a() { }", - "static set #a() { }", - "static *#a() { }", - "static async #a() { }", - "static async *#a() { }", - // ASI "static #['a'] = 0\n", "static #['a'] = 0\n b", diff --git a/deps/v8/test/cctest/test-poison-disasm-arm.cc b/deps/v8/test/cctest/test-poison-disasm-arm.cc index 3410e5487d6461..dd54bf28bc40bb 100644 --- a/deps/v8/test/cctest/test-poison-disasm-arm.cc +++ b/deps/v8/test/cctest/test-poison-disasm-arm.cc @@ -24,6 +24,8 @@ const std::string kPReg = // NOLINT(runtime/string) TEST(DisasmPoisonMonomorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -58,6 +60,8 @@ TEST(DisasmPoisonMonomorphicLoad) { TEST(DisasmPoisonPolymorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -101,7 +105,7 @@ TEST(DisasmPoisonPolymorphicLoad) { "csdb", // spec. barrier "ldr <<BSt:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load backing store "and <<BSt>>, <<BSt>>, " + kPReg, // apply the poison - "ldr <<Prop:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the property + "ldr <<Prop:r[0-9]+>>, \\[<<BSt>>, #\\+[0-9]+\\]", // load the property "and <<Prop>>, <<Prop>>, " + kPReg, // apply the poison // Ldone: }; @@ -109,5 +113,43 @@ TEST(DisasmPoisonPolymorphicLoad) { #endif // ENABLE_DISASSEMBLER } +TEST(DisasmPoisonMonomorphicLoadFloat64) { +#ifdef ENABLE_DISASSEMBLER + if (i::FLAG_always_opt || !i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + i::FLAG_untrusted_code_mitigations = true; + + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + CompileRun( + "function mono(o) { return o.x; }" + "%PrepareFunctionForOptimization(mono);" + "mono({ x : 1.1 });" + "mono({ x : 1.1 });" + "%OptimizeFunctionOnNextCall(mono);" + "mono({ x : 1.1 });"); + + // Matches that the property access sequence is instrumented with + // poisoning. + std::vector<std::string> patterns_array = { + "ldr <<Map:r[0-9]+>>, \\[<<Obj:r[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:r[0-9]+>>, \\[pc, #", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "bne", // deopt if different + "eorne " + kPReg + ", " + kPReg + ", " + kPReg, // update the poison + "csdb", // spec. barrier + "ldr <<Field:r[0-9]+>>, \\[<<Obj>>, #\\+[0-9]+\\]", // load the field + "and <<Field>>, <<Field>>, " + kPReg, // apply the poison + "mov <<Mov:r[0-9]+>>, #[0-9]+", // addr. calculation + "add ip, <<Field>>, <<Mov>>", // addr. calculation + "and ip, ip, " + kPReg, // apply the poison + "vldr d[0-9]+, \\[ip", // load Float64 + }; + CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array)); +#endif // ENABLE_DISASSEMBLER +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-poison-disasm-arm64.cc b/deps/v8/test/cctest/test-poison-disasm-arm64.cc index a428ce7b892bb7..32f4315e3a0b48 100644 --- a/deps/v8/test/cctest/test-poison-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-poison-disasm-arm64.cc @@ -24,6 +24,8 @@ const std::string kPReg = // NOLINT(runtime/string) TEST(DisasmPoisonMonomorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -49,7 +51,7 @@ TEST(DisasmPoisonMonomorphicLoad) { "b.ne", // deopt if different "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldursw x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field + "ldur w<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field "and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison }; #else @@ -71,6 +73,8 @@ TEST(DisasmPoisonMonomorphicLoad) { TEST(DisasmPoisonPolymorphicLoad) { #ifdef ENABLE_DISASSEMBLER if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; i::FLAG_allow_natives_syntax = true; i::FLAG_untrusted_code_mitigations = true; @@ -113,7 +117,7 @@ TEST(DisasmPoisonPolymorphicLoad) { // Lcase1: "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldursw x<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store + "ldur w<<BSt:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load backing store // branchful decompress "add x<<BSt>>, x26, x<<BSt>>", // Add root to ref "and x<<BSt>>, x<<BSt>>, " + kPReg, // apply the poison @@ -135,9 +139,13 @@ TEST(DisasmPoisonPolymorphicLoad) { "b.ne", // deopt if different "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison "csdb", // spec. barrier - "ldur <<Field:x[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field - "and <<Field>>, <<Field>>, " + kPReg, // apply the poison - "asr x[0-9]+, <<Field>>, #32", // untag + "ldur x<<Field:[0-9]+>>, \\[<<Obj>>, #[0-9]+\\]", // load the field + "and x<<Field>>, x<<Field>>, " + kPReg, // apply the poison +#ifdef V8_31BIT_SMIS_ON_64BIT_ARCH + "asr w<<Field>>, w<<Field>>, #1", // untag +#else + "asr x[0-9]+, x<<Field>>, #32", // untag +#endif "b", // goto merge point // Lcase1: "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison @@ -153,5 +161,65 @@ TEST(DisasmPoisonPolymorphicLoad) { #endif // ENABLE_DISASSEMBLER } +TEST(DisasmPoisonMonomorphicLoadFloat64) { +#ifdef ENABLE_DISASSEMBLER + if (i::FLAG_always_opt || !i::FLAG_opt) return; + // TODO(9684): Re-enable for TurboProp if necessary. + if (i::FLAG_turboprop) return; + + i::FLAG_allow_natives_syntax = true; + i::FLAG_untrusted_code_mitigations = true; + + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + CompileRun( + "function mono(o) { return o.x; }" + "%PrepareFunctionForOptimization(mono);" + "mono({ x : 1.1 });" + "mono({ x : 1.1 });" + "%OptimizeFunctionOnNextCall(mono);" + "mono({ x : 1.1 });"); + + // Matches that the property access sequence is instrumented with + // poisoning. +#if defined(V8_COMPRESS_POINTERS) + std::vector<std::string> patterns_array = { + "ldur <<Map:w[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:w[0-9]+>>, pc", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "b.ne", // deopt if differ + "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison + "csdb", // spec. barrier + "ldur w<<F1:[0-9]+>>, \\[<<Obj>>, #11\\]", // load heap number + "add x<<F1>>, x26, x<<F1>>", // Decompress ref + "and x<<F1>>, x<<F1>>, " + kPReg, // apply the poison + "add <<Addr:x[0-9]+>>, x<<F1>>, #0x[0-9a-f]+", // addr. calculation + "and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison + "ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64 + }; +#else + std::vector<std::string> patterns_array = { + "ldur <<Map:x[0-9]+>>, \\[<<Obj:x[0-9]+>>, #-1\\]", // load map + "ldr <<ExpMap:x[0-9]+>>, pc", // load expected map + "cmp <<Map>>, <<ExpMap>>", // compare maps + "b.ne", // deopt if differ + "csel " + kPReg + ", xzr, " + kPReg + ", ne", // update the poison + "csdb", // spec. barrier +#if V8_DOUBLE_FIELDS_UNBOXING + "add <<Addr:x[0-9]+>>, <<Obj>>, #0x[0-9a-f]+", // addr. calculation +#else + "ldur <<F1:x[0-9]+>>, \\[<<Obj>>, #23\\]", // load heap number + "and <<F1>>, <<F1>>, " + kPReg, // apply the poison + "add <<Addr:x[0-9]+>>, <<F1>>, #0x7", // addr. calculation +#endif + "and <<Addr>>, <<Addr>>, " + kPReg, // apply the poison + "ldr d[0-9]+, \\[<<Addr>>\\]", // load Float64 + }; +#endif + CHECK(CheckDisassemblyRegexPatterns("mono", patterns_array)); +#endif // ENABLE_DISASSEMBLER +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index ccebabec304e36..5cfc4df2a34f42 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -674,13 +674,12 @@ static const char* line_number_test_source_profile_time_functions = "bar_at_the_second_line();\n" "function lazy_func_at_6th_line() {}"; -int GetFunctionLineNumber(CpuProfiler& profiler, // NOLINT(runtime/references) - LocalContext& env, // NOLINT(runtime/references) +int GetFunctionLineNumber(CpuProfiler* profiler, LocalContext* env, const char* name) { - CodeMap* code_map = profiler.generator()->code_map(); + CodeMap* code_map = profiler->generator()->code_map(); i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(env.local(), v8_str(name)).ToLocalChecked()))); + (*env)->Global()->Get(env->local(), v8_str(name)).ToLocalChecked()))); CodeEntry* func_entry = code_map->FindEntry(func->abstract_code().InstructionStart()); if (!func_entry) FATAL("%s", name); @@ -705,12 +704,12 @@ TEST(LineNumber) { profiler.processor()->StopSynchronously(); bool is_lazy = i::FLAG_lazy; - CHECK_EQ(1, GetFunctionLineNumber(profiler, env, "foo_at_the_first_line")); + CHECK_EQ(1, GetFunctionLineNumber(&profiler, &env, "foo_at_the_first_line")); CHECK_EQ(is_lazy ? 0 : 4, - GetFunctionLineNumber(profiler, env, "lazy_func_at_forth_line")); - CHECK_EQ(2, GetFunctionLineNumber(profiler, env, "bar_at_the_second_line")); + GetFunctionLineNumber(&profiler, &env, "lazy_func_at_forth_line")); + CHECK_EQ(2, GetFunctionLineNumber(&profiler, &env, "bar_at_the_second_line")); CHECK_EQ(is_lazy ? 0 : 6, - GetFunctionLineNumber(profiler, env, "lazy_func_at_6th_line")); + GetFunctionLineNumber(&profiler, &env, "lazy_func_at_6th_line")); profiler.StopProfiling("LineNumber"); } diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 1374673c618792..95e752bece7a2d 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -38,6 +38,7 @@ #include "src/objects/js-regexp-inl.h" #include "src/objects/objects-inl.h" #include "src/regexp/regexp-bytecode-generator.h" +#include "src/regexp/regexp-bytecodes.h" #include "src/regexp/regexp-compiler.h" #include "src/regexp/regexp-interpreter.h" #include "src/regexp/regexp-macro-assembler-arch.h" @@ -1744,19 +1745,6 @@ TEST(UseCountRegExp) { CHECK_EQ(2, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]); CHECK(resultToStringError->IsObject()); - - // Increment a UseCounter when .matchAll() is used with a non-global - // regular expression. - CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - v8::Local<v8::Value> resultReMatchAllNonGlobal = - CompileRun("'a'.matchAll(/./)"); - CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - CHECK(resultReMatchAllNonGlobal->IsObject()); - // Don't increment the counter for global regular expressions. - v8::Local<v8::Value> resultReMatchAllGlobal = - CompileRun("'a'.matchAll(/./g)"); - CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp]); - CHECK(resultReMatchAllGlobal->IsObject()); } class UncachedExternalString @@ -1783,6 +1771,567 @@ TEST(UncachedExternalString) { ExpectString("external.substring(1).match(re)[1]", "z"); } +// Test bytecode peephole optimization + +void CreatePeepholeNoChangeBytecode(RegExpMacroAssembler* m) { + Label fail, backtrack; + m->PushBacktrack(&fail); + m->CheckNotAtStart(0, nullptr); + m->LoadCurrentCharacter(2, nullptr); + m->CheckNotCharacter('o', nullptr); + m->LoadCurrentCharacter(1, nullptr, false); + m->CheckNotCharacter('o', nullptr); + m->LoadCurrentCharacter(0, nullptr, false); + m->CheckNotCharacter('f', nullptr); + m->WriteCurrentPositionToRegister(0, 0); + m->WriteCurrentPositionToRegister(1, 3); + m->AdvanceCurrentPosition(3); + m->PushBacktrack(&backtrack); + m->Succeed(); + m->Bind(&backtrack); + m->Backtrack(); + m->Bind(&fail); + m->Fail(); +} + +TEST(PeepholeNoChange) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeNoChangeBytecode(&orig); + CreatePeepholeNoChangeBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("^foo"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + byte* byte_array = array->GetDataStartAddress(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + byte* byte_array_optimized = array_optimized->GetDataStartAddress(); + + CHECK_EQ(0, memcmp(byte_array, byte_array_optimized, length)); +} + +void CreatePeepholeSkipUntilCharBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilChar) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharBytecode(&orig); + CreatePeepholeSkipUntilCharBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, + array_optimized->get(RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR))); +} + +void CreatePeepholeSkipUntilBitInTableBytecode(RegExpMacroAssembler* m, + Factory* factory) { + Handle<ByteArray> bit_table = factory->NewByteArray( + RegExpMacroAssembler::kTableSize, AllocationType::kOld); + for (uint32_t i = 0; i < RegExpMacroAssembler::kTableSize; i++) { + bit_table->set(i, 0); + } + + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckBitInTable(bit_table, nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilBitInTable) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilBitInTableBytecode(&orig, factory); + CreatePeepholeSkipUntilBitInTableBytecode(&opt, factory); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_BIT_IN_TABLE, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get( + RegExpBytecodeLength(BC_SKIP_UNTIL_BIT_IN_TABLE))); +} + +void CreatePeepholeSkipUntilCharPosCheckedBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true, 1, 2); + m->CheckCharacter('x', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharPosChecked) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharPosCheckedBytecode(&orig); + CreatePeepholeSkipUntilCharPosCheckedBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_CHECK_CURRENT_POSITION) + + RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR_UNCHECKED) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_POS_CHECKED) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_POS_CHECKED, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get(RegExpBytecodeLength( + BC_SKIP_UNTIL_CHAR_POS_CHECKED))); +} + +void CreatePeepholeSkipUntilCharAndBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true, 1, 2); + m->CheckCharacterAfterAnd('x', 0xFF, nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharAnd) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharAndBytecode(&orig); + CreatePeepholeSkipUntilCharAndBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_CHECK_CURRENT_POSITION) + + RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR_UNCHECKED) + + RegExpBytecodeLength(BC_AND_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_AND) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_AND, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, + array_optimized->get(RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_AND))); +} + +void CreatePeepholeSkipUntilCharOrCharBytecode(RegExpMacroAssembler* m) { + Label start; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); +} + +TEST(PeepholeSkipUntilCharOrChar) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilCharOrCharBytecode(&orig); + CreatePeepholeSkipUntilCharOrCharBytecode(&opt); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_CHECK_CHAR) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_OR_CHAR) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_CHAR_OR_CHAR, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get( + RegExpBytecodeLength(BC_SKIP_UNTIL_CHAR_OR_CHAR))); +} + +void CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(RegExpMacroAssembler* m, + Factory* factory) { + Handle<ByteArray> bit_table = factory->NewByteArray( + RegExpMacroAssembler::kTableSize, AllocationType::kOld); + for (uint32_t i = 0; i < RegExpMacroAssembler::kTableSize; i++) { + bit_table->set(i, 0); + } + + Label start, end, advance; + m->Bind(&start); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacterGT('x', nullptr); + m->CheckBitInTable(bit_table, &advance); + m->GoTo(&end); + m->Bind(&advance); + m->AdvanceCurrentPosition(1); + m->GoTo(&start); + m->Bind(&end); +} + +TEST(PeepholeSkipUntilGtOrNotBitInTable) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(&orig, factory); + CreatePeepholeSkipUntilGtOrNotBitInTableBytecode(&opt, factory); + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + int length = array->length(); + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + int length_optimized = array_optimized->length(); + + int length_expected = RegExpBytecodeLength(BC_LOAD_CURRENT_CHAR) + + RegExpBytecodeLength(BC_CHECK_GT) + + RegExpBytecodeLength(BC_CHECK_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_GOTO) + + RegExpBytecodeLength(BC_ADVANCE_CP_AND_GOTO) + + RegExpBytecodeLength(BC_POP_BT); + int length_optimized_expected = + RegExpBytecodeLength(BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE) + + RegExpBytecodeLength(BC_POP_BT); + + CHECK_EQ(length, length_expected); + CHECK_EQ(length_optimized, length_optimized_expected); + + CHECK_EQ(BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE, array_optimized->get(0)); + CHECK_EQ(BC_POP_BT, array_optimized->get(RegExpBytecodeLength( + BC_SKIP_UNTIL_GT_OR_NOT_BIT_IN_TABLE))); +} + +void CreatePeepholeLabelFixupsInsideBytecode(RegExpMacroAssembler* m, + Label* dummy_before, + Label* dummy_after, + Label* dummy_inside) { + Label loop; + m->Bind(dummy_before); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_after); + m->CheckCharacter('b', dummy_inside); + m->Bind(&loop); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->Bind(dummy_inside); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop); + m->Bind(dummy_after); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_after); + m->CheckCharacter('b', dummy_inside); +} + +TEST(PeepholeLabelFixupsInside) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + { + Label dummy_before, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsInsideBytecode(&opt, &dummy_before, &dummy_after, + &dummy_inside); + } + Label dummy_before, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsInsideBytecode(&orig, &dummy_before, &dummy_after, + &dummy_inside); + + CHECK_EQ(0x00, dummy_before.pos()); + CHECK_EQ(0x28, dummy_inside.pos()); + CHECK_EQ(0x38, dummy_after.pos()); + + const Label* labels[] = {&dummy_before, &dummy_after, &dummy_inside}; + const int label_positions[4][3] = { + {0x04, 0x3C}, // dummy_before + {0x0C, 0x44}, // dummy after + {0x14, 0x4C} // dummy inside + }; + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + + for (int label_idx = 0; label_idx < 3; label_idx++) { + for (int pos_idx = 0; pos_idx < 2; pos_idx++) { + CHECK_EQ(labels[label_idx]->pos(), + array->get(label_positions[label_idx][pos_idx])); + } + } + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + + const int pos_fixups[] = { + 0, // Position before optimization should be unchanged. + 4, // Position after first replacement should be 4 (optimized size (20) - + // original size (32) + preserve length (16)). + }; + const int target_fixups[] = { + 0, // dummy_before should be unchanged + 4, // dummy_inside should be 4 + 4 // dummy_after should be 4 + }; + + for (int label_idx = 0; label_idx < 3; label_idx++) { + for (int pos_idx = 0; pos_idx < 2; pos_idx++) { + int label_pos = label_positions[label_idx][pos_idx] + pos_fixups[pos_idx]; + int jump_address = *reinterpret_cast<uint32_t*>( + array_optimized->GetDataStartAddress() + label_pos); + int expected_jump_address = + labels[label_idx]->pos() + target_fixups[label_idx]; + CHECK_EQ(expected_jump_address, jump_address); + } + } +} + +void CreatePeepholeLabelFixupsComplexBytecode(RegExpMacroAssembler* m, + Label* dummy_before, + Label* dummy_between, + Label* dummy_after, + Label* dummy_inside) { + Label loop1, loop2; + m->Bind(dummy_before); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); + m->Bind(&loop1); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop1); + m->Bind(dummy_between); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); + m->Bind(&loop2); + m->LoadCurrentCharacter(0, nullptr, true); + m->CheckCharacter('x', nullptr); + m->Bind(dummy_inside); + m->CheckCharacter('y', nullptr); + m->AdvanceCurrentPosition(1); + m->GoTo(&loop2); + m->Bind(dummy_after); + m->LoadCurrentCharacter(0, dummy_before); + m->CheckCharacter('a', dummy_between); + m->CheckCharacter('b', dummy_after); + m->CheckCharacter('c', dummy_inside); +} + +TEST(PeepholeLabelFixupsComplex) { + Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + RegExpBytecodeGenerator orig(CcTest::i_isolate(), &zone); + RegExpBytecodeGenerator opt(CcTest::i_isolate(), &zone); + + { + Label dummy_before, dummy_between, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsComplexBytecode( + &opt, &dummy_before, &dummy_between, &dummy_after, &dummy_inside); + } + Label dummy_before, dummy_between, dummy_after, dummy_inside; + CreatePeepholeLabelFixupsComplexBytecode(&orig, &dummy_before, &dummy_between, + &dummy_after, &dummy_inside); + + CHECK_EQ(0x00, dummy_before.pos()); + CHECK_EQ(0x40, dummy_between.pos()); + CHECK_EQ(0x70, dummy_inside.pos()); + CHECK_EQ(0x80, dummy_after.pos()); + + const Label* labels[] = {&dummy_before, &dummy_between, &dummy_after, + &dummy_inside}; + const int label_positions[4][3] = { + {0x04, 0x44, 0x84}, // dummy_before + {0x0C, 0x4C, 0x8C}, // dummy between + {0x14, 0x54, 0x94}, // dummy after + {0x1C, 0x5C, 0x9C} // dummy inside + }; + + Handle<String> source = factory->NewStringFromStaticChars("dummy"); + + i::FLAG_regexp_peephole_optimization = false; + Handle<ByteArray> array = Handle<ByteArray>::cast(orig.GetCode(source)); + + for (int label_idx = 0; label_idx < 4; label_idx++) { + for (int pos_idx = 0; pos_idx < 3; pos_idx++) { + CHECK_EQ(labels[label_idx]->pos(), + array->get(label_positions[label_idx][pos_idx])); + } + } + + i::FLAG_regexp_peephole_optimization = true; + Handle<ByteArray> array_optimized = + Handle<ByteArray>::cast(opt.GetCode(source)); + + const int pos_fixups[] = { + 0, // Position before optimization should be unchanged. + -12, // Position after first replacement should be -12 (optimized size = + // 20 - 32 = original size). + -8 // Position after second replacement should be -8 (-12 from first + // optimization -12 from second optimization + 16 preserved + // bytecodes). + }; + const int target_fixups[] = { + 0, // dummy_before should be unchanged + -12, // dummy_between should be -12 + -8, // dummy_inside should be -8 + -8 // dummy_after should be -8 + }; + + for (int label_idx = 0; label_idx < 4; label_idx++) { + for (int pos_idx = 0; pos_idx < 3; pos_idx++) { + int label_pos = label_positions[label_idx][pos_idx] + pos_fixups[pos_idx]; + int jump_address = *reinterpret_cast<uint32_t*>( + array_optimized->GetDataStartAddress() + label_pos); + int expected_jump_address = + labels[label_idx]->pos() + target_fixups[label_idx]; + CHECK_EQ(expected_jump_address, jump_address); + } + } +} + #undef CHECK_PARSE_ERROR #undef CHECK_SIMPLE #undef CHECK_MIN_MAX diff --git a/deps/v8/test/cctest/test-roots.cc b/deps/v8/test/cctest/test-roots.cc index d04190363978a4..f3d1a565434329 100644 --- a/deps/v8/test/cctest/test-roots.cc +++ b/deps/v8/test/cctest/test-roots.cc @@ -46,8 +46,8 @@ bool IsInitiallyMutable(Factory* factory, Address object_address) { V(detached_contexts) \ V(dirty_js_finalization_groups) \ V(feedback_vectors_for_profiling_tools) \ + V(shared_wasm_memories) \ V(materialized_objects) \ - V(noscript_shared_function_infos) \ V(public_symbol_table) \ V(retained_maps) \ V(retaining_path_targets) \ diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 407437c4b1b48e..e2ab99679639c7 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -98,8 +98,7 @@ class TestSerializer { return v8_isolate; } - static v8::Isolate* NewIsolateFromBlob( - StartupBlobs& blobs) { // NOLINT(runtime/references) + static v8::Isolate* NewIsolateFromBlob(const StartupBlobs& blobs) { SnapshotData startup_snapshot(blobs.startup); SnapshotData read_only_snapshot(blobs.read_only); ReadOnlyDeserializer read_only_deserializer(&read_only_snapshot); @@ -204,8 +203,7 @@ Vector<const uint8_t> ConstructSource(Vector<const uint8_t> head, source_length); } -static v8::Isolate* Deserialize( - StartupBlobs& blobs) { // NOLINT(runtime/references) +static v8::Isolate* Deserialize(const StartupBlobs& blobs) { v8::Isolate* isolate = TestSerializer::NewIsolateFromBlob(blobs); CHECK(isolate); return isolate; @@ -1522,7 +1520,8 @@ TEST(CodeSerializerWithProfiler) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1563,7 +1562,8 @@ TEST(CodeSerializerWithProfiler) { void TestCodeSerializerOnePlusOneImpl(bool verify_builtins_count = true) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1676,7 +1676,8 @@ TEST(CodeSerializerPromotedToCompilationCache) { TEST(CodeSerializerInternalizedString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1734,7 +1735,8 @@ TEST(CodeSerializerInternalizedString) { TEST(CodeSerializerLargeCodeObject) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1793,7 +1795,8 @@ TEST(CodeSerializerLargeCodeObjectWithIncrementalMarking) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Heap* heap = isolate->heap(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1863,7 +1866,8 @@ TEST(CodeSerializerLargeStrings) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Factory* f = isolate->factory(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -1919,7 +1923,8 @@ TEST(CodeSerializerThreeBigStrings) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); Factory* f = isolate->factory(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -2038,7 +2043,8 @@ class SerializerTwoByteResource : public v8::String::ExternalStringResource { TEST(CodeSerializerExternalString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); @@ -2104,7 +2110,8 @@ TEST(CodeSerializerExternalString) { TEST(CodeSerializerLargeExternalString) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. Factory* f = isolate->factory(); @@ -2164,7 +2171,8 @@ TEST(CodeSerializerLargeExternalString) { TEST(CodeSerializerExternalScriptName) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. Factory* f = isolate->factory(); @@ -3606,13 +3614,13 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) { // We can introduce new extensions, which could override functions already // in the snapshot. auto extension = - base::make_unique<v8::Extension>("new extension", - "function i() { return 24; }" - "function j() { return 25; }" - "let a = 26;" - "try {" - " if (o.p == 7) o.p++;" - "} catch {}"); + std::make_unique<v8::Extension>("new extension", + "function i() { return 24; }" + "function j() { return 25; }" + "let a = 26;" + "try {" + " if (o.p == 7) o.p++;" + "} catch {}"); extension->set_auto_enable(true); v8::RegisterExtension(std::move(extension)); { @@ -3900,7 +3908,7 @@ UNINITIALIZED_TEST(WeakArraySerializationInSnapshot) { TEST(WeakArraySerializationInCodeCache) { LocalContext context; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); + isolate->compilation_cache()->DisableScriptAndEval(); v8::HandleScope scope(CcTest::isolate()); @@ -3929,7 +3937,8 @@ TEST(CachedCompileFunctionInContext) { DisableAlwaysOpt(); LocalContext env; Isolate* isolate = CcTest::i_isolate(); - isolate->compilation_cache()->Disable(); // Disable same-isolate code cache. + isolate->compilation_cache() + ->DisableScriptAndEval(); // Disable same-isolate code cache. v8::HandleScope scope(CcTest::isolate()); diff --git a/deps/v8/test/cctest/test-smi-lexicographic-compare.cc b/deps/v8/test/cctest/test-smi-lexicographic-compare.cc index 914444c6343cc7..7b3e600c14cf77 100644 --- a/deps/v8/test/cctest/test-smi-lexicographic-compare.cc +++ b/deps/v8/test/cctest/test-smi-lexicographic-compare.cc @@ -14,11 +14,11 @@ namespace internal { namespace { -void AddSigned(std::set<Smi>& smis, int64_t x) { // NOLINT(runtime/references) +void AddSigned(std::set<Smi>* smis, int64_t x) { if (!Smi::IsValid(x)) return; - smis.insert(Smi::FromInt(static_cast<int>(x))); - smis.insert(Smi::FromInt(static_cast<int>(-x))); + smis->insert(Smi::FromInt(static_cast<int>(x))); + smis->insert(Smi::FromInt(static_cast<int>(-x))); } // Uses std::lexicographical_compare twice to convert the result to -1, 0 or 1. @@ -58,14 +58,14 @@ TEST(TestSmiLexicographicCompare) { for (int64_t xb = 1; xb <= Smi::kMaxValue; xb *= 10) { for (int64_t xf = 0; xf <= 9; ++xf) { for (int64_t xo = -1; xo <= 1; ++xo) { - AddSigned(smis, xb * xf + xo); + AddSigned(&smis, xb * xf + xo); } } } for (int64_t yb = 1; yb <= Smi::kMaxValue; yb *= 2) { for (int64_t yo = -2; yo <= 2; ++yo) { - AddSigned(smis, yb + yo); + AddSigned(&smis, yb + yo); } } diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index 796f38a73b1767..f64c044a0c9bf5 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -1857,6 +1857,48 @@ GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING( #undef GC_INSIDE_NEW_STRING_FROM_UTF8_SUB_STRING +namespace { + +struct IndexData { + const char* string; + bool is_array_index; + uint32_t array_index; + bool is_integer_index; + size_t integer_index; +}; + +void TestString(i::Isolate* isolate, const IndexData& data) { + Handle<String> s = isolate->factory()->NewStringFromAsciiChecked(data.string); + if (data.is_array_index) { + uint32_t index; + CHECK(s->AsArrayIndex(&index)); + CHECK_EQ(data.array_index, index); + // AsArrayIndex only forces hash computation for cacheable indices; + // so trigger hash computation for longer strings manually. + if (s->length() > String::kMaxCachedArrayIndexLength) s->Hash(); + CHECK_EQ(0, s->hash_field() & String::kIsNotArrayIndexMask); + CHECK(s->HasHashCode()); + } + if (data.is_integer_index) { + size_t index; + CHECK(s->AsIntegerIndex(&index)); + CHECK_EQ(data.integer_index, index); + s->Hash(); + CHECK_EQ(0, s->hash_field() & String::kIsNotIntegerIndexMask); + CHECK(s->HasHashCode()); + } + if (!s->HasHashCode()) s->Hash(); + CHECK(s->HasHashCode()); + if (!data.is_array_index) { + CHECK_NE(0, s->hash_field() & String::kIsNotArrayIndexMask); + } + if (!data.is_integer_index) { + CHECK_NE(0, s->hash_field() & String::kIsNotIntegerIndexMask); + } +} + +} // namespace + TEST(HashArrayIndexStrings) { CcTest::InitializeVM(); LocalContext context; @@ -1870,6 +1912,27 @@ TEST(HashArrayIndexStrings) { CHECK_EQ(StringHasher::MakeArrayIndexHash(1 /* value */, 1 /* length */) >> Name::kHashShift, isolate->factory()->one_string()->Hash()); + + IndexData tests[] = { + {"", false, 0, false, 0}, + {"123no", false, 0, false, 0}, + {"12345", true, 12345, true, 12345}, + {"12345678", true, 12345678, true, 12345678}, + {"4294967294", true, 4294967294u, true, 4294967294u}, +#if V8_TARGET_ARCH_32_BIT + {"4294967295", false, 0, false, 0}, // Valid length but not index. + {"4294967296", false, 0, false, 0}, + {"18446744073709551615", false, 0, false, 0}, +#else + {"4294967295", false, 0, true, 4294967295u}, + {"4294967296", false, 0, true, 4294967296ull}, + {"18446744073709551615", false, 0, true, 18446744073709551615ull}, +#endif + {"18446744073709551616", false, 0, false, 0} + }; + for (int i = 0, n = arraysize(tests); i < n; i++) { + TestString(isolate, tests[i]); + } } TEST(StringEquals) { diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 20627240431ea0..5c852d7232e4c6 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -75,7 +75,7 @@ TEST(ThreadIdValidation) { ThreadIdValidationThread* prev = i == kNThreads - 1 ? nullptr : threads[i + 1].get(); threads[i] = - base::make_unique<ThreadIdValidationThread>(prev, refs, i, &semaphore); + std::make_unique<ThreadIdValidationThread>(prev, refs, i, &semaphore); } CHECK(threads[0]->Start()); for (int i = 0; i < kNThreads; i++) { diff --git a/deps/v8/test/cctest/test-trace-event.cc b/deps/v8/test/cctest/test-trace-event.cc index 7b3c215d698e47..0f4a699d8ac6c0 100644 --- a/deps/v8/test/cctest/test-trace-event.cc +++ b/deps/v8/test/cctest/test-trace-event.cc @@ -6,7 +6,6 @@ #include "src/init/v8.h" -#include "src/base/template-utils.h" #include "test/cctest/cctest.h" #include "src/tracing/trace-event.h" @@ -55,9 +54,8 @@ class MockTracingController : public v8::TracingController { const uint64_t* arg_values, std::unique_ptr<v8::ConvertableToTraceFormat>* arg_convertables, unsigned int flags, int64_t timestamp) override { - std::unique_ptr<MockTraceObject> to = - v8::base::make_unique<MockTraceObject>( - phase, std::string(name), id, bind_id, num_args, flags, timestamp); + std::unique_ptr<MockTraceObject> to = std::make_unique<MockTraceObject>( + phase, std::string(name), id, bind_id, num_args, flags, timestamp); trace_objects_.push_back(std::move(to)); return 0; } diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc index fb4740cb92b00a..5e715b75e0902c 100644 --- a/deps/v8/test/cctest/test-typedarrays.cc +++ b/deps/v8/test/cctest/test-typedarrays.cc @@ -7,6 +7,7 @@ #include "src/init/v8.h" #include "test/cctest/cctest.h" +#include "src/execution/protectors-inl.h" #include "src/heap/heap.h" #include "src/objects/objects-inl.h" #include "src/objects/objects.h" @@ -14,12 +15,11 @@ namespace v8 { namespace internal { -void TestArrayBufferViewContents( - LocalContext& env, // NOLINT(runtime/references) - bool should_use_buffer) { +void TestArrayBufferViewContents(LocalContext* env, bool should_use_buffer) { v8::Local<v8::Object> obj_a = v8::Local<v8::Object>::Cast( - env->Global() - ->Get(env->GetIsolate()->GetCurrentContext(), v8_str("a")) + (*env) + ->Global() + ->Get((*env)->GetIsolate()->GetCurrentContext(), v8_str("a")) .ToLocalChecked()); CHECK(obj_a->IsArrayBufferView()); v8::Local<v8::ArrayBufferView> array_buffer_view = @@ -43,7 +43,7 @@ TEST(CopyContentsTypedArray) { "a[1] = 1;" "a[2] = 2;" "a[3] = 3;"); - TestArrayBufferViewContents(env, false); + TestArrayBufferViewContents(&env, false); } @@ -51,7 +51,7 @@ TEST(CopyContentsArray) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); CompileRun("var a = new Uint8Array([0, 1, 2, 3]);"); - TestArrayBufferViewContents(env, false); + TestArrayBufferViewContents(&env, false); } @@ -68,7 +68,7 @@ TEST(CopyContentsView) { "c[4] = 2;" "c[5] = 3;" "var a = new DataView(b, 2);"); - TestArrayBufferViewContents(env, true); + TestArrayBufferViewContents(&env, true); } @@ -82,7 +82,7 @@ TEST(AllocateNotExternal) { v8::ArrayBuffer::New(env->GetIsolate(), memory, 1024, v8::ArrayBufferCreationMode::kInternalized); CHECK(!buffer->IsExternal()); - CHECK_EQ(memory, buffer->GetContents().Data()); + CHECK_EQ(memory, buffer->GetBackingStore()->Data()); } void TestSpeciesProtector(char* code, @@ -115,12 +115,12 @@ void TestSpeciesProtector(char* code, v8::internal::Isolate* i_isolate = reinterpret_cast<v8::internal::Isolate*>(isolate); - CHECK(i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); CompileRun(code); if (invalidates_species_protector) { - CHECK(!i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(!Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); } else { - CHECK(i_isolate->IsTypedArraySpeciesLookupChainIntact()); + CHECK(Protectors::IsTypedArraySpeciesLookupChainIntact(i_isolate)); } v8::Local<v8::Value> my_typed_array = CompileRun("MyTypedArray"); diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc index 9cfc40d37d992e..ebeb05597e4da5 100644 --- a/deps/v8/test/cctest/test-unboxed-doubles.cc +++ b/deps/v8/test/cctest/test-unboxed-doubles.cc @@ -78,8 +78,9 @@ static double GetDoubleFieldValue(JSObject obj, FieldIndex field_index) { } } -void WriteToField(JSObject object, int descriptor, Object value) { +void WriteToField(JSObject object, int index, Object value) { DescriptorArray descriptors = object.map().instance_descriptors(); + InternalIndex descriptor(index); PropertyDetails details = descriptors.GetDetails(descriptor); object.WriteToField(descriptor, details, value); } @@ -811,7 +812,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull( Handle<Map> map; // Now check layout descriptors of all intermediate maps. for (int i = 0; i < number_of_descriptors; i++) { - PropertyDetails details = descriptors->GetDetails(i); + PropertyDetails details = descriptors->GetDetails(InternalIndex(i)); map = maps[i]; LayoutDescriptor layout_desc = map->layout_descriptor(); @@ -962,7 +963,7 @@ TEST(Regress436816) { CHECK(fake_object.IsHeapObject()); uint64_t boom_value = bit_cast<uint64_t>(fake_object); - for (int i = 0; i < kPropsCount; i++) { + for (InternalIndex i : InternalIndex::Range(kPropsCount)) { FieldIndex index = FieldIndex::ForDescriptor(*map, i); CHECK(map->IsUnboxedDoubleField(index)); object->RawFastDoublePropertyAsBitsAtPut(index, boom_value); @@ -1100,7 +1101,7 @@ TEST(DoScavenge) { { // Ensure the object is properly set up. - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(0)); CHECK(field_index.is_inobject() && field_index.is_double()); CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index)); @@ -1119,7 +1120,8 @@ TEST(DoScavenge) { Address fake_object = temp->ptr() + kSystemPointerSize; double boom_value = bit_cast<double>(fake_object); - FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0); + FieldIndex field_index = + FieldIndex::ForDescriptor(obj->map(), InternalIndex(0)); auto boom_number = factory->NewHeapNumber(boom_value); obj->FastPropertyAtPut(field_index, *boom_number); @@ -1182,12 +1184,12 @@ TEST(DoScavengeWithIncrementalWriteBarrier) { { // Ensure the object is properly set up. - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 0); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(0)); CHECK(field_index.is_inobject() && field_index.is_double()); CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index)); - field_index = FieldIndex::ForDescriptor(*map, 1); + field_index = FieldIndex::ForDescriptor(*map, InternalIndex(1)); CHECK(field_index.is_inobject() && !field_index.is_double()); CHECK(!map->IsUnboxedDoubleField(field_index)); } @@ -1225,7 +1227,7 @@ TEST(DoScavengeWithIncrementalWriteBarrier) { // |obj_value| must be evacuated. CHECK(!MarkCompactCollector::IsOnEvacuationCandidate(*obj_value)); - FieldIndex field_index = FieldIndex::ForDescriptor(*map, 1); + FieldIndex field_index = FieldIndex::ForDescriptor(*map, InternalIndex(1)); CHECK_EQ(*obj_value, obj->RawFastPropertyAt(field_index)); } @@ -1248,7 +1250,7 @@ static void TestLayoutDescriptorHelper(Isolate* isolate, int end_offset = instance_size * 2; int first_non_tagged_field_offset = end_offset; - for (int i = 0; i < number_of_descriptors; i++) { + for (InternalIndex i : InternalIndex::Range(number_of_descriptors)) { PropertyDetails details = descriptors->GetDetails(i); if (details.location() != kField) continue; FieldIndex index = FieldIndex::ForDescriptor(*map, i); @@ -1430,9 +1432,9 @@ TEST(LayoutDescriptorSharing) { CHECK(map2->layout_descriptor().IsConsistentWithMap(*map2, true)); } - static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, - int tagged_descriptor, int double_descriptor, + InternalIndex tagged_descriptor, + InternalIndex double_descriptor, bool check_tagged_value = true) { FLAG_stress_compaction = true; FLAG_manual_evacuation_candidates_selection = true; @@ -1491,10 +1493,9 @@ static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, CHECK_EQ(boom_value, obj->RawFastDoublePropertyAsBitsAt(double_field_index)); } - static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map, - int tagged_descriptor, - int double_descriptor, + InternalIndex tagged_descriptor, + InternalIndex double_descriptor, bool check_tagged_value = true) { if (FLAG_never_compact || !FLAG_incremental_marking) return; ManualGCScope manual_gc_scope; @@ -1607,14 +1608,16 @@ static void TestWriteBarrierObjectShiftFieldsRight( .ToHandleChecked(); // Shift fields right by turning constant property to a field. - Handle<Map> new_map = Map::ReconfigureProperty( - isolate, map, 0, kData, NONE, Representation::Tagged(), any_type); + Handle<Map> new_map = + Map::ReconfigureProperty(isolate, map, InternalIndex(0), kData, NONE, + Representation::Tagged(), any_type); if (write_barrier_kind == OLD_TO_NEW_WRITE_BARRIER) { - TestWriteBarrier(map, new_map, 2, 1); + TestWriteBarrier(map, new_map, InternalIndex(2), InternalIndex(1)); } else { CHECK_EQ(OLD_TO_OLD_WRITE_BARRIER, write_barrier_kind); - TestIncrementalWriteBarrier(map, new_map, 2, 1); + TestIncrementalWriteBarrier(map, new_map, InternalIndex(2), + InternalIndex(1)); } } diff --git a/deps/v8/test/cctest/torque/test-torque.cc b/deps/v8/test/cctest/torque/test-torque.cc index 184a86794634fb..5cf70f3374796c 100644 --- a/deps/v8/test/cctest/torque/test-torque.cc +++ b/deps/v8/test/cctest/torque/test-torque.cc @@ -26,7 +26,6 @@ namespace compiler { namespace { -using Label = CodeAssemblerLabel; using Variable = CodeAssemblerVariable; class TestTorqueAssembler : public CodeStubAssembler { diff --git a/deps/v8/test/cctest/wasm/OWNERS b/deps/v8/test/cctest/wasm/OWNERS index dc68b3973351c0..16b08f3b3b743a 100644 --- a/deps/v8/test/cctest/wasm/OWNERS +++ b/deps/v8/test/cctest/wasm/OWNERS @@ -1,5 +1,5 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org titzer@chromium.org # COMPONENT: Blink>JavaScript>WebAssembly diff --git a/deps/v8/test/cctest/wasm/test-grow-memory.cc b/deps/v8/test/cctest/wasm/test-grow-memory.cc new file mode 100644 index 00000000000000..a188707caef79e --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-grow-memory.cc @@ -0,0 +1,131 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/wasm/wasm-objects-inl.h" +#include "src/wasm/wasm-opcodes.h" + +#include "src/wasm/wasm-module-builder.h" +#include "test/cctest/cctest.h" +#include "test/cctest/manually-externalized-buffer.h" +#include "test/common/wasm/flag-utils.h" +#include "test/common/wasm/test-signatures.h" +#include "test/common/wasm/wasm-macro-gen.h" +#include "test/common/wasm/wasm-module-runner.h" + +namespace v8 { +namespace internal { +namespace wasm { +namespace test_grow_memory { + +using testing::CompileAndInstantiateForTesting; +using v8::internal::testing::ManuallyExternalizedBuffer; + +namespace { +void ExportAsMain(WasmFunctionBuilder* f) { + f->builder()->AddExport(CStrVector("main"), f); +} +#define EMIT_CODE_WITH_END(f, code) \ + do { \ + f->EmitCode(code, sizeof(code)); \ + f->Emit(kExprEnd); \ + } while (false) + +void Cleanup(Isolate* isolate = CcTest::InitIsolateOnce()) { + // By sending a low memory notifications, we will try hard to collect all + // garbage and will therefore also invoke all weak callbacks of actually + // unreachable persistent handles. + reinterpret_cast<v8::Isolate*>(isolate)->LowMemoryNotification(); +} +} // namespace + +TEST(GrowMemDetaches) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<WasmMemoryObject> memory_object = + WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared) + .ToHandleChecked(); + Handle<JSArrayBuffer> buffer(memory_object->array_buffer(), isolate); + int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK_EQ(16, result); + CHECK_NE(*buffer, memory_object->array_buffer()); + CHECK(buffer->was_detached()); + } + Cleanup(); +} + +TEST(Externalized_GrowMemMemSize) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<WasmMemoryObject> memory_object = + WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared) + .ToHandleChecked(); + ManuallyExternalizedBuffer external( + handle(memory_object->array_buffer(), isolate)); + int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0); + CHECK_EQ(16, result); + CHECK_NE(*external.buffer_, memory_object->array_buffer()); + CHECK(external.buffer_->was_detached()); + } + Cleanup(); +} + +TEST(Run_WasmModule_Buffer_Externalized_GrowMem) { + { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + TestSignatures sigs; + v8::internal::AccountingAllocator allocator; + Zone zone(&allocator, ZONE_NAME); + + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); + ExportAsMain(f); + byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP, + WASM_MEMORY_SIZE}; + EMIT_CODE_WITH_END(f, code); + + ZoneBuffer buffer(&zone); + builder->WriteTo(&buffer); + testing::SetupIsolateForWasmModule(isolate); + ErrorThrower thrower(isolate, "Test"); + const Handle<WasmInstanceObject> instance = + CompileAndInstantiateForTesting( + isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end())) + .ToHandleChecked(); + Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); + + // Fake the Embedder flow by externalizing the array buffer. + ManuallyExternalizedBuffer external1( + handle(memory_object->array_buffer(), isolate)); + + // Grow using the API. + uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4); + CHECK_EQ(16, result); + CHECK(external1.buffer_->was_detached()); // growing always detaches + CHECK_EQ(0, external1.buffer_->byte_length()); + + CHECK_NE(*external1.buffer_, memory_object->array_buffer()); + + // Fake the Embedder flow by externalizing the array buffer. + ManuallyExternalizedBuffer external2( + handle(memory_object->array_buffer(), isolate)); + + // Grow using an internal WASM bytecode. + result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr); + CHECK_EQ(26, result); + CHECK(external2.buffer_->was_detached()); // growing always detaches + CHECK_EQ(0, external2.buffer_->byte_length()); + CHECK_NE(*external2.buffer_, memory_object->array_buffer()); + } + Cleanup(); +} + +} // namespace test_grow_memory +} // namespace wasm +} // namespace internal +} // namespace v8 + +#undef EMIT_CODE_WITH_END diff --git a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc index 556d74daefc411..d3aa75a64ef7d7 100644 --- a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc +++ b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc @@ -36,7 +36,7 @@ constexpr size_t kThunkBufferSize = AssemblerBase::kMinimalBufferSize; #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 constexpr uint32_t kAvailableBufferSlots = - (kMaxWasmCodeMemory - kJumpTableSize) / kThunkBufferSize; + (kMaxWasmCodeSpaceSize - kJumpTableSize) / kThunkBufferSize; constexpr uint32_t kBufferSlotStartOffset = RoundUp<kThunkBufferSize>(kJumpTableSize); #else @@ -49,7 +49,7 @@ Address AllocateJumpTableThunk( std::vector<std::unique_ptr<TestingAssemblerBuffer>>* thunk_buffers) { #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64 // To guarantee that the branch range lies within the near-call range, - // generate the thunk in the same (kMaxWasmCodeMemory-sized) buffer as the + // generate the thunk in the same (kMaxWasmCodeSpaceSize-sized) buffer as the // jump_target itself. // // Allocate a slot that we haven't already used. This is necessary because @@ -181,11 +181,13 @@ class JumpTablePatcher : public v8::base::Thread { // Then, repeatedly patch the jump table to jump to one of the two thunks. constexpr int kNumberOfPatchIterations = 64; for (int i = 0; i < kNumberOfPatchIterations; ++i) { - TRACE(" patcher %p patch slot " V8PRIxPTR_FMT " to thunk #%d\n", this, - slot_address, i % 2); + TRACE(" patcher %p patch slot " V8PRIxPTR_FMT + " to thunk #%d (" V8PRIxPTR_FMT ")\n", + this, slot_address, i % 2, thunks_[i % 2]); base::MutexGuard jump_table_guard(jump_table_mutex_); JumpTableAssembler::PatchJumpTableSlot( - slot_start_, slot_index_, thunks_[i % 2], WasmCode::kFlushICache); + slot_start_ + JumpTableAssembler::JumpSlotIndexToOffset(slot_index_), + kNullAddress, thunks_[i % 2]); } TRACE("Patcher %p is stopping ...\n", this); } @@ -219,11 +221,8 @@ TEST(JumpTablePatchingStress) { // is not reliable enough to guarantee that we can always achieve this with // separate allocations, so for Arm64 we generate all code in a single // kMaxMasmCodeMemory-sized chunk. - // - // TODO(wasm): Currently {kMaxWasmCodeMemory} limits code sufficiently, so - // that the jump table only supports {near_call} distances. - STATIC_ASSERT(kMaxWasmCodeMemory >= kJumpTableSize); - auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeMemory); + STATIC_ASSERT(kMaxWasmCodeSpaceSize >= kJumpTableSize); + auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeSpaceSize); byte* thunk_slot_buffer = buffer->start() + kBufferSlotStartOffset; #else auto buffer = AllocateAssemblerBuffer(kJumpTableSize); @@ -242,8 +241,9 @@ TEST(JumpTablePatchingStress) { std::vector<std::unique_ptr<TestingAssemblerBuffer>> thunk_buffers; // Patch the jump table slot to jump to itself. This will later be patched // by the patchers. - JumpTableAssembler::PatchJumpTableSlot( - slot_start, slot, slot_start + slot_offset, WasmCode::kFlushICache); + Address slot_addr = + slot_start + JumpTableAssembler::JumpSlotIndexToOffset(slot); + JumpTableAssembler::PatchJumpTableSlot(slot_addr, kNullAddress, slot_addr); // For each patcher, generate two thunks where this patcher can emit code // which finally jumps back to {slot} in the jump table. std::vector<Address> patcher_thunks; diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc index 3f96f8720fd434..09d1eb7fda07fc 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc @@ -1502,7 +1502,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) { std::vector<byte> code; for (byte p = 0; p < num_params; p++) { - ADD_CODE(code, kExprGetLocal, p); + ADD_CODE(code, kExprLocalGet, p); } ADD_CODE(code, kExprI32Const, 0); ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO); @@ -1563,7 +1563,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) { // Store the result in a local. byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result)); - ADD_CODE(code, kExprSetLocal, local_index); + ADD_CODE(code, kExprLocalSet, local_index); // Store the result in memory. ADD_CODE(code, diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc index e794c00ece6042..d2ac3434dfff8b 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc @@ -13,11 +13,10 @@ namespace wasm { namespace test_run_wasm_bulk_memory { namespace { -void CheckMemoryEquals( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - size_t index, const std::vector<byte>& expected) { - const byte* mem_start = builder.raw_mem_start<byte>(); - const byte* mem_end = builder.raw_mem_end<byte>(); +void CheckMemoryEquals(TestingModuleBuilder* builder, size_t index, + const std::vector<byte>& expected) { + const byte* mem_start = builder->raw_mem_start<byte>(); + const byte* mem_end = builder->raw_mem_end<byte>(); size_t mem_size = mem_end - mem_start; CHECK_LE(index, mem_size); CHECK_LE(index + expected.size(), mem_size); @@ -26,11 +25,10 @@ void CheckMemoryEquals( } } -void CheckMemoryEqualsZero( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - size_t index, size_t length) { - const byte* mem_start = builder.raw_mem_start<byte>(); - const byte* mem_end = builder.raw_mem_end<byte>(); +void CheckMemoryEqualsZero(TestingModuleBuilder* builder, size_t index, + size_t length) { + const byte* mem_start = builder->raw_mem_start<byte>(); + const byte* mem_end = builder->raw_mem_end<byte>(); size_t mem_size = mem_end - mem_start; CHECK_LE(index, mem_size); CHECK_LE(index + length, mem_size); @@ -39,12 +37,11 @@ void CheckMemoryEqualsZero( } } -void CheckMemoryEqualsFollowedByZeroes( - TestingModuleBuilder& builder, // NOLINT(runtime/references) - const std::vector<byte>& expected) { +void CheckMemoryEqualsFollowedByZeroes(TestingModuleBuilder* builder, + const std::vector<byte>& expected) { CheckMemoryEquals(builder, 0, expected); CheckMemoryEqualsZero(builder, expected.size(), - builder.mem_size() - expected.size()); + builder->mem_size() - expected.size()); } } // namespace @@ -60,24 +57,24 @@ WASM_EXEC_TEST(MemoryInit) { kExprI32Const, 0); // All zeroes. - CheckMemoryEqualsZero(r.builder(), 0, kWasmPageSize); + CheckMemoryEqualsZero(&r.builder(), 0, kWasmPageSize); // Copy all bytes from data segment 0, to memory at [10, 20). CHECK_EQ(0, r.Call(10, 0, 10)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy bytes in range [5, 10) from data segment 0, to memory at [0, 5). CHECK_EQ(0, r.Call(0, 5, 5)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy 0 bytes does nothing. CHECK_EQ(0, r.Call(10, 1, 0)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); // Copy 0 at end of memory region or data segment is OK. @@ -100,12 +97,12 @@ WASM_EXEC_TEST(MemoryInitOutOfBoundsData) { // Write all values up to the out-of-bounds write. CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, 0, 6)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 1, 2, 3, 4}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 1, 2, 3, 4}); // Write all values up to the out-of-bounds read. r.builder().BlankMemory(); CHECK_EQ(0xDEADBEEF, r.Call(0, 5, 6)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {5, 6, 7, 8, 9}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {5, 6, 7, 8, 9}); } WASM_EXEC_TEST(MemoryInitOutOfBounds) { @@ -155,13 +152,13 @@ WASM_EXEC_TEST(MemoryCopy) { // Copy from [1, 8] to [10, 16]. CHECK_EQ(0, r.Call(10, 1, 8)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77}); // Copy 0 bytes does nothing. CHECK_EQ(0, r.Call(10, 2, 0)); CheckMemoryEqualsFollowedByZeroes( - r.builder(), + &r.builder(), {0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77}); // Copy 0 at end of memory region is OK. @@ -184,12 +181,12 @@ WASM_EXEC_TEST(MemoryCopyOverlapping) { // Copy from [0, 3] -> [2, 5]. The copy must not overwrite 30 before copying // it (i.e. cannot copy forward in this case). CHECK_EQ(0, r.Call(2, 0, 3)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 10, 20, 30}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 10, 20, 30}); // Copy from [2, 5] -> [0, 3]. The copy must not write the first 10 (i.e. // cannot copy backward in this case). CHECK_EQ(0, r.Call(0, 2, 3)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 30, 20, 30}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 30, 20, 30}); } WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) { @@ -209,21 +206,21 @@ WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) { // Copy with source < destination. Copy would happen backwards, // but the first byte to copy is out-of-bounds, so no data should be written. CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, 6)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); // Copy overlapping with destination < source. Copy will happen forwards, up // to the out-of-bounds access. r.builder().BlankMemory(); memcpy(mem + last_5_bytes, data, 5); CHECK_EQ(0xDEADBEEF, r.Call(0, last_5_bytes, kWasmPageSize)); - CheckMemoryEquals(r.builder(), 0, {11, 22, 33, 44, 55}); + CheckMemoryEquals(&r.builder(), 0, {11, 22, 33, 44, 55}); // Copy overlapping with source < destination. Copy would happen backwards, // but the first byte to copy is out-of-bounds, so no data should be written. r.builder().BlankMemory(); memcpy(mem, data, 5); CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, kWasmPageSize)); - CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); + CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0}); } WASM_EXEC_TEST(MemoryCopyOutOfBounds) { @@ -265,15 +262,15 @@ WASM_EXEC_TEST(MemoryFill) { WASM_MEMORY_FILL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)), kExprI32Const, 0); CHECK_EQ(0, r.Call(1, 33, 5)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), {0, 33, 33, 33, 33, 33}); + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 33, 33}); CHECK_EQ(0, r.Call(4, 66, 4)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 66, 66, 66, 66}); // Fill 0 bytes does nothing. CHECK_EQ(0, r.Call(4, 66, 0)); - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 66, 66, 66, 66}); // Fill 0 at end of memory region is OK. @@ -290,7 +287,7 @@ WASM_EXEC_TEST(MemoryFillValueWrapsToByte) { kExprI32Const, 0); CHECK_EQ(0, r.Call(0, 1000, 3)); const byte expected = 1000 & 255; - CheckMemoryEqualsFollowedByZeroes(r.builder(), + CheckMemoryEqualsFollowedByZeroes(&r.builder(), {expected, expected, expected}); } @@ -304,7 +301,7 @@ WASM_EXEC_TEST(MemoryFillOutOfBoundsData) { kExprI32Const, 0); const byte v = 123; CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, v, 999)); - CheckMemoryEquals(r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v}); + CheckMemoryEquals(&r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v}); } WASM_EXEC_TEST(MemoryFillOutOfBounds) { @@ -408,14 +405,13 @@ void CheckTable(Isolate* isolate, Handle<WasmTableObject> table, Args... args) { template <typename WasmRunner, typename... Args> void CheckTableCall(Isolate* isolate, Handle<WasmTableObject> table, - WasmRunner& r, // NOLINT(runtime/references) - uint32_t function_index, Args... args) { + WasmRunner* r, uint32_t function_index, Args... args) { uint32_t args_length = static_cast<uint32_t>(sizeof...(args)); CHECK_EQ(table->current_length(), args_length); double expected[] = {args...}; for (uint32_t i = 0; i < args_length; ++i) { Handle<Object> buffer[] = {isolate->factory()->NewNumber(i)}; - r.CheckCallApplyViaJS(expected[i], function_index, buffer, 1); + r->CheckCallApplyViaJS(expected[i], function_index, buffer, 1); } } } // namespace @@ -462,7 +458,7 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) { isolate); const double null = 0xDEADBEEF; - CheckTableCall(isolate, table, r, call_index, null, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null); // 0 count is ok in bounds, and at end of regions. r.CheckCallViaJS(0, 0, 0, 0); @@ -471,19 +467,19 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) { // Test actual writes. r.CheckCallViaJS(0, 0, 0, 1); - CheckTableCall(isolate, table, r, call_index, 0, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, null, null, null, null); r.CheckCallViaJS(0, 0, 0, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, null, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, 1, null, null, null); r.CheckCallViaJS(0, 0, 0, 3); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, null, null); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, null, null); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 0, 1); r.CheckCallViaJS(0, 3, 1, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 1, 2); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 1, 2); r.CheckCallViaJS(0, 3, 2, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 2, 3); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 2, 3); r.CheckCallViaJS(0, 3, 3, 2); - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); } WASM_EXEC_TEST(TableInitElems0) { TestTableInitElems(execution_tier, 0); } @@ -534,15 +530,15 @@ void TestTableInitOob(ExecutionTier execution_tier, int table_index) { isolate); const double null = 0xDEADBEEF; - CheckTableCall(isolate, table, r, call_index, null, null, null, null, null); + CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null); // Write all values up to the out-of-bounds write. r.CheckCallViaJS(0xDEADBEEF, 3, 0, 3); - CheckTableCall(isolate, table, r, call_index, null, null, null, 0, 1); + CheckTableCall(isolate, table, &r, call_index, null, null, null, 0, 1); // Write all values up to the out-of-bounds read. r.CheckCallViaJS(0xDEADBEEF, 0, 3, 3); - CheckTableCall(isolate, table, r, call_index, 3, 4, null, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 3, 4, null, 0, 1); // 0-count is never oob. r.CheckCallViaJS(0, kTableSize + 1, 0, 0); @@ -696,21 +692,21 @@ void TestTableCopyCalls(ExecutionTier execution_tier, int table_dst, isolate); if (table_dst == table_src) { - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 1); - CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 1, 2); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 1, 2); } else { - CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 1); - CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4); r.CheckCallViaJS(0, 0, 1, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4); r.CheckCallViaJS(0, 3, 0, 2); - CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 0, 1); + CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 0, 1); } } diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc index 4c1842b53718cb..1b64135cb80ba0 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc @@ -278,7 +278,7 @@ TEST(Breakpoint_I32Add) { static const int kNumBreakpoints = 3; byte code[] = {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; std::unique_ptr<int[]> offsets = - Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal, + Find(code, sizeof(code), kNumBreakpoints, kExprLocalGet, kExprLocalGet, kExprI32Add); WasmRunner<int32_t, uint32_t, uint32_t> r(ExecutionTier::kInterpreter); diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc index 51d97650d4cf43..5f70ab6c7b8a77 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc @@ -11,7 +11,6 @@ #include "src/utils/version.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" @@ -943,154 +942,6 @@ TEST(MemoryWithOOBEmptyDataSegment) { Cleanup(); } -// Utility to free the allocated memory for a buffer that is manually -// externalized in a test. -struct ManuallyExternalizedBuffer { - Isolate* isolate_; - Handle<JSArrayBuffer> buffer_; - void* allocation_base_; - size_t allocation_length_; - bool const should_free_; - - ManuallyExternalizedBuffer(JSArrayBuffer buffer, Isolate* isolate) - : isolate_(isolate), - buffer_(buffer, isolate), - allocation_base_(buffer.allocation_base()), - allocation_length_(buffer.allocation_length()), - should_free_(!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory( - buffer.backing_store())) { - if (!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory( - buffer.backing_store())) { - v8::Utils::ToLocal(buffer_)->Externalize(); - } - } - ~ManuallyExternalizedBuffer() { - if (should_free_) { - buffer_->FreeBackingStoreFromMainThread(); - } - } -}; - -TEST(Run_WasmModule_Buffer_Externalized_GrowMem) { - { - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - TestSignatures sigs; - v8::internal::AccountingAllocator allocator; - Zone zone(&allocator, ZONE_NAME); - - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); - ExportAsMain(f); - byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP, - WASM_MEMORY_SIZE}; - EMIT_CODE_WITH_END(f, code); - - ZoneBuffer buffer(&zone); - builder->WriteTo(&buffer); - testing::SetupIsolateForWasmModule(isolate); - ErrorThrower thrower(isolate, "Test"); - const Handle<WasmInstanceObject> instance = - CompileAndInstantiateForTesting( - isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end())) - .ToHandleChecked(); - Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate); - - // Fake the Embedder flow by externalizing the array buffer. - ManuallyExternalizedBuffer buffer1(memory_object->array_buffer(), isolate); - - // Grow using the API. - uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4); - CHECK_EQ(16, result); - CHECK(buffer1.buffer_->was_detached()); // growing always detaches - CHECK_EQ(0, buffer1.buffer_->byte_length()); - - CHECK_NE(*buffer1.buffer_, memory_object->array_buffer()); - - // Fake the Embedder flow by externalizing the array buffer. - ManuallyExternalizedBuffer buffer2(memory_object->array_buffer(), isolate); - - // Grow using an internal WASM bytecode. - result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr); - CHECK_EQ(26, result); - CHECK(buffer2.buffer_->was_detached()); // growing always detaches - CHECK_EQ(0, buffer2.buffer_->byte_length()); - CHECK_NE(*buffer2.buffer_, memory_object->array_buffer()); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_GrowMemMemSize) { - { - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - Handle<WasmMemoryObject> mem_obj = - WasmMemoryObject::New(isolate, buffer, 100); - auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); - int32_t result = WasmMemoryObject::Grow(isolate, mem_obj, 0); - CHECK_EQ(16, result); - constexpr bool is_wasm_memory = true; - const JSArrayBuffer::Allocation allocation{contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory}; - JSArrayBuffer::FreeBackingStore(isolate, allocation); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_Detach) { - { - // Regression test for - // https://bugs.chromium.org/p/chromium/issues/detail?id=731046 - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - auto const contents = v8::Utils::ToLocal(buffer)->Externalize(); - wasm::DetachMemoryBuffer(isolate, buffer, true); - constexpr bool is_wasm_memory = true; - const JSArrayBuffer::Allocation allocation{contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory}; - JSArrayBuffer::FreeBackingStore(isolate, allocation); - } - Cleanup(); -} - -TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) { - // Regresion test for https://crbug.com/813876 - Isolate* isolate = CcTest::InitIsolateOnce(); - HandleScope scope(isolate); - Handle<JSArrayBuffer> buffer; - CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer)); - Handle<WasmMemoryObject> mem = WasmMemoryObject::New(isolate, buffer, 128); - auto contents = v8::Utils::ToLocal(buffer)->Externalize(); - WasmMemoryObject::Grow(isolate, mem, 0); - constexpr bool is_wasm_memory = true; - JSArrayBuffer::FreeBackingStore( - isolate, JSArrayBuffer::Allocation(contents.AllocationBase(), - contents.AllocationLength(), - contents.Data(), is_wasm_memory)); - // Make sure we can write to the buffer without crashing - uint32_t* int_buffer = - reinterpret_cast<uint32_t*>(mem->array_buffer().backing_store()); - int_buffer[0] = 0; -} - -#if V8_TARGET_ARCH_64_BIT -TEST(Run_WasmModule_Reclaim_Memory) { - // Make sure we can allocate memories without running out of address space. - Isolate* isolate = CcTest::InitIsolateOnce(); - Handle<JSArrayBuffer> buffer; - for (int i = 0; i < 256; ++i) { - HandleScope scope(isolate); - CHECK(NewArrayBuffer(isolate, kWasmPageSize).ToHandle(&buffer)); - } -} -#endif - TEST(AtomicOpDisassembly) { { EXPERIMENTAL_FLAG_SCOPE(threads); @@ -1118,12 +969,15 @@ TEST(AtomicOpDisassembly) { ErrorThrower thrower(isolate, "Test"); auto enabled_features = WasmFeaturesFromIsolate(isolate); - MaybeHandle<WasmModuleObject> module_object = - isolate->wasm_engine()->SyncCompile( - isolate, enabled_features, &thrower, - ModuleWireBytes(buffer.begin(), buffer.end())); + Handle<WasmModuleObject> module_object = + isolate->wasm_engine() + ->SyncCompile(isolate, enabled_features, &thrower, + ModuleWireBytes(buffer.begin(), buffer.end())) + .ToHandleChecked(); + NativeModule* native_module = module_object->native_module(); + ModuleWireBytes wire_bytes(native_module->wire_bytes()); - module_object.ToHandleChecked()->DisassembleFunction(0); + DisassembleWasmFunction(native_module->module(), wire_bytes, 0); } Cleanup(); } diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc index b48321df40b554..d76c4c36438976 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc @@ -184,13 +184,20 @@ T UnsignedGreaterEqual(T a, T b) { template <typename T> T LogicalShiftLeft(T a, int shift) { using UnsignedT = typename std::make_unsigned<T>::type; - return static_cast<UnsignedT>(a) << shift; + return static_cast<UnsignedT>(a) << (shift % (sizeof(T) * 8)); } template <typename T> T LogicalShiftRight(T a, int shift) { using UnsignedT = typename std::make_unsigned<T>::type; - return static_cast<UnsignedT>(a) >> shift; + return static_cast<UnsignedT>(a) >> (shift % (sizeof(T) * 8)); +} + +// Define our own ArithmeticShiftRight instead of using the one from utils.h +// because the shift amount needs to be taken modulo lane width. +template <typename T> +T ArithmeticShiftRight(T a, int shift) { + return a >> (shift % (sizeof(T) * 8)); } template <typename T> @@ -279,7 +286,7 @@ T Sqrt(T a) { return std::sqrt(a); } -#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 // only used for F64x2 tests below int64_t Equal(double a, double b) { return a == b ? -1 : 0; } @@ -292,14 +299,106 @@ int64_t GreaterEqual(double a, double b) { return a >= b ? -1 : 0; } int64_t Less(double a, double b) { return a < b ? -1 : 0; } int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +// Only used for qfma and qfms tests below. + +// FMOperation holds the params (a, b, c) for a Multiply-Add or +// Multiply-Subtract operation, and the expected result if the operation was +// fused, rounded only once for the entire operation, or unfused, rounded after +// multiply and again after add/subtract. +template <typename T> +struct FMOperation { + const T a; + const T b; + const T c; + const T fused_result; + const T unfused_result; +}; + +// large_n is large number that overflows T when multiplied by itself, this is a +// useful constant to test fused/unfused behavior. +template <typename T> +constexpr T large_n = T(0); + +template <> +constexpr double large_n<double> = 1e200; + +template <> +constexpr float large_n<float> = 1e20; + +// Fused Multiply-Add performs a + b * c. +template <typename T> +static constexpr FMOperation<T> qfma_array[] = { + {1.0f, 2.0f, 3.0f, 7.0f, 7.0f}, + // fused: a + b * c = -inf + (positive overflow) = -inf + // unfused: a + b * c = -inf + inf = NaN + {-std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>, + -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // fused: a + b * c = inf + (negative overflow) = inf + // unfused: a + b * c = inf + -inf = NaN + {std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>, + std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // NaN + {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}, + // -NaN + {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}}; + +template <typename T> +static constexpr Vector<const FMOperation<T>> qfma_vector() { + return ArrayVector(qfma_array<T>); +} + +// Fused Multiply-Subtract performs a - b * c. +template <typename T> +static constexpr FMOperation<T> qfms_array[]{ + {1.0f, 2.0f, 3.0f, -5.0f, -5.0f}, + // fused: a - b * c = inf - (positive overflow) = inf + // unfused: a - b * c = inf - inf = NaN + {std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>, + std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // fused: a - b * c = -inf - (negative overflow) = -inf + // unfused: a - b * c = -inf - -inf = NaN + {-std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>, + -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()}, + // NaN + {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}, + // -NaN + {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f, + std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}}; + +template <typename T> +static constexpr Vector<const FMOperation<T>> qfms_vector() { + return ArrayVector(qfms_array<T>); +} + +// Fused results only when fma3 feature is enabled, and running on TurboFan. +bool ExpectFused(ExecutionTier tier) { +#ifdef V8_TARGET_ARCH_X64 + return CpuFeatures::IsSupported(FMA3) && (tier == ExecutionTier::kTurbofan); +#else + return (tier == ExecutionTier::kTurbofan); +#endif +} #endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 } // namespace -#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ - WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ - WASM_SIMD_##TYPE##_EXTRACT_LANE( \ - lane_index, WASM_GET_LOCAL(value))), \ +#define WASM_SIMD_CHECK_LANE_S(TYPE, value, LANE_TYPE, lane_value, lane_index) \ + WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ + WASM_SIMD_##TYPE##_EXTRACT_LANE( \ + lane_index, WASM_GET_LOCAL(value))), \ + WASM_RETURN1(WASM_ZERO)) + +// Unsigned Extracts are only available for I8x16, I16x8 types +#define WASM_SIMD_CHECK_LANE_U(TYPE, value, LANE_TYPE, lane_value, lane_index) \ + WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ + WASM_SIMD_##TYPE##_EXTRACT_LANE_U( \ + lane_index, WASM_GET_LOCAL(value))), \ WASM_RETURN1(WASM_ZERO)) #define TO_BYTE(val) static_cast<byte>(val) @@ -338,13 +437,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } #define WASM_SIMD_I16x8_SPLAT(x) WASM_SIMD_SPLAT(I16x8, x) #define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \ - x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane) + x, WASM_SIMD_OP(kExprI16x8ExtractLaneS), TO_BYTE(lane) +#define WASM_SIMD_I16x8_EXTRACT_LANE_U(lane, x) \ + x, WASM_SIMD_OP(kExprI16x8ExtractLaneU), TO_BYTE(lane) #define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \ x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane) #define WASM_SIMD_I8x16_SPLAT(x) WASM_SIMD_SPLAT(I8x16, x) #define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \ - x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane) + x, WASM_SIMD_OP(kExprI8x16ExtractLaneS), TO_BYTE(lane) +#define WASM_SIMD_I8x16_EXTRACT_LANE_U(lane, x) \ + x, WASM_SIMD_OP(kExprI8x16ExtractLaneU), TO_BYTE(lane) #define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \ x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane) @@ -357,8 +460,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; } #define WASM_SIMD_LOAD_MEM(index) \ index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, ZERO_OFFSET +#define WASM_SIMD_LOAD_MEM_OFFSET(offset, index) \ + index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, offset #define WASM_SIMD_STORE_MEM(index, val) \ index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, ZERO_OFFSET +#define WASM_SIMD_STORE_MEM_OFFSET(offset, index, val) \ + index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, offset + +#define WASM_SIMD_F64x2_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfma) +#define WASM_SIMD_F64x2_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfms) +#define WASM_SIMD_F32x4_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfma) +#define WASM_SIMD_F32x4_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfms) // Runs tests of compiled code, using the interpreter as a reference. #define WASM_SIMD_COMPILED_TEST(name) \ @@ -589,10 +701,15 @@ void RunF32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WASM_SIMD_TEST(F32x4Abs) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Abs, std::abs); } + WASM_SIMD_TEST(F32x4Neg) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Neg, Negate); } +WASM_SIMD_TEST(F32x4Sqrt) { + RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Sqrt, Sqrt); +} + WASM_SIMD_TEST(F32x4RecipApprox) { RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipApprox, base::Recip, false /* !exact */); @@ -724,6 +841,57 @@ WASM_SIMD_TEST(F32x4Le) { RunF32x4CompareOpTest(execution_tier, lower_simd, kExprF32x4Le, LessEqual); } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +WASM_SIMD_TEST_NO_LOWERING(F32x4Qfma) { + WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd); + // Set up global to hold mask output. + float* g = r.builder().AddGlobal<float>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMA( + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<float> x : qfma_vector<float>()) { + r.Call(x.a, x.b, x.c); + float expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 4; i++) { + float actual = ReadLittleEndianValue<float>(&g[i]); + CheckFloatResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} + +WASM_SIMD_TEST_NO_LOWERING(F32x4Qfms) { + WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd); + // Set up global to hold mask output. + float* g = r.builder().AddGlobal<float>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMS( + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<float> x : qfms_vector<float>()) { + r.Call(x.a, x.b, x.c); + float expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 4; i++) { + float actual = ReadLittleEndianValue<float>(&g[i]); + CheckFloatResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2Splat) { WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd); @@ -803,7 +971,8 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2Neg) { void RunI64x2ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int64ShiftOp expected_op) { - for (int shift = 1; shift < 64; shift++) { + // Intentionally shift by 64, should be no-op. + for (int shift = 1; shift <= 64; shift++) { WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd); int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128); byte value = 0; @@ -918,6 +1087,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2GeU) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2GeU, UnsignedGreaterEqual); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { WasmRunner<int32_t, double> r(execution_tier, lower_simd); @@ -941,6 +1111,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) { WasmRunner<int64_t> r(execution_tier, lower_simd); BUILD(r, WASM_IF_ELSE_L( @@ -950,6 +1121,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) { WASM_I64V(1), WASM_I64V(0))); CHECK_EQ(1, r.Call()); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { WasmRunner<double, double> r(execution_tier, lower_simd); @@ -973,6 +1145,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) { WasmRunner<int64_t> r(execution_tier, lower_simd); BUILD(r, WASM_IF_ELSE_L( @@ -982,6 +1155,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) { WASM_I64V(1), WASM_I64V(0))); CHECK_EQ(1, r.Call()); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(F64x2ReplaceLane) { WasmRunner<int32_t> r(execution_tier, lower_simd); @@ -1124,6 +1298,10 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Neg) { RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Neg, Negate); } +WASM_SIMD_TEST_NO_LOWERING(F64x2Sqrt) { + RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Sqrt, Sqrt); +} + void RunF64x2BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, DoubleBinOp expected_op) { WasmRunner<int32_t, double, double> r(execution_tier, lower_simd); @@ -1249,12 +1427,14 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Max) { RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Max, JSMax); } -#if V8_TARGET_ARCH_X64 +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 WASM_SIMD_TEST_NO_LOWERING(I64x2Mul) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Mul, base::MulWithWraparound); } +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#if V8_TARGET_ARCH_X64 WASM_SIMD_TEST_NO_LOWERING(I64x2MinS) { RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2MinS, Minimum); } @@ -1273,7 +1453,57 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2MaxU) { UnsignedMaximum); } #endif // V8_TARGET_ARCH_X64 + +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +WASM_SIMD_TEST_NO_LOWERING(F64x2Qfma) { + WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd); + // Set up global to hold mask output. + double* g = r.builder().AddGlobal<double>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMA( + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<double> x : qfma_vector<double>()) { + r.Call(x.a, x.b, x.c); + double expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 2; i++) { + double actual = ReadLittleEndianValue<double>(&g[i]); + CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} + +WASM_SIMD_TEST_NO_LOWERING(F64x2Qfms) { + WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd); + // Set up global to hold mask output. + double* g = r.builder().AddGlobal<double>(kWasmS128); + // Build fn to splat test values, perform compare op, and write the result. + byte value1 = 0, value2 = 1, value3 = 2; + BUILD(r, + WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMS( + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)), + WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))), + WASM_ONE); + + for (FMOperation<double> x : qfms_vector<double>()) { + r.Call(x.a, x.b, x.c); + double expected = + ExpectFused(execution_tier) ? x.fused_result : x.unfused_result; + for (int i = 0; i < 2; i++) { + double actual = ReadLittleEndianValue<double>(&g[i]); + CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */); + } + } +} #endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 WASM_SIMD_TEST(I32x4Splat) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); @@ -1652,7 +1882,8 @@ WASM_SIMD_TEST(I32x4GeU) { void RunI32x4ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int32ShiftOp expected_op) { - for (int shift = 1; shift < 32; shift++) { + // Intentionally shift by 32, should be no-op. + for (int shift = 1; shift <= 32; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int32_t* g = r.builder().AddGlobal<int32_t>(kWasmS128); byte value = 0; @@ -1902,7 +2133,8 @@ WASM_SIMD_TEST(I16x8LeU) { void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int16ShiftOp expected_op) { - for (int shift = 1; shift < 16; shift++) { + // Intentionally shift by 16, should be no-op. + for (int shift = 1; shift <= 16; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int16_t* g = r.builder().AddGlobal<int16_t>(kWasmS128); byte value = 0; @@ -1917,7 +2149,7 @@ void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, FOR_INT16_INPUTS(x) { r.Call(x); - float expected = expected_op(x, shift); + int16_t expected = expected_op(x, shift); for (int i = 0; i < 8; i++) { CHECK_EQ(expected, ReadLittleEndianValue<int16_t>(&g[i])); } @@ -2118,7 +2350,8 @@ WASM_SIMD_TEST(I8x16Mul) { void RunI8x16ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd, WasmOpcode opcode, Int8ShiftOp expected_op) { - for (int shift = 1; shift < 8; shift++) { + // Intentionally shift by 8, should be no-op. + for (int shift = 1; shift <= 8; shift++) { WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); int8_t* g = r.builder().AddGlobal<int8_t>(kWasmS128); byte value = 0; @@ -2184,10 +2417,10 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16ShrU) { format, WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2), \ WASM_SIMD_BINOP(kExprI##format##Ne, WASM_GET_LOCAL(mask), \ WASM_GET_LOCAL(zero)))), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 1), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 1), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 2), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \ \ CHECK_EQ(1, r.Call(0x12, 0x34)); \ } @@ -2222,10 +2455,10 @@ WASM_SIMD_SELECT_TEST(8x16) WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(src1), \ WASM_GET_LOCAL(src2), \ WASM_GET_LOCAL(mask))), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 1), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 2), \ - WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 1), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 2), \ + WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \ \ CHECK_EQ(1, r.Call(0x12, 0x34, 0x32)); \ } @@ -2454,6 +2687,62 @@ WASM_SIMD_TEST(S8x16Concat) { } } +#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 +struct SwizzleTestArgs { + const Shuffle input; + const Shuffle indices; + const Shuffle expected; +}; + +static constexpr SwizzleTestArgs swizzle_test_args[] = { + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}, + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {15, 0, 14, 1, 13, 2, 12, 3, 11, 4, 10, 5, 9, 6, 8, 7}, + {0, 15, 1, 14, 2, 13, 3, 12, 4, 11, 5, 10, 6, 9, 7, 8}}, + {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}, + {15, 13, 11, 9, 7, 5, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0}}, + // all indices are out of range + {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {16, 17, 18, 19, 20, 124, 125, 126, 127, -1, -2, -3, -4, -5, -6, -7}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; + +static constexpr Vector<const SwizzleTestArgs> swizzle_test_vector = + ArrayVector(swizzle_test_args); + +WASM_SIMD_TEST(S8x16Swizzle) { + // RunBinaryLaneOpTest set up the two globals to be consecutive integers, + // [0-15] and [16-31]. Using [0-15] as the indices will not sufficiently test + // swizzle since the expected result is a no-op, using [16-31] will result in + // all 0s. + WasmRunner<int32_t> r(execution_tier, lower_simd); + static const int kElems = kSimd128Size / sizeof(uint8_t); + uint8_t* dst = r.builder().AddGlobal<uint8_t>(kWasmS128); + uint8_t* src0 = r.builder().AddGlobal<uint8_t>(kWasmS128); + uint8_t* src1 = r.builder().AddGlobal<uint8_t>(kWasmS128); + BUILD( + r, + WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(kExprS8x16Swizzle, WASM_GET_GLOBAL(1), + WASM_GET_GLOBAL(2))), + WASM_ONE); + + for (SwizzleTestArgs si : swizzle_test_vector) { + for (int i = 0; i < kElems; i++) { + WriteLittleEndianValue<uint8_t>(&src0[i], si.input[i]); + WriteLittleEndianValue<uint8_t>(&src1[i], si.indices[i]); + } + + CHECK_EQ(1, r.Call()); + + for (int i = 0; i < kElems; i++) { + CHECK_EQ(ReadLittleEndianValue<uint8_t>(&dst[i]), si.expected[i]); + } + } +} +#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 + // Combine 3 shuffles a, b, and c by applying both a and b and then applying c // to those two results. Shuffle Combine(const Shuffle& a, const Shuffle& b, const Shuffle& c) { @@ -2487,7 +2776,7 @@ void AppendShuffle(const Shuffle& shuffle, std::vector<byte>* buffer) { for (size_t i = 0; i < kSimd128Size; ++i) buffer->push_back((shuffle[i])); } -void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references) +void BuildShuffle(const std::vector<Shuffle>& shuffles, std::vector<byte>* buffer) { // Perform the leaf shuffles on globals 0 and 1. size_t row_index = (shuffles.size() - 1) / 2; @@ -2504,7 +2793,7 @@ void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references) } row_index /= 2; } while (row_index != 0); - byte epilog[] = {kExprSetGlobal, static_cast<byte>(0), WASM_ONE}; + byte epilog[] = {kExprGlobalSet, static_cast<byte>(0), WASM_ONE}; for (size_t j = 0; j < arraysize(epilog); ++j) buffer->push_back(epilog[j]); } @@ -2895,11 +3184,34 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) { r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t)); // Load memory, store it, then reload it and extract the first lane. Use a // non-zero offset into the memory of 1 lane (4 bytes) to test indexing. - BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(4), WASM_SIMD_LOAD_MEM(WASM_I32V(4))), - WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(4)))); + BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(8), WASM_SIMD_LOAD_MEM(WASM_I32V(4))), + WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(8)))); + + FOR_INT32_INPUTS(i) { + int32_t expected = i; + r.builder().WriteMemory(&memory[1], expected); + CHECK_EQ(expected, r.Call()); + } +} + +WASM_SIMD_TEST(SimdLoadStoreLoadMemargOffset) { + WasmRunner<int32_t> r(execution_tier, lower_simd); + int32_t* memory = + r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t)); + constexpr byte offset_1 = 4; + constexpr byte offset_2 = 8; + // Load from memory at offset_1, store to offset_2, load from offset_2, and + // extract first lane. We use non-zero memarg offsets to test offset decoding. + BUILD( + r, + WASM_SIMD_STORE_MEM_OFFSET( + offset_2, WASM_ZERO, WASM_SIMD_LOAD_MEM_OFFSET(offset_1, WASM_ZERO)), + WASM_SIMD_I32x4_EXTRACT_LANE( + 0, WASM_SIMD_LOAD_MEM_OFFSET(offset_2, WASM_ZERO))); FOR_INT32_INPUTS(i) { int32_t expected = i; + // Index 1 of memory (int32_t) will be bytes 4 to 8. r.builder().WriteMemory(&memory[1], expected); CHECK_EQ(expected, r.Call()); } @@ -3040,8 +3352,48 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { UnsignedGreater); } +#define WASM_EXTRACT_I16x8_TEST(Sign, Type) \ + WASM_SIMD_TEST(I16X8ExtractLane##Sign) { \ + WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \ + byte int_val = r.AllocateLocal(kWasmI32); \ + byte simd_val = r.AllocateLocal(kWasmS128); \ + BUILD(r, \ + WASM_SET_LOCAL(simd_val, \ + WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(int_val))), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 0), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 2), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 4), \ + WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 6), WASM_ONE); \ + FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \ + } +WASM_EXTRACT_I16x8_TEST(S, UINT16) WASM_EXTRACT_I16x8_TEST(I, INT16) +#undef WASM_EXTRACT_I16x8_TEST + +#define WASM_EXTRACT_I8x16_TEST(Sign, Type) \ + WASM_SIMD_TEST(I8x16ExtractLane##Sign) { \ + WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \ + byte int_val = r.AllocateLocal(kWasmI32); \ + byte simd_val = r.AllocateLocal(kWasmS128); \ + BUILD(r, \ + WASM_SET_LOCAL(simd_val, \ + WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(int_val))), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 1), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 3), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 5), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 7), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 9), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 10), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 11), \ + WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 13), \ + WASM_ONE); \ + FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \ + } + WASM_EXTRACT_I8x16_TEST(S, UINT8) WASM_EXTRACT_I8x16_TEST(I, INT8) +#undef WASM_EXTRACT_I8x16_TEST + #undef WASM_SIMD_TEST -#undef WASM_SIMD_CHECK_LANE +#undef WASM_SIMD_CHECK_LANE_S +#undef WASM_SIMD_CHECK_LANE_U #undef TO_BYTE #undef WASM_SIMD_OP #undef WASM_SIMD_SPLAT @@ -3064,13 +3416,17 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { #undef WASM_SIMD_I32x4_REPLACE_LANE #undef WASM_SIMD_I16x8_SPLAT #undef WASM_SIMD_I16x8_EXTRACT_LANE +#undef WASM_SIMD_I16x8_EXTRACT_LANE_U #undef WASM_SIMD_I16x8_REPLACE_LANE #undef WASM_SIMD_I8x16_SPLAT #undef WASM_SIMD_I8x16_EXTRACT_LANE +#undef WASM_SIMD_I8x16_EXTRACT_LANE_U #undef WASM_SIMD_I8x16_REPLACE_LANE #undef WASM_SIMD_S8x16_SHUFFLE_OP #undef WASM_SIMD_LOAD_MEM +#undef WASM_SIMD_LOAD_MEM_OFFSET #undef WASM_SIMD_STORE_MEM +#undef WASM_SIMD_STORE_MEM_OFFSET #undef WASM_SIMD_SELECT_TEST #undef WASM_SIMD_NON_CANONICAL_SELECT_TEST #undef WASM_SIMD_COMPILED_TEST @@ -3078,6 +3434,10 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) { #undef WASM_SIMD_TEST_NO_LOWERING #undef WASM_SIMD_ANYTRUE_TEST #undef WASM_SIMD_ALLTRUE_TEST +#undef WASM_SIMD_F64x2_QFMA +#undef WASM_SIMD_F64x2_QFMS +#undef WASM_SIMD_F32x4_QFMA +#undef WASM_SIMD_F32x4_QFMS } // namespace test_run_wasm_simd } // namespace wasm diff --git a/deps/v8/test/cctest/wasm/test-run-wasm.cc b/deps/v8/test/cctest/wasm/test-run-wasm.cc index 26df61ceb8adb4..aa6195b8b3db68 100644 --- a/deps/v8/test/cctest/wasm/test-run-wasm.cc +++ b/deps/v8/test/cctest/wasm/test-run-wasm.cc @@ -49,8 +49,8 @@ WASM_EXEC_TEST(Int32Const_many) { WASM_EXEC_TEST(GraphTrimming) { // This WebAssembly code requires graph trimming in the TurboFan compiler. WasmRunner<int32_t, int32_t> r(execution_tier); - BUILD(r, kExprGetLocal, 0, kExprGetLocal, 0, kExprGetLocal, 0, kExprI32RemS, - kExprI32Eq, kExprGetLocal, 0, kExprI32DivS, kExprUnreachable); + BUILD(r, kExprLocalGet, 0, kExprLocalGet, 0, kExprLocalGet, 0, kExprI32RemS, + kExprI32Eq, kExprLocalGet, 0, kExprI32DivS, kExprUnreachable); r.Call(1); } @@ -1810,18 +1810,18 @@ WASM_EXEC_TEST(CheckMachIntsZero) { BUILD(r, // -- /**/ kExprLoop, kLocalVoid, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprIf, kLocalVoid, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32LoadMem, 0, 0, // -- /* */ kExprIf, kLocalVoid, // -- /* */ kExprI32Const, 127, // -- /* */ kExprReturn, // -- /* */ kExprEnd, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32Const, 4, // -- /* */ kExprI32Sub, // -- - /* */ kExprTeeLocal, 0, // -- + /* */ kExprLocalTee, 0, // -- /* */ kExprBr, DEPTH_0, // -- /* */ kExprEnd, // -- /**/ kExprEnd, // -- @@ -2012,16 +2012,16 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { FunctionSig* sig = WasmOpcodes::Signature(opcode); if (sig->parameter_count() == 1) { - byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode), + byte code[] = {WASM_NO_LOCALS, kExprLocalGet, 0, static_cast<byte>(opcode), WASM_END}; TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code, code + arraysize(code)); } else { CHECK_EQ(2, sig->parameter_count()); byte code[] = {WASM_NO_LOCALS, - kExprGetLocal, + kExprLocalGet, 0, - kExprGetLocal, + kExprLocalGet, 1, static_cast<byte>(opcode), WASM_END}; @@ -2667,7 +2667,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) { // Store the result in a local. byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result)); - ADD_CODE(code, kExprSetLocal, local_index); + ADD_CODE(code, kExprLocalSet, local_index); // Store the result in memory. ADD_CODE(code, @@ -2761,10 +2761,11 @@ void RunMultiReturnSelect(ExecutionTier execution_tier, const T* inputs) { WASM_GET_LOCAL(3)), WASM_DROP); } else { - BUILD(r, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0), - WASM_GET_LOCAL(1), WASM_GET_LOCAL(2), - WASM_GET_LOCAL(3)), - kExprSetLocal, 0, WASM_DROP, WASM_GET_LOCAL(0)); + BUILD(r, + WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0), + WASM_GET_LOCAL(1), WASM_GET_LOCAL(2), + WASM_GET_LOCAL(3)), + kExprLocalSet, 0, WASM_DROP, WASM_GET_LOCAL(0)); } T expected = inputs[k == 0 ? i : j]; @@ -3330,7 +3331,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) { std::vector<byte> code; for (byte p = 0; p < num_params; ++p) { - ADD_CODE(code, kExprGetLocal, p); + ADD_CODE(code, kExprLocalGet, p); } ADD_CODE(code, kExprI32Const, 0); ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO); diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc index 795fa30e725d21..f9089b7821c542 100644 --- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc +++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc @@ -194,17 +194,17 @@ ZoneBuffer GetValidModuleBytes(Zone* zone) { WasmModuleBuilder builder(zone); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 1, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 1, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 2, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 2, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -317,17 +317,17 @@ ZoneBuffer GetModuleWithInvalidSection(Zone* zone) { WasmInitExpr(WasmInitExpr::kGlobalIndex, 12)); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 1, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 1, kExprEnd}; f->EmitCode(code, arraysize(code)); } { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 2, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 2, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -442,7 +442,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByModuleDecoder) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -481,7 +481,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByStreamingDecoder) { uint8_t code[] = { U32V_1(26), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -520,7 +520,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByCompiler) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -679,7 +679,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled1) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -713,7 +713,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled2) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -745,7 +745,7 @@ STREAM_TEST(TestAbortAfterCodeSection1) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -781,7 +781,7 @@ STREAM_TEST(TestAbortAfterCodeSection2) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -815,7 +815,7 @@ STREAM_TEST(TestAbortAfterCompilationError1) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -857,7 +857,7 @@ STREAM_TEST(TestAbortAfterCompilationError2) { uint8_t code[] = { U32V_1(4), // !!! invalid body size !!! U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; uint8_t invalid_code[] = { @@ -934,7 +934,7 @@ STREAM_TEST(TestModuleWithMultipleFunctions) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -970,7 +970,7 @@ STREAM_TEST(TestModuleWithDataSection) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { @@ -1016,7 +1016,7 @@ STREAM_TEST(TestModuleWithImportedFunction) { builder.AddImport(ArrayVector("Test"), sigs.i_iii()); { WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii()); - uint8_t code[] = {kExprGetLocal, 0, kExprEnd}; + uint8_t code[] = {kExprLocalGet, 0, kExprEnd}; f->EmitCode(code, arraysize(code)); } builder.WriteTo(&buffer); @@ -1047,7 +1047,7 @@ STREAM_TEST(TestModuleWithErrorAfterDataSection) { U32V_1(1), // functions count U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, // some code + kExprLocalGet, // some code 0, // some code kExprEnd, // some code kDataSectionCode, // section code @@ -1133,7 +1133,7 @@ STREAM_TEST(TestSetModuleCompiledCallback) { uint8_t code[] = { U32V_1(4), // body size U32V_1(0), // locals count - kExprGetLocal, 0, kExprEnd // body + kExprLocalGet, 0, kExprEnd // body }; const uint8_t bytes[] = { diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc index e287b1139e2891..798e1d46dac07e 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc @@ -22,10 +22,11 @@ namespace wasm { namespace { void CheckLocations( - WasmModuleObject module_object, debug::Location start, debug::Location end, + NativeModule* native_module, debug::Location start, debug::Location end, std::initializer_list<debug::Location> expected_locations_init) { std::vector<debug::BreakLocation> locations; - bool success = module_object.GetPossibleBreakpoints(start, end, &locations); + bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start, + end, &locations); CHECK(success); printf("got %d locations: ", static_cast<int>(locations.size())); @@ -45,10 +46,11 @@ void CheckLocations( } } -void CheckLocationsFail(WasmModuleObject module_object, debug::Location start, +void CheckLocationsFail(NativeModule* native_module, debug::Location start, debug::Location end) { std::vector<debug::BreakLocation> locations; - bool success = module_object.GetPossibleBreakpoints(start, end, &locations); + bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start, + end, &locations); CHECK(!success); } @@ -63,8 +65,12 @@ class BreakHandler : public debug::DebugDelegate { struct BreakPoint { int position; Action action; + std::function<void(void)> pre_action; BreakPoint(int position, Action action) - : position(position), action(action) {} + : position(position), action(action), pre_action([]() {}) {} + BreakPoint(int position, Action action, + std::function<void(void)> pre_action) + : position(position), action(action), pre_action(pre_action) {} }; explicit BreakHandler(Isolate* isolate, @@ -96,6 +102,7 @@ class BreakHandler : public debug::DebugDelegate { auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasmInterpreted(); CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset()); + expected_breaks_[count_].pre_action(); Action next_action = expected_breaks_[count_].action; switch (next_action) { case Continue: @@ -112,22 +119,21 @@ class BreakHandler : public debug::DebugDelegate { } }; -void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references) - int function_index, int byte_offset, - int expected_set_byte_offset = -1) { +Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index, + int byte_offset, + int expected_set_byte_offset = -1) { int func_offset = - runner.builder().GetFunctionAt(function_index)->code.offset(); + runner->builder().GetFunctionAt(function_index)->code.offset(); int code_offset = func_offset + byte_offset; if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset; - Handle<WasmInstanceObject> instance = runner.builder().instance_object(); - Handle<WasmModuleObject> module_object(instance->module_object(), - runner.main_isolate()); + Handle<WasmInstanceObject> instance = runner->builder().instance_object(); + Handle<Script> script(instance->module_object().script(), + runner->main_isolate()); static int break_index = 0; Handle<BreakPoint> break_point = - runner.main_isolate()->factory()->NewBreakPoint( - break_index++, runner.main_isolate()->factory()->empty_string()); - CHECK(WasmModuleObject::SetBreakPoint(module_object, &code_offset, - break_point)); + runner->main_isolate()->factory()->NewBreakPoint( + break_index++, runner->main_isolate()->factory()->empty_string()); + CHECK(WasmModuleObject::SetBreakPoint(script, &code_offset, break_point)); int set_byte_offset = code_offset - func_offset; CHECK_EQ(expected_set_byte_offset, set_byte_offset); // Also set breakpoint on the debug info of the instance directly, since the @@ -135,6 +141,24 @@ void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references) Handle<WasmDebugInfo> debug_info = WasmInstanceObject::GetOrCreateDebugInfo(instance); WasmDebugInfo::SetBreakpoint(debug_info, function_index, set_byte_offset); + + return break_point; +} + +void ClearBreakpoint(WasmRunnerBase* runner, int function_index, + int byte_offset, Handle<BreakPoint> break_point) { + int func_offset = + runner->builder().GetFunctionAt(function_index)->code.offset(); + int code_offset = func_offset + byte_offset; + Handle<WasmInstanceObject> instance = runner->builder().instance_object(); + Handle<Script> script(instance->module_object().script(), + runner->main_isolate()); + CHECK(WasmModuleObject::ClearBreakPoint(script, code_offset, break_point)); + // Also clear breakpoint on the debug info of the instance directly, since the + // instance chain is not setup properly in tests. + Handle<WasmDebugInfo> debug_info = + WasmInstanceObject::GetOrCreateDebugInfo(instance); + WasmDebugInfo::ClearBreakpoint(debug_info, function_index, byte_offset); } // Wrapper with operator<<. @@ -247,25 +271,25 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) { BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE)); WasmInstanceObject instance = *runner.builder().instance_object(); - WasmModuleObject module_object = instance.module_object(); + NativeModule* native_module = instance.module_object().native_module(); std::vector<debug::Location> locations; // Check all locations for function 0. - CheckLocations(module_object, {0, 0}, {1, 0}, + CheckLocations(native_module, {0, 0}, {1, 0}, {{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}}); // Check a range ending at an instruction. - CheckLocations(module_object, {0, 2}, {0, 4}, {{0, 2}}); + CheckLocations(native_module, {0, 2}, {0, 4}, {{0, 2}}); // Check a range ending one behind an instruction. - CheckLocations(module_object, {0, 2}, {0, 5}, {{0, 2}, {0, 4}}); + CheckLocations(native_module, {0, 2}, {0, 5}, {{0, 2}, {0, 4}}); // Check a range starting at an instruction. - CheckLocations(module_object, {0, 7}, {0, 8}, {{0, 7}}); + CheckLocations(native_module, {0, 7}, {0, 8}, {{0, 7}}); // Check from an instruction to beginning of next function. - CheckLocations(module_object, {0, 7}, {1, 0}, {{0, 7}}); + CheckLocations(native_module, {0, 7}, {1, 0}, {{0, 7}}); // Check from end of one function (no valid instruction position) to beginning // of next function. Must be empty, but not fail. - CheckLocations(module_object, {0, 8}, {1, 0}, {}); + CheckLocations(native_module, {0, 8}, {1, 0}, {}); // Check from one after the end of the function. Must fail. - CheckLocationsFail(module_object, {0, 9}, {1, 0}); + CheckLocationsFail(native_module, {0, 9}, {1, 0}); } WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) { @@ -276,7 +300,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) { Handle<JSFunction> main_fun_wrapper = runner.builder().WrapCode(runner.function_index()); - SetBreakpoint(runner, runner.function_index(), 4, 4); + SetBreakpoint(&runner, runner.function_index(), 4, 4); BreakHandler count_breaks(isolate, {{4, BreakHandler::Continue}}); @@ -298,7 +322,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) { runner.builder().WrapCode(runner.function_index()); // Set breakpoint at the first I32Const. - SetBreakpoint(runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 1, 1); BreakHandler count_breaks(isolate, { @@ -340,12 +364,12 @@ WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) { Handle<JSFunction> main_fun_wrapper = runner.builder().WrapCode(f2.function_index()); - // Set first breakpoint on the GetLocal (offset 19) before the Call. - SetBreakpoint(runner, f2.function_index(), 19, 19); + // Set first breakpoint on the LocalGet (offset 19) before the Call. + SetBreakpoint(&runner, f2.function_index(), 19, 19); BreakHandler count_breaks(isolate, { - {19, BreakHandler::StepIn}, // GetLocal + {19, BreakHandler::StepIn}, // LocalGet {21, BreakHandler::StepIn}, // Call {1, BreakHandler::StepOut}, // in f2 {23, BreakHandler::Continue} // After Call @@ -377,7 +401,7 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) { // Set breakpoint at the first instruction (7 bytes for local decls: num // entries + 3x<count, type>). - SetBreakpoint(runner, runner.function_index(), 7, 7); + SetBreakpoint(&runner, runner.function_index(), 7, 7); CollectValuesBreakHandler break_handler( isolate, @@ -401,6 +425,104 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) { CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 1, args).is_null()); } +WASM_COMPILED_EXEC_TEST(WasmRemoveBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + SetBreakpoint(&runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> to_delete = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + SetBreakpoint(&runner, runner.function_index(), 4, 4); + + BreakHandler count_breaks(isolate, {{1, BreakHandler::Continue}, + {2, BreakHandler::Continue, + [&runner, &to_delete]() { + ClearBreakpoint( + &runner, runner.function_index(), + 3, to_delete); + }}, + {4, BreakHandler::Continue}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + +WASM_COMPILED_EXEC_TEST(WasmRemoveLastBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + SetBreakpoint(&runner, runner.function_index(), 1, 1); + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> to_delete = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + + BreakHandler count_breaks( + isolate, {{1, BreakHandler::Continue}, + {2, BreakHandler::Continue, [&runner, &to_delete]() { + ClearBreakpoint(&runner, runner.function_index(), 3, + to_delete); + }}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + +WASM_COMPILED_EXEC_TEST(WasmRemoveAllBreakPoint) { + WasmRunner<int> runner(execution_tier); + Isolate* isolate = runner.main_isolate(); + + BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, + WASM_I32V_1(14)); + + Handle<JSFunction> main_fun_wrapper = + runner.builder().WrapCode(runner.function_index()); + + Handle<BreakPoint> bp1 = + SetBreakpoint(&runner, runner.function_index(), 1, 1); + Handle<BreakPoint> bp2 = + SetBreakpoint(&runner, runner.function_index(), 2, 2); + Handle<BreakPoint> bp3 = + SetBreakpoint(&runner, runner.function_index(), 3, 3); + + BreakHandler count_breaks( + isolate, {{1, BreakHandler::Continue, [&runner, &bp1, &bp2, &bp3]() { + ClearBreakpoint(&runner, runner.function_index(), 1, bp1); + ClearBreakpoint(&runner, runner.function_index(), 3, bp3); + ClearBreakpoint(&runner, runner.function_index(), 2, bp2); + }}}); + + Handle<Object> global(isolate->context().global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr); + CHECK(!retval.is_null()); + int result; + CHECK(retval.ToHandleChecked()->ToInt32(&result)); + CHECK_EQ(14, result); +} + } // namespace wasm } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc index 299c039698cdb3..15267215e1ab7d 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc @@ -22,10 +22,8 @@ std::shared_ptr<NativeModule> NewModule(Isolate* isolate) { std::shared_ptr<WasmModule> module(new WasmModule); bool can_request_more = false; size_t size = 16384; - auto native_module = isolate->wasm_engine()->NewNativeModule( + return isolate->wasm_engine()->NewNativeModule( isolate, kAllWasmFeatures, size, can_request_more, std::move(module)); - native_module->SetRuntimeStubs(isolate); - return native_module; } TEST(CacheHit) { diff --git a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc index 736475ff558deb..75e927fafe12a1 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc @@ -32,28 +32,27 @@ namespace { template <typename T> class ArgPassingHelper { public: - ArgPassingHelper( - WasmRunnerBase& runner, // NOLINT(runtime/references) - WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references) - std::initializer_list<uint8_t> bytes_inner_function, - std::initializer_list<uint8_t> bytes_outer_function, - const T& expected_lambda) - : isolate_(runner.main_isolate()), + ArgPassingHelper(WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler, + std::initializer_list<uint8_t> bytes_inner_function, + std::initializer_list<uint8_t> bytes_outer_function, + const T& expected_lambda) + : isolate_(runner->main_isolate()), expected_lambda_(expected_lambda), debug_info_(WasmInstanceObject::GetOrCreateDebugInfo( - runner.builder().instance_object())) { + runner->builder().instance_object())) { std::vector<uint8_t> inner_code{bytes_inner_function}; - inner_compiler.Build(inner_code.data(), - inner_code.data() + inner_code.size()); + inner_compiler->Build(inner_code.data(), + inner_code.data() + inner_code.size()); std::vector<uint8_t> outer_code{bytes_outer_function}; - runner.Build(outer_code.data(), outer_code.data() + outer_code.size()); + runner->Build(outer_code.data(), outer_code.data() + outer_code.size()); - int funcs_to_redict[] = {static_cast<int>(inner_compiler.function_index())}; - runner.builder().SetExecutable(); + int funcs_to_redict[] = { + static_cast<int>(inner_compiler->function_index())}; + runner->builder().SetExecutable(); WasmDebugInfo::RedirectToInterpreter(debug_info_, ArrayVector(funcs_to_redict)); - main_fun_wrapper_ = runner.builder().WrapCode(runner.function_index()); + main_fun_wrapper_ = runner->builder().WrapCode(runner->function_index()); } template <typename... Args> @@ -82,8 +81,7 @@ class ArgPassingHelper { template <typename T> static ArgPassingHelper<T> GetHelper( - WasmRunnerBase& runner, // NOLINT(runtime/references) - WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references) + WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler, std::initializer_list<uint8_t> bytes_inner_function, std::initializer_list<uint8_t> bytes_outer_function, const T& expected_lambda) { @@ -99,7 +97,7 @@ TEST(TestArgumentPassing_int32) { WasmFunctionCompiler& f2 = runner.NewFunction<int32_t, int32_t>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return 2*<0> + 1. WASM_I32_ADD(WASM_I32_MUL(WASM_I32V_1(2), WASM_GET_LOCAL(0)), WASM_ONE)}, {// Call f2 with param <0>. @@ -117,7 +115,7 @@ TEST(TestArgumentPassing_double_int64) { WasmFunctionCompiler& f2 = runner.NewFunction<double, int64_t>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return (double)<0>. WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))}, {// Call f2 with param (<0> | (<1> << 32)). @@ -150,7 +148,7 @@ TEST(TestArgumentPassing_int64_double) { WasmFunctionCompiler& f2 = runner.NewFunction<int64_t, double>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return (int64_t)<0>. WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))}, {// Call f2 with param <0>, convert returned value back to double. @@ -169,7 +167,7 @@ TEST(TestArgumentPassing_float_double) { WasmFunctionCompiler& f2 = runner.NewFunction<double, float>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, {// Return 2*(double)<0> + 1. WASM_F64_ADD( WASM_F64_MUL(WASM_F64(2), WASM_F64_CONVERT_F32(WASM_GET_LOCAL(0))), @@ -186,7 +184,7 @@ TEST(TestArgumentPassing_double_double) { WasmRunner<double, double, double> runner(ExecutionTier::kTurbofan); WasmFunctionCompiler& f2 = runner.NewFunction<double, double, double>(); - auto helper = GetHelper(runner, f2, + auto helper = GetHelper(&runner, &f2, {// Return <0> + <1>. WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}, {// Call f2 with params <0>, <1>. @@ -208,7 +206,7 @@ TEST(TestArgumentPassing_AllTypes) { runner.NewFunction<double, int32_t, int64_t, float, double>(); auto helper = GetHelper( - runner, f2, + &runner, &f2, { // Convert all arguments to double, add them and return the sum. WASM_F64_ADD( // <0+1+2> + <3> diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc index 1ff2a899ad7a76..ad5d5b13825279 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc @@ -11,7 +11,6 @@ #include "src/utils/version.h" #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-module-builder.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" diff --git a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc index b5bacf57d4b36b..2d6e93039704c6 100644 --- a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc +++ b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc @@ -27,7 +27,7 @@ namespace test_wasm_shared_engine { class SharedEngine { public: explicit SharedEngine(size_t max_committed = kMaxWasmCodeMemory) - : wasm_engine_(base::make_unique<WasmEngine>()) {} + : wasm_engine_(std::make_unique<WasmEngine>()) {} ~SharedEngine() { // Ensure no remaining uses exist. CHECK(wasm_engine_.unique()); @@ -112,19 +112,19 @@ class SharedEngineIsolate { class SharedEngineThread : public v8::base::Thread { public: SharedEngineThread(SharedEngine* engine, - std::function<void(SharedEngineIsolate&)> callback) + std::function<void(SharedEngineIsolate*)> callback) : Thread(Options("SharedEngineThread")), engine_(engine), callback_(callback) {} void Run() override { SharedEngineIsolate isolate(engine_); - callback_(isolate); + callback_(&isolate); } private: SharedEngine* engine_; - std::function<void(SharedEngineIsolate&)> callback_; + std::function<void(SharedEngineIsolate*)> callback_; }; namespace { @@ -159,43 +159,39 @@ class MockInstantiationResolver : public InstantiationResultResolver { class MockCompilationResolver : public CompilationResultResolver { public: - MockCompilationResolver( - SharedEngineIsolate& isolate, // NOLINT(runtime/references) - Handle<Object>* out_instance) + MockCompilationResolver(SharedEngineIsolate* isolate, + Handle<Object>* out_instance) : isolate_(isolate), out_instance_(out_instance) {} void OnCompilationSucceeded(Handle<WasmModuleObject> result) override { - isolate_.isolate()->wasm_engine()->AsyncInstantiate( - isolate_.isolate(), - base::make_unique<MockInstantiationResolver>(out_instance_), result, - {}); + isolate_->isolate()->wasm_engine()->AsyncInstantiate( + isolate_->isolate(), + std::make_unique<MockInstantiationResolver>(out_instance_), result, {}); } void OnCompilationFailed(Handle<Object> error_reason) override { UNREACHABLE(); } private: - SharedEngineIsolate& isolate_; + SharedEngineIsolate* isolate_; Handle<Object>* out_instance_; }; -void PumpMessageLoop( - SharedEngineIsolate& isolate) { // NOLINT(runtime/references) +void PumpMessageLoop(SharedEngineIsolate* isolate) { v8::platform::PumpMessageLoop(i::V8::GetCurrentPlatform(), - isolate.v8_isolate(), + isolate->v8_isolate(), platform::MessageLoopBehavior::kWaitForWork); - isolate.isolate()->default_microtask_queue()->RunMicrotasks( - isolate.isolate()); + isolate->isolate()->default_microtask_queue()->RunMicrotasks( + isolate->isolate()); } Handle<WasmInstanceObject> CompileAndInstantiateAsync( - SharedEngineIsolate& isolate, // NOLINT(runtime/references) - ZoneBuffer* buffer) { - Handle<Object> maybe_instance = handle(Smi::kZero, isolate.isolate()); - auto enabled_features = WasmFeaturesFromIsolate(isolate.isolate()); + SharedEngineIsolate* isolate, ZoneBuffer* buffer) { + Handle<Object> maybe_instance = handle(Smi::kZero, isolate->isolate()); + auto enabled_features = WasmFeaturesFromIsolate(isolate->isolate()); constexpr const char* kAPIMethodName = "Test.CompileAndInstantiateAsync"; - isolate.isolate()->wasm_engine()->AsyncCompile( - isolate.isolate(), enabled_features, - base::make_unique<MockCompilationResolver>(isolate, &maybe_instance), + isolate->isolate()->wasm_engine()->AsyncCompile( + isolate->isolate(), enabled_features, + std::make_unique<MockCompilationResolver>(isolate, &maybe_instance), ModuleWireBytes(buffer->begin(), buffer->end()), true, kAPIMethodName); while (!maybe_instance->IsWasmInstanceObject()) PumpMessageLoop(isolate); Handle<WasmInstanceObject> instance = @@ -261,17 +257,19 @@ TEST(SharedEngineRunImported) { TEST(SharedEngineRunThreadedBuildingSync) { SharedEngine engine; - SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); - Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); + Handle<WasmInstanceObject> instance = + isolate->CompileAndInstantiate(buffer); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42); - Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); - CHECK_EQ(42, isolate.Run(instance)); + SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); + Handle<WasmInstanceObject> instance = + isolate->CompileAndInstantiate(buffer); + CHECK_EQ(42, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -281,19 +279,19 @@ TEST(SharedEngineRunThreadedBuildingSync) { TEST(SharedEngineRunThreadedBuildingAsync) { SharedEngine engine; - SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23); + SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23); Handle<WasmInstanceObject> instance = CompileAndInstantiateAsync(isolate, buffer); - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42); + SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42); Handle<WasmInstanceObject> instance = CompileAndInstantiateAsync(isolate, buffer); - CHECK_EQ(42, isolate.Run(instance)); + CHECK_EQ(42, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -311,15 +309,15 @@ TEST(SharedEngineRunThreadedExecution) { Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer); module = isolate.ExportInstance(instance); } - SharedEngineThread thread1(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread1(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); + CHECK_EQ(23, isolate->Run(instance)); }); - SharedEngineThread thread2(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); - CHECK_EQ(23, isolate.Run(instance)); + SharedEngineThread thread2(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); + CHECK_EQ(23, isolate->Run(instance)); }); CHECK(thread1.Start()); CHECK(thread2.Start()); @@ -340,23 +338,23 @@ TEST(SharedEngineRunThreadedTierUp) { constexpr int kNumberOfThreads = 5; std::list<SharedEngineThread> threads; for (int i = 0; i < kNumberOfThreads; ++i) { - threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) { + threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { constexpr int kNumberOfIterations = 100; - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); for (int j = 0; j < kNumberOfIterations; ++j) { - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); } }); } - threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) { - HandleScope scope(isolate.isolate()); - Handle<WasmInstanceObject> instance = isolate.ImportInstance(module); + threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) { + HandleScope scope(isolate->isolate()); + Handle<WasmInstanceObject> instance = isolate->ImportInstance(module); WasmFeatures detected = kNoWasmFeatures; WasmCompilationUnit::CompileWasmFunction( - isolate.isolate(), module.get(), &detected, + isolate->isolate(), module.get(), &detected, &module->module()->functions[0], ExecutionTier::kTurbofan); - CHECK_EQ(23, isolate.Run(instance)); + CHECK_EQ(23, isolate->Run(instance)); }); for (auto& thread : threads) CHECK(thread.Start()); for (auto& thread : threads) thread.Join(); diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc index 528d71f53c6642..09d64e5d97b609 100644 --- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc +++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc @@ -10,7 +10,6 @@ #include "src/wasm/graph-builder-interface.h" #include "src/wasm/module-compiler.h" #include "src/wasm/wasm-import-wrapper-cache.h" -#include "src/wasm/wasm-memory.h" #include "src/wasm/wasm-objects-inl.h" namespace v8 { @@ -75,29 +74,23 @@ byte* TestingModuleBuilder::AddMemory(uint32_t size, SharedFlag shared) { CHECK_NULL(mem_start_); CHECK_EQ(0, mem_size_); DCHECK(!instance_object_->has_memory_object()); - DCHECK_IMPLIES(test_module_->origin == kWasmOrigin, - size % kWasmPageSize == 0); + uint32_t initial_pages = RoundUp(size, kWasmPageSize) / kWasmPageSize; + uint32_t maximum_pages = (test_module_->maximum_pages != 0) + ? test_module_->maximum_pages + : initial_pages; test_module_->has_memory = true; - uint32_t max_size = - (test_module_->maximum_pages != 0) ? test_module_->maximum_pages : size; - uint32_t alloc_size = RoundUp(size, kWasmPageSize); - Handle<JSArrayBuffer> new_buffer; - if (shared == SharedFlag::kShared) { - CHECK(NewSharedArrayBuffer(isolate_, alloc_size, max_size) - .ToHandle(&new_buffer)); - } else { - CHECK(NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer)); - } - CHECK(!new_buffer.is_null()); - mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store()); - mem_size_ = size; - CHECK(size == 0 || mem_start_); - memset(mem_start_, 0, size); // Create the WasmMemoryObject. Handle<WasmMemoryObject> memory_object = - WasmMemoryObject::New(isolate_, new_buffer, max_size); + WasmMemoryObject::New(isolate_, initial_pages, maximum_pages, shared) + .ToHandleChecked(); instance_object_->set_memory_object(*memory_object); + + mem_start_ = + reinterpret_cast<byte*>(memory_object->array_buffer().backing_store()); + mem_size_ = size; + CHECK(size == 0 || mem_start_); + WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_); // TODO(wasm): Delete the following two lines when test-run-wasm will use a // multiple of kPageSize as memory size. At the moment, the effect of these @@ -328,7 +321,6 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() { auto native_module = isolate_->wasm_engine()->NewNativeModule( isolate_, enabled_features_, test_module_); native_module->SetWireBytes(OwnedVector<const uint8_t>()); - native_module->SetRuntimeStubs(isolate_); Handle<WasmModuleObject> module_object = WasmModuleObject::New(isolate_, std::move(native_module), script); @@ -487,7 +479,7 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode() { CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); OFStream os(tracing_scope.file()); - code->Disassemble("wasm wrapper", os); + code->Disassemble("wasm wrapper", os, isolate); } #endif } diff --git a/deps/v8/test/common/assembler-tester.h b/deps/v8/test/common/assembler-tester.h index 4c3d8ff6180e1b..17e376ef60800d 100644 --- a/deps/v8/test/common/assembler-tester.h +++ b/deps/v8/test/common/assembler-tester.h @@ -5,6 +5,8 @@ #ifndef V8_TEST_COMMON_ASSEMBLER_TESTER_H_ #define V8_TEST_COMMON_ASSEMBLER_TESTER_H_ +#include <memory> + #include "src/codegen/assembler.h" #include "src/codegen/code-desc.h" @@ -74,7 +76,7 @@ class TestingAssemblerBuffer : public AssemblerBuffer { static inline std::unique_ptr<TestingAssemblerBuffer> AllocateAssemblerBuffer( size_t requested = v8::internal::AssemblerBase::kMinimalBufferSize, void* address = nullptr) { - return base::make_unique<TestingAssemblerBuffer>(requested, address); + return std::make_unique<TestingAssemblerBuffer>(requested, address); } } // namespace internal diff --git a/deps/v8/test/common/wasm/wasm-macro-gen.h b/deps/v8/test/common/wasm/wasm-macro-gen.h index ed20641c65cdcf..d007fbd0022229 100644 --- a/deps/v8/test/common/wasm/wasm-macro-gen.h +++ b/deps/v8/test/common/wasm/wasm-macro-gen.h @@ -27,12 +27,14 @@ #define ACTIVE_NO_INDEX 0 #define PASSIVE 1 #define ACTIVE_WITH_INDEX 2 +#define PASSIVE_WITH_ELEMENTS 5 +#define ACTIVE_WITH_ELEMENTS 6 // The table index field in an element segment was repurposed as a flags field. // To specify a table index, we have to set the flag value to 2, followed by // the table index. -#define TABLE_INDEX0 U32V_1(ACTIVE_NO_INDEX) -#define TABLE_INDEX(v) U32V_1(ACTIVE_WITH_INDEX), U32V_1(v) +#define TABLE_INDEX0 static_cast<byte>(ACTIVE_NO_INDEX) +#define TABLE_INDEX(v) static_cast<byte>(ACTIVE_WITH_INDEX), U32V_1(v) #define ZERO_ALIGNMENT 0 #define ZERO_OFFSET 0 @@ -361,13 +363,13 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { #define WASM_REF_FUNC(val) kExprRefFunc, val #define WASM_REF_IS_NULL(val) val, kExprRefIsNull -#define WASM_GET_LOCAL(index) kExprGetLocal, static_cast<byte>(index) -#define WASM_SET_LOCAL(index, val) val, kExprSetLocal, static_cast<byte>(index) -#define WASM_TEE_LOCAL(index, val) val, kExprTeeLocal, static_cast<byte>(index) +#define WASM_GET_LOCAL(index) kExprLocalGet, static_cast<byte>(index) +#define WASM_SET_LOCAL(index, val) val, kExprLocalSet, static_cast<byte>(index) +#define WASM_TEE_LOCAL(index, val) val, kExprLocalTee, static_cast<byte>(index) #define WASM_DROP kExprDrop -#define WASM_GET_GLOBAL(index) kExprGetGlobal, static_cast<byte>(index) +#define WASM_GET_GLOBAL(index) kExprGlobalGet, static_cast<byte>(index) #define WASM_SET_GLOBAL(index, val) \ - val, kExprSetGlobal, static_cast<byte>(index) + val, kExprGlobalSet, static_cast<byte>(index) #define WASM_TABLE_GET(table_index, index) \ index, kExprTableGet, static_cast<byte>(table_index) #define WASM_TABLE_SET(table_index, index, val) \ @@ -442,15 +444,15 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) { kExprLoop, kLocalVoid, x, kExprIf, kLocalVoid, y, kExprBr, DEPTH_1, \ kExprEnd, kExprEnd #define WASM_INC_LOCAL(index) \ - kExprGetLocal, static_cast<byte>(index), kExprI32Const, 1, kExprI32Add, \ - kExprTeeLocal, static_cast<byte>(index) + kExprLocalGet, static_cast<byte>(index), kExprI32Const, 1, kExprI32Add, \ + kExprLocalTee, static_cast<byte>(index) #define WASM_INC_LOCAL_BYV(index, count) \ - kExprGetLocal, static_cast<byte>(index), kExprI32Const, \ - static_cast<byte>(count), kExprI32Add, kExprTeeLocal, \ + kExprLocalGet, static_cast<byte>(index), kExprI32Const, \ + static_cast<byte>(count), kExprI32Add, kExprLocalTee, \ static_cast<byte>(index) #define WASM_INC_LOCAL_BY(index, count) \ - kExprGetLocal, static_cast<byte>(index), kExprI32Const, \ - static_cast<byte>(count), kExprI32Add, kExprSetLocal, \ + kExprLocalGet, static_cast<byte>(index), kExprI32Const, \ + static_cast<byte>(count), kExprI32Add, kExprLocalSet, \ static_cast<byte>(index) #define WASM_UNOP(opcode, x) x, static_cast<byte>(opcode) #define WASM_BINOP(opcode, x, y) x, y, static_cast<byte>(opcode) diff --git a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-3.js b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-3.js new file mode 100644 index 00000000000000..2a41109565cae7 --- /dev/null +++ b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context-3.js @@ -0,0 +1,39 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test that debug-evaluate properly shadows stack-allocated variables. + +Debug = debug.Debug + +let exception = null; +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + assertEquals(2, exec_state.frame(0).evaluate("b").value()); + assertEquals(3, exec_state.frame(0).evaluate("c").value()) + assertThrows(() => exec_state.frame(0).evaluate("a").value()); + } catch (e) { + exception = e; + print(e + e.stack); + } +} + +Debug.setListener(listener); + +(function f() { + let a = 1; + let b = 2; + let c = 3; + () => a + c; // a and c are context-allocated + return function g() { + let a = 2; // a is stack-allocated + return function h() { + b; // b is allocated onto f's context. + debugger; + } + } +})()()(); + +Debug.setListener(null); +assertNull(exception); diff --git a/deps/v8/test/debugger/debug/es6/generators-relocation.js b/deps/v8/test/debugger/debug/es6/generators-relocation.js index 78413fde6e713c..13ebb01d0f45c2 100644 --- a/deps/v8/test/debugger/debug/es6/generators-relocation.js +++ b/deps/v8/test/debugger/debug/es6/generators-relocation.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --expose-gc var Debug = debug.Debug; @@ -28,6 +29,8 @@ function RunTest(formals_and_body, args, value1, value2) { // function and relocation of the suspended generator activation. Debug.setListener(listener); + gc(); + // Add a breakpoint on line 3 (the second yield). var bp = Debug.setBreakPoint(gen, 3); diff --git a/deps/v8/test/debugger/debugger.status b/deps/v8/test/debugger/debugger.status index 503e5e71459506..85e4cec3eef17b 100644 --- a/deps/v8/test/debugger/debugger.status +++ b/deps/v8/test/debugger/debugger.status @@ -11,6 +11,9 @@ # not work, but we expect it to not crash. 'debug/debug-step-turbofan': [PASS, FAIL], + # BUG (v8:9721) + 'debug/es6/generators-relocation': [FAIL], + # Issue 3641: The new 'then' semantics suppress some exceptions. # These tests may be changed or removed when 'chain' is deprecated. 'debug/es6/debug-promises/reject-with-throw-in-reject': [FAIL], @@ -136,4 +139,10 @@ '*': [SKIP], }], # variant == jitless and not embedded_builtins +############################################################################## +['variant == turboprop', { + # Deopts differently than TurboFan. + 'debug/debug-optimize': [SKIP], +}], # variant == turboprop + ] diff --git a/deps/v8/test/debugger/regress/regress-9482.js b/deps/v8/test/debugger/regress/regress-9482.js new file mode 100644 index 00000000000000..e07c660a086ed1 --- /dev/null +++ b/deps/v8/test/debugger/regress/regress-9482.js @@ -0,0 +1,32 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Debug = debug.Debug +var exception = null; + +function listener(event, exec_state, event_data, data) { + try { + if (event == Debug.DebugEvent.Break) { + assertEquals("n", exec_state.frame(0).evaluate("n").value()); + assertEquals("m", exec_state.frame(0).evaluate("m").value()); + } + } catch(e) { + exception = e; + print(e, e.stack); + } +}; + +Debug.setListener(listener); + +(function foo () { + var n = "n"; + var m = "m"; + (function bar() { + assertEquals("m", eval("m")); // force context-allocation. + debugger; + })(); +})(); + +assertNull(exception); +Debug.setListener(null); diff --git a/deps/v8/test/fuzzer/fuzzer-support.cc b/deps/v8/test/fuzzer/fuzzer-support.cc index 5d6861dd6246fb..6235ea5f8292b7 100644 --- a/deps/v8/test/fuzzer/fuzzer-support.cc +++ b/deps/v8/test/fuzzer/fuzzer-support.cc @@ -63,7 +63,7 @@ std::unique_ptr<FuzzerSupport> FuzzerSupport::fuzzer_support_; void FuzzerSupport::InitializeFuzzerSupport(int* argc, char*** argv) { DCHECK_NULL(FuzzerSupport::fuzzer_support_); FuzzerSupport::fuzzer_support_ = - v8::base::make_unique<v8_fuzzer::FuzzerSupport>(argc, argv); + std::make_unique<v8_fuzzer::FuzzerSupport>(argc, argv); } // static diff --git a/deps/v8/test/fuzzer/fuzzer-support.h b/deps/v8/test/fuzzer/fuzzer-support.h index 229c8c6b49239a..7b967073b57edb 100644 --- a/deps/v8/test/fuzzer/fuzzer-support.h +++ b/deps/v8/test/fuzzer/fuzzer-support.h @@ -5,6 +5,8 @@ #ifndef TEST_FUZZER_FUZZER_SUPPORT_H_ #define TEST_FUZZER_FUZZER_SUPPORT_H_ +#include <memory> + #include "include/libplatform/libplatform.h" #include "include/v8.h" diff --git a/deps/v8/test/fuzzer/wasm-compile.cc b/deps/v8/test/fuzzer/wasm-compile.cc index 29f2ebb02d16b7..10e41e103936c2 100644 --- a/deps/v8/test/fuzzer/wasm-compile.cc +++ b/deps/v8/test/fuzzer/wasm-compile.cc @@ -322,7 +322,7 @@ class WasmGenerator { return Generate<wanted_type>(data); } - if (opcode != kExprGetLocal) Generate(local.type, data); + if (opcode != kExprLocalGet) Generate(local.type, data); builder_->EmitWithU32V(opcode, local.index); if (wanted_type != kWasmStmt && local.type != wanted_type) { Convert(local.type, wanted_type); @@ -332,14 +332,14 @@ class WasmGenerator { template <ValueType wanted_type> void get_local(DataRange* data) { static_assert(wanted_type != kWasmStmt, "illegal type"); - local_op<wanted_type>(data, kExprGetLocal); + local_op<wanted_type>(data, kExprLocalGet); } - void set_local(DataRange* data) { local_op<kWasmStmt>(data, kExprSetLocal); } + void set_local(DataRange* data) { local_op<kWasmStmt>(data, kExprLocalSet); } template <ValueType wanted_type> void tee_local(DataRange* data) { - local_op<wanted_type>(data, kExprTeeLocal); + local_op<wanted_type>(data, kExprLocalTee); } template <size_t num_bytes> @@ -377,7 +377,7 @@ class WasmGenerator { } if (is_set) Generate(global.type, data); - builder_->EmitWithU32V(is_set ? kExprSetGlobal : kExprGetGlobal, + builder_->EmitWithU32V(is_set ? kExprGlobalSet : kExprGlobalGet, global.index); if (!is_set && global.type != wanted_type) { Convert(global.type, wanted_type); @@ -465,7 +465,7 @@ class WasmGenerator { template <ValueType T1, ValueType T2, ValueType... Ts> void Generate(DataRange* data) { - // TODO(clemensh): Implement a more even split. + // TODO(clemensb): Implement a more even split. auto first_data = data->split(); Generate<T1>(&first_data); Generate<T2, Ts...>(data); diff --git a/deps/v8/test/fuzzer/wasm-fuzzer-common.h b/deps/v8/test/fuzzer/wasm-fuzzer-common.h index 8ab802a702bd8b..bca9a2c433a395 100644 --- a/deps/v8/test/fuzzer/wasm-fuzzer-common.h +++ b/deps/v8/test/fuzzer/wasm-fuzzer-common.h @@ -7,6 +7,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include "src/wasm/module-decoder.h" #include "src/wasm/wasm-interpreter.h" diff --git a/deps/v8/test/inspector/cpu-profiler/console-profile-wasm.js b/deps/v8/test/inspector/cpu-profiler/console-profile-wasm.js index dc96406d4a8179..0541ce02bb8302 100644 --- a/deps/v8/test/inspector/cpu-profiler/console-profile-wasm.js +++ b/deps/v8/test/inspector/cpu-profiler/console-profile-wasm.js @@ -11,14 +11,14 @@ utils.load('test/mjsunit/wasm/wasm-module-builder.js'); var builder = new WasmModuleBuilder(); builder.addFunction('fib', kSig_i_i) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Const, 2, kExprI32LeS, // i < 2 ? kExprBrIf, 0, // --> return i kExprI32Const, 1, kExprI32Sub, // i - 1 kExprCallFunction, 0, // fib(i - 1) - kExprGetLocal, 0, kExprI32Const, 2, kExprI32Sub, // i - 2 + kExprLocalGet, 0, kExprI32Const, 2, kExprI32Sub, // i - 2 kExprCallFunction, 0, // fib(i - 2) kExprI32Add ]) diff --git a/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt b/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt index 4be4e96efe7bc6..28708d79506e99 100644 --- a/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt +++ b/deps/v8/test/inspector/debugger/class-fields-scopes-expected.txt @@ -109,26 +109,6 @@ Running test: testScopesPaused type : local } [1] : { - endLocation : { - columnNumber : 3 - lineNumber : 15 - scriptId : <scriptId> - } - name : run - object : { - className : Object - description : Object - objectId : <objectId> - type : object - } - startLocation : { - columnNumber : 9 - lineNumber : 11 - scriptId : <scriptId> - } - type : block - } - [2] : { endLocation : { columnNumber : 1 lineNumber : 19 @@ -148,7 +128,7 @@ Running test: testScopesPaused } type : local } - [3] : { + [2] : { object : { className : global description : global diff --git a/deps/v8/test/inspector/debugger/pause-on-async-call-expected.txt b/deps/v8/test/inspector/debugger/pause-on-async-call-expected.txt index 012ab4b0b9a425..4fb08f6319d112 100644 --- a/deps/v8/test/inspector/debugger/pause-on-async-call-expected.txt +++ b/deps/v8/test/inspector/debugger/pause-on-async-call-expected.txt @@ -28,13 +28,6 @@ paused at: #Promise.resolve().then(v => v * 2); } -paused at: - debugger; - Promise.resolve().#then(v => v * 2); -} - -asyncCallStackTraceId is set - paused at: debugger; Promise.resolve().then(v => v #* 2); @@ -52,13 +45,6 @@ paused at: p.#then(v => v * 2); resolveCallback(); -paused at: - debugger; - p.#then(v => v * 2); - resolveCallback(); - -asyncCallStackTraceId is set - paused at: debugger; p.then(v => v #* 2); @@ -76,13 +62,6 @@ paused at: #Promise.resolve().then(v => v * 2); Promise.resolve().then(v => v * 4); -paused at: - debugger; - Promise.resolve().#then(v => v * 2); - Promise.resolve().then(v => v * 4); - -asyncCallStackTraceId is set - paused at: debugger; Promise.resolve().then(v => v #* 2); @@ -105,13 +84,6 @@ paused at: #Promise.resolve().then(v => v * 4); } -paused at: - Promise.resolve().then(v => v * 2); - Promise.resolve().#then(v => v * 4); -} - -asyncCallStackTraceId is set - paused at: Promise.resolve().then(v => v * 2); Promise.resolve().then(v => v #* 4); @@ -129,13 +101,6 @@ paused at: #Promise.resolve().then(v => v * 2); debugger; -paused at: - debugger; - Promise.resolve().#then(v => v * 2); - debugger; - -asyncCallStackTraceId is set - paused at: Promise.resolve().then(v => v * 2); #debugger; @@ -146,13 +111,6 @@ paused at: #Promise.resolve().then(v => v * 4); } -paused at: - debugger; - Promise.resolve().#then(v => v * 4); -} - -asyncCallStackTraceId is set - paused at: debugger; Promise.resolve().then(v => v #* 4); @@ -170,13 +128,6 @@ paused at: #Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2); } -paused at: - debugger; - Promise.all([ Promise.resolve(), Promise.resolve() ]).#then(v => v * 2); -} - -asyncCallStackTraceId is set - paused at: debugger; Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v #* 2); @@ -194,13 +145,6 @@ paused at: #createPromise().then(v => v * 2); } -paused at: - debugger; - createPromise().#then(v => v * 2); -} - -asyncCallStackTraceId is set - paused at: debugger; createPromise().then(v => v #* 2); @@ -218,13 +162,6 @@ paused at: #createPromise().then(v => v * 2); } -paused at: - debugger; - createPromise().#then(v => v * 2); -} - -asyncCallStackTraceId is set - paused at: debugger; createPromise().then(v => v #* 2); @@ -272,13 +209,6 @@ paused at: foo().#then(boo); -paused at: - await foo(); - foo().#then(boo); - - -asyncCallStackTraceId is set - paused at: function boo() { #} diff --git a/deps/v8/test/inspector/debugger/pause-on-async-call-set-timeout.js b/deps/v8/test/inspector/debugger/pause-on-async-call-set-timeout.js index be26bc11de581f..716d860f08a64a 100644 --- a/deps/v8/test/inspector/debugger/pause-on-async-call-set-timeout.js +++ b/deps/v8/test/inspector/debugger/pause-on-async-call-set-timeout.js @@ -12,9 +12,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -26,9 +23,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - await Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); @@ -43,9 +37,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); await InspectorTest.waitForPendingTasks(); @@ -57,9 +48,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -69,20 +57,14 @@ InspectorTest.runAsyncTestSuite([ Protocol.Runtime.evaluate({expression: 'setTimeout(() => 42, 0)'}); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); } ]); async function waitPauseAndDumpLocation() { - var {params: {callFrames, asyncCallStackTraceId}} = + var {params: {callFrames}} = await Protocol.Debugger.oncePaused(); - if (!asyncCallStackTraceId) { - InspectorTest.log('paused at:'); - await session.logSourceLocation(callFrames[0].location); - } - return asyncCallStackTraceId; + InspectorTest.log('paused at:'); + await session.logSourceLocation(callFrames[0].location); } diff --git a/deps/v8/test/inspector/debugger/pause-on-async-call.js b/deps/v8/test/inspector/debugger/pause-on-async-call.js index 24e7fc6647f266..c6104a1ae20109 100644 --- a/deps/v8/test/inspector/debugger/pause-on-async-call.js +++ b/deps/v8/test/inspector/debugger/pause-on-async-call.js @@ -90,9 +90,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -103,9 +100,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -116,9 +110,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepInto(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -131,9 +122,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -144,16 +132,10 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -164,9 +146,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -178,9 +157,6 @@ InspectorTest.runAsyncTestSuite([ await waitPauseAndDumpLocation(); await Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js'] }); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -192,9 +168,6 @@ InspectorTest.runAsyncTestSuite([ await waitPauseAndDumpLocation(); await Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js']}); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); }, @@ -205,17 +178,11 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOver(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let parentStackTraceId = await waitPauseAndDumpLocation(); - if (parentStackTraceId) - InspectorTest.log( - 'ERROR: we should not report parent stack trace id on async call'); + await waitPauseAndDumpLocation(); Protocol.Debugger.stepOut(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - parentStackTraceId = await waitPauseAndDumpLocation(); - if (parentStackTraceId) - InspectorTest.log( - 'ERROR: we should not report parent stack trace id on async call'); + await waitPauseAndDumpLocation(); Protocol.Debugger.stepOut(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); @@ -223,9 +190,6 @@ InspectorTest.runAsyncTestSuite([ Protocol.Debugger.stepOut(); await waitPauseAndDumpLocation(); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - parentStackTraceId = await waitPauseAndDumpLocation(); - Protocol.Debugger.pauseOnAsyncCall({parentStackTraceId}); - Protocol.Debugger.resume(); await waitPauseAndDumpLocation(); await Protocol.Debugger.resume(); @@ -233,12 +197,8 @@ InspectorTest.runAsyncTestSuite([ ]); async function waitPauseAndDumpLocation() { - var {params: {callFrames, asyncCallStackTraceId}} = + var {params: {callFrames}} = await Protocol.Debugger.oncePaused(); InspectorTest.log('paused at:'); await session.logSourceLocation(callFrames[0].location); - if (asyncCallStackTraceId) { - InspectorTest.log('asyncCallStackTraceId is set\n'); - } - return asyncCallStackTraceId; } diff --git a/deps/v8/test/inspector/debugger/step-into-break-on-async-call-expected.txt b/deps/v8/test/inspector/debugger/step-into-break-on-async-call-expected.txt index 5f61c89c1af4aa..72f896567f27a7 100644 --- a/deps/v8/test/inspector/debugger/step-into-break-on-async-call-expected.txt +++ b/deps/v8/test/inspector/debugger/step-into-break-on-async-call-expected.txt @@ -1,13 +1,7 @@ Test for Debugger.stepInto with breakOnAsyncCall. Running test: testSetTimeout -(anonymous) (test.js:0:0) -asyncCallStackTraceId is set (anonymous) (test.js:0:17) -asyncCallStackTraceId is empty Running test: testPromiseThen -(anonymous) (test.js:0:2) -asyncCallStackTraceId is set (anonymous) (test.js:0:13) -asyncCallStackTraceId is empty diff --git a/deps/v8/test/inspector/debugger/step-into-break-on-async-call.js b/deps/v8/test/inspector/debugger/step-into-break-on-async-call.js index d47df9f7ebe874..417f4a39363273 100644 --- a/deps/v8/test/inspector/debugger/step-into-break-on-async-call.js +++ b/deps/v8/test/inspector/debugger/step-into-break-on-async-call.js @@ -17,21 +17,8 @@ InspectorTest.runAsyncTestSuite([ }); await pausedPromise; Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let {params: {callFrames, asyncCallStackTraceId}} = - await Protocol.Debugger.oncePaused(); + let {params: {callFrames}} = await Protocol.Debugger.oncePaused(); session.logCallFrames(callFrames); - if (asyncCallStackTraceId) { - InspectorTest.log('asyncCallStackTraceId is set'); - } - Protocol.Debugger.pauseOnAsyncCall( - {parentStackTraceId: asyncCallStackTraceId}); - pausedPromise = Protocol.Debugger.oncePaused(); - Protocol.Debugger.resume(); - ({params: {callFrames, asyncCallStackTraceId}} = await pausedPromise); - session.logCallFrames(callFrames); - if (!asyncCallStackTraceId) { - InspectorTest.log('asyncCallStackTraceId is empty'); - } await Protocol.Debugger.disable(); }, @@ -45,21 +32,8 @@ InspectorTest.runAsyncTestSuite([ Protocol.Runtime.evaluate({expression: 'p.then(() => 42)//# sourceURL=test.js'}); await pausedPromise; Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let {params: {callFrames, asyncCallStackTraceId}} = - await Protocol.Debugger.oncePaused(); - session.logCallFrames(callFrames); - if (asyncCallStackTraceId) { - InspectorTest.log('asyncCallStackTraceId is set'); - } - Protocol.Debugger.pauseOnAsyncCall( - {parentStackTraceId: asyncCallStackTraceId}); - pausedPromise = Protocol.Debugger.oncePaused(); - Protocol.Debugger.resume(); - ({params: {callFrames, asyncCallStackTraceId}} = await pausedPromise); + let {params: {callFrames}} = await Protocol.Debugger.oncePaused(); session.logCallFrames(callFrames); - if (!asyncCallStackTraceId) { - InspectorTest.log('asyncCallStackTraceId is empty'); - } await Protocol.Debugger.disable(); } ]); diff --git a/deps/v8/test/inspector/debugger/step-into-external-async-task-expected.txt b/deps/v8/test/inspector/debugger/step-into-external-async-task-expected.txt index 8bf702b3550e73..ce82054f067fa0 100644 --- a/deps/v8/test/inspector/debugger/step-into-external-async-task-expected.txt +++ b/deps/v8/test/inspector/debugger/step-into-external-async-task-expected.txt @@ -2,7 +2,6 @@ Test for step-into remote async task Setup debugger agents.. Pause before stack trace is captured.. Run stepInto with breakOnAsyncCall flag -Call pauseOnAsyncCall Trigger external async task on another context group Dump stack trace boo (target.js:1:22) diff --git a/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context-expected.txt b/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context-expected.txt index 4b2fba9856f05f..ba93facf004cc4 100644 --- a/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context-expected.txt +++ b/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context-expected.txt @@ -2,7 +2,6 @@ Test for step-into remote async task. Setup debugger agents.. Pause before stack trace is captured.. Run stepInto with breakOnAsyncCall flag -Call pauseOnAsyncCall Trigger external async task on another context group Dump stack trace boo (target.js:1:22) diff --git a/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context.js b/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context.js index fec786422e0963..132c0690f15013 100644 --- a/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context.js +++ b/deps/v8/test/inspector/debugger/step-into-external-async-task-same-context.js @@ -42,13 +42,6 @@ session.setupScriptMap(); InspectorTest.log('Run stepInto with breakOnAsyncCall flag'); Protocol.Debugger.stepInto({breakOnAsyncCall: true}); - let {params: {asyncCallStackTraceId}} = await Protocol.Debugger.oncePaused(); - - InspectorTest.log('Call pauseOnAsyncCall'); - Protocol.Debugger.pauseOnAsyncCall({ - parentStackTraceId: asyncCallStackTraceId, - }); - Protocol.Debugger.resume(); InspectorTest.log('Trigger external async task on another context group'); let stackTraceId = (await evaluatePromise).result.result.value; diff --git a/deps/v8/test/inspector/debugger/step-into-external-async-task.js b/deps/v8/test/inspector/debugger/step-into-external-async-task.js index b0d55c950d4630..59b78c1630dfeb 100644 --- a/deps/v8/test/inspector/debugger/step-into-external-async-task.js +++ b/deps/v8/test/inspector/debugger/step-into-external-async-task.js @@ -62,13 +62,6 @@ session2.setupScriptMap(); InspectorTest.log('Run stepInto with breakOnAsyncCall flag'); Protocol1.Debugger.stepInto({breakOnAsyncCall: true}); - let {params: {asyncCallStackTraceId}} = await Protocol1.Debugger.oncePaused(); - - InspectorTest.log('Call pauseOnAsyncCall'); - Protocol2.Debugger.pauseOnAsyncCall({ - parentStackTraceId: asyncCallStackTraceId, - }); - Protocol1.Debugger.resume(); InspectorTest.log('Trigger external async task on another context group'); let stackTraceId = (await evaluatePromise).result.result.value; diff --git a/deps/v8/test/inspector/debugger/wasm-anyref-global.js b/deps/v8/test/inspector/debugger/wasm-anyref-global.js index d4c88ac69443e7..d9f63d2d2094c7 100644 --- a/deps/v8/test/inspector/debugger/wasm-anyref-global.js +++ b/deps/v8/test/inspector/debugger/wasm-anyref-global.js @@ -15,7 +15,7 @@ let {session, contextGroup, Protocol} = builder.addImportedGlobal('m', 'global', kWasmAnyRef, false); builder.addFunction('func', kSig_v_v) .addBody([ - kExprGetGlobal, 0, // + kExprGlobalGet, 0, // kExprDrop, // ]) .exportAs('main'); diff --git a/deps/v8/test/inspector/debugger/wasm-clone-module-expected.txt b/deps/v8/test/inspector/debugger/wasm-clone-module-expected.txt index fba9bb4cf2f2c6..d07f035f7891c9 100644 --- a/deps/v8/test/inspector/debugger/wasm-clone-module-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-clone-module-expected.txt @@ -1,5 +1,5 @@ Tests that cloning a module notifies the debugger -Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 -Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 -Got URL: wasm://wasm/wasm-cae8f226/wasm-cae8f226-0 +Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0 +Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0 +Got URL: wasm://wasm/wasm-95d1e44e/wasm-95d1e44e-0 Done! diff --git a/deps/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt b/deps/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt index 8fec6bc2df562b..519d77911bd261 100644 --- a/deps/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-get-breakable-locations-expected.txt @@ -2,9 +2,9 @@ Tests breakable locations in wasm Running testFunction... Script nr 0 parsed. URL: v8://test/setup Script nr 1 parsed. URL: v8://test/runTestFunction -Script nr 2 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-0 +Script nr 2 parsed. URL: wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0 This is a wasm script (nr 0). -Script nr 3 parsed. URL: wasm://wasm/wasm-354ada0e/wasm-354ada0e-1 +Script nr 3 parsed. URL: wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1 This is a wasm script (nr 1). Querying breakable locations for all wasm scripts now... Requesting all breakable locations in wasm script 0 @@ -38,51 +38,51 @@ Requesting breakable locations in lines [4,6) [0] 4:6 || >call 0 [1] 5:4 || >end Setting a breakpoint on each breakable location... -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:2:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:3:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:4:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:5:0 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:1:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:2:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:3:4 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:4:6 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:5:4 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:6:2 Success! -Setting at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 +Setting at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:7:0 Success! Running wasm code... Missing breakpoints: 11 Script nr 4 parsed. URL: v8://test/runWasm -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:1:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:1:2 Missing breakpoints: 10 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:2:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:2:2 Missing breakpoints: 9 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:3:4 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:3:4 Missing breakpoints: 8 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:4:6 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:4:6 Missing breakpoints: 7 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:2:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:2:2 Missing breakpoints: 6 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:3:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:3:2 Missing breakpoints: 5 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:4:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:4:2 Missing breakpoints: 4 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-0:5:0 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-0:5:0 Missing breakpoints: 3 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:5:4 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:5:4 Missing breakpoints: 2 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:6:2 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:6:2 Missing breakpoints: 1 -Stopped at wasm://wasm/wasm-354ada0e/wasm-354ada0e-1:7:0 +Stopped at wasm://wasm/wasm-6a95b41e/wasm-6a95b41e-1:7:0 Missing breakpoints: 0 Finished! diff --git a/deps/v8/test/inspector/debugger/wasm-get-breakable-locations.js b/deps/v8/test/inspector/debugger/wasm-get-breakable-locations.js index f0c20b3955dbfb..62f50749f32031 100644 --- a/deps/v8/test/inspector/debugger/wasm-get-breakable-locations.js +++ b/deps/v8/test/inspector/debugger/wasm-get-breakable-locations.js @@ -16,12 +16,12 @@ var func_idx = builder.addFunction('helper', kSig_v_v) .addBody([ kExprNop, kExprI32Const, 12, - kExprSetLocal, 0, + kExprLocalSet, 0, ]).index; builder.addFunction('main', kSig_v_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprIf, kWasmStmt, kExprBlock, kWasmStmt, kExprCallFunction, func_idx, diff --git a/deps/v8/test/inspector/debugger/wasm-reset-context-group.js b/deps/v8/test/inspector/debugger/wasm-reset-context-group.js index c1353da86b8928..a9a096d65ba7aa 100644 --- a/deps/v8/test/inspector/debugger/wasm-reset-context-group.js +++ b/deps/v8/test/inspector/debugger/wasm-reset-context-group.js @@ -12,7 +12,7 @@ var builder = new WasmModuleBuilder(); builder.addFunction('wasm_func', kSig_i_i) .addBody([ // clang-format off - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, // clang-format on diff --git a/deps/v8/test/inspector/debugger/wasm-scope-info.js b/deps/v8/test/inspector/debugger/wasm-scope-info.js index 116b0ce146b01c..2a5e2961ac68e3 100644 --- a/deps/v8/test/inspector/debugger/wasm-scope-info.js +++ b/deps/v8/test/inspector/debugger/wasm-scope-info.js @@ -41,21 +41,21 @@ async function instantiateWasm() { ['i32Arg', undefined, 'i64_local', 'unicode☼f64']) .addBody([ // Set param 0 to 11. - kExprI32Const, 11, kExprSetLocal, 0, + kExprI32Const, 11, kExprLocalSet, 0, // Set local 1 to 47. - kExprI32Const, 47, kExprSetLocal, 1, + kExprI32Const, 47, kExprLocalSet, 1, // Set local 2 to 0x7FFFFFFFFFFFFFFF (max i64). kExprI64Const, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, - kExprSetLocal, 2, + kExprLocalSet, 2, // Set local 2 to 0x8000000000000000 (min i64). kExprI64Const, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - kExprSetLocal, 2, + kExprLocalSet, 2, // Set local 3 to 1/7. kExprI32Const, 1, kExprF64UConvertI32, kExprI32Const, 7, - kExprF64UConvertI32, kExprF64Div, kExprSetLocal, 3, + kExprF64UConvertI32, kExprF64Div, kExprLocalSet, 3, // Set global 0 to 15 - kExprI32Const, 15, kExprSetGlobal, 0, + kExprI32Const, 15, kExprGlobalSet, 0, ]) .exportAs('main'); diff --git a/deps/v8/test/inspector/debugger/wasm-scripts-expected.txt b/deps/v8/test/inspector/debugger/wasm-scripts-expected.txt index 0afcc861c4cebe..210292c858e9e3 100644 --- a/deps/v8/test/inspector/debugger/wasm-scripts-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-scripts-expected.txt @@ -1,16 +1,23 @@ Tests how wasm scripts are reported -Check that inspector gets two wasm scripts at module creation time. -Script #0 parsed. URL: v8://test/testFunction -Script #1 parsed. URL: -Script #2 parsed. URL: v8://test/runTestRunction -Script #3 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-0 -Script #4 parsed. URL: wasm://wasm/wasm-7b04570e/wasm-7b04570e-1 -Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-0: +Check that each inspector gets two wasm scripts at module creation time. +Session #1: Script #0 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0. Source map URL: +Session #1: Script #1 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1. Source map URL: +Session #2: Script #0 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0. Source map URL: +Session #2: Script #1 parsed. URL: wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1. Source map URL: +Session #1: Script #2 parsed. URL: wasm://wasm/wasm-74f86b7e. Source map URL: wasm://dwarf +Session #2: Script #2 parsed. URL: wasm://wasm/wasm-74f86b7e. Source map URL: wasm://dwarf +Session #1: Script #3 parsed. URL: wasm://wasm/wasm-3754e3fe. Source map URL: abc +Session #2: Script #3 parsed. URL: wasm://wasm/wasm-3754e3fe. Source map URL: abc +Session #1: Script #4 parsed. URL: wasm://wasm/wasm-2bd2e40e. Source map URL: abc +Session #2: Script #4 parsed. URL: wasm://wasm/wasm-2bd2e40e. Source map URL: abc +Session #1: Script #5 parsed. URL: wasm://wasm/wasm-f568e726. Source map URL: abc +Session #2: Script #5 parsed. URL: wasm://wasm/wasm-f568e726. Source map URL: abc +Session #1: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0: func $nopFunction nop end -Source for wasm://wasm/wasm-7b04570e/wasm-7b04570e-1: +Session #1: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1: func $main block i32.const 2 @@ -18,3 +25,48 @@ func $main end end +Session #2: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-0: +func $nopFunction + nop +end + +Session #2: Source for wasm://wasm/wasm-f608ae1e/wasm-f608ae1e-1: +func $main + block + i32.const 2 + drop + end +end + +Session #1: Source for wasm://wasm/wasm-74f86b7e: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #2: Source for wasm://wasm/wasm-74f86b7e: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #1: Source for wasm://wasm/wasm-3754e3fe: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #2: Source for wasm://wasm/wasm-3754e3fe: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #1: Source for wasm://wasm/wasm-2bd2e40e: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #2: Source for wasm://wasm/wasm-2bd2e40e: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #1: Source for wasm://wasm/wasm-f568e726: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] +Session #2: Source for wasm://wasm/wasm-f568e726: +Raw: 00 61 73 6d 01 00 00 00 01 07 02 60 00 00 60 00 00 03 03 02 00 01 07 08 01 04 6d 61 69 6e 00 01 0a 0e 02 03 00 01 0b 08 00 02 40 41 02 1a 0b 0b 00 15 10 73 6f 75 72 63 65 4d 61 70 70 69 6e 67 55 52 4c 03 61 62 63 00 11 0b 2e 64 65 62 75 67 5f 69 6e 66 6f 01 02 03 04 05 00 1b 04 6e 61 6d 65 01 14 02 00 0b 6e 6f 70 46 75 6e 63 74 69 6f 6e 01 04 6d 61 69 6e +Imports: [] +Exports: [main: function] diff --git a/deps/v8/test/inspector/debugger/wasm-scripts.js b/deps/v8/test/inspector/debugger/wasm-scripts.js index 04e5ec88c1a3e8..72d886b0e5e98d 100644 --- a/deps/v8/test/inspector/debugger/wasm-scripts.js +++ b/deps/v8/test/inspector/debugger/wasm-scripts.js @@ -4,68 +4,140 @@ // Flags: --expose-wasm -let {session, contextGroup, Protocol} = InspectorTest.start('Tests how wasm scripts are reported'); +InspectorTest.log("Tests how wasm scripts are reported"); -utils.load('test/mjsunit/wasm/wasm-module-builder.js'); +let contextGroup = new InspectorTest.ContextGroup(); +let sessions = [ + // Main session. + trackScripts(), + // Extra session to verify that all inspectors get same messages. + // See https://bugs.chromium.org/p/v8/issues/detail?id=9725. + trackScripts(), +]; -// Add two empty functions. Both should be registered as individual scripts at -// module creation time. -var builder = new WasmModuleBuilder(); -builder.addFunction('nopFunction', kSig_v_v).addBody([kExprNop]); -builder.addFunction('main', kSig_v_v) - .addBody([kExprBlock, kWasmStmt, kExprI32Const, 2, kExprDrop, kExprEnd]) - .exportAs('main'); -var module_bytes = builder.toArray(); +utils.load('test/mjsunit/wasm/wasm-module-builder.js'); -function testFunction(bytes) { - var buffer = new ArrayBuffer(bytes.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < bytes.length; i++) { - view[i] = bytes[i] | 0; +// Create module with given custom sections. +function createModule(...customSections) { + var builder = new WasmModuleBuilder(); + builder.addFunction('nopFunction', kSig_v_v).addBody([kExprNop]); + builder.addFunction('main', kSig_v_v) + .addBody([kExprBlock, kWasmStmt, kExprI32Const, 2, kExprDrop, kExprEnd]) + .exportAs('main'); + for (var { name, value } of customSections) { + builder.addCustomSection(name, value); } + return builder.toArray(); +} +function testFunction(bytes) { // Compilation triggers registration of wasm scripts. - new WebAssembly.Module(buffer); + new WebAssembly.Module(new Uint8Array(bytes)); } contextGroup.addScript(testFunction.toString(), 0, 0, 'v8://test/testFunction'); -contextGroup.addScript('var module_bytes = ' + JSON.stringify(module_bytes)); -Protocol.Debugger.enable(); -Protocol.Debugger.onScriptParsed(handleScriptParsed); InspectorTest.log( - 'Check that inspector gets two wasm scripts at module creation time.'); -Protocol.Runtime + 'Check that each inspector gets two wasm scripts at module creation time.'); + +// Sample .debug_info section. +// Content doesn't matter, as we don't try to parse it in V8, +// but should be non-empty to check that we're skipping it correctly. +const dwarfSection = { name: '.debug_info', value: [1, 2, 3, 4, 5] }; + +// Sample sourceMappingURL section set to "abc". +const sourceMapSection = { name: 'sourceMappingURL', value: [3, 97, 98, 99] }; + +sessions[0].Protocol.Runtime .evaluate({ - 'expression': '//# sourceURL=v8://test/runTestRunction\n' + - 'testFunction(module_bytes)' + 'expression': `//# sourceURL=v8://test/runTestRunction + + // no debug info + testFunction([${createModule()}]); + + // DWARF + testFunction([${createModule(dwarfSection)}]); + + // Source map + testFunction([${createModule(sourceMapSection)}]); + + // DWARF + source map + testFunction([${createModule(dwarfSection, sourceMapSection)}]); + + // Source map + DWARF (different order) + testFunction([${createModule(sourceMapSection, dwarfSection)}]); + ` }) - .then(checkFinished); + .then(() => ( + // At this point all scripts were parsed. + // Stop tracking and wait for script sources in each session. + Promise.all(sessions.map(session => session.getScripts())) + )) + .catch(err => { + InspectorTest.log(err.stack); + }) + .then(() => InspectorTest.completeTest()); + +function decodeBase64(base64) { + const LOOKUP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + const paddingLength = base64.match(/=*$/)[0].length; + const bytesLength = base64.length * 0.75 - paddingLength; -var num_scripts = 0; -var missing_sources = 0; + let bytes = new Uint8Array(bytesLength); + + for (let i = 0, p = 0; i < base64.length; i += 4, p += 3) { + let bits = 0; + for (let j = 0; j < 4; j++) { + bits <<= 6; + const c = base64[i + j]; + if (c !== '=') bits |= LOOKUP.indexOf(c); + } + for (let j = p + 2; j >= p; j--) { + if (j < bytesLength) bytes[j] = bits; + bits >>= 8; + } + } -function checkFinished() { - if (missing_sources == 0) - InspectorTest.completeTest(); + return bytes; } -function handleScriptParsed(messageObject) -{ - var url = messageObject.params.url; - InspectorTest.log("Script #" + num_scripts + " parsed. URL: " + url); - ++num_scripts; - - if (url.startsWith("wasm://")) { - ++missing_sources; - function dumpScriptSource(message) { - InspectorTest.log("Source for " + url + ":"); - InspectorTest.log(message.result.scriptSource); - --missing_sources; +function trackScripts(debuggerParams) { + let {id: sessionId, Protocol} = contextGroup.connect(); + let scripts = []; + + Protocol.Debugger.enable(debuggerParams); + Protocol.Debugger.onScriptParsed(handleScriptParsed); + + async function loadScript({url, scriptId, sourceMapURL}) { + InspectorTest.log(`Session #${sessionId}: Script #${scripts.length} parsed. URL: ${url}. Source map URL: ${sourceMapURL}`); + let scriptSource; + if (sourceMapURL) { + let {result: {bytecode}} = await Protocol.Debugger.getWasmBytecode({scriptId}); + // Binary value is represented as base64 in JSON, decode it. + bytecode = decodeBase64(bytecode); + // Check that it can be parsed back to a WebAssembly module. + let module = new WebAssembly.Module(bytecode); + scriptSource = ` +Raw: ${Array.from(bytecode, b => ('0' + b.toString(16)).slice(-2)).join(' ')} +Imports: [${WebAssembly.Module.imports(module).map(i => `${i.name}: ${i.kind} from "${i.module}"`).join(', ')}] +Exports: [${WebAssembly.Module.exports(module).map(e => `${e.name}: ${e.kind}`).join(', ')}] + `.trim(); + } else { + ({result: {scriptSource}} = await Protocol.Debugger.getScriptSource({scriptId})); } + InspectorTest.log(`Session #${sessionId}: Source for ${url}:`); + InspectorTest.log(scriptSource); + } - Protocol.Debugger.getScriptSource({scriptId: messageObject.params.scriptId}) - .then(dumpScriptSource.bind(null)) - .then(checkFinished); + function handleScriptParsed({params}) { + if (params.url.startsWith("wasm://")) { + scripts.push(loadScript(params)); + } } + + return { + Protocol, + getScripts: () => Promise.all(scripts), + }; } diff --git a/deps/v8/test/inspector/debugger/wasm-set-breakpoint-expected.txt b/deps/v8/test/inspector/debugger/wasm-set-breakpoint-expected.txt index 406d39dd9500e0..29ee78c65ad3a3 100644 --- a/deps/v8/test/inspector/debugger/wasm-set-breakpoint-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-set-breakpoint-expected.txt @@ -1,13 +1,13 @@ Tests stepping through wasm scripts. Instantiating. Waiting for two wasm scripts (ignoring first non-wasm script). -Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0: +Source of script wasm://wasm/wasm-18214bfe/wasm-18214bfe-0: 1: func $wasm_A 2: nop 3: nop 4: end -Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1: +Source of script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1: 1: func $wasm_B (param i32) 2: loop 3: local.get 0 @@ -22,12 +22,12 @@ Source of script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1: 12: end 13: end -Setting breakpoint on line 8 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Setting breakpoint on line 7 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Setting breakpoint on line 6 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Setting breakpoint on line 5 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Setting breakpoint on line 3 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Setting breakpoint on line 4 on script wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 +Setting breakpoint on line 8 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Setting breakpoint on line 7 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Setting breakpoint on line 6 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Setting breakpoint on line 5 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Setting breakpoint on line 3 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Setting breakpoint on line 4 on script wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 Calling main(4) Breaking on line 3 Breaking on line 4 diff --git a/deps/v8/test/inspector/debugger/wasm-set-breakpoint.js b/deps/v8/test/inspector/debugger/wasm-set-breakpoint.js index a9b676f8a7ee8d..1696a0f59ce022 100644 --- a/deps/v8/test/inspector/debugger/wasm-set-breakpoint.js +++ b/deps/v8/test/inspector/debugger/wasm-set-breakpoint.js @@ -17,12 +17,12 @@ builder.addFunction('wasm_B', kSig_v_i) .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprCallFunction, func_a_idx, // - kExprBr, 1, // continue kExprEnd, // - diff --git a/deps/v8/test/inspector/debugger/wasm-stepping-expected.txt b/deps/v8/test/inspector/debugger/wasm-stepping-expected.txt index c951dce4ba7989..4a1fd58f2b7e4d 100644 --- a/deps/v8/test/inspector/debugger/wasm-stepping-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-stepping-expected.txt @@ -3,10 +3,10 @@ Installing code an global variable. Calling instantiate function. Waiting for two wasm scripts to be parsed. Ignoring script with url v8://test/callInstantiate -Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0 -Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0... -Got wasm script: wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 -Requesting source for wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1... +Got wasm script: wasm://wasm/wasm-18214bfe/wasm-18214bfe-0 +Requesting source for wasm://wasm/wasm-18214bfe/wasm-18214bfe-0... +Got wasm script: wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 +Requesting source for wasm://wasm/wasm-18214bfe/wasm-18214bfe-1... func $wasm_A nop nop @@ -26,13 +26,13 @@ func $wasm_B (param i32) end end -Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1 +Setting breakpoint on line 7 (on the setlocal before the call), url wasm://wasm/wasm-18214bfe/wasm-18214bfe-1 { columnNumber : 6 lineNumber : 7 scriptId : <scriptId> } -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0 at wasm_B (7:6): - scope (global): -- skipped @@ -43,7 +43,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0 at wasm_B (8:6): - scope (global): -- skipped @@ -54,7 +54,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop at wasm_A (1:2): - scope (global): -- skipped @@ -70,7 +70,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:2:2: >nop at wasm_A (2:2): - scope (global): -- skipped @@ -86,7 +86,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1 at wasm_B (9:6): - scope (global): -- skipped @@ -97,7 +97,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0 at wasm_B (7:6): - scope (global): -- skipped @@ -108,7 +108,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0 at wasm_B (8:6): - scope (global): -- skipped @@ -119,7 +119,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1 at wasm_B (9:6): - scope (global): -- skipped @@ -130,7 +130,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.resume called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0 at wasm_B (7:6): - scope (global): -- skipped @@ -141,7 +141,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0 at wasm_B (8:6): - scope (global): -- skipped @@ -152,7 +152,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop at wasm_A (1:2): - scope (global): -- skipped @@ -168,7 +168,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1 at wasm_B (9:6): - scope (global): -- skipped @@ -179,7 +179,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:1:2: >loop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:1:2: >loop at wasm_B (1:2): - scope (global): -- skipped @@ -190,7 +190,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:2:4: >local.get 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:2:4: >local.get 0 at wasm_B (2:4): - scope (global): -- skipped @@ -201,7 +201,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:3:4: >if +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:3:4: >if at wasm_B (3:4): - scope (global): -- skipped @@ -212,7 +212,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:4:6: >local.get 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:4:6: >local.get 0 at wasm_B (4:6): - scope (global): -- skipped @@ -223,7 +223,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:5:6: >i32.const 1 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:5:6: >i32.const 1 at wasm_B (5:6): - scope (global): -- skipped @@ -234,7 +234,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:6:6: >i32.sub +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:6:6: >i32.sub at wasm_B (6:6): - scope (global): -- skipped @@ -245,7 +245,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:7:6: >local.set 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:7:6: >local.set 0 at wasm_B (7:6): - scope (global): -- skipped @@ -256,7 +256,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:8:6: >call 0 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:8:6: >call 0 at wasm_B (8:6): - scope (global): -- skipped @@ -267,7 +267,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:1:2: >nop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:1:2: >nop at wasm_A (1:2): - scope (global): -- skipped @@ -283,7 +283,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:2:2: >nop +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:2:2: >nop at wasm_A (2:2): - scope (global): -- skipped @@ -299,7 +299,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-0:3:0: >end +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-0:3:0: >end at wasm_A (3:0): - scope (global): -- skipped @@ -315,7 +315,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm://wasm/wasm-0c10a5fe/wasm-0c10a5fe-1:9:6: >br 1 +Paused at wasm://wasm/wasm-18214bfe/wasm-18214bfe-1:9:6: >br 1 at wasm_B (9:6): - scope (global): -- skipped diff --git a/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map-expected.txt b/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map-expected.txt index 34f9cf1df9d46c..325049fffb58be 100644 --- a/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map-expected.txt +++ b/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map-expected.txt @@ -1,16 +1,16 @@ Tests stepping through wasm scripts with source maps Installing code an global variable and instantiate. -Got wasm script: wasm-9b4bf87e +Got wasm script: wasm://wasm/wasm-3697f0fe Script sourceMapURL: abc -Requesting source for wasm-9b4bf87e... +Requesting source for wasm://wasm/wasm-3697f0fe... Source retrieved without error: true -Setting breakpoint on offset 54 (on the setlocal before the call), url wasm-9b4bf87e +Setting breakpoint on offset 54 (on the setlocal before the call), url wasm://wasm/wasm-3697f0fe { columnNumber : 54 lineNumber : 0 scriptId : <scriptId> } -Paused at wasm-9b4bf87e:0:54 +Paused at wasm://wasm/wasm-3697f0fe:0:54 at wasm_B (0:54): - scope (global): -- skipped @@ -21,7 +21,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:56 +Paused at wasm://wasm/wasm-3697f0fe:0:56 at wasm_B (0:56): - scope (global): -- skipped @@ -32,7 +32,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:38 +Paused at wasm://wasm/wasm-3697f0fe:0:38 at wasm_A (0:38): - scope (global): -- skipped @@ -48,7 +48,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm-9b4bf87e:0:39 +Paused at wasm://wasm/wasm-3697f0fe:0:39 at wasm_A (0:39): - scope (global): -- skipped @@ -64,7 +64,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm-9b4bf87e:0:58 +Paused at wasm://wasm/wasm-3697f0fe:0:58 at wasm_B (0:58): - scope (global): -- skipped @@ -75,7 +75,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm-9b4bf87e:0:54 +Paused at wasm://wasm/wasm-3697f0fe:0:54 at wasm_B (0:54): - scope (global): -- skipped @@ -86,7 +86,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm-9b4bf87e:0:56 +Paused at wasm://wasm/wasm-3697f0fe:0:56 at wasm_B (0:56): - scope (global): -- skipped @@ -97,7 +97,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOver called -Paused at wasm-9b4bf87e:0:58 +Paused at wasm://wasm/wasm-3697f0fe:0:58 at wasm_B (0:58): - scope (global): -- skipped @@ -108,7 +108,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.resume called -Paused at wasm-9b4bf87e:0:54 +Paused at wasm://wasm/wasm-3697f0fe:0:54 at wasm_B (0:54): - scope (global): -- skipped @@ -119,7 +119,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:56 +Paused at wasm://wasm/wasm-3697f0fe:0:56 at wasm_B (0:56): - scope (global): -- skipped @@ -130,7 +130,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:38 +Paused at wasm://wasm/wasm-3697f0fe:0:38 at wasm_A (0:38): - scope (global): -- skipped @@ -146,7 +146,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepOut called -Paused at wasm-9b4bf87e:0:58 +Paused at wasm://wasm/wasm-3697f0fe:0:58 at wasm_B (0:58): - scope (global): -- skipped @@ -157,7 +157,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:43 +Paused at wasm://wasm/wasm-3697f0fe:0:43 at wasm_B (0:43): - scope (global): -- skipped @@ -168,7 +168,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:45 +Paused at wasm://wasm/wasm-3697f0fe:0:45 at wasm_B (0:45): - scope (global): -- skipped @@ -179,7 +179,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:47 +Paused at wasm://wasm/wasm-3697f0fe:0:47 at wasm_B (0:47): - scope (global): -- skipped @@ -190,7 +190,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:49 +Paused at wasm://wasm/wasm-3697f0fe:0:49 at wasm_B (0:49): - scope (global): -- skipped @@ -201,7 +201,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:51 +Paused at wasm://wasm/wasm-3697f0fe:0:51 at wasm_B (0:51): - scope (global): -- skipped @@ -212,7 +212,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:53 +Paused at wasm://wasm/wasm-3697f0fe:0:53 at wasm_B (0:53): - scope (global): -- skipped @@ -223,7 +223,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:54 +Paused at wasm://wasm/wasm-3697f0fe:0:54 at wasm_B (0:54): - scope (global): -- skipped @@ -234,7 +234,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:56 +Paused at wasm://wasm/wasm-3697f0fe:0:56 at wasm_B (0:56): - scope (global): -- skipped @@ -245,7 +245,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:38 +Paused at wasm://wasm/wasm-3697f0fe:0:38 at wasm_A (0:38): - scope (global): -- skipped @@ -261,7 +261,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:39 +Paused at wasm://wasm/wasm-3697f0fe:0:39 at wasm_A (0:39): - scope (global): -- skipped @@ -277,7 +277,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:40 +Paused at wasm://wasm/wasm-3697f0fe:0:40 at wasm_A (0:40): - scope (global): -- skipped @@ -293,7 +293,7 @@ at (anonymous) (0:17): - scope (global): -- skipped Debugger.stepInto called -Paused at wasm-9b4bf87e:0:58 +Paused at wasm://wasm/wasm-3697f0fe:0:58 at wasm_B (0:58): - scope (global): -- skipped diff --git a/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map.js b/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map.js index 1c9ec9557772cf..57b2fd581cbf79 100644 --- a/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map.js +++ b/deps/v8/test/inspector/debugger/wasm-stepping-with-source-map.js @@ -17,12 +17,12 @@ builder.addFunction('wasm_B', kSig_v_i) .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprCallFunction, func_a_idx, // - kExprBr, 1, // continue kExprEnd, // - diff --git a/deps/v8/test/inspector/debugger/wasm-stepping.js b/deps/v8/test/inspector/debugger/wasm-stepping.js index 0fda6b73be9571..01d83b6696fbd3 100644 --- a/deps/v8/test/inspector/debugger/wasm-stepping.js +++ b/deps/v8/test/inspector/debugger/wasm-stepping.js @@ -6,9 +6,9 @@ let {session, contextGroup, Protocol} = InspectorTest.start('Tests stepping thro utils.load('test/mjsunit/wasm/wasm-module-builder.js'); -var builder = new WasmModuleBuilder(); +let builder = new WasmModuleBuilder(); -var func_a_idx = +let func_a_idx = builder.addFunction('wasm_A', kSig_v_v).addBody([kExprNop, kExprNop]).index; // wasm_B calls wasm_A <param0> times. @@ -16,12 +16,12 @@ builder.addFunction('wasm_B', kSig_v_i) .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprCallFunction, func_a_idx, // - kExprBr, 1, // continue kExprEnd, // - @@ -30,26 +30,26 @@ builder.addFunction('wasm_B', kSig_v_i) ]) .exportAs('main'); -var module_bytes = builder.toArray(); +let module_bytes = builder.toArray(); function instantiate(bytes) { - var buffer = new ArrayBuffer(bytes.length); - var view = new Uint8Array(buffer); - for (var i = 0; i < bytes.length; ++i) { + let buffer = new ArrayBuffer(bytes.length); + let view = new Uint8Array(buffer); + for (let i = 0; i < bytes.length; ++i) { view[i] = bytes[i] | 0; } - var module = new WebAssembly.Module(buffer); + let module = new WebAssembly.Module(buffer); // Set global variable. instance = new WebAssembly.Instance(module); } -var evalWithUrl = (code, url) => Protocol.Runtime.evaluate( +let evalWithUrl = (code, url) => Protocol.Runtime.evaluate( {'expression': code + '\n//# sourceURL=v8://test/' + url}); Protocol.Debugger.onPaused(handlePaused); -var wasm_B_scriptId; -var step_actions = [ +let wasm_B_scriptId; +let step_actions = [ 'stepInto', // == stepOver, to call instruction 'stepInto', // into call to wasm_A 'stepOver', // over first nop @@ -69,38 +69,33 @@ var step_actions = [ // then just resume. 'resume' ]; -for (var action of step_actions) { +for (let action of step_actions) { InspectorTest.logProtocolCommandCalls('Debugger.' + action) } -var sources = {}; -var urls = {}; -var afterTwoSourcesCallback; - -Protocol.Debugger.enable() - .then(() => InspectorTest.log('Installing code an global variable.')) - .then( - () => evalWithUrl('var instance;\n' + instantiate.toString(), 'setup')) - .then(() => InspectorTest.log('Calling instantiate function.')) - .then( - () => - (evalWithUrl( - 'instantiate(' + JSON.stringify(module_bytes) + ')', - 'callInstantiate'), - 0)) - .then(waitForTwoWasmScripts) - .then( - () => InspectorTest.log( - 'Setting breakpoint on line 7 (on the setlocal before the call), url ' + - urls[wasm_B_scriptId])) - .then( - () => Protocol.Debugger.setBreakpoint( - {'location': {'scriptId': wasm_B_scriptId, 'lineNumber': 7}})) - .then(printFailure) - .then(msg => InspectorTest.logMessage(msg.result.actualLocation)) - .then(() => evalWithUrl('instance.exports.main(4)', 'runWasm')) - .then(() => InspectorTest.log('exports.main returned!')) - .then(() => InspectorTest.log('Finished!')) - .then(InspectorTest.completeTest); +let sources = {}; +let urls = {}; +let afterTwoSourcesCallback; + +(async function Test() { + await Protocol.Debugger.enable(); + InspectorTest.log('Installing code an global variable.'); + await evalWithUrl('var instance;\n' + instantiate.toString(), 'setup'); + InspectorTest.log('Calling instantiate function.'); + evalWithUrl( + 'instantiate(' + JSON.stringify(module_bytes) + ')', 'callInstantiate'); + await waitForTwoWasmScripts(); + InspectorTest.log( + 'Setting breakpoint on line 7 (on the setlocal before the call), url ' + + urls[wasm_B_scriptId]); + let msg = await Protocol.Debugger.setBreakpoint( + {'location': {'scriptId': wasm_B_scriptId, 'lineNumber': 7}}); + printFailure(msg); + InspectorTest.logMessage(msg.result.actualLocation); + await evalWithUrl('instance.exports.main(4)', 'runWasm'); + InspectorTest.log('exports.main returned!'); + InspectorTest.log('Finished!'); + InspectorTest.completeTest(); +})(); function printFailure(message) { if (!message.result) { @@ -109,41 +104,37 @@ function printFailure(message) { return message; } -function waitForTwoWasmScripts() { - var num = 0; +async function waitForTwoWasmScripts() { + let num = 0; InspectorTest.log('Waiting for two wasm scripts to be parsed.'); - var promise = new Promise(fulfill => gotBothSources = fulfill); - function waitForMore() { - if (num == 2) return promise; - Protocol.Debugger.onceScriptParsed() - .then(handleNewScript) - .then(waitForMore); + let source_promises = []; + async function getWasmSource(scriptId) { + let msg = await Protocol.Debugger.getScriptSource({scriptId: scriptId}); + printFailure(msg); + InspectorTest.log(msg.result.scriptSource); + sources[scriptId] = msg.result.scriptSource; } - function handleNewScript(msg) { - var url = msg.params.url; + while (num < 2) { + let msg = await Protocol.Debugger.onceScriptParsed(); + let url = msg.params.url; if (!url.startsWith('wasm://')) { InspectorTest.log('Ignoring script with url ' + url); - return; + continue; } num += 1; - var scriptId = msg.params.scriptId; + let scriptId = msg.params.scriptId; urls[scriptId] = url; InspectorTest.log('Got wasm script: ' + url); if (url.substr(-2) == '-1') wasm_B_scriptId = scriptId; InspectorTest.log('Requesting source for ' + url + '...'); - Protocol.Debugger.getScriptSource({scriptId: scriptId}) - .then(printFailure) - .then(msg => sources[scriptId] = msg.result.scriptSource) - .then(InspectorTest.log) - .then(() => Object.keys(sources).length == 2 ? gotBothSources() : 0); + source_promises.push(getWasmSource(scriptId)); } - waitForMore(); - return promise; + await Promise.all(source_promises); } function printPauseLocation(scriptId, lineNr, columnNr) { - var lines = sources[scriptId].split('\n'); - var line = '<illegal line number>'; + let lines = sources[scriptId].split('\n'); + let line = '<illegal line number>'; if (lineNr < lines.length) { line = lines[lineNr]; if (columnNr < line.length) { @@ -157,7 +148,7 @@ function printPauseLocation(scriptId, lineNr, columnNr) { async function getValueString(value) { if (value.type == 'object') { - var msg = await Protocol.Runtime.callFunctionOn({ + let msg = await Protocol.Runtime.callFunctionOn({ objectId: value.objectId, functionDeclaration: 'function () { return JSON.stringify(this); }' }); @@ -169,24 +160,24 @@ async function getValueString(value) { async function dumpProperties(message) { printFailure(message); - for (var value of message.result.result) { - var value_str = await getValueString(value.value); + for (let value of message.result.result) { + let value_str = await getValueString(value.value); InspectorTest.log(' ' + value.name + ': ' + value_str); } } async function dumpScopeChainsOnPause(message) { - for (var frame of message.params.callFrames) { - var functionName = frame.functionName || '(anonymous)'; - var lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber; - var columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber; + for (let frame of message.params.callFrames) { + let functionName = frame.functionName || '(anonymous)'; + let lineNumber = frame.location ? frame.location.lineNumber : frame.lineNumber; + let columnNumber = frame.location ? frame.location.columnNumber : frame.columnNumber; InspectorTest.log(`at ${functionName} (${lineNumber}:${columnNumber}):`); - for (var scope of frame.scopeChain) { + for (let scope of frame.scopeChain) { InspectorTest.logObject(' - scope (' + scope.type + '):'); if (scope.type == 'global') { InspectorTest.logObject(' -- skipped'); } else { - var properties = await Protocol.Runtime.getProperties( + let properties = await Protocol.Runtime.getProperties( {'objectId': scope.object.objectId}); await dumpProperties(properties); } @@ -194,9 +185,10 @@ async function dumpScopeChainsOnPause(message) { } } -function handlePaused(msg) { - var loc = msg.params.callFrames[0].location; +async function handlePaused(msg) { + let loc = msg.params.callFrames[0].location; printPauseLocation(loc.scriptId, loc.lineNumber, loc.columnNumber); - dumpScopeChainsOnPause(msg) - .then(Protocol.Debugger[step_actions.shift() || 'resume']); + await dumpScopeChainsOnPause(msg); + let action = step_actions.shift() || 'resume'; + await Protocol.Debugger[action](); } diff --git a/deps/v8/test/inspector/inspector-test.cc b/deps/v8/test/inspector/inspector-test.cc index 0a4cd48e92381b..0f39bc9417a9b2 100644 --- a/deps/v8/test/inspector/inspector-test.cc +++ b/deps/v8/test/inspector/inspector-test.cc @@ -968,8 +968,8 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { data->StoreCurrentStackTrace(description_view); v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, sizeof(id)); - *static_cast<v8_inspector::V8StackTraceId*>(buffer->GetContents().Data()) = - id; + *static_cast<v8_inspector::V8StackTraceId*>( + buffer->GetBackingStore()->Data()) = id; args.GetReturnValue().Set(buffer); } @@ -983,7 +983,7 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { IsolateData* data = IsolateData::FromContext(context); v8_inspector::V8StackTraceId* id = static_cast<v8_inspector::V8StackTraceId*>( - args[0].As<v8::ArrayBuffer>()->GetContents().Data()); + args[0].As<v8::ArrayBuffer>()->GetBackingStore()->Data()); data->ExternalAsyncTaskStarted(*id); } @@ -997,7 +997,7 @@ class InspectorExtension : public IsolateData::SetupGlobalTask { IsolateData* data = IsolateData::FromContext(context); v8_inspector::V8StackTraceId* id = static_cast<v8_inspector::V8StackTraceId*>( - args[0].As<v8::ArrayBuffer>()->GetContents().Data()); + args[0].As<v8::ArrayBuffer>()->GetBackingStore()->Data()); data->ExternalAsyncTaskFinished(*id); } diff --git a/deps/v8/test/inspector/isolate-data.cc b/deps/v8/test/inspector/isolate-data.cc index ae4126407259c7..8011007e3480d3 100644 --- a/deps/v8/test/inspector/isolate-data.cc +++ b/deps/v8/test/inspector/isolate-data.cc @@ -61,8 +61,9 @@ IsolateData::IsolateData(TaskRunner* task_runner, : task_runner_(task_runner), setup_global_tasks_(std::move(setup_global_tasks)) { v8::Isolate::CreateParams params; - params.array_buffer_allocator = - v8::ArrayBuffer::Allocator::NewDefaultAllocator(); + array_buffer_allocator_.reset( + v8::ArrayBuffer::Allocator::NewDefaultAllocator()); + params.array_buffer_allocator = array_buffer_allocator_.get(); params.snapshot_blob = startup_data; params.only_terminate_in_safe_scope = true; isolate_.reset(v8::Isolate::New(params)); diff --git a/deps/v8/test/inspector/isolate-data.h b/deps/v8/test/inspector/isolate-data.h index d569ab11e0411f..fc15c3b5f35abb 100644 --- a/deps/v8/test/inspector/isolate-data.h +++ b/deps/v8/test/inspector/isolate-data.h @@ -6,6 +6,7 @@ #define V8_TEST_INSPECTOR_PROTOCOL_ISOLATE_DATA_H_ #include <map> +#include <memory> #include "include/v8-inspector.h" #include "include/v8-platform.h" @@ -129,6 +130,7 @@ class IsolateData : public v8_inspector::V8InspectorClient { TaskRunner* task_runner_; SetupGlobalTasks setup_global_tasks_; + std::unique_ptr<v8::ArrayBuffer::Allocator> array_buffer_allocator_; std::unique_ptr<v8::Isolate, IsolateDeleter> isolate_; std::unique_ptr<v8_inspector::V8Inspector> inspector_; int last_context_group_id_ = 0; diff --git a/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks-expected.txt b/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks-expected.txt new file mode 100644 index 00000000000000..a6be5b9121e8ea --- /dev/null +++ b/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks-expected.txt @@ -0,0 +1,72 @@ +Tests that Runtime.evaluate can run with breaks disabled. +Test disableBreaks: false +paused +{ + id : <messageId> + result : { + result : { + type : undefined + } + } +} +Test disableBreaks: true +{ + id : <messageId> + result : { + result : { + type : undefined + } + } +} +Test calling out with disableBreaks: false +paused +{ + id : <messageId> + result : { + result : { + type : undefined + } + } +} +Test calling out with disableBreaks: true +{ + id : <messageId> + result : { + result : { + type : undefined + } + } +} +Test Debugger.pause with disableBreaks: false +{ + id : <messageId> + result : { + } +} +paused +{ + id : <messageId> + result : { + result : { + description : 1 + type : number + value : 1 + } + } +} +Test Debugger.pause with disableBreaks: true +{ + id : <messageId> + result : { + } +} +{ + id : <messageId> + result : { + result : { + description : 1 + type : number + value : 1 + } + } +} diff --git a/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks.js b/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks.js new file mode 100644 index 00000000000000..43ddc5278c6513 --- /dev/null +++ b/deps/v8/test/inspector/runtime/evaluate-with-disable-breaks.js @@ -0,0 +1,60 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate can run with breaks disabled."); + +session.setupScriptMap(); +contextGroup.addScript(` + function f() { + debugger; + } //# sourceURL=test.js`); +Protocol.Runtime.enable(); +Protocol.Debugger.enable(); + +Protocol.Debugger.onPaused(message => { + InspectorTest.log("paused"); + Protocol.Debugger.resume(); +}); + +(async function() { + InspectorTest.log("Test disableBreaks: false"); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "debugger;", + disableBreaks: false + })); + + InspectorTest.log("Test disableBreaks: true"); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "debugger;", + disableBreaks: true + })); + + InspectorTest.log("Test calling out with disableBreaks: false"); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "f();", + disableBreaks: false + })); + + InspectorTest.log("Test calling out with disableBreaks: true"); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "f();", + disableBreaks: true + })); + + InspectorTest.log("Test Debugger.pause with disableBreaks: false"); + InspectorTest.logMessage(await Protocol.Debugger.pause()); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "1", + disableBreaks: false + })); + + InspectorTest.log("Test Debugger.pause with disableBreaks: true"); + InspectorTest.logMessage(await Protocol.Debugger.pause()); + InspectorTest.logMessage(await Protocol.Runtime.evaluate({ + expression: "1", + disableBreaks: true + })); + + InspectorTest.completeTest(); +})(); diff --git a/deps/v8/test/inspector/task-runner.h b/deps/v8/test/inspector/task-runner.h index 41a57295715696..afc3c39ab2b827 100644 --- a/deps/v8/test/inspector/task-runner.h +++ b/deps/v8/test/inspector/task-runner.h @@ -6,6 +6,7 @@ #define V8_TEST_INSPECTOR_PROTOCOL_TASK_RUNNER_H_ #include <map> +#include <memory> #include "include/v8-inspector.h" #include "include/v8-platform.h" diff --git a/deps/v8/test/intl/assert.js b/deps/v8/test/intl/assert.js index a6367a8cf254db..ae1646cc023b89 100644 --- a/deps/v8/test/intl/assert.js +++ b/deps/v8/test/intl/assert.js @@ -157,7 +157,7 @@ function assertThrows(code, type_opt, cause_opt) { assertInstanceof(e, type_opt); } if (arguments.length >= 3) { - assertEquals(cause_opt, e.type, 'thrown exception type mismatch'); + assertEquals(cause_opt, e.message, 'thrown exception type mismatch'); } // Success. return; diff --git a/deps/v8/test/intl/bigint/tolocalestring.js b/deps/v8/test/intl/bigint/tolocalestring.js index d0b6792ea8387a..449d644546a6e8 100644 --- a/deps/v8/test/intl/bigint/tolocalestring.js +++ b/deps/v8/test/intl/bigint/tolocalestring.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-bigint - var locales = [ "en", // "1,234,567,890,123,456" "de", // "1.234.567.890.123.456" diff --git a/deps/v8/test/intl/date-format/check-calendar.js b/deps/v8/test/intl/date-format/check-calendar.js index b6c7c58ea3da56..f9e5565f600f43 100644 --- a/deps/v8/test/intl/date-format/check-calendar.js +++ b/deps/v8/test/intl/date-format/check-calendar.js @@ -7,6 +7,15 @@ let invalidCalendar = [ "invalid", "abce", + "abc-defghi", +]; + +let illFormedCalendar = [ + "", + "i", + "ij", + "abcdefghi", + "abc-ab", ]; // https://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml @@ -36,8 +45,17 @@ let locales = [ "ar", ]; - invalidCalendar.forEach(function(calendar) { + locales.forEach(function(base) { + var df; + assertDoesNotThrow(() => df = new Intl.DateTimeFormat([base], {calendar})); + assertEquals( + (new Intl.DateTimeFormat([base])).resolvedOptions().calendar, + df.resolvedOptions().calendar); + }); +}); + +illFormedCalendar.forEach(function(calendar) { assertThrows( () => new Intl.DateTimeFormat(["en"], {calendar}), RangeError); diff --git a/deps/v8/test/intl/date-format/check-numbering-system.js b/deps/v8/test/intl/date-format/check-numbering-system.js index 0bb71c5358b2a6..aa6ac8728e29a4 100644 --- a/deps/v8/test/intl/date-format/check-numbering-system.js +++ b/deps/v8/test/intl/date-format/check-numbering-system.js @@ -10,6 +10,15 @@ let invalidNumberingSystem = [ "finance", "native", "traditio", + "abc-defghi", +]; + +let illFormedNumberingSystem = [ + "", + "i", + "ij", + "abcdefghi", + "abc-ab", ]; // https://tc39.github.io/ecma402/#table-numbering-system-digits @@ -43,13 +52,22 @@ let locales = [ "ar", ]; - invalidNumberingSystem.forEach(function(numberingSystem) { + locales.forEach(function(base) { + var df; + assertDoesNotThrow( + () => df = new Intl.DateTimeFormat([base], {numberingSystem})); + assertEquals( + (new Intl.DateTimeFormat([base])).resolvedOptions().numberingSystem, + df.resolvedOptions().numberingSystem); + }); +}); + +illFormedNumberingSystem.forEach(function(numberingSystem) { assertThrows( () => new Intl.DateTimeFormat(["en"], {numberingSystem}), RangeError); -} -); +}); let value = new Date(); validNumberingSystem.forEach(function(numberingSystem) { diff --git a/deps/v8/test/intl/date-format/constructor-calendar-numberingSytem-order.js b/deps/v8/test/intl/date-format/constructor-calendar-numberingSytem-order.js new file mode 100644 index 00000000000000..75b4a456d4b843 --- /dev/null +++ b/deps/v8/test/intl/date-format/constructor-calendar-numberingSytem-order.js @@ -0,0 +1,35 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-add-calendar-numbering-system +const actual = []; + +const options = { + get localeMatcher() { + actual.push("localeMatcher"); + return undefined; + }, + get calendar() { + actual.push("calendar"); + return undefined; + }, + get numberingSystem() { + actual.push("numberingSystem"); + return undefined; + }, + get hour12() { + actual.push("hour12"); + return undefined; + }, +}; + +const expected = [ + "localeMatcher", + "calendar", + "numberingSystem", + "hour12" +]; + +let df = new Intl.DateTimeFormat(undefined, options); +assertEquals(actual.join(":"), expected.join(":")); diff --git a/deps/v8/test/intl/date-format/constructor-date-style-order.js b/deps/v8/test/intl/date-format/constructor-date-style-order.js index 8e601b48d34a5e..b148d8eea7734e 100644 --- a/deps/v8/test/intl/date-format/constructor-date-style-order.js +++ b/deps/v8/test/intl/date-format/constructor-date-style-order.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Throws only once during construction. // Check for all getters to prevent regression. // Preserve the order of getter initialization. diff --git a/deps/v8/test/intl/date-format/constructor-date-time-style-order.js b/deps/v8/test/intl/date-format/constructor-date-time-style-order.js index d4d114662fed33..8152b17618d9da 100644 --- a/deps/v8/test/intl/date-format/constructor-date-time-style-order.js +++ b/deps/v8/test/intl/date-format/constructor-date-time-style-order.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Throws only once during construction. // Check for all getters to prevent regression. // Preserve the order of getter initialization. diff --git a/deps/v8/test/intl/date-format/constructor-date-time-style.js b/deps/v8/test/intl/date-format/constructor-date-time-style.js index f4bc40b3968dc6..477c5c5a01a2c7 100644 --- a/deps/v8/test/intl/date-format/constructor-date-time-style.js +++ b/deps/v8/test/intl/date-format/constructor-date-time-style.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - var validStyle = ["full", "long", "medium", "short", undefined]; var invalidStyle = ["narrow", "numeric"]; diff --git a/deps/v8/test/intl/date-format/constructor-no-style-order.js b/deps/v8/test/intl/date-format/constructor-no-style-order.js index bd4bc4cc379e38..a671968367898d 100644 --- a/deps/v8/test/intl/date-format/constructor-no-style-order.js +++ b/deps/v8/test/intl/date-format/constructor-no-style-order.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Throws only once during construction. // Check for all getters to prevent regression. // Preserve the order of getter initialization. diff --git a/deps/v8/test/intl/date-format/constructor-time-style-order.js b/deps/v8/test/intl/date-format/constructor-time-style-order.js index d35f21a1960267..b3c8850dde226a 100644 --- a/deps/v8/test/intl/date-format/constructor-time-style-order.js +++ b/deps/v8/test/intl/date-format/constructor-time-style-order.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Throws only once during construction. // Check for all getters to prevent regression. // Preserve the order of getter initialization. diff --git a/deps/v8/test/intl/date-format/en-format-range-to-parts.js b/deps/v8/test/intl/date-format/en-format-range-to-parts.js index c2421812f81a57..9d9b2b81934fff 100644 --- a/deps/v8/test/intl/date-format/en-format-range-to-parts.js +++ b/deps/v8/test/intl/date-format/en-format-range-to-parts.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-date-format-range - const date1 = new Date("2019-01-03T03:20"); const date2 = new Date("2019-01-05T19:33"); const date3 = new Date("2019-01-05T22:57"); diff --git a/deps/v8/test/intl/date-format/format-range-to-parts.js b/deps/v8/test/intl/date-format/format-range-to-parts.js index b2eac1765c600b..3ffd61ba7e4732 100644 --- a/deps/v8/test/intl/date-format/format-range-to-parts.js +++ b/deps/v8/test/intl/date-format/format-range-to-parts.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-date-format-range - let descriptor = Object.getOwnPropertyDescriptor( Intl.DateTimeFormat.prototype, "formatRangeToParts"); assertTrue(descriptor.writable); diff --git a/deps/v8/test/intl/date-format/format-range.js b/deps/v8/test/intl/date-format/format-range.js index f00f228b07b47b..066e53e1bd2ba5 100644 --- a/deps/v8/test/intl/date-format/format-range.js +++ b/deps/v8/test/intl/date-format/format-range.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-date-format-range - let descriptor = Object.getOwnPropertyDescriptor( Intl.DateTimeFormat.prototype, "formatRange"); assertTrue(descriptor.writable); diff --git a/deps/v8/test/intl/date-format/format-with-extensions.js b/deps/v8/test/intl/date-format/format-with-extensions.js index b9eb0fcb1e0ccf..9aa37e1f32ec63 100644 --- a/deps/v8/test/intl/date-format/format-with-extensions.js +++ b/deps/v8/test/intl/date-format/format-with-extensions.js @@ -20,18 +20,9 @@ function checkFormat(locale, options, expected) { assertEquals(expected.formatted, formatted); } -// Even though the calendar is Chinese, the best pattern search for formatting -// should be done in the base locale (i.e. en or en-GB instead of -// en-u-ca-chinese or en-GB-u-ca-chinese). Otherwise, {year: 'numeric'} would -// results in '35 (wu-su)' where 'wu-su' is the designation for year 35 in the -// 60-year cycle. See https://github.com/tc39/ecma402/issues/225 . [ ["en", "gregory", "latn", "2018"], ["en-GB", "gregory", "latn", "2018"], - ["en-u-ca-chinese", "chinese", "latn", "35"], - ["en-GB-u-ca-chinese", "chinese", "latn", "35"], - ["en-u-ca-chinese-nu-deva", "chinese", "deva", "३५"], - ["en-GB-u-ca-chinese-nu-deva", "chinese", "deva", "३५"], ].forEach(function(entry) { checkFormat(entry[0], {year: 'numeric'}, { cal: entry[1], @@ -48,9 +39,6 @@ const enGBTypes = ["day", "literal", "month", "literal", "year"]; ["en", "gregory", "latn", "6/21/2018", enUSTypes], ["en-GB", "gregory", "latn", "21/06/2018", enGBTypes], ["en-u-nu-deva", "gregory", "deva", "६/२१/२०१८", enUSTypes], - ["en-u-ca-chinese", "chinese", "latn", "5/8/35", enUSTypes], - ["en-GB-u-ca-chinese", "chinese", "latn", "08/05/35", enGBTypes], - ["en-u-ca-chinese-nu-deva", "chinese", "deva", "५/८/३५", enUSTypes], ].forEach(function(entry) { checkFormat(entry[0], {}, { cal: entry[1], diff --git a/deps/v8/test/intl/date-format/property-override-date-style.js b/deps/v8/test/intl/date-format/property-override-date-style.js index 542ef5eb2709be..c7965a41c5f186 100644 --- a/deps/v8/test/intl/date-format/property-override-date-style.js +++ b/deps/v8/test/intl/date-format/property-override-date-style.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Checks for security holes introduced by Object.property overrides. // For example: // Object.defineProperty(Array.prototype, 'locale', { @@ -34,8 +32,6 @@ var expectedProperties = [ 'calendar', 'numberingSystem', 'timeZone', - 'hourCycle', - 'hour12', 'dateStyle', ]; diff --git a/deps/v8/test/intl/date-format/property-override-date-time-style.js b/deps/v8/test/intl/date-format/property-override-date-time-style.js index 8977be2967f423..6cb7af171f386d 100644 --- a/deps/v8/test/intl/date-format/property-override-date-time-style.js +++ b/deps/v8/test/intl/date-format/property-override-date-time-style.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Checks for security holes introduced by Object.property overrides. // For example: // Object.defineProperty(Array.prototype, 'locale', { diff --git a/deps/v8/test/intl/date-format/property-override-time-style.js b/deps/v8/test/intl/date-format/property-override-time-style.js index ab8fa22d0b2f05..50cb6e26f16852 100644 --- a/deps/v8/test/intl/date-format/property-override-time-style.js +++ b/deps/v8/test/intl/date-format/property-override-time-style.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-datetime-style - // Checks for security holes introduced by Object.property overrides. // For example: // Object.defineProperty(Array.prototype, 'locale', { diff --git a/deps/v8/test/intl/date-format/related-year.js b/deps/v8/test/intl/date-format/related-year.js new file mode 100644 index 00000000000000..a3d9e9dcb4bc60 --- /dev/null +++ b/deps/v8/test/intl/date-format/related-year.js @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-other-calendars +// Test it will output relatedYear and yearName + +let df = new Intl.DateTimeFormat("zh-u-ca-chinese", {year: "numeric"}) +let date = new Date(2019, 5, 1); +assertEquals("2019己亥年", df.format(date)); +assertEquals([{type: "relatedYear", value: "2019"}, + {type: "yearName", value: "己亥"}, + {type: "literal", value: "年"}], + df.formatToParts(date)); diff --git a/deps/v8/test/intl/general/case-mapping.js b/deps/v8/test/intl/general/case-mapping.js index 79d162482123c2..606af09c442987 100644 --- a/deps/v8/test/intl/general/case-mapping.js +++ b/deps/v8/test/intl/general/case-mapping.js @@ -125,9 +125,6 @@ assertEquals("abci\u0307", "aBcI\u0307".toLowerCase()); // Anything other than 'tr' and 'az' behave like root for U+0307. assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("fil")); assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("zh-Hant-TW")); -assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-klingon")); -assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("i-enochian")); -assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("x-foobar")); // Up to 8 chars are allowed for the primary language tag in BCP 47. assertEquals("abci\u0307", "aBcI\u0307".toLocaleLowerCase("longlang")); diff --git a/deps/v8/test/intl/general/grandfathered_tags_without_preferred_value.js b/deps/v8/test/intl/general/grandfathered_tags_without_preferred_value.js index 808e50d2088433..16bf369601fc90 100644 --- a/deps/v8/test/intl/general/grandfathered_tags_without_preferred_value.js +++ b/deps/v8/test/intl/general/grandfathered_tags_without_preferred_value.js @@ -8,18 +8,8 @@ // v8 works around that ICU issue. // See https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry . ["cel-gaulish", "cel-gaulish"], - ["i-default", "i-default"], - ["i-mingo", "i-mingo"], - ["i-enochian", "i-enochian"], - ["zh-min", "zh-min"], // Matching should be case-insensitive. - ["I-default", "i-default"], - ["i-DEFAULT", "i-default"], - ["I-DEFAULT", "i-default"], - ["i-DEfauLT", "i-default"], - ["zh-Min", "zh-min"], - ["Zh-min", "zh-min"], ].forEach(([inputLocale, expectedLocale]) => { const canonicalLocales = Intl.getCanonicalLocales(inputLocale); assertEquals(canonicalLocales.length, 1); diff --git a/deps/v8/test/intl/general/language_tags_with_preferred_values.js b/deps/v8/test/intl/general/language_tags_with_preferred_values.js index 4f2fbbfb2edd11..462bcfb8f74437 100644 --- a/deps/v8/test/intl/general/language_tags_with_preferred_values.js +++ b/deps/v8/test/intl/general/language_tags_with_preferred_values.js @@ -9,8 +9,6 @@ // Matching should be case-insensitive. ["sgn-De", "gsg"], - ["sgn-BE-FR", "sfb"], - ["Sgn-bE-Fr", "sfb"], // deprecated region tag ["und-Latn-dd", "und-Latn-DE"], diff --git a/deps/v8/test/intl/general/supported-locales-of.js b/deps/v8/test/intl/general/supported-locales-of.js index eb5c426f0744c6..84984c1d25ecc7 100644 --- a/deps/v8/test/intl/general/supported-locales-of.js +++ b/deps/v8/test/intl/general/supported-locales-of.js @@ -83,16 +83,15 @@ for (const service of services) { privateuseLocale = service.supportedLocalesOf("en-US-x-twain"); assertEquals("en-US-x-twain", privateuseLocale[0]); - privateuseLocale2 = service.supportedLocalesOf("x-twain"); - assertEquals(undefined, privateuseLocale2[0]); + assertThrows(() => service.supportedLocalesOf("x-twain"), RangeError); + if (service != Intl.PluralRules) { grandfatheredLocale = service.supportedLocalesOf("art-lojban"); assertEquals(undefined, grandfatheredLocale[0]); } - grandfatheredLocale2 = service.supportedLocalesOf("i-pwn"); - assertEquals(undefined, grandfatheredLocale2[0]); + assertThrows(() => service.supportedLocalesOf("x-pwn"), RangeError); unicodeInPrivateuseLocale = service.supportedLocalesOf( "en-US-x-u-co-phonebk" diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status index ba54743d678cc2..669f5d93d541fd 100644 --- a/deps/v8/test/intl/intl.status +++ b/deps/v8/test/intl/intl.status @@ -36,9 +36,6 @@ # https://code.google.com/p/v8/issues/detail?id=9312 'regress-9312': [FAIL], - - # Slow tests. - 'regress-903566': [PASS, SLOW], }], # ALWAYS ['variant == no_wasm_traps', { @@ -71,12 +68,6 @@ 'relative-time-format/resolved-options-nu-extended': [FAIL], }], # 'system == android' -############################################################################## -['variant == stress', { - # Too slow. - 'regress-903566': [SKIP], -}], # 'variant == stress' - ############################################################################## ['variant == jitless and not embedded_builtins', { '*': [SKIP], diff --git a/deps/v8/test/intl/list-format/resolved-options.js b/deps/v8/test/intl/list-format/resolved-options.js index 42687990f995c2..a2cfff860695b2 100644 --- a/deps/v8/test/intl/list-format/resolved-options.js +++ b/deps/v8/test/intl/list-format/resolved-options.js @@ -144,7 +144,3 @@ assertEquals( assertEquals( 'ar', (new Intl.ListFormat(['xyz', 'ar'])).resolvedOptions().locale); - -assertEquals( - 'ar', - (new Intl.ListFormat(['i-default', 'ar'])).resolvedOptions().locale); diff --git a/deps/v8/test/intl/number-format/check-numbering-system.js b/deps/v8/test/intl/number-format/check-numbering-system.js index cd7884b8dc5d35..c9df98a671c1a8 100644 --- a/deps/v8/test/intl/number-format/check-numbering-system.js +++ b/deps/v8/test/intl/number-format/check-numbering-system.js @@ -10,6 +10,15 @@ let invalidNumberingSystem = [ "finance", "native", "traditio", + "abc-defghi", +]; + +let illFormedNumberingSystem = [ + "", + "i", + "ij", + "abcdefghi", + "abc-ab", ]; // https://tc39.github.io/ecma402/#table-numbering-system-digits @@ -45,11 +54,21 @@ let locales = [ invalidNumberingSystem.forEach(function(numberingSystem) { + locales.forEach(function(base) { + var df; + assertDoesNotThrow( + () => df = new Intl.NumberFormat([base], {numberingSystem})); + assertEquals( + (new Intl.NumberFormat([base])).resolvedOptions().numberingSystem, + df.resolvedOptions().numberingSystem); + }); +}); + +illFormedNumberingSystem.forEach(function(numberingSystem) { assertThrows( () => new Intl.NumberFormat(["en"], {numberingSystem}), RangeError); -} -); +}); let value = 1234567.89; validNumberingSystem.forEach(function(numberingSystem) { diff --git a/deps/v8/test/intl/number-format/constructor-numberingSytem-order.js b/deps/v8/test/intl/number-format/constructor-numberingSytem-order.js new file mode 100644 index 00000000000000..8c284967ff8a67 --- /dev/null +++ b/deps/v8/test/intl/number-format/constructor-numberingSytem-order.js @@ -0,0 +1,30 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-add-calendar-numbering-system +const actual = []; + +const options = { + get localeMatcher() { + actual.push("localeMatcher"); + return undefined; + }, + get numberingSystem() { + actual.push("numberingSystem"); + return undefined; + }, + get style() { + actual.push("style"); + return undefined; + }, +}; + +const expected = [ + "localeMatcher", + "numberingSystem", + "style" +]; + +let nf = new Intl.NumberFormat(undefined, options); +assertEquals(actual.join(":"), expected.join(":")); diff --git a/deps/v8/test/intl/number-format/property-override.js b/deps/v8/test/intl/number-format/property-override.js deleted file mode 100644 index 590b1c2e4bc36f..00000000000000 --- a/deps/v8/test/intl/number-format/property-override.js +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Checks for security holes introduced by Object.property overrides. -// For example: -// Object.defineProperty(Array.prototype, 'locale', { -// set: function(value) { -// throw new Error('blah'); -// }, -// configurable: true, -// enumerable: false -// }); -// -// would throw in case of (JS) x.locale = 'us' or (C++) x->Set('locale', 'us'). -// -// Update both number-format.js and number-format.cc so they have the same -// list of properties. - -// Flags: --noharmony-intl-numberformat-unified - -// First get supported properties. -var properties = []; -// Some properties are optional and won't show up in resolvedOptions if -// they were not requested - currency, currencyDisplay, -// minimumSignificantDigits and maximumSignificantDigits - so we request them. -var options = Intl.NumberFormat( - undefined, {style: 'currency', currency: 'USD', currencyDisplay: 'name', - minimumSignificantDigits: 1, maximumSignificantDigits: 5}). - resolvedOptions(); -for (var prop in options) { - if (options.hasOwnProperty(prop)) { - properties.push(prop); - } -} - -var expectedProperties = [ - 'style', 'locale', 'numberingSystem', - 'currency', 'currencyDisplay', 'useGrouping', - 'minimumIntegerDigits', 'minimumFractionDigits', - 'maximumFractionDigits', 'minimumSignificantDigits', - 'maximumSignificantDigits' -]; - -assertEquals(expectedProperties.length, properties.length); - -properties.forEach(function(prop) { - assertFalse(expectedProperties.indexOf(prop) === -1); -}); - -taintProperties(properties); - -var locale = Intl.NumberFormat(undefined, - {currency: 'USD', currencyDisplay: 'name', - minimumIntegerDigits: 2, - numberingSystem: 'latn'}). - resolvedOptions().locale; diff --git a/deps/v8/test/intl/number-format/unified/compact-display.js b/deps/v8/test/intl/number-format/unified/compact-display.js index 228a2b62598979..666cab86f4f440 100644 --- a/deps/v8/test/intl/number-format/unified/compact-display.js +++ b/deps/v8/test/intl/number-format/unified/compact-display.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - const testData = [ ["short"], ["long"], diff --git a/deps/v8/test/intl/number-format/unified/constructor-order.js b/deps/v8/test/intl/number-format/unified/constructor-order.js index be716371f5ba81..f32f0b1696b44c 100644 --- a/deps/v8/test/intl/number-format/unified/constructor-order.js +++ b/deps/v8/test/intl/number-format/unified/constructor-order.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified // Similar to constructor-order.js but also consider the new options // in https://tc39-transfer.github.io/proposal-unified-intl-numberformat/ diff --git a/deps/v8/test/intl/number-format/unified/currency-display.js b/deps/v8/test/intl/number-format/unified/currency-display.js index effd0267780c13..3c407f27cbf2e2 100644 --- a/deps/v8/test/intl/number-format/unified/currency-display.js +++ b/deps/v8/test/intl/number-format/unified/currency-display.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test defaults let nf = new Intl.NumberFormat(); assertEquals(undefined, nf.resolvedOptions().currencyDisplay); diff --git a/deps/v8/test/intl/number-format/unified/currency-sign.js b/deps/v8/test/intl/number-format/unified/currency-sign.js index 3f2941a8e9d8de..9bfecf8c9be651 100644 --- a/deps/v8/test/intl/number-format/unified/currency-sign.js +++ b/deps/v8/test/intl/number-format/unified/currency-sign.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test default. let nf = new Intl.NumberFormat(); assertEquals(undefined, nf.resolvedOptions().currencySign); diff --git a/deps/v8/test/intl/number-format/unified/no-compact-display.js b/deps/v8/test/intl/number-format/unified/no-compact-display.js index 95611e90fc089a..36d75722ea0c22 100644 --- a/deps/v8/test/intl/number-format/unified/no-compact-display.js +++ b/deps/v8/test/intl/number-format/unified/no-compact-display.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Except when the notation is "compact", the resolvedOptions().compactDisplay // should be undefined. // diff --git a/deps/v8/test/intl/number-format/unified/notation-engineering-formatToParts.js b/deps/v8/test/intl/number-format/unified/notation-engineering-formatToParts.js index 280771b2e7b5fa..da91f4ba9639d5 100644 --- a/deps/v8/test/intl/number-format/unified/notation-engineering-formatToParts.js +++ b/deps/v8/test/intl/number-format/unified/notation-engineering-formatToParts.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test notation: "engineering" with formatToParts. const nf = Intl.NumberFormat("en", {notation: "engineering"}); diff --git a/deps/v8/test/intl/number-format/unified/notation-scientific-formatToParts.js b/deps/v8/test/intl/number-format/unified/notation-scientific-formatToParts.js index 9ffd5f870936ec..ade723dbe37e82 100644 --- a/deps/v8/test/intl/number-format/unified/notation-scientific-formatToParts.js +++ b/deps/v8/test/intl/number-format/unified/notation-scientific-formatToParts.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test notation: "scientific" with formatToParts. const nf = Intl.NumberFormat("en", {notation: "scientific"}); diff --git a/deps/v8/test/intl/number-format/unified/notation.js b/deps/v8/test/intl/number-format/unified/notation.js index b26ee01f5c6863..3711644f524bdf 100644 --- a/deps/v8/test/intl/number-format/unified/notation.js +++ b/deps/v8/test/intl/number-format/unified/notation.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test defaults. let nf = new Intl.NumberFormat(); diff --git a/deps/v8/test/intl/number-format/unified/percent.js b/deps/v8/test/intl/number-format/unified/percent.js index 9918210ec7fc08..c4de0f7fec6b70 100644 --- a/deps/v8/test/intl/number-format/unified/percent.js +++ b/deps/v8/test/intl/number-format/unified/percent.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified -// // Test the handling of "percent" w/ "unit" let nf1 = new Intl.NumberFormat("en-US", { diff --git a/deps/v8/test/intl/number-format/unified/sign-display.js b/deps/v8/test/intl/number-format/unified/sign-display.js index c71f57e67c7677..18b74c9f0b7d67 100644 --- a/deps/v8/test/intl/number-format/unified/sign-display.js +++ b/deps/v8/test/intl/number-format/unified/sign-display.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test default. let nf = new Intl.NumberFormat(); assertEquals("auto", nf.resolvedOptions().signDisplay); diff --git a/deps/v8/test/intl/number-format/unified/style-unit.js b/deps/v8/test/intl/number-format/unified/style-unit.js index 72eb0a782d2ce4..757c0093c21a79 100644 --- a/deps/v8/test/intl/number-format/unified/style-unit.js +++ b/deps/v8/test/intl/number-format/unified/style-unit.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test default. let nf = new Intl.NumberFormat(); diff --git a/deps/v8/test/intl/number-format/unified/unit-display.js b/deps/v8/test/intl/number-format/unified/unit-display.js index d4d814d70e2431..d451fda324ca03 100644 --- a/deps/v8/test/intl/number-format/unified/unit-display.js +++ b/deps/v8/test/intl/number-format/unified/unit-display.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified - // Test default. let nf = new Intl.NumberFormat(); assertEquals(undefined, nf.resolvedOptions().unitDisplay); diff --git a/deps/v8/test/intl/regress-1003748.js b/deps/v8/test/intl/regress-1003748.js new file mode 100644 index 00000000000000..89ef559e166205 --- /dev/null +++ b/deps/v8/test/intl/regress-1003748.js @@ -0,0 +1,18 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let usd = new Intl.NumberFormat('en', + { style: 'currency', currency: 'USD' }).resolvedOptions(); +assertEquals(2, usd.maximumFractionDigits); +assertEquals(2, usd.minimumFractionDigits); + +let jpy = new Intl.NumberFormat('en', + { style: 'currency', currency: 'JPY' }).resolvedOptions(); +assertEquals(0, jpy.maximumFractionDigits); +assertEquals(0, jpy.minimumFractionDigits); + +let krw = new Intl.NumberFormat('en', + { style: 'currency', currency: 'KRW' }).resolvedOptions(); +assertEquals(0, krw.maximumFractionDigits); +assertEquals(0, krw.minimumFractionDigits); diff --git a/deps/v8/test/intl/regress-1012579.js b/deps/v8/test/intl/regress-1012579.js new file mode 100644 index 00000000000000..9051a0004cca90 --- /dev/null +++ b/deps/v8/test/intl/regress-1012579.js @@ -0,0 +1,6 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let longLocale = 'de-u-cf-cu-em-kk-kr-ks-kv-lb-lw-ms-nu-rg-sd-ss-tz'; +rtf = new Intl.RelativeTimeFormat(longLocale); diff --git a/deps/v8/test/intl/regress-8725514.js b/deps/v8/test/intl/regress-8725514.js index 82f884a093f2ad..f1bf92b7cc1d19 100644 --- a/deps/v8/test/intl/regress-8725514.js +++ b/deps/v8/test/intl/regress-8725514.js @@ -6,5 +6,5 @@ Object.prototype.__defineGetter__('x', function () { return -2147483648; }); -var f = ["x-u-foo"]; +var f = ["en-US"]; Intl.NumberFormat(f); diff --git a/deps/v8/test/intl/regress-903566.js b/deps/v8/test/intl/regress-903566.js index 9346fa63a8c60d..65f604f4529104 100644 --- a/deps/v8/test/intl/regress-903566.js +++ b/deps/v8/test/intl/regress-903566.js @@ -13,7 +13,9 @@ let arr = ["a","b","c"]; // Test under no HasHoleyElements(); assertFalse(%HasHoleyElements(arr)); assertDoesNotThrow(()=>(new Intl.ListFormat()).format(arr)); -for (var i = 0; i < 10000; i++) { +// ICU uses bubblesort, so keep the array reasonably small (as of mid-2019: +// 100 entries -> 1ms, 1,000 entries -> 64ms, 10,000 entries -> 5s). +for (var i = 0; i < 100; i++) { arr.push("xx"); } assertFalse(%HasHoleyElements(arr)); diff --git a/deps/v8/test/intl/regress-9356.js b/deps/v8/test/intl/regress-9356.js new file mode 100644 index 00000000000000..a355aa1b9e4507 --- /dev/null +++ b/deps/v8/test/intl/regress-9356.js @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assertFalse(/ſ/i.test('ſ'.toUpperCase())); +assertFalse(/ſ/i.test('ſ'.toUpperCase()[0])); +assertTrue(/ſ/i.test('ſ')); +assertTrue(/ſ/i.test('ſ'[0])); +assertFalse(/ſ/i.test('s'.toUpperCase())); +assertFalse(/ſ/i.test('s'.toUpperCase()[0])); +assertFalse(/ſ/i.test('S'.toUpperCase())); +assertFalse(/ſ/i.test('S'.toUpperCase()[0])); +assertFalse(/ſ/i.test('S')); +assertFalse(/ſ/i.test('S'[0])); diff --git a/deps/v8/test/intl/regress-9408.js b/deps/v8/test/intl/regress-9408.js index 88883981f328b9..d5cfb11345c717 100644 --- a/deps/v8/test/intl/regress-9408.js +++ b/deps/v8/test/intl/regress-9408.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified // Test precision of compact-rounding let compact = {notation: "compact"}; diff --git a/deps/v8/test/intl/regress-9464.js b/deps/v8/test/intl/regress-9464.js new file mode 100644 index 00000000000000..fc51d632f91ccd --- /dev/null +++ b/deps/v8/test/intl/regress-9464.js @@ -0,0 +1,51 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Number, BigInt and Intl.NumberFormat +assertThrows( + "new Intl.NumberFormat('en', { style: 'unit', unit: 'son'});", + RangeError, + "Invalid unit argument for Intl.NumberFormat() 'son'"); + +assertThrows( + "123n.toLocaleString('en', { style: 'unit', unit: 'son'});", + RangeError, + "Invalid unit argument for BigInt.prototype.toLocaleString() 'son'"); + +assertThrows( + "Math.PI.toLocaleString('en', { style: 'unit', unit: 'son'});", + RangeError, + "Invalid unit argument for Number.prototype.toLocaleString() 'son'"); + +// String and Intl.Collator +assertThrows( + "new Intl.Collator('en', { usage: 'mom'});", + RangeError, + "Value mom out of range for Intl.Collator options property usage"); + +assertThrows( + "'abc'.localeCompare('efg', 'en', { usage: 'mom'});", + RangeError, + "Value mom out of range for String.prototype.localeCompare options property usage"); + +// Date and Intl.DateTimeFormat +assertThrows( + "new Intl.DateTimeFormat('en', { hour: 'dad'});", + RangeError, + "Value dad out of range for Intl.DateTimeFormat options property hour"); + +assertThrows( + "(new Date).toLocaleDateString('en', { hour: 'dad'});", + RangeError, + "Value dad out of range for Date.prototype.toLocaleDateString options property hour"); + +assertThrows( + "(new Date).toLocaleString('en', { hour: 'dad'});", + RangeError, + "Value dad out of range for Date.prototype.toLocaleString options property hour"); + +assertThrows( + "(new Date).toLocaleTimeString('en', { hour: 'dad'});", + RangeError, + "Value dad out of range for Date.prototype.toLocaleTimeString options property hour"); diff --git a/deps/v8/test/intl/regress-9475.js b/deps/v8/test/intl/regress-9475.js index 3549ef8f3899f1..68e2fdd7d7beff 100644 --- a/deps/v8/test/intl/regress-9475.js +++ b/deps/v8/test/intl/regress-9475.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified // Test format of all valid units won't throw exception. let validList = [ diff --git a/deps/v8/test/intl/regress-9513.js b/deps/v8/test/intl/regress-9513.js index e23b5cf77ed11f..fc50df2418baf8 100644 --- a/deps/v8/test/intl/regress-9513.js +++ b/deps/v8/test/intl/regress-9513.js @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-intl-numberformat-unified // Test Infinity, -Infinity, NaN won't crash with any notation in formatToParts. let validNotations = [ diff --git a/deps/v8/test/intl/regress-9731.js b/deps/v8/test/intl/regress-9731.js new file mode 100644 index 00000000000000..3cabade5a1854b --- /dev/null +++ b/deps/v8/test/intl/regress-9731.js @@ -0,0 +1,15 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assertFalse(/k/i.test('\u212A')); +assertTrue(/k/i.test('K')); +assertTrue(/k/i.test('k')); + +assertFalse(/K/i.test('\u212A')); +assertTrue(/K/i.test('K')); +assertTrue(/K/i.test('k')); + +assertTrue(/\u212A/i.test('\u212A')); +assertFalse(/\u212A/i.test('k')); +assertFalse(/\u212A/i.test('K')); diff --git a/deps/v8/test/intl/regress-9747.js b/deps/v8/test/intl/regress-9747.js new file mode 100644 index 00000000000000..8b51ddc27599ca --- /dev/null +++ b/deps/v8/test/intl/regress-9747.js @@ -0,0 +1,50 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let lf = new Intl.ListFormat("en"); + +// Test normal array +assertDoesNotThrow(() => lf.format(['a','b','c'])); +assertThrows("lf.format(['a','b',3])", TypeError, "Iterable yielded 3 which is not a string"); + +// Test sparse array +let sparse = ['a','b']; +sparse[10] = 'c'; +assertThrows("lf.format(sparse)", TypeError, "Iterable yielded undefined which is not a string"); + +// Test iterable of all String +let iterable_of_strings = { + [Symbol.iterator]() { + return this; + }, + count: 0, + next() { + if (this.count++ < 4) { + return {done: false, value: String(this.count)}; + } + return {done:true} + } +}; +assertDoesNotThrow(() => lf.format(iterable_of_strings)); + +// Test iterable of none String throw TypeError +let iterable_of_strings_and_number = { + [Symbol.iterator]() { + return this; + }, + count: 0, + next() { + this.count++; + if (this.count == 3) { + return {done:false, value: 3}; + } + if (this.count < 5) { + return {done: false, value: String(this.count)}; + } + return {done:true} + } +}; +assertThrows("lf.format(iterable_of_strings_and_number)", + TypeError, "Iterable yielded 3 which is not a string"); +assertEquals(3, iterable_of_strings_and_number.count); diff --git a/deps/v8/test/intl/regress-9786.js b/deps/v8/test/intl/regress-9786.js new file mode 100644 index 00000000000000..e922dba5f7455d --- /dev/null +++ b/deps/v8/test/intl/regress-9786.js @@ -0,0 +1,21 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-add-calendar-numbering-system + +// Well-formed but invalid calendar should not throw RangeError. +var calendar = "abc"; +var len = 3; +var expected = new Intl.DateTimeFormat("en").resolvedOptions().calendar; +var df; + +for (var i = 3; i < 20; i++, len++, calendar += "a") { + assertDoesNotThrow(() => df = new Intl.DateTimeFormat("en", {calendar}), + "Well-formed calendar should not throw"); + assertEquals(expected, df.resolvedOptions().calendar); + if (len == 8) { + calendar += "-ab"; + len = 2; + } +} diff --git a/deps/v8/test/intl/regress-9787.js b/deps/v8/test/intl/regress-9787.js new file mode 100644 index 00000000000000..576c0f7d649f29 --- /dev/null +++ b/deps/v8/test/intl/regress-9787.js @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-add-calendar-numbering-system + +// ill-formed and valid calendar should throw RangeError. +assertThrows( + 'new Intl.DateTimeFormat("en", {calendar: "gregorian"})', + RangeError); diff --git a/deps/v8/test/intl/regress-9788.js b/deps/v8/test/intl/regress-9788.js new file mode 100644 index 00000000000000..7a3679584fa6c5 --- /dev/null +++ b/deps/v8/test/intl/regress-9788.js @@ -0,0 +1,29 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-intl-add-calendar-numbering-system + +// Well-formed but invalid numberingSystem should not throw RangeError. +var numberingSystem = "abc"; +var len = 3; + +const intlClasses = [ + Intl.DateTimeFormat, + Intl.NumberFormat, + Intl.RelativeTimeFormat +]; + +intlClasses.forEach(function(cls) { + var expected = new cls("en").resolvedOptions().numberingSystem; + var obj; + for (var i = 3; i < 20; i++, len++, numberingSystem += "a") { + assertDoesNotThrow(() => obj = new cls("en", {numberingSystem}), + "Well-formed numberingSystem should not throw"); + assertEquals(expected, obj.resolvedOptions().numberingSystem); + if (len == 8) { + numberingSystem += "-ab"; + len = 2; + } + } +}); diff --git a/deps/v8/test/intl/regress-9812.js b/deps/v8/test/intl/regress-9812.js new file mode 100644 index 00000000000000..c85f9e65c16635 --- /dev/null +++ b/deps/v8/test/intl/regress-9812.js @@ -0,0 +1,65 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +const locales = [ + "cs", + "cs-CZ", + "en-001", + "en-150", + "en-TV", + "es-419", + "es-AR", + "fil", + "fr-CA", + "id", + "in", + "lt", + "nl", + "pl", + "pt-PT", + "sr-ME", + "sv", + "uk", + "vi", +]; + +const calendars = [ + // Calendars we know have issues + "islamic", + "islamic-civil", + "islamic-tbla", + "islamic-umalqura", + "ethiopic-amete-alem", + "islamicc", + "ethioaa", + "islamic-rgsa", + + // Other calendars + "gregory", + "japanese", + "buddhist", + "roc", + "persian", + "islamic", + "hebrew", + "chinese", + "indian", + "coptic", + "ethiopic", + "iso8601", + "dangi", + "chinese", +]; + +let d1 = new Date(2019, 3, 4); +let d2 = new Date(2019, 5, 6); + +calendars.forEach(function(calendar) { + locales.forEach(function(baseLocale) { + let locale = `${baseLocale}-u-ca-${calendar}`; + assertDoesNotThrow( + () => (new Intl.DateTimeFormat(locale)).formatRange(d1, d2), + `Using Intl.DateFormat formatRange with ${locale} should not throw`); + }) +}) diff --git a/deps/v8/test/intl/regress-9849.js b/deps/v8/test/intl/regress-9849.js new file mode 100644 index 00000000000000..0b406a0381259f --- /dev/null +++ b/deps/v8/test/intl/regress-9849.js @@ -0,0 +1,15 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let d = new Date(271733878); +d.toLocaleString('en-u-nu-arab'); +d.toLocaleString('en-u-nu-arab', {dateStyle : 'full', timeStyle : 'full'}); +d.toLocaleString('en-u-nu-roman'); +d.toLocaleString('en-u-nu-roman', {dateStyle : 'full', timeStyle : 'full'}); +d.toLocaleString('sr-u-nu-roman'); +d.toLocaleString('sr-u-nu-roman', {dateStyle : 'full', timeStyle : 'full'}); +d.toLocaleString('sr-Cyrl-u-nu-roman'); +d.toLocaleString('sr-Cyrl-u-nu-roman', {dateStyle : 'full', timeStyle : 'full'}); +d.toLocaleString('zh-u-nu-roman', {dateStyle : 'full', timeStyle : 'full'}); +d.toLocaleString('ja-u-nu-cyrl', {dateStyle : 'full', timeStyle : 'full'}); diff --git a/deps/v8/test/intl/regress-992694.js b/deps/v8/test/intl/regress-992694.js new file mode 100644 index 00000000000000..0729636989d298 --- /dev/null +++ b/deps/v8/test/intl/regress-992694.js @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Make sure the "hu" locale format the number group correctly. + +let number = 123456.789; +let expected = "123 456,79 Ft"; +assertEquals(expected, + (new Intl.NumberFormat('hu', { style: 'currency', currency: 'HUF'}).format(number))); +assertEquals(expected, + (new Intl.NumberFormat('hu-HU', { style: 'currency', currency: 'HUF' }).format(number))); diff --git a/deps/v8/test/intl/regress-997401.js b/deps/v8/test/intl/regress-997401.js new file mode 100644 index 00000000000000..4c46acff7d07df --- /dev/null +++ b/deps/v8/test/intl/regress-997401.js @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test no crash with a very long locale. +let dtf = new Intl.DateTimeFormat( + 'de-u-cu-eur-em-default-hc-h23-ks-level1-lb-strict-lw-normal-ms-metric-nu-latn-rg-atzzzz-sd-atat1-ss-none-tz-atvie-va-posix'); diff --git a/deps/v8/test/intl/relative-time-format/check-numbering-system.js b/deps/v8/test/intl/relative-time-format/check-numbering-system.js new file mode 100644 index 00000000000000..91f4b3aee0071b --- /dev/null +++ b/deps/v8/test/intl/relative-time-format/check-numbering-system.js @@ -0,0 +1,85 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let invalidNumberingSystem = [ + "invalid", + "abce", + "finance", + "native", + "traditio", + "abc-defghi", +]; + +let illFormedNumberingSystem = [ + "", + "i", + "ij", + "abcdefghi", + "abc-ab", +]; + +// https://tc39.github.io/ecma402/#table-numbering-system-digits +let validNumberingSystem= [ + "arab", + "arabext", + "bali", + "beng", + "deva", + "fullwide", + "gujr", + "guru", + "hanidec", + "khmr", + "knda", + "laoo", + "latn", + "limb", + "mlym", + "mong", + "mymr", + "orya", + "tamldec", + "telu", + "thai", + "tibt", +]; + +let locales = [ + "en", + "ar", +]; + + +invalidNumberingSystem.forEach(function(numberingSystem) { + locales.forEach(function(base) { + var df; + assertDoesNotThrow( + () => df = new Intl.RelativeTimeFormat([base], {numberingSystem})); + assertEquals( + (new Intl.RelativeTimeFormat([base])).resolvedOptions().numberingSystem, + df.resolvedOptions().numberingSystem); + }); +}); + +illFormedNumberingSystem.forEach(function(numberingSystem) { + assertThrows( + () => new Intl.RelativeTimeFormat(["en"], {numberingSystem}), + RangeError); +}); + +let value = 1234567.89; +validNumberingSystem.forEach(function(numberingSystem) { + locales.forEach(function(base) { + let l = base + "-u-nu-" + numberingSystem; + let nf = new Intl.RelativeTimeFormat([base], {numberingSystem}); + assertEquals(l, nf.resolvedOptions().locale); + assertEquals(numberingSystem, nf.resolvedOptions().numberingSystem); + + // Test the formatting result is the same as passing in via u-nu- + // in the locale. + let nf2 = new Intl.RelativeTimeFormat([l]); + assertEquals(nf2.format(value, "day"), nf.format(value, "day")); + }); +} +); diff --git a/deps/v8/test/intl/relative-time-format/resolved-options.js b/deps/v8/test/intl/relative-time-format/resolved-options.js index 1caa4f86c996d4..53648320c96ca8 100644 --- a/deps/v8/test/intl/relative-time-format/resolved-options.js +++ b/deps/v8/test/intl/relative-time-format/resolved-options.js @@ -156,7 +156,3 @@ assertEquals( assertThrows(() => Intl.RelativeTimeFormat.prototype.resolvedOptions.call(receiver), TypeError); } - -assertEquals( - 'ar', - (new Intl.RelativeTimeFormat(['i-default', 'ar'])).resolvedOptions().locale); diff --git a/deps/v8/test/js-perf-test/BytecodeHandlers/LdaGlobal.js b/deps/v8/test/js-perf-test/BytecodeHandlers/LdaGlobal.js new file mode 100644 index 00000000000000..a986f5f18f7812 --- /dev/null +++ b/deps/v8/test/js-perf-test/BytecodeHandlers/LdaGlobal.js @@ -0,0 +1,60 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function addBenchmark(name, test) { + new BenchmarkSuite(name, [1000], + [ + new Benchmark(name, false, false, 0, test) + ]); +} + +addBenchmark('LoadGlobal', ldaGlobal); +addBenchmark('LoadGlobalInsideTypeof', ldaGlobalInsideTypeof); + +var g_var = 10; + +function ldaGlobal() { + for (var i = 0; i < 1000; ++i) { + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; g_var; + } +} + +function ldaGlobalInsideTypeof() { + for (var i = 0; i < 1000; ++i) { + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + typeof(g_var); typeof(g_var); typeof(g_var); typeof(g_var); + } +} diff --git a/deps/v8/test/js-perf-test/JSTests3.json b/deps/v8/test/js-perf-test/JSTests3.json index 598e9fc6d118c6..e2b669614c21be 100644 --- a/deps/v8/test/js-perf-test/JSTests3.json +++ b/deps/v8/test/js-perf-test/JSTests3.json @@ -371,6 +371,17 @@ {"name": "Object-Lookup-Index-Number"}, {"name": "Object-Lookup-Index-String"} ] + }, + { + "name": "LdaGlobal", + "main": "run.js", + "resources": [ "LdaGlobal.js" ], + "test_flags": [ "LdaGlobal" ], + "results_regexp": "^%s\\-BytecodeHandler\\(Score\\): (.+)$", + "tests": [ + {"name": "LoadGlobal"}, + {"name": "LoadGlobalInsideTypeof"} + ] } ] }, diff --git a/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.mjs b/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.mjs new file mode 100644 index 00000000000000..3a00ba67ae3647 --- /dev/null +++ b/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MODULE +// +// Flags: --harmony-top-level-await + +import "modules-skip-1-top-level-await-fail.mjs" diff --git a/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.out b/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.out new file mode 100644 index 00000000000000..2b2cb407a4ae0d --- /dev/null +++ b/deps/v8/test/message/fail/modules-import-top-level-await-fail-1.out @@ -0,0 +1,3 @@ +*modules-skip-1-top-level-await-fail.mjs:7: ReferenceError: x is not defined +await x; +^ diff --git a/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.mjs b/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.mjs new file mode 100644 index 00000000000000..c0bc4c22aa0acf --- /dev/null +++ b/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MODULE +// +// Flags: --harmony-top-level-await + +import "modules-skip-2-top-level-await-fail.mjs" diff --git a/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.out b/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.out new file mode 100644 index 00000000000000..208d53e1d28b2f --- /dev/null +++ b/deps/v8/test/message/fail/modules-import-top-level-await-fail-2.out @@ -0,0 +1,3 @@ +*modules-skip-2-top-level-await-fail.mjs:7: ReferenceError: ththsths is not defined +ththsths +^ diff --git a/deps/v8/test/message/fail/modules-skip-1-top-level-await-fail.mjs b/deps/v8/test/message/fail/modules-skip-1-top-level-await-fail.mjs new file mode 100644 index 00000000000000..0642ddf36635b4 --- /dev/null +++ b/deps/v8/test/message/fail/modules-skip-1-top-level-await-fail.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MODULE + +await x; diff --git a/deps/v8/test/message/fail/modules-skip-2-top-level-await-fail.mjs b/deps/v8/test/message/fail/modules-skip-2-top-level-await-fail.mjs new file mode 100644 index 00000000000000..19edc2c5467a6d --- /dev/null +++ b/deps/v8/test/message/fail/modules-skip-2-top-level-await-fail.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import "modules-skip-3-top-level-await-fail.mjs" + +ththsths diff --git a/deps/v8/test/message/fail/modules-skip-3-top-level-await-fail.mjs b/deps/v8/test/message/fail/modules-skip-3-top-level-await-fail.mjs new file mode 100644 index 00000000000000..caf3431b7fea94 --- /dev/null +++ b/deps/v8/test/message/fail/modules-skip-3-top-level-await-fail.mjs @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +await 42; diff --git a/deps/v8/test/message/message.status b/deps/v8/test/message/message.status index 25c87b5e5c2ca9..45f0347b4ca577 100644 --- a/deps/v8/test/message/message.status +++ b/deps/v8/test/message/message.status @@ -38,7 +38,7 @@ }], # ALWAYS # Liftoff is currently only sufficiently implemented on x64 and ia32. -# TODO(clemensh): Implement on all other platforms (crbug.com/v8/6600). +# TODO(clemensb): Implement on all other platforms (crbug.com/v8/6600). ['arch != x64 and arch != ia32', { 'wasm-trace-memory-liftoff': [SKIP], }], # arch != x64 and arch != ia32 diff --git a/deps/v8/test/message/wasm-trace-memory-interpreted.js b/deps/v8/test/message/wasm-trace-memory-interpreted.js index fdac585b391852..401707f5811741 100644 --- a/deps/v8/test/message/wasm-trace-memory-interpreted.js +++ b/deps/v8/test/message/wasm-trace-memory-interpreted.js @@ -3,5 +3,6 @@ // found in the LICENSE file. // Flags: --no-stress-opt --expose-wasm --trace-wasm-memory --wasm-interpret-all +// Flags: --experimental-wasm-simd load("test/message/wasm-trace-memory.js"); diff --git a/deps/v8/test/message/wasm-trace-memory-interpreted.out b/deps/v8/test/message/wasm-trace-memory-interpreted.out index 248d67e827e508..e390f10fe39fc0 100644 --- a/deps/v8/test/message/wasm-trace-memory-interpreted.out +++ b/deps/v8/test/message/wasm-trace-memory-interpreted.out @@ -7,3 +7,5 @@ interpreter func: 2+0x3 load from 00000002 val: f32:68169720922112.00000 interpreter func: 4+0x5 store to 00000004 val: i8:171 / ab interpreter func: 0+0x3 load from 00000002 val: i32:1454047232 / 56ab0000 interpreter func: 2+0x3 load from 00000002 val: f32:94008244174848.000000 / 56ab0000 +interpreter func: 6+0x7 store to 00000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef +interpreter func: 5+0x3 load from 00000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000 diff --git a/deps/v8/test/message/wasm-trace-memory-liftoff.js b/deps/v8/test/message/wasm-trace-memory-liftoff.js index a23eca4a0fb554..b50d33dbe8f2fe 100644 --- a/deps/v8/test/message/wasm-trace-memory-liftoff.js +++ b/deps/v8/test/message/wasm-trace-memory-liftoff.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --no-stress-opt --trace-wasm-memory --liftoff --no-future -// Flags: --no-wasm-tier-up +// Flags: --no-wasm-tier-up --experimental-wasm-simd +// liftoff does not support simd128, so the s128 load and store traces are in +// the turbofan tier and not liftoff load("test/message/wasm-trace-memory.js"); diff --git a/deps/v8/test/message/wasm-trace-memory-liftoff.out b/deps/v8/test/message/wasm-trace-memory-liftoff.out index 31fdefde3d917c..cdd8e765d92f39 100644 --- a/deps/v8/test/message/wasm-trace-memory-liftoff.out +++ b/deps/v8/test/message/wasm-trace-memory-liftoff.out @@ -7,3 +7,5 @@ liftoff func: 2+0x3 load from 00000002 val: f32:68169720922112.00000 liftoff func: 4+0x5 store to 00000004 val: i8:171 / ab liftoff func: 0+0x3 load from 00000002 val: i32:1454047232 / 56ab0000 liftoff func: 2+0x3 load from 00000002 val: f32:94008244174848.000000 / 56ab0000 +turbofan func: 6+0x7 store to 00000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef +turbofan func: 5+0x3 load from 00000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000 diff --git a/deps/v8/test/message/wasm-trace-memory.js b/deps/v8/test/message/wasm-trace-memory.js index 23425f4ddbac25..de2f1159e9ef10 100644 --- a/deps/v8/test/message/wasm-trace-memory.js +++ b/deps/v8/test/message/wasm-trace-memory.js @@ -3,26 +3,33 @@ // found in the LICENSE file. // Flags: --no-stress-opt --trace-wasm-memory --no-liftoff --no-future -// Flags: --no-wasm-tier-up +// Flags: --no-wasm-tier-up --experimental-wasm-simd load("test/mjsunit/wasm/wasm-module-builder.js"); var builder = new WasmModuleBuilder(); builder.addMemory(1); builder.addFunction('load', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprDrop]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0, kExprDrop]) .exportFunc(); builder.addFunction('load8', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem8U, 0, 0, kExprDrop]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem8U, 0, 0, kExprDrop]) .exportFunc(); builder.addFunction('loadf', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprF32LoadMem, 0, 0, kExprDrop]) + .addBody([kExprLocalGet, 0, kExprF32LoadMem, 0, 0, kExprDrop]) .exportFunc(); builder.addFunction('store', kSig_v_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0]) .exportFunc(); builder.addFunction('store8', kSig_v_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem8, 0, 0]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem8, 0, 0]) + .exportFunc(); +builder.addFunction('load128', kSig_v_i) + .addBody([kExprLocalGet, 0, kSimdPrefix, kExprS128LoadMem, 0, 0, kExprDrop]) + .exportFunc(); +// SIMD is not exposed to JS, so use splat to construct a s128 value. +builder.addFunction('store128', kSig_v_ii) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kSimdPrefix, kExprI32x4Splat, kSimdPrefix, kExprS128StoreMem, 0, 0]) .exportFunc(); var module = builder.instantiate(); @@ -35,3 +42,5 @@ module.exports.loadf(2); module.exports.store8(4, 0xab); module.exports.load(2); module.exports.loadf(2); +module.exports.store128(4, 0xbeef); +module.exports.load128(2); diff --git a/deps/v8/test/message/wasm-trace-memory.out b/deps/v8/test/message/wasm-trace-memory.out index bc6b1b64ec8512..f41bc30fee85c8 100644 --- a/deps/v8/test/message/wasm-trace-memory.out +++ b/deps/v8/test/message/wasm-trace-memory.out @@ -7,3 +7,5 @@ turbofan func: 2+0x3 load from 00000002 val: f32:68169720922112.00000 turbofan func: 4+0x5 store to 00000004 val: i8:171 / ab turbofan func: 0+0x3 load from 00000002 val: i32:1454047232 / 56ab0000 turbofan func: 2+0x3 load from 00000002 val: f32:94008244174848.000000 / 56ab0000 +turbofan func: 6+0x7 store to 00000004 val: s128:48879 48879 48879 48879 / 0000beef 0000beef 0000beef 0000beef +turbofan func: 5+0x3 load from 00000002 val: s128:-1091633152 -1091633152 -1091633152 -1091633152 / beef0000 beef0000 beef0000 beef0000 diff --git a/deps/v8/test/mjsunit/asm/regress-1013920.js b/deps/v8/test/mjsunit/asm/regress-1013920.js new file mode 100644 index 00000000000000..f7a2e57d1d0035 --- /dev/null +++ b/deps/v8/test/mjsunit/asm/regress-1013920.js @@ -0,0 +1,17 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function asm(stdlib, foreign, heap) { + "use asm"; + var heap32 = new stdlib.Uint32Array(heap); + function f() { return 0; } + return {f : f}; +} + +var heap = Reflect.construct( + SharedArrayBuffer, + [1024 * 1024], + ArrayBuffer.prototype.constructor); + +asm(this, {}, heap); diff --git a/deps/v8/test/mjsunit/bit-not.js b/deps/v8/test/mjsunit/bit-not.js index d0316a71eaab45..4ef1b7c2e389ff 100644 --- a/deps/v8/test/mjsunit/bit-not.js +++ b/deps/v8/test/mjsunit/bit-not.js @@ -62,16 +62,3 @@ testBitNot(0x80000000 - 0.12345, "float6"); testBitNot("0", "string0"); testBitNot("2.3", "string2.3"); testBitNot("-9.4", "string-9.4"); - - -// Try to test that we can deal with allocation failures in -// the fast path and just use the slow path instead. -function TryToGC() { - var x = 0x40000000; - // Put in an eval to foil Crankshaft. - eval(""); - for (var i = 0; i < 1000000; i++) { - assertEquals(~0x40000000, ~x); - } -} -TryToGC(); diff --git a/deps/v8/test/mjsunit/code-coverage-block-async.js b/deps/v8/test/mjsunit/code-coverage-block-async.js new file mode 100644 index 00000000000000..111be213b6837c --- /dev/null +++ b/deps/v8/test/mjsunit/code-coverage-block-async.js @@ -0,0 +1,122 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --no-always-opt --no-stress-flush-bytecode +// Flags: --no-stress-incremental-marking +// Files: test/mjsunit/code-coverage-utils.js + +%DebugToggleBlockCoverage(true); + +TestCoverage( +"await expressions", +` +async function f() { // 0000 + await 42; // 0050 + await 42; // 0100 +}; // 0150 +f(); // 0200 +%PerformMicrotaskCheckpoint(); // 0250 +`, +[{"start":0,"end":299,"count":1}, + {"start":0,"end":151,"count":1}] +); + +TestCoverage( +"for-await-of statements", +` +!async function() { // 0000 + for await (var x of [0,1,2,3]) { // 0050 + nop(); // 0100 + } // 0150 +}(); // 0200 +%PerformMicrotaskCheckpoint(); // 0250 +`, +[{"start":0,"end":299,"count":1}, + {"start":1,"end":201,"count":1}, + {"start":83,"end":153,"count":4}] +); + +TestCoverage( +"https://crbug.com/981313", +` +class Foo { // 0000 + async timeout() { // 0000 + return new Promise( // 0100 + (r) => setTimeout(r, 10)); // 0000 + } // 0200 +} // 0000 +new Foo().timeout(); // 0300 +`, +[ {"start":0, "end":349, "count":1}, + {"start":52, "end":203, "count":1}, + {"start":158,"end":182, "count":1}]); + +TestCoverage( + "test async generator coverage", +` +class Foo { // 0000 + async *timeout() { // 0000 + return new Promise( // 0100 + (r) => setTimeout(r, 10)); // 0000 + } // 0200 +} // 0000 +new Foo().timeout(); // 0300 +`, + [ {"start":0, "end":349, "count":1}, + {"start":52, "end":203, "count":1}, + {"start":158,"end":182, "count":0}]); + +TestCoverage( + "test async generator coverage with next call", +` +class Foo { // 0000 + async *timeout() { // 0000 + return new Promise( // 0100 + (r) => setTimeout(r, 10)); // 0000 + } // 0200 +} // 0000 +new Foo().timeout().next(); // 0300 +`, + [ {"start":0, "end":349, "count":1}, + {"start":52, "end":203, "count":1}, + {"start":158,"end":182, "count":1}]); + +TestCoverage( + "test two consecutive returns", +` +class Foo { // 0000 + timeout() { // 0000 + return new Promise( // 0100 + (r) => setTimeout(r, 10)); // 0000 + return new Promise( // 0200 + (r) => setTimeout(r, 10)); // 0000 + } // 0300 +} // 0000 +new Foo().timeout(); // 0400 +`, +[ {"start":0,"end":449,"count":1}, + {"start":52,"end":303,"count":1}, + {"start":184,"end":302,"count":0}, + {"start":158,"end":182,"count":1}] ); + + +TestCoverage( + "test async generator with two consecutive returns", +` +class Foo { // 0000 + async *timeout() { // 0000 + return new Promise( // 0100 + (r) => setTimeout(r, 10)); // 0000 + return new Promise( // 0200 + (r) => setTimeout(r, 10)); // 0000 + } // 0300 +} // 0000 +new Foo().timeout().next(); // 0400 +`, +[ {"start":0,"end":449,"count":1}, + {"start":52,"end":303,"count":1}, + {"start":184,"end":302,"count":0}, + {"start":158,"end":182,"count":1}] ); + +%DebugToggleBlockCoverage(false); diff --git a/deps/v8/test/mjsunit/code-coverage-block.js b/deps/v8/test/mjsunit/code-coverage-block.js index a7bad5bf11fbc4..6cf81bcce0a311 100644 --- a/deps/v8/test/mjsunit/code-coverage-block.js +++ b/deps/v8/test/mjsunit/code-coverage-block.js @@ -205,21 +205,6 @@ TestCoverage( {"start":381,"end":391,"count":2}] ); -TestCoverage( -"for-await-of statements", -` -!async function() { // 0000 - for await (var x of [0,1,2,3]) { // 0050 - nop(); // 0100 - } // 0150 -}(); // 0200 -%PerformMicrotaskCheckpoint(); // 0250 -`, -[{"start":0,"end":299,"count":1}, - {"start":1,"end":201,"count":1}, - {"start":83,"end":153,"count":4}] -); - TestCoverage( "while and do-while statements", ` @@ -658,20 +643,6 @@ try { // 0200 {"start":317,"end":352,"count":0}] ); -TestCoverage( -"await expressions", -` -async function f() { // 0000 - await 42; // 0050 - await 42; // 0100 -}; // 0150 -f(); // 0200 -%PerformMicrotaskCheckpoint(); // 0250 -`, -[{"start":0,"end":299,"count":1}, - {"start":0,"end":151,"count":1}] -); - TestCoverage( "LogicalOrExpression assignment", ` @@ -1097,4 +1068,19 @@ f(43); // 0450 {"start":204,"end":226,"count":1}] ); +TestCoverage( +"https://crbug.com/v8/9857", +`function foo() {}`, +[{"start":0,"end":17,"count":1}, + {"start":0,"end":17,"count":0}] +); + +TestCoverage( +"https://crbug.com/v8/9857", +`function foo() {function bar() {}}; foo()`, +[{"start":0,"end":41,"count":1}, + {"start":0,"end":34,"count":1}, + {"start":16,"end":33,"count":0}] +); + %DebugToggleBlockCoverage(false); diff --git a/deps/v8/test/mjsunit/compiler/concurrent-inlining-1.js b/deps/v8/test/mjsunit/compiler/concurrent-inlining-1.js new file mode 100644 index 00000000000000..9cbdbc863fb437 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/concurrent-inlining-1.js @@ -0,0 +1,26 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// This test ensures that we manage to serialize the global.gaga function for +// compilation and therefore are able to inline it. Since the call feedback in +// bar is megamorphic, this relies on recording the correct accumulator hint for +// the named load of obj.gaga while serializing bar (in turn while serializing +// foo). + +const global = this; +global.gaga = function gaga() { return true; }; + +function bar(obj) { return obj.gaga(); }; +function foo() { return %TurbofanStaticAssert(bar(global)); } + +%PrepareFunctionForOptimization(foo); +%PrepareFunctionForOptimization(bar); +%PrepareFunctionForOptimization(global.gaga); + +bar({gaga() {}}); +foo(); +%OptimizeFunctionOnNextCall(foo); +foo(); diff --git a/deps/v8/test/mjsunit/compiler/concurrent-inlining-2.js b/deps/v8/test/mjsunit/compiler/concurrent-inlining-2.js new file mode 100644 index 00000000000000..e3e63d195cebb1 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/concurrent-inlining-2.js @@ -0,0 +1,26 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +// This test ensures that we manage to serialize the global.gaga function for +// compilation and therefore are able to inline it. Since the call feedback in +// bar is megamorphic, this relies on recording the correct accumulator hint for +// the named load of obj.gaga while serializing bar (in turn while serializing +// foo). + +const global = this; +global.gaga = function gaga() { return true; }; + +function bar(obj) { return obj.gaga(); } +function foo(obj) { obj.gaga; %TurbofanStaticAssert(bar(obj)); } + +%PrepareFunctionForOptimization(foo); +%PrepareFunctionForOptimization(bar); +%PrepareFunctionForOptimization(global.gaga); + +bar({gaga() {}}); +foo(global); +%OptimizeFunctionOnNextCall(foo); +foo(global); diff --git a/deps/v8/test/mjsunit/compiler/promise-constructor.js b/deps/v8/test/mjsunit/compiler/promise-constructor.js index ab2d7207555313..27deeda9d59f29 100644 --- a/deps/v8/test/mjsunit/compiler/promise-constructor.js +++ b/deps/v8/test/mjsunit/compiler/promise-constructor.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --allow-natives-syntax --experimental-inline-promise-constructor +// Flags: --allow-natives-syntax // We have to patch mjsunit because normal assertion failures just throw // exceptions which are swallowed in a then clause. diff --git a/deps/v8/test/mjsunit/compiler/regress-9017.js b/deps/v8/test/mjsunit/compiler/regress-9017.js index 7cbd4e0178c983..c484e177c67344 100644 --- a/deps/v8/test/mjsunit/compiler/regress-9017.js +++ b/deps/v8/test/mjsunit/compiler/regress-9017.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --noturbo-inlining --noturbo-verify-allocation +// This test invokes optimization manually, no need for stress modes: +// Flags: --nostress-opt --noalways-opt // Ensure that very large stack frames can be used successfully. // The flag --noturbo-verify-allocation is to make this run a little faster; it diff --git a/deps/v8/test/mjsunit/d8/d8-performance-measure-memory.js b/deps/v8/test/mjsunit/d8/d8-performance-measure-memory.js new file mode 100644 index 00000000000000..baf6479fff3b06 --- /dev/null +++ b/deps/v8/test/mjsunit/d8/d8-performance-measure-memory.js @@ -0,0 +1,47 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test the performance.measureMemory() function of d8. This test only makes +// sense with d8. + +load('test/mjsunit/mjsunit.js'); + +function assertLessThanOrEqual(a, b) { + assertTrue(a <= b, `Expected ${a} <= ${b}`); +} + +function checkMeasureMemoryResult(result) { + assertTrue('total' in result); + assertTrue('jsMemoryEstimate' in result.total); + assertTrue('jsMemoryRange' in result.total); + assertEquals('number', typeof result.total.jsMemoryEstimate); + assertEquals(2, result.total.jsMemoryRange.length); + assertEquals('number', typeof result.total.jsMemoryRange[0]); + assertEquals('number', typeof result.total.jsMemoryRange[1]); + assertLessThanOrEqual(result.total.jsMemoryRange[0], + result.total.jsMemoryRange[1]); + assertLessThanOrEqual(result.total.jsMemoryRange[0], + result.total.jsMemoryEstimate); + assertLessThanOrEqual(result.total.jsMemoryEstimate, + result.total.jsMemoryRange[1]); +} + +if (this.performance && performance.measureMemory) { + assertPromiseResult((async () => { + let result = await performance.measureMemory(); + checkMeasureMemoryResult(result); + })()); + + assertPromiseResult((async () => { + let result = await performance.measureMemory({detailed: false}); + checkMeasureMemoryResult(result); + })()); + + assertPromiseResult((async () => { + let result = await performance.measureMemory({detailed: true}); + // TODO(ulan): Also check the detailed results once measureMemory + // supports them. + checkMeasureMemoryResult(result); + })()); +} diff --git a/deps/v8/test/mjsunit/es6/array-iterator-detached.js b/deps/v8/test/mjsunit/es6/array-iterator-detached.js index f385039b4d0940..4e4f664373738d 100644 --- a/deps/v8/test/mjsunit/es6/array-iterator-detached.js +++ b/deps/v8/test/mjsunit/es6/array-iterator-detached.js @@ -17,7 +17,7 @@ function Baseline() { %NeverOptimizeFunction(Baseline); assertThrows(Baseline, TypeError, - "Cannot perform Array Iterator.prototype.next on a neutered ArrayBuffer"); + "Cannot perform Array Iterator.prototype.next on a detached ArrayBuffer"); function Turbo(count = 10000) { let array = Array(10000); @@ -45,4 +45,4 @@ Turbo(10); %OptimizeFunctionOnNextCall(Turbo); assertThrows(Turbo, TypeError, - "Cannot perform Array Iterator.prototype.next on a neutered ArrayBuffer"); + "Cannot perform Array Iterator.prototype.next on a detached ArrayBuffer"); diff --git a/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js b/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js index b2ebfce6c995e6..8d896b93a24101 100644 --- a/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js +++ b/deps/v8/test/mjsunit/es6/block-conflicts-sloppy.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Test for conflicting variable bindings. +// Stress-testing this test is very slow and provides no useful coverage. +// Flags: --nostress-opt --noalways-opt function CheckException(e) { var string = e.toString(); diff --git a/deps/v8/test/mjsunit/es6/block-const-assign.js b/deps/v8/test/mjsunit/es6/block-const-assign.js index 541dc0d97b1937..5700d69d043002 100644 --- a/deps/v8/test/mjsunit/es6/block-const-assign.js +++ b/deps/v8/test/mjsunit/es6/block-const-assign.js @@ -29,6 +29,9 @@ // when using an immutable binding in an assigment or with // prefix/postfix decrement/increment operators. +// Optimization stress is not useful for early syntax errors. +// Flags: --nostress-opt --noalways-opt + "use strict"; const decls = [ @@ -135,7 +138,8 @@ let usecontexts = [ function Test(program, error) { program = "'use strict'; " + program; try { - print(program, " // throw " + error.name); + // If you need to debug this test, enable the following line: + // print(program, " // throw " + error.name); eval(program); } catch (e) { assertInstanceof(e, error); diff --git a/deps/v8/test/mjsunit/es6/iterator-eager-deopt.js b/deps/v8/test/mjsunit/es6/iterator-eager-deopt.js new file mode 100644 index 00000000000000..fe004c8c6d4edf --- /dev/null +++ b/deps/v8/test/mjsunit/es6/iterator-eager-deopt.js @@ -0,0 +1,69 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The GetIterator bytecode is used to implement a part of the iterator +// protocol (https://tc39.es/ecma262/#sec-getiterator). Here, the +// bytecode performs multiple operations including some that have side-effects +// and may deoptimize eagerly or lazily. +// This test ensures the eager deoptimization is handled correctly. + +// Flags: --allow-natives-syntax --no-always-opt + +var getIteratorCount = 0; +var iteratorCount = 0; +var iteratorAfterEagerDeoptCount = 0; + +function foo(obj) { + // The following for-of loop uses the iterator protocol to iterate + // over the 'obj'. + // The GetIterator bytecode invovlves 3 steps: + // 1. method = GetMethod(obj, @@iterator) + // 2. iterator = Call(method, obj) + // 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid. + for(var x of obj){} +} + +// This iterator gets inlined when the 'foo' function is JIT compiled for +// the first time. +var iterator = function() { + iteratorCount++; + return { + next: function() { + return { done: true }; + } + } +} + +var iteratorAfterEagerDeopt = function() { + iteratorAfterEagerDeoptCount++; + return { + next: function() { + return { done: true }; + } + } +} + +// Here, retrieval of function at @@iterator has side effect (increments the +// 'getIteratorCount'). Changing the value of 'iterator' in the JIT compiled +// 'foo' causes deoptimization after the count is incremented. Now the deopt +// cannot resume at the beginning of the bytecode because it would end up in +// incrementing the count again. +let y = { get [Symbol.iterator] () { + getIteratorCount++; + return iterator; + } + }; + +%PrepareFunctionForOptimization(foo); +foo(y); +foo(y); +%OptimizeFunctionOnNextCall(foo); + +// Change the value of 'iterator' to trigger eager deoptimization of 'foo'. +iterator = iteratorAfterEagerDeopt +foo(y); +assertUnoptimized(foo); +assertEquals(getIteratorCount, 3); +assertEquals(iteratorCount, 2); +assertEquals(iteratorAfterEagerDeoptCount, 1); diff --git a/deps/v8/test/mjsunit/es6/iterator-invalid-receiver-opt.js b/deps/v8/test/mjsunit/es6/iterator-invalid-receiver-opt.js new file mode 100644 index 00000000000000..fac416b5b5c63b --- /dev/null +++ b/deps/v8/test/mjsunit/es6/iterator-invalid-receiver-opt.js @@ -0,0 +1,51 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The GetIterator bytecode is used to implement a part of the iterator +// protocol (https://tc39.es/ecma262/#sec-getiterator). +// Here, call to the @@iterator property returns invalid JS receiver. +// This test ensures that the optimized version of the GetIterator bytecode +// incorporates exception handling mechanism without deoptimizing. + +// Flags: --allow-natives-syntax --opt + +var iteratorCount = 0; +var exceptionCount = 0; + +function foo(obj) { + // The following for-of loop uses the iterator protocol to iterate + // over the 'obj'. + // The GetIterator bytecode invovlves 3 steps: + // 1. method = GetMethod(obj, @@iterator) + // 2. iterator = Call(method, obj) + // 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid. + try{ + for(let a of obj){ + assertUnreachable(); + } + } catch(e){ + exceptionCount++; + } +} + +// This iterator retuns '3' which is not a valid JSReceiver +var iterator = function() { + iteratorCount++; + return 3; +} + +let y = { + get [Symbol.iterator]() { + return iterator; + } +}; + +%PrepareFunctionForOptimization(foo); +foo(y); +foo(y); +%OptimizeFunctionOnNextCall(foo); +foo(y); +assertOptimized(foo); +assertEquals(iteratorCount, 3); +assertEquals(exceptionCount, 3); diff --git a/deps/v8/test/mjsunit/es6/iterator-lazy-deopt.js b/deps/v8/test/mjsunit/es6/iterator-lazy-deopt.js new file mode 100644 index 00000000000000..f2b39a208d181e --- /dev/null +++ b/deps/v8/test/mjsunit/es6/iterator-lazy-deopt.js @@ -0,0 +1,71 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The GetIterator bytecode is used to implement a part of the iterator +// protocol (https://tc39.es/ecma262/#sec-getiterator). Here, the +// bytecode performs multiple operations including some that have side-effects +// and may deoptimize eagerly or lazily. +// This test ensures the lazy deoptimization is handled correctly. + +// Flags: --allow-natives-syntax --no-always-opt + +var triggerLazyDeopt = false +var iteratorCount = 0; +var iteratorAfterLazyDeoptCount = 0; +var getIteratorCount = 0; + +function foo(obj) { + // The following for-of loop uses the iterator protocol to iterate + // over the 'obj'. + // The GetIterator bytecode invovlves 3 steps: + // 1. method = GetMethod(obj, @@iterator) + // 2. iterator = Call(method, obj) + // 3. if(!IsJSReceiver(iterator)) throw SymbolIteratorInvalid. + for(var x of obj){} +} + +// This iterator gets inlined when the 'foo' function is JIT compiled for +// the first time. +var iterator = function() { + iteratorCount++; + return { + next: function() { + return { done: true }; + } + } +} + +iteratorAfterLazyDeopt = function() { + iteratorAfterLazyDeoptCount++; + return { + next: function() { + return { done: true }; + } + } +} +// Here, retrieval of function at @@iterator has side effect (increments the +// 'getIteratorCount').The lazy deoptimization is triggerred by setting the +// 'triggerLazyDeopt' to true after the count is incremented. Now the deopt +// cannot resume at the beginning of the bytecode because it would end up in +// incrementing the count again. +let y = { get [Symbol.iterator] () { + getIteratorCount++; + if(triggerLazyDeopt) { + %DeoptimizeFunction(foo); + iterator = iteratorAfterLazyDeopt + } + return iterator; + } + }; + +%PrepareFunctionForOptimization(foo); +foo(y); +foo(y); +%OptimizeFunctionOnNextCall(foo); +triggerLazyDeopt = true; +foo(y); +assertUnoptimized(foo); +assertEquals(getIteratorCount, 3); +assertEquals(iteratorCount, 2); +assertEquals(iteratorAfterLazyDeoptCount, 1); diff --git a/deps/v8/test/mjsunit/es6/large-classes-properties.js b/deps/v8/test/mjsunit/es6/large-classes-properties.js index fe3fb13b8ff0cc..c725d8376e5aa1 100644 --- a/deps/v8/test/mjsunit/es6/large-classes-properties.js +++ b/deps/v8/test/mjsunit/es6/large-classes-properties.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax +// This gets very slow with stress flags, and triggers optimization anyway: +// Flags: --nostress-opt --noalways-opt (function testLargeClassesProperties(){ // This is to test for dictionary mode when there more than diff --git a/deps/v8/test/mjsunit/global-proxy-globalThis.js b/deps/v8/test/mjsunit/global-proxy-globalThis.js new file mode 100644 index 00000000000000..3b53d74792de8a --- /dev/null +++ b/deps/v8/test/mjsunit/global-proxy-globalThis.js @@ -0,0 +1,91 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + %OptimizeFunctionOnNextCall(foo); + assertSame(foo(), foo); +} + +// detachGlobal, old map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.detachGlobal(realm); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, old map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.navigate(realm); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// detachGlobal, new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + assertSame(foo(), foo); + Realm.detachGlobal(realm); + %PrepareFunctionForOptimization(foo); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + assertSame(foo(), foo); + Realm.navigate(realm); + %PrepareFunctionForOptimization(foo); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// detachGlobal, old and new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.detachGlobal(realm); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, old and new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return globalThis.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.navigate(realm); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} diff --git a/deps/v8/test/mjsunit/global-proxy-this.js b/deps/v8/test/mjsunit/global-proxy-this.js new file mode 100644 index 00000000000000..32e786865093d5 --- /dev/null +++ b/deps/v8/test/mjsunit/global-proxy-this.js @@ -0,0 +1,91 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + %OptimizeFunctionOnNextCall(foo); + assertSame(foo(), foo); +} + +// detachGlobal, old map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.detachGlobal(realm); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, old map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.navigate(realm); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// detachGlobal, new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + assertSame(foo(), foo); + Realm.detachGlobal(realm); + %PrepareFunctionForOptimization(foo); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + assertSame(foo(), foo); + Realm.navigate(realm); + %PrepareFunctionForOptimization(foo); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// detachGlobal, old and new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.detachGlobal(realm); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} + +// navigate, old and new map +{ + const realm = Realm.createAllowCrossRealmAccess(); + const foo = Realm.eval(realm, "function foo() { return this.foo }; foo"); + + %PrepareFunctionForOptimization(foo); + assertSame(foo(), foo); + Realm.navigate(realm); + assertThrows(foo); + %OptimizeFunctionOnNextCall(foo); + assertThrows(foo); +} diff --git a/deps/v8/test/mjsunit/harmony/modules-import-15-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-import-15-top-level-await.mjs new file mode 100644 index 00000000000000..1feb3dae277721 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-15-top-level-await.mjs @@ -0,0 +1,58 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await --allow-natives-syntax +// Flags: --harmony-dynamic-import + +var ran = false; + +async function test1() { + try { + let x = await import('modules-skip-8.mjs'); + %AbortJS('failure: should be unreachable'); + } catch(e) { + assertEquals('x is not defined', e.message); + ran = true; + } +} + +test1(); +%PerformMicrotaskCheckpoint(); +assertTrue(ran); + +ran = false; + +async function test2() { + try { + let x = await import('modules-skip-9.mjs'); + %AbortJS('failure: should be unreachable'); + } catch(e) { + assertInstanceof(e, SyntaxError); + assertEquals( + "The requested module 'modules-skip-empty.mjs' does not provide an " + + "export named 'default'", + e.message); + ran = true; + } +} + +test2(); +%PerformMicrotaskCheckpoint(); +assertTrue(ran); + +ran = false; + +async function test3() { + try { + let x = await import('nonexistent-file.mjs'); + %AbortJS('failure: should be unreachable'); + } catch(e) { + assertTrue(e.startsWith('Error reading')); + ran = true; + } +} + +test3(); +%PerformMicrotaskCheckpoint(); +assertTrue(ran); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-15.mjs b/deps/v8/test/mjsunit/harmony/modules-import-15.mjs index b4febd5787c321..8b313d6017896e 100644 --- a/deps/v8/test/mjsunit/harmony/modules-import-15.mjs +++ b/deps/v8/test/mjsunit/harmony/modules-import-15.mjs @@ -3,6 +3,9 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --harmony-dynamic-import +// +// Note: This test fails with top level await due to test1, which tries to +// import a module using top level await and expects it to fail. var ran = false; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-1.mjs new file mode 100644 index 00000000000000..9c9dfc385b51b6 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-1.mjs @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, ['1', '2', '3', '4']); + +import 'modules-skip-1-rqstd-order.mjs'; +import 'modules-skip-2-rqstd-order.mjs'; +import 'modules-skip-3-rqstd-order.mjs'; +import 'modules-skip-4-rqstd-order.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-2.mjs new file mode 100644 index 00000000000000..374660ec798ef2 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-2.mjs @@ -0,0 +1,15 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1_dir_a', '2_dir_a', '3_dir_a', '4_dir_a', + '1', '2', '3', '4', + '1_dir_b', '2_dir_b', '3_dir_b', '4_dir_b']); + +import 'modules-skip-1-rqstd-order-top-level-await.mjs'; +import 'modules-skip-2-rqstd-order-top-level-await.mjs'; +import 'modules-skip-3-rqstd-order-top-level-await.mjs'; +import 'modules-skip-4-rqstd-order-top-level-await.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-3.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-3.mjs new file mode 100644 index 00000000000000..f145a75d5b31d1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-3.mjs @@ -0,0 +1,13 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1', '2_dir_a', '3', '4_dir_a', '2', '4', '2_dir_b', '4_dir_b']); + +import 'modules-skip-1-rqstd-order.mjs'; +import 'modules-skip-2-rqstd-order-top-level-await.mjs'; +import 'modules-skip-3-rqstd-order.mjs'; +import 'modules-skip-4-rqstd-order-top-level-await.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-4.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-4.mjs new file mode 100644 index 00000000000000..57e6e5431053e1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-4.mjs @@ -0,0 +1,17 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1_dir_a', '2_dir_a', '3_dir_a', '4_dir_a', + '1', '2', '3', '4', + '1_dir_b', '2_dir_b', '3_dir_b', '4_dir_b', + '1_ind', '2_ind', '3_ind', '4_ind', +]); + +import 'modules-skip-1-rqstd-order-indirect-top-level-await.mjs'; +import 'modules-skip-2-rqstd-order-indirect-top-level-await.mjs'; +import 'modules-skip-3-rqstd-order-indirect-top-level-await.mjs'; +import 'modules-skip-4-rqstd-order-indirect-top-level-await.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-5.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-5.mjs new file mode 100644 index 00000000000000..e018705c334549 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-5.mjs @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1', '2_dir_a', '3_dir_a', '4', + '2', '3', '2_dir_b', '3_dir_b', + '2_ind', +]); + +import 'modules-skip-1-rqstd-order.mjs'; +import 'modules-skip-2-rqstd-order-indirect-top-level-await.mjs'; +import 'modules-skip-3-rqstd-order-top-level-await.mjs'; +import 'modules-skip-4-rqstd-order.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-6.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-6.mjs new file mode 100644 index 00000000000000..8d3ed1f2558bdf --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-6.mjs @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1_dir_a', '2_dir_a', '3', '4_dir_a', + '1', '2', '4', '1_dir_b', '2_dir_b', + '4_dir_b', '2_ind', +]); + +import 'modules-skip-1-rqstd-order-top-level-await.mjs'; +import 'modules-skip-2-rqstd-order-indirect-top-level-await.mjs'; +import 'modules-skip-3-rqstd-order.mjs'; +import 'modules-skip-4-rqstd-order-top-level-await.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-7.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-7.mjs new file mode 100644 index 00000000000000..64bbeb1eb47680 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-7.mjs @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1_udir_a', '1_udir_b', '2', +]); + +import 'modules-skip-1-rqstd-order-unreached-top-level-await.mjs'; +import 'modules-skip-2-rqstd-order.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-8.mjs b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-8.mjs new file mode 100644 index 00000000000000..0d9fe3e3818726 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-rqstd-order-top-level-await-8.mjs @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-top-level-await + +assertEquals(globalThis.test262, [ + '1_udir_a', '1_udir_b', '2', '1_uind' +]); + +import 'modules-skip-1-rqstd-order-indirect-unreached-top-level-await.mjs'; +import 'modules-skip-2-rqstd-order.mjs'; diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-1.mjs new file mode 100644 index 00000000000000..c8efa5d94ebd68 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-1.mjs @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-dynamic-import --harmony-top-level-await + +let promise_resolved = false; +let m = import('modules-skip-1.mjs'); +m.then( + () => { promise_resolved = true; }, + () => { %AbortJS('Promise rejected'); }); +await m; + +assertEquals(promise_resolved, true); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-2.mjs new file mode 100644 index 00000000000000..0f74aa7ca97a53 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-2.mjs @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +let m = import('modules-skip-1.mjs'); +let m_namespace = await m; + +assertEquals(42, m_namespace.life()); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-3.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-3.mjs new file mode 100644 index 00000000000000..44c8145127fbd7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-3.mjs @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +let m1 = import('modules-skip-1.mjs'); +let m1_namespace = await m1; + +let m2 = import('modules-skip-3.mjs'); +let m2_namespace = await m2; + +assertEquals(42, m1_namespace.life()); +assertEquals('42', m2_namespace.stringlife); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-4.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-4.mjs new file mode 100644 index 00000000000000..29730fa4a515d1 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-4.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +import * as m from 'modules-skip-1-top-level-await.mjs' + +assertEquals(42, m.life()); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-5.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-5.mjs new file mode 100644 index 00000000000000..f1e78133461efa --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-5.mjs @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +import * as m from 'modules-skip-2-top-level-await.mjs' + +assertEquals(42, m.life()); +assertEquals('42', m.stringlife); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-6.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-6.mjs new file mode 100644 index 00000000000000..f852895e4bc423 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-6.mjs @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +import * as m from 'modules-skip-3-top-level-await.mjs' + +assertEquals(42, m.life()); +assertEquals('42', m.stringlife); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-7.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-7.mjs new file mode 100644 index 00000000000000..26f14407747cac --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-7.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-top-level-await --harmony-dynamic-import + +import * as m from 'modules-skip-6-top-level-await.mjs'; + +assertEquals(m.m1.life(), m.m2.life()); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-8.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-8.mjs new file mode 100644 index 00000000000000..aa80c73eddb424 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-8.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +import * as m from 'modules-skip-7-top-level-await.mjs' + +assertEquals(42, m.life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-cycle.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-cycle.mjs new file mode 100644 index 00000000000000..0ec478e59baddd --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-cycle.mjs @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-top-level-await --harmony-dynamic-import + +import * as m1 from 'modules-skip-1-top-level-await-cycle.mjs' +import * as m2 from 'modules-skip-2-top-level-await-cycle.mjs' +import * as m3 from 'modules-skip-3-top-level-await-cycle.mjs' + +assertSame(m1.m1.m.m.life, m1.m2.m.m.life); +assertSame(m1.m1.m.m.life, m2.m.m.life); +assertSame(m1.m1.m.m.life, m3.m.m.life); + +let m4 = await import('modules-skip-1.mjs'); +assertSame(m1.m1.m.m.life, m4.life); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-1.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-1.mjs new file mode 100644 index 00000000000000..1e22f15758b54f --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-1.mjs @@ -0,0 +1,18 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +let ran = false; +let m = import('modules-skip-2.mjs'); +await m.then( + () => { + assertUnreachable(); + }, + (e) => { + assertEquals(e.message, '42 is not the answer'); + ran = true; + }); + +assertEquals(ran, true); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-2.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-2.mjs new file mode 100644 index 00000000000000..476cfbee15956b --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-2.mjs @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +let ran = false; +try { + await import('modules-skip-2.mjs'); + assertUnreachable(); +} catch (e) { + assertEquals(e.message, '42 is not the answer'); + ran = true; +} + +assertEquals(ran, true); diff --git a/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-3.mjs b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-3.mjs new file mode 100644 index 00000000000000..20de7ef06e6cb7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-import-top-level-await-exception-3.mjs @@ -0,0 +1,16 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-dynamic-import --harmony-top-level-await + +let ran = false; +try { + await import('modules-skip-4-top-level-await.mjs'); + assertUnreachable(); +} catch (e) { + assertEquals(e.message, '42 is not the answer'); + ran = true; +} + +assertEquals(ran, true); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-top-level-await.mjs new file mode 100644 index 00000000000000..cbd357c86b029c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-top-level-await.mjs @@ -0,0 +1,6 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-1-rqstd-order-top-level-await.mjs' +Function('return this;')().test262.push('1_ind'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-unreached-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-unreached-top-level-await.mjs new file mode 100644 index 00000000000000..543a0382321102 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-indirect-unreached-top-level-await.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-1-rqstd-order-unreached-top-level-await.mjs'; + +Function('return this;')().test262.push('1_uind'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-top-level-await.mjs new file mode 100644 index 00000000000000..fcbe07a8482f83 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-top-level-await.mjs @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (typeof Function('return this;')().test262 === 'undefined') { + Function('return this;')().test262 = ['1_dir_a']; +} else { + Function('return this;')().test262.push('1_dir_a'); +} +let m = import('modules-skip-1-rqstd-order.mjs'); +await m; +Function('return this;')().test262.push('1_dir_b'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-unreached-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-unreached-top-level-await.mjs new file mode 100644 index 00000000000000..f2b2104ad381a6 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order-unreached-top-level-await.mjs @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (typeof Function('return this;')().test262 === 'undefined') { + Function('return this;')().test262 = ['1_udir_a']; +} else { + Function('return this;')().test262.push('1_udir_a'); +} +if (false) { + assertUnreachable(); + await 42; +} +Function('return this;')().test262.push('1_udir_b'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order.mjs new file mode 100644 index 00000000000000..5ac18829351208 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-rqstd-order.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (typeof Function('return this;')().test262 === 'undefined') { + Function('return this;')().test262 = ['1']; +} else { + Function('return this;')().test262.push('1'); +} diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await-cycle.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await-cycle.mjs new file mode 100644 index 00000000000000..601e80a1b12f9c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await-cycle.mjs @@ -0,0 +1,8 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m1 from 'modules-skip-2-top-level-await-cycle.mjs'; +import * as m2 from 'modules-skip-3-top-level-await-cycle.mjs'; + +export { m1, m2 }; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await.mjs new file mode 100644 index 00000000000000..87816b9183bc35 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-1-top-level-await.mjs @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let m = import('modules-skip-1.mjs'); +let m_namespace = await m; + +export function life() { + return m_namespace.life(); +} diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-indirect-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-indirect-top-level-await.mjs new file mode 100644 index 00000000000000..2305422b8131ff --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-indirect-top-level-await.mjs @@ -0,0 +1,6 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-2-rqstd-order-top-level-await.mjs' +Function('return this;')().test262.push('2_ind'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-top-level-await.mjs new file mode 100644 index 00000000000000..c2b20a53f2dccb --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order-top-level-await.mjs @@ -0,0 +1,8 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('2_dir_a'); +let m = import('modules-skip-2-rqstd-order.mjs'); +await m; +Function('return this;')().test262.push('2_dir_b'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order.mjs new file mode 100644 index 00000000000000..7dbd64c4cf78f7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-2-rqstd-order.mjs @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('2'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await-cycle.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await-cycle.mjs new file mode 100644 index 00000000000000..3171bb88eab35b --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await-cycle.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m from 'modules-skip-4-top-level-await-cycle.mjs'; + +export { m }; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await.mjs new file mode 100644 index 00000000000000..8e02410b584c2c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-2-top-level-await.mjs @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m1 from 'modules-skip-3.mjs' + +let m2 = import('modules-skip-1-top-level-await.mjs'); +let m2_namespace = await m2; + +export let stringlife = m1.stringlife; + +export function life() { + return m2_namespace.life(); +} diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-indirect-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-indirect-top-level-await.mjs new file mode 100644 index 00000000000000..2b4dae00634522 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-indirect-top-level-await.mjs @@ -0,0 +1,6 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-3-rqstd-order-top-level-await.mjs' +Function('return this;')().test262.push('3_ind'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-top-level-await.mjs new file mode 100644 index 00000000000000..f3b890473184ac --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order-top-level-await.mjs @@ -0,0 +1,8 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('3_dir_a'); +let m = import('modules-skip-3-rqstd-order.mjs'); +await m; +Function('return this;')().test262.push('3_dir_b'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order.mjs new file mode 100644 index 00000000000000..bd70e70aa575c2 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-3-rqstd-order.mjs @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('3'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await-cycle.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await-cycle.mjs new file mode 100644 index 00000000000000..3171bb88eab35b --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await-cycle.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m from 'modules-skip-4-top-level-await-cycle.mjs'; + +export { m }; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await.mjs new file mode 100644 index 00000000000000..eea2c7a29b01ec --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-3-top-level-await.mjs @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m1 from 'modules-skip-1-top-level-await.mjs'; +import * as m2 from 'modules-skip-3.mjs'; + +export function life() { + return m1.life(); +} + +export let stringlife = m2.stringlife; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-indirect-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-indirect-top-level-await.mjs new file mode 100644 index 00000000000000..7c75a9aadc6bdc --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-indirect-top-level-await.mjs @@ -0,0 +1,6 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-4-rqstd-order-top-level-await.mjs' +Function('return this;')().test262.push('4_ind'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-top-level-await.mjs new file mode 100644 index 00000000000000..1659ba681ec47b --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order-top-level-await.mjs @@ -0,0 +1,8 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('4_dir_a'); +let m = import('modules-skip-4-rqstd-order.mjs'); +await m; +Function('return this;')().test262.push('4_dir_b'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order.mjs new file mode 100644 index 00000000000000..7fdd12ca7aa62f --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-4-rqstd-order.mjs @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Function('return this;')().test262.push('4'); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await-cycle.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await-cycle.mjs new file mode 100644 index 00000000000000..2b58e2399fb5dd --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await-cycle.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let m = await import('modules-skip-1.mjs'); + +export { m }; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await.mjs new file mode 100644 index 00000000000000..00576a23c1fe0a --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-4-top-level-await.mjs @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'modules-skip-5-top-level-await.mjs'; + +assertUnreachable(); diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-5-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-5-top-level-await.mjs new file mode 100644 index 00000000000000..28cf2a9c189bab --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-5-top-level-await.mjs @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +await import('modules-skip-2.mjs') diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-6-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-6-top-level-await.mjs new file mode 100644 index 00000000000000..8637d5643bbec0 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-6-top-level-await.mjs @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import * as m1 from 'modules-skip-3-top-level-await.mjs'; + +let m2 = await import('modules-skip-1.mjs'); + +export { m1, m2 }; diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-7-top-level-await.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-7-top-level-await.mjs new file mode 100644 index 00000000000000..bc7f22b771a960 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/modules-skip-7-top-level-await.mjs @@ -0,0 +1,14 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function sleeping_promise() { + return new Promise((resolve) => setTimeout(resolve)); +} + +export let life; + +await sleeping_promise(); +life = -1; +await sleeping_promise(); +life = (await import('modules-skip-1.mjs')).life(); diff --git a/deps/v8/test/mjsunit/harmony/private-accessors.js b/deps/v8/test/mjsunit/harmony/private-accessors.js index 3a828116a1c3db..44ec2a07906a3b 100644 --- a/deps/v8/test/mjsunit/harmony/private-accessors.js +++ b/deps/v8/test/mjsunit/harmony/private-accessors.js @@ -83,6 +83,30 @@ assertEquals('d', new C().getA().getD()); } +{ + assertThrows(() => { + class A { + [this.#a] = 1; + get #a() {} + } + }, TypeError); + + assertThrows(() => { + class A { + [this.#a] = 1; + set #a(val) {} + } + }, TypeError); + + assertThrows(() => { + class A { + [this.#a] = 1; + set #a(val) {} + get #a() {} + } + }, TypeError); +} + // Duplicate private accessors. // https://tc39.es/proposal-private-methods/#sec-static-semantics-early-errors { diff --git a/deps/v8/test/mjsunit/harmony/private-fields.js b/deps/v8/test/mjsunit/harmony/private-fields.js index 0c1c04bc75038b..067b20862049ce 100644 --- a/deps/v8/test/mjsunit/harmony/private-fields.js +++ b/deps/v8/test/mjsunit/harmony/private-fields.js @@ -476,3 +476,12 @@ let c = new C; assertThrows(() => c.getA(), SyntaxError); } + +{ + assertThrows(() => { + class A { + [this.#a] = 1; + #a = 2; + } + }, TypeError); +} diff --git a/deps/v8/test/mjsunit/harmony/private-methods.js b/deps/v8/test/mjsunit/harmony/private-methods.js index fcd80823c1c52a..b42e4f658c288b 100644 --- a/deps/v8/test/mjsunit/harmony/private-methods.js +++ b/deps/v8/test/mjsunit/harmony/private-methods.js @@ -295,3 +295,12 @@ assertEquals(1, new C().fn()); } + +{ + assertThrows(() => { + class A { + [this.#a] = 1; + #a() { } + } + }, TypeError); +} diff --git a/deps/v8/test/mjsunit/harmony/private-name-scopes.js b/deps/v8/test/mjsunit/harmony/private-name-scopes.js new file mode 100644 index 00000000000000..e6060cf81a62c7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/private-name-scopes.js @@ -0,0 +1,137 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +{ + let heritageFn; + class O { + #f = "O.#f"; + static C = class C extends (heritageFn = function () { + return class D { + exfil(obj) { return obj.#f; } + exfilEval(obj) { return eval("obj.#f"); } + }; + }) { + #f = "C.#f"; + }; + } + + const o = new O; + const c = new O.C; + const D = heritageFn(); + const d = new D; + assertEquals(d.exfil(o), "O.#f"); + assertEquals(d.exfilEval(o), "O.#f"); + assertThrows(() => d.exfil(c), TypeError); + assertThrows(() => d.exfilEval(c), TypeError); +} + +// Early errors + +assertThrows(() => eval("new class extends " + + "(class { m() { let x = this.#f; } }) " + + "{ #f }"), SyntaxError); + +assertThrows(() => eval("new class extends this.#foo { #foo }"), SyntaxError); + +// Runtime errors + +{ + // Test private name context chain recalc. + let heritageFn; + class O { + #f = "O.#f"; + static C = class C extends (heritageFn = function () { + return class D { exfil(obj) { return obj.#f; } } + }) { + #f = "C.#f"; + }; + } + + const o = new O; + const c = new O.C; + const D = heritageFn(); + const d = new D; + assertEquals(d.exfil(o), "O.#f"); + assertThrows(() => d.exfil(c), TypeError); +} + +{ + // Test private name context chain recalc with nested closures with context. + let heritageFn; + class O { + #f = "O.#f"; + static C = class C extends (heritageFn = function () { + let forceContext = 1; + return () => { + assertEquals(forceContext, 1); + return class D { exfil(obj) { return obj.#f; } } + }; + }) { + #f = "C.#f"; + }; + } + + const o = new O; + const c = new O.C; + const D = heritageFn()(); + const d = new D; + assertEquals(d.exfil(o), "O.#f"); + assertThrows(() => d.exfil(c), TypeError); +} + +{ + // Test private name context chain recalc where skipped class has no context. + let heritageFn; + class O { + #f = "O.#f"; + static C = class C0 extends (class C1 extends (heritageFn = function (obj) { + if (obj) { return obj.#f; } + }) {}) { + #f = "C0.#f" + } + } + + const o = new O; + const c = new O.C; + assertEquals(heritageFn(o), "O.#f"); + assertThrows(() => heritageFn(c), TypeError); +} + +{ + // Test private name context chain recalc where skipping function has no + // context. + let heritageFn; + class O { + #f = "O.#f"; + static C = class C extends (heritageFn = function () { + return (obj) => { return obj.#f; } + }) { + #f = "C.#f"; + } + } + + const o = new O; + const c = new O.C; + assertEquals(heritageFn()(o), "O.#f"); + assertThrows(() => heritageFn()(c), TypeError); +} + +{ + // Test private name context chain recalc where neither skipped class nor + // skipping function has contexts. + let heritageFn; + class O { + #f = "O.#f"; + static C = class C0 extends (class C1 extends (heritageFn = function () { + return (obj) => { return obj.#f; } + }) {}) { + #f = "C0.#f"; + } + } + + const o = new O; + const c = new O.C; + assertEquals(heritageFn()(o), "O.#f"); + assertThrows(() => heritageFn()(c), TypeError); +} diff --git a/deps/v8/test/mjsunit/harmony/regexp-match-indices.js b/deps/v8/test/mjsunit/harmony/regexp-match-indices.js new file mode 100644 index 00000000000000..cc3710ce7ecd3d --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/regexp-match-indices.js @@ -0,0 +1,105 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-regexp-match-indices + +// Sanity test. +{ + const re = /a+(?<Z>z)?/; + const m = re.exec("xaaaz"); + + assertEquals(m.indices, [[1, 5], [4, 5]]); + assertEquals(m.indices.groups, {'Z': [4, 5]}) +} + +// Capture groups that are not matched return `undefined`. +{ + const re = /a+(?<Z>z)?/; + const m = re.exec("xaaay"); + + assertEquals(m.indices, [[1, 4], undefined]); + assertEquals(m.indices.groups, {'Z': undefined}); +} + +// Two capture groups. +{ + const re = /a+(?<A>zz)?(?<B>ii)?/; + const m = re.exec("xaaazzii"); + + assertEquals(m.indices, [[1, 8], [4, 6], [6, 8]]); + assertEquals(m.indices.groups, {'A': [4, 6], 'B': [6, 8]}); +} + +// No capture groups. +{ + const re = /a+/; + const m = re.exec("xaaazzii"); + + assertEquals(m.indices [[1, 4]]); + assertEquals(m.indices.groups, undefined); +} + +// No match. +{ + const re = /a+/; + const m = re.exec("xzzii"); + + assertEquals(null, m); +} + +// Unnamed capture groups. +{ + const re = /a+(z)?/; + const m = re.exec("xaaaz") + + assertEquals(m.indices, [[1, 5], [4, 5]]); + assertEquals(m.indices.groups, undefined) +} + +// Named and unnamed capture groups. +{ + const re = /a+(z)?(?<Y>y)?/; + const m = re.exec("xaaazyy") + + assertEquals(m.indices, [[1, 6], [4, 5], [5, 6]]); + assertEquals(m.indices.groups, {'Y': [5, 6]}) +} + + +// Verify property overwrite. +{ + const re = /a+(?<Z>z)?/; + const m = re.exec("xaaaz"); + + m.indices = null; + assertEquals(null, m.indices); +} + +// Mess with array prototype, we should still do the right thing. +{ + Object.defineProperty(Array.prototype, "groups", { + get: () => { + assertUnreachable(); + return null; + }, + set: (x) => { + assertUnreachable(); + } + }); + + Object.defineProperty(Array.prototype, "0", { + get: () => { + assertUnreachable(); + return null; + }, + set: (x) => { + assertUnreachable(); + } + }); + + const re = /a+(?<Z>z)?/; + const m = re.exec("xaaaz"); + + assertEquals(m.indices.groups, {'Z': [4, 5]}) +} diff --git a/deps/v8/test/mjsunit/harmony/sharedarraybuffer-stress.js b/deps/v8/test/mjsunit/harmony/sharedarraybuffer-stress.js index 24724eea1425f6..e4cdff5d368041 100644 --- a/deps/v8/test/mjsunit/harmony/sharedarraybuffer-stress.js +++ b/deps/v8/test/mjsunit/harmony/sharedarraybuffer-stress.js @@ -9,11 +9,9 @@ function Alloc(size) { } function RunSomeAllocs(total, retained, size) { - print(`-------iterations = ${total}, retained = $ { retained } -------`); + print(`-------iterations = ${total}, retained = ${retained} -------`); var array = new Array(retained); for (var i = 0; i < total; i++) { - if ((i % 25) == 0) - print(`iteration $ { i }`); let pair = Alloc(size); // For some iterations, retain the memory, view, or both. switch (i % 3) { diff --git a/deps/v8/test/mjsunit/harmony/static-private-methods.js b/deps/v8/test/mjsunit/harmony/static-private-methods.js new file mode 100644 index 00000000000000..ed81bb303877a2 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/static-private-methods.js @@ -0,0 +1,248 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-private-methods + +"use strict"; + +// Static private methods +{ + let store = 1; + class C { + static #a() { return store; } + static a() { return this.#a(); } + } + assertEquals(C.a(), store); + assertThrows(() => C.a.call(new C), TypeError); +} + +// Complementary static private accessors. +{ + let store = 1; + class C { + static get #a() { return store; } + static set #a(val) { store = val; } + static incA() { this.#a++; } + static getA() { return this.#a; } + static setA(val) { this.#a = val; } + } + assertEquals(C.getA(), 1); + C.incA(); + assertEquals(store, 2); + C.setA(3); + assertEquals(store, 3); + + assertThrows(() => C.incA.call(new C), TypeError); + assertThrows(() => C.getA.call(new C), TypeError); + assertThrows(() => C.setA.call(new C), TypeError); + + assertThrows(() => { const incA = C.incA; incA(); }, TypeError); + assertThrows(() => { const getA = C.getA; getA(); }, TypeError); + assertThrows(() => { const setA = C.setA; setA(); }, TypeError); +} + +// Static private methods accessed explicitly in an anonymous nested class. +{ + class Outer { + #a() { return 'Outer'; } + a() { return this.#a(); } + test() { + return class { + static #a() { return 'Inner'; } + static a() { return this.#a(); } + }; + } + } + + const obj = new Outer; + const C = obj.test(); + assertEquals(C.a(), 'Inner'); + assertThrows(() => obj.a.call(C), TypeError); + assertThrows(() => obj.a.call(new C), TypeError); +} + +// Static private methods accessed explicitly in a named nested class. +{ + class Outer { + #a() { return 'Outer'; } + a() { return this.#a(); } + test() { + return class Inner { + static #a() { return 'Inner'; } + static a() { return this.#a(); } + }; + } + } + + const obj = new Outer; + const C = obj.test(); + assertEquals(C.a(), 'Inner'); + assertThrows(() => obj.a.call(C), TypeError); + assertThrows(() => obj.a.call(new C), TypeError); +} + +// Static private methods accessed through eval in an anonymous nested class. +{ + class Outer { + #a() { return 'Outer'; } + a() { return this.#a(); } + test() { + return class { + static #a() { return 'Inner'; } + static a(str) { return eval(str); } + }; + } + } + + const obj = new Outer; + const C = obj.test(); + assertEquals(C.a('this.#a()'), 'Inner'); + assertThrows(() => C.a('Outer.#a()'), TypeError); +} + +// Static private methods accessed through eval in a named nested class. +{ + class Outer { + #a() { return 'Outer'; } + a() { return this.#a(); } + test() { + return class Inner { + static #a() { return 'Inner'; } + static a(str) { return eval(str); } + }; + } + } + + const obj = new Outer; + const C = obj.test(); + assertEquals(C.a('this.#a()'), 'Inner'); + assertEquals(C.a('Inner.#a()'), 'Inner'); + assertThrows(() => C.a('Outer.#a()'), TypeError); + assertThrows(() => C.run('(new Outer).#a()'), TypeError); +} + +// Static private methods in the outer class accessed through eval +// in a named nested class. +{ + class Outer { + static #a() { return 'Outer'; } + static test() { + return class Inner { + static run(str) { return eval(str); } + }; + } + } + + const C = Outer.test(); + assertEquals(C.run('Outer.#a()'), 'Outer'); + assertThrows(() => C.run('this.#a()'), TypeError); + assertThrows(() => C.run('Inner.#a()'), TypeError); + assertThrows(() => C.run('(new Outer).#a()'), TypeError); +} + +// Static private methods in the outer class accessed explicitly +// in a named nested class. +{ + class Outer { + static #a() { return 'Outer'; } + static test() { + return class Inner { + static getA(klass) { return klass.#a(); } + }; + } + } + + const C = Outer.test(); + assertEquals(C.getA(Outer), 'Outer'); + assertThrows(() => C.getA.call(C), TypeError); + assertThrows(() => C.getA.call(new Outer), TypeError); +} + +// Static private methods in the outer class accessed explicitly +// in an anonymous nested class. +{ + class Outer { + static #a() { return 'Outer'; } + static test() { + return class { + static getA(klass) { return klass.#a(); } + }; + } + } + + const C = Outer.test(); + assertEquals(C.getA(Outer), 'Outer'); + assertThrows(() => C.getA.call(C), TypeError); + assertThrows(() => C.getA.call(new Outer), TypeError); +} + +// Super property access in static private methods +{ + class A { + static a = 1; + } + + class B extends A { + static #a() { return super.a; } + static getA() { return this.#a(); } + } + + assertEquals(B.getA(), 1); +} + +// Invalid super property access in static private methods +{ + class A { + static #a() { return 1; } + static getA() { return this.#a(); } + } + + class B extends A { + static getA() { return super.getA(); } + } + + assertThrows(() => B.getA(), TypeError); +} + +// Static private methods accessed in eval. +{ + class C { + static #m(v) { return v; } + static test(str) { + return eval(str); + } + } + + assertEquals(C.test('this.#m(1)'), 1); +} + +// Test that the receiver is checked during run time. +{ + const C = class { + static #a() { } + static test(klass) { return klass.#a; } + }; + const test = C.test; + assertThrows(test, TypeError); +} + +// Duplicate static private accessors and methods. +{ + assertThrows('class C { static get #a() {} static get #a() {} }', SyntaxError); + assertThrows('class C { static get #a() {} static #a() {} }', SyntaxError); + assertThrows('class C { static get #a() {} get #a() {} }', SyntaxError); + assertThrows('class C { static get #a() {} set #a(val) {} }', SyntaxError); + assertThrows('class C { static get #a() {} #a() {} }', SyntaxError); + + assertThrows('class C { static set #a(val) {} static set #a(val) {} }', SyntaxError); + assertThrows('class C { static set #a(val) {} static #a() {} }', SyntaxError); + assertThrows('class C { static set #a(val) {} get #a() {} }', SyntaxError); + assertThrows('class C { static set #a(val) {} set #a(val) {} }', SyntaxError); + assertThrows('class C { static set #a(val) {} #a() {} }', SyntaxError); + + assertThrows('class C { static #a() {} static #a() {} }', SyntaxError); + assertThrows('class C { static #a() {} #a(val) {} }', SyntaxError); + assertThrows('class C { static #a() {} set #a(val) {} }', SyntaxError); + assertThrows('class C { static #a() {} get #a() {} }', SyntaxError); +} diff --git a/deps/v8/test/mjsunit/md5.js b/deps/v8/test/mjsunit/md5.js index 38dc80231250dd..b2dbc1e45a7d6c 100644 --- a/deps/v8/test/mjsunit/md5.js +++ b/deps/v8/test/mjsunit/md5.js @@ -201,11 +201,9 @@ To know our further pleasure in this case,\n\ To old Free-town, our common judgment-place.\n\ Once more, on pain of death, all men depart.\n" -for (var i = 0; i < 4; ++i) { +for (var i = 0; i < 2; ++i) { plainText += plainText; } -assertEquals(hex_md5("abc"), "900150983cd24fb0d6963f7d28e17f72"); -for (var i = 0; i < 11; ++i) { - assertEquals(hex_md5(plainText), "1b8719c72d5d8bfd06e096ef6c6288c5"); -} +assertEquals("900150983cd24fb0d6963f7d28e17f72", hex_md5("abc")); +assertEquals("6c843ffbdd773e88ae4ac4a5df79a784", hex_md5(plainText)); diff --git a/deps/v8/test/mjsunit/messages.js b/deps/v8/test/mjsunit/messages.js index 916a7d554f9a57..7c3521b6857a09 100644 --- a/deps/v8/test/mjsunit/messages.js +++ b/deps/v8/test/mjsunit/messages.js @@ -166,13 +166,13 @@ for (constructor of typedArrayConstructors) { const ta = new constructor([1]); %ArrayBufferDetach(ta.buffer); ta.find(() => {}); - }, "Cannot perform %TypedArray%.prototype.find on a neutered ArrayBuffer", TypeError); + }, "Cannot perform %TypedArray%.prototype.find on a detached ArrayBuffer", TypeError); test(() => { const ta = new constructor([1]); %ArrayBufferDetach(ta.buffer); ta.findIndex(() => {}); - }, "Cannot perform %TypedArray%.prototype.findIndex on a neutered ArrayBuffer", TypeError); + }, "Cannot perform %TypedArray%.prototype.findIndex on a detached ArrayBuffer", TypeError); } // kFirstArgumentNotRegExp diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status index 134a49f7480c87..4fbc027c69c1a7 100644 --- a/deps/v8/test/mjsunit/mjsunit.status +++ b/deps/v8/test/mjsunit/mjsunit.status @@ -81,6 +81,9 @@ 'wasm/shared-memory-worker-explicit-gc-stress': [PASS, ['mode == debug', SKIP], ['tsan', SKIP]], 'wasm/shared-memory-worker-gc-stress': [PASS, ['mode == debug', SKIP]], + # Slow in simulator runs. + 'random-bit-correlations': [PASS, ['simulator_run == True', SLOW]], + ############################################################################## # Only RegExp stuff tested, no need for extensive optimizing compiler tests. 'regexp-global': [PASS, NO_VARIANTS], @@ -292,7 +295,6 @@ 'compare-known-objects-slow': [SKIP], 'compiler/array-multiple-receiver-maps': [SKIP], # Tests taking too long - 'packed-elements': [SKIP], 'regress/regress-1122': [SKIP], 'regress/regress-331444': [SKIP], 'regress/regress-353551': [SKIP], @@ -377,6 +379,7 @@ 'regress/regress-6838-2': [SKIP], 'regress/regress-6838-3': [SKIP], 'regress/regress-9022': [SKIP], + 'regress/regress-9832': [SKIP], 'regress/regress-crbug-934138': [SKIP], 'regress/regress-crbug-976934': [SKIP], @@ -393,13 +396,14 @@ 'regress/regress-crbug-759327': [SKIP], 'regress/regress-crbug-898974': [SKIP], 'regexp-tier-up': [SKIP], + 'regexp-tier-up-multiple': [SKIP], + 'regress/regress-996234': [SKIP], # These tests check that we can trace the compiler. 'tools/compiler-trace-flags': [SKIP], 'tools/compiler-trace-flags-wasm': [SKIP], # Too slow on arm64 simulator and debug: https://crbug.com/v8/7783 - 'bit-not': [PASS, ['arch == arm64 and mode == debug and simulator_run', SKIP]], 'md5': [PASS, ['arch == arm64 and mode == debug and simulator_run', SKIP]], # Slow with pointer compression. @@ -470,15 +474,15 @@ 'array-reduce': [PASS, SLOW], 'array-sort': [PASS, SLOW], 'array-splice': [PASS, SLOW], - 'bit-not': [PASS, SLOW], + 'array-store-and-grow': [PASS, SLOW], 'compiler/alloc-number': [PASS, SLOW], 'compiler/osr-with-args': [PASS, SLOW], 'generated-transition-stub': [PASS, SLOW], 'json2': [PASS, SLOW], + 'large-object-literal-slow-elements': [PASS, SLOW], 'math-floor-of-div-nosudiv': [PASS, SLOW], 'math-floor-of-div': [PASS, SLOW], 'messages': [PASS, SLOW], - 'packed-elements': [PASS, SLOW], 'regress/regress-2790': [PASS, SLOW], 'regress/regress-331444': [PASS, SLOW], 'regress/regress-490': [PASS, SLOW], @@ -486,6 +490,7 @@ 'regress/regress-create-exception': [PASS, SLOW], 'regress/regress-json-stringify-gc': [PASS, SLOW], 'string-indexof-2': [PASS, SLOW], + 'unbox-double-arrays': [PASS, SLOW], 'unicodelctest-no-optimization': [PASS, SLOW], 'unicodelctest': [PASS, SLOW], 'unicode-test': [PASS, SLOW], @@ -494,19 +499,28 @@ # BUG(v8:7247). 'regress/regress-779407': [PASS, SLOW, NO_VARIANTS], - - # BUG(v8:9256). Slow with pointer compression. - 'regress/regress-708247': [PASS, ['pointer_compression', SLOW]], - 'es6/array-concat': [PASS, ['pointer_compression', SLOW]], - 'non-extensible-array-reduce': [PASS, ['pointer_compression', SLOW]], - 'regress/regress-454725': [PASS, ['pointer_compression', SLOW]], }], # 'arch == arm64' +############################################################################## +['arch == arm64 and simulator_run', { + # Slow in simulator builds + 'compiler/osr-follow': [PASS, SLOW], + 'es6/array-concat': [PASS, SLOW], + 'non-extensible-array-reduce': [PASS, SLOW], + 'regress/regress-454725': [PASS, SLOW], + 'regress/regress-708247': [PASS, SLOW], + 'compiler/osr-big': [PASS, SLOW], + 'frozen-array-reduce': [PASS, SLOW], + 'json': [PASS, SLOW], + 'sealed-array-reduce': [PASS, SLOW], + 'try': [PASS, SLOW], +}], # 'arch == arm64 and simulator_run' + +############################################################################## ['arch == arm64 and mode == debug and simulator_run', { # Pass but take too long with the simulator in debug mode. 'array-sort': [PASS, SLOW], - 'packed-elements': [SKIP], 'regexp-global': [SKIP], 'math-floor-of-div': [PASS, SLOW], 'math-floor-of-div-nosudiv': [PASS, SLOW], @@ -641,7 +655,6 @@ # Slow tests. 'array-sort': [PASS, SLOW], 'compiler/osr-with-args': [PASS, SLOW], - 'packed-elements': [PASS, SLOW], 'regress/regress-2790': [PASS, SLOW], 'regress/regress-91008': [PASS, SLOW], 'regress/regress-json-stringify-gc': [PASS, SLOW], @@ -913,6 +926,13 @@ 'wasm/atomics-stress': [SKIP], 'wasm/atomics64-stress': [SKIP], 'wasm/futex': [SKIP], + + # Deadlocks on predictable platform (https://crbug.com/v8/9760). + 'wasm/async-compile': [SKIP], + 'wasm/streaming-compile': [SKIP], + + # Race between postMessage and wasm memory.grow. (https://crbug.com/1010272). + 'regress/wasm/regress-1010272': [SKIP], }], # 'predictable == True' ############################################################################## @@ -925,7 +945,6 @@ 'regress/regress-crbug-482998': [PASS, SLOW], 'regress/regress-91008': [PASS, SLOW], 'regress/regress-779407': [PASS, SLOW], - 'packed-elements': [PASS, SLOW], 'harmony/regexp-property-lu-ui': [PASS, SLOW], 'whitespaces': [PASS, SLOW], 'generated-transition-stub': [PASS, SLOW], @@ -964,6 +983,7 @@ # The RegExp code cache means running this test multiple times is invalid. 'regexp-tier-up': [SKIP], + 'regexp-tier-up-multiple': [SKIP], # Flaky crash on Odroid devices: https://crbug.com/v8/7678 'regress/regress-336820': [PASS, ['arch == arm and not simulator_run', SKIP]], @@ -997,10 +1017,8 @@ }], # variant == stress and (arch == arm or arch == arm64) and simulator_run ############################################################################## -['variant == nooptimization and (arch == arm or arch == arm64) and simulator_run', { +['variant in (nooptimization, jitless) and arch in (arm, arm64) and simulator_run', { # Slow tests: https://crbug.com/v8/7783 - 'md5': [SKIP], - 'packed-elements': [SKIP], 'regress/regress-crbug-319860': [SKIP], 'wasm/asm-wasm-f32': [SKIP], 'wasm/asm-wasm-f64': [SKIP], @@ -1057,7 +1075,7 @@ ############################################################################## # Liftoff is currently only sufficiently implemented on x64, ia32, arm64 and # arm. -# TODO(clemensh): Implement on all other platforms (crbug.com/v8/6600). +# TODO(clemensb): Implement on all other platforms (crbug.com/v8/6600). ['arch != x64 and arch != ia32 and arch != arm64 and arch != arm', { 'wasm/liftoff': [SKIP], 'wasm/tier-up-testing-flag': [SKIP], @@ -1068,9 +1086,6 @@ # Slow tests. 'regress/regress-crbug-493779': [SKIP], 'string-replace-gc': [SKIP], - - # https://crbug.com/v8/9221 - 'wasm/grow-shared-memory': [SKIP], }], # variant == slow_path ############################################################################## @@ -1096,4 +1111,34 @@ 'regress/regress-992389': [SKIP], }], # not embedded_builtins +############################################################################## +['variant == turboprop', { + # Deopts differently than TurboFan. + 'parallel-optimize-disabled': [SKIP], + 'compiler/native-context-specialization-hole-check': [SKIP], + 'compiler/number-comparison-truncations': [SKIP], + 'compiler/redundancy-elimination': [SKIP], + + # Static asserts for optimizations don't hold due to removed optimization + # phases. + 'compiler/concurrent-inlining-1': [SKIP], + 'compiler/concurrent-inlining-2': [SKIP], + 'compiler/diamond-followedby-branch': [SKIP], + 'compiler/load-elimination-const-field': [SKIP], + 'compiler/constant-fold-add-static': [SKIP], +}], # variant == turboprop + +############################################################################## +['variant == top_level_await', { + # specifically expects to fail on top level await. + 'harmony/modules-import-15': [SKIP], +}], # variant == top_level_await + +############################################################################## +['variant == stress_js_bg_compile_wasm_code_gc', { + # Runs significantly slower with --stress-wasm-code-gc, problematic + # especially in combination with tsan or other slow configurations. + 'wasm/many-modules': [SKIP], +}], # variant == stress_js_bg_compile_wasm_code_gc + ] diff --git a/deps/v8/test/mjsunit/mod.js b/deps/v8/test/mjsunit/mod.js index 8ad98fa7ec8395..4374dcc11d0af3 100644 --- a/deps/v8/test/mjsunit/mod.js +++ b/deps/v8/test/mjsunit/mod.js @@ -31,7 +31,6 @@ function foo() { for (var j = 1; j < 100; j++) { if (answer == i) answer = 0; // Positive case. - print(j + " % " + i + " = " + answer); m = j % i; assertEquals(answer, m, j + " % " + i); m = j % (-i); diff --git a/deps/v8/test/mjsunit/packed-elements.js b/deps/v8/test/mjsunit/packed-elements.js index d0df553451cc30..85630e79546862 100644 --- a/deps/v8/test/mjsunit/packed-elements.js +++ b/deps/v8/test/mjsunit/packed-elements.js @@ -92,12 +92,15 @@ function test6() { } function test_with_optimization(f) { - // Run tests in a loop to make sure that inlined Array() constructor runs out - // of new space memory and must fall back on runtime impl. %PrepareFunctionForOptimization(f); - for (i = 0; i < 25000; ++i) f(); + for (i = 0; i < 3; ++i) f(); + // Cause the inlined Array() constructor to fall back to the runtime impl. + %SimulateNewspaceFull(); + f(); %OptimizeFunctionOnNextCall(f); - for (i = 0; i < 25000; ++i) f(); // Make sure GC happens + f(); + %SimulateNewspaceFull(); // Make sure GC happens. + f(); } test_with_optimization(test1); diff --git a/deps/v8/test/mjsunit/readonly.js b/deps/v8/test/mjsunit/readonly.js index ec938d65c0cc32..69a3e6a01648dc 100644 --- a/deps/v8/test/mjsunit/readonly.js +++ b/deps/v8/test/mjsunit/readonly.js @@ -26,6 +26,8 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax +// This test manually triggers optimization, no need for stress modes. +// Flags: --nostress-opt --noalways-opt // Different ways to create an object. diff --git a/deps/v8/test/mjsunit/regexp-tier-up-multiple.js b/deps/v8/test/mjsunit/regexp-tier-up-multiple.js new file mode 100644 index 00000000000000..7325b341d0a1ca --- /dev/null +++ b/deps/v8/test/mjsunit/regexp-tier-up-multiple.js @@ -0,0 +1,101 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Tier-up behavior differs between slow and fast paths in +// RegExp.prototype.replace with a function as an argument. +// Flags: --regexp-tier-up --regexp-tier-up-ticks=5 +// Flags: --allow-natives-syntax --no-force-slow-path --no-regexp-interpret-all + +const kLatin1 = true; +const kUnicode = false; + +function CheckRegexpNotYetCompiled(regexp) { + assertFalse(%RegexpHasBytecode(regexp, kLatin1) && + %RegexpHasNativeCode(regexp, kLatin1)); + assertFalse(%RegexpHasBytecode(regexp, kUnicode) && + %RegexpHasNativeCode(regexp, kUnicode)); +} + +// Testing RegExp.test method which calls into Runtime_RegExpExec. +let re = new RegExp('^.$'); +CheckRegexpNotYetCompiled(re); + +// Testing first five executions of regexp with one-byte string subject. +for (var i = 0; i < 5; i++) { + re.test("a"); + assertTrue(%RegexpHasBytecode(re, kLatin1)); + assertTrue(!%RegexpHasBytecode(re, kUnicode) && + !%RegexpHasNativeCode(re, kUnicode)); +} +// Testing the tier-up to native code. +re.test("a"); +assertTrue(!%RegexpHasBytecode(re, kLatin1) && + %RegexpHasNativeCode(re,kLatin1)); +assertTrue(!%RegexpHasBytecode(re, kUnicode) && + !%RegexpHasNativeCode(re,kUnicode)); +re.test("a"); +assertTrue(!%RegexpHasBytecode(re, kLatin1) && + %RegexpHasNativeCode(re,kLatin1)); +assertTrue(!%RegexpHasBytecode(re, kUnicode) && + !%RegexpHasNativeCode(re,kUnicode)); +// Testing that the regexp will compile to native code for two-byte string +// subject as well, because we have a single tick counter for both string +// representations. +re.test("π"); +assertTrue(!%RegexpHasBytecode(re, kLatin1) && + %RegexpHasNativeCode(re,kLatin1)); +assertTrue(!%RegexpHasBytecode(re, kUnicode) && + %RegexpHasNativeCode(re,kUnicode)); + +// Testing String.replace method for non-global regexps. +var subject = "a1111"; +re = /\w1/; +CheckRegexpNotYetCompiled(re); + +for (var i = 0; i < 5; i++) { + subject.replace(re, "x"); + assertTrue(%RegexpHasBytecode(re, kLatin1)); + assertTrue(!%RegexpHasBytecode(re, kUnicode) && + !%RegexpHasNativeCode(re, kUnicode)); +} + +subject.replace(re, "x"); +assertTrue(!%RegexpHasBytecode(re, kLatin1) && + %RegexpHasNativeCode(re, kLatin1)); +assertTrue(!%RegexpHasBytecode(re, kUnicode) && + !%RegexpHasNativeCode(re, kUnicode)); + +// Testing String.replace method for global regexps. +let re_g = /\w11111/g; +CheckRegexpNotYetCompiled(re_g); +// This regexp will not match, so it will only execute the bytecode once, +// each time the replace method is invoked, without tiering-up and +// recompiling to native code. +for (var i = 0; i < 5; i++) { + subject.replace(re_g, "x"); + assertTrue(%RegexpHasBytecode(re_g, kLatin1)); + assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && + !%RegexpHasNativeCode(re_g, kUnicode)); +} + +// This regexp will match, so it will execute five times, and tier-up. +re_g = /\w/g; +CheckRegexpNotYetCompiled(re_g); +subject.replace(re_g, "x"); +assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && + %RegexpHasNativeCode(re_g, kLatin1)); +assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && + !%RegexpHasNativeCode(re_g, kUnicode)); + +// Testing String.replace method for global regexps with a function as a +// parameter. This will tier-up eagerly and compile to native code right +// away, even though the regexp is only executed once. +function f() { return "x"; } +re_g = /\w2/g; +CheckRegexpNotYetCompiled(re_g); +subject.replace(re_g, f); +assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && + %RegexpHasNativeCode(re_g, kLatin1)); +assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && + !%RegexpHasNativeCode(re_g, kUnicode)); diff --git a/deps/v8/test/mjsunit/regexp-tier-up.js b/deps/v8/test/mjsunit/regexp-tier-up.js index e55e87f5938a47..6269128f53fb0e 100644 --- a/deps/v8/test/mjsunit/regexp-tier-up.js +++ b/deps/v8/test/mjsunit/regexp-tier-up.js @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Tier-up behavior differs between slow and fast paths in functional -// RegExp.prototype.replace. -// Flags: --regexp-tier-up --allow-natives-syntax --no-force-slow-path +// Tier-up behavior differs between slow and fast paths in +// RegExp.prototype.replace with a function as an argument. +// Flags: --regexp-tier-up --regexp-tier-up-ticks=1 +// Flags: --allow-natives-syntax --no-force-slow-path --no-regexp-interpret-all const kLatin1 = true; const kUnicode = false; @@ -90,3 +91,15 @@ assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && %RegexpHasNativeCode(re_g, kLatin1)); assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && !%RegexpHasNativeCode(re_g, kUnicode)); + +// Testing eager tier-up for very long strings. +let dna = "ATCG".repeat(251); + +re_g = />.*\n|\n/; +CheckRegexpNotYetCompiled(re_g); + +dna = dna.replace(re_g,""); +assertTrue(!%RegexpHasBytecode(re_g, kLatin1) && + %RegexpHasNativeCode(re_g, kLatin1)); +assertTrue(!%RegexpHasBytecode(re_g, kUnicode) && + !%RegexpHasNativeCode(re_g, kUnicode)); diff --git a/deps/v8/test/mjsunit/regress/regress-1002827.js b/deps/v8/test/mjsunit/regress/regress-1002827.js new file mode 100644 index 00000000000000..2acaf73debfa5b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1002827.js @@ -0,0 +1,13 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-gc + +var PI = new Proxy(this, { + get() { + PI(); + } +}); + +assertThrows(() => new gc(PI, {}), TypeError); diff --git a/deps/v8/test/mjsunit/regress/regress-1003730.js b/deps/v8/test/mjsunit/regress/regress-1003730.js new file mode 100644 index 00000000000000..e20a4e4a44cf0a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1003730.js @@ -0,0 +1,25 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --allow-natives-syntax --concurrent-inlining + +function bar(error) { + try { + throw "didn't throw TypeError"; + } catch (err) { + error instanceof error, "didn't throw " + error.prototype.name; + } +} +function foo(param) { + bar(TypeError); +} +try { + bar(); +} catch (e) {} +%PrepareFunctionForOptimization(foo); +try { + foo(); +} catch (e) {} +%OptimizeFunctionOnNextCall(foo); +foo(); diff --git a/deps/v8/test/mjsunit/regress/regress-1003919.js b/deps/v8/test/mjsunit/regress/regress-1003919.js new file mode 100644 index 00000000000000..def45eeca46613 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1003919.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Define an object with a getter and a proxy as it's prototype. +var obj = {foo: 'bar'}; +Object.defineProperty(obj, 'foo', { + get: function () { + } +}); +obj.__proto__ = new Proxy([], {}); + +// Get key from a function to avoid the property access turning into a +// named property access. +function getKey() { + return 'values' +} + +// Keyed access to update obj's values property. +obj[getKey()] = 1; diff --git a/deps/v8/test/mjsunit/regress/regress-1004912.js b/deps/v8/test/mjsunit/regress/regress-1004912.js new file mode 100644 index 00000000000000..baa31db1384e90 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1004912.js @@ -0,0 +1,12 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var key = { + toString() { + return Symbol(); + } +}; + +var obj = {}; +obj[key]; diff --git a/deps/v8/test/mjsunit/regress/regress-1005400.js b/deps/v8/test/mjsunit/regress/regress-1005400.js new file mode 100644 index 00000000000000..77234235fed0e6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1005400.js @@ -0,0 +1,23 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function foo(a, key) { + a[key]; +} + +let obj = {}; +let count = 0; + +var key_obj = { + toString: function() { + count++; + // Force string to be internalized during keyed lookup. + return 'foo' + count; + } +}; + +foo(obj, key_obj); + +// We should only call toString once. +assertEquals(count, 1); diff --git a/deps/v8/test/mjsunit/regress/regress-1006629.js b/deps/v8/test/mjsunit/regress/regress-1006629.js new file mode 100644 index 00000000000000..bd307fa2288065 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1006629.js @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +const workerScript = ` + onmessage = function() { + };`; +const worker = new Worker(workerScript, {type: 'string'}); +const i32a = new Int32Array( new SharedArrayBuffer() ); +worker.postMessage([i32a.buffer]); diff --git a/deps/v8/test/mjsunit/regress/regress-1006640.js b/deps/v8/test/mjsunit/regress/regress-1006640.js new file mode 100644 index 00000000000000..597b42057d8d7b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1006640.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-gc + +function main() { + const v2 = [1337,1337,1337,1337,1337]; + function v9() { + const v15 = {get:RegExp}; + Object.defineProperty(v2,501,v15); + const v18 = RegExp(); + const v19 = 1337 instanceof v18; + } + const v30 = {defineProperty:Function,get:v9,getPrototypeOf:Object}; + const v32 = new Proxy(ArrayBuffer,v30); + const v34 = gc(v32); +} + +assertThrows(() => main(), TypeError); diff --git a/deps/v8/test/mjsunit/regress/regress-1006670.js b/deps/v8/test/mjsunit/regress/regress-1006670.js new file mode 100644 index 00000000000000..4d1408b3d18190 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1006670.js @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assertThrows(() => /(a?;?){4000000}/.exec("a"), RangeError); diff --git a/deps/v8/test/mjsunit/regress/regress-1011980.js b/deps/v8/test/mjsunit/regress/regress-1011980.js new file mode 100644 index 00000000000000..89e4fed159c2a7 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1011980.js @@ -0,0 +1,22 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --allow-natives-syntax + +let hex_b = 0x0b; +let hex_d = 0x0d; +let hex_20 = 0x20; +let hex_52 = 0x52; +let hex_fe = 0xfe; + +function f(a) { + let unused = [ a / 8, ...[ ...[ ...[], a / 8, ...[ 7, hex_fe, a, 0, 0, hex_20, + 6, hex_52, hex_d, 0, hex_b], 0, hex_b], hex_b]]; +} + +%PrepareFunctionForOptimization(f) +f(64) +f(64); +%OptimizeFunctionOnNextCall(f); +f(64); diff --git a/deps/v8/test/mjsunit/regress/regress-1016703.js b/deps/v8/test/mjsunit/regress/regress-1016703.js new file mode 100644 index 00000000000000..6830d194fda23a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-1016703.js @@ -0,0 +1,15 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-gc + +let realms = []; +for (let i = 0; i < 4; i++) { + realms.push(Realm.createAllowCrossRealmAccess()); +} + +for (let i = 0; i < 4; i++) { + Realm.detachGlobal(realms[i]); + gc(); +} diff --git a/deps/v8/test/mjsunit/regress/regress-752764.js b/deps/v8/test/mjsunit/regress/regress-752764.js index 30ab7b2a6ded44..106d9edd876558 100644 --- a/deps/v8/test/mjsunit/regress/regress-752764.js +++ b/deps/v8/test/mjsunit/regress/regress-752764.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --nostress-incremental-marking +// Stress-testing this test is very slow and provides no useful coverage. +// Flags: --nostress-opt --noalways-opt // This test uses a lot of memory and fails with flaky OOM when run // with --stress-incremental-marking on TSAN. diff --git a/deps/v8/test/mjsunit/regress/regress-779407.js b/deps/v8/test/mjsunit/regress/regress-779407.js index 140f7bdd7471bc..71e57df9a78860 100644 --- a/deps/v8/test/mjsunit/regress/regress-779407.js +++ b/deps/v8/test/mjsunit/regress/regress-779407.js @@ -10,4 +10,4 @@ for (var i = 0; i < 17; i++) { } catch (e) { } } -s.replace(/[a]/g); +s.replace(/a/g); diff --git a/deps/v8/test/mjsunit/regress/regress-9165.js b/deps/v8/test/mjsunit/regress/regress-9165.js index 1de6e9db2a43b5..1709b488fd2da4 100644 --- a/deps/v8/test/mjsunit/regress/regress-9165.js +++ b/deps/v8/test/mjsunit/regress/regress-9165.js @@ -14,12 +14,12 @@ let kSig_r_i = makeSig([kWasmI32], [kWasmAnyRef]); builder.addFunction("merge", kSig_r_i) .addLocals({anyref_count: 1, anyfunc_count: 1}) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmAnyRef, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprElse, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprEnd, ]).exportFunc(); let instance = builder.instantiate(); @@ -33,12 +33,12 @@ let kSig_r_i = makeSig([kWasmI32], [kWasmAnyRef]); builder.addFunction("merge", kSig_r_i) .addLocals({anyfunc_count: 1}) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmAnyRef, kExprRefNull, kExprElse, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprEnd, ]).exportFunc(); let instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/regress-9832.js b/deps/v8/test/mjsunit/regress/regress-9832.js new file mode 100644 index 00000000000000..41a8c38f0d7731 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-9832.js @@ -0,0 +1,35 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --experimental-wasm-eh + +load("test/mjsunit/wasm/wasm-module-builder.js"); + +(function TestRegress9832() { + let builder = new WasmModuleBuilder(); + let f = builder.addFunction("f", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprLocalGet, 0, + kExprI32Add, + ]).exportFunc(); + builder.addFunction("main", kSig_i_i) + .addLocals({except_count: 1}) + .addBody([ + kExprTry, kWasmStmt, + kExprLocalGet, 0, + kExprCallFunction, f.index, + kExprCallFunction, f.index, + kExprLocalSet, 0, + kExprCatch, + kExprDrop, + kExprLocalGet, 0, + kExprCallFunction, f.index, + kExprLocalSet, 0, + kExprEnd, + kExprLocalGet, 0, + ]).exportFunc(); + let instance = builder.instantiate(); + assertEquals(92, instance.exports.main(23)); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-9894.js b/deps/v8/test/mjsunit/regress/regress-9894.js new file mode 100644 index 00000000000000..0a7bf5d4566b26 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-9894.js @@ -0,0 +1,48 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function frozen() { + const ary = [1.1] + Object.defineProperty(ary, 0, {get:run_it} ); + + // v8::internal::Runtime_ArrayIncludes_Slow. + ary.includes(); + + function run_it(el) { + ary.length = 0; + ary[0] = 1.1; + Object.freeze(ary); + return 2.2; + } +})(); + +(function seal() { + const ary = [1.1] + Object.defineProperty(ary, 0, {get:run_it} ); + + // v8::internal::Runtime_ArrayIncludes_Slow. + ary.includes(); + + function run_it(el) { + ary.length = 0; + ary[0] = 1.1; + Object.seal(ary); + return 2.2; + } +})(); + +(function preventExtensions() { + const ary = [1.1] + Object.defineProperty(ary, 0, {get:run_it} ); + + // v8::internal::Runtime_ArrayIncludes_Slow. + ary.includes(); + + function run_it(el) { + ary.length = 0; + ary[0] = 1.1; + Object.preventExtensions(ary); + return 2.2; + } +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-996161.js b/deps/v8/test/mjsunit/regress/regress-996161.js new file mode 100644 index 00000000000000..dada3f47bd2656 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-996161.js @@ -0,0 +1,43 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function checkOwnProperties(v, count) { + var properties = Object.getOwnPropertyNames(v); + assertEquals(properties.length, count); +} + + +function testStoreNoFeedback() { + arr = new Int32Array(10); + function f(a) { a["-1"] = 15; } + + for (var i = 0; i < 3; i++) { + arr.__defineGetter__("x", function() { }); + checkOwnProperties(arr, 11); + f(arr); + } +} +testStoreNoFeedback(); + +function testStoreGeneric() { + arr = new Int32Array(10); + var index = "-1"; + function f1(a) { a[index] = 15; } + %EnsureFeedbackVectorForFunction(f1); + + // Make a[index] in f1 megamorphic + f1({a: 1}); + f1({b: 1}); + f1({c: 1}); + f1({d: 1}); + + for (var i = 0; i < 3; i++) { + arr.__defineGetter__("x", function() { }); + checkOwnProperties(arr, 11); + f1(arr); + } +} +testStoreGeneric(); diff --git a/deps/v8/test/mjsunit/regress/regress-997485.js b/deps/v8/test/mjsunit/regress/regress-997485.js new file mode 100644 index 00000000000000..bcc1664222d39a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-997485.js @@ -0,0 +1,127 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +(function doubleToTaggedWithTaggedValueStoresCorrectly() { + + function setX_Double(o) { o.x = 4.2; } + + function foo() { + // o.x starts off as Double + const o = { x: 0.1 }; + + // Write to it a few times with setX_Double, to make sure setX_Double has + // Double feedback. + setX_Double(o); + setX_Double(o); + + // Transition o.x to Tagged. + o.x = {}; + + // setX_Double will still have Double feedback, so make sure it works with + // the new Tagged representation o.x. + setX_Double(o); + + assertEquals(o.x, 4.2); + } + + %EnsureFeedbackVectorForFunction(setX_Double); + foo(); + +})(); + +(function doubleToTaggedWithDoubleValueDoesNotMutate() { + + function setX_Double(o) { o.x = 4.2; } + + function foo() { + // o.x starts off as Double + const o = { x: 0.1 }; + + // Write to it a few times with setX_Double, to make sure setX_Double has + // Double feedback. + setX_Double(o); + setX_Double(o); + + // Transition o.x to Tagged. + o.x = {}; + + // Write the HeapNumber val to o.x. + const val = 1.25; + o.x = val; + + // setX_Double will still have Double feedback, which expects to be able to + // mutate o.x's HeapNumber, so make sure it does not mutate val. + setX_Double(o); + + assertEquals(o.x, 4.2); + assertNotEquals(val, 4.2); + } + + %EnsureFeedbackVectorForFunction(setX_Double); + foo(); + +})(); + +(function doubleToTaggedWithTaggedValueStoresSmiCorrectly() { + + function setX_Smi(o) { o.x = 42; } + + function foo() { + // o.x starts off as Double + const o = { x: 0.1 }; + + // Write to it a few times with setX_Smi, to make sure setX_Smi has + // Double feedback. + setX_Smi(o); + setX_Smi(o); + + // Transition o.x to Tagged. + o.x = {}; + + // setX_Smi will still have Double feedback, so make sure it works with + // the new Tagged representation o.x. + setX_Smi(o); + + assertEquals(o.x, 42); + } + + %EnsureFeedbackVectorForFunction(setX_Smi); + foo(); + +})(); + +(function doubleToTaggedWithSmiValueDoesNotMutate() { + + function setX_Smi(o) { o.x = 42; } + + function foo() { + // o.x starts off as Double + const o = { x: 0.1 }; + + // Write to it a few times with setX_Smi, to make sure setX_Smi has + // Double feedback. + setX_Smi(o); + setX_Smi(o); + + // Transition o.x to Tagged. + o.x = {}; + + // Write the HeapNumber val to o.x. + const val = 1.25; + o.x = val; + + // setX_Smi will still have Double feedback, which expects to be able to + // mutate o.x's HeapNumber, so make sure it does not mutate val. + setX_Smi(o); + + assertEquals(o.x, 42); + assertNotEquals(val, 42); + } + + %EnsureFeedbackVectorForFunction(setX_Smi); + foo(); + +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-997989.js b/deps/v8/test/mjsunit/regress/regress-997989.js new file mode 100644 index 00000000000000..f049a317248b56 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-997989.js @@ -0,0 +1,27 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --allow-natives-syntax + +// A function with a for-in loop, that will be optimized. +function foo(o) { + for (var i in o) { + return o[i]; + } +} + +var o = { x: 0.5 }; + +// Warm up foo with Double values in the enum cache. +%PrepareFunctionForOptimization(foo); +assertEquals(foo(o), 0.5); +assertEquals(foo(o), 0.5); +%OptimizeFunctionOnNextCall(foo); +assertEquals(foo(o), 0.5); + +// Transition the double field to a tagged field +o.x = "abc"; + +// Make sure that the optimized code correctly loads the tagged field. +assertEquals(foo(o), "abc"); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1002628.js b/deps/v8/test/mjsunit/regress/regress-crbug-1002628.js new file mode 100644 index 00000000000000..8be7e8687de8cb --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1002628.js @@ -0,0 +1,22 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --always-opt + +"use strict"; +var __v_0 = {}; +try { + __v_0 = this; + Object.freeze(__v_0); +} +catch (e) { +} + +function f() { + x = { [Symbol.toPrimitive]: () => FAIL }; +} +try { + f() +} catch (e) { } +assertThrows(() => f(), ReferenceError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1003403.js b/deps/v8/test/mjsunit/regress/regress-crbug-1003403.js new file mode 100644 index 00000000000000..877b9c8c73344c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1003403.js @@ -0,0 +1,10 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --enable-lazy-source-positions --stress-lazy-source-positions +// Flags: --no-lazy +({ x: b = 0 }) => { + try { b; } catch (e) {} + function a() { b } +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1003732.js b/deps/v8/test/mjsunit/regress/regress-crbug-1003732.js new file mode 100644 index 00000000000000..5e2bbe773241c2 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1003732.js @@ -0,0 +1,25 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function f_1() { + var v = new Array(); + v[0] = 10; + return v; +} + +function test() { + var setter_called = false; + // Turn array to NumberDictionary + Array.prototype[123456789] = 42; + assertEquals(f_1().length, 1); + + // Reset to empty_slow_dictionary + Array.prototype.length = 0; + + // This should reset the prototype validity cell. + Array.prototype.__defineSetter__("0", function() {setter_called = true}); + f_1(); + assertEquals(setter_called, true); +} +test(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1004037.js b/deps/v8/test/mjsunit/regress/regress-crbug-1004037.js new file mode 100644 index 00000000000000..cf7ba70458ef22 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1004037.js @@ -0,0 +1,23 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --always-opt + +__v_1 = {}; +__v_1.__defineGetter__('x', function () { }); +__proto__ = __v_1; +function __f_4() { + __v_1 = {}; +} +function __f_3() { + 'use strict'; + x = 42; +} +__f_4() +try { + __f_3(); +} catch (e) { } + +__proto__ = __v_1; +assertThrows(() => __f_3(), ReferenceError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1004061.js b/deps/v8/test/mjsunit/regress/regress-crbug-1004061.js new file mode 100644 index 00000000000000..8b36d4d609b57c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1004061.js @@ -0,0 +1,55 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +(function testPackedDoublesIncludes() { + arr = [1.5, 2.5]; + arr.length = 0; + function f() { + return arr.includes(1); + }; + %PrepareFunctionForOptimization(f); + assertEquals(f(), false); + %OptimizeFunctionOnNextCall(f); + assertEquals(f(), false); +})(); + +(function testHoleyDoublesIncludes() { + arr = [1.1]; + arr[3]= 1.5; + arr.length = 0; + function f() { + return arr.includes(1); + }; + %PrepareFunctionForOptimization(f); + assertEquals(f(), false); + %OptimizeFunctionOnNextCall(f); + assertEquals(f(), false); +})(); + +(function testPackedDoublesIndexOf() { + arr = [1.5, 2.5]; + arr.length = 0; + function f() { + return arr.indexOf(1); + }; + %PrepareFunctionForOptimization(f); + assertEquals(f(), -1); + %OptimizeFunctionOnNextCall(f); + assertEquals(f(), -1); +})(); + +(function testHoleyDoublesIndexOf() { + arr = [1.1]; + arr[3]= 1.5; + arr.length = 0; + function f() { + return arr.indexOf(1); + }; + %PrepareFunctionForOptimization(f); + assertEquals(f(), -1); + %OptimizeFunctionOnNextCall(f); + assertEquals(f(), -1); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1006592.js b/deps/v8/test/mjsunit/regress/regress-crbug-1006592.js new file mode 100644 index 00000000000000..c051d0861af19f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1006592.js @@ -0,0 +1,21 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function Module(stdlib) { + "use asm"; + var fround = stdlib.Math.fround; + function f(a, b) { + a = +a; + b = +b; + return fround(a, b); + } + return { f: f }; +} + +var m = Module(this); +assertEquals(23, m.f(23)); +assertEquals(42, m.f(42, 65)); +assertFalse(%IsAsmWasmCode(Module)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1008632.js b/deps/v8/test/mjsunit/regress/regress-crbug-1008632.js new file mode 100644 index 00000000000000..8b46baefa13ce5 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1008632.js @@ -0,0 +1,24 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --no-lazy-feedback-allocation + +var __v_9690 = function () {}; +try { + (function () { + __f_1653(); + })() +} catch (__v_9763) { +} +function __f_1653(__v_9774, __v_9775) { + try { + } catch (e) {} + __v_9774[__v_9775 + 4] = 2; +} +(function () { + %PrepareFunctionForOptimization(__f_1653); + __f_1653(__v_9690, true); + %OptimizeFunctionOnNextCall(__f_1653); + assertThrows(() => __f_1653(), TypeError); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1012301-1.js b/deps/v8/test/mjsunit/regress/regress-crbug-1012301-1.js new file mode 100644 index 00000000000000..9c2f87c4fed2aa --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1012301-1.js @@ -0,0 +1,27 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function get() { + // Update the descriptor array now shared between the Foo map and the + // (Foo + c) map. + o1.c = 10; + // Change the type of the field on the new descriptor array in-place to + // Tagged. If Object.assign has a cached descriptor array, then it will point + // to the old Foo map's descriptors, which still have .b as Double. + o2.b = "string"; + return 1; +} + +function Foo() { + Object.defineProperty(this, "a", {get, enumerable: true}); + // Initialise Foo.b to have Double representation. + this.b = 1.5; +} + +var o1 = new Foo(); +var o2 = new Foo(); +var target = {}; +Object.assign(target, o2); +// Make sure that target has the right representation after assignment. +assertEquals(target.b, "string"); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1012301.js b/deps/v8/test/mjsunit/regress/regress-crbug-1012301.js new file mode 100644 index 00000000000000..dc2ef92a6f166c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1012301.js @@ -0,0 +1,23 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --allow-natives-syntax + +function f(o) { + // The spread after the CloneObject IC shouldn't crash when trying to write a + // double value to a field created by CloneObject. + return {...o, ...{a:1.4}}; +} + +%EnsureFeedbackVectorForFunction(f); + +var o = {}; +// Train the CloneObject IC with a Double field. +o.a = 1.5; +f(o); +f(o); +f(o); +// Change the source map to have a Tagged field. +o.a = undefined; +f(o); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1015567.js b/deps/v8/test/mjsunit/regress/regress-crbug-1015567.js new file mode 100644 index 00000000000000..520d6c539bcc52 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1015567.js @@ -0,0 +1,5 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +assertThrows('a ( { b() {} } [ [ 1 , c.d = 1 ] = 1.1 ] )', SyntaxError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1015945.js b/deps/v8/test/mjsunit/regress/regress-crbug-1015945.js new file mode 100644 index 00000000000000..a43736e7b5bd50 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1015945.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-async-hooks + +async function* foo() { + await 1; + throw new Error(); +} + +(async () => { + for await (const x of foo()) { } +})(); + +async_hooks.createHook({ + promiseResolve() { + throw new Error(); + } +}).enable() diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-729597.js b/deps/v8/test/mjsunit/regress/regress-crbug-729597.js index b4c54e8e885a5e..7656bc048ad653 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-729597.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-729597.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --verify-heap +// Flags: --verify-heap --expose-gc function __f_3(f) { arguments.__defineGetter__('length', f); @@ -13,6 +13,7 @@ function __f_4() { return "boom"; } __v_4 = []; __v_13 = ""; -for (var i = 0; i < 12800; ++i) { +for (var i = 0; i < 128; ++i) { __v_13 += __v_4.__proto__ = __f_3(__f_4); } +gc(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-808192.js b/deps/v8/test/mjsunit/regress/regress-crbug-808192.js index f57d5fc3a696f7..af92ce7f351e6c 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-808192.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-808192.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --expose-gc +// Stress-testing this test is very slow and doesn't provide useful coverage. +// Flags: --nostress-opt --noalways-opt const f = eval(`(function f(i) { if (i == 0) { diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-941743.js b/deps/v8/test/mjsunit/regress/regress-crbug-941743.js index eaac4c4c4d846a..81416b8725c00a 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-941743.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-941743.js @@ -3,6 +3,8 @@ // found in the LICENSE file. // Flags: --allow-natives-syntax --noenable-slow-asserts +// This test triggers optimization manually, no stress mode necessary. +// Flags: --nostress-opt --noalways-opt // This call ensures that TurboFan won't inline array constructors. Array(2 ** 30); diff --git a/deps/v8/test/mjsunit/regress/regress-v8-9758.js b/deps/v8/test/mjsunit/regress/regress-v8-9758.js new file mode 100644 index 00000000000000..7f9eab3339491c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-v8-9758.js @@ -0,0 +1,9 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --throws + +// Can't put this in a try-catch as that changes the parsing so the crash +// doesn't reproduce. +((a = ((b = a) => {})()) => 1)(); diff --git a/deps/v8/test/mjsunit/regress/regress-v8-9825.mjs b/deps/v8/test/mjsunit/regress/regress-v8-9825.mjs new file mode 100644 index 00000000000000..f8d0708848e57b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-v8-9825.mjs @@ -0,0 +1,11 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +async function foo() { + for (;;await[]) { + break; + } +} + +foo(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-02256.js b/deps/v8/test/mjsunit/regress/wasm/regress-02256.js index 199626b3c32ff7..63da0cc10b6170 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-02256.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-02256.js @@ -273,19 +273,19 @@ try { function __f_16() { var __v_1 = new WasmModuleBuilder(); __v_1.addFunction("grow_memory", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow]) .exportFunc(); __v_1.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); __v_1.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, kExprLocalGet, 1]) .exportFunc(); __v_1.addFunction("load16", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem16U, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem16U, 0, 0]) .exportFunc(); __v_1.addFunction("store16", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem16, 0, 0, kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem16, 0, 0, kExprLocalGet, 1]) .exportFunc(); __v_1.__p_1551105852 = __v_1[getRandomProperty(__v_1, 1551105852)]; __v_1.__defineGetter__(getRandomProperty(__v_1, 348910887), function() { @@ -294,10 +294,10 @@ function __f_16() { return __v_1.__p_1551105852; }); __v_1.addFunction("load8", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem8U, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem8U, 0, 0]) .exportFunc(); __v_1.addFunction("store8", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem8, 0, 0, kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem8, 0, 0, kExprLocalGet, 1]) .exportFunc(); return __v_1; } diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-1010272.js b/deps/v8/test/mjsunit/regress/wasm/regress-1010272.js new file mode 100644 index 00000000000000..ff685eda79c8d4 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-1010272.js @@ -0,0 +1,30 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --wasm-grow-shared-memory --experimental-wasm-threads + +const kNumWorkers = 100; +const kNumMessages = 50; + +function AllocMemory(initial, maximum = initial) { + return new WebAssembly.Memory({initial : initial, maximum : maximum, shared : true}); +} + +(function RunTest() { + let worker = []; + for (let w = 0; w < kNumWorkers; w++) { + worker[w] = new Worker( + `onmessage = + function(msg) { + msg.memory.grow(1); + }`, {type : 'string'}); + } + + for (let i = 0; i < kNumMessages; i++) { + let memory = AllocMemory(1, 128); + for (let w = 0; w < kNumWorkers; w++) { + worker[w].postMessage({memory : memory}); + } + } +})(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-1014798.js b/deps/v8/test/mjsunit/regress/wasm/regress-1014798.js new file mode 100644 index 00000000000000..98f0314b99daf3 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-1014798.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +load('test/mjsunit/wasm/wasm-module-builder.js'); + +const builder = new WasmModuleBuilder(); +builder.addFunction('main', kSig_i_iii) + .addLocals({f32_count: 4}) + .addLocals({i64_count: 1}) + .addLocals({f32_count: 2}) + .addBodyWithEnd([ + kExprI64Const, 0, + kExprLocalGet, 3, + kExprI64SConvertF32, + kExprI64Ne, + kExprEnd, // @17 + ]).exportFunc(); +const instance = builder.instantiate(); +assertEquals(0, instance.exports.main(1, 2, 3)); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-1016515.js b/deps/v8/test/mjsunit/regress/wasm/regress-1016515.js new file mode 100644 index 00000000000000..f56579912db605 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-1016515.js @@ -0,0 +1,20 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --wasm-lazy-compilation + +load('test/mjsunit/wasm/wasm-module-builder.js'); + +var builder = new WasmModuleBuilder(); +var func = builder.addFunction('func', kSig_i_v).addBody([kExprI32Const, 1]); +var body = []; +for (let i = 0; i < 200; ++i) { + body.push(kExprCallFunction, func.index); +} +for (let i = 1; i < 200; ++i) { + body.push(kExprI32Add); +} +builder.addFunction('test', kSig_i_v).addBody(body).exportFunc(); +var instance = builder.instantiate(); +instance.exports.test(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-648079.js b/deps/v8/test/mjsunit/regress/wasm/regress-648079.js index fbb54144803a47..cf4bf1c6981671 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-648079.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-648079.js @@ -8,7 +8,6 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); // Non-standard opcodes. let kSig_s_v = makeSig([], [kWasmS128]); -let kExprS128LoadMem = 0xc0; (function() { "use asm"; @@ -109,7 +108,7 @@ builder.addFunction("regression_648079", kSig_s_v) kExprF32Min, kExprI64GtU, kExprBlock, 01, // @107 i32 - kExprTeeLocal, + kExprLocalTee, kExprBlock, 01, // @111 i32 kExprBlock, 01, // @113 i32 kExprBlock, 01, // @115 i32 @@ -169,7 +168,7 @@ builder.addFunction("regression_648079", kSig_s_v) kExprF64Sub, kExprI32Const, kExprUnreachable, - kExprGetLocal, + kExprLocalGet, kExprI64LoadMem32U, kExprUnreachable, kExprI64RemU, @@ -273,7 +272,7 @@ builder.addFunction("regression_648079", kSig_s_v) kExprF64Sub, kExprI32Const, kExprUnreachable, - kExprGetLocal, + kExprLocalGet, kExprI64LoadMem32U, kExprUnreachable, kExprUnreachable, @@ -300,7 +299,7 @@ builder.addFunction("regression_648079", kSig_s_v) kExprF64Sub, kExprI32Const, kExprUnreachable, - kExprGetLocal, + kExprLocalGet, kExprI64LoadMem32U, kExprF64Min, kExprF64Min, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-689450.js b/deps/v8/test/mjsunit/regress/wasm/regress-689450.js index bcd25387b43166..a629766bce8f37 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-689450.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-689450.js @@ -9,7 +9,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder.addMemory(16, 32, false); builder.addFunction('test', kSig_i_i) .addBodyWithEnd([ - kExprGetLocal, 0x00, + kExprLocalGet, 0x00, kExprI32Const, 0x29, kExprI32Shl, kExprI32Const, 0x18, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-702460.js b/deps/v8/test/mjsunit/regress/wasm/regress-702460.js index 21a84bcf28583e..3f1e11e3938a83 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-702460.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-702460.js @@ -4,10 +4,6 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); -// Non-standard opcodes. -let kSig_s_v = makeSig([], [kWasmS128]); -let kExprS128LoadMem = 0xc0; - (function() { "use asm"; var builder = new WasmModuleBuilder(); @@ -20,7 +16,7 @@ let kExprS128LoadMem = 0xc0; kExprMemoryGrow, 0x00, kExprMemoryGrow, 0x00, kExprMemoryGrow, 0x00, - kExprSetLocal, 0x00, + kExprLocalSet, 0x00, kExprMemoryGrow, 0x00, kExprMemoryGrow, 0x00, kExprMemoryGrow, 0x00, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7049.js b/deps/v8/test/mjsunit/regress/wasm/regress-7049.js index 6d2cd351fb92f5..46dce4a8716509 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7049.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7049.js @@ -20,7 +20,7 @@ let func1_sig = makeSig(new Array(8).fill(kWasmI32), [kWasmI32]); let imp = builder1.addImport('q', 'gc', kSig_v_v); let func1 = builder1.addFunction('func1', func1_sig) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallFunction, imp ]) .exportFunc(); @@ -31,14 +31,14 @@ let builder2 = new WasmModuleBuilder(); let func1_imp = builder2.addImport('q', 'func1', func1_sig); let func2 = builder2.addFunction('func2', kSig_i_i) .addBody([ - kExprGetLocal, 0, // 1 - kExprGetLocal, 0, // 2 - kExprGetLocal, 0, // 3 - kExprGetLocal, 0, // 4 - kExprGetLocal, 0, // 5 - kExprGetLocal, 0, // 6 - kExprGetLocal, 0, // 7 - kExprGetLocal, 0, // 8 + kExprLocalGet, 0, // 1 + kExprLocalGet, 0, // 2 + kExprLocalGet, 0, // 3 + kExprLocalGet, 0, // 4 + kExprLocalGet, 0, // 5 + kExprLocalGet, 0, // 6 + kExprLocalGet, 0, // 7 + kExprLocalGet, 0, // 8 kExprCallFunction, func1_imp ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7353.js b/deps/v8/test/mjsunit/regress/wasm/regress-7353.js index 81f45fe6a5de30..671da730fbeeab 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7353.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7353.js @@ -9,17 +9,17 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const builder = new WasmModuleBuilder(); builder.addMemory(16, 32); builder.addFunction('grow', kSig_i_i).addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprMemoryGrow, 0, ]).exportFunc(); builder.addFunction('main', kSig_i_i).addBody([ ...wasmI32Const(0x41), - kExprSetLocal, 0, + kExprLocalSet, 0, // Enter loop, such that values are spilled to the stack. kExprLoop, kWasmStmt, kExprEnd, // Reload value. This must be loaded as 32 bit value. - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 0, ]).exportFunc(); const instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7366.js b/deps/v8/test/mjsunit/regress/wasm/regress-7366.js index b5cae8daa42850..b5e4e2e2b6eabb 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7366.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7366.js @@ -7,22 +7,22 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_i_iii).addBody([ // Return the sum of all arguments. - kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kExprI32Add, kExprI32Add + kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kExprI32Add, kExprI32Add ]); const sig = builder.addType(kSig_i_iii); builder.addFunction(undefined, kSig_i_iii) .addBody([ ...wasmI32Const(1), // i32.const 0x1 - kExprSetLocal, 0, // set_local 0 + kExprLocalSet, 0, // set_local 0 ...wasmI32Const(4), // i32.const 0x1 - kExprSetLocal, 1, // set_local 1 + kExprLocalSet, 1, // set_local 1 ...wasmI32Const(16), // i32.const 0x1 - kExprSetLocal, 2, // set_local 2 + kExprLocalSet, 2, // set_local 2 kExprLoop, kWasmStmt, // loop kExprEnd, // end - kExprGetLocal, 0, // get_local 0 - kExprGetLocal, 1, // get_local 1 - kExprGetLocal, 2, // get_local 2 + kExprLocalGet, 0, // get_local 0 + kExprLocalGet, 1, // get_local 1 + kExprLocalGet, 2, // get_local 2 kExprI32Const, 0, // i32.const 0 (func index) kExprCallIndirect, sig, 0, // call indirect ]) diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-739768.js b/deps/v8/test/mjsunit/regress/wasm/regress-739768.js index 5fca49bc0fd9c8..0bd73223c9efee 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-739768.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-739768.js @@ -11,7 +11,7 @@ builder0.setName('module_0'); let sig_index = builder0.addType(kSig_i_v); builder0.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index, kTableZero ]) // -- .exportAs('main'); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7422.js b/deps/v8/test/mjsunit/regress/wasm/regress-7422.js index 71e1eb89bd871e..6bf737857ac2bb 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7422.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7422.js @@ -6,18 +6,18 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); var builder = new WasmModuleBuilder(); sig = makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32], [kWasmI32]); -builder.addFunction(undefined, sig).addBody([kExprGetLocal, 4]); +builder.addFunction(undefined, sig).addBody([kExprLocalGet, 4]); builder.addMemory(16, 32); builder.addFunction('main', sig) .addBody([ - kExprI32Const, 0, kExprSetLocal, 0, + kExprI32Const, 0, kExprLocalSet, 0, // Compute five arguments to the function call. kExprI32Const, 0, kExprI32Const, 0, kExprI32Const, 0, kExprI32Const, 0, - kExprGetLocal, 4, kExprI32Const, 1, kExprI32Add, + kExprLocalGet, 4, kExprI32Const, 1, kExprI32Add, // Now some intermediate computation to force the arguments to be spilled // to the stack: - kExprGetLocal, 0, kExprI32Const, 1, kExprI32Add, kExprGetLocal, 1, - kExprGetLocal, 1, kExprI32Add, kExprI32Add, kExprDrop, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add, kExprLocalGet, 1, + kExprLocalGet, 1, kExprI32Add, kExprI32Add, kExprDrop, // Now call the function. kExprCallFunction, 0 ]) diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7508.js b/deps/v8/test/mjsunit/regress/wasm/regress-7508.js index 10ce500a445da8..1c020609575923 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7508.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7508.js @@ -15,6 +15,6 @@ builder.addFunction(undefined, kSig_v_v).addLocals({i64_count: 1}).addBody([ kExprI32Const, 0, // i32.const kExprEnd, // end kExprBrIf, 0, // br_if depth=0 - kExprSetLocal, 0, // set_local 0 + kExprLocalSet, 0, // set_local 0 ]); builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-752423.js b/deps/v8/test/mjsunit/regress/wasm/regress-752423.js index 938ecbf2522c8e..304dbd955d4f67 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-752423.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-752423.js @@ -13,7 +13,7 @@ builder.addImportedTable("x", "table", 1, 10000000); builder.addFunction("main", kSig_i_i) .addBody([ kExprI32Const, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero]) .exportAs("main"); let module = new WebAssembly.Module(builder.toBuffer()); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7565.js b/deps/v8/test/mjsunit/regress/wasm/regress-7565.js index c9d4e2ca88dfc4..3b97fe86153a0b 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7565.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7565.js @@ -9,7 +9,7 @@ sig0 = makeSig([], [kWasmI32]); builder.addFunction(undefined, sig0).addLocals({i64_count: 1}).addBody([ kExprLoop, kWasmI32, // loop i32 kExprF32Const, 0x00, 0x00, 0x00, 0x00, // f32.const 0 --> f32:0 - kExprGetLocal, 0x00, // get_local 0 --> i64:0 + kExprLocalGet, 0x00, // get_local 0 --> i64:0 kExprF32SConvertI64, // f32.sconvert/i64 --> f32:0 kExprF32Ge, // f32.ge --> i32:1 kExprEnd, // end diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7579.js b/deps/v8/test/mjsunit/regress/wasm/regress-7579.js index 876a76cad93afb..da774b00f19cff 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7579.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7579.js @@ -51,7 +51,7 @@ const builder2 = new WasmModuleBuilder(); sig0 = makeSig([], [kWasmI32]); builder2.addFunction(undefined, sig0).addLocals({i64_count: 1}).addBody([ kExprLoop, kWasmI32, // loop i32 - kExprGetLocal, 0, // get_local 3 + kExprLocalGet, 0, // get_local 3 kExprF32SConvertI64, // f32.sconvert/i64 kExprI32ReinterpretF32, // i32.reinterpret/f32 kExprEnd // end diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-763697.js b/deps/v8/test/mjsunit/regress/wasm/regress-763697.js index c831a55fba5f9f..5f36d42c8d7c8c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-763697.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-763697.js @@ -8,7 +8,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addFunction("main", kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .addLocals({s128_count: 1}); assertFalse(WebAssembly.validate(builder.toBuffer())); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-771243.js b/deps/v8/test/mjsunit/regress/wasm/regress-771243.js index 81b9e8f2a98878..c06adebd76934d 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-771243.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-771243.js @@ -25,7 +25,7 @@ function __f_1() { __v_21 = __f_1(__v_18 = false, __v_25 = kSig_i_i); __v_21.addFunction('plus_one', kSig_i_i) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallFunction, __v_29 ]) .exportFunc(); __v_32 = diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-772332.js b/deps/v8/test/mjsunit/regress/wasm/regress-772332.js index e8547c8175897d..54676b198e08d1 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-772332.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-772332.js @@ -19,7 +19,7 @@ function __f_15356(__v_50316, __v_50317) { } (function __f_15357() { let __v_50320 = __f_15356(__v_50350 = false, __v_50351 = kSig_i_i); - __v_50320.addFunction('plus_one', kSig_i_i).addBody([kExprGetLocal, 0, kExprCallFunction, __v_50315, kExprI32Const, kExprI32Add, kExprReturn]).exportFunc(); + __v_50320.addFunction('plus_one', kSig_i_i).addBody([kExprLocalGet, 0, kExprCallFunction, __v_50315, kExprI32Const, kExprI32Add, kExprReturn]).exportFunc(); let __v_50321 = __f_15356(); let __v_50324 = __v_50321.instantiate(); let __v_50325 = __v_50320.instantiate({ diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-7785.js b/deps/v8/test/mjsunit/regress/wasm/regress-7785.js index 72638b168587d3..9f06ae5f10dbf7 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-7785.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-7785.js @@ -24,7 +24,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function testAnyRefIsNull() { const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_i_r) - .addBody([kExprGetLocal, 0, kExprRefIsNull]) + .addBody([kExprLocalGet, 0, kExprRefIsNull]) .exportFunc(); var wire_bytes = builder.toBuffer(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-791810.js b/deps/v8/test/mjsunit/regress/wasm/regress-791810.js index 73b47bdd78ac11..3daeff9e15200c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-791810.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-791810.js @@ -7,7 +7,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const builder = new WasmModuleBuilder(); builder.addFunction('test', kSig_i_i) .addBody([ - kExprGetLocal, 0x00, // get_local 0 + kExprLocalGet, 0x00, // get_local 0 kExprBlock, kWasmStmt, // block kExprBr, 0x00, // br depth=0 kExprEnd, // end diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-793551.js b/deps/v8/test/mjsunit/regress/wasm/regress-793551.js index 657b2c00134874..ac2b34019e28c7 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-793551.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-793551.js @@ -8,8 +8,8 @@ const builder = new WasmModuleBuilder(); builder.addFunction('test', kSig_i_i) .addBody([ // body: - kExprGetLocal, 0, // get_local 0 - kExprGetLocal, 0, // get_local 0 + kExprLocalGet, 0, // get_local 0 + kExprLocalGet, 0, // get_local 0 kExprLoop, kWasmStmt, // loop kExprBr, 0, // br depth=0 kExprEnd, // end diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-801785.js b/deps/v8/test/mjsunit/regress/wasm/regress-801785.js index 105fd4bc38e4df..7c68a0d59342fb 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-801785.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-801785.js @@ -10,11 +10,11 @@ const builder = new WasmModuleBuilder(); builder.addMemory(8, 16); builder.addFunction(undefined, kSig_i_i).addBody([ // wasm to wasm call. - kExprGetLocal, 0, kExprCallFunction, 0x1 + kExprLocalGet, 0, kExprCallFunction, 0x1 ]); builder.addFunction(undefined, kSig_i_i).addBody([ // load from <get_local 0> to create trap code. - kExprGetLocal, 0, kExprI32LoadMem, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, // unreachable to create a runtime call. kExprUnreachable ]); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-802244.js b/deps/v8/test/mjsunit/regress/wasm/regress-802244.js index aeaf850365d177..e212ec05d1db5c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-802244.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-802244.js @@ -8,10 +8,10 @@ const builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_v_iii).addBody([ kExprI32Const, 0x41, // i32.const 0x41 kExprLoop, 0x7c, // loop f64 - kExprGetLocal, 0x00, // get_local 0 - kExprGetLocal, 0x01, // get_local 1 + kExprLocalGet, 0x00, // get_local 0 + kExprLocalGet, 0x01, // get_local 1 kExprBrIf, 0x01, // br_if depth=1 - kExprGetLocal, 0x00, // get_local 0 + kExprLocalGet, 0x00, // get_local 0 kExprI32Rol, // i32.rol kExprBrIf, 0x00, // br_if depth=0 kExprUnreachable, // unreachable diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-8059.js b/deps/v8/test/mjsunit/regress/wasm/regress-8059.js index 78ee6bd1d262f7..4ee9cd3c431d18 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-8059.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-8059.js @@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function TestPostModule() { let builder = new WasmModuleBuilder(); builder.addFunction("add", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); let module = builder.toModule(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-808848.js b/deps/v8/test/mjsunit/regress/wasm/regress-808848.js index 57920de09d1593..269489059faa23 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-808848.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-808848.js @@ -27,11 +27,11 @@ function varuint32(val) { let body = []; for (let i = 0; i < kNumLocals; ++i) { - body.push(kExprCallFunction, 0, kExprSetLocal, ...varuint32(i)); + body.push(kExprCallFunction, 0, kExprLocalSet, ...varuint32(i)); } for (let i = 0; i < kNumLocals; ++i) { - body.push(kExprGetLocal, ...varuint32(i), kExprCallFunction, 1); + body.push(kExprLocalGet, ...varuint32(i), kExprCallFunction, 1); } let builder = new WasmModuleBuilder(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-808980.js b/deps/v8/test/mjsunit/regress/wasm/regress-808980.js index d78c07f36c21b9..6487a35cd3d1b6 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-808980.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-808980.js @@ -10,7 +10,7 @@ let kTableSize = 3; var builder = new WasmModuleBuilder(); var sig_index1 = builder.addType(kSig_i_v); builder.addFunction('main', kSig_i_ii).addBody([ - kExprGetLocal, + kExprLocalGet, 0, kExprCallIndirect, sig_index1, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-817380.js b/deps/v8/test/mjsunit/regress/wasm/regress-817380.js index c7748d89043159..23ab2a5c91d73d 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-817380.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-817380.js @@ -8,7 +8,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const builder1 = new WasmModuleBuilder(); builder1.addFunction('mul', kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Mul]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Mul]) .exportFunc(); const mul = builder1.instantiate().exports.mul; const table = new WebAssembly.Table({ diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-834619.js b/deps/v8/test/mjsunit/regress/wasm/regress-834619.js index 1062d5547a88db..af7043904ee8bb 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-834619.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-834619.js @@ -29,7 +29,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addTable(kWasmAnyFunc, 4); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-834624.js b/deps/v8/test/mjsunit/regress/wasm/regress-834624.js index 45af23cde22f2b..3e3548ed3217e2 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-834624.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-834624.js @@ -14,7 +14,7 @@ let instance; let module = new WasmModuleBuilder(); module.addImport('mod', 'func', kSig_v_i); module.addFunction('main', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprCallFunction, 0]) .exportFunc(); instance = module.instantiate({ mod: { diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-8505.js b/deps/v8/test/mjsunit/regress/wasm/regress-8505.js index b1fdedfc93c800..c1becbe454103c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-8505.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-8505.js @@ -171,8 +171,8 @@ function wasmBinop(name, sig) { builder.addImport('Math', name, sig_index); builder.addFunction('main', sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0 ]) // -- .exportAs('main'); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-854011.js b/deps/v8/test/mjsunit/regress/wasm/regress-854011.js index b0356a873f3531..00cfe655cb69ca 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-854011.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-854011.js @@ -9,14 +9,14 @@ builder.addFunction('main', kSig_d_d) .addBody([ // Call with param 0 (converted to i64), to fill the stack with non-zero // values. - kExprGetLocal, 0, kExprI64SConvertF64, // arg 0 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 1 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 2 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 3 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 4 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 5 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 6 - kExprGetLocal, 0, kExprI64SConvertF64, // arg 7 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 0 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 1 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 2 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 3 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 4 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 5 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 6 + kExprLocalGet, 0, kExprI64SConvertF64, // arg 7 kExprCallFunction, 1, // call #1 // Now call with 0 constants. // The bug was that they were written out as i32 values, thus the upper 32 @@ -36,7 +36,7 @@ builder.addFunction('main', kSig_d_d) .exportFunc(); builder.addFunction(undefined, makeSig(new Array(8).fill(kWasmI64), [kWasmF64])) .addBody([ - kExprGetLocal, 7, // get_local 7 (last parameter) + kExprLocalGet, 7, // get_local 7 (last parameter) kExprF64SConvertI64, // f64.convert_s/i64 ]); const instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-854050.js b/deps/v8/test/mjsunit/regress/wasm/regress-854050.js index d6c4829acd58b8..713059587039de 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-854050.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-854050.js @@ -8,18 +8,18 @@ const builder = new WasmModuleBuilder(); builder.addFunction(undefined, makeSig([kWasmI32, kWasmF32], [])) .addLocals({i32_count: 7}) .addBody([ - kExprGetLocal, 0, // get_local + kExprLocalGet, 0, // get_local kExprI32Const, 0, // i32.const 0 kExprIf, kWasmStmt, // if kExprUnreachable, // unreachable kExprEnd, // end if - kExprGetLocal, 4, // get_local - kExprTeeLocal, 8, // tee_local + kExprLocalGet, 4, // get_local + kExprLocalTee, 8, // tee_local kExprBrIf, 0, // br_if depth=0 - kExprTeeLocal, 7, // tee_local - kExprTeeLocal, 0, // tee_local - kExprTeeLocal, 2, // tee_local - kExprTeeLocal, 8, // tee_local + kExprLocalTee, 7, // tee_local + kExprLocalTee, 0, // tee_local + kExprLocalTee, 2, // tee_local + kExprLocalTee, 8, // tee_local kExprDrop, // drop kExprLoop, kWasmStmt, // loop kExprEnd, // end loop diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-864509.js b/deps/v8/test/mjsunit/regress/wasm/regress-864509.js index 19e3bfcfb80d0b..45e9e0b898355c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-864509.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-864509.js @@ -10,7 +10,7 @@ const builder = new WasmModuleBuilder(); builder.addMemory(1, 1); // First function is Liftoff. The first parameter is used as memory offset. builder.addFunction(undefined, kSig_v_i).addBody([ - kExprGetLocal, 0, // get_local 0 + kExprLocalGet, 0, // get_local 0 kExprI32Const, 0, // i32.const 0 kExprI32StoreMem, 0, 0, // i32.store offset=0 ]); @@ -19,7 +19,7 @@ builder.addFunction(undefined, kSig_v_i).addBody([ // is loaded as 64-bit value on x64. builder.addFunction(undefined, makeSig(new Array(6).fill(kWasmI32), [])) .addBody([ - kExprGetLocal, 5, // get_local 5 + kExprLocalGet, 5, // get_local 5 kExprCallFunction, 0 // call 0 ]); // The third function is Liftoff again. A value is spilled on the stack as i32, @@ -27,8 +27,8 @@ builder.addFunction(undefined, makeSig(new Array(6).fill(kWasmI32), [])) // copied on the stack, even though just 32-bit were written before. Hence, the // stack slot is not zero-extended. const gen_i32_code = [ - kExprTeeLocal, 0, // tee_local 0 - kExprGetLocal, 0, // get_local 0 + kExprLocalTee, 0, // tee_local 0 + kExprLocalGet, 0, // get_local 0 kExprI32Const, 1, // i32.const 1 kExprI32Add // i32.add --> 2nd param ]; diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-894307.js b/deps/v8/test/mjsunit/regress/wasm/regress-894307.js index f40388fcb401d0..a9a3595fbc1aa6 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-894307.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-894307.js @@ -8,8 +8,8 @@ const builder = new WasmModuleBuilder(); const sig = makeSig([kWasmI32, kWasmI64, kWasmI64], [kWasmI64]); builder.addFunction(undefined, sig) .addBody([ - kExprGetLocal, 2, - kExprGetLocal, 1, + kExprLocalGet, 2, + kExprLocalGet, 1, kExprI64Shl, ]); builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-910824.js b/deps/v8/test/mjsunit/regress/wasm/regress-910824.js index b795425b1f0c17..6101f8ca81e4a0 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-910824.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-910824.js @@ -11,26 +11,26 @@ builder.addType(makeSig([kWasmI32, kWasmF32, kWasmF32, kWasmF64], [kWasmI32])); builder.addFunction(undefined, 0 /* sig */) .addLocals({i32_count: 504}) .addBody([ -kExprGetGlobal, 0x00, -kExprSetLocal, 0x04, -kExprGetLocal, 0x04, +kExprGlobalGet, 0x00, +kExprLocalSet, 0x04, +kExprLocalGet, 0x04, kExprI32Const, 0x01, kExprI32Sub, -kExprGetGlobal, 0x00, +kExprGlobalGet, 0x00, kExprI32Const, 0x00, kExprI32Eqz, -kExprGetGlobal, 0x00, +kExprGlobalGet, 0x00, kExprI32Const, 0x01, kExprI32Const, 0x01, kExprI32Sub, -kExprGetGlobal, 0x00, +kExprGlobalGet, 0x00, kExprI32Const, 0x00, kExprI32Eqz, -kExprGetGlobal, 0x00, +kExprGlobalGet, 0x00, kExprI32Const, 0x00, kExprI32Const, 0x01, kExprI32Sub, -kExprGetGlobal, 0x01, +kExprGlobalGet, 0x01, kExprUnreachable, ]); builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-917412.js b/deps/v8/test/mjsunit/regress/wasm/regress-917412.js index b74572ac8a82d4..4b9528ccf6d097 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-917412.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-917412.js @@ -14,11 +14,11 @@ kExprIf, kWasmI32, kExprElse, kExprI32Const, 1, kExprEnd, -kExprTeeLocal, 0, -kExprGetLocal, 0, +kExprLocalTee, 0, +kExprLocalGet, 0, kExprLoop, kWasmStmt, kExprI64Const, 0x80, 0x80, 0x80, 0x70, - kExprSetLocal, 0x01, + kExprLocalSet, 0x01, kExprI32Const, 0x00, kExprIf, kWasmI32, kExprI32Const, 0x00, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-918284.js b/deps/v8/test/mjsunit/regress/wasm/regress-918284.js index dadbf3f7ea7be3..16de9caabdf71b 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-918284.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-918284.js @@ -14,7 +14,7 @@ builder.addFunction(undefined, kSig_i_i) kExprElse, // @15 kExprI32Const, 1, kExprEnd, // @18 - kExprTeeLocal, 0, + kExprLocalTee, 0, kExprI32Popcnt ]); builder.instantiate(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-918917.js b/deps/v8/test/mjsunit/regress/wasm/regress-918917.js index f007957c6f6064..3660244cda01d5 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-918917.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-918917.js @@ -8,9 +8,9 @@ const builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_v_v) .addLocals({i32_count: 1}).addLocals({f32_count: 1}).addLocals({f64_count: 1}) .addBody([ -kExprGetLocal, 1, -kExprGetLocal, 2, -kExprGetLocal, 0, +kExprLocalGet, 1, +kExprLocalGet, 2, +kExprLocalGet, 0, kExprIf, kWasmI32, kExprI32Const, 1, kExprElse, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-919308.js b/deps/v8/test/mjsunit/regress/wasm/regress-919308.js index 8c454413e86c54..e2f0426702f699 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-919308.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-919308.js @@ -8,23 +8,23 @@ const builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_i_i) .addLocals({i32_count: 5}) .addBody([ - kExprGetLocal, 0, // --> 1 + kExprLocalGet, 0, // --> 1 kExprIf, kWasmI32, - kExprGetLocal, 0, // --> 1 + kExprLocalGet, 0, // --> 1 kExprElse, kExprUnreachable, kExprEnd, kExprIf, kWasmI32, - kExprGetLocal, 0, // --> 1 + kExprLocalGet, 0, // --> 1 kExprElse, kExprUnreachable, kExprEnd, kExprIf, kWasmI32, kExprI32Const, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Sub, // --> -1 - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Sub, // --> 0 kExprI32Sub, // --> -1 kExprElse, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-919533.js b/deps/v8/test/mjsunit/regress/wasm/regress-919533.js index 706d3cc7f4eb06..1cc4b675c20800 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-919533.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-919533.js @@ -8,8 +8,8 @@ const builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_v_v).addBody([]); builder.addFunction(undefined, kSig_i_i) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, // Stack now contains two copies of the first param register. // Start a loop to create a merge point (values still in registers). kExprLoop, kWasmStmt, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-922432.js b/deps/v8/test/mjsunit/regress/wasm/regress-922432.js index f6175b3a63e10a..d5aee0d33238d1 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-922432.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-922432.js @@ -12,7 +12,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); .addLocals({except_count: 1}) .addBody([ kExprLoop, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprBrOnExn // Bytecode truncated here. ]).exportFunc(); fun.body.pop(); // Pop implicitly added kExprEnd from body. diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-922670.js b/deps/v8/test/mjsunit/regress/wasm/regress-922670.js index 2988eddf302457..96a17bebbad753 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-922670.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-922670.js @@ -10,10 +10,10 @@ builder.addFunction(undefined, sig) .addLocals({i64_count: 1}) .addBody([ kExprLoop, kWasmI32, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64Const, 1, kExprLoop, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Const, 1, kExprIf, kWasmI32, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-922933.js b/deps/v8/test/mjsunit/regress/wasm/regress-922933.js index 4d445095988499..6d0286d95aa3e0 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-922933.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-922933.js @@ -14,30 +14,30 @@ builder.addFunction(undefined, sig) kExprEnd, kExprBlock, kWasmStmt, kExprI32Const, 0x00, - kExprSetLocal, 0x09, + kExprLocalSet, 0x09, kExprI32Const, 0x00, kExprIf, kWasmStmt, kExprBlock, kWasmStmt, kExprI32Const, 0x00, - kExprSetLocal, 0x0a, + kExprLocalSet, 0x0a, kExprBr, 0x00, kExprEnd, kExprBlock, kWasmStmt, kExprBlock, kWasmStmt, - kExprGetLocal, 0x00, - kExprSetLocal, 0x12, + kExprLocalGet, 0x00, + kExprLocalSet, 0x12, kExprBr, 0x00, kExprEnd, - kExprGetLocal, 0x16, - kExprSetLocal, 0x0f, - kExprGetLocal, 0x0f, - kExprSetLocal, 0x17, - kExprGetLocal, 0x0f, - kExprSetLocal, 0x18, - kExprGetLocal, 0x17, - kExprGetLocal, 0x18, + kExprLocalGet, 0x16, + kExprLocalSet, 0x0f, + kExprLocalGet, 0x0f, + kExprLocalSet, 0x17, + kExprLocalGet, 0x0f, + kExprLocalSet, 0x18, + kExprLocalGet, 0x17, + kExprLocalGet, 0x18, kExprI64ShrS, - kExprSetLocal, 0x19, + kExprLocalSet, 0x19, kExprUnreachable, kExprEnd, kExprUnreachable, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-924843.js b/deps/v8/test/mjsunit/regress/wasm/regress-924843.js index 0549a769fbf886..c77845af76a2f5 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-924843.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-924843.js @@ -8,7 +8,7 @@ const builder = new WasmModuleBuilder(); const sig = builder.addType(makeSig([kWasmI32, kWasmI32, kWasmI32], [kWasmI32])); builder.addFunction(undefined, sig) .addBody([ - kExprGetLocal, 2, + kExprLocalGet, 2, kExprIf, kWasmStmt, kExprBlock, kWasmStmt ]); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-935138.js b/deps/v8/test/mjsunit/regress/wasm/regress-935138.js index 20835428e37221..dd585bb255b20c 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-935138.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-935138.js @@ -11,8 +11,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); binary.emit_header(); binary.emit_bytes([kTypeSectionCode, 4, 1, kWasmFunctionTypeForm, 0, 0]); binary.emit_bytes([kFunctionSectionCode, 2, 1, 0]); - binary.emit_bytes([kCodeSectionCode, 6, 1, 4, 0, kExprGetLocal, 0, kExprEnd]); - binary.emit_bytes([kCodeSectionCode, 6, 1, 4, 0, kExprGetLocal, 0, kExprEnd]); + binary.emit_bytes([kCodeSectionCode, 6, 1, 4, 0, kExprLocalGet, 0, kExprEnd]); + binary.emit_bytes([kCodeSectionCode, 6, 1, 4, 0, kExprLocalGet, 0, kExprEnd]); let buffer = binary.trunc_buffer(); assertPromiseResult(WebAssembly.compile(buffer), assertUnreachable, e => assertInstanceof(e, WebAssembly.CompileError)); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-952342.js b/deps/v8/test/mjsunit/regress/wasm/regress-952342.js index eb81f5a9c60bdf..5e20860d4dd510 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-952342.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-952342.js @@ -9,9 +9,9 @@ const memory = new WebAssembly.Memory({initial: 1}); let builder = new WasmModuleBuilder(); builder.addImportedMemory("imports", "mem", 1); builder.addFunction("copy", kSig_v_iii) - .addBody([kExprGetLocal, 0, // dst - kExprGetLocal, 1, // src - kExprGetLocal, 2, // size + .addBody([kExprLocalGet, 0, // dst + kExprLocalGet, 1, // src + kExprLocalGet, 2, // size kNumericPrefix, kExprMemoryCopy, 0, 0]).exportAs("copy"); let instance = builder.instantiate({imports: {mem: memory}}); memory.grow(1); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-957405.js b/deps/v8/test/mjsunit/regress/wasm/regress-957405.js index a83104297e50b6..51adce7698bb1b 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-957405.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-957405.js @@ -9,9 +9,9 @@ const memory = new WebAssembly.Memory({initial: 1}); let builder = new WasmModuleBuilder(); builder.addImportedMemory("imports", "mem"); builder.addFunction("fill", kSig_v_iii) - .addBody([kExprGetLocal, 0, // dst - kExprGetLocal, 1, // value - kExprGetLocal, 2, // size + .addBody([kExprLocalGet, 0, // dst + kExprLocalGet, 1, // value + kExprLocalGet, 2, // size kNumericPrefix, kExprMemoryFill, 0]).exportAs("fill"); let instance = builder.instantiate({imports: {mem: memory}}); memory.grow(1); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-968078.js b/deps/v8/test/mjsunit/regress/wasm/regress-968078.js index 2935ea05e332f1..07081087fa5d93 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-968078.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-968078.js @@ -28,16 +28,16 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("foo", kSig_v_iii) .addBody([].concat([ kExprBlock, kWasmStmt, - kExprGetLocal, 0x2, + kExprLocalGet, 0x2, kExprI32Const, 0x01, kExprI32And, // Generate a test branch (which has 32k limited reach). kExprIf, kWasmStmt, - kExprGetLocal, 0x0, + kExprLocalGet, 0x0, kExprI32Const, 0x01, kExprI32And, kExprBrIf, 0x1, - kExprGetLocal, 0x0, + kExprLocalGet, 0x0, // Emit a br_table that is long enough to make the test branch go out of range. ], br_table(0x1, 9000, 0x00), [ kExprEnd, diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-9759.js b/deps/v8/test/mjsunit/regress/wasm/regress-9759.js new file mode 100644 index 00000000000000..9d1f86a48dd000 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-9759.js @@ -0,0 +1,26 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --no-wasm-tier-up --no-liftoff + +load("test/mjsunit/wasm/wasm-module-builder.js"); + +// This constant was chosen as it is the smallest number of cases that still +// triggers the input count overflow. The new limit put into place is smaller. +const NUM_CASES = 0xfffd; + +(function TestBrTableTooLarge() { + let builder = new WasmModuleBuilder(); + let cases = new Array(NUM_CASES).fill(0); + builder.addFunction('main', kSig_v_i) + .addBody([].concat([ + kExprBlock, kWasmStmt, + kExprLocalGet, 0, + kExprBrTable], wasmSignedLeb(NUM_CASES), + cases, [0, + kExprEnd + ])).exportFunc(); + assertThrows(() => new WebAssembly.Module(builder.toBuffer()), + WebAssembly.CompileError, /invalid table count/); +})(); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1006631.js b/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1006631.js new file mode 100644 index 00000000000000..ab555e4551474e --- /dev/null +++ b/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1006631.js @@ -0,0 +1,7 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --experimental-wasm-type-reflection --trace-turbo-graph + +new WebAssembly.Function({ parameters: [], results: [] }, x => x); diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1007608.js b/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1007608.js index 37d5b2e4a2f700..279d2dbd06bfb6 100644 --- a/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1007608.js +++ b/deps/v8/test/mjsunit/regress/wasm/regress-crbug-1007608.js @@ -13,7 +13,7 @@ let types = new Array(argc).fill(kWasmI32); let sig = makeSig(types, []); let body = []; for (let i = 0; i < argc; ++i) { - body.push(kExprGetLocal, i); + body.push(kExprLocalGet, i); } body.push(kExprCallFunction, 0); builder.addImport('', 'f', sig); diff --git a/deps/v8/test/mjsunit/string-replace-gc.js b/deps/v8/test/mjsunit/string-replace-gc.js index 2f1efd8813c343..56b6a09da1e482 100644 --- a/deps/v8/test/mjsunit/string-replace-gc.js +++ b/deps/v8/test/mjsunit/string-replace-gc.js @@ -25,31 +25,22 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Regression test for the r1512 fix. +// Regression test for the r1513 fix. + +// Flags: --allow-natives-syntax var foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; +assertEquals(39, foo.length); + +for (var i = 0; i < 12; i++) { + foo = foo + foo; +} -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; -foo = foo + foo; - -foo.replace(/[b]/, "c"); // Flatten foo. +foo = %FlattenString(foo); var moving_string = "b" + "c"; -var bar = foo.replace(/[a]/g, moving_string); +var bar = foo.replace(/a/g, moving_string); -print(bar.length); +// 39 * 2^12 * 2 +assertEquals(319488, bar.length); diff --git a/deps/v8/test/mjsunit/tools/compiler-trace-flags-wasm.js b/deps/v8/test/mjsunit/tools/compiler-trace-flags-wasm.js index 2d7cd00ac3ba18..7be5abb6758a2b 100644 --- a/deps/v8/test/mjsunit/tools/compiler-trace-flags-wasm.js +++ b/deps/v8/test/mjsunit/tools/compiler-trace-flags-wasm.js @@ -20,8 +20,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addFunction("add", kSig_i_ii) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Add]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/unicodelctest-no-optimization.js b/deps/v8/test/mjsunit/unicodelctest-no-optimization.js index 0b31c560e07326..e56d690ed2a891 100644 --- a/deps/v8/test/mjsunit/unicodelctest-no-optimization.js +++ b/deps/v8/test/mjsunit/unicodelctest-no-optimization.js @@ -93,7 +93,6 @@ function fuzz() { fuzz_index = 0; seed = 49734321; for (var i = 0; i < 1000; i++) { - print(i); var len = rand() & 0x1f; var ranges = new Array(len); var last = rand(); diff --git a/deps/v8/test/mjsunit/wasm/OWNERS b/deps/v8/test/mjsunit/wasm/OWNERS index b6d75023d799ab..c400f97de0620e 100644 --- a/deps/v8/test/mjsunit/wasm/OWNERS +++ b/deps/v8/test/mjsunit/wasm/OWNERS @@ -1,3 +1,3 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org titzer@chromium.org diff --git a/deps/v8/test/mjsunit/wasm/adapter-frame.js b/deps/v8/test/mjsunit/wasm/adapter-frame.js index 55634163c60847..a25e2aaf3bbb08 100644 --- a/deps/v8/test/mjsunit/wasm/adapter-frame.js +++ b/deps/v8/test/mjsunit/wasm/adapter-frame.js @@ -28,7 +28,7 @@ function makeSelect(type, args, which) { var params = []; for (var i = 0; i < args; i++) params.push(type); builder.addFunction("select", makeSig(params, [type])) - .addBody([kExprGetLocal, which]) + .addBody([kExprLocalGet, which]) .exportFunc(); return builder.instantiate().exports.select; diff --git a/deps/v8/test/mjsunit/wasm/anyfunc.js b/deps/v8/test/mjsunit/wasm/anyfunc.js index f0d587b25aa8e1..4a53a044680165 100644 --- a/deps/v8/test/mjsunit/wasm/anyfunc.js +++ b/deps/v8/test/mjsunit/wasm/anyfunc.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_a_a) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportFunc(); const instance = builder.instantiate(); @@ -27,7 +27,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const sig_index = builder.addType(kSig_v_a); const imp_index = builder.addImport('q', 'func', sig_index); builder.addFunction('main', sig_index) - .addBody([kExprGetLocal, 0, kExprCallFunction, imp_index]) + .addBody([kExprLocalGet, 0, kExprCallFunction, imp_index]) .exportFunc(); const main = builder.instantiate({q: {func: checkFunction}}).exports.main; @@ -50,28 +50,28 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder.addFunction('main', ref_sig) .addLocals({anyfunc_count: 10}) .addBody([ - kExprGetLocal, 0, - kExprSetLocal, 1, // Set local - kExprGetLocal, 0, - kExprSetLocal, 2, // Set local - kExprGetLocal, 0, - kExprSetLocal, 3, // Set local - kExprGetLocal, 0, - kExprSetLocal, 4, // Set local - kExprGetLocal, 0, - kExprSetLocal, 5, // Set local - kExprGetLocal, 0, - kExprSetLocal, 6, // Set local - kExprGetLocal, 0, - kExprSetLocal, 7, // Set local - kExprGetLocal, 0, - kExprSetLocal, 8, // Set local - kExprGetLocal, 0, - kExprSetLocal, 9, // Set local - kExprGetLocal, 0, - kExprSetLocal, 10, // Set local + kExprLocalGet, 0, + kExprLocalSet, 1, // Set local + kExprLocalGet, 0, + kExprLocalSet, 2, // Set local + kExprLocalGet, 0, + kExprLocalSet, 3, // Set local + kExprLocalGet, 0, + kExprLocalSet, 4, // Set local + kExprLocalGet, 0, + kExprLocalSet, 5, // Set local + kExprLocalGet, 0, + kExprLocalSet, 6, // Set local + kExprLocalGet, 0, + kExprLocalSet, 7, // Set local + kExprLocalGet, 0, + kExprLocalSet, 8, // Set local + kExprLocalGet, 0, + kExprLocalSet, 9, // Set local + kExprLocalGet, 0, + kExprLocalSet, 10, // Set local kExprCallFunction, gc_index, // call gc - kExprGetLocal, 9, + kExprLocalGet, 9, kExprCallFunction, imp_index // call import ]) .exportFunc(); @@ -97,7 +97,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder.addFunction('main', ref_sig) .addBody([ kExprCallFunction, gc_index, // call gc - kExprGetLocal, 0, kExprCallFunction, imp_index // call import + kExprLocalGet, 0, kExprCallFunction, imp_index // call import ]) .exportFunc(); @@ -118,7 +118,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); makeSig([kWasmI32, kWasmAnyFunc, kWasmI32], [kWasmAnyFunc]); const sig_index = builder.addType(kSig_a_iai); builder.addFunction('main', sig_index) - .addBody([kExprGetLocal, 1]) + .addBody([kExprLocalGet, 1]) .exportFunc(); const main = builder.instantiate().exports.main; @@ -140,7 +140,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const sig_index = builder.addType(kSig_a_v); builder.addFunction('main', sig_index) .addLocals({anyfunc_count: 1}) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportFunc(); const main = builder.instantiate().exports.main; @@ -152,7 +152,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const builder = new WasmModuleBuilder(); const sig_index = builder.addType(kSig_a_a); builder.addFunction('main', sig_index) - .addBody([kExprRefNull, kExprSetLocal, 0, kExprGetLocal, 0]) + .addBody([kExprRefNull, kExprLocalSet, 0, kExprLocalGet, 0]) .exportFunc(); const main = builder.instantiate().exports.main; @@ -187,7 +187,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const sig_index = builder.addType(kSig_r_v); builder.addFunction('main', sig_index) .addLocals({anyfunc_count: 1}) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportFunc(); const main = builder.instantiate().exports.main; @@ -200,7 +200,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); const sig_index = builder.addType(kSig_r_v); builder.addFunction('main', sig_index) .addLocals({anyfunc_count: 1}) - .addBody([kExprGetLocal, 0, kExprReturn]) + .addBody([kExprLocalGet, 0, kExprReturn]) .exportFunc(); const main = builder.instantiate().exports.main; diff --git a/deps/v8/test/mjsunit/wasm/anyref-globals.js b/deps/v8/test/mjsunit/wasm/anyref-globals.js index 39d3bcb14709d2..d243e37486f6ee 100644 --- a/deps/v8/test/mjsunit/wasm/anyref-globals.js +++ b/deps/v8/test/mjsunit/wasm/anyref-globals.js @@ -12,10 +12,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g_nullref = builder.addGlobal(kWasmAnyRef, true).index; const g_nullfunc = builder.addGlobal(kWasmAnyFunc, true).index; builder.addFunction("get_anyref_global", kSig_r_v) - .addBody([kExprGetGlobal, g_nullref]) + .addBody([kExprGlobalGet, g_nullref]) .exportAs("get_anyref_global"); builder.addFunction("get_anyfunc_global", kSig_a_v) - .addBody([kExprGetGlobal, g_nullfunc]) + .addBody([kExprGlobalGet, g_nullfunc]) .exportAs("get_anyfunc_global"); const instance = builder.instantiate(); @@ -32,16 +32,16 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g_nullfunc = builder.addGlobal(kWasmAnyFunc, true); builder.addFunction("get_anyref_global", kSig_r_r) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g_setref.index, - kExprGetGlobal, g_nullref.index + kExprLocalGet, 0, + kExprGlobalSet, g_setref.index, + kExprGlobalGet, g_nullref.index ]) .exportAs("get_anyref_global"); builder.addFunction("get_anyfunc_global", kSig_a_a) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g_setfunc.index, - kExprGetGlobal, g_nullfunc.index + kExprLocalGet, 0, + kExprGlobalSet, g_setfunc.index, + kExprGlobalGet, g_nullfunc.index ]) .exportAs("get_anyfunc_global"); @@ -59,9 +59,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g = builder.addGlobal(kWasmAnyRef, true); builder.addFunction("main", kSig_r_r) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g.index, - kExprGetGlobal, g.index + kExprLocalGet, 0, + kExprGlobalSet, g.index, + kExprGlobalGet, g.index ]) .exportAs("main"); @@ -79,9 +79,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g = builder.addGlobal(kWasmAnyFunc, true); builder.addFunction("main", kSig_a_a) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g.index, - kExprGetGlobal, g.index + kExprLocalGet, 0, + kExprGlobalSet, g.index, + kExprGlobalGet, g.index ]) .exportAs("main"); @@ -100,10 +100,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g = builder.addGlobal(kWasmAnyRef, true); builder.addFunction("main", kSig_r_r) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g.index, + kExprLocalGet, 0, + kExprGlobalSet, g.index, kExprCallFunction, gc_index, // call gc - kExprGetGlobal, g.index + kExprGlobalGet, g.index ]) .exportAs("main"); @@ -121,14 +121,14 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const g = builder.addGlobal(kWasmAnyRef, true); builder.addFunction("get_global", kSig_r_v) .addBody([ - kExprGetGlobal, g.index + kExprGlobalGet, g.index ]) .exportAs("get_global"); builder.addFunction("set_global", kSig_v_r) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g.index + kExprLocalGet, 0, + kExprGlobalSet, g.index ]) .exportAs("set_global"); @@ -150,7 +150,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); const g = builder.addImportedGlobal('m', 'val', kWasmAnyRef); builder.addFunction('main', kSig_r_v) - .addBody([kExprGetGlobal, g]) + .addBody([kExprGlobalGet, g]) .exportAs('main'); const instance = builder.instantiate({ m: { val: obj } }); @@ -178,7 +178,7 @@ function dummy_func() { let builder = new WasmModuleBuilder(); const g = builder.addImportedGlobal('m', 'val', kWasmAnyFunc); builder.addFunction('main', kSig_a_v) - .addBody([kExprGetGlobal, g]) + .addBody([kExprGlobalGet, g]) .exportAs('main'); const module = builder.toModule(); @@ -285,14 +285,14 @@ function dummy_func() { builder.addFunction("main", makeSig([kWasmAnyRef, kWasmAnyFunc, kWasmAnyRef, kWasmAnyFunc], [])) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g1.index, - kExprGetLocal, 1, - kExprSetGlobal, g2.index, - kExprGetLocal, 2, - kExprSetGlobal, g3.index, - kExprGetLocal, 3, - kExprSetGlobal, g4.index + kExprLocalGet, 0, + kExprGlobalSet, g1.index, + kExprLocalGet, 1, + kExprGlobalSet, g2.index, + kExprLocalGet, 2, + kExprGlobalSet, g3.index, + kExprLocalGet, 3, + kExprGlobalSet, g4.index ]) .exportAs("main"); @@ -314,7 +314,7 @@ function dummy_func() { let builder = new WasmModuleBuilder(); const g = builder.addImportedGlobal('m', 'val', kWasmAnyRef, true); builder.addFunction('main', kSig_r_v) - .addBody([kExprGetGlobal, g]) + .addBody([kExprGlobalGet, g]) .exportAs('main'); const global = new WebAssembly.Global({ value: 'anyref', mutable: 'true' }, obj); @@ -335,7 +335,7 @@ function dummy_func() { let builder = new WasmModuleBuilder(); const g = builder.addImportedGlobal('m', 'val', kWasmAnyFunc, true); builder.addFunction('main', kSig_a_v) - .addBody([kExprGetGlobal, g]) + .addBody([kExprGlobalGet, g]) .exportAs('main'); const global = new WebAssembly.Global({ value: 'anyfunc', mutable: 'true' }, obj); @@ -358,19 +358,19 @@ function dummy_func() { builder1.addFunction("set_globals", kSig_v_rr) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g2.index, - kExprGetLocal, 1, - kExprSetGlobal, g3.index, + kExprLocalGet, 0, + kExprGlobalSet, g2.index, + kExprLocalGet, 1, + kExprGlobalSet, g3.index, ]) .exportAs("set_globals"); builder1.addFunction('get_global2', kSig_r_v) - .addBody([kExprGetGlobal, g2.index]) + .addBody([kExprGlobalGet, g2.index]) .exportAs('get_global2'); builder1.addFunction('get_global3', kSig_r_v) - .addBody([kExprGetGlobal, g3.index]) + .addBody([kExprGlobalGet, g3.index]) .exportAs('get_global3'); const instance1 = builder1.instantiate(); @@ -392,19 +392,19 @@ function dummy_func() { builder2.addFunction("set_globals", kSig_v_rr) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, i2, - kExprGetLocal, 1, - kExprSetGlobal, i3, + kExprLocalGet, 0, + kExprGlobalSet, i2, + kExprLocalGet, 1, + kExprGlobalSet, i3, ]) .exportAs("set_globals"); builder2.addFunction('get_global2', kSig_r_v) - .addBody([kExprGetGlobal, i2]) + .addBody([kExprGlobalGet, i2]) .exportAs('get_global2'); builder2.addFunction('get_global3', kSig_r_v) - .addBody([kExprGetGlobal, i3]) + .addBody([kExprGlobalGet, i3]) .exportAs('get_global3'); const instance2 = builder2.instantiate(instance1); @@ -454,19 +454,19 @@ function dummy_func() { builder1.addFunction("set_globals", kSig_v_aa) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g2.index, - kExprGetLocal, 1, - kExprSetGlobal, g3.index, + kExprLocalGet, 0, + kExprGlobalSet, g2.index, + kExprLocalGet, 1, + kExprGlobalSet, g3.index, ]) .exportAs("set_globals"); builder1.addFunction('get_global2', kSig_a_v) - .addBody([kExprGetGlobal, g2.index]) + .addBody([kExprGlobalGet, g2.index]) .exportAs('get_global2'); builder1.addFunction('get_global3', kSig_a_v) - .addBody([kExprGetGlobal, g3.index]) + .addBody([kExprGlobalGet, g3.index]) .exportAs('get_global3'); const instance1 = builder1.instantiate(); @@ -489,19 +489,19 @@ function dummy_func() { builder2.addFunction("set_globals", kSig_v_aa) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, i2, - kExprGetLocal, 1, - kExprSetGlobal, i3, + kExprLocalGet, 0, + kExprGlobalSet, i2, + kExprLocalGet, 1, + kExprGlobalSet, i3, ]) .exportAs("set_globals"); builder2.addFunction('get_global2', kSig_a_v) - .addBody([kExprGetGlobal, i2]) + .addBody([kExprGlobalGet, i2]) .exportAs('get_global2'); builder2.addFunction('get_global3', kSig_a_v) - .addBody([kExprGetGlobal, i3]) + .addBody([kExprGlobalGet, i3]) .exportAs('get_global3'); const instance2 = builder2.instantiate(instance1); @@ -563,10 +563,10 @@ function dummy_func() { const g_ref = builder.addGlobal(kWasmAnyRef, true); const g_func = builder.addGlobal(kWasmAnyFunc, true); const f_ref = builder.addFunction('get_anyref_global', kSig_r_v) - .addBody([kExprGetGlobal, g_ref.index]) + .addBody([kExprGlobalGet, g_ref.index]) .exportAs('get_anyref_global'); const f_func = builder.addFunction('get_anyfunc_global', kSig_a_v) - .addBody([kExprGetGlobal, g_func.index]) + .addBody([kExprGlobalGet, g_func.index]) .exportAs('get_anyfunc_global'); g_ref.function_index = f_ref.index; @@ -591,10 +591,10 @@ function dummy_func() { g_wasm.function_index = import_wasm; g_js.function_index = import_js; builder.addFunction('get_global_wasm', kSig_a_v) - .addBody([kExprGetGlobal, g_wasm.index]) + .addBody([kExprGlobalGet, g_wasm.index]) .exportFunc(); builder.addFunction('get_global_js', kSig_a_v) - .addBody([kExprGetGlobal, g_js.index]) + .addBody([kExprGlobalGet, g_js.index]) .exportFunc(); const expected_wasm = dummy_func(); diff --git a/deps/v8/test/mjsunit/wasm/anyref.js b/deps/v8/test/mjsunit/wasm/anyref.js index 141d25d1e3a989..cdb4742776234a 100644 --- a/deps/v8/test/mjsunit/wasm/anyref.js +++ b/deps/v8/test/mjsunit/wasm/anyref.js @@ -10,7 +10,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_r_r) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportFunc(); @@ -31,7 +31,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const sig_index = builder.addType(kSig_v_r); const imp_index = builder.addImport("q", "func", sig_index); builder.addFunction('main', sig_index) - .addBody([kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, kExprCallFunction, imp_index]) .exportFunc(); @@ -55,18 +55,18 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction('main', ref_sig) .addLocals({anyref_count: 10}) .addBody([ - kExprGetLocal, 0, kExprSetLocal, 1, // Set local - kExprGetLocal, 0, kExprSetLocal, 2, // Set local - kExprGetLocal, 0, kExprSetLocal, 3, // Set local - kExprGetLocal, 0, kExprSetLocal, 4, // Set local - kExprGetLocal, 0, kExprSetLocal, 5, // Set local - kExprGetLocal, 0, kExprSetLocal, 6, // Set local - kExprGetLocal, 0, kExprSetLocal, 7, // Set local - kExprGetLocal, 0, kExprSetLocal, 8, // Set local - kExprGetLocal, 0, kExprSetLocal, 9, // Set local - kExprGetLocal, 0, kExprSetLocal, 10, // Set local + kExprLocalGet, 0, kExprLocalSet, 1, // Set local + kExprLocalGet, 0, kExprLocalSet, 2, // Set local + kExprLocalGet, 0, kExprLocalSet, 3, // Set local + kExprLocalGet, 0, kExprLocalSet, 4, // Set local + kExprLocalGet, 0, kExprLocalSet, 5, // Set local + kExprLocalGet, 0, kExprLocalSet, 6, // Set local + kExprLocalGet, 0, kExprLocalSet, 7, // Set local + kExprLocalGet, 0, kExprLocalSet, 8, // Set local + kExprLocalGet, 0, kExprLocalSet, 9, // Set local + kExprLocalGet, 0, kExprLocalSet, 10, // Set local kExprCallFunction, gc_index, // call gc - kExprGetLocal, 9, kExprCallFunction, imp_index // call import + kExprLocalGet, 9, kExprCallFunction, imp_index // call import ]) .exportFunc(); @@ -90,7 +90,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction('main', ref_sig) .addBody([ kExprCallFunction, gc_index, // call gc - kExprGetLocal, 0, kExprCallFunction, imp_index // call import + kExprLocalGet, 0, kExprCallFunction, imp_index // call import ]) .exportFunc(); @@ -119,7 +119,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction('main', main_sig) .addBody([ kExprCallFunction, gc_index, // call gc - kExprGetLocal, index, kExprCallFunction, imp_index // call import + kExprLocalGet, index, kExprCallFunction, imp_index // call import ]) .exportFunc(); @@ -145,7 +145,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const kSig_r_iri = makeSig([kWasmI32, kWasmAnyRef, kWasmI32], [kWasmAnyRef]); const sig_index = builder.addType(kSig_r_iri); builder.addFunction('main', sig_index) - .addBody([kExprGetLocal, 1]) + .addBody([kExprLocalGet, 1]) .exportFunc(); const instance = builder.instantiate(); @@ -177,7 +177,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_i_r) - .addBody([kExprGetLocal, 0, kExprRefIsNull]) + .addBody([kExprLocalGet, 0, kExprRefIsNull]) .exportFunc(); const instance = builder.instantiate(); @@ -208,7 +208,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_r_v) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .addLocals({anyref_count: 1}) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm-i32.js b/deps/v8/test/mjsunit/wasm/asm-wasm-i32.js index 9d8b14afecd59a..0f93e77f6c6572 100644 --- a/deps/v8/test/mjsunit/wasm/asm-wasm-i32.js +++ b/deps/v8/test/mjsunit/wasm/asm-wasm-i32.js @@ -192,28 +192,15 @@ function i32_invert(a) { var inputs = [ 0, 1, 2, 3, 4, - 10, 20, 30, 31, 32, 33, 100, 2000, - 30000, 400000, 5000000, - 100000000, 2000000000, 2147483646, - 2147483647, - 2147483648, - 2147483649, - 0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344, + 2147483647, // max positive int32 + 2147483648, // overflow max positive int32 0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c, - 0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00, - 0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000, - 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff, - 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff, - 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff, + 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x0003ffff, 0x00001fff, -1, -2, -3, -4, - -10, -20, -30, -31, -32, -33, -100, -2000, - -30000, -400000, -5000000, - -100000000, -2000000000, - -2147483646, -2147483647, - -2147483648, - -2147483649, + -2147483648, // min negative int32 + -2147483649, // overflow min negative int32 ]; var funcs = [ diff --git a/deps/v8/test/mjsunit/wasm/asm-wasm-u32.js b/deps/v8/test/mjsunit/wasm/asm-wasm-u32.js index 0809bca6ab9517..fda60910840b17 100644 --- a/deps/v8/test/mjsunit/wasm/asm-wasm-u32.js +++ b/deps/v8/test/mjsunit/wasm/asm-wasm-u32.js @@ -170,28 +170,15 @@ function u32_invert(a) { var inputs = [ 0, 1, 2, 3, 4, - 10, 20, 30, 31, 32, 33, 100, 2000, - 30000, 400000, 5000000, - 100000000, 2000000000, 2147483646, - 2147483647, - 2147483648, - 2147483649, - 0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344, + 2147483647, // max positive int32 + 2147483648, // overflow max positive int32 0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c, - 0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00, - 0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000, - 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff, - 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff, - 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff, + 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x0003ffff, 0x00001fff, -1, -2, -3, -4, - -10, -20, -30, -31, -32, -33, -100, -2000, - -30000, -400000, -5000000, - -100000000, -2000000000, - -2147483646, -2147483647, - -2147483648, - -2147483649, + -2147483648, // min negative int32 + -2147483649, // overflow min negative int32 ]; var funcs = [ diff --git a/deps/v8/test/mjsunit/wasm/atomics-stress.js b/deps/v8/test/mjsunit/wasm/atomics-stress.js index 8622919043a186..9eb18050cb81b1 100644 --- a/deps/v8/test/mjsunit/wasm/atomics-stress.js +++ b/deps/v8/test/mjsunit/wasm/atomics-stress.js @@ -165,15 +165,15 @@ class Operation { // Load address of low 32 bits. kExprI32Const, 0, // Load expected value. - kExprGetLocal, 0, kExprI32StoreMem, 2, 0, + kExprLocalGet, 0, kExprI32StoreMem, 2, 0, // Load address of high 32 bits. kExprI32Const, 4, // Load expected value. - kExprGetLocal, 1, kExprI32StoreMem, 2, 0, + kExprLocalGet, 1, kExprI32StoreMem, 2, 0, // Load address of where our window starts. kExprI32Const, 0, // Load input if there is one. - ...(this.hasInput ? [kExprGetLocal, 2] : []), + ...(this.hasInput ? [kExprLocalGet, 2] : []), // Perform operation. kAtomicPrefix, ...this.wasmOpcode, // Drop output if it had any. @@ -261,19 +261,19 @@ function generateFunctionBodyForSequence(sequence) { if (!kDebug) { body.push( // Decrement the wait count. - kExprGetLocal, 2, kExprI32Const, 1, kAtomicPrefix, kExprI32AtomicSub, 2, + kExprLocalGet, 2, kExprI32Const, 1, kAtomicPrefix, kExprI32AtomicSub, 2, 0, // Spin until zero. - kExprLoop, kWasmStmt, kExprGetLocal, 2, kAtomicPrefix, + kExprLoop, kWasmStmt, kExprLocalGet, 2, kAtomicPrefix, kExprI32AtomicLoad, 2, 0, kExprI32Const, 0, kExprI32GtU, kExprBrIf, 0, kExprEnd); } for (let operation of sequence) { body.push( // Pre-load address of results sequence pointer for later. - kExprGetLocal, 1, + kExprLocalGet, 1, // Load address where atomic pointers are stored. - kExprGetLocal, 0, + kExprLocalGet, 0, // Load the second argument if it had any. ...(operation.hasInput ? [kExprI32Const, ...toSLeb128(operation.input)] : @@ -285,10 +285,10 @@ function generateFunctionBodyForSequence(sequence) { // Store read intermediate to sequence. kExprI32StoreMem, 2, 0, // Increment result sequence pointer. - kExprGetLocal, 1, kExprI32Const, 4, kExprI32Add, kExprSetLocal, 1); + kExprLocalGet, 1, kExprI32Const, 4, kExprI32Add, kExprLocalSet, 1); } // Return end of sequence index. - body.push(kExprGetLocal, 1, kExprReturn); + body.push(kExprLocalGet, 1, kExprReturn); return body; } diff --git a/deps/v8/test/mjsunit/wasm/atomics.js b/deps/v8/test/mjsunit/wasm/atomics.js index 08714bbc0162f4..264662f2ac05f1 100644 --- a/deps/v8/test/mjsunit/wasm/atomics.js +++ b/deps/v8/test/mjsunit/wasm/atomics.js @@ -25,8 +25,8 @@ function GetAtomicBinOpFunction(wasmExpression, alignment, offset) { builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kAtomicPrefix, wasmExpression, alignment, offset]) .exportAs("main"); @@ -43,9 +43,9 @@ function GetAtomicCmpExchangeFunction(wasmExpression, alignment, offset) { builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared"); builder.addFunction("main", kSig_i_iii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 2, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, kAtomicPrefix, wasmExpression, alignment, offset]) .exportAs("main"); @@ -62,7 +62,7 @@ function GetAtomicLoadFunction(wasmExpression, alignment, offset) { builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared"); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kAtomicPrefix, wasmExpression, alignment, offset]) .exportAs("main"); @@ -79,8 +79,8 @@ function GetAtomicStoreFunction(wasmExpression, alignment, offset) { builder.addImportedMemory("m", "imported_mem", 0, maxSize, "shared"); builder.addFunction("main", kSig_v_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kAtomicPrefix, wasmExpression, alignment, offset]) .exportAs("main"); @@ -440,11 +440,11 @@ function CmpExchgLoop(opcode, alignment) { .addLocals({i64_count: 2}) .addBody([ kExprLoop, kWasmStmt, - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 2, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, kAtomicPrefix, opcode, alignment, 0, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64Ne, kExprBrIf, 0, kExprEnd diff --git a/deps/v8/test/mjsunit/wasm/atomics64-stress.js b/deps/v8/test/mjsunit/wasm/atomics64-stress.js index 386a3b5549b96e..99e9016f1a4eb6 100644 --- a/deps/v8/test/mjsunit/wasm/atomics64-stress.js +++ b/deps/v8/test/mjsunit/wasm/atomics64-stress.js @@ -191,18 +191,18 @@ class Operation { // Load address of low 32 bits. kExprI32Const, 0, // Load expected value. - kExprGetLocal, 0, kExprI32StoreMem, 2, 0, + kExprLocalGet, 0, kExprI32StoreMem, 2, 0, // Load address of high 32 bits. kExprI32Const, 4, // Load expected value. - kExprGetLocal, 1, kExprI32StoreMem, 2, 0, + kExprLocalGet, 1, kExprI32StoreMem, 2, 0, // Load address of where our window starts. kExprI32Const, 0, // Load input if there is one. ...(this.hasInput ? [ - kExprGetLocal, 3, kExprI64UConvertI32, kExprI64Const, 32, - kExprI64Shl, kExprGetLocal, 2, kExprI64UConvertI32, + kExprLocalGet, 3, kExprI64UConvertI32, kExprI64Const, 32, + kExprI64Shl, kExprLocalGet, 2, kExprI64UConvertI32, kExprI64Ior ] : []), @@ -299,19 +299,19 @@ function generateFunctionBodyForSequence(sequence) { if (!kDebug) { body.push( // Decrement the wait count. - kExprGetLocal, 2, kExprI32Const, 1, kAtomicPrefix, kExprI32AtomicSub, 2, + kExprLocalGet, 2, kExprI32Const, 1, kAtomicPrefix, kExprI32AtomicSub, 2, 0, // Spin until zero. - kExprLoop, kWasmStmt, kExprGetLocal, 2, kAtomicPrefix, + kExprLoop, kWasmStmt, kExprLocalGet, 2, kAtomicPrefix, kExprI32AtomicLoad, 2, 0, kExprI32Const, 0, kExprI32GtU, kExprBrIf, 0, kExprEnd); } for (let operation of sequence) { body.push( // Pre-load address of results sequence pointer for later. - kExprGetLocal, 1, + kExprLocalGet, 1, // Load address where atomic pointers are stored. - kExprGetLocal, 0, + kExprLocalGet, 0, // Load the second argument if it had any. ...(operation.hasInput ? [ @@ -326,10 +326,10 @@ function generateFunctionBodyForSequence(sequence) { // Store read intermediate to sequence. kExprI64StoreMem, 3, 0, // Increment result sequence pointer. - kExprGetLocal, 1, kExprI32Const, 8, kExprI32Add, kExprSetLocal, 1); + kExprLocalGet, 1, kExprI32Const, 8, kExprI32Add, kExprLocalSet, 1); } // Return end of sequence index. - body.push(kExprGetLocal, 1, kExprReturn); + body.push(kExprLocalGet, 1, kExprReturn); return body; } diff --git a/deps/v8/test/mjsunit/wasm/bigint.js b/deps/v8/test/mjsunit/wasm/bigint.js index ff9046e9dcf16b..0c9ebb6559d919 100644 --- a/deps/v8/test/mjsunit/wasm/bigint.js +++ b/deps/v8/test/mjsunit/wasm/bigint.js @@ -26,30 +26,30 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); let a_global_index = builder - .addImportedGlobal("mod", "a", kWasmI64) + .addImportedGlobal("mod", "a", kWasmI64); let b_global_index = builder .addImportedGlobal("mod", "b", kWasmI64); - let c_global_index = builder - .addImportedGlobal("mod", "c", kWasmI64); - builder .addExportOfKind('a', kExternalGlobal, a_global_index) .addExportOfKind('b', kExternalGlobal, b_global_index) - .addExportOfKind('c', kExternalGlobal, c_global_index); let module = builder.instantiate({ mod: { a: 1n, b: 2n ** 63n, - c: "123", } }); assertEquals(module.exports.a.value, 1n); assertEquals(module.exports.b.value, - (2n ** 63n)); - assertEquals(module.exports.c.value, 123n); +})(); + +(function TestJSBigIntGlobalImportInvalidType() { + let builder = new WasmModuleBuilder(); + builder.addImportedGlobal("mod", "a", kWasmI64); + assertThrows(() => builder.instantiate({mod: { a: {} } }), WebAssembly.LinkError); })(); (function TestJSBigIntToWasmI64MutableGlobal() { @@ -86,7 +86,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder .addFunction("f", kSig_l_l) // i64 -> i64 .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, ]) .exportFunc(); @@ -108,7 +108,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder .addFunction("f", kSig_l_ll) // i64 -> i64 .addBody([ - kExprGetLocal, 1, + kExprLocalGet, 1, ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js b/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js index 43ff8570c67bb1..90ede1ac92cf62 100644 --- a/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js +++ b/deps/v8/test/mjsunit/wasm/bounds-check-64bit.js @@ -8,9 +8,9 @@ const builder = new WasmModuleBuilder(); builder.addMemory(1, undefined, false); builder.addFunction('load', kSig_i_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI64SConvertI32, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64SConvertI32, kExprI64Shl, kExprI32ConvertI64, diff --git a/deps/v8/test/mjsunit/wasm/bounds-check-turbofan.js b/deps/v8/test/mjsunit/wasm/bounds-check-turbofan.js index d972e7830d032a..b740a20f1a3e4d 100644 --- a/deps/v8/test/mjsunit/wasm/bounds-check-turbofan.js +++ b/deps/v8/test/mjsunit/wasm/bounds-check-turbofan.js @@ -10,7 +10,7 @@ const builder = new WasmModuleBuilder(); builder.addMemory(1, undefined, false); builder.addFunction('load', kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 100]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/bulk-memory.js b/deps/v8/test/mjsunit/wasm/bulk-memory.js index d783c6bf594021..53ca1454b6fdfe 100644 --- a/deps/v8/test/mjsunit/wasm/bulk-memory.js +++ b/deps/v8/test/mjsunit/wasm/bulk-memory.js @@ -33,9 +33,9 @@ function getMemoryInit(mem, segment_data) { builder.addPassiveDataSegment(segment_data); builder.addFunction('init', kSig_v_iii) .addBody([ - kExprGetLocal, 0, // Dest. - kExprGetLocal, 1, // Source. - kExprGetLocal, 2, // Size in bytes. + kExprLocalGet, 0, // Dest. + kExprLocalGet, 1, // Source. + kExprLocalGet, 2, // Size in bytes. kNumericPrefix, kExprMemoryInit, 0, // Data segment index. 0, // Memory index. @@ -102,9 +102,9 @@ function getMemoryCopy(mem) { const builder = new WasmModuleBuilder(); builder.addImportedMemory("", "mem", 0); builder.addFunction("copy", kSig_v_iii).addBody([ - kExprGetLocal, 0, // Dest. - kExprGetLocal, 1, // Source. - kExprGetLocal, 2, // Size in bytes. + kExprLocalGet, 0, // Dest. + kExprLocalGet, 1, // Source. + kExprLocalGet, 2, // Size in bytes. kNumericPrefix, kExprMemoryCopy, 0, 0, ]).exportAs("copy"); return builder.instantiate({'': {mem}}).exports.copy; @@ -128,9 +128,9 @@ function getMemoryFill(mem) { const builder = new WasmModuleBuilder(); builder.addImportedMemory("", "mem", 0); builder.addFunction("fill", kSig_v_iii).addBody([ - kExprGetLocal, 0, // Dest. - kExprGetLocal, 1, // Byte value. - kExprGetLocal, 2, // Size. + kExprLocalGet, 0, // Dest. + kExprLocalGet, 1, // Byte value. + kExprLocalGet, 2, // Size. kNumericPrefix, kExprMemoryFill, 0, ]).exportAs("fill"); return builder.instantiate({'': {mem}}).exports.fill; diff --git a/deps/v8/test/mjsunit/wasm/calls.js b/deps/v8/test/mjsunit/wasm/calls.js index 97188964d1c03a..f8a4616def0a49 100644 --- a/deps/v8/test/mjsunit/wasm/calls.js +++ b/deps/v8/test/mjsunit/wasm/calls.js @@ -49,8 +49,8 @@ function assertFunction(module, func) { builder.addMemory(1, 1, true); builder.addFunction("sub", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Sub, // -- ]) .exportFunc() @@ -91,8 +91,8 @@ function assertFunction(module, func) { builder.addMemory(kPages, kPages, true); builder.addFunction("flt", kSig_i_dd) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprF64Lt // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/code-space-exhaustion.js b/deps/v8/test/mjsunit/wasm/code-space-exhaustion.js index 6f4698c0d0a341..45eaef92e80d26 100644 --- a/deps/v8/test/mjsunit/wasm/code-space-exhaustion.js +++ b/deps/v8/test/mjsunit/wasm/code-space-exhaustion.js @@ -9,7 +9,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); // We only have 1 MB code space. This is enough for the code below, but for all // 1000 modules, it requires several GCs to get rid of the old code. const builder = new WasmModuleBuilder(); -builder.addFunction('main', kSig_i_i).addBody([kExprGetLocal, 0]); +builder.addFunction('main', kSig_i_i).addBody([kExprLocalGet, 0]); const buffer = builder.toBuffer(); for (let i = 0; i < 1000; ++i) { diff --git a/deps/v8/test/mjsunit/wasm/compare-exchange-stress.js b/deps/v8/test/mjsunit/wasm/compare-exchange-stress.js index 5102216933527f..050a15e3804161 100644 --- a/deps/v8/test/mjsunit/wasm/compare-exchange-stress.js +++ b/deps/v8/test/mjsunit/wasm/compare-exchange-stress.js @@ -37,42 +37,42 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, const kLocalNextValue = 7; // the value to write in the update let body = [ // Turn sequence length to equivalent in bytes. - kExprGetLocal, kArgSeqenceLength, + kExprLocalGet, kArgSeqenceLength, kExprI32Const, size / 8, kExprI32Mul, - kExprSetLocal, kArgSeqenceLength, + kExprLocalSet, kArgSeqenceLength, // Outer block so we have something to jump for return. ...[kExprBlock, kWasmStmt, // Set counter to 0. kExprI32Const, 0, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, // Outer loop until maxcount. ...[kExprLoop, kWasmStmt, // Find the next value to wait for. ...[kExprLoop, kWasmStmt, // Check end of sequence. - kExprGetLocal, kLocalCurrentOffset, - kExprGetLocal, kArgSeqenceLength, + kExprLocalGet, kLocalCurrentOffset, + kExprLocalGet, kArgSeqenceLength, kExprI32Eq, kExprBrIf, 2, // return ...[kExprBlock, kWasmStmt, // Load next value. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, loadMemOpcode, 0, 0, // Mask off bits. - kExprGetLocal, kArgBitMask, + kExprLocalGet, kArgBitMask, kExprI32And, // Compare with worker id. - kExprGetLocal, kArgWorkerId, + kExprLocalGet, kArgWorkerId, kExprI32Eq, kExprBrIf, 0, // Not found, increment position. - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kLocalCurrentOffset, kExprI32Const, size / 8, kExprI32Add, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, kExprBr, 1, kExprEnd ], @@ -80,41 +80,41 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, kExprEnd ], // Load expected value to local. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, loadMemOpcode, 0, 0, - kExprSetLocal, kLocalExpectedValue, + kExprLocalSet, kLocalExpectedValue, // Load value after expected one. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, kExprI32Const, size / 8, kExprI32Add, loadMemOpcode, 0, 0, - kExprSetLocal, kLocalNextValue, + kExprLocalSet, kLocalNextValue, // Hammer on memory until value found. ...[kExprLoop, kWasmStmt, // Load address. - kExprGetLocal, kArgMemoryCell, + kExprLocalGet, kArgMemoryCell, // Load expected value. - kExprGetLocal, kLocalExpectedValue, + kExprLocalGet, kLocalExpectedValue, // Load updated value. - kExprGetLocal, kLocalNextValue, + kExprLocalGet, kLocalNextValue, // Try update. kAtomicPrefix, compareExchangeOpcode, 0, 0, // Load expected value. - kExprGetLocal, kLocalExpectedValue, + kExprLocalGet, kLocalExpectedValue, // Spin if not what expected. kExprI32Ne, kExprBrIf, 0, kExprEnd ], // Next iteration of loop. - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kLocalCurrentOffset, kExprI32Const, size / 8, kExprI32Add, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, kExprBr, 0, kExprEnd ], // outer loop diff --git a/deps/v8/test/mjsunit/wasm/compare-exchange64-stress.js b/deps/v8/test/mjsunit/wasm/compare-exchange64-stress.js index bd1c5c95a54910..b2ffcf1475e6d6 100644 --- a/deps/v8/test/mjsunit/wasm/compare-exchange64-stress.js +++ b/deps/v8/test/mjsunit/wasm/compare-exchange64-stress.js @@ -40,44 +40,44 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, const kLocalNextValue = 7; // the value to write in the update let body = [ // Turn sequence length to equivalent in bytes. - kExprGetLocal, kArgSeqenceLength, + kExprLocalGet, kArgSeqenceLength, kExprI32Const, size / 8, kExprI32Mul, - kExprSetLocal, kArgSeqenceLength, + kExprLocalSet, kArgSeqenceLength, // Outer block so we have something to jump for return. ...[kExprBlock, kWasmStmt, // Set counter to 0. kExprI32Const, 0, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, // Outer loop until maxcount. ...[kExprLoop, kWasmStmt, // Find the next value to wait for. ...[kExprLoop, kWasmStmt, // Check end of sequence. - kExprGetLocal, kLocalCurrentOffset, - kExprGetLocal, kArgSeqenceLength, + kExprLocalGet, kLocalCurrentOffset, + kExprLocalGet, kArgSeqenceLength, kExprI32Eq, kExprBrIf, 2, // return ...[kExprBlock, kWasmStmt, // Load next value. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, loadMemOpcode, 0, 0, // Mask off bits. - kExprGetLocal, kArgBitMask, + kExprLocalGet, kArgBitMask, kExprI64UConvertI32, kExprI64And, // Compare with worker id. - kExprGetLocal, kArgWorkerId, + kExprLocalGet, kArgWorkerId, kExprI64UConvertI32, kExprI64Eq, kExprBrIf, 0, // Not found, increment position. - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kLocalCurrentOffset, kExprI32Const, size / 8, kExprI32Add, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, kExprBr, 1, kExprEnd ], @@ -85,41 +85,41 @@ function makeWorkerCodeForOpcode(compareExchangeOpcode, size, functionName, kExprEnd ], // Load expected value to local. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, loadMemOpcode, 0, 0, - kExprSetLocal, kLocalExpectedValue, + kExprLocalSet, kLocalExpectedValue, // Load value after expected one. - kExprGetLocal, kArgSequencePtr, - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kArgSequencePtr, + kExprLocalGet, kLocalCurrentOffset, kExprI32Add, kExprI32Const, size / 8, kExprI32Add, loadMemOpcode, 0, 0, - kExprSetLocal, kLocalNextValue, + kExprLocalSet, kLocalNextValue, // Hammer on memory until value found. ...[kExprLoop, kWasmStmt, // Load address. - kExprGetLocal, kArgMemoryCell, + kExprLocalGet, kArgMemoryCell, // Load expected value. - kExprGetLocal, kLocalExpectedValue, + kExprLocalGet, kLocalExpectedValue, // Load updated value. - kExprGetLocal, kLocalNextValue, + kExprLocalGet, kLocalNextValue, // Try update. kAtomicPrefix, compareExchangeOpcode, 0, 0, // Load expected value. - kExprGetLocal, kLocalExpectedValue, + kExprLocalGet, kLocalExpectedValue, // Spin if not what expected. kExprI64Ne, kExprBrIf, 0, kExprEnd ], // Next iteration of loop. - kExprGetLocal, kLocalCurrentOffset, + kExprLocalGet, kLocalCurrentOffset, kExprI32Const, size / 8, kExprI32Add, - kExprSetLocal, kLocalCurrentOffset, + kExprLocalSet, kLocalCurrentOffset, kExprBr, 0, kExprEnd ], // outer loop diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-async-compilation.js b/deps/v8/test/mjsunit/wasm/compilation-hints-async-compilation.js index 5ca20cbb953d0a..4723b92acff2a5 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-async-compilation.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-async-compilation.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierOptimized, kCompilationHintTierBaseline) @@ -26,7 +26,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_l) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, kCompilationHintTierDefault) @@ -49,7 +49,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, kCompilationHintTierDefault) @@ -63,7 +63,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazyBaselineEagerTopTier, kCompilationHintTierDefault, kCompilationHintTierDefault) diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-decoder.js b/deps/v8/test/mjsunit/wasm/compilation-hints-decoder.js index e39e15feeb205d..5bcac2af9e96cb 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-decoder.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-decoder.js @@ -11,8 +11,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierOptimized, @@ -29,20 +29,20 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyDefault, kCompilationHintTierInterpreter, kCompilationHintTierInterpreter) .exportFunc(); builder.addFunction('upow2', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow3', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) let instance = builder.instantiate({mod: {pow: Math.pow}}); assertEquals(27, instance.exports.upow(3)) @@ -53,16 +53,16 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow2', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow3', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyEager, kCompilationHintTierBaseline, @@ -76,8 +76,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('sq', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyEager, kCompilationHintTierDefault, @@ -91,8 +91,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('sq', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyEager, kCompilationHintTierDefault, @@ -104,8 +104,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('sq', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyEager, kCompilationHintTierOptimized, @@ -119,8 +119,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('sq', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyLazyBaselineEagerTopTier, kCompilationHintTierOptimized, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-ignored.js b/deps/v8/test/mjsunit/wasm/compilation-hints-ignored.js index 553426db08eaca..4bfc22fb89c939 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-ignored.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-ignored.js @@ -9,8 +9,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyDefault, kCompilationHintTierInterpreter, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-interpreter.js b/deps/v8/test/mjsunit/wasm/compilation-hints-interpreter.js index f0a46b9ec77c2f..f9f85a7d91f85b 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-interpreter.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-interpreter.js @@ -19,7 +19,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder1.addImport("otherModule", "getX", kSig_i_v); builder1.addFunction("plusX", kSig_i_i) .addBody([kExprCallFunction, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Add]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, @@ -44,7 +44,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder1.addImport("otherModule", "getX", kSig_i_v); builder1.addFunction("plusX", kSig_i_i) .addBody([kExprCallFunction, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Add]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, @@ -64,8 +64,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); let sig_i_ii = builder.addType(kSig_i_ii); let add = builder.addFunction('add', sig_i_ii) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Add]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, @@ -73,9 +73,9 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder.appendToTable([add.index]); builder.addFunction('main', kSig_i_iii) .addBody([// Call indirect #0 with args <#1, #2>. - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprCallIndirect, sig_i_ii, kTableZero]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, @@ -89,8 +89,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); let sig_i_ii = builder.addType(kSig_i_ii); let add = builder.addFunction('add', sig_i_ii) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kExprI64Add]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, @@ -98,9 +98,9 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder.appendToTable([add.index]); builder.addFunction('main', kSig_i_iii) .addBody([// Call indirect #0 with args <#1, #2>. - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprCallIndirect, sig_i_ii, kTableZero]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierInterpreter, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-lazy-validation.js b/deps/v8/test/mjsunit/wasm/compilation-hints-lazy-validation.js index e6958cb5541bb4..de2bbd1c1329b2 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-lazy-validation.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-lazy-validation.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, kExprI64Const, 1, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyLazy, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-compilation.js b/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-compilation.js index f48169fa0ad777..2708da149b8a06 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-compilation.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-compilation.js @@ -11,12 +11,12 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow2', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, @@ -33,12 +33,12 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow2', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierOptimized, @@ -59,12 +59,12 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_f_ff); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) builder.addFunction('upow2', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, @@ -94,8 +94,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, @@ -112,8 +112,8 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); let builder = new WasmModuleBuilder(); builder.addImport('mod', 'pow', kSig_i_ii); builder.addFunction('upow', kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .setCompilationHint(kCompilationHintStrategyLazyBaselineEagerTopTier, kCompilationHintTierDefault, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-lazy-validation.js b/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-lazy-validation.js index 6db4c0e328270d..f125aeaa7edb3a 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-lazy-validation.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-streaming-lazy-validation.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, kExprI64Const, 1, kExprI32Mul]) .setCompilationHint(kCompilationHintStrategyLazy, diff --git a/deps/v8/test/mjsunit/wasm/compilation-hints-sync-compilation.js b/deps/v8/test/mjsunit/wasm/compilation-hints-sync-compilation.js index 6c4364b6d33c5b..35f77de157dd1c 100644 --- a/deps/v8/test/mjsunit/wasm/compilation-hints-sync-compilation.js +++ b/deps/v8/test/mjsunit/wasm/compilation-hints-sync-compilation.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierOptimized, kCompilationHintTierBaseline) @@ -25,7 +25,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_l) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, kCompilationHintTierDefault) @@ -46,7 +46,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazy, kCompilationHintTierDefault, kCompilationHintTierDefault) @@ -58,7 +58,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('id', kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .setCompilationHint(kCompilationHintStrategyLazyBaselineEagerTopTier, kCompilationHintTierDefault, kCompilationHintTierDefault) diff --git a/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js b/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js index c95e4d05b719b3..859a3095aec77a 100644 --- a/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js +++ b/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js @@ -17,11 +17,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 0, kExprI32Const, 1, kExprCallIndirect, signature, kTableZero, - kExprGetLocal,0, + kExprLocalGet,0, kExprI32LoadMem,0, 0, kExprCallFunction, 0, kExprI32Add @@ -31,7 +31,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); // return mem[i] + some_value(); builder.addFunction("_wrap_writer", signature) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 1]); builder.appendToTable([2, 3]); @@ -175,13 +175,13 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addGlobal(kWasmI32, true); builder.addFunction("read", kSig_i_v) .addBody([ - kExprGetGlobal, 0]) + kExprGlobalGet, 0]) .exportFunc(); builder.addFunction("write", kSig_v_i) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, 0]) + kExprLocalGet, 0, + kExprGlobalSet, 0]) .exportFunc(); var wire_bytes = builder.toBuffer(); @@ -213,7 +213,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index1, kTableZero]) // -- .exportAs("main"); @@ -234,7 +234,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index2, kTableZero]) // -- .exportAs("main"); @@ -293,7 +293,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const builder = new WasmModuleBuilder(); builder.addMemory(1, 1); builder.addFunction('main', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); const wire_bytes = builder.toBuffer(); const module = new WebAssembly.Module(wire_bytes); @@ -364,7 +364,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); kExprBlock, kWasmStmt, kExprBlock, kWasmStmt, kExprBlock, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprBrTable, 6, 0, 1, 2, 3, 4, 5, 6, kExprEnd, kExprI32Const, 3, diff --git a/deps/v8/test/mjsunit/wasm/data-segments.js b/deps/v8/test/mjsunit/wasm/data-segments.js index 91b6525537de84..38fd5ee06b6b3a 100644 --- a/deps/v8/test/mjsunit/wasm/data-segments.js +++ b/deps/v8/test/mjsunit/wasm/data-segments.js @@ -13,7 +13,7 @@ function SimpleDataSegmentTest(offset) { var builder = new WasmModuleBuilder(); builder.addMemory(1, 1, false); builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportAs("load"); builder.addDataSegment(offset, [9, 9, 9, 9]); @@ -41,7 +41,7 @@ function GlobalImportedInitTest(pad) { while (pad-- > 0) builder.addGlobal(kWasmI32); // pad builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportAs("load"); builder.addDataSegment(g.index, [5, 5, 5, 5], true); diff --git a/deps/v8/test/mjsunit/wasm/divrem-trap.js b/deps/v8/test/mjsunit/wasm/divrem-trap.js index d9a23693f08949..5eadaa44e9e08e 100644 --- a/deps/v8/test/mjsunit/wasm/divrem-trap.js +++ b/deps/v8/test/mjsunit/wasm/divrem-trap.js @@ -16,8 +16,8 @@ function makeBinop(opcode) { builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- opcode, // -- ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/empirical_max_memory.js b/deps/v8/test/mjsunit/wasm/empirical_max_memory.js index e2ff7ca517eee9..59e15f84644a86 100644 --- a/deps/v8/test/mjsunit/wasm/empirical_max_memory.js +++ b/deps/v8/test/mjsunit/wasm/empirical_max_memory.js @@ -19,14 +19,14 @@ let kMaxMemory = 2 * k1GiB - kPageSize; // TODO(titzer): raise this to 4GiB builder.addImportedMemory("i", "mem"); builder.addFunction("load", makeSig([kWasmI32], [type])) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- load_opcode, 0, 0, // -- ]) // -- .exportFunc(); builder.addFunction("store", makeSig([kWasmI32, type], [])) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- store_opcode, 0, 0, // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/ensure-wasm-binaries-up-to-date.js b/deps/v8/test/mjsunit/wasm/ensure-wasm-binaries-up-to-date.js index 9f7a7f71d2e03c..e9e380a4ca57d0 100644 --- a/deps/v8/test/mjsunit/wasm/ensure-wasm-binaries-up-to-date.js +++ b/deps/v8/test/mjsunit/wasm/ensure-wasm-binaries-up-to-date.js @@ -14,7 +14,7 @@ var module = new WasmModuleBuilder(); module.addFunction(undefined, kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32Const, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add]) .exportAs("increment"); var buffer = module.toBuffer(true); diff --git a/deps/v8/test/mjsunit/wasm/errors.js b/deps/v8/test/mjsunit/wasm/errors.js index d98452e0e82ef3..4304e54588e330 100644 --- a/deps/v8/test/mjsunit/wasm/errors.js +++ b/deps/v8/test/mjsunit/wasm/errors.js @@ -64,7 +64,7 @@ function assertConversionError(bytes, imports, msg) { .end().toBuffer(), f_error('expected 1 elements on the stack for return, found 0 @+24')); assertCompileError(builder().addFunction('f', kSig_v_v).addBody([ - kExprGetLocal, 0 + kExprLocalGet, 0 ]).end().toBuffer(), f_error('invalid local index: 0 @+24')); assertCompileError( builder().addStart(0).toBuffer(), @@ -182,7 +182,7 @@ function import_error(index, module, func, msg) { var sig = builder.addType(kSig_i_dd); builder.addImport("mod", "func", sig); builder.addFunction("main", sig) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprCallFunction, 0]) .exportAs("main"); var main = builder.instantiate({ mod: { diff --git a/deps/v8/test/mjsunit/wasm/exceptions-anyref.js b/deps/v8/test/mjsunit/wasm/exceptions-anyref.js index a41d69c0af2647..ccda100f65d1ea 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions-anyref.js +++ b/deps/v8/test/mjsunit/wasm/exceptions-anyref.js @@ -30,7 +30,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_null", kSig_i_i) .addBody([ kExprTry, kWasmAnyRef, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmAnyRef, kExprRefNull, @@ -63,7 +63,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_r); builder.addFunction("throw_param", kSig_v_r) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, ]).exportFunc(); let instance = builder.instantiate(); @@ -83,7 +83,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_r_r) .addBody([ kExprTry, kWasmAnyRef, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprCatch, kExprBrOnExn, 0, except, @@ -108,7 +108,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); .addLocals({anyfunc_count: 1}) .addBody([ kExprTry, kWasmAnyFunc, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprCatch, kExprBrOnExn, 0, except, @@ -128,7 +128,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_e_e) .addBody([ kExprTry, kWasmExnRef, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprCatch, kExprBrOnExn, 0, except, diff --git a/deps/v8/test/mjsunit/wasm/exceptions-global.js b/deps/v8/test/mjsunit/wasm/exceptions-global.js index 4a74dfb010d35b..80af193c3e9e0d 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions-global.js +++ b/deps/v8/test/mjsunit/wasm/exceptions-global.js @@ -16,7 +16,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let g = builder.addGlobal(kWasmExnRef); builder.addFunction("push_and_drop_exnref", kSig_v_v) .addBody([ - kExprGetGlobal, g.index, + kExprGlobalGet, g.index, kExprDrop, ]).exportFunc(); let instance = builder.instantiate(); @@ -30,7 +30,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); let g = builder.addGlobal(kWasmExnRef); builder.addFunction('push_and_return_exnref', kSig_e_v) - .addBody([kExprGetGlobal, g.index]) + .addBody([kExprGlobalGet, g.index]) .exportFunc(); let instance = builder.instantiate(); @@ -46,10 +46,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction('catch_and_set_exnref', kSig_v_i) .addBody([ kExprTry, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprCatch, - kExprSetGlobal, g.index, + kExprGlobalSet, g.index, kExprEnd, ]).exportFunc(); let instance = builder.instantiate(); @@ -68,10 +68,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction('set_param_exnref', kSig_v_e) .addBody([ kExprTry, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprRethrow, kExprCatch, - kExprSetGlobal, g.index, + kExprGlobalSet, g.index, kExprEnd, ]).exportFunc(); let exception = "my fancy exception"; @@ -88,7 +88,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let g_index = builder.addImportedGlobal("m", "exn", kWasmExnRef); builder.addFunction('rethrow_exnref', kSig_v_v) .addBody([ - kExprGetGlobal, g_index, + kExprGlobalGet, g_index, kExprRethrow, ]).exportFunc(); let exception = "my fancy exception"; @@ -104,7 +104,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let g = builder.addGlobal(kWasmExnRef, true).exportAs("exn"); builder.addFunction('rethrow_exnref', kSig_v_v) .addBody([ - kExprGetGlobal, g.index, + kExprGlobalGet, g.index, kExprRethrow, ]).exportFunc(); let instance = builder.instantiate(); @@ -122,7 +122,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let g_index = builder.addImportedGlobal("m", "exn", kWasmExnRef, true); builder.addFunction('rethrow_exnref', kSig_v_v) .addBody([ - kExprGetGlobal, g_index, + kExprGlobalGet, g_index, kExprRethrow, ]).exportFunc(); let exception1 = "my fancy exception"; @@ -143,7 +143,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let g2 = builder.addGlobal(kWasmExnRef); g2.init_index = g1_index; // Initialize {g2} to equal {g1}. builder.addFunction('push_and_return_exnref', kSig_e_v) - .addBody([kExprGetGlobal, g2.index]) + .addBody([kExprGlobalGet, g2.index]) .exportFunc(); let exception = { x: "my fancy exception" }; let instance = builder.instantiate({ "m": { "exn": exception }}); diff --git a/deps/v8/test/mjsunit/wasm/exceptions-rethrow.js b/deps/v8/test/mjsunit/wasm/exceptions-rethrow.js index 3b3fa365d5244e..be609cbf2d2fc1 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions-rethrow.js +++ b/deps/v8/test/mjsunit/wasm/exceptions-rethrow.js @@ -26,11 +26,11 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprTry, kWasmI32, kExprThrow, except, kExprCatch, - kExprSetLocal, 1, - kExprGetLocal, 0, + kExprLocalSet, 1, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprRethrow, kExprEnd, kExprI32Const, 23, @@ -56,23 +56,23 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprTry, kWasmI32, kExprThrow, except2, kExprCatch, - kExprSetLocal, 2, + kExprLocalSet, 2, kExprTry, kWasmI32, kExprThrow, except1, kExprCatch, - kExprSetLocal, 1, - kExprGetLocal, 0, + kExprLocalSet, 1, + kExprLocalGet, 0, kExprI32Const, 0, kExprI32Eq, kExprIf, kWasmStmt, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprRethrow, kExprEnd, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Eq, kExprIf, kWasmStmt, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprRethrow, kExprEnd, kExprI32Const, 23, @@ -98,12 +98,12 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprTry, kWasmI32, kExprThrow, except, kExprCatch, - kExprSetLocal, 1, + kExprLocalSet, 1, kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprRethrow, kExprEnd, kExprI32Const, 42, diff --git a/deps/v8/test/mjsunit/wasm/exceptions-simd.js b/deps/v8/test/mjsunit/wasm/exceptions-simd.js index ed16a7f2ccbceb..00fc725f5de522 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions-simd.js +++ b/deps/v8/test/mjsunit/wasm/exceptions-simd.js @@ -14,7 +14,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_simd", kSig_v_v) .addLocals({s128_count: 1}) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, 0, ]) .exportFunc(); @@ -32,7 +32,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); .addLocals({s128_count: 1}) .addBody([ kExprTry, kWasmS128, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, 0, kExprCatch, kExprBrOnExn, 0, except, diff --git a/deps/v8/test/mjsunit/wasm/exceptions.js b/deps/v8/test/mjsunit/wasm/exceptions.js index 7d53037269a4f4..ecaf0d06c99662 100644 --- a/deps/v8/test/mjsunit/wasm/exceptions.js +++ b/deps/v8/test/mjsunit/wasm/exceptions.js @@ -14,7 +14,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("push_and_drop_exnref", kSig_v_v) .addLocals({except_count: 1}) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprDrop, ]).exportFunc(); let instance = builder.instantiate(); @@ -29,7 +29,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_v); builder.addFunction("throw_if_param_not_zero", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 0, kExprI32Ne, kExprIf, kWasmStmt, @@ -68,7 +68,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("simple_throw_catch_to_0_1", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, kExprThrow, except, @@ -99,12 +99,12 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprBlock, kWasmStmt, kExprTry, kWasmStmt, kExprTry, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, kExprThrow, except1, kExprElse, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Eq, kExprIf, kWasmStmt, @@ -149,12 +149,12 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprBlock, kWasmStmt, kExprBlock, kWasmStmt, kExprTry, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, kExprThrow, except1, kExprElse, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Eq, kExprIf, kWasmStmt, @@ -194,15 +194,15 @@ load("test/mjsunit/wasm/exceptions-utils.js"); .addBody([ kExprBlock, kWasmI32, kExprTry, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, kExprThrow, except, kExprEnd, kExprCatch, - kExprSetLocal, 1, + kExprLocalSet, 1, kExprI32Const, 23, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprBrOnExn, 1, except, kExprRethrow, kExprEnd, @@ -239,7 +239,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprI32Const, 2, kExprCatch, @@ -261,7 +261,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_i); builder.addFunction("throw_param", kSig_v_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, ]).exportFunc(); let instance = builder.instantiate(); @@ -278,7 +278,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_f_f) .addBody([ kExprTry, kWasmF32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprF32Const, 0, 0, 0, 0, kExprCatch, @@ -299,7 +299,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_f); builder.addFunction("throw_param", kSig_v_f) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, ]).exportFunc(); let instance = builder.instantiate(); @@ -316,18 +316,18 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_i_i) .addLocals({i64_count: 1}) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI64UConvertI32, - kExprSetLocal, 1, + kExprLocalSet, 1, kExprTry, kWasmI64, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprThrow, except, kExprI64Const, 23, kExprCatch, kExprBrOnExn, 0, except, kExprRethrow, kExprEnd, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64Eq, ]).exportFunc(); let instance = builder.instantiate(); @@ -344,11 +344,11 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_l); builder.addFunction("throw_param", kSig_v_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI64UConvertI32, kExprI64Const, 32, kExprI64Shl, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64UConvertI32, kExprI64Ior, kExprThrow, except, @@ -367,7 +367,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_catch_param", kSig_d_d) .addBody([ kExprTry, kWasmF64, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprF64Const, 0, 0, 0, 0, 0, 0, 0, 0, kExprCatch, @@ -388,7 +388,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let except = builder.addException(kSig_v_d); builder.addFunction("throw_param", kSig_v_f) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprF64ConvertF32, kExprThrow, except, ]).exportFunc(); @@ -406,10 +406,10 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("throw_expr_with_params", kSig_v_ddi) .addBody([ // p2 * (p0 + min(p0, p1))|0 - 20 - kExprGetLocal, 2, - kExprGetLocal, 0, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprF64Min, kExprF64Add, kExprI32SConvertF64, @@ -468,7 +468,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); let kWasmThrowFunction = builder.addFunction("throw", kSig_v_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, ]) .index; @@ -478,11 +478,11 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("same_scope", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 0, kExprI32Ne, kExprIf, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprUnreachable, kExprEnd, @@ -497,7 +497,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("same_scope_ignore", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprThrow, except, kExprUnreachable, kExprCatch, @@ -545,7 +545,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprTry, kWasmI32, kExprTry, kWasmI32, kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Eq, kExprIf, kWasmStmt, @@ -555,9 +555,9 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprEnd, kExprI32Const, 2, kExprCatch, - kExprSetLocal, 2, + kExprLocalSet, 2, kExprBlock, kWasmI32, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprBrOnExn, 0, except, kExprRethrow, kExprEnd, @@ -566,12 +566,12 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprThrow, except, kExprUnreachable, kExprEnd, - kExprTeeLocal, 1, - kExprGetLocal, 0, + kExprLocalTee, 1, + kExprLocalGet, 0, kExprI32Const, 2, kExprI32Eq, kExprIf, kWasmStmt, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI32Const, 8, kExprI32Ior, kExprThrow, except, @@ -580,9 +580,9 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprI32Const, 16, kExprI32Ior, kExprCatch, - kExprSetLocal, 2, + kExprLocalSet, 2, kExprBlock, kWasmI32, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprBrOnExn, 0, except, kExprRethrow, kExprEnd, @@ -591,12 +591,12 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprThrow, except, kExprUnreachable, kExprEnd, - kExprTeeLocal, 1, - kExprGetLocal, 0, + kExprLocalTee, 1, + kExprLocalGet, 0, kExprI32Const, 3, kExprI32Eq, kExprIf, kWasmStmt, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI32Const, /*64=*/ 192, 0, kExprI32Ior, kExprThrow, except, @@ -605,9 +605,9 @@ load("test/mjsunit/wasm/exceptions-utils.js"); kExprI32Const, /*128=*/ 128, 1, kExprI32Ior, kExprCatch, - kExprSetLocal, 2, + kExprLocalSet, 2, kExprBlock, kWasmI32, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprBrOnExn, 0, except, kExprRethrow, kExprEnd, @@ -621,7 +621,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("from_direct_callee", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, kWasmThrowFunction, kExprUnreachable, kExprCatch, @@ -637,8 +637,8 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("from_indirect_callee", kSig_i_ii) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprCallIndirect, sig_v_i, kTableZero, kExprUnreachable, kExprCatch, @@ -653,7 +653,7 @@ load("test/mjsunit/wasm/exceptions-utils.js"); builder.addFunction("i_from_js", kSig_i_i) .addBody([ kExprTry, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, kJSThrowI, kExprUnreachable, kExprCatch, diff --git a/deps/v8/test/mjsunit/wasm/export-mutable-global.js b/deps/v8/test/mjsunit/wasm/export-mutable-global.js index 1ce918c6cc903b..90238f3cf99b93 100644 --- a/deps/v8/test/mjsunit/wasm/export-mutable-global.js +++ b/deps/v8/test/mjsunit/wasm/export-mutable-global.js @@ -59,10 +59,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let global_builder = builder.addGlobal(type, true).exportAs(name); if (value) global_builder.init = value; builder.addFunction("get " + name, makeSig([], [type])) - .addBody([kExprGetGlobal, index]) + .addBody([kExprGlobalGet, index]) .exportFunc(); builder.addFunction("set " + name, makeSig([type], [])) - .addBody([kExprGetLocal, 0, kExprSetGlobal, index]) + .addBody([kExprLocalGet, 0, kExprGlobalSet, index]) .exportFunc(); } var instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/wasm/ffi-error.js b/deps/v8/test/mjsunit/wasm/ffi-error.js index 5f777ef1cf0ecb..217d7f3fd205fe 100644 --- a/deps/v8/test/mjsunit/wasm/ffi-error.js +++ b/deps/v8/test/mjsunit/wasm/ffi-error.js @@ -13,8 +13,8 @@ function CreateDefaultBuilder() { builder.addImport('mod', 'fun', sig_index); builder.addFunction('main', sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0, // -- ]) // -- .exportFunc(); @@ -76,7 +76,7 @@ function checkFailingInstantiation( let sig_index = kSig_i_dd; builder.addFunction('exp', kSig_i_i) .addBody([ - kExprGetLocal, + kExprLocalGet, 0, ]) // -- .exportFunc(); @@ -126,8 +126,8 @@ function checkFailingInstantiation( builder.addMemory(1, 1, true); builder.addFunction('function_with_invalid_signature', kSig_l_ll) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI64Sub]) // -- .exportFunc() @@ -144,7 +144,7 @@ function checkFailingInstantiation( builder.addMemory(1, 1, true); builder.addFunction('function_with_invalid_signature', kSig_i_l) - .addBody([kExprGetLocal, 0, kExprI32ConvertI64]) + .addBody([kExprLocalGet, 0, kExprI32ConvertI64]) .exportFunc(); checkSuccessfulInstantiation( @@ -163,7 +163,7 @@ function checkFailingInstantiation( let index = builder.addImport('', 'func', sig_i64_index); builder.addFunction('main', sig_index) .addBody([ - kExprGetLocal, 0, kExprI64SConvertI32, kExprCallFunction, index // -- + kExprLocalGet, 0, kExprI64SConvertI32, kExprCallFunction, index // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/ffi.js b/deps/v8/test/mjsunit/wasm/ffi.js index 72cc57f5983f17..884bd29450854c 100644 --- a/deps/v8/test/mjsunit/wasm/ffi.js +++ b/deps/v8/test/mjsunit/wasm/ffi.js @@ -13,8 +13,8 @@ function testCallFFI(func, check) { builder.addImport("", "func", sig_index); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0 // -- ]) // -- .exportFunc(); @@ -76,8 +76,8 @@ testCallFFI(bind_sub, check_FOREIGN_SUB); builder.addImport("", "func", sig_index); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0 // -- ]) // -- .exportFunc(); @@ -259,8 +259,8 @@ function testCallBinopVoid(type, func, check) { builder.addImport("", "func", makeSig_v_xx(type)); builder.addFunction("main", makeSig_r_xx(kWasmI32, type)) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0, // -- kExprI32Const, 33 // -- ]) // -- @@ -316,7 +316,7 @@ testCallBinopVoid(kWasmF64); .addBody([ kExprI32Const, 37, // -- kExprCallFunction, 0, // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallFunction, 1 // -- ]) // -- .exportFunc() diff --git a/deps/v8/test/mjsunit/wasm/float-constant-folding.js b/deps/v8/test/mjsunit/wasm/float-constant-folding.js index 6205da7cfc149f..332042e7febe4a 100644 --- a/deps/v8/test/mjsunit/wasm/float-constant-folding.js +++ b/deps/v8/test/mjsunit/wasm/float-constant-folding.js @@ -10,7 +10,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print("F32: sNaN - 0 = qNaN"); var builder = new WasmModuleBuilder(); builder.addFunction("F32Sub0", kSig_i_i).addBody( - [ kExprGetLocal, 0, kExprF32ReinterpretI32, kExprF32Const, 0x00, 0x00, + [ kExprLocalGet, 0, kExprF32ReinterpretI32, kExprF32Const, 0x00, 0x00, 0x00, 0x00, // 0.0 kExprF32Sub, kExprI32ReinterpretF32, ]).exportFunc(); var module = builder.instantiate(); @@ -23,7 +23,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); var builder = new WasmModuleBuilder(); builder.addFunction("F32Sub0", kSig_i_i).addBody( [ kExprF32Const, 0x00, 0x00, 0x00, 0x80, // 0.0 - kExprGetLocal, 0, kExprF32ReinterpretI32, kExprF32Sub, + kExprLocalGet, 0, kExprF32ReinterpretI32, kExprF32Sub, kExprI32ReinterpretF32, ]).exportFunc(); var module = builder.instantiate(); // F32Sub0(signalling_NaN) diff --git a/deps/v8/test/mjsunit/wasm/futex.js b/deps/v8/test/mjsunit/wasm/futex.js index 00353d48b0a546..d5bbf9ff1a99a1 100644 --- a/deps/v8/test/mjsunit/wasm/futex.js +++ b/deps/v8/test/mjsunit/wasm/futex.js @@ -14,8 +14,8 @@ function WasmAtomicNotify(memory, offset, index, num) { builder.addImportedMemory("m", "memory", 0, 20, "shared"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kAtomicPrefix, kExprAtomicNotify, /* alignment */ 0, offset]) .exportAs("main"); @@ -32,9 +32,9 @@ function WasmI32AtomicWait(memory, offset, index, val, timeout) { builder.addFunction("main", makeSig([kWasmI32, kWasmI32, kWasmF64], [kWasmI32])) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 2, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, kExprI64SConvertF64, kAtomicPrefix, kExprI32AtomicWait, /* alignment */ 0, offset]) @@ -56,17 +56,17 @@ function WasmI64AtomicWait(memory, offset, index, val_low, makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmF64], [kWasmI32])) .addLocals({i64_count: 1}) // local that is passed as value param to wait .addBody([ - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI64UConvertI32, kExprI64Const, 32, kExprI64Shl, - kExprGetLocal, 2, + kExprLocalGet, 2, kExprI64UConvertI32, kExprI64Ior, - kExprSetLocal, 4, // Store the created I64 value in local - kExprGetLocal, 0, - kExprGetLocal, 4, - kExprGetLocal, 3, + kExprLocalSet, 4, // Store the created I64 value in local + kExprLocalGet, 0, + kExprLocalGet, 4, + kExprLocalGet, 3, kExprI64SConvertF64, kAtomicPrefix, kExprI64AtomicWait, /* alignment */ 0, offset]) diff --git a/deps/v8/test/mjsunit/wasm/gc-buffer.js b/deps/v8/test/mjsunit/wasm/gc-buffer.js index d8aa9a86d84b56..c7fdbbc47c835c 100644 --- a/deps/v8/test/mjsunit/wasm/gc-buffer.js +++ b/deps/v8/test/mjsunit/wasm/gc-buffer.js @@ -14,7 +14,7 @@ function run(f) { builder.addImport("mod", "the_name_of_my_import", kSig_i_i); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .exportAs("main"); print("module"); diff --git a/deps/v8/test/mjsunit/wasm/gc-frame.js b/deps/v8/test/mjsunit/wasm/gc-frame.js index de8bdab51e5e0a..7d3b19741ac201 100644 --- a/deps/v8/test/mjsunit/wasm/gc-frame.js +++ b/deps/v8/test/mjsunit/wasm/gc-frame.js @@ -16,28 +16,28 @@ function makeFFI(func, t) { // the different parts of the stack. builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- - kExprGetLocal, 2, // -- - kExprGetLocal, 3, // -- - kExprGetLocal, 4, // -- - kExprGetLocal, 5, // -- - kExprGetLocal, 6, // -- - kExprGetLocal, 7, // -- - kExprGetLocal, 8, // -- - kExprGetLocal, 9, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- + kExprLocalGet, 2, // -- + kExprLocalGet, 3, // -- + kExprLocalGet, 4, // -- + kExprLocalGet, 5, // -- + kExprLocalGet, 6, // -- + kExprLocalGet, 7, // -- + kExprLocalGet, 8, // -- + kExprLocalGet, 9, // -- kExprCallFunction, 0, // -- kExprDrop, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- - kExprGetLocal, 2, // -- - kExprGetLocal, 3, // -- - kExprGetLocal, 4, // -- - kExprGetLocal, 5, // -- - kExprGetLocal, 6, // -- - kExprGetLocal, 7, // -- - kExprGetLocal, 8, // -- - kExprGetLocal, 9, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- + kExprLocalGet, 2, // -- + kExprLocalGet, 3, // -- + kExprLocalGet, 4, // -- + kExprLocalGet, 5, // -- + kExprLocalGet, 6, // -- + kExprLocalGet, 7, // -- + kExprLocalGet, 8, // -- + kExprLocalGet, 9, // -- kExprCallFunction, 0, // -- ]) // -- .exportFunc(); @@ -79,7 +79,7 @@ function print10(a, b, c, d, e, f, g, h, i) { var sig_index = builder.addType(kSig_i_i); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/gc-memory.js b/deps/v8/test/mjsunit/wasm/gc-memory.js new file mode 100644 index 00000000000000..31e96f8be3fff2 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/gc-memory.js @@ -0,0 +1,41 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +let kPageSize = 65536; + +function allocMems(count, initial, maximum) { + print(`alloc ${count}`); + let result = []; + for (let i = 0; i < count; i++) { + print(` memory #${i} (initial=${initial}, maximum=${maximum})...`); + result.push(new WebAssembly.Memory({initial: initial, maximum: maximum})); + } + return result; +} + +function check(mems, initial) { + for (m of mems) { + assertEquals(initial * kPageSize, m.buffer.byteLength); + } +} + +function test(count, initial, maximum) { + let mems = allocMems(count, initial, maximum); + check(mems, initial); +} + +test(1, 1, 1); +test(1, 1, 2); +test(1, 1, 3); +test(1, 1, 4); + +test(2, 1, 1); +test(2, 1, 2); +test(2, 1, 3); +test(2, 1, 4); + +test(1, 1, undefined); +test(2, 1, undefined); +test(3, 1, undefined); +test(4, 1, undefined); diff --git a/deps/v8/test/mjsunit/wasm/gc-stress.js b/deps/v8/test/mjsunit/wasm/gc-stress.js index 8daff420daeedf..55a780d3ec4533 100644 --- a/deps/v8/test/mjsunit/wasm/gc-stress.js +++ b/deps/v8/test/mjsunit/wasm/gc-stress.js @@ -11,7 +11,7 @@ function run(f) { builder.addImport("m", "f", kSig_i_i); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .exportAs("main"); diff --git a/deps/v8/test/mjsunit/wasm/globals.js b/deps/v8/test/mjsunit/wasm/globals.js index b29993a8fcc58d..a72bc118c7c2e9 100644 --- a/deps/v8/test/mjsunit/wasm/globals.js +++ b/deps/v8/test/mjsunit/wasm/globals.js @@ -15,12 +15,12 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let sig_index = builder.addType(kSig_i_v); builder.addFunction("get", sig_index) .addBody([ - kExprGetGlobal, g.index]) + kExprGlobalGet, g.index]) .exportAs("get"); builder.addFunction("set", kSig_v_i) .addBody([ - kExprGetLocal, 0, - kExprSetGlobal, g.index]) + kExprLocalGet, 0, + kExprGlobalSet, g.index]) .exportAs("set"); let module = new WebAssembly.Module(builder.toBuffer()); @@ -54,7 +54,7 @@ function TestImported(type, val, expected) { var sig = makeSig([], [type]); var g = builder.addImportedGlobal("uuu", "foo", type); builder.addFunction("main", sig) - .addBody([kExprGetGlobal, g]) + .addBody([kExprGlobalGet, g]) .exportAs("main"); builder.addGlobal(kWasmI32); // pad @@ -76,7 +76,7 @@ TestImported(kWasmF64, 77777.88888, 77777.88888); let sig_index = builder.addType(kSig_i_v); builder.addFunction("main", sig_index) .addBody([ - kExprGetGlobal, g]) + kExprGlobalGet, g]) .exportAs("main"); let module = new WebAssembly.Module(builder.toBuffer()); @@ -152,7 +152,7 @@ function TestGlobalIndexSpace(type, val) { var sig = makeSig([], [type]); builder.addFunction("main", sig) - .addBody([kExprGetGlobal, def.index]) + .addBody([kExprGlobalGet, def.index]) .exportAs("main"); var instance = builder.instantiate({nnn: {foo: val}}); @@ -173,22 +173,22 @@ TestGlobalIndexSpace(kWasmF64, 12345.678); let sig_index = builder.addType(kSig_i_i); builder.addFunction("get", sig_index) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprIf, kWasmI32, - kExprGetGlobal, g.index, + kExprGlobalGet, g.index, kExprElse, - kExprGetGlobal, h.index, + kExprGlobalGet, h.index, kExprEnd]) .exportAs("get"); builder.addFunction("set", kSig_v_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprIf, kWasmStmt, - kExprGetLocal, 1, - kExprSetGlobal, g.index, + kExprLocalGet, 1, + kExprGlobalSet, g.index, kExprElse, - kExprGetLocal, 1, - kExprSetGlobal, h.index, + kExprLocalGet, 1, + kExprGlobalSet, h.index, kExprEnd]) .exportAs("set"); diff --git a/deps/v8/test/mjsunit/wasm/graceful_shutdown.js b/deps/v8/test/mjsunit/wasm/graceful_shutdown.js index aa50e6cf770467..0f55b795c15073 100644 --- a/deps/v8/test/mjsunit/wasm/graceful_shutdown.js +++ b/deps/v8/test/mjsunit/wasm/graceful_shutdown.js @@ -14,7 +14,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); for (i = 0; i < 100; i++) { builder.addFunction("sub" + i, kSig_i_i) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32Const, i % 61, // -- kExprI32Sub]) // -- .exportFunc() diff --git a/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js b/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js index 17c6803784f8f4..f615602a8ef232 100644 --- a/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js +++ b/deps/v8/test/mjsunit/wasm/graceful_shutdown_during_tierup.js @@ -14,7 +14,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); for (i = 0; i < 100; i++) { builder.addFunction("sub" + i, kSig_i_i) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32Const, i % 61, // -- kExprI32Sub]) // -- .exportFunc() diff --git a/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js b/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js index 9ab2334a6315f5..b22844970383c6 100644 --- a/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js +++ b/deps/v8/test/mjsunit/wasm/grow-memory-detaching.js @@ -10,7 +10,7 @@ let module = (() => { let builder = new WasmModuleBuilder(); builder.addMemory(1, undefined, false); builder.addFunction("grow_memory", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); builder.exportMemoryAs("memory"); return builder.toModule(); diff --git a/deps/v8/test/mjsunit/wasm/grow-memory-in-branch.js b/deps/v8/test/mjsunit/wasm/grow-memory-in-branch.js index 93bb56d83da812..8babc66b758158 100644 --- a/deps/v8/test/mjsunit/wasm/grow-memory-in-branch.js +++ b/deps/v8/test/mjsunit/wasm/grow-memory-in-branch.js @@ -13,12 +13,12 @@ function generateBuilder() { let builder = new WasmModuleBuilder(); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); builder.addFunction('load', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction('store', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, - kExprI32StoreMem, 0, 0, kExprGetLocal, 1 + kExprLocalGet, 0, kExprLocalGet, 1, + kExprI32StoreMem, 0, 0, kExprLocalGet, 1 ]) .exportFunc(); return builder; @@ -32,7 +32,7 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPages, // put deltaPages on stack kExprMemoryGrow, kMemoryZero, // grow memory @@ -59,7 +59,7 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPages, // put deltaPages on stack kExprMemoryGrow, kMemoryZero, // grow memory @@ -94,7 +94,7 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, index, // put index on stack kExprI32Const, newValue, // put the value on stack @@ -127,7 +127,7 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPagesIf, // put deltaPagesIf on stack kExprMemoryGrow, kMemoryZero, // grow memory @@ -159,16 +159,16 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPages, // put deltaPages on stack kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, value, // put the value on stack kExprI32StoreMem, 0, 0, // store kExprEnd, - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32LoadMem, 0, 0 // load from grown memory ]) .exportFunc(); @@ -191,20 +191,20 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPages, // put deltaPages on stack kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, value, // put the value on stack kExprI32StoreMem, 0, 0, // store kExprElse, - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, value, // put the value on stack kExprI32StoreMem, 0, 0, // store kExprEnd, - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32LoadMem, 0, 0 // load from grown memory ]) .exportFunc(); @@ -226,20 +226,20 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, value, // put the value on stack kExprI32StoreMem, 0, 0, // store kExprElse, kExprI32Const, deltaPages, // put deltaPages on stack kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, value, // put the value on stack kExprI32StoreMem, 0, 0, // store kExprEnd, - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32LoadMem, 0, 0 // load from grown memory ]) .exportFunc(); @@ -263,23 +263,23 @@ function generateBuilder() { let builder = generateBuilder(); builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 0, // get condition parameter + kExprLocalGet, 0, // get condition parameter kExprIf, kWasmStmt, // if it's 1 then enter if kExprI32Const, deltaPagesIf, // put deltaPagesIf on stack kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, valueIf, // put valueIf on stack kExprI32StoreMem, 0, 0, // store kExprElse, kExprI32Const, deltaPagesElse, // put deltaPagesElse on stack kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32Const, valueElse, // put valueElse on stack kExprI32StoreMem, 0, 0, // store kExprEnd, - kExprGetLocal, 1, // get index parameter + kExprLocalGet, 1, // get index parameter kExprI32LoadMem, 0, 0 // load from grown memory ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/grow-memory-in-call.js b/deps/v8/test/mjsunit/wasm/grow-memory-in-call.js index 1790f9760f5ca5..7940ab5f19d5cf 100644 --- a/deps/v8/test/mjsunit/wasm/grow-memory-in-call.js +++ b/deps/v8/test/mjsunit/wasm/grow-memory-in-call.js @@ -20,12 +20,12 @@ print('=== grow_memory in direct calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // get number of new pages + kExprLocalGet, 0, // get number of new pages kExprCallFunction, kGrowFunction, // call the grow function kExprDrop, // drop the result of grow kExprMemorySize, kMemoryZero // get the memory size @@ -47,19 +47,19 @@ print('=== grow_memory in direct calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('load', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction('main', kSig_v_iii) .addBody([ - kExprGetLocal, 0, // get number of new pages + kExprLocalGet, 0, // get number of new pages kExprCallFunction, kGrowFunction, // call the grow function kExprDrop, // drop the result of grow - kExprGetLocal, 1, // get index - kExprGetLocal, 2, // get value + kExprLocalGet, 1, // get index + kExprLocalGet, 2, // get value kExprI32StoreMem, 0, 0 // store ]) .exportFunc(); @@ -118,24 +118,24 @@ print('=== grow_memory in direct calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('main', kSig_i_ii) .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. - kExprGetLocal, 1, // get number of new pages + kExprLocalGet, 1, // get number of new pages kExprCallFunction, kGrowFunction, // call the grow function kExprDrop, // drop the result of grow // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop @@ -161,13 +161,13 @@ print('=== grow_memory in direct calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); builder.addFunction('store', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1 + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1 ]) .exportFunc(); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; // parameters: iterations, deltaPages, index @@ -175,29 +175,29 @@ print('=== grow_memory in direct calls ==='); .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. - kExprGetLocal, 1, // get number of new pages + kExprLocalGet, 1, // get number of new pages kExprCallFunction, kGrowFunction, // call the grow function kExprDrop, // drop the result of grow // Increase counter in memory. - kExprGetLocal, 2, // put index (for store) - kExprGetLocal, 2, // put index (for load) + kExprLocalGet, 2, // put index (for store) + kExprLocalGet, 2, // put index (for load) kExprI32LoadMem, 0, 0, // load from grown memory kExprI32Const, 1, // - kExprI32Add, // increase counter kExprI32StoreMem, 0, 0, // store counter in memory // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop // Return the value - kExprGetLocal, 2, // - + kExprLocalGet, 2, // - kExprI32LoadMem, 0, 0 // load from grown memory // clang-format on ]) @@ -225,13 +225,13 @@ print('\n=== grow_memory in indirect calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 1, // get number of new pages - kExprGetLocal, 0, // get index of the function + kExprLocalGet, 1, // get number of new pages + kExprLocalGet, 0, // get index of the function kExprCallIndirect, 0, kTableZero, // call the function kExprDrop, // drop the result of grow kExprMemorySize, kMemoryZero // get the memory size @@ -255,21 +255,21 @@ print('\n=== grow_memory in indirect calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('load', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); let sig = makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], []); builder.addFunction('main', sig) .addBody([ - kExprGetLocal, 1, // get number of new pages - kExprGetLocal, 0, // get index of the function + kExprLocalGet, 1, // get number of new pages + kExprLocalGet, 0, // get index of the function kExprCallIndirect, 0, kTableZero, // call the function kExprDrop, // drop the result of grow - kExprGetLocal, 2, // get index - kExprGetLocal, 3, // get value + kExprLocalGet, 2, // get index + kExprLocalGet, 3, // get value kExprI32StoreMem, 0, 0 // store ]) .exportFunc(); @@ -311,7 +311,7 @@ print('\n=== grow_memory in indirect calls ==='); kExprI32Const, index, // put index on stack kExprI32Const, oldValue, // put old value on stack kExprI32StoreMem, 0, 0, // store - kExprGetLocal, 0, // get index of the function + kExprLocalGet, 0, // get index of the function kExprCallIndirect, 0, kTableZero, // call the function kExprI32Const, index, // put index on stack kExprI32LoadMem, 0, 0 // load from grown memory @@ -332,25 +332,25 @@ print('\n=== grow_memory in indirect calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('main', kSig_i_iii) .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 1, // - + kExprLocalGet, 1, // - kExprIf, kWasmStmt, // if <param1> != 0 // Grow memory. - kExprGetLocal, 2, // get number of new pages - kExprGetLocal, 0, // get index of the function + kExprLocalGet, 2, // get number of new pages + kExprLocalGet, 0, // get index of the function kExprCallIndirect, 0, kTableZero, // call the function kExprDrop, // drop the result of grow // Decrease loop variable. - kExprGetLocal, 1, // - + kExprLocalGet, 1, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 1, // decrease <param1> + kExprLocalSet, 1, // decrease <param1> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop @@ -378,13 +378,13 @@ print('\n=== grow_memory in indirect calls ==='); builder.addMemory(initialMemoryPages, maximumMemoryPages, true); let kGrowFunction = builder.addFunction('grow', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc() .index; builder.addFunction('store', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1 + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1 ]) .exportFunc(); builder @@ -394,30 +394,30 @@ print('\n=== grow_memory in indirect calls ==='); .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 1, // - + kExprLocalGet, 1, // - kExprIf, kWasmStmt, // if <param1> != 0 // Grow memory. - kExprGetLocal, 2, // get number of new pages - kExprGetLocal, 0, // get index of the function + kExprLocalGet, 2, // get number of new pages + kExprLocalGet, 0, // get index of the function kExprCallIndirect, 0, kTableZero, // call the function kExprDrop, // drop the result of grow // Increase counter in memory. - kExprGetLocal, 3, // put index (for store) - kExprGetLocal, 3, // put index (for load) + kExprLocalGet, 3, // put index (for store) + kExprLocalGet, 3, // put index (for load) kExprI32LoadMem, 0, 0, // load from grown memory kExprI32Const, 1, // - kExprI32Add, // increase counter kExprI32StoreMem, 0, 0, // store counter in memory // Decrease loop variable. - kExprGetLocal, 1, // - + kExprLocalGet, 1, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 1, // decrease <param1> + kExprLocalSet, 1, // decrease <param1> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop // Return the value - kExprGetLocal, 3, // - + kExprLocalGet, 3, // - kExprI32LoadMem, 0, 0 // load from grown memory // clang-format on ]) diff --git a/deps/v8/test/mjsunit/wasm/grow-memory-in-loop.js b/deps/v8/test/mjsunit/wasm/grow-memory-in-loop.js index ed04e23c636f7a..143b555b17b9da 100644 --- a/deps/v8/test/mjsunit/wasm/grow-memory-in-loop.js +++ b/deps/v8/test/mjsunit/wasm/grow-memory-in-loop.js @@ -14,8 +14,8 @@ function generateBuilder() { builder.addMemory(initialPages, maximumPages, true); builder.addFunction('store', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1 + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1 ]) .exportFunc(); return builder; @@ -31,17 +31,17 @@ function generateBuilder() { .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. kExprI32Const, deltaPages, // - kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop @@ -83,17 +83,17 @@ function generateBuilder() { kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. kExprI32Const, deltaPagesIn, // - kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop @@ -132,29 +132,29 @@ function generateBuilder() { .addBody([ // clang-format off kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. kExprI32Const, deltaPages, // - kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow // Increase counter in memory. - kExprGetLocal, 1, // put index (for store) - kExprGetLocal, 1, // put index (for load) + kExprLocalGet, 1, // put index (for store) + kExprLocalGet, 1, // put index (for load) kExprI32LoadMem, 0, 0, // load from grown memory kExprI32Const, 1, // - kExprI32Add, // increase counter kExprI32StoreMem, 0, 0, // store counter in memory // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop // Increase counter in memory. - kExprGetLocal, 1, // - + kExprLocalGet, 1, // - kExprI32LoadMem, 0, 0 // load from grown memory // clang-format on ]) @@ -195,37 +195,37 @@ function generateBuilder() { kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow // Increase counter in memory. - kExprGetLocal, 1, // put index (for store) - kExprGetLocal, 1, // put index (for load) + kExprLocalGet, 1, // put index (for store) + kExprLocalGet, 1, // put index (for load) kExprI32LoadMem, 0, 0, // load from grown memory kExprI32Const, 1, // - kExprI32Add, // increase value on stack kExprI32StoreMem, 0, 0, // store new value // Start loop. kExprLoop, kWasmStmt, // while - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprIf, kWasmStmt, // if <param0> != 0 // Grow memory. kExprI32Const, deltaPagesIn, // - kExprMemoryGrow, kMemoryZero, // grow memory kExprDrop, // drop the result of grow // Increase counter in memory. - kExprGetLocal, 1, // put index (for store) - kExprGetLocal, 1, // put index (for load) + kExprLocalGet, 1, // put index (for store) + kExprLocalGet, 1, // put index (for load) kExprI32LoadMem, 0, 0, // load from grown memory kExprI32Const, 1, // - kExprI32Add, // increase value on stack kExprI32StoreMem, 0, 0, // store new value // Decrease loop variable. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Sub, // - - kExprSetLocal, 0, // decrease <param0> + kExprLocalSet, 0, // decrease <param0> kExprBr, 1, // continue kExprEnd, // end if kExprEnd, // end loop // Return counter from memory. - kExprGetLocal, 1, // put index on stack + kExprLocalGet, 1, // put index on stack kExprI32LoadMem, 0, 0 // load from grown memory // clang-format on ]) diff --git a/deps/v8/test/mjsunit/wasm/grow-memory.js b/deps/v8/test/mjsunit/wasm/grow-memory.js index 0e5618a2b15b96..6d0e7e5c5f3b16 100644 --- a/deps/v8/test/mjsunit/wasm/grow-memory.js +++ b/deps/v8/test/mjsunit/wasm/grow-memory.js @@ -10,28 +10,28 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); function genMemoryGrowBuilder() { var builder = new WasmModuleBuilder(); builder.addFunction("grow_memory", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1]) .exportFunc(); builder.addFunction("load16", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem16U, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem16U, 0, 0]) .exportFunc(); builder.addFunction("store16", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem16, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem16, 0, 0, + kExprLocalGet, 1]) .exportFunc(); builder.addFunction("load8", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem8U, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem8U, 0, 0]) .exportFunc(); builder.addFunction("store8", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem8, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem8, 0, 0, + kExprLocalGet, 1]) .exportFunc(); return builder; } diff --git a/deps/v8/test/mjsunit/wasm/grow-shared-memory.js b/deps/v8/test/mjsunit/wasm/grow-shared-memory.js index bbd180b39cf57b..3c9d72b499c072 100644 --- a/deps/v8/test/mjsunit/wasm/grow-shared-memory.js +++ b/deps/v8/test/mjsunit/wasm/grow-shared-memory.js @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(v8:8832): Enable --stress-opt on these tests -// Flags: --wasm-grow-shared-memory -// Flags: --experimental-wasm-threads --no-stress-opt +// Flags: --wasm-grow-shared-memory --experimental-wasm-threads load("test/mjsunit/wasm/wasm-module-builder.js"); @@ -137,7 +135,7 @@ let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString(); var builder = new WasmModuleBuilder(); builder.addImportedMemory("m", "memory", 5, 100, "shared"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); let obj = {memory: memory, module: module}; @@ -169,7 +167,7 @@ let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString(); var builder = new WasmModuleBuilder(); builder.addImportedMemory("m", "memory", 5, 100, "shared"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); let obj = {memory: memory, module: module}; @@ -200,10 +198,10 @@ let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString(); var builder = new WasmModuleBuilder(); builder.addImportedMemory("m", "memory", 5, 100, "shared"); builder.addFunction("grow_twice", kSig_i_i) - .addBody([kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero, kExprDrop, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); @@ -239,10 +237,10 @@ let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString(); var builder = new WasmModuleBuilder(); builder.addImportedMemory("m", "memory", 5, 100, "shared"); builder.addFunction("grow_and_size", kSig_i_i) - .addBody([kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero, kExprDrop, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero, kExprDrop, kExprMemorySize, kMemoryZero]) @@ -298,13 +296,13 @@ let workerHelpers = assertTrue.toString() + assertIsWasmSharedMemory.toString(); var builder = new WasmModuleBuilder(); builder.addImportedMemory("m", "memory", 5, 100, "shared"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); builder.addFunction("atomic_load", kSig_i_i) - .addBody([kExprGetLocal, 0, kAtomicPrefix, kExprI32AtomicLoad, 2, 0]) + .addBody([kExprLocalGet, 0, kAtomicPrefix, kExprI32AtomicLoad, 2, 0]) .exportFunc(); builder.addFunction("atomic_store", kSig_v_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kAtomicPrefix, kExprI32AtomicStore, 2, 0]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); diff --git a/deps/v8/test/mjsunit/wasm/huge-memory.js b/deps/v8/test/mjsunit/wasm/huge-memory.js index bf037b0c9297fa..6c145d70cb8492 100644 --- a/deps/v8/test/mjsunit/wasm/huge-memory.js +++ b/deps/v8/test/mjsunit/wasm/huge-memory.js @@ -16,8 +16,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addMemory(num_pages, num_pages, true); builder.addFunction("geti", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Mul, kExprI32LoadMem, 0, 0, ]) diff --git a/deps/v8/test/mjsunit/wasm/import-function.js b/deps/v8/test/mjsunit/wasm/import-function.js index ec187aff4a04d4..6bbad8a2221100 100644 --- a/deps/v8/test/mjsunit/wasm/import-function.js +++ b/deps/v8/test/mjsunit/wasm/import-function.js @@ -13,8 +13,8 @@ function testCallImport(func, check) { builder.addImport("q", "func", sig_index); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0]) // -- .exportAs("main"); @@ -186,8 +186,8 @@ function testCallBinopVoid(type, func, check) { builder.addImport("q", "func", makeSig_v_xx(type)); builder.addFunction("main", makeSig_r_xx(kWasmI32, type)) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0, // -- kExprI32Const, 39, // -- ]) @@ -244,7 +244,7 @@ function testCallPrint() { .addBody([ kExprI32Const, 27, // -- kExprCallFunction, 0, // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallFunction, 1 // -- ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/import-memory.js b/deps/v8/test/mjsunit/wasm/import-memory.js index fc688dc7ce81fa..08100efabdbed3 100644 --- a/deps/v8/test/mjsunit/wasm/import-memory.js +++ b/deps/v8/test/mjsunit/wasm/import-memory.js @@ -51,7 +51,7 @@ var kV8MaxPages = 32767; builder.exportMemoryAs("exported_mem"); builder.addFunction("foo", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportAs("foo"); i1 = builder.instantiate(); @@ -63,7 +63,7 @@ var kV8MaxPages = 32767; builder.addImportedMemory("fil", "imported_mem"); builder.addFunction("bar", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportAs("bar"); i2 = builder.instantiate({fil: {imported_mem: i1.exports.exported_mem}}); @@ -89,11 +89,11 @@ var kV8MaxPages = 32767; let builder = new WasmModuleBuilder(); builder.addImportedMemory("gaz", "mine"); builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1]) .exportFunc(); var offset; let instance = builder.instantiate({gaz: {mine: memory}}); @@ -119,11 +119,11 @@ var kV8MaxPages = 32767; let builder = new WasmModuleBuilder(); builder.addImportedMemory("mine", "dog", 0, 20); builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1]) .exportFunc(); var offset; let instance = builder.instantiate({mine: {dog: memory}}); @@ -157,11 +157,11 @@ var kV8MaxPages = 32767; let builder = new WasmModuleBuilder(); builder.addImportedMemory("mine", "fro"); builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1]) .exportFunc(); var offset; let instance = builder.instantiate({mine: {fro: memory}}); @@ -187,7 +187,7 @@ var kV8MaxPages = 32767; assertEquals(2*kPageSize, memory.buffer.byteLength); let builder = new WasmModuleBuilder(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); builder.addImportedMemory("cat", "mine"); let instance = builder.instantiate({cat: {mine: memory}}); @@ -217,7 +217,7 @@ var kV8MaxPages = 32767; .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); instance = builder.instantiate({fur: { imported_mem: exp_instance.exports.exported_mem}}); @@ -238,7 +238,7 @@ var kV8MaxPages = 32767; .addBody([kExprMemorySize, kMemoryZero]) .exportAs("mem_size"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); var instances = []; @@ -279,7 +279,7 @@ var kV8MaxPages = 32767; .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var instances = []; for (var i = 0; i < 5; i++) { @@ -344,7 +344,7 @@ var kV8MaxPages = 32767; .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var instances = []; for (var i = 0; i < 10; i++) { @@ -379,7 +379,7 @@ var kV8MaxPages = 32767; builder.addMemory(1, kSpecMaxPages, true); builder.exportMemoryAs("exported_mem"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); instance_1 = builder.instantiate(); } @@ -387,7 +387,7 @@ var kV8MaxPages = 32767; let builder = new WasmModuleBuilder(); builder.addImportedMemory("doo", "imported_mem"); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); instance_2 = builder.instantiate({ doo: {imported_mem: instance_1.exports.exported_mem}}); @@ -407,7 +407,7 @@ var kV8MaxPages = 32767; .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); instance = builder.instantiate(); assertEquals(kPageSize, instance.exports.exported_mem.buffer.byteLength); diff --git a/deps/v8/test/mjsunit/wasm/import-mutable-global.js b/deps/v8/test/mjsunit/wasm/import-mutable-global.js index 715549a41f223f..70ce50be003695 100644 --- a/deps/v8/test/mjsunit/wasm/import-mutable-global.js +++ b/deps/v8/test/mjsunit/wasm/import-mutable-global.js @@ -11,7 +11,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let builder = new WasmModuleBuilder(); builder.addImportedGlobal("mod", "g", kWasmI32); builder.addFunction("main", kSig_i_v) - .addBody([kExprGetGlobal, 0]) + .addBody([kExprGlobalGet, 0]) .exportAs("main"); let main = builder.instantiate({mod: {g: global}}).exports.main; @@ -54,10 +54,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); function addGlobalGetterAndSetter(builder, index, name, type) { builder.addFunction('get' + name, makeSig([], [type])) - .addBody([kExprGetGlobal, index]) + .addBody([kExprGlobalGet, index]) .exportFunc(); builder.addFunction('set' + name, makeSig([type], [])) - .addBody([kExprGetLocal, 0, kExprSetGlobal, index]) + .addBody([kExprLocalGet, 0, kExprGlobalSet, index]) .exportFunc(); } @@ -137,20 +137,20 @@ function addGlobalGetterAndSetter(builder, index, name, type) { const index = 0; builder.addFunction('geti64_hi', makeSig([], [kWasmI32])) .addBody([ - kExprGetGlobal, index, + kExprGlobalGet, index, kExprI64Const, 32, kExprI64ShrU, kExprI32ConvertI64]) .exportFunc(); builder.addFunction('geti64_lo', makeSig([], [kWasmI32])) - .addBody([kExprGetGlobal, index, kExprI32ConvertI64]) + .addBody([kExprGlobalGet, index, kExprI32ConvertI64]) .exportFunc(); builder.addFunction("seti64", makeSig([kWasmI32, kWasmI32], [])) .addBody([ - kExprGetLocal, 1, kExprI64UConvertI32, - kExprGetLocal, 0, kExprI64UConvertI32, + kExprLocalGet, 1, kExprI64UConvertI32, + kExprLocalGet, 0, kExprI64UConvertI32, kExprI64Const, 32, kExprI64Shl, kExprI64Ior, - kExprSetGlobal, index]) + kExprGlobalSet, index]) .exportFunc(); }; diff --git a/deps/v8/test/mjsunit/wasm/import-table.js b/deps/v8/test/mjsunit/wasm/import-table.js index 098d03d4d62dce..6693559c8f5127 100644 --- a/deps/v8/test/mjsunit/wasm/import-table.js +++ b/deps/v8/test/mjsunit/wasm/import-table.js @@ -34,7 +34,7 @@ let kTableSize = 50; let f15 = addConstFunc(builder, 15); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); @@ -57,7 +57,7 @@ let kTableSize = 50; let f21 = addConstFunc(builder, 21); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); @@ -92,7 +92,7 @@ function addConstFuncUsingGlobal(builder, val) { let g = builder.addGlobal(kWasmI32, false); g.init = val; return builder.addFunction("global" + val, kSig_i_v) - .addBody([kExprGetGlobal, g.index]).index; + .addBody([kExprGlobalGet, g.index]).index; } (function TestAliasedImportedTableInstanceGlobals() { @@ -106,7 +106,7 @@ function addConstFuncUsingGlobal(builder, val) { let f14 = addConstFuncUsingGlobal(builder, 14); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); @@ -129,7 +129,7 @@ function addConstFuncUsingGlobal(builder, val) { let f22 = addConstFuncUsingGlobal(builder, 22); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); @@ -186,7 +186,7 @@ function addConstFuncUsingMemory(builder, val) { let f13 = addConstFuncUsingMemory(builder, 13); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); @@ -211,7 +211,7 @@ function addConstFuncUsingMemory(builder, val) { let f23 = addConstFuncUsingMemory(builder, 23); let call = builder.addFunction("call", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, signums.i_v, kTableZero ]) .exportAs("call"); diff --git a/deps/v8/test/mjsunit/wasm/indirect-call-non-zero-table.js b/deps/v8/test/mjsunit/wasm/indirect-call-non-zero-table.js index 414ca19c9954db..69fb4dcf437cfa 100644 --- a/deps/v8/test/mjsunit/wasm/indirect-call-non-zero-table.js +++ b/deps/v8/test/mjsunit/wasm/indirect-call-non-zero-table.js @@ -41,28 +41,28 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); .index; builder.addFunction('call1', kSig_i_i) - .addBody([kExprGetLocal, 0, // function index + .addBody([kExprLocalGet, 0, // function index kExprCallIndirect, sig_index, table1]) .exportAs('call1'); builder.addFunction('return_call1', kSig_i_i) - .addBody([kExprGetLocal, 0, // function index + .addBody([kExprLocalGet, 0, // function index kExprReturnCallIndirect, sig_index, table1]) .exportAs('return_call1'); builder.addFunction('call2', kSig_i_i) - .addBody([kExprGetLocal, 0, // function index + .addBody([kExprLocalGet, 0, // function index kExprCallIndirect, sig_index, table2]) .exportAs('call2'); builder.addFunction('return_call2', kSig_i_i) - .addBody([kExprGetLocal, 0, // function index + .addBody([kExprLocalGet, 0, // function index kExprReturnCallIndirect, sig_index, table2]) .exportAs('return_call2'); builder.addFunction('call_invalid_sig', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprGetLocal, 0, // function index + param + .addBody([kExprLocalGet, 0, kExprLocalGet, 0, // function index + param kExprCallIndirect, other_sig, table2]) .exportAs('call_invalid_sig'); builder.addFunction('return_call_invalid_sig', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprGetLocal, 0, // function index + param + .addBody([kExprLocalGet, 0, kExprLocalGet, 0, // function index + param kExprReturnCallIndirect, other_sig, table2]) .exportAs('return_call_invalid_sig'); @@ -119,10 +119,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); const sig_index = builder.addType(kSig_i_v); const f1 = builder.addFunction("foo", sig_index) - .addBody([kExprGetGlobal, g, kExprI32Const, 12, kExprI32Add]); + .addBody([kExprGlobalGet, g, kExprI32Const, 12, kExprI32Add]); builder.addFunction('call', kSig_i_i) - .addBody([kExprGetLocal, 0, // function index + .addBody([kExprLocalGet, 0, // function index kExprCallIndirect, sig_index, t1]) .exportAs('call'); @@ -167,14 +167,14 @@ function js_div(a, b) { return (a / b) | 0; } let sig_index = builder.addType(kSig_i_ii); builder.addFunction("placeholder", sig_index) - .addBody([kExprGetLocal, 0]); + .addBody([kExprLocalGet, 0]); builder.addElementSegment(table_index, g, true, [div]); builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 55, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, table_index]) // -- .exportAs("main"); diff --git a/deps/v8/test/mjsunit/wasm/indirect-calls.js b/deps/v8/test/mjsunit/wasm/indirect-calls.js index e9f560a01988cb..603d7561ece489 100644 --- a/deps/v8/test/mjsunit/wasm/indirect-calls.js +++ b/deps/v8/test/mjsunit/wasm/indirect-calls.js @@ -15,20 +15,20 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addImport("q", "add", sig_index); var f = builder.addFunction("add", sig_index) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, 0 + kExprLocalGet, 0, kExprLocalGet, 1, kExprCallFunction, 0 ]); print("internal add index = " + f.index); builder.addFunction("sub", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Sub, // -- ]); builder.addFunction("main", kSig_i_iii) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprCallIndirect, sig_index, kTableZero ]) .exportFunc() @@ -68,20 +68,20 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); var mul = builder.addImport("q", "mul", sig_i_ii); var add = builder.addFunction("add", sig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Add // -- ]); var popcnt = builder.addFunction("popcnt", sig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32Popcnt // -- ]); var main = builder.addFunction("main", kSig_i_iii) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprCallIndirect, sig_i_ii, kTableZero ]) .exportFunc(); @@ -106,20 +106,20 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); function AddFunctions(builder) { var mul = builder.addFunction("mul", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Mul // -- ]); var add = builder.addFunction("add", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Add // -- ]); var sub = builder.addFunction("sub", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Sub // -- ]); return {mul: mul, add: add, sub: sub}; @@ -135,8 +135,8 @@ function AddFunctions(builder) { builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -163,8 +163,8 @@ function AddFunctions(builder) { builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -200,8 +200,8 @@ function AddFunctions(builder) { builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); diff --git a/deps/v8/test/mjsunit/wasm/indirect-sig-mismatch.js b/deps/v8/test/mjsunit/wasm/indirect-sig-mismatch.js index 9e8ddac1c58953..ea148c50877500 100644 --- a/deps/v8/test/mjsunit/wasm/indirect-sig-mismatch.js +++ b/deps/v8/test/mjsunit/wasm/indirect-sig-mismatch.js @@ -65,14 +65,14 @@ function caller_module() { builder.addFunction("call1", sig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_i_v, kTableZero]) // -- .exportAs("call1"); builder.addFunction("call2", sig_i_i) .addBody([ kExprI32Const, 11, // -- - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_i_i, kTableZero]) // -- .exportAs("call2"); @@ -80,7 +80,7 @@ function caller_module() { .addBody([ kExprI32Const, 21, kExprI32Const, 22, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_i_ii, kTableZero]) // -- .exportAs("call3"); diff --git a/deps/v8/test/mjsunit/wasm/indirect-tables.js b/deps/v8/test/mjsunit/wasm/indirect-tables.js index 58df978859cd9b..e48157001bd75e 100644 --- a/deps/v8/test/mjsunit/wasm/indirect-tables.js +++ b/deps/v8/test/mjsunit/wasm/indirect-tables.js @@ -10,20 +10,20 @@ function AddFunctions(builder) { let sig_index = builder.addType(kSig_i_ii); let mul = builder.addFunction("mul", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Mul // -- ]); let add = builder.addFunction("add", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Add // -- ]); let sub = builder.addFunction("sub", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Sub // -- ]); return {mul: mul, add: add, sub: sub}; @@ -41,8 +41,8 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -121,8 +121,8 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -184,8 +184,8 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 55, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -249,11 +249,11 @@ function js_div(a, b) { return (a / b) | 0; } let sig_index = builder.addType(kSig_i_v); let f = builder.addFunction("f", sig_index) .addBody([ - kExprGetGlobal, g + kExprGlobalGet, g ]); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, kTableZero]) // -- .exportAs("main"); builder.addElementSegment(0, g, true, [f.index]); @@ -292,7 +292,7 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index1, kTableZero]) // -- .exportAs("main"); @@ -311,7 +311,7 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index2, kTableZero]) // -- .exportAs("main"); @@ -404,11 +404,11 @@ function js_div(a, b) { return (a / b) | 0; } let sig_index = builder.addType(kSig_i_v); builder.addFunction("g", sig_index) .addBody([ - kExprGetGlobal, g + kExprGlobalGet, g ]); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, kTableZero]) // -- .exportAs("main"); builder.addElementSegment(0, g, true, [g]); @@ -572,7 +572,7 @@ function js_div(a, b) { return (a / b) | 0; } let sig_index = builder0.addType(kSig_i_v); builder0.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallIndirect, sig_index, kTableZero ]) .exportAs('main'); @@ -584,7 +584,7 @@ function js_div(a, b) { return (a / b) | 0; } // instance1 imports the table and adds a function to it. let builder1 = new WasmModuleBuilder(); builder1.setName('module_1'); - builder1.addFunction('f', kSig_i_i).addBody([kExprGetLocal, 0]); + builder1.addFunction('f', kSig_i_i).addBody([kExprLocalGet, 0]); builder1.addImportedTable('z', 'table'); builder1.addElementSegment(0, 0, false, [0]); let module1 = new WebAssembly.Module(builder1.toBuffer()); @@ -611,7 +611,7 @@ function js_div(a, b) { return (a / b) | 0; } let builder = new WasmModuleBuilder(); let sig = builder.addType(kSig_i_v); builder.addFunction('main', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallIndirect, sig, kTableZero]) + .addBody([kExprLocalGet, 0, kExprCallIndirect, sig, kTableZero]) .exportAs('main'); builder.addImportedMemory('', 'memory', 1); @@ -653,7 +653,7 @@ function js_div(a, b) { return (a / b) | 0; } let builder = new WasmModuleBuilder(); let sig = builder.addType(kSig_i_v); builder.addFunction('main', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallIndirect, sig, kTableZero]) + .addBody([kExprLocalGet, 0, kExprCallIndirect, sig, kTableZero]) .exportAs('main'); builder.addImportedTable('', 'table'); @@ -711,8 +711,8 @@ function js_div(a, b) { return (a / b) | 0; } let builder = new WasmModuleBuilder(); builder.addFunction("mul", kSig_i_ii) .addBody( - [kExprGetLocal, 0, - kExprGetLocal, 1, + [kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Mul]) .exportFunc(); return builder.instantiate().exports.mul; @@ -725,8 +725,8 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 33, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -756,8 +756,8 @@ function js_div(a, b) { return (a / b) | 0; } let builder = new WasmModuleBuilder(); builder.addFunction("mul", kSig_i_ii) .addBody( - [kExprGetLocal, 0, - kExprGetLocal, 1, + [kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Mul]) .exportFunc(); return builder.instantiate().exports.mul; @@ -775,8 +775,8 @@ function js_div(a, b) { return (a / b) | 0; } builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 44, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -817,7 +817,7 @@ function js_div(a, b) { return (a / b) | 0; } builder.addImport("q", "f1", kSig_i_v); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero ]) .exportFunc(); @@ -879,7 +879,7 @@ function js_div(a, b) { return (a / b) | 0; } ]); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/instance-memory-gc-stress.js b/deps/v8/test/mjsunit/wasm/instance-memory-gc-stress.js index 29b65bc9b810dd..401be715040814 100644 --- a/deps/v8/test/mjsunit/wasm/instance-memory-gc-stress.js +++ b/deps/v8/test/mjsunit/wasm/instance-memory-gc-stress.js @@ -17,7 +17,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var instances = []; for (var i = 0; i < 5; i++) { diff --git a/deps/v8/test/mjsunit/wasm/instantiate-module-basic.js b/deps/v8/test/mjsunit/wasm/instantiate-module-basic.js index 1c5f10a83207d8..7d4b8484654a02 100644 --- a/deps/v8/test/mjsunit/wasm/instantiate-module-basic.js +++ b/deps/v8/test/mjsunit/wasm/instantiate-module-basic.js @@ -130,8 +130,8 @@ assertFalse(WebAssembly.validate(bytes(88, 88, 88, 88, 88, 88, 88, 88))); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprI32Const, 1, - kExprCallIndirect, signature, kTableZero, kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32LoadMem, 0, 0, kExprI32Const, 1, + kExprCallIndirect, signature, kTableZero, kExprLocalGet, 0, kExprI32LoadMem, 0, 0, kExprCallFunction, 0, kExprI32Add ]) .exportFunc(); @@ -139,7 +139,7 @@ assertFalse(WebAssembly.validate(bytes(88, 88, 88, 88, 88, 88, 88, 88))); // writer(mem[i]); // return mem[i] + some_value(); builder.addFunction('_wrap_writer', signature).addBody([ - kExprGetLocal, 0, kExprCallFunction, 1 + kExprLocalGet, 0, kExprCallFunction, 1 ]); builder.appendToTable([2, 3]); @@ -176,11 +176,11 @@ assertFalse(WebAssembly.validate(bytes(88, 88, 88, 88, 88, 88, 88, 88))); var builder = new WasmModuleBuilder(); builder.addGlobal(kWasmI32, true); builder.addFunction('read', kSig_i_v) - .addBody([kExprGetGlobal, 0]) + .addBody([kExprGlobalGet, 0]) .exportFunc(); builder.addFunction('write', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprSetGlobal, 0]) + .addBody([kExprLocalGet, 0, kExprGlobalSet, 0]) .exportFunc(); var module = new WebAssembly.Module(builder.toBuffer()); diff --git a/deps/v8/test/mjsunit/wasm/interpreter-mixed.js b/deps/v8/test/mjsunit/wasm/interpreter-mixed.js index 573e1e1d9ea345..27df605d466904 100644 --- a/deps/v8/test/mjsunit/wasm/interpreter-mixed.js +++ b/deps/v8/test/mjsunit/wasm/interpreter-mixed.js @@ -29,9 +29,9 @@ function checkStack(stack, expected_lines) { // grow_memory can be called from interpreted or compiled code, and changes // should be reflected in either execution. var builder = new WasmModuleBuilder(); - var grow_body = [kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]; - var load_body = [kExprGetLocal, 0, kExprI32LoadMem, 0, 0]; - var store_body = [kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0]; + var grow_body = [kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]; + var load_body = [kExprLocalGet, 0, kExprI32LoadMem, 0, 0]; + var store_body = [kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0]; builder.addFunction('grow_memory', kSig_i_i).addBody(grow_body).exportFunc(); builder.addFunction('load', kSig_i_i).addBody(load_body).exportFunc(); builder.addFunction('store', kSig_v_ii).addBody(store_body).exportFunc(); @@ -96,7 +96,7 @@ function createTwoInstancesCallingEachOther(inner_throws = false) { let id_imp = builder1.addImport('q', 'id', kSig_i_i); let plus_one = builder1.addFunction('plus_one', kSig_i_i) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprI32Const, 1, // - kExprI32Add, // - kExprCallFunction, id_imp @@ -114,7 +114,7 @@ function createTwoInstancesCallingEachOther(inner_throws = false) { let plus_two = builder2.addFunction('plus_two', kSig_i_i) .addBody([ // Call import, add one more. - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallFunction, plus_one_imp, // - kExprI32Const, 1, // - kExprI32Add diff --git a/deps/v8/test/mjsunit/wasm/interpreter.js b/deps/v8/test/mjsunit/wasm/interpreter.js index c1c03a4dd08412..43ecc4a33a92b4 100644 --- a/deps/v8/test/mjsunit/wasm/interpreter.js +++ b/deps/v8/test/mjsunit/wasm/interpreter.js @@ -59,10 +59,10 @@ function checkStack(stack, expected_lines) { builder.addFunction('main', makeSig([kWasmI32, kWasmF64], [kWasmF32])) .addBody([ // call #0 with arg 0 and arg 0 + 1 - kExprGetLocal, 0, kExprGetLocal, 0, kExprI32Const, 1, kExprI32Add, + kExprLocalGet, 0, kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add, kExprCallFunction, 0, // call #1 with arg 1 - kExprGetLocal, 1, kExprCallFunction, 1, + kExprLocalGet, 1, kExprCallFunction, 1, // convert returned value to f32 kExprF32UConvertI32, // add the two values @@ -151,28 +151,28 @@ function checkStack(stack, expected_lines) { builder.addGlobal(kWasmF32, true); // 2 builder.addGlobal(kWasmF64, true); // 3 builder.addFunction('get_i32', kSig_i_v) - .addBody([kExprGetGlobal, 0]) + .addBody([kExprGlobalGet, 0]) .exportFunc(); builder.addFunction('get_i64', kSig_d_v) - .addBody([kExprGetGlobal, 1, kExprF64SConvertI64]) + .addBody([kExprGlobalGet, 1, kExprF64SConvertI64]) .exportFunc(); builder.addFunction('get_f32', kSig_d_v) - .addBody([kExprGetGlobal, 2, kExprF64ConvertF32]) + .addBody([kExprGlobalGet, 2, kExprF64ConvertF32]) .exportFunc(); builder.addFunction('get_f64', kSig_d_v) - .addBody([kExprGetGlobal, 3]) + .addBody([kExprGlobalGet, 3]) .exportFunc(); builder.addFunction('set_i32', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprSetGlobal, 0]) + .addBody([kExprLocalGet, 0, kExprGlobalSet, 0]) .exportFunc(); builder.addFunction('set_i64', kSig_v_d) - .addBody([kExprGetLocal, 0, kExprI64SConvertF64, kExprSetGlobal, 1]) + .addBody([kExprLocalGet, 0, kExprI64SConvertF64, kExprGlobalSet, 1]) .exportFunc(); builder.addFunction('set_f32', kSig_v_d) - .addBody([kExprGetLocal, 0, kExprF32ConvertF64, kExprSetGlobal, 2]) + .addBody([kExprLocalGet, 0, kExprF32ConvertF64, kExprGlobalSet, 2]) .exportFunc(); builder.addFunction('set_f64', kSig_v_d) - .addBody([kExprGetLocal, 0, kExprSetGlobal, 3]) + .addBody([kExprLocalGet, 0, kExprGlobalSet, 3]) .exportFunc(); var instance = builder.instantiate(); // Initially, all should be zero. @@ -205,7 +205,7 @@ function checkStack(stack, expected_lines) { var builder = new WasmModuleBuilder(); builder.addImport('mod', 'func', kSig_v_i); builder.addFunction('main', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprCallFunction, 0]) .exportFunc(); instance = builder.instantiate({mod: {func: func}}); // Test that this does not mess up internal state by executing it three times. @@ -239,14 +239,14 @@ function checkStack(stack, expected_lines) { var sig_i_i = builder.addType(kSig_i_i); var mul = builder.addImport('q', 'mul', sig_i_ii); var add = builder.addFunction('add', sig_i_ii).addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add ]); var mismatch = - builder.addFunction('sig_mismatch', sig_i_i).addBody([kExprGetLocal, 0]); + builder.addFunction('sig_mismatch', sig_i_i).addBody([kExprLocalGet, 0]); var main = builder.addFunction('main', kSig_i_iii) .addBody([ // Call indirect #0 with args <#1, #2>. - kExprGetLocal, 1, kExprGetLocal, 2, kExprGetLocal, 0, + kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, kExprCallIndirect, sig_i_ii, kTableZero ]) .exportFunc(); @@ -281,7 +281,7 @@ function checkStack(stack, expected_lines) { builder.addFunction('main', kSig_v_i) .addBody([ // Call indirect #0 with arg #0, drop result. - kExprGetLocal, 0, kExprCallIndirect, sig_l_v, kTableZero, kExprDrop + kExprLocalGet, 0, kExprCallIndirect, sig_l_v, kTableZero, kExprDrop ]) .exportFunc(); builder.appendToTable([imp, direct.index, indirect.index]); @@ -409,7 +409,7 @@ function checkStack(stack, expected_lines) { var builder = new WasmModuleBuilder(); var imp = builder.addImport('mod', 'the_name_of_my_import', kSig_i_i); builder.addFunction('main', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallFunction, imp]) + .addBody([kExprLocalGet, 0, kExprCallFunction, imp]) .exportAs('main'); print('module'); return new WebAssembly.Module(builder.toBuffer()); @@ -525,7 +525,7 @@ function checkStack(stack, expected_lines) { const sig_index = builder0.addType(kSig_i_v); builder0.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallIndirect, sig_index, kTableZero ]) // -- .exportAs('main'); @@ -549,7 +549,7 @@ function checkStack(stack, expected_lines) { print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('main', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32Const, 7, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprI32Const, 7, kExprI32Add]) .exportFunc(); const wire_bytes = builder.toBuffer(); diff --git a/deps/v8/test/mjsunit/wasm/lazy-compilation.js b/deps/v8/test/mjsunit/wasm/lazy-compilation.js index c7cd40d05d72bf..c45fb6deb09fbe 100644 --- a/deps/v8/test/mjsunit/wasm/lazy-compilation.js +++ b/deps/v8/test/mjsunit/wasm/lazy-compilation.js @@ -24,7 +24,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder1.addFunction('store', kSig_v_i) .addBody([ kExprI32Const, 0, // i32.const 1 - kExprGetLocal, 0, // get_local 0 + kExprLocalGet, 0, // get_local 0 kExprI32StoreMem, 0, 0, // i32.store offset=0 align=0 ]) .exportFunc(); @@ -35,7 +35,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder2.addMemory(1, 1, true); builder2.addImport('mod', 'store', kSig_v_i); builder2.addFunction('call_store', kSig_v_i) - .addBody([kExprGetLocal, 0, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprCallFunction, 0]) .exportFunc(); const instance2 = builder2.instantiate({mod: {store: instance1.exports.store}}); const mem2 = new Int32Array(instance2.exports.memory.buffer); @@ -75,7 +75,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); builder1.addFunction('store', kSig_v_i) .addBody([ kExprI32Const, 0, // i32.const 1 - kExprGetLocal, 0, // get_local 0 + kExprLocalGet, 0, // get_local 0 kExprI32StoreMem, 0, 0, // i32.store offset=0 align=0 ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/liftoff-trap-handler.js b/deps/v8/test/mjsunit/wasm/liftoff-trap-handler.js index 3ce74816ea623f..eadfaacca438c0 100644 --- a/deps/v8/test/mjsunit/wasm/liftoff-trap-handler.js +++ b/deps/v8/test/mjsunit/wasm/liftoff-trap-handler.js @@ -13,13 +13,13 @@ function testCompileLoadStore() { const builder = new WasmModuleBuilder(); // These functions generate statically out of bounds accesses. builder.addFunction("load", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0x80, 0x80, 0x80, 1]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0x80, 0x80, 0x80, 1]) .exportFunc(); builder.addFunction("store", kSig_i_ii) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32StoreMem, 0, 0x80, 0x80, 0x80, 1, - kExprGetLocal, 1]) + kExprLocalGet, 1]) .exportFunc(); builder.addMemory(1, 1, false); const instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/wasm/liftoff.js b/deps/v8/test/mjsunit/wasm/liftoff.js index 51b30878d36bfd..04eeffbea27ca7 100644 --- a/deps/v8/test/mjsunit/wasm/liftoff.js +++ b/deps/v8/test/mjsunit/wasm/liftoff.js @@ -10,7 +10,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('i32_add', kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); const module = new WebAssembly.Module(builder.toBuffer()); @@ -26,7 +26,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('i32_add', kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); const instance = builder.instantiate(); @@ -38,7 +38,7 @@ async function testLiftoffAsync() { print(arguments.callee.name); const builder = new WasmModuleBuilder(); builder.addFunction('i32_add', kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); print('Compiling...'); diff --git a/deps/v8/test/mjsunit/wasm/loop-rotation.js b/deps/v8/test/mjsunit/wasm/loop-rotation.js index 92ad1f31c79f47..7805f5ccf5e4fb 100644 --- a/deps/v8/test/mjsunit/wasm/loop-rotation.js +++ b/deps/v8/test/mjsunit/wasm/loop-rotation.js @@ -12,10 +12,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_v_i) .addBody([ kExprLoop, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, - kExprTeeLocal, 0, + kExprLocalTee, 0, kExprBrIf, 0, kExprEnd, ]) @@ -33,10 +33,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_v_i) .addBody([ kExprLoop, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, - kExprTeeLocal, 0, + kExprLocalTee, 0, kExprBrIf, 1, kExprBr, 0, kExprEnd, @@ -56,10 +56,10 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_v_i) .addBody([ kExprLoop, kWasmStmt, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, - kExprTeeLocal, 0, + kExprLocalTee, 0, kExprBrIf, 1, kExprI32Const, 0, kExprI32Const, 0, diff --git a/deps/v8/test/mjsunit/wasm/many-modules.js b/deps/v8/test/mjsunit/wasm/many-modules.js new file mode 100644 index 00000000000000..66db04237a2a6e --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/many-modules.js @@ -0,0 +1,45 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// No reason to stress-opt this; save some time. +// Flags: --wasm-far-jump-table --no-stress-opt + +load('test/mjsunit/wasm/wasm-module-builder.js'); + +// We generate the module bytes once to make this test more efficient, +// especially on simulator builds. The bytes contain a sentinel which is later +// patched to different constants. This makes the modules distinct and forces +// the engine to create different code for them. + +// This is the sentinel placed in the bytes. It's a 5 byte LEB-encoded integer. +const sentinel = wasmSignedLeb(0x12345678); +assertEquals(5, sentinel.length); + +const builder = new WasmModuleBuilder(); +builder.addFunction('f', kSig_i_i).addBody([kExprI32Const, ...sentinel]); +const module_bytes = builder.toBuffer(); + +// Checks whether {module_bytes[i .. i+sentinel.length]} matches {sentinel}. +const has_sentinel = (i, k = 0) => module_bytes[i + k] == sentinel[k] && + (k == sentinel.length - 1 || has_sentinel(i, k + 1)); +// Now find the sentinel. +const find_sentinel = i => + module_bytes.slice(i).findIndex((e, i) => has_sentinel(i)); +const sentinel_position = find_sentinel(0); +assertTrue(has_sentinel(sentinel_position), 'found sentinel'); +assertEquals(-1, find_sentinel(sentinel_position + 1), 'exactly one sentinel'); + +// Generating {num_modules} modules should not run out of memory, since the code +// space needed per module is quite low. +const num_modules = 10000; +// Keep all generated modules alive. +const modules = []; +// Reset sentinel section to nops so that shorter LEBs will just be followed by +// nops. This resion will be patched in the loop with values of increasing size. +module_bytes.set(Array(sentinel.length).fill(_ => kExprNop), sentinel_position); +for (let i = 0; i < num_modules; ++i) { + if (i % 50 == 0) print(i); + module_bytes.set(wasmSignedLeb(i), sentinel_position); + modules.push(new WebAssembly.Module(module_bytes)); +} diff --git a/deps/v8/test/mjsunit/wasm/many-parameters.js b/deps/v8/test/mjsunit/wasm/many-parameters.js index 46b231943df0de..7813ad453c8357 100644 --- a/deps/v8/test/mjsunit/wasm/many-parameters.js +++ b/deps/v8/test/mjsunit/wasm/many-parameters.js @@ -37,7 +37,7 @@ types.forEach((type, type_idx) => { let body = []; for (let i = 0; i < num_params; ++i) - body.push(kExprGetLocal, (i + shift) % num_params); + body.push(kExprLocalGet, (i + shift) % num_params); for (let i = 0; i < num_const_params; ++i) body.push(...type_const[type_idx](num_params + i)); body.push(kExprCallFunction, 0); diff --git a/deps/v8/test/mjsunit/wasm/memory-external-call.js b/deps/v8/test/mjsunit/wasm/memory-external-call.js index 853cdf616a9948..1bb4bb1ecc8111 100644 --- a/deps/v8/test/mjsunit/wasm/memory-external-call.js +++ b/deps/v8/test/mjsunit/wasm/memory-external-call.js @@ -25,12 +25,12 @@ function generateBuilder(add_memory, import_sig) { // Add the memory if we expect a module builder with memory and load/store. builder.addMemory(initialMemoryPages, maximumMemoryPages, true); builder.addFunction('load', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportFunc(); builder.addFunction('store', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1 + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32StoreMem, 0, 0, + kExprLocalGet, 1 ]) .exportFunc(); } @@ -83,14 +83,14 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { builder.addMemory(kPages, kPages, true); builder.addFunction("store", kSig_v_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32StoreMem, 0, 0, // -- ]) // -- .exportFunc(); builder.addFunction("load", kSig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32LoadMem, 0, 0, // -- ]) // -- .exportFunc(); @@ -103,14 +103,14 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { builder.addMemory(kPages, kPages, true); builder.addFunction("store", kSig_v_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0, // -- ]) // -- .exportFunc(); builder.addFunction("load", kSig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32LoadMem, 0, 0, // -- ]) // -- .exportFunc(); @@ -152,7 +152,7 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { // Function to invoke the imported function and add 1 to the result. first_module.addFunction('plus_one', kSig_i_i) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallFunction, other_fn_idx, // call the imported function kExprI32Const, 1, // - kExprI32Add, // add 1 to the result @@ -185,7 +185,7 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { // Function to invoke the imported function and add 1 to the result. first_module.addFunction('plus_one', kSig_i_i) .addBody([ - kExprGetLocal, 0, // - + kExprLocalGet, 0, // - kExprCallFunction, other_fn_idx, // call the imported function kExprI32Const, 1, // - kExprI32Add, // add 1 to the result @@ -221,14 +221,14 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { // Function to invoke the imported function and add 1 to the result. first_module.addFunction('sandwich', kSig_i_iii) .addBody([ - kExprGetLocal, 0, // param0 (index) - kExprGetLocal, 1, // param1 (first_value) + kExprLocalGet, 0, // param0 (index) + kExprLocalGet, 1, // param1 (first_value) kExprI32StoreMem, 0, 0, // store value in first_instance - kExprGetLocal, 0, // param0 (index) - kExprGetLocal, 2, // param2 (second_value) + kExprLocalGet, 0, // param0 (index) + kExprLocalGet, 2, // param2 (second_value) kExprCallFunction, other_fn_idx, // call the imported function kExprDrop, // drop the return value - kExprGetLocal, 0, // param0 (index) + kExprLocalGet, 0, // param0 (index) kExprI32LoadMem, 0, 0, // load from first_instance kExprReturn // - ]) @@ -263,14 +263,14 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { builder.addMemory(kPages, kPages, true); builder.addFunction("store", kSig_v_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32StoreMem, 0, 0, // -- ]) // -- .exportFunc(); builder.addFunction("load", kSig_i_i) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32LoadMem, 0, 0, // -- ]) // -- .exportFunc(); @@ -308,9 +308,9 @@ function assertMemoryIndependence(load_a, store_a, load_b, store_b) { var sig_index = builder.addType(kSig_v_ii); builder.addFunction("store", kSig_v_iii) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprCallIndirect, sig_index, kTableZero, ]).exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/memory-instance-validation.js b/deps/v8/test/mjsunit/wasm/memory-instance-validation.js index ef658405328b18..a19b94b1320d92 100644 --- a/deps/v8/test/mjsunit/wasm/memory-instance-validation.js +++ b/deps/v8/test/mjsunit/wasm/memory-instance-validation.js @@ -17,7 +17,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); builder.addFunction("grow", kSig_i_i) - .addBody([kExprGetLocal, 0, kExprMemoryGrow, kMemoryZero]) + .addBody([kExprLocalGet, 0, kExprMemoryGrow, kMemoryZero]) .exportFunc(); var instances = []; for (var i = 0; i < 5; i++) { diff --git a/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js index f2b22d97ab51fa..a365b419f9d10b 100644 --- a/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js +++ b/deps/v8/test/mjsunit/wasm/memory_1gb_oob.js @@ -40,14 +40,14 @@ const indexes = (() => { 0|((offset >>> 28) & m)]; builder.addFunction("load", makeSig([kWasmI32], [type])) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- load_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); builder.addFunction("store", makeSig([kWasmI32, type], [])) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- store_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js index 6baf0f3c7e4257..d5be98aa18c744 100644 --- a/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js +++ b/deps/v8/test/mjsunit/wasm/memory_2gb_oob.js @@ -40,14 +40,14 @@ const indexes = (() => { 0|((offset >>> 28) & m)]; builder.addFunction("load", makeSig([kWasmI32], [type])) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- load_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); builder.addFunction("store", makeSig([kWasmI32, type], [])) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- store_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js b/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js index 39b9f95d9ce1af..e9533b8d6c07b1 100644 --- a/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js +++ b/deps/v8/test/mjsunit/wasm/memory_4gb_oob.js @@ -38,14 +38,14 @@ const indexes = (() => { 0|((offset >>> 28) & m)]; builder.addFunction("load", makeSig([kWasmI32], [type])) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- load_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); builder.addFunction("store", makeSig([kWasmI32, type], [])) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- store_opcode, 0, ...offset_bytes, // -- ]) // -- .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/module-memory.js b/deps/v8/test/mjsunit/wasm/module-memory.js index 3dd580d269e420..0f870e7815aa1f 100644 --- a/deps/v8/test/mjsunit/wasm/module-memory.js +++ b/deps/v8/test/mjsunit/wasm/module-memory.js @@ -18,18 +18,18 @@ function genModule(memory) { // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0; // TODO(titzer): this manual bytecode has a copy of test-run-wasm.cc /**/ kExprLoop, kWasmStmt, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprIf, kWasmStmt, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32LoadMem, 0, 0, // -- /* */ kExprIf, kWasmStmt, // -- /* */ kExprI32Const, 127, // -- /* */ kExprReturn, // -- /* */ kExprEnd, // -- - /* */ kExprGetLocal, 0, // -- + /* */ kExprLocalGet, 0, // -- /* */ kExprI32Const, 4, // -- /* */ kExprI32Sub, // -- - /* */ kExprSetLocal, 0, // -- + /* */ kExprLocalSet, 0, // -- /* */ kExprBr, 1, // -- /* */ kExprEnd, // -- /* */ kExprEnd, // -- @@ -52,9 +52,7 @@ function testPokeMemory() { var array = new Int8Array(buffer); assertEquals(kMemSize, array.length); - for (var i = 0; i < kMemSize; i++) { - assertEquals(0, array[i]); - } + assertTrue(array.every((e => e === 0))); for (var i = 0; i < 10; i++) { assertEquals(0, main(kMemSize - 4)); @@ -99,9 +97,7 @@ function testPokeOuterMemory() { var array = new Int8Array(buffer.buffer); assertEquals(kMemSize, array.length); - for (var i = 0; i < kMemSize; i++) { - assertEquals(0, array[i]); - } + assertTrue(array.every((e => e === 0))); for (var i = 0; i < 10; i++) { assertEquals(0, main(kMemSize - 4)); @@ -139,33 +135,30 @@ function testOOBThrows() { builder.addMemory(1, 1, true); builder.addFunction("geti", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32LoadMem, 0, 0, kExprI32StoreMem, 0, 0, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprI32LoadMem, 0, 0, ]) .exportFunc(); var module = builder.instantiate(); - var offset; - function read() { return module.exports.geti(0, offset); } - function write() { return module.exports.geti(offset, 0); } + let read = offset => module.exports.geti(0, offset); + let write = offset => module.exports.geti(offset, 0); - for (offset = 0; offset < 65533; offset++) { - assertEquals(0, read()); - assertEquals(0, write()); - } + assertEquals(0, read(65532)); + assertEquals(0, write(65532)); // Note that this test might be run concurrently in multiple Isolates, which // makes an exact comparison of the expected trap count unreliable. But is is // still possible to check the lower bound for the expected trap count. - for (offset = 65534; offset < 66536; offset++) { + for (let offset = 65534; offset < 66536; offset++) { const trap_count = %GetWasmRecoveredTrapCount(); - assertTraps(kTrapMemOutOfBounds, read); - assertTraps(kTrapMemOutOfBounds, write); + assertTraps(kTrapMemOutOfBounds, () => read(offset)); + assertTraps(kTrapMemOutOfBounds, () => write(offset)); if (%IsWasmTrapHandlerEnabled()) { assertTrue(trap_count + 2 <= %GetWasmRecoveredTrapCount()); } diff --git a/deps/v8/test/mjsunit/wasm/multi-value.js b/deps/v8/test/mjsunit/wasm/multi-value.js index 31f9e8149b130f..e6a7ae99a5cc4c 100644 --- a/deps/v8/test/mjsunit/wasm/multi-value.js +++ b/deps/v8/test/mjsunit/wasm/multi-value.js @@ -15,8 +15,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ kExprBlock, sig_ii_v, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprEnd, kExprI32Add]) .exportAs("main"); @@ -33,8 +33,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprBlock, sig_i_ii, kExprI32Add, kExprEnd]) @@ -54,8 +54,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ kExprBlock, sig_ii_v, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprBr, 0, kExprEnd, kExprI32Add]) @@ -76,8 +76,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ kExprLoop, sig_ii_v, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprEnd, kExprI32Add]) .exportAs("main"); @@ -94,8 +94,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprLoop, sig_i_ii, kExprI32Add, kExprEnd]) @@ -114,13 +114,13 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let sig_ii_ii = builder.addType(kSig_ii_ii); builder.addFunction("dup", kSig_ii_i) - .addBody([kExprGetLocal, 0, kExprGetLocal, 0]); + .addBody([kExprLocalGet, 0, kExprLocalGet, 0]); builder.addFunction("swap", kSig_ii_ii) - .addBody([kExprGetLocal, 1, kExprGetLocal, 0]); + .addBody([kExprLocalGet, 1, kExprLocalGet, 0]); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprLoop, sig_ii_ii, kExprCallFunction, 1, // swap kExprCallFunction, 0, // dup @@ -164,13 +164,13 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprIf, sig_ii_v, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprElse, - kExprGetLocal, 1, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 0, kExprEnd, kExprI32Sub]) .exportAs("main"); @@ -188,9 +188,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 0, kExprIf, sig_i_ii, kExprI32Add, kExprElse, @@ -212,14 +212,14 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprIf, sig_ii_v, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprBr, 0, kExprElse, - kExprGetLocal, 1, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 0, kExprBr, 0, kExprEnd, kExprI32Sub]) @@ -231,6 +231,27 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); assertEquals(instance.exports.main(0, 3), 3); })(); +(function MultiIfParamOneArmedTest() { + print("MultiIfParamOneArmedTest"); + let builder = new WasmModuleBuilder(); + let sig_i_i = builder.addType(kSig_i_i); + + builder.addFunction("main", kSig_i_i) + .addBody([ + kExprLocalGet, 0, + kExprLocalGet, 0, + kExprIf, sig_i_i, + kExprI32Const, 5, + kExprI32Add, + kExprEnd]) + .exportAs("main"); + + let module = new WebAssembly.Module(builder.toBuffer()); + let instance = new WebAssembly.Instance(module); + assertEquals(instance.exports.main(0), 0); + assertEquals(instance.exports.main(1), 6); +})(); + (function MultiResultTest() { print("MultiResultTest"); let builder = new WasmModuleBuilder(); @@ -239,15 +260,15 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("callee", kSig_iii_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Sub]); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprCallFunction, 0, kExprI32Mul, kExprI32Add]) @@ -272,14 +293,14 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("callee", kSig_ii_i) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Add, kExprReturn]); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0, kExprI32Mul]) .exportAs("main"); @@ -300,14 +321,14 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("callee", kSig_ii_i) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Add, kExprBr, 0]); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0, kExprI32Mul]) .exportAs("main"); @@ -320,26 +341,26 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); assertEquals(instance.exports.main(10), 200); })(); -(function MultiJSReturnTest() { +(function MultiWasmToJSReturnTest() { print(arguments.callee.name); let builder = new WasmModuleBuilder(); let sig_fi_if = makeSig([kWasmI32, kWasmF32], [kWasmF32, kWasmI32]); builder.addFunction("swap", sig_fi_if) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 0]) + kExprLocalGet, 1, + kExprLocalGet, 0]) .exportAs("swap"); builder.addFunction("addsubmul", kSig_iii_i) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Add, - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Sub, - kExprGetLocal, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, + kExprLocalGet, 0, kExprI32Mul]) .exportAs("addsubmul"); @@ -350,3 +371,75 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); assertEquals(instance.exports.addsubmul(4), [8, 0, 16]); assertEquals(instance.exports.addsubmul(5), [10, 0, 25]); })(); + +(function MultiJSToWasmReturnTest() { + print(arguments.callee.name); + let builder = new WasmModuleBuilder(); + function swap(x, y) { return [y, x]; } + function swap_proxy(x, y) { + return new Proxy([y, x], { + get: function(obj, prop) { return Reflect.get(obj, prop); }, + }); + } + function proxy_throw(x, y) { + return new Proxy([y, x], { + get: function(obj, prop) { + if (prop == 1) { + throw new Error("abc"); + } + return Reflect.get(obj, prop); }, + }); + } + function drop_first(x, y) { + return [y]; + } + function repeat(x, y) { + return [x, y, x, y]; + } + function not_receiver(x, y) { + return 0; + } + function not_iterable(x, y) { + a = [x, y]; + a[Symbol.iterator] = undefined; + return a; + } + function* generator(x, y) { + yield x; + yield y; + } + function* generator_throw(x, y) { + yield x; + throw new Error("def"); + } + + builder.addImport('imports', 'f', kSig_ii_ii); + builder.addFunction("main", kSig_ii_ii) + .addBody([ + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprCallFunction, 0]) + .exportAs("main") + + let module = new WebAssembly.Module(builder.toBuffer()); + + var instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : swap } }); + assertEquals(instance.exports.main(1, 2), [2, 1]); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : swap_proxy } }); + assertEquals(instance.exports.main(1, 2), [2, 1]); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : generator } }); + assertEquals(instance.exports.main(1, 2), [1, 2]); + + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : drop_first } }); + assertThrows(() => instance.exports.main(1, 2), TypeError, "multi-return length mismatch"); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : repeat } }); + assertThrows(() => instance.exports.main(1, 2), TypeError, "multi-return length mismatch"); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : proxy_throw } }); + assertThrows(() => instance.exports.main(1, 2), Error, "abc"); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : not_receiver } }); + assertThrows(() => instance.exports.main(1, 2), TypeError, /not iterable/); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : not_iterable } }); + assertThrows(() => instance.exports.main(1, 2), TypeError, /not iterable/); + instance = new WebAssembly.Instance(module, { 'imports' : { 'f' : generator_throw } }); + assertThrows(() => instance.exports.main(1, 2), Error, "def"); +})(); diff --git a/deps/v8/test/mjsunit/wasm/multiple-code-spaces.js b/deps/v8/test/mjsunit/wasm/multiple-code-spaces.js new file mode 100644 index 00000000000000..f180cf62349c98 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/multiple-code-spaces.js @@ -0,0 +1,54 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --randomize-all-allocations +// Flags: --wasm-far-jump-table --wasm-max-initial-code-space-reservation=1 + +load('test/mjsunit/wasm/wasm-module-builder.js'); + +// Instantiate bigger modules, until at least four separate code spaces have +// been allocated. +// Each function calls through many of the previous functions to execute the +// jump table(s) sufficiently. + +let num_functions = 50; +while (true) { + print(`Trying ${num_functions} functions...`); + if (num_functions > 1e6) { + throw new Error('We should have hit four code spaces by now'); + } + const builder = new WasmModuleBuilder(); + builder.addMemory(1, 1, false); + builder.addFunction('f0', kSig_i_i).addBody([kExprLocalGet, 0]); + // Generate some code per function to fill the code space. + // Each function contains a number of loads that will not be executed + // (inside an "if (i == 0)" block). They increase the code size a bit so we + // do not need too many functions. + // Each function f<n> with argument {i} then calls f<n/10> with argument + // {i + 1} and returns whatever that function returns. + const body_template = [ + kExprLocalGet, 0, kExprI32Eqz, kExprIf, kWasmStmt, // if (i == 0) + kExprLocalGet, 0 // get i + ]; + for (let i = 0; i < 1000; ++i) body_template.push(kExprI32LoadMem, 0, 0); + body_template.push( + kExprDrop, kExprEnd, // end if + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add, // i + 1 + kExprCallFunction // call f<?> + ); + for (let i = 1; i < num_functions; ++i) { + const body = body_template.slice(); + body.push(...wasmSignedLeb(Math.floor(i / 10))); + builder.addFunction('f' + i, kSig_i_i).addBody(body); + } + builder.addExport('f', num_functions - 1); + const instance = builder.instantiate(); + let expected = 17; + for (let i = num_functions - 1; i > 0; i = Math.floor(i / 10)) ++expected; + assertEquals(expected, instance.exports.f(17)); + const num_code_spaces = %WasmNumCodeSpaces(instance); + print(`--> ${num_code_spaces} code spaces.`); + if (num_code_spaces >= 4) break; + num_functions *= 2; +} diff --git a/deps/v8/test/mjsunit/wasm/origin-trial-flags.js b/deps/v8/test/mjsunit/wasm/origin-trial-flags.js index b9ce6f7f948bfa..eae8ceb58c6f45 100644 --- a/deps/v8/test/mjsunit/wasm/origin-trial-flags.js +++ b/deps/v8/test/mjsunit/wasm/origin-trial-flags.js @@ -13,7 +13,7 @@ function instantiateModuleWithThreads() { builder.addMemory(2, 10, false, shared); builder.addFunction('main', kSig_i_ii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kAtomicPrefix, kExprI32AtomicAdd, 2, + kExprLocalGet, 0, kExprLocalGet, 1, kAtomicPrefix, kExprI32AtomicAdd, 2, 0 ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/parallel_compilation.js b/deps/v8/test/mjsunit/wasm/parallel_compilation.js index 6eca124bc427a1..7a1da58e8f9e19 100644 --- a/deps/v8/test/mjsunit/wasm/parallel_compilation.js +++ b/deps/v8/test/mjsunit/wasm/parallel_compilation.js @@ -50,7 +50,7 @@ function assertFunction(module, func) { for (i = 0; i < 1000; i++) { builder.addFunction("sub" + i, kSig_i_i) .addBody([ // -- - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprI32Const, i % 61, // -- kExprI32Sub]) // -- .exportFunc() @@ -74,8 +74,8 @@ function assertFunction(module, func) { f[0] = builder.addFunction("add0", kSig_i_ii) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Add, // -- ]) .exportFunc() @@ -84,8 +84,8 @@ function assertFunction(module, func) { for (i = 1; i < 256; i++) { f[i] = builder.addFunction("add" + i, kSig_i_ii) .addBody([ // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, f[i >>> 1].index]) // -- .exportFunc() } diff --git a/deps/v8/test/mjsunit/wasm/params.js b/deps/v8/test/mjsunit/wasm/params.js index 33858429c4bff0..eed893fd57fcc0 100644 --- a/deps/v8/test/mjsunit/wasm/params.js +++ b/deps/v8/test/mjsunit/wasm/params.js @@ -17,7 +17,7 @@ function testSelect2(type) { var builder = new WasmModuleBuilder(); builder.addFunction("select", makeSig_r_xx(type, type)) - .addBody([kExprGetLocal, which]) + .addBody([kExprLocalGet, which]) .exportFunc() var select = builder.instantiate().exports.select; @@ -79,7 +79,7 @@ function testSelect10(t) { var builder = new WasmModuleBuilder(); builder.addFunction("select", makeSig([t,t,t,t,t,t,t,t,t,t], [t])) - .addBody([kExprGetLocal, which]) + .addBody([kExprLocalGet, which]) .exportFunc(); var select = builder.instantiate().exports.select; diff --git a/deps/v8/test/mjsunit/wasm/receiver.js b/deps/v8/test/mjsunit/wasm/receiver.js index 10e88559272e05..de8954ff980702 100644 --- a/deps/v8/test/mjsunit/wasm/receiver.js +++ b/deps/v8/test/mjsunit/wasm/receiver.js @@ -13,8 +13,8 @@ function testCallImport(func, expected, a, b) { builder.addImport("mod", "func", sig_index); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0]) // -- .exportAs("main"); diff --git a/deps/v8/test/mjsunit/wasm/return-calls.js b/deps/v8/test/mjsunit/wasm/return-calls.js index 22d2860df10bdd..7dd56ef02f6d1e 100644 --- a/deps/v8/test/mjsunit/wasm/return-calls.js +++ b/deps/v8/test/mjsunit/wasm/return-calls.js @@ -18,15 +18,15 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); // f_aux(N,X) => f_aux(N-1,X*N) let fact_aux = builder.addFunction("fact_aux",kSig_i_ii); fact_aux.addBody([ - kExprGetLocal, 0, kExprI32Const, 1, kExprI32LeS, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32LeS, kExprIf, kWasmI32, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprElse, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Mul, kExprReturnCall, fact_aux.index, kExprEnd @@ -35,7 +35,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); //main(N)=>fact_aux(N,1) let main = builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprReturnCall,0 ]).exportFunc(); @@ -63,18 +63,18 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let f_ind = builder.addFunction("f_ind",kSig_i_iii). addBody([ - kExprGetLocal, 0, kExprI32Const, 1, kExprI32LeS, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32LeS, kExprIf, kWasmI32, - kExprGetLocal, 1, + kExprLocalGet, 1, kExprElse, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Sub, - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Mul, - kExprGetLocal, 2, - kExprGetLocal, 2, + kExprLocalGet, 2, + kExprLocalGet, 2, kExprReturnCallIndirect, sig_i_iii, kTableZero, kExprEnd ]); @@ -82,7 +82,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); //main(N)=>fact_aux(N,1) let main = builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 1, kExprI32Const, f_ind.index, kExprReturnCall, f_ind.index @@ -109,9 +109,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let main = builder.addFunction("main", kSig_i_iii) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprReturnCall, pick ]) .exportFunc(); @@ -141,9 +141,9 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); let main = builder.addFunction("main", kSig_i_iii) .addBody([ - kExprGetLocal, 1, - kExprGetLocal, 2, - kExprGetLocal, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, + kExprLocalGet, 0, kExprI32Const, tableIndex, kExprReturnCallIndirect, sig_i_iii, kTableZero ]) diff --git a/deps/v8/test/mjsunit/wasm/shared-arraybuffer-worker-simple-gc.js b/deps/v8/test/mjsunit/wasm/shared-arraybuffer-worker-simple-gc.js new file mode 100644 index 00000000000000..a32e6f4d15140b --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/shared-arraybuffer-worker-simple-gc.js @@ -0,0 +1,84 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-gc + +const kNumIterations = 10; + +function NewWorker() { + let script = +`onmessage = (msg) => { + if (msg.memory) postMessage("ack"); + if (msg.quit) postMessage("bye"); + gc(); +}`; + return new Worker(script, {type: 'string'}); +} + +function PingWorker(worker, memory) { + worker.postMessage({memory: memory}); + assertEquals("ack", worker.getMessage()); + worker.postMessage({quit: true}); + assertEquals("bye", worker.getMessage()); +} + +function AllocMemory() { + return new SharedArrayBuffer(1024); +} + +function RunSingleWorkerSingleMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + gc(); + } + worker.terminate(); +} + +function RunSingleWorkerTwoMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(), second = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + PingWorker(worker, second); + gc(); + } + worker.terminate(); +} + +function RunSingleWorkerMultipleMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + PingWorker(worker, AllocMemory()); + gc(); + } + worker.terminate(); +} + +function RunMultipleWorkerMultipleMemoryTest() { + print(arguments.callee.name); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + let worker = NewWorker(); + PingWorker(worker, first); + PingWorker(worker, AllocMemory()); + worker.terminate(); + gc(); + } +} + +RunSingleWorkerSingleMemoryTest(); +RunSingleWorkerTwoMemoryTest(); +RunSingleWorkerMultipleMemoryTest(); +RunMultipleWorkerMultipleMemoryTest(); diff --git a/deps/v8/test/mjsunit/wasm/shared-memory-gc-stress.js b/deps/v8/test/mjsunit/wasm/shared-memory-gc-stress.js index 8721d8d0663cfc..1dbbcb9ff6dd1c 100644 --- a/deps/v8/test/mjsunit/wasm/shared-memory-gc-stress.js +++ b/deps/v8/test/mjsunit/wasm/shared-memory-gc-stress.js @@ -10,11 +10,11 @@ function AllocMemory(pages, max = pages) { } function RunSomeAllocs(total, retained, pages, max = pages) { - print(`-------iterations = ${total}, retained = $ { retained } -------`); + print(`-------iterations = ${total}, retained = ${retained} -------`); var array = new Array(retained); for (var i = 0; i < total; i++) { if ((i % 25) == 0) - print(`iteration $ { i }`); + print(`iteration ${i}`); let pair = AllocMemory(pages, max); // For some iterations, retain the memory, view, or both. switch (i % 3) { diff --git a/deps/v8/test/mjsunit/wasm/shared-memory-worker-gc.js b/deps/v8/test/mjsunit/wasm/shared-memory-worker-gc.js index 376917b6eeb06a..6afc6115f86e24 100644 --- a/deps/v8/test/mjsunit/wasm/shared-memory-worker-gc.js +++ b/deps/v8/test/mjsunit/wasm/shared-memory-worker-gc.js @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --experimental-wasm-threads +// Flags: --experimental-wasm-threads --expose-gc -const kNumMessages = 5000; +const kNumMessages = 1000; function AllocMemory(pages = 1, max = pages) { return new WebAssembly.Memory({initial : pages, maximum : max, shared : true}); @@ -15,6 +15,7 @@ function AllocMemory(pages = 1, max = pages) { `onmessage = function(msg) { if (msg.memory) postMessage({memory : msg.memory}); + gc(); }`, {type : 'string'}); let time = performance.now(); @@ -30,5 +31,6 @@ function AllocMemory(pages = 1, max = pages) { if (msg.memory) { assertInstanceof(msg.memory, WebAssembly.Memory); } + gc(); } })(); diff --git a/deps/v8/test/mjsunit/wasm/shared-memory-worker-simple-gc.js b/deps/v8/test/mjsunit/wasm/shared-memory-worker-simple-gc.js new file mode 100644 index 00000000000000..53229861cc0ce2 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/shared-memory-worker-simple-gc.js @@ -0,0 +1,85 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --experimental-wasm-threads --expose-gc + +const kNumIterations = 10; + +function NewWorker() { + let script = +`onmessage = (msg) => { + if (msg.memory) postMessage("ack"); + if (msg.quit) postMessage("bye"); + gc(); +}`; + return new Worker(script, {type: 'string'}); +} + +function PingWorker(worker, memory) { + worker.postMessage({memory: memory}); + assertEquals("ack", worker.getMessage()); + worker.postMessage({quit: true}); + assertEquals("bye", worker.getMessage()); +} + +function AllocMemory() { + let pages = 1, max = 1; + return new WebAssembly.Memory({initial : pages, maximum : max, shared : true}); +} + +function RunSingleWorkerSingleMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + gc(); + } + worker.terminate(); +} + +function RunSingleWorkerTwoMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(), second = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + PingWorker(worker, second); + gc(); + } + worker.terminate(); +} + +function RunSingleWorkerMultipleMemoryTest() { + print(arguments.callee.name); + let worker = NewWorker(); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + PingWorker(worker, first); + PingWorker(worker, AllocMemory()); + gc(); + } + worker.terminate(); +} + +function RunMultipleWorkerMultipleMemoryTest() { + print(arguments.callee.name); + let first = AllocMemory(); + for (let i = 0; i < kNumIterations; i++) { + print(`iteration ${i}`); + let worker = NewWorker(); + PingWorker(worker, first); + PingWorker(worker, AllocMemory()); + worker.terminate(); + gc(); + } +} + +RunSingleWorkerSingleMemoryTest(); +RunSingleWorkerTwoMemoryTest(); +RunSingleWorkerMultipleMemoryTest(); +RunMultipleWorkerMultipleMemoryTest(); diff --git a/deps/v8/test/mjsunit/wasm/shared-memory.js b/deps/v8/test/mjsunit/wasm/shared-memory.js index 80e894b28f34fa..696b0412ae95c6 100644 --- a/deps/v8/test/mjsunit/wasm/shared-memory.js +++ b/deps/v8/test/mjsunit/wasm/shared-memory.js @@ -73,8 +73,8 @@ function assertMemoryIsValid(memory, shared) { let builder = new WasmModuleBuilder(); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kAtomicPrefix, kExprI32AtomicAdd]); builder.addImportedMemory("m", "imported_mem"); @@ -119,8 +119,8 @@ function assertMemoryIsValid(memory, shared) { builder.addMemory(2, 10, false, "shared"); builder.addFunction("main", kSig_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kAtomicPrefix, kExprI32AtomicAdd, 2, 0]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/stackwalk.js b/deps/v8/test/mjsunit/wasm/stackwalk.js index 91951ff4c35b7e..e1cd6522ec6597 100644 --- a/deps/v8/test/mjsunit/wasm/stackwalk.js +++ b/deps/v8/test/mjsunit/wasm/stackwalk.js @@ -13,8 +13,8 @@ function makeFFI(func) { builder.addImport("mom", "func", sig_index); builder.addFunction("main", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0, // -- ]) .exportFunc() diff --git a/deps/v8/test/mjsunit/wasm/start-function.js b/deps/v8/test/mjsunit/wasm/start-function.js index e17c8f1785b408..bda9d085c5ee7d 100644 --- a/deps/v8/test/mjsunit/wasm/start-function.js +++ b/deps/v8/test/mjsunit/wasm/start-function.js @@ -29,9 +29,9 @@ function assertVerifies(sig, body) { assertVerifies(kSig_v_v, [kExprNop]); // Arguments aren't allowed to start functions. -assertThrows(() => {instantiate(kSig_i_i, [kExprGetLocal, 0]);}); -assertThrows(() => {instantiate(kSig_i_ii, [kExprGetLocal, 0]);}); -assertThrows(() => {instantiate(kSig_i_dd, [kExprGetLocal, 0]);}); +assertThrows(() => {instantiate(kSig_i_i, [kExprLocalGet, 0]);}); +assertThrows(() => {instantiate(kSig_i_ii, [kExprLocalGet, 0]);}); +assertThrows(() => {instantiate(kSig_i_dd, [kExprLocalGet, 0]);}); assertThrows(() => {instantiate(kSig_i_v, [kExprI32Const, 0]);}); (function testInvalidIndex() { diff --git a/deps/v8/test/mjsunit/wasm/streaming-api.js b/deps/v8/test/mjsunit/wasm/streaming-api.js index 3decc1a70c2699..01e6637b4dfdd1 100644 --- a/deps/v8/test/mjsunit/wasm/streaming-api.js +++ b/deps/v8/test/mjsunit/wasm/streaming-api.js @@ -10,7 +10,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction("main", kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportAs("main"); let bytes = builder.toBuffer(); assertPromiseResult(WebAssembly.compileStreaming(Promise.resolve(bytes)).then( @@ -22,7 +22,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction("main", kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportAs("main"); let bytes = builder.toBuffer(); assertPromiseResult(WebAssembly.instantiateStreaming(Promise.resolve(bytes)).then( @@ -47,8 +47,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction("main", kSig_i_i) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 0, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 0, kExprF32Mul]) .exportAs("main"); let bytes = builder.toBuffer(); diff --git a/deps/v8/test/mjsunit/wasm/streaming-error-position.js b/deps/v8/test/mjsunit/wasm/streaming-error-position.js index b6d008cd1328f9..77c1b46e85fc2d 100644 --- a/deps/v8/test/mjsunit/wasm/streaming-error-position.js +++ b/deps/v8/test/mjsunit/wasm/streaming-error-position.js @@ -303,11 +303,11 @@ function testErrorPosition(bytes, pos, test_name) { 1, // functions count 4, // body size 0, // locals count - kExprGetLocal, 0, // Access a non-existing local + kExprLocalGet, 0, // Access a non-existing local kExprEnd // -- ]); - // Find error at the index of kExprGetLocal. + // Find error at the index of kExprLocalGet. let pos = bytes.length - 1 - 1; testErrorPosition(bytes, pos, 'testInvalidCode'); })(); @@ -334,7 +334,7 @@ function testErrorPosition(bytes, pos, test_name) { 0, // section length (too big) ]); - // Find error at the index of kExprGetLocal. + // Find error at the index of kExprLocalGet. let pos = bytes.length - 1; testErrorPosition(bytes, pos, 'testCodeSectionSizeZero'); })(); diff --git a/deps/v8/test/mjsunit/wasm/table-access.js b/deps/v8/test/mjsunit/wasm/table-access.js index b91934d949887c..3e718cf06c19ad 100644 --- a/deps/v8/test/mjsunit/wasm/table-access.js +++ b/deps/v8/test/mjsunit/wasm/table-access.js @@ -11,14 +11,14 @@ function addTableWithAccessors(builder, type, size, name) { const table = builder.addTable(type, size); const set_sig = makeSig([kWasmI32, type], []); builder.addFunction('set_' + name, set_sig) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kExprTableSet, table.index]) .exportFunc(); const get_sig = makeSig([kWasmI32], [type]); builder.addFunction('get_' + name, get_sig) - .addBody([kExprGetLocal, 0, kExprTableGet, table.index]) + .addBody([kExprLocalGet, 0, kExprTableGet, table.index]) .exportFunc(); } @@ -109,10 +109,10 @@ const dummy_func = exports.set_table_func1; const f2 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value2]); const f3 = builder.addFunction('f', kSig_i_v).addBody([kExprI32Const, value3]); builder.addFunction('get_t1', kSig_a_i) - .addBody([kExprGetLocal, 0, kExprTableGet, t1]) + .addBody([kExprLocalGet, 0, kExprTableGet, t1]) .exportFunc(); builder.addFunction('get_t2', kSig_a_i) - .addBody([kExprGetLocal, 0, kExprTableGet, t2]) + .addBody([kExprLocalGet, 0, kExprTableGet, t2]) .exportFunc(); const offset1 = 3; diff --git a/deps/v8/test/mjsunit/wasm/table-copy-anyref.js b/deps/v8/test/mjsunit/wasm/table-copy-anyref.js index d5cddb3ed6f05f..8b2546a594da72 100644 --- a/deps/v8/test/mjsunit/wasm/table-copy-anyref.js +++ b/deps/v8/test/mjsunit/wasm/table-copy-anyref.js @@ -17,7 +17,7 @@ builder.addTable(kWasmAnyFunc, 1000); builder.addFunction('copy', kSig_v_iii) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix, + kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kNumericPrefix, kExprTableCopy, kTableZero, kTableZero ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/table-copy.js b/deps/v8/test/mjsunit/wasm/table-copy.js index db0dc831912637..ead06f4f23f3f7 100644 --- a/deps/v8/test/mjsunit/wasm/table-copy.js +++ b/deps/v8/test/mjsunit/wasm/table-copy.js @@ -38,7 +38,7 @@ function assertCall(call, ...elems) { for (let i = 0; i < kTableSize; i++) { let f = builder.addFunction("", kSig_i_v) .addBody([ - kExprGetGlobal, g, + kExprGlobalGet, g, ...wasmI32Const(i), kExprI32Add ]); @@ -47,15 +47,15 @@ function assertCall(call, ...elems) { builder.addFunction("copy", sig_v_iii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, - kExprGetLocal, 2, + kExprLocalGet, 0, + kExprLocalGet, 1, + kExprLocalGet, 2, kNumericPrefix, kExprTableCopy, kTableZero, kTableZero]) .exportAs("copy"); builder.addFunction("call", sig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_i_v, kTableZero]) .exportAs("call"); diff --git a/deps/v8/test/mjsunit/wasm/table-fill.js b/deps/v8/test/mjsunit/wasm/table-fill.js index ed5938f9086ef1..64c4d7732df6e9 100644 --- a/deps/v8/test/mjsunit/wasm/table-fill.js +++ b/deps/v8/test/mjsunit/wasm/table-fill.js @@ -32,13 +32,13 @@ const internal_func = builder.addTable(kWasmAnyFunc, size, maximum).index; for (index of [import_ref, internal_ref]) { builder.addFunction(`fill${index}`, kSig_v_iri) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix, + kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kNumericPrefix, kExprTableFill, index ]) .exportFunc(); builder.addFunction(`get${index}`, kSig_r_i) - .addBody([kExprGetLocal, 0, kExprTableGet, index]) + .addBody([kExprLocalGet, 0, kExprTableGet, index]) .exportFunc(); } @@ -47,13 +47,13 @@ const sig_index = builder.addType(kSig_i_v); for (index of [import_func, internal_func]) { builder.addFunction(`fill${index}`, kSig_v_iai) .addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprGetLocal, 2, kNumericPrefix, + kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kNumericPrefix, kExprTableFill, index ]) .exportFunc(); builder.addFunction(`call${index}`, kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallIndirect, sig_index, index]) + .addBody([kExprLocalGet, 0, kExprCallIndirect, sig_index, index]) .exportFunc(); } diff --git a/deps/v8/test/mjsunit/wasm/table-grow-from-wasm.js b/deps/v8/test/mjsunit/wasm/table-grow-from-wasm.js index 5b37af32c20d85..80184073481373 100644 --- a/deps/v8/test/mjsunit/wasm/table-grow-from-wasm.js +++ b/deps/v8/test/mjsunit/wasm/table-grow-from-wasm.js @@ -28,8 +28,8 @@ function testGrowInternalAnyRefTable(table_index) { builder.addTable(kWasmAnyRef, initial_size).index; } builder.addFunction('grow', kSig_i_ri) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, table_index]) .exportFunc(); @@ -38,7 +38,7 @@ function testGrowInternalAnyRefTable(table_index) { .exportFunc(); builder.addFunction('get', kSig_r_i) - .addBody([kExprGetLocal, 0, kExprTableGet, table_index]) + .addBody([kExprLocalGet, 0, kExprTableGet, table_index]) .exportFunc(); const instance = builder.instantiate(); @@ -75,8 +75,8 @@ function testGrowInternalAnyFuncTable(table_index) { builder.addTable(kWasmAnyFunc, size).index; } builder.addFunction('grow', kSig_i_ai) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, table_index]) .exportFunc(); @@ -86,7 +86,7 @@ function testGrowInternalAnyFuncTable(table_index) { const sig_index = builder.addType(kSig_i_v); builder.addFunction('call', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallIndirect, sig_index, table_index]) + .addBody([kExprLocalGet, 0, kExprCallIndirect, sig_index, table_index]) .exportFunc(); const instance = builder.instantiate(); @@ -118,8 +118,8 @@ testGrowInternalAnyFuncTable(9); const builder = new WasmModuleBuilder(); const table_index = builder.addImportedTable("imp", "table", size, undefined, kWasmAnyRef); builder.addFunction('grow', kSig_i_ri) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, table_index]) .exportFunc(); @@ -164,26 +164,26 @@ testGrowInternalAnyFuncTable(9); const internal_func = builder.addTable(kWasmAnyFunc, initial, maximum).index; builder.addFunction('grow_imported_ref', kSig_i_ri) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, import_ref]) .exportFunc(); builder.addFunction('grow_imported_func', kSig_i_ai) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, import_func]) .exportFunc(); builder.addFunction('grow_internal_ref', kSig_i_ri) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, internal_ref]) .exportFunc(); builder.addFunction('grow_internal_func', kSig_i_ai) - .addBody([kExprGetLocal, 0, - kExprGetLocal, 1, + .addBody([kExprLocalGet, 0, + kExprLocalGet, 1, kNumericPrefix, kExprTableGrow, internal_func]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/table-grow.js b/deps/v8/test/mjsunit/wasm/table-grow.js index a8508b4bdd0b83..d2b7970bfa1b1e 100644 --- a/deps/v8/test/mjsunit/wasm/table-grow.js +++ b/deps/v8/test/mjsunit/wasm/table-grow.js @@ -10,20 +10,20 @@ function addFunctions(builder) { let sig_index = builder.addType(kSig_i_ii); let mul = builder.addFunction("mul", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Mul // -- ]); let add = builder.addFunction("add", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Add // -- ]); let sub = builder.addFunction("sub", sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprI32Sub // -- ]); return {mul: mul, add: add, sub: sub}; @@ -45,7 +45,7 @@ function addMain(builder) { builder.addFunction("main", kSig_i_i) .addBody([ kExprI32Const, 0, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero]) .exportAs("main"); } @@ -53,7 +53,7 @@ function addMain(builder) { let id = (() => { // identity exported function let builder = new WasmModuleBuilder(); builder.addFunction("id", kSig_i_i) - .addBody([kExprGetLocal, 0]) + .addBody([kExprLocalGet, 0]) .exportAs("id"); let module = new WebAssembly.Module(builder.toBuffer()); return (new WebAssembly.Instance(builder.toModule())).exports.id; @@ -125,8 +125,8 @@ let id = (() => { // identity exported function builder.addFunction("main", kSig_i_ii) .addBody([ kExprI32Const, 15, // -- - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallIndirect, 0, kTableZero]) // -- .exportAs("main"); @@ -254,14 +254,14 @@ let id = (() => { // identity exported function builder.addImportedTable("x", "table", 1, kMaxTableSize); builder.addFunction("add", index_i_ii) .addBody([ - kExprGetLocal, 0, - kExprGetLocal, 1, + kExprLocalGet, 0, + kExprLocalGet, 1, kExprI32Add]); builder.addFunction("main", index_i_i) .addBody([ kExprI32Const, 5, kExprI32Const, 5, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, index_i_ii, kTableZero]) .exportAs("main"); builder.addElementSegment(0, 0, false, [0]); diff --git a/deps/v8/test/mjsunit/wasm/test-wasm-module-builder.js b/deps/v8/test/mjsunit/wasm/test-wasm-module-builder.js index 96d3a0bac5c72b..e43eaf7258bd1d 100644 --- a/deps/v8/test/mjsunit/wasm/test-wasm-module-builder.js +++ b/deps/v8/test/mjsunit/wasm/test-wasm-module-builder.js @@ -44,7 +44,7 @@ function instantiate(buffer, ffi) { let builder = new WasmModuleBuilder(); builder.addFunction(undefined, kSig_i_i) .addLocals({i32_count: 1}) - .addBody([kExprGetLocal, 0, kExprSetLocal, 1, kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1]) .exportAs('main'); var buffer = builder.toBuffer(debug); @@ -67,7 +67,7 @@ function instantiate(buffer, ffi) { let builder = new WasmModuleBuilder(); builder.addFunction(undefined, makeSig_r_x(p.type, p.type)) .addLocals(p.locals) - .addBody([kExprGetLocal, 0, kExprSetLocal, 1, kExprGetLocal, 1]) + .addBody([kExprLocalGet, 0, kExprLocalSet, 1, kExprLocalGet, 1]) .exportAs('main'); var buffer = builder.toBuffer(debug); @@ -81,10 +81,10 @@ function instantiate(buffer, ffi) { print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('add', kSig_i_ii).addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add ]); builder.addFunction('main', kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprCallFunction, 0]) .exportAs('main'); var instance = builder.instantiate(); @@ -96,11 +96,11 @@ function instantiate(buffer, ffi) { print(arguments.callee.name); let builder = new WasmModuleBuilder(); builder.addFunction('add', kSig_i_ii).addBody([ - kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add + kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add ]); builder.addFunction('main', kSig_i_iii) .addBody([ - kExprGetLocal, 1, kExprGetLocal, 2, kExprGetLocal, 0, kExprCallIndirect, + kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 0, kExprCallIndirect, 0, kTableZero ]) .exportAs('main'); @@ -117,7 +117,7 @@ function instantiate(buffer, ffi) { let builder = new WasmModuleBuilder(); builder.addMemory(1, 1, false); builder.addFunction('load', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0]) + .addBody([kExprLocalGet, 0, kExprI32LoadMem, 0, 0]) .exportAs('load'); builder.addDataSegment(0, [9, 9, 9, 9]); diff --git a/deps/v8/test/mjsunit/wasm/trap-location.js b/deps/v8/test/mjsunit/wasm/trap-location.js index d893f97d625405..91cb0d07214fb1 100644 --- a/deps/v8/test/mjsunit/wasm/trap-location.js +++ b/deps/v8/test/mjsunit/wasm/trap-location.js @@ -54,27 +54,27 @@ builder.addFunction("main", kSig_i_i) .addBody([ // offset 1 kExprBlock, kWasmI32, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 2, kExprI32LtU, kExprIf, kWasmStmt, // offset 9 kExprI32Const, 0x7e /* -2 */, - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32DivU, // offset 15 kExprI32LoadMem, 0, 0, kExprBr, 1, kExprEnd, // offset 21 - kExprGetLocal, 0, + kExprLocalGet, 0, kExprI32Const, 2, kExprI32Eq, kExprIf, kWasmStmt, kExprUnreachable, kExprEnd, // offset 30 - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, kTableZero, kExprEnd, ]) diff --git a/deps/v8/test/mjsunit/wasm/type-reflection-with-anyref.js b/deps/v8/test/mjsunit/wasm/type-reflection-with-anyref.js index b7a7ee7969b64f..863a59aaa4ef88 100644 --- a/deps/v8/test/mjsunit/wasm/type-reflection-with-anyref.js +++ b/deps/v8/test/mjsunit/wasm/type-reflection-with-anyref.js @@ -57,13 +57,13 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); table.set(0, f1); builder.addFunction('call0', kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, table_index0 ]) .exportFunc(); builder.addFunction('call1', kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, table_index1 ]) .exportFunc(); diff --git a/deps/v8/test/mjsunit/wasm/type-reflection-with-mv.js b/deps/v8/test/mjsunit/wasm/type-reflection-with-mv.js new file mode 100644 index 00000000000000..0a7e98492fcf41 --- /dev/null +++ b/deps/v8/test/mjsunit/wasm/type-reflection-with-mv.js @@ -0,0 +1,80 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --experimental-wasm-type-reflection --expose-gc --experimental-wasm-mv + +(function TestFunctionConstructedCoercions() { + let obj1 = { valueOf: _ => 123.45 }; + let obj2 = { toString: _ => "456" }; + let gcer = { valueOf: _ => gc() }; + let testcases = [ + { params: { sig: [], + val: [], + exp: [], }, + result: { sig: ["i32", "f32"], + val: [42.7, "xyz"], + exp: [42, NaN] }, + }, + { params: { sig: [], + val: [], + exp: [], }, + result: { sig: ["i32", "f32", "f64"], + val: (function* () { yield obj1; yield obj2; yield "789" })(), + exp: [123, 456, 789], }, + }, + { params: { sig: [], + val: [], + exp: [], }, + result: { sig: ["i32", "f32", "f64"], + val: new Proxy([gcer, {}, "xyz"], { + get: function(obj, prop) { return Reflect.get(obj, prop); } + }), + exp: [0, NaN, NaN], }, + }, + ]; + testcases.forEach(function({params, result}) { + let p = params.sig; let r = result.sig; var params_after; + function testFun() { params_after = arguments; return result.val; } + let fun = new WebAssembly.Function({parameters:p, results:r}, testFun); + let result_after = fun.apply(undefined, params.val); + assertArrayEquals(params.exp, params_after); + assertEquals(result.exp, result_after); + }); +})(); + +(function TestFunctionConstructedCoercionsThrow() { + let proxy_throw = new Proxy([1, 2], { + get: function(obj, prop) { + if (prop == 1) { + throw new Error("abc"); + } + return Reflect.get(obj, prop); }, + }); + function* generator_throw() { + yield 1; + throw new Error("def"); + } + let testcases = [ + { val: 0, + error: Error, + msg: /not iterable/ }, + { val: [1], + error: TypeError, + msg: /multi-return length mismatch/ }, + { val: [1, 2, 3], + error: TypeError, + msg: /multi-return length mismatch/ }, + { val: proxy_throw, + error: Error, + msg: /abc/ }, + { val: generator_throw(), + error: Error, + msg: /def/ }, + ]; + testcases.forEach(function({val, error, msg}) { + fun = new WebAssembly.Function({parameters:[], results:["i32", "i32"]}, + () => val); + assertThrows(fun, error, msg); + }) +})(); diff --git a/deps/v8/test/mjsunit/wasm/type-reflection.js b/deps/v8/test/mjsunit/wasm/type-reflection.js index a9a0b871436053..bac877d187e596 100644 --- a/deps/v8/test/mjsunit/wasm/type-reflection.js +++ b/deps/v8/test/mjsunit/wasm/type-reflection.js @@ -533,7 +533,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); table.set(0, fun1); builder.addFunction('main', kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, table_index ]) .exportFunc(); @@ -554,7 +554,7 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); table.set(0, fun); builder.addFunction('main', kSig_v_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallIndirect, sig_index, table_index, kExprDrop ]) diff --git a/deps/v8/test/mjsunit/wasm/unicode.js b/deps/v8/test/mjsunit/wasm/unicode.js index 2b5f5ce9fe74d3..73dc0608c6edbe 100644 --- a/deps/v8/test/mjsunit/wasm/unicode.js +++ b/deps/v8/test/mjsunit/wasm/unicode.js @@ -9,7 +9,7 @@ function checkImport( var builder = new WasmModuleBuilder(); builder.addImport(imported_module_name, imported_function_name, kSig_i_i); builder.addFunction('call_imp', kSig_i_i) - .addBody([kExprGetLocal, 0, kExprCallFunction, 0]) + .addBody([kExprLocalGet, 0, kExprCallFunction, 0]) .exportFunc(); let imp = i => i + 3; @@ -29,10 +29,10 @@ function checkExports( exported_name_add) { var builder = new WasmModuleBuilder(); builder.addFunction(internal_name_mul, kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Mul]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Mul]) .exportAs(exported_name_mul); builder.addFunction(internal_name_add, kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportAs(exported_name_add); let instance = builder.instantiate(); diff --git a/deps/v8/test/mjsunit/wasm/user-properties-exported.js b/deps/v8/test/mjsunit/wasm/user-properties-exported.js index 80f2077f3c44f9..0b2f249e05d690 100644 --- a/deps/v8/test/mjsunit/wasm/user-properties-exported.js +++ b/deps/v8/test/mjsunit/wasm/user-properties-exported.js @@ -13,7 +13,7 @@ load("test/mjsunit/wasm/user-properties-common.js"); var builder = new WasmModuleBuilder(); builder.addFunction("exp", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .exportAs("exp"); let module1 = builder.toModule(); diff --git a/deps/v8/test/mjsunit/wasm/user-properties-module.js b/deps/v8/test/mjsunit/wasm/user-properties-module.js index 69a1f898d74648..84727e1b537956 100644 --- a/deps/v8/test/mjsunit/wasm/user-properties-module.js +++ b/deps/v8/test/mjsunit/wasm/user-properties-module.js @@ -14,7 +14,7 @@ load("test/mjsunit/wasm/user-properties-common.js"); builder.addImport("m", "f", kSig_i_i); builder.addFunction("main", kSig_i_i) .addBody([ - kExprGetLocal, 0, + kExprLocalGet, 0, kExprCallFunction, 0]) .exportAs("main"); builder.addMemory(1, 1, false) diff --git a/deps/v8/test/mjsunit/wasm/wasm-math-intrinsic.js b/deps/v8/test/mjsunit/wasm/wasm-math-intrinsic.js index 3b1a333c7fc0ff..3d9512cf85f914 100644 --- a/deps/v8/test/mjsunit/wasm/wasm-math-intrinsic.js +++ b/deps/v8/test/mjsunit/wasm/wasm-math-intrinsic.js @@ -140,7 +140,7 @@ function genUnop(name, sig) { builder.addImport('Math', name, sig_index); builder.addFunction('main', sig_index) .addBody([ - kExprGetLocal, 0, // -- + kExprLocalGet, 0, // -- kExprCallFunction, 0 ]) // -- .exportAs('main'); @@ -155,8 +155,8 @@ function genBinop(name, sig) { builder.addImport('Math', name, sig_index); builder.addFunction('main', sig_index) .addBody([ - kExprGetLocal, 0, // -- - kExprGetLocal, 1, // -- + kExprLocalGet, 0, // -- + kExprLocalGet, 1, // -- kExprCallFunction, 0 ]) // -- .exportAs('main'); diff --git a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js index 45af969d09fcbb..b4d7cae41ba022 100644 --- a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js +++ b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js @@ -84,6 +84,7 @@ let kSharedHasMaximumFlag = 3; let kActiveNoIndex = 0; let kPassive = 1; let kActiveWithIndex = 2; +let kPassiveWithElements = 5; // Function declaration flags let kDeclFunctionName = 0x01; @@ -209,11 +210,11 @@ let kExprReturnCall = 0x12; let kExprReturnCallIndirect = 0x13; let kExprDrop = 0x1a; let kExprSelect = 0x1b; -let kExprGetLocal = 0x20; -let kExprSetLocal = 0x21; -let kExprTeeLocal = 0x22; -let kExprGetGlobal = 0x23; -let kExprSetGlobal = 0x24; +let kExprLocalGet = 0x20; +let kExprLocalSet = 0x21; +let kExprLocalTee = 0x22; +let kExprGlobalGet = 0x23; +let kExprGlobalSet = 0x24; let kExprTableGet = 0x25; let kExprTableSet = 0x26; let kExprI32LoadMem = 0x28; @@ -464,6 +465,9 @@ let kExprI64AtomicCompareExchange16U = 0x4d; let kExprI64AtomicCompareExchange32U = 0x4e; // Simd opcodes. +let kExprS128LoadMem = 0x00; +let kExprS128StoreMem = 0x01; +let kExprI32x4Splat = 0x0c; let kExprF32x4Min = 0x9e; // Compilation hint constants. @@ -1093,7 +1097,7 @@ class WasmModuleBuilder { } } else { // Emit a global-index initializer. - section.emit_u8(kExprGetGlobal); + section.emit_u8(kExprGlobalGet); section.emit_u32v(global.init_index); } section.emit_u8(kExprEnd); // end of init expression @@ -1158,19 +1162,22 @@ class WasmModuleBuilder { section.emit_u32v(init.table); } if (init.is_global) { - section.emit_u8(kExprGetGlobal); + section.emit_u8(kExprGlobalGet); } else { section.emit_u8(kExprI32Const); } section.emit_u32v(init.base); section.emit_u8(kExprEnd); + if (init.table != 0) { + section.emit_u8(kExternalFunction); + } section.emit_u32v(init.array.length); for (let index of init.array) { section.emit_u32v(index); } } else { // Passive segment. - section.emit_u8(kPassive); // flags + section.emit_u8(kPassiveWithElements); // flags section.emit_u8(kWasmAnyFunc); section.emit_u32v(init.array.length); for (let index of init.array) { @@ -1290,7 +1297,7 @@ class WasmModuleBuilder { section.emit_u8(0); // linear memory index 0 / flags if (seg.is_global) { // initializer is a global variable - section.emit_u8(kExprGetGlobal); + section.emit_u8(kExprGlobalGet); section.emit_u32v(seg.addr); } else { // initializer is a constant diff --git a/deps/v8/test/mjsunit/wasm/worker-interpreter.js b/deps/v8/test/mjsunit/wasm/worker-interpreter.js index ccf6d279a081cd..9a7ab60756e395 100644 --- a/deps/v8/test/mjsunit/wasm/worker-interpreter.js +++ b/deps/v8/test/mjsunit/wasm/worker-interpreter.js @@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function TestPostInterpretedModule() { let builder = new WasmModuleBuilder(); let add = builder.addFunction("add", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); let module = builder.toModule(); diff --git a/deps/v8/test/mjsunit/wasm/worker-module.js b/deps/v8/test/mjsunit/wasm/worker-module.js index f626263b257285..76d84daabae90f 100644 --- a/deps/v8/test/mjsunit/wasm/worker-module.js +++ b/deps/v8/test/mjsunit/wasm/worker-module.js @@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function TestPostModule() { let builder = new WasmModuleBuilder(); builder.addFunction("add", kSig_i_ii) - .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]) + .addBody([kExprLocalGet, 0, kExprLocalGet, 1, kExprI32Add]) .exportFunc(); let module = builder.toModule(); diff --git a/deps/v8/test/mkgrokdump/mkgrokdump.cc b/deps/v8/test/mkgrokdump/mkgrokdump.cc index 8c07576d3aab0f..5f39a063e4d7a0 100644 --- a/deps/v8/test/mkgrokdump/mkgrokdump.cc +++ b/deps/v8/test/mkgrokdump/mkgrokdump.cc @@ -26,10 +26,9 @@ static const char* kHeader = "\n" "# List of known V8 instance types.\n"; -// Non-snapshot builds allocate objects to different places. // Debug builds emit debug code, affecting code object sizes. // Embedded builtins cause objects to be allocated in different locations. -#if defined(V8_EMBEDDED_BUILTINS) && defined(V8_USE_SNAPSHOT) && !defined(DEBUG) +#if defined(V8_EMBEDDED_BUILTINS) && !defined(DEBUG) static const char* kBuild = "shipping"; #else static const char* kBuild = "non-shipping"; @@ -97,6 +96,14 @@ static void DumpKnownObject(FILE* out, i::Heap* heap, const char* space_name, #undef RO_ROOT_LIST_CASE } +static void DumpSpaceFirstPageAddress(FILE* out, i::PagedSpace* space) { + const char* name = space->name(); + i::Address first_page = reinterpret_cast<i::Address>(space->first_page()); + i::Tagged_t compressed = i::CompressTagged(first_page); + uintptr_t unsigned_compressed = static_cast<uint32_t>(compressed); + i::PrintF(out, " 0x%08" V8PRIxPTR ": \"%s\",\n", unsigned_compressed, name); +} + static int DumpHeapConstants(FILE* out, const char* argv0) { // Start up V8. std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); @@ -164,6 +171,29 @@ static int DumpHeapConstants(FILE* out, const char* argv0) { i::PrintF(out, "}\n"); } + if (COMPRESS_POINTERS_BOOL) { + // Dump a list of addresses for the first page of each space that contains + // objects in the other tables above. This is only useful if two + // assumptions hold: + // 1. Those pages are positioned deterministically within the heap + // reservation block during snapshot deserialization. + // 2. Those pages cannot ever be moved (such as by compaction). + i::PrintF(out, + "\n# Lower 32 bits of first page addresses for various heap " + "spaces.\n"); + i::PrintF(out, "HEAP_FIRST_PAGES = {\n"); + i::PagedSpaceIterator it(heap); + for (i::PagedSpace* s = it.Next(); s != nullptr; s = it.Next()) { + // Code page is different on Windows vs Linux (bug v8:9844), so skip it. + if (s->identity() == i::CODE_SPACE) { + continue; + } + DumpSpaceFirstPageAddress(out, s); + } + DumpSpaceFirstPageAddress(out, read_only_heap->read_only_space()); + i::PrintF(out, "}\n"); + } + // Dump frame markers i::PrintF(out, "\n# List of known V8 Frame Markers.\n"); #define DUMP_MARKER(T, class) i::PrintF(out, " \"%s\",\n", #T); diff --git a/deps/v8/test/mozilla/mozilla.status b/deps/v8/test/mozilla/mozilla.status index 5a1c89ac9efc89..78630381f9f0af 100644 --- a/deps/v8/test/mozilla/mozilla.status +++ b/deps/v8/test/mozilla/mozilla.status @@ -1011,6 +1011,8 @@ #BUG(3837): Crashes due to C stack overflow. 'js1_5/extensions/regress-355497': [SKIP], + # Slow test + 'js1_5/Regress/regress-80981': [PASS, SLOW], }], # 'arch == arm and simulator_run' ['arch == arm64 and simulator_run', { @@ -1035,6 +1037,9 @@ #BUG(3152): Avoid C stack overflow. 'js1_5/extensions/regress-355497': [FAIL_OK, '--sim-stack-size=512'], + + # Slow without pointer compression + 'js1_5/Regress/regress-80981': [PASS, ['not pointer_compression', SLOW]], }], # 'arch == arm64 and simulator_run' ['system == android', { diff --git a/deps/v8/test/test262/OWNERS b/deps/v8/test/test262/OWNERS index 246672d0ff0832..56c71e23b1ecf7 100644 --- a/deps/v8/test/test262/OWNERS +++ b/deps/v8/test/test262/OWNERS @@ -1,2 +1,3 @@ adamk@chromium.org gsathya@chromium.org +syg@chromium.org diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index 7ccb304a0b05a0..3f82c49d1e91ed 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -65,7 +65,13 @@ # Intl tests which require flags. # https://bugs.chromium.org/p/v8/issues/detail?id=9154 'intl402/NumberFormat/numbering-system-options': ['--harmony-intl-add-calendar-numbering-system'], + 'intl402/DateTimeFormat/constructor-calendar-numberingSystem-order': ['--harmony-intl-add-calendar-numbering-system'], 'intl402/DateTimeFormat/numbering-system-calendar-options': ['--harmony-intl-add-calendar-numbering-system'], + 'intl402/DateTimeFormat/constructor-options-throwing-getters': ['--harmony-intl-add-calendar-numbering-system'], + 'intl402/NumberFormat/constructor-options-throwing-getters': ['--harmony-intl-add-calendar-numbering-system'], + 'intl402/NumberFormat/constructor-numberingSystem-order': ['--harmony-intl-add-calendar-numbering-system'], + 'intl402/DateTimeFormat/prototype/formatToParts/pattern-on-calendar': ['--harmony-intl-other-calendars'], + 'intl402/DateTimeFormat/prototype/formatToParts/related-year': ['--harmony-intl-other-calendars'], # https://bugs.chromium.org/p/v8/issues/detail?id=9084 'intl402/supportedLocalesOf-consistent-with-resolvedOptions': [FAIL], @@ -457,9 +463,6 @@ 'language/expressions/async-generator/generator-created-after-decl-inst': [FAIL], 'language/statements/async-generator/generator-created-after-decl-inst': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=9611 - 'language/statements/class/elements/private-field-is-visible-in-computed-properties': [SKIP], - # https://github.com/tc39/test262/issues/2034 'language/expressions/postfix-decrement/arguments': [SKIP], 'language/expressions/postfix-decrement/arguments-nostrict': [SKIP], @@ -484,23 +487,14 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=9049 'language/comments/hashbang/use-strict': [SKIP], - # https://bugs.chromium.org/p/v8/issues/detail?id=9229 - 'language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage': [FAIL], - 'language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-chained-usage': [FAIL], - 'language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-function-expression': [FAIL], - 'language/expressions/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-recursive': [FAIL], - 'language/statements/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage': [FAIL], - 'language/statements/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-chained-usage': [FAIL], - 'language/statements/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-function-expression': [FAIL], - 'language/statements/class/elements/syntax/early-errors/grammar-private-environment-on-class-heritage-recursive': [FAIL], - # https://bugs.chromium.org/p/v8/issues/detail?id=8179 + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 # # These tests require exception handling support which is currently # blocked on landing https://chromium-review.googlesource.com/c/v8/v8/+/1655655 'built-ins/FinalizationGroup/FinalizationGroupCleanupIteratorPrototype/next-job-not-active-throws': [FAIL], 'built-ins/FinalizationGroup/prototype/cleanupSome/poisoned-callback-throws': [FAIL], - 'built-ins/FinalizationGroup/prototype/cleanupSome/poisoned-cleanup-callback-throws': [FAIL], + # 'built-ins/FinalizationGroup/prototype/cleanupSome/poisoned-cleanup-callback-throws': [FAIL], # https://bugs.chromium.org/p/v8/issues/detail?id=8179 # @@ -510,23 +504,28 @@ 'built-ins/FinalizationGroup/prototype/register/return-undefined-register-itself': [FAIL], # https://bugs.chromium.org/p/v8/issues/detail?id=8179 + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 # # This test has target === holdings which throws, changing holdings to # { y } makes the test pass. - 'built-ins/FinalizationGroup/prototype/cleanupSome/cleanup-prevented-with-reference': [FAIL], + # 'built-ins/FinalizationGroup/prototype/cleanupSome/cleanup-prevented-with-reference': [FAIL], # https://github.com/tc39/test262/issues/2256 - 'built-ins/FinalizationGroup/prototype/cleanupSome/cleanup-prevented-with-unregister': [FAIL], + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 + # 'built-ins/FinalizationGroup/prototype/cleanupSome/cleanup-prevented-with-unregister': [FAIL], # https://github.com/tc39/test262/issues/2239 - 'built-ins/WeakRef/prototype/deref/gc-cleanup-not-prevented-with-wr-deref': [FAIL], - 'built-ins/FinalizationGroup/prototype/cleanupSome/gc-cleanup-not-prevented-with-wr-deref': [FAIL], + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 + # 'built-ins/WeakRef/prototype/deref/gc-cleanup-not-prevented-with-wr-deref': [FAIL], + # 'built-ins/FinalizationGroup/prototype/cleanupSome/gc-cleanup-not-prevented-with-wr-deref': [FAIL], # https://github.com/tc39/test262/issues/2255 - 'built-ins/FinalizationGroup/prototype/cleanupSome/iterator-holdings-multiple-values': [FAIL], + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 + # 'built-ins/FinalizationGroup/prototype/cleanupSome/iterator-holdings-multiple-values': [FAIL], # https://github.com/tc39/test262/issues/2260 - 'built-ins/FinalizationGroup/prototype/cleanupSome/return-undefined-with-gc': [FAIL], + # Temporarily removed pending https://github.com/tc39/test262/issues/2339 + # 'built-ins/FinalizationGroup/prototype/cleanupSome/return-undefined-with-gc': [FAIL], # https://bugs.chromium.org/p/v8/issues/detail?id=9612 'intl402/DateTimeFormat/prototype/formatRange/fractionalSecondDigits': [FAIL], @@ -534,267 +533,30 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=9613 'intl402/Intl/getCanonicalLocales/canonicalized-tags': [FAIL], 'intl402/Intl/getCanonicalLocales/grandfathered': [FAIL], - 'intl402/Intl/getCanonicalLocales/invalid-tags': [FAIL], 'intl402/Intl/getCanonicalLocales/non-iana-canon': [FAIL], 'intl402/Intl/getCanonicalLocales/preferred-grandfathered': [FAIL], 'intl402/Intl/getCanonicalLocales/preferred-variant': [FAIL], - 'intl402/language-tags-invalid': [FAIL], - 'intl402/ListFormat/constructor/constructor/locales-valid': [FAIL], 'intl402/Locale/constructor-non-iana-canon': [FAIL], + 'intl402/Locale/likely-subtags-grandfathered': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=9742 + 'intl402/Locale/getters': [FAIL], + + # https://github.com/tc39/test262/pull/2349 'intl402/Locale/constructor-options-region-valid': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=9741 'intl402/Locale/constructor-tag': [FAIL], - 'intl402/Locale/getters': [FAIL], - 'intl402/Locale/likely-subtags-grandfathered': [FAIL], - 'intl402/PluralRules/prototype/resolvedOptions/order': [FAIL], - 'intl402/RelativeTimeFormat/constructor/constructor/locales-valid': [FAIL], - 'intl402/Segmenter/constructor/constructor/locales-valid': [FAIL], - - # https://bugs.chromium.org/p/v8/issues/detail?id=9647 - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-break-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-case-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-catch-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-class-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-const-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-continue-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-debugger-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-default-escaped-ext': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-default-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-delete-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-do-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-else-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-enum-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-export-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-extends-escaped-ext': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-extends-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-finally-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-for-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-function-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-if-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-import-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-in-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-instanceof-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-new-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-return-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-super-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-switch-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-this-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-throw-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-try-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-typeof-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-var-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-void-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-while-escaped': [FAIL], - 'language/expressions/assignment/dstr/ident-name-prop-name-literal-with-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-break-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-case-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-catch-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-class-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-const-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-continue-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-debugger-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-default-escaped-ext': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-default-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-delete-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-do-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-else-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-enum-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-export-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-extends-escaped-ext': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-extends-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-finally-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-for-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-function-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-if-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-import-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-in-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-instanceof-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-new-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-return-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-super-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-switch-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-this-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-throw-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-try-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-typeof-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-var-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-void-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-while-escaped': [FAIL], - 'language/expressions/assignment/member-expr-ident-name-with-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-break-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-case-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-catch-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-class-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-const-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-continue-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-debugger-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-default-escaped-ext': [FAIL], - 'language/expressions/class/ident-name-method-def-default-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-delete-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-do-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-else-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-enum-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-export-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-extends-escaped-ext': [FAIL], - 'language/expressions/class/ident-name-method-def-extends-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-finally-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-for-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-function-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-if-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-import-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-in-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-instanceof-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-new-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-return-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-super-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-switch-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-this-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-throw-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-try-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-typeof-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-var-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-void-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-while-escaped': [FAIL], - 'language/expressions/class/ident-name-method-def-with-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-break-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-case-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-catch-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-class-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-const-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-continue-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-debugger-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-default-escaped-ext': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-default-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-delete-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-do-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-else-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-enum-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-export-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-extends-escaped-ext': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-extends-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-finally-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-for-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-function-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-if-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-import-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-in-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-instanceof-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-new-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-return-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-super-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-switch-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-this-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-throw-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-try-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-typeof-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-var-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-void-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-while-escaped': [FAIL], - 'language/expressions/object/covered-ident-name-prop-name-literal-with-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-break-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-case-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-catch-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-class-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-const-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-continue-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-debugger-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-default-escaped-ext': [FAIL], - 'language/expressions/object/ident-name-method-def-default-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-delete-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-do-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-else-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-enum-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-export-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-extends-escaped-ext': [FAIL], - 'language/expressions/object/ident-name-method-def-extends-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-finally-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-for-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-function-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-if-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-import-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-in-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-instanceof-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-new-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-return-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-super-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-switch-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-this-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-throw-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-try-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-typeof-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-var-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-void-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-while-escaped': [FAIL], - 'language/expressions/object/ident-name-method-def-with-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-break-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-case-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-catch-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-class-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-const-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-continue-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-debugger-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-default-escaped-ext': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-default-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-delete-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-do-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-else-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-enum-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-export-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-extends-escaped-ext': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-extends-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-finally-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-for-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-function-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-if-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-import-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-in-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-instanceof-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-new-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-return-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-super-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-switch-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-this-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-throw-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-try-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-typeof-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-var-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-void-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-while-escaped': [FAIL], - 'language/expressions/object/ident-name-prop-name-literal-with-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-break-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-case-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-catch-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-class-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-const-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-continue-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-debugger-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-default-escaped-ext': [FAIL], - 'language/statements/class/ident-name-method-def-default-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-delete-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-do-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-else-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-enum-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-export-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-extends-escaped-ext': [FAIL], - 'language/statements/class/ident-name-method-def-extends-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-finally-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-for-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-function-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-if-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-import-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-in-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-instanceof-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-new-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-return-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-super-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-switch-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-this-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-throw-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-try-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-typeof-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-var-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-void-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-while-escaped': [FAIL], - 'language/statements/class/ident-name-method-def-with-escaped': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=9800 + 'built-ins/String/prototype/matchAll/flags-undefined-throws': [FAIL], + 'built-ins/String/prototype/matchAll/flags-nonglobal-throws': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=9818 + 'built-ins/AsyncFunction/proto-from-ctor-realm': [FAIL], + + # https://bugs.chromium.org/p/v8/issues/detail?id=9819 + 'built-ins/Array/prototype/flatMap/array-like-objects-nested': [FAIL], ######################## NEEDS INVESTIGATION ########################### @@ -892,9 +654,10 @@ 'intl402/String/prototype/toLocaleUpperCase/special_casing_Lithuanian': [FAIL], 'intl402/String/prototype/toLocaleUpperCase/special_casing_Turkish': [FAIL], - # Unicode property escapes unavailable without i18n + # Unicode features unavaible without i18n, ie property escapes. 'built-ins/RegExp/property-escapes/*': [SKIP], 'built-ins/RegExp/named-groups/unicode-property-names': [SKIP], + 'built-ins/RegExp/match-indices/indices-array-unicode-property-names': [SKIP], }], # no_i18n == True ['arch == arm or arch == mipsel or arch == mips or arch == arm64 or arch == mips64 or arch == mips64el', { @@ -920,528 +683,6 @@ 'built-ins/TypedArray/prototype/set/typedarray-arg-set-values-same-buffer-other-type': [SKIP], }], -['asan == True', { - # BUG(v8:4653): Test262 tests which rely on quit() are not compatible with - # asan's --omit-quit flag. - 'built-ins/Promise/prototype/then/deferred-is-resolved-value': [SKIP], - 'language/expressions/dynamic-import/always-create-new-promise': [SKIP], - 'language/expressions/dynamic-import/assign-expr-get-value-abrupt-throws': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/additive-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/array-literal': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/arrow-function': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/await-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/await-identifier': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/call-expr-arguments': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/call-expr-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/call-expr-identifier': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/cover-call-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/cover-parenthesized-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/identifier': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/import-meta': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/lhs-assign-operator-assign-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/lhs-eq-assign-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/lhs-eq-assign-expr-nostrict': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/logical-and-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/logical-or-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/member-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/new-target': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/object-literal': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/tagged-function-call': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/ternary': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/this': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/unary-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/yield-assign-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/yield-expr': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/yield-identifier': [SKIP], - 'language/expressions/dynamic-import/assignment-expression/yield-star': [SKIP], - 'language/expressions/dynamic-import/await-import-evaluation': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-arrow-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-arrow-function-return-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-return-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-function-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-async-gen-return-await-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-block-labeled-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-do-while-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-else-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-function-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-if-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/nested-while-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-eval-rqstd-abrupt-typeerror': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-eval-rqstd-abrupt-urierror': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-eval-script-code-target': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-file-does-not-exist': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-instn-iee-err-ambiguous-import': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-instn-iee-err-circular': [SKIP], - 'language/expressions/dynamic-import/catch/top-level-import-catch-specifier-tostring-abrupt-rejects': [SKIP], - 'language/expressions/dynamic-import/custom-primitive': [SKIP], - 'language/expressions/dynamic-import/escape-sequence-import': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-cls-anon': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-cls-named': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-cls-name-meth': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-cls-anon': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-cls-named': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-cls-name-meth': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-fn-anon': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-fn-named': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-gen-anon': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-gen-named': [SKIP], - 'language/expressions/dynamic-import/eval-export-dflt-expr-in': [SKIP], - 'language/expressions/dynamic-import/eval-rqstd-once': [SKIP], - 'language/expressions/dynamic-import/eval-self-once-module': [SKIP], - 'language/expressions/dynamic-import/eval-self-once-script': [SKIP], - 'language/expressions/dynamic-import/for-await-resolution-and-error-agen': [SKIP], - 'language/expressions/dynamic-import/for-await-resolution-and-error-agen-yield': [SKIP], - 'language/expressions/dynamic-import/for-await-resolution-and-error': [SKIP], - 'language/expressions/dynamic-import/imported-self-update': [SKIP], - 'language/expressions/dynamic-import/indirect-resolution': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-define-own-property': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-delete-exported-init-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-delete-exported-init-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-delete-non-exported-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-delete-non-exported-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-extensible': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-nested-namespace-dflt-direct': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-nested-namespace-dflt-indirect': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-nested-namespace-props-nrml': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-own-property-str-found-init': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-own-property-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-own-property-sym': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-str-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-sym-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-get-sym-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-has-property-str-found-init': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-has-property-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-has-property-sym-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-has-property-sym-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-no-iterator': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-own-property-keys-sort': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-prevent-extensions-object': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-prevent-extensions-reflect': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-prop-descs': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-prototype': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-prototype-of': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-prototype-of-null': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-same-values-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-same-values-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-set-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/await-ns-Symbol-toStringTag': [SKIP], - 'language/expressions/dynamic-import/namespace/default-property-not-set-own': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-define-own-property': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-delete-exported-init-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-delete-exported-init-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-delete-non-exported-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-delete-non-exported-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-extensible': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-nested-namespace-dflt-direct': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-nested-namespace-dflt-indirect': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-nested-namespace-props-nrml': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-own-property-str-found-init': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-own-property-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-own-property-sym': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-str-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-sym-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-get-sym-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-has-property-str-found-init': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-has-property-str-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-has-property-sym-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-has-property-sym-not-found': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-no-iterator': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-own-property-keys-sort': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-prevent-extensions-object': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-prevent-extensions-reflect': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-prop-descs': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-prototype': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-prototype-of': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-prototype-of-null': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-same-values-no-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-same-values-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-set-strict': [SKIP], - 'language/expressions/dynamic-import/namespace/promise-then-ns-Symbol-toStringTag': [SKIP], - 'language/expressions/dynamic-import/returns-promise': [SKIP], - 'language/expressions/dynamic-import/reuse-namespace-object': [SKIP], - 'language/expressions/dynamic-import/reuse-namespace-object-from-import': [SKIP], - 'language/expressions/dynamic-import/reuse-namespace-object-from-script': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expression-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expression-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expression-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expression-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expression-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-arrow-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-await-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-await-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-await-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-await-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-await-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-return-await-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-return-await-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-return-await-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-return-await-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-arrow-function-return-await-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-await-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-await-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-await-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-await-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-await-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-return-await-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-return-await-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-return-await-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-return-await-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-function-return-await-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-gen-await-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-gen-await-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-gen-await-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-gen-await-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-async-gen-await-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-labeled-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-labeled-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-labeled-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-labeled-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-labeled-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-block-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-do-while-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-do-while-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-do-while-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-do-while-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-do-while-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-braceless-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-braceless-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-braceless-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-braceless-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-braceless-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-else-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-return-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-return-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-return-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-return-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-function-return-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-braceless-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-braceless-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-braceless-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-braceless-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-braceless-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-if-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-while-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-while-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-while-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-while-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-while-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-expression-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-expression-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-expression-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-expression-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-expression-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/nested-with-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/top-level-assignment-expr-not-optional': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/top-level-no-new-call-expression': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/top-level-no-rest-param': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/top-level-not-extensible-args': [SKIP], - 'language/expressions/dynamic-import/syntax/invalid/top-level-not-extensible-no-trailing-comma': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/callexpression-arguments': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/callexpression-templateliteral': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-assignment-expression-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-arrow-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-await-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-arrow-function-return-await-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-await-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-await-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-await-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-return-await-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-function-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-async-gen-await-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-labeled-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-labeled-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-labeled-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-block-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-do-while-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-do-while-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-do-while-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-braceless-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-braceless-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-braceless-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-else-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-return-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-return-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-return-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-function-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-braceless-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-braceless-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-braceless-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-if-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-while-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-while-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-while-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-expression-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-expression-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-expression-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/nested-with-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/new-covered-expression-is-valid': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/top-level-empty-str-is-valid-assign-expr': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/top-level-nested-imports': [SKIP], - 'language/expressions/dynamic-import/syntax/valid/top-level-script-code-valid': [SKIP], - 'language/expressions/dynamic-import/update-to-dynamic-import': [SKIP], - 'language/expressions/dynamic-import/usage-from-eval': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-arrow-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-arrow-function-return-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-return-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-function-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-async-gen-return-await-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-block-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-do-while-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-else-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-function-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-braceless-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-if-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/nested-while-import-then-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/syntax-nested-block-labeled-specifier-tostring': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-eval-gtbndng-indirect-update-dflt': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-eval-gtbndng-indirect-update': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-eval-script-code-host-resolves-module-code': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-is-call-expression-square-brackets': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-returns-thenable': [SKIP], - 'language/expressions/dynamic-import/usage/top-level-import-then-specifier-tostring': [SKIP], -}], # asan == True - ['asan == True or msan == True or tsan == True', { # https://bugs.chromium.org/p/v8/issues/detail?id=4639 # The failed allocation causes an asan/msan/tsan error @@ -1451,6 +692,12 @@ 'built-ins/SharedArrayBuffer/length-is-too-large-throws': [SKIP], }], # asan == True or msan == True or tsan == True +['system == android', { + # Android Arm64 failures + # https://bugs.chromium.org/p/v8/issues/detail?id=9845 + 'intl402/DateTimeFormat/prototype/formatToParts/related-year': [FAIL], +}], # system == android + ############################################################################## ['variant == jitless', { # https://crbug.com/v8/7777 diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py index 9aa91dfaef144c..d70e644d9b9dc9 100644 --- a/deps/v8/test/test262/testcfg.py +++ b/deps/v8/test/test262/testcfg.py @@ -44,26 +44,26 @@ # TODO(littledan): move the flag mapping into the status file FEATURE_FLAGS = { - 'Intl.DateTimeFormat-datetimestyle': '--harmony-intl-datetime-style', - 'Intl.DateTimeFormat-formatRange': '--harmony-intl-date-format-range', - 'Intl.NumberFormat-unified': '--harmony-intl-numberformat-unified', 'Intl.Segmenter': '--harmony-intl-segmenter', 'Intl.DateTimeFormat-dayPeriod': '--harmony-intl-dateformat-day-period', 'Intl.DateTimeFormat-quarter': '--harmony-intl-dateformat-quarter', 'Intl.DateTimeFormat-fractionalSecondDigits': '--harmony-intl-dateformat-fractional-second-digits', 'Symbol.prototype.description': '--harmony-symbol-description', 'export-star-as-namespace-from-module': '--harmony-namespace-exports', - 'BigInt': '--harmony-intl-bigint', 'Promise.allSettled': '--harmony-promise-all-settled', 'FinalizationGroup': '--harmony-weak-refs', 'WeakRef': '--harmony-weak-refs', 'host-gc-required': '--expose-gc-as=v8GC', 'optional-chaining': '--harmony-optional-chaining', + 'top-level-await': '--harmony-top-level-await', + 'regexp-match-indices': '--harmony-regexp-match-indices', + # https://github.com/tc39/test262/pull/2395 + 'regexp-named-groups': '--harmony-regexp-match-indices', + 'class-methods-private': '--harmony-private-methods', + 'class-static-methods-private': '--harmony-private-methods', } -SKIPPED_FEATURES = set(['class-methods-private', - 'class-static-methods-private', - 'top-level-await']) +SKIPPED_FEATURES = set([]) DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data") diff --git a/deps/v8/test/unittests/BUILD.gn b/deps/v8/test/unittests/BUILD.gn index 7a379f77e851ac..4ae76e1543847e 100644 --- a/deps/v8/test/unittests/BUILD.gn +++ b/deps/v8/test/unittests/BUILD.gn @@ -188,7 +188,9 @@ v8_source_set("unittests_sources") { "logging/counters-unittest.cc", "numbers/bigint-unittest.cc", "numbers/conversions-unittest.cc", + "objects/backing-store-unittest.cc", "objects/object-unittest.cc", + "objects/osr-optimized-code-cache-unittest.cc", "objects/value-serializer-unittest.cc", "parser/ast-value-unittest.cc", "parser/preparser-unittest.cc", diff --git a/deps/v8/test/unittests/api/isolate-unittest.cc b/deps/v8/test/unittests/api/isolate-unittest.cc index 8d1a5dd84f8ba0..cda251f7754f6e 100644 --- a/deps/v8/test/unittests/api/isolate-unittest.cc +++ b/deps/v8/test/unittests/api/isolate-unittest.cc @@ -9,7 +9,6 @@ #include "include/v8.h" #include "src/base/macros.h" #include "src/base/platform/semaphore.h" -#include "src/base/template-utils.h" #include "src/execution/execution.h" #include "src/execution/isolate.h" #include "src/init/v8.h" @@ -62,7 +61,7 @@ TEST_F(IsolateTest, MemoryPressureNotificationBackground) { base::Semaphore semaphore(0); internal::V8::GetCurrentPlatform()->CallOnWorkerThread( - base::make_unique<MemoryPressureTask>(isolate(), &semaphore)); + std::make_unique<MemoryPressureTask>(isolate(), &semaphore)); semaphore.Wait(); diff --git a/deps/v8/test/unittests/base/template-utils-unittest.cc b/deps/v8/test/unittests/base/template-utils-unittest.cc index 0819b3de8cf32a..4b1f3b834b5761 100644 --- a/deps/v8/test/unittests/base/template-utils-unittest.cc +++ b/deps/v8/test/unittests/base/template-utils-unittest.cc @@ -136,7 +136,7 @@ TEST(TemplateUtilsTest, FoldMoveOnlyType) { str->push_back(c); return str; }; - std::unique_ptr<std::string> str = base::make_unique<std::string>("foo"); + std::unique_ptr<std::string> str = std::make_unique<std::string>("foo"); std::unique_ptr<std::string> folded = base::fold(fn, std::move(str), 'b', 'a', 'r'); CHECK_NULL(str); diff --git a/deps/v8/test/unittests/base/utils/random-number-generator-unittest.cc b/deps/v8/test/unittests/base/utils/random-number-generator-unittest.cc index 420b236432a9b5..453d788a6eb3ec 100644 --- a/deps/v8/test/unittests/base/utils/random-number-generator-unittest.cc +++ b/deps/v8/test/unittests/base/utils/random-number-generator-unittest.cc @@ -37,11 +37,10 @@ static void CheckSlowSample(const std::vector<uint64_t>& sample, uint64_t max, } } -static void TestNextSample( - RandomNumberGenerator& rng, // NOLINT(runtime/references) - uint64_t max, size_t size, bool slow = false) { +static void TestNextSample(RandomNumberGenerator* rng, uint64_t max, + size_t size, bool slow = false) { std::vector<uint64_t> sample = - slow ? rng.NextSampleSlow(max, size) : rng.NextSample(max, size); + slow ? rng->NextSampleSlow(max, size) : rng->NextSample(max, size); CheckSample(sample, max, size); } @@ -100,14 +99,14 @@ TEST_P(RandomNumberGeneratorTest, NextSample0) { size_t m = 1; RandomNumberGenerator rng(GetParam()); - TestNextSample(rng, m, 0); + TestNextSample(&rng, m, 0); } TEST_P(RandomNumberGeneratorTest, NextSampleSlow0) { size_t m = 1; RandomNumberGenerator rng(GetParam()); - TestNextSample(rng, m, 0, true); + TestNextSample(&rng, m, 0, true); } TEST_P(RandomNumberGeneratorTest, NextSample1) { @@ -115,7 +114,7 @@ TEST_P(RandomNumberGeneratorTest, NextSample1) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, 1); + TestNextSample(&rng, m, 1); } } @@ -124,7 +123,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleSlow1) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, 1, true); + TestNextSample(&rng, m, 1, true); } } @@ -133,7 +132,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleMax) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, m); + TestNextSample(&rng, m, m); } } @@ -142,7 +141,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleSlowMax) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, m, true); + TestNextSample(&rng, m, m, true); } } @@ -152,7 +151,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n); + TestNextSample(&rng, m, n); } } @@ -162,7 +161,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleSlowHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n, true); + TestNextSample(&rng, m, n, true); } } @@ -172,7 +171,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleMoreThanHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n); + TestNextSample(&rng, m, n); } } @@ -182,7 +181,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleSlowMoreThanHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n, true); + TestNextSample(&rng, m, n, true); } } @@ -192,7 +191,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleLessThanHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n); + TestNextSample(&rng, m, n); } } @@ -202,7 +201,7 @@ TEST_P(RandomNumberGeneratorTest, NextSampleSlowLessThanHalf) { RandomNumberGenerator rng(GetParam()); for (int k = 0; k < kMaxRuns; ++k) { - TestNextSample(rng, m, n, true); + TestNextSample(&rng, m, n, true); } } diff --git a/deps/v8/test/unittests/codegen/code-stub-assembler-unittest.cc b/deps/v8/test/unittests/codegen/code-stub-assembler-unittest.cc index df387d3d94dde2..7be9f758685d35 100644 --- a/deps/v8/test/unittests/codegen/code-stub-assembler-unittest.cc +++ b/deps/v8/test/unittests/codegen/code-stub-assembler-unittest.cc @@ -14,7 +14,6 @@ using ::testing::_; using v8::internal::compiler::Node; -using v8::internal::compiler::TNode; namespace c = v8::internal::compiler; diff --git a/deps/v8/test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc b/deps/v8/test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc index 8b15811d3605a4..954bdd5065fe34 100644 --- a/deps/v8/test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc +++ b/deps/v8/test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc @@ -12,7 +12,6 @@ #include "src/ast/ast.h" #include "src/ast/scopes.h" #include "src/base/platform/semaphore.h" -#include "src/base/template-utils.h" #include "src/codegen/compiler.h" #include "src/flags/flags.h" #include "src/handles/handles.h" @@ -205,7 +204,7 @@ class MockPlatform : public v8::Platform { tasks.swap(worker_tasks_); } platform->CallOnWorkerThread( - base::make_unique<TaskWrapper>(this, std::move(tasks), true)); + std::make_unique<TaskWrapper>(this, std::move(tasks), true)); sem_.Wait(); } @@ -216,7 +215,7 @@ class MockPlatform : public v8::Platform { tasks.swap(worker_tasks_); } platform->CallOnWorkerThread( - base::make_unique<TaskWrapper>(this, std::move(tasks), false)); + std::make_unique<TaskWrapper>(this, std::move(tasks), false)); } void RunForegroundTasks() { diff --git a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index b969d9a278a9aa..d7a3a92c964b01 100644 --- a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc +++ b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc @@ -41,16 +41,15 @@ std::ostream& operator<<(std::ostream& os, const Shift& shift) { // Helper to build Int32Constant or Int64Constant depending on the given // machine type. -Node* BuildConstant( - InstructionSelectorTest::StreamBuilder& m, // NOLINT(runtime/references) - MachineType type, int64_t value) { +Node* BuildConstant(InstructionSelectorTest::StreamBuilder* m, MachineType type, + int64_t value) { switch (type.representation()) { case MachineRepresentation::kWord32: - return m.Int32Constant(static_cast<int32_t>(value)); + return m->Int32Constant(static_cast<int32_t>(value)); break; case MachineRepresentation::kWord64: - return m.Int64Constant(value); + return m->Int64Constant(value); break; default: @@ -373,8 +372,6 @@ const MachInst2 kCanElideChangeUint32ToUint64[] = { MachineType::Uint32()}, }; -} // namespace - // ----------------------------------------------------------------------------- // Logical instructions. @@ -464,9 +461,8 @@ TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) { TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) { StreamBuilder m(this, type, type, type); m.Return((m.*dpi.constructor)( - m.Parameter(0), - (m.*shift.mi.constructor)(m.Parameter(1), - BuildConstant(m, type, imm)))); + m.Parameter(0), (m.*shift.mi.constructor)( + m.Parameter(1), BuildConstant(&m, type, imm)))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode()); @@ -480,7 +476,7 @@ TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) { StreamBuilder m(this, type, type, type); m.Return((m.*dpi.constructor)( (m.*shift.mi.constructor)(m.Parameter(1), - BuildConstant(m, type, imm)), + BuildConstant(&m, type, imm)), m.Parameter(0))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -521,7 +517,7 @@ TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) { TRACED_FOREACH(int32_t, imm, kAddSubImmediates) { StreamBuilder m(this, type, type); m.Return( - (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); + (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(&m, type, imm))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); @@ -540,7 +536,7 @@ TEST_P(InstructionSelectorAddSubTest, NegImmediateOnRight) { if (imm == 0) continue; StreamBuilder m(this, type, type); m.Return( - (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, -imm))); + (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(&m, type, -imm))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode()); @@ -568,9 +564,8 @@ TEST_P(InstructionSelectorAddSubTest, ShiftByImmediateOnRight) { TRACED_FORRANGE(int, imm, 0, ((type == MachineType::Int32()) ? 31 : 63)) { StreamBuilder m(this, type, type, type); m.Return((m.*dpi.mi.constructor)( - m.Parameter(0), - (m.*shift.mi.constructor)(m.Parameter(1), - BuildConstant(m, type, imm)))); + m.Parameter(0), (m.*shift.mi.constructor)( + m.Parameter(1), BuildConstant(&m, type, imm)))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode()); @@ -1156,7 +1151,7 @@ TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) { struct TestAndBranch { MachInst<std::function<Node*(InstructionSelectorTest::StreamBuilder&, Node*, - uint32_t mask)>> + uint64_t mask)>> mi; FlagsCondition cond; }; @@ -1275,6 +1270,92 @@ INSTANTIATE_TEST_SUITE_P(InstructionSelectorTest, InstructionSelectorTestAndBranchTest, ::testing::ValuesIn(kTestAndBranchMatchers32)); +// TODO(arm64): Add the missing Word32BinaryNot test cases from the 32-bit +// version. +const TestAndBranch kTestAndBranchMatchers64[] = { + // Branch on the result of Word64And directly. + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, uint64_t mask) + -> Node* { return m.Word64And(x, m.Int64Constant(mask)); }, + "if (x and mask)", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}, + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Word64And(x, m.Int64Constant(mask)), + m.Int64Constant(0)); + }, + "if not (x and mask)", kArm64TestAndBranch, MachineType::Int64()}, + kEqual}, + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, uint64_t mask) + -> Node* { return m.Word64And(m.Int64Constant(mask), x); }, + "if (mask and x)", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}, + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Word64And(m.Int64Constant(mask), x), + m.Int64Constant(0)); + }, + "if not (mask and x)", kArm64TestAndBranch, MachineType::Int64()}, + kEqual}, + // Branch on the result of '(x and mask) == mask'. This tests that a bit is + // set rather than cleared which is why conditions are inverted. + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Word64And(x, m.Int64Constant(mask)), + m.Int64Constant(mask)); + }, + "if ((x and mask) == mask)", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}, + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Int64Constant(mask), + m.Word64And(x, m.Int64Constant(mask))); + }, + "if (mask == (x and mask))", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}, + // Same as above but swap 'mask' and 'x'. + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Word64And(m.Int64Constant(mask), x), + m.Int64Constant(mask)); + }, + "if ((mask and x) == mask)", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}, + {{[](InstructionSelectorTest::StreamBuilder& m, Node* x, + uint64_t mask) -> Node* { + return m.Word64Equal(m.Int64Constant(mask), + m.Word64And(m.Int64Constant(mask), x)); + }, + "if (mask == (mask and x))", kArm64TestAndBranch, MachineType::Int64()}, + kNotEqual}}; + +using InstructionSelectorTestAndBranchTest64 = + InstructionSelectorTestWithParam<TestAndBranch>; + +TEST_P(InstructionSelectorTestAndBranchTest64, TestAndBranch64) { + const TestAndBranch inst = GetParam(); + TRACED_FORRANGE(int, bit, 0, 63) { + uint64_t mask = uint64_t{1} << bit; + StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); + RawMachineLabel a, b; + m.Branch(inst.mi.constructor(m, m.Parameter(0), mask), &a, &b); + m.Bind(&a); + m.Return(m.Int64Constant(1)); + m.Bind(&b); + m.Return(m.Int64Constant(0)); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(inst.mi.arch_opcode, s[0]->arch_opcode()); + EXPECT_EQ(inst.cond, s[0]->flags_condition()); + EXPECT_EQ(4U, s[0]->InputCount()); + EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); + EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); + } +} + +INSTANTIATE_TEST_SUITE_P(InstructionSelectorTest, + InstructionSelectorTestAndBranchTest64, + ::testing::ValuesIn(kTestAndBranchMatchers64)); + TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { TRACED_FORRANGE(int, bit, 0, 63) { uint64_t mask = uint64_t{1} << bit; @@ -2035,7 +2116,7 @@ TEST_P(InstructionSelectorIntDPWithIntMulTest, NegativeMul) { { StreamBuilder m(this, type, type, type); Node* n = - (m.*mdpi.sub_constructor)(BuildConstant(m, type, 0), m.Parameter(0)); + (m.*mdpi.sub_constructor)(BuildConstant(&m, type, 0), m.Parameter(0)); m.Return((m.*mdpi.mul_constructor)(n, m.Parameter(1))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -2046,7 +2127,7 @@ TEST_P(InstructionSelectorIntDPWithIntMulTest, NegativeMul) { { StreamBuilder m(this, type, type, type); Node* n = - (m.*mdpi.sub_constructor)(BuildConstant(m, type, 0), m.Parameter(1)); + (m.*mdpi.sub_constructor)(BuildConstant(&m, type, 0), m.Parameter(1)); m.Return((m.*mdpi.mul_constructor)(m.Parameter(0), n)); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); @@ -2578,6 +2659,22 @@ TEST_F(InstructionSelectorTest, ChangeInt32ToInt64AfterLoad) { } } +TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithWord32Sar) { + // Test the mod 32 behaviour of Word32Sar by iterating up to 33. + TRACED_FORRANGE(int32_t, imm, 0, 33) { + StreamBuilder m(this, MachineType::Int64(), MachineType::Int32()); + m.Return(m.ChangeInt32ToInt64( + m.Word32Sar(m.Parameter(0), m.Int32Constant(imm)))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Sbfx, s[0]->arch_opcode()); + EXPECT_EQ(3U, s[0]->InputCount()); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(imm & 0x1f, s.ToInt32(s[0]->InputAt(1))); + EXPECT_EQ(32 - (imm & 0x1f), s.ToInt32(s[0]->InputAt(2))); + } +} + // ----------------------------------------------------------------------------- // Memory access instructions. @@ -2938,7 +3035,8 @@ TEST_P(InstructionSelectorComparisonTest, WithImmediate) { // Compare with 0 are turned into tst instruction. if (imm == 0) continue; StreamBuilder m(this, type, type); - m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm))); + m.Return( + (m.*cmp.constructor)(m.Parameter(0), BuildConstant(&m, type, imm))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); @@ -2953,7 +3051,8 @@ TEST_P(InstructionSelectorComparisonTest, WithImmediate) { // Compare with 0 are turned into tst instruction. if (imm == 0) continue; StreamBuilder m(this, type, type); - m.Return((m.*cmp.constructor)(BuildConstant(m, type, imm), m.Parameter(0))); + m.Return( + (m.*cmp.constructor)(BuildConstant(&m, type, imm), m.Parameter(0))); Stream s = m.Build(); ASSERT_EQ(1U, s.size()); EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode()); @@ -3507,6 +3606,33 @@ const IntegerCmp kBinopCmpZeroRightInstructions[] = { kNotEqual, kNotEqual}}; +const IntegerCmp kBinop64CmpZeroRightInstructions[] = { + {{&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, + MachineType::Int64()}, + kEqual, + kEqual}, + {{&RawMachineAssembler::Word64NotEqual, "Word64NotEqual", kArm64Cmp, + MachineType::Int64()}, + kNotEqual, + kNotEqual}, + {{&RawMachineAssembler::Int64LessThan, "Int64LessThan", kArm64Cmp, + MachineType::Int64()}, + kNegative, + kNegative}, + {{&RawMachineAssembler::Int64GreaterThanOrEqual, "Int64GreaterThanOrEqual", + kArm64Cmp, MachineType::Int64()}, + kPositiveOrZero, + kPositiveOrZero}, + {{&RawMachineAssembler::Uint64LessThanOrEqual, "Uint64LessThanOrEqual", + kArm64Cmp, MachineType::Int64()}, + kEqual, + kEqual}, + {{&RawMachineAssembler::Uint64GreaterThan, "Uint64GreaterThan", kArm64Cmp, + MachineType::Int64()}, + kNotEqual, + kNotEqual}, +}; + const IntegerCmp kBinopCmpZeroLeftInstructions[] = { {{&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, MachineType::Int32()}, @@ -4019,7 +4145,7 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { TRACED_FORRANGE(int32_t, shift, -32, 63) { int32_t lsb = shift & 0x1F; TRACED_FORRANGE(int32_t, width, 1, 31) { - uint32_t msk = (1 << width) - 1; + uint32_t msk = (1u << width) - 1; StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), m.Int32Constant(msk))); @@ -4035,7 +4161,7 @@ TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) { TRACED_FORRANGE(int32_t, shift, -32, 63) { int32_t lsb = shift & 0x1F; TRACED_FORRANGE(int32_t, width, 1, 31) { - uint32_t msk = (1 << width) - 1; + uint32_t msk = (1u << width) - 1; StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); m.Return( m.Word32And(m.Int32Constant(msk), @@ -4282,7 +4408,7 @@ TEST_F(InstructionSelectorTest, Word32ShlWithWord32And) { StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); Node* const p0 = m.Parameter(0); Node* const r = - m.Word32Shl(m.Word32And(p0, m.Int32Constant((1 << (31 - shift)) - 1)), + m.Word32Shl(m.Word32And(p0, m.Int32Constant((1u << (31 - shift)) - 1)), m.Int32Constant(shift + 1)); m.Return(r); Stream s = m.Build(); @@ -4531,6 +4657,34 @@ TEST_F(InstructionSelectorTest, CompareAgainstZero32) { } } +TEST_F(InstructionSelectorTest, CompareAgainstZero64) { + TRACED_FOREACH(IntegerCmp, cmp, kBinop64CmpZeroRightInstructions) { + StreamBuilder m(this, MachineType::Int64(), MachineType::Int64()); + Node* const param = m.Parameter(0); + RawMachineLabel a, b; + m.Branch((m.*cmp.mi.constructor)(param, m.Int64Constant(0)), &a, &b); + m.Bind(&a); + m.Return(m.Int64Constant(1)); + m.Bind(&b); + m.Return(m.Int64Constant(0)); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0))); + if (cmp.cond == kNegative || cmp.cond == kPositiveOrZero) { + EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); + EXPECT_EQ(4U, s[0]->InputCount()); // The labels are also inputs. + EXPECT_EQ((cmp.cond == kNegative) ? kNotEqual : kEqual, + s[0]->flags_condition()); + EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); + EXPECT_EQ(63, s.ToInt32(s[0]->InputAt(1))); + } else { + EXPECT_EQ(kArm64CompareAndBranch, s[0]->arch_opcode()); + EXPECT_EQ(3U, s[0]->InputCount()); // The labels are also inputs. + EXPECT_EQ(cmp.cond, s[0]->flags_condition()); + } + } +} + TEST_F(InstructionSelectorTest, CompareFloat64HighLessThanZero64) { StreamBuilder m(this, MachineType::Int32(), MachineType::Float64()); Node* const param = m.Parameter(0); @@ -4615,18 +4769,18 @@ namespace { // Then checks that the correct number of kArm64Poke and kArm64PokePair were // generated. void TestPokePair( - InstructionSelectorTest::StreamBuilder& m, // NOLINT(runtime/references) + InstructionSelectorTest::StreamBuilder* m, // NOLINT(runtime/references) Zone* zone, - MachineSignature::Builder& builder, // NOLINT(runtime/references) + MachineSignature::Builder* builder, // NOLINT(runtime/references) Node* nodes[], int num_nodes, int expected_poke_pair, int expected_poke) { auto call_descriptor = InstructionSelectorTest::StreamBuilder::MakeSimpleCallDescriptor( - zone, builder.Build()); + zone, builder->Build()); - m.CallN(call_descriptor, num_nodes, nodes); - m.Return(m.UndefinedConstant()); + m->CallN(call_descriptor, num_nodes, nodes); + m->Return(m->UndefinedConstant()); - auto s = m.Build(); + auto s = m->Build(); int num_poke_pair = 0; int num_poke = 0; for (size_t i = 0; i < s.size(); ++i) { @@ -4664,7 +4818,7 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsInt32) { // EmitPrepareArguments. const int expected_poke = 1 + 1; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), expected_poke_pair, expected_poke); } @@ -4684,7 +4838,7 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsInt32) { const int expected_poke_pair = 2; const int expected_poke = 0; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), expected_poke_pair, expected_poke); } } @@ -4705,8 +4859,8 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsInt64) { const int expected_poke_pair = 2; const int expected_poke = 0; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), expected_poke_pair, - expected_poke); + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), + expected_poke_pair, expected_poke); } TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsFloat32) { @@ -4725,8 +4879,8 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsFloat32) { const int expected_poke_pair = 2; const int expected_poke = 0; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), expected_poke_pair, - expected_poke); + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), + expected_poke_pair, expected_poke); } TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsFloat64) { @@ -4745,8 +4899,8 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsFloat64) { const int expected_poke_pair = 2; const int expected_poke = 0; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), expected_poke_pair, - expected_poke); + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), + expected_poke_pair, expected_poke); } TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsIntFloatMixed) { @@ -4766,7 +4920,7 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsIntFloatMixed) { const int expected_poke_pair = 0; const int expected_poke = 4; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), expected_poke_pair, expected_poke); } @@ -4792,7 +4946,7 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsIntFloatMixed) { // EmitPrepareArguments. const int expected_poke = 3 + 1; - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), expected_poke_pair, expected_poke); } } @@ -4811,10 +4965,11 @@ TEST_F(InstructionSelectorTest, PokePairPrepareArgumentsSimd128) { const int expected_poke = 2; // Using kArm64PokePair is not currently supported for Simd128. - TestPokePair(m, zone(), builder, nodes, arraysize(nodes), expected_poke_pair, - expected_poke); + TestPokePair(&m, zone(), &builder, nodes, arraysize(nodes), + expected_poke_pair, expected_poke); } +} // namespace } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/compiler/backend/instruction-sequence-unittest.h b/deps/v8/test/unittests/compiler/backend/instruction-sequence-unittest.h index 82a8b3019d63c7..b75da308f9b387 100644 --- a/deps/v8/test/unittests/compiler/backend/instruction-sequence-unittest.h +++ b/deps/v8/test/unittests/compiler/backend/instruction-sequence-unittest.h @@ -47,7 +47,6 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { kFixedRegister, kSlot, kFixedSlot, - kExplicit, kImmediate, kNone, kConstant, @@ -75,17 +74,6 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { static TestOperand Same() { return TestOperand(kSameAsFirst); } - static TestOperand ExplicitReg(int index) { - TestOperandType type = kExplicit; - return TestOperand(type, index); - } - - static TestOperand ExplicitFPReg(int index, - MachineRepresentation rep = kFloat64) { - TestOperandType type = kExplicit; - return TestOperand(type, index, rep); - } - static TestOperand Reg(VReg vreg, int index = kNoValue) { TestOperandType type = (index == kNoValue) ? kRegister : kFixedRegister; return TestOperand(type, vreg, index); diff --git a/deps/v8/test/unittests/compiler/common-operator-unittest.cc b/deps/v8/test/unittests/compiler/common-operator-unittest.cc index 19e7c6c55fe84b..365b3ea05baaa8 100644 --- a/deps/v8/test/unittests/compiler/common-operator-unittest.cc +++ b/deps/v8/test/unittests/compiler/common-operator-unittest.cc @@ -62,8 +62,6 @@ class CommonSharedOperatorTest : public TestWithZone, public ::testing::WithParamInterface<SharedOperator> {}; -} // namespace - TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) { const SharedOperator& sop = GetParam(); @@ -387,6 +385,7 @@ TEST_F(CommonOperatorTest, Projection) { } } +} // namespace } // namespace common_operator_unittest } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc b/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc index 52769b09ded304..7e927ea078bbb7 100644 --- a/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/int64-lowering-unittest.cc @@ -1015,7 +1015,7 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseBigIntToI64) { Operator::kNoProperties, // properties StubCallMode::kCallCodeObject); // stub call mode - auto lowering_special_case = base::make_unique<Int64LoweringSpecialCase>(); + auto lowering_special_case = std::make_unique<Int64LoweringSpecialCase>(); lowering_special_case->bigint_to_i64_call_descriptor = bigint_to_i64_call_descriptor; lowering_special_case->bigint_to_i32_pair_call_descriptor = @@ -1063,7 +1063,7 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseI64ToBigInt) { Operator::kNoProperties, // properties StubCallMode::kCallCodeObject); // stub call mode - auto lowering_special_case = base::make_unique<Int64LoweringSpecialCase>(); + auto lowering_special_case = std::make_unique<Int64LoweringSpecialCase>(); lowering_special_case->i64_to_bigint_call_descriptor = i64_to_bigint_call_descriptor; lowering_special_case->i32_pair_to_bigint_call_descriptor = diff --git a/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc b/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc index 7c062698c41010..10643ddc8ba444 100644 --- a/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-call-reducer-unittest.cc @@ -11,6 +11,7 @@ #include "src/compiler/js-graph.h" #include "src/compiler/simplified-operator.h" #include "src/execution/isolate.h" +#include "src/execution/protectors.h" #include "src/heap/factory.h" #include "src/objects/feedback-vector.h" #include "test/unittests/compiler/graph-unittest.h" @@ -175,12 +176,7 @@ TEST_F(JSCallReducerTest, PromiseConstructorBasic) { context, frame_state, effect, control); Reduction r = Reduce(construct); - - if (FLAG_experimental_inline_promise_constructor) { - ASSERT_TRUE(r.Changed()); - } else { - ASSERT_FALSE(r.Changed()); - } + ASSERT_TRUE(r.Changed()); } // Exactly the same as PromiseConstructorBasic which expects a reduction, @@ -198,7 +194,7 @@ TEST_F(JSCallReducerTest, PromiseConstructorWithHook) { graph()->NewNode(javascript()->Construct(3), promise, executor, promise, context, frame_state, effect, control); - isolate()->InvalidatePromiseHookProtector(); + Protectors::InvalidatePromiseHook(isolate()); Reduction r = Reduce(construct); diff --git a/deps/v8/test/unittests/compiler/js-operator-unittest.cc b/deps/v8/test/unittests/compiler/js-operator-unittest.cc index 082e81f27c70ba..5a951b35ae444d 100644 --- a/deps/v8/test/unittests/compiler/js-operator-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-operator-unittest.cc @@ -54,9 +54,6 @@ std::ostream& operator<<(std::ostream& os, const SharedOperator& sop) { return os << IrOpcode::Mnemonic(sop.opcode); } -} // namespace - - class JSSharedOperatorTest : public TestWithZone, public ::testing::WithParamInterface<SharedOperator> {}; @@ -111,6 +108,7 @@ TEST_P(JSSharedOperatorTest, Properties) { INSTANTIATE_TEST_SUITE_P(JSOperatorTest, JSSharedOperatorTest, ::testing::ValuesIn(kSharedOperators)); +} // namespace } // namespace js_operator_unittest } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc index 0d85253847c130..eed74f61812ba0 100644 --- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -52,13 +52,6 @@ class JSTypedLoweringTest : public TypedGraphTest { return reducer.Reduce(node); } - Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) { - Handle<JSArrayBuffer> buffer = - factory()->NewJSArrayBuffer(SharedFlag::kNotShared); - JSArrayBuffer::Setup(buffer, isolate(), true, bytes, byte_length); - return buffer; - } - JSOperatorBuilder* javascript() { return &javascript_; } private: diff --git a/deps/v8/test/unittests/compiler/regalloc/OWNERS b/deps/v8/test/unittests/compiler/regalloc/OWNERS deleted file mode 100644 index bfde831c207ccf..00000000000000 --- a/deps/v8/test/unittests/compiler/regalloc/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -set noparent - -bmeurer@chromium.org -jarin@chromium.org diff --git a/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc index e72afd5601e7be..344ea3dfad4b0f 100644 --- a/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc +++ b/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc @@ -83,11 +83,6 @@ class MoveOptimizerTest : public InstructionSequenceTest { CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep)); return AllocatedOperand(LocationOperand::REGISTER, rep, op.value_); } - case kExplicit: { - MachineRepresentation rep = GetCanonicalRep(op); - CHECK(0 <= op.value_ && op.value_ < GetNumRegs(rep)); - return ExplicitOperand(LocationOperand::REGISTER, rep, op.value_); - } default: break; } @@ -123,45 +118,6 @@ TEST_F(MoveOptimizerTest, RemovesRedundant) { CHECK(Contains(move, FPReg(kF32_1, kFloat32), FPReg(kF32_2, kFloat32))); } -TEST_F(MoveOptimizerTest, RemovesRedundantExplicit) { - int index1 = GetAllocatableCode(0); - int index2 = GetAllocatableCode(1); - int s128_1 = GetAllocatableCode(kS128_1, kSimd128); - int s128_2 = GetAllocatableCode(kS128_2, kSimd128); - int f64_1 = GetAllocatableCode(kF64_1, kFloat64); - int f64_2 = GetAllocatableCode(kF64_2, kFloat64); - int f32_1 = GetAllocatableCode(kF32_1, kFloat32); - int f32_2 = GetAllocatableCode(kF32_2, kFloat32); - - StartBlock(); - auto first_instr = EmitNop(); - auto last_instr = EmitNop(); - - AddMove(first_instr, Reg(index1), ExplicitReg(index2)); - AddMove(last_instr, Reg(index2), Reg(index1)); - - AddMove(first_instr, FPReg(s128_1, kSimd128), - ExplicitFPReg(s128_2, kSimd128)); - AddMove(last_instr, FPReg(s128_2, kSimd128), FPReg(s128_1, kSimd128)); - AddMove(first_instr, FPReg(f64_1, kFloat64), ExplicitFPReg(f64_2, kFloat64)); - AddMove(last_instr, FPReg(f64_2, kFloat64), FPReg(f64_1, kFloat64)); - AddMove(first_instr, FPReg(f32_1, kFloat32), ExplicitFPReg(f32_2, kFloat32)); - AddMove(last_instr, FPReg(f32_2, kFloat32), FPReg(f32_1, kFloat32)); - - EndBlock(Last()); - - Optimize(); - - CHECK_EQ(0, NonRedundantSize(first_instr->parallel_moves()[0])); - auto move = last_instr->parallel_moves()[0]; - CHECK_EQ(4, NonRedundantSize(move)); - CHECK(Contains(move, Reg(index1), ExplicitReg(index2))); - CHECK( - Contains(move, FPReg(s128_1, kSimd128), ExplicitFPReg(s128_2, kSimd128))); - CHECK(Contains(move, FPReg(f64_1, kFloat64), ExplicitFPReg(f64_2, kFloat64))); - CHECK(Contains(move, FPReg(f32_1, kFloat32), ExplicitFPReg(f32_2, kFloat32))); -} - TEST_F(MoveOptimizerTest, SplitsConstants) { StartBlock(); EndBlock(Last()); diff --git a/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc index 262c51d31edf81..f06b004d495271 100644 --- a/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc +++ b/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc @@ -73,7 +73,6 @@ bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos, return found_match; } -} // namespace class RegisterAllocatorTest : public InstructionSequenceTest { public: @@ -824,6 +823,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::Combine(::testing::ValuesIn(kParameterTypes), ::testing::Range(0, SlotConstraintTest::kMaxVariant))); +} // namespace } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/unittests/heap/heap-unittest.cc b/deps/v8/test/unittests/heap/heap-unittest.cc index 048ff5d0a638ac..76cab01a411bf8 100644 --- a/deps/v8/test/unittests/heap/heap-unittest.cc +++ b/deps/v8/test/unittests/heap/heap-unittest.cc @@ -145,8 +145,7 @@ TEST_F(HeapWithPointerCompressionTest, HeapLayout) { EXPECT_TRUE(IsAligned(isolate_root, size_t{4} * GB)); // Check that all memory chunks belong this region. - base::AddressRegion heap_reservation(isolate_root - size_t{2} * GB, - size_t{4} * GB); + base::AddressRegion heap_reservation(isolate_root, size_t{4} * GB); OldGenerationMemoryChunkIterator iter(i_isolate()->heap()); for (;;) { diff --git a/deps/v8/test/unittests/heap/slot-set-unittest.cc b/deps/v8/test/unittests/heap/slot-set-unittest.cc index 54b60f55e8e9d3..fa635705b3012c 100644 --- a/deps/v8/test/unittests/heap/slot-set-unittest.cc +++ b/deps/v8/test/unittests/heap/slot-set-unittest.cc @@ -16,12 +16,11 @@ namespace internal { TEST(SlotSet, InsertAndLookup1) { SlotSet set; - set.SetPageStart(0); for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { EXPECT_FALSE(set.Lookup(i)); } for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { - set.Insert(i); + set.Insert<AccessMode::ATOMIC>(i); } for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { EXPECT_TRUE(set.Lookup(i)); @@ -30,10 +29,9 @@ TEST(SlotSet, InsertAndLookup1) { TEST(SlotSet, InsertAndLookup2) { SlotSet set; - set.SetPageStart(0); for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { if (i % 7 == 0) { - set.Insert(i); + set.Insert<AccessMode::ATOMIC>(i); } } for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { @@ -47,14 +45,14 @@ TEST(SlotSet, InsertAndLookup2) { TEST(SlotSet, Iterate) { SlotSet set; - set.SetPageStart(0); for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { if (i % 7 == 0) { - set.Insert(i); + set.Insert<AccessMode::ATOMIC>(i); } } set.Iterate( + kNullAddress, [](MaybeObjectSlot slot) { if (slot.address() % 3 == 0) { return KEEP_SLOT; @@ -75,10 +73,9 @@ TEST(SlotSet, Iterate) { TEST(SlotSet, Remove) { SlotSet set; - set.SetPageStart(0); for (int i = 0; i < Page::kPageSize; i += kTaggedSize) { if (i % 7 == 0) { - set.Insert(i); + set.Insert<AccessMode::ATOMIC>(i); } } @@ -99,13 +96,12 @@ TEST(SlotSet, Remove) { void CheckRemoveRangeOn(uint32_t start, uint32_t end) { SlotSet set; - set.SetPageStart(0); uint32_t first = start == 0 ? 0 : start - kTaggedSize; uint32_t last = end == Page::kPageSize ? end - kTaggedSize : end; for (const auto mode : {SlotSet::FREE_EMPTY_BUCKETS, SlotSet::KEEP_EMPTY_BUCKETS}) { for (uint32_t i = first; i <= last; i += kTaggedSize) { - set.Insert(i); + set.Insert<AccessMode::ATOMIC>(i); } set.RemoveRange(start, end, mode); if (first != start) { @@ -137,10 +133,9 @@ TEST(SlotSet, RemoveRange) { } } SlotSet set; - set.SetPageStart(0); for (const auto mode : {SlotSet::FREE_EMPTY_BUCKETS, SlotSet::KEEP_EMPTY_BUCKETS}) { - set.Insert(Page::kPageSize / 2); + set.Insert<AccessMode::ATOMIC>(Page::kPageSize / 2); set.RemoveRange(0, Page::kPageSize, mode); for (uint32_t i = 0; i < Page::kPageSize; i += kTaggedSize) { EXPECT_FALSE(set.Lookup(i)); diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc index a9c631f8d2202c..667bfee64b5ac8 100644 --- a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc +++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc @@ -96,6 +96,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { FeedbackSlot sloppy_store_global_slot = feedback_spec.AddStoreGlobalICSlot(LanguageMode::kSloppy); FeedbackSlot load_slot = feedback_spec.AddLoadICSlot(); + FeedbackSlot call_slot = feedback_spec.AddCallICSlot(); FeedbackSlot keyed_load_slot = feedback_spec.AddKeyedLoadICSlot(); FeedbackSlot sloppy_store_slot = feedback_spec.AddStoreICSlot(LanguageMode::kSloppy); @@ -152,7 +153,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { .StoreInArrayLiteral(reg, reg, store_array_element_slot.ToInt()); // Emit Iterator-protocol operations - builder.GetIterator(reg, load_slot.ToInt()); + builder.GetIterator(reg, load_slot.ToInt(), call_slot.ToInt()); // Emit load / store lookup slots. builder.LoadLookupSlot(name, TypeofMode::NOT_INSIDE_TYPEOF) diff --git a/deps/v8/test/unittests/interpreter/interpreter-assembler-unittest.cc b/deps/v8/test/unittests/interpreter/interpreter-assembler-unittest.cc index a8ff9981073db5..09d21e3095eb82 100644 --- a/deps/v8/test/unittests/interpreter/interpreter-assembler-unittest.cc +++ b/deps/v8/test/unittests/interpreter/interpreter-assembler-unittest.cc @@ -16,7 +16,6 @@ using ::testing::_; using ::testing::Eq; using v8::internal::compiler::Node; -using v8::internal::compiler::TNode; namespace c = v8::internal::compiler; @@ -310,44 +309,6 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoadRegisterOperand( LoadSensitivity::kCritical)); } -TARGET_TEST_F(InterpreterAssemblerTest, Jump) { - // If debug code is enabled we emit extra code in Jump. - if (FLAG_debug_code) return; - - int jump_offsets[] = {-9710, -77, 0, +3, +97109}; - TRACED_FOREACH(int, jump_offset, jump_offsets) { - TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { - if (!interpreter::Bytecodes::IsJump(bytecode)) return; - - InterpreterAssemblerTestState state(this, bytecode); - InterpreterAssemblerForTest m(&state, bytecode); - Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset)); - - Matcher<Node*> next_bytecode_offset_matcher = c::IsIntPtrAdd( - c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), - c::IsIntPtrConstant(jump_offset)); - Matcher<Node*> target_bytecode_matcher = - m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher); - target_bytecode_matcher = - c::IsChangeUint32ToWord(target_bytecode_matcher); - Matcher<Node*> code_target_matcher = m.IsLoad( - MachineType::Pointer(), - c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable), - c::IsWordShl(target_bytecode_matcher, - c::IsIntPtrConstant(kSystemPointerSizeLog2))); - - EXPECT_THAT( - tail_call_node, - c::IsTailCall( - _, code_target_matcher, - c::IsParameter(InterpreterDispatchDescriptor::kAccumulator), - next_bytecode_offset_matcher, _, - c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable), _, - _)); - } - } -} - TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { static const OperandScale kOperandScales[] = { OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple}; @@ -444,67 +405,70 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { InterpreterAssemblerForTest m(&state, bytecode); { TNode<IntPtrT> index = m.IntPtrConstant(2); - Node* load_constant = m.LoadConstantPoolEntry(index); -#ifdef V8_COMPRESS_POINTERS - Matcher<Node*> constant_pool_matcher = - IsChangeCompressedToTagged(m.IsLoadFromObject( - MachineType::AnyCompressed(), - c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), - c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - - kHeapObjectTag))); - EXPECT_THAT(load_constant, - IsChangeCompressedToTagged(m.IsLoad( - MachineType::AnyCompressed(), constant_pool_matcher, - c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) - - kHeapObjectTag), - LoadSensitivity::kCritical))); -#else - Matcher<Node*> constant_pool_matcher = m.IsLoadFromObject( - MachineType::AnyTagged(), - c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), - c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - - kHeapObjectTag)); - EXPECT_THAT( - load_constant, - m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, - c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) - - kHeapObjectTag), - LoadSensitivity::kCritical)); -#endif + TNode<Object> load_constant = m.LoadConstantPoolEntry(index); + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + Matcher<Node*> constant_pool_matcher = + IsChangeCompressedToTagged(m.IsLoadFromObject( + MachineType::AnyCompressed(), + c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), + c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - + kHeapObjectTag))); + EXPECT_THAT(load_constant, + IsChangeCompressedToTagged(m.IsLoad( + MachineType::AnyCompressed(), constant_pool_matcher, + c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) - + kHeapObjectTag), + LoadSensitivity::kCritical))); + } else { + Matcher<Node*> constant_pool_matcher = m.IsLoadFromObject( + MachineType::AnyTagged(), + c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), + c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - + kHeapObjectTag)); + EXPECT_THAT( + load_constant, + m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, + c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) - + kHeapObjectTag), + LoadSensitivity::kCritical)); + } } { Node* index = m.Parameter(2); - Node* load_constant = m.LoadConstantPoolEntry(index); -#if V8_COMPRESS_POINTERS - Matcher<Node*> constant_pool_matcher = - IsChangeCompressedToTagged(m.IsLoadFromObject( - MachineType::AnyCompressed(), - c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), - c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - - kHeapObjectTag))); - EXPECT_THAT( - load_constant, - IsChangeCompressedToTagged(m.IsLoad( - MachineType::AnyCompressed(), constant_pool_matcher, - c::IsIntPtrAdd( - c::IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), - c::IsWordShl(index, c::IsIntPtrConstant(kTaggedSizeLog2))), - LoadSensitivity::kCritical))); -#else - Matcher<Node*> constant_pool_matcher = m.IsLoadFromObject( - MachineType::AnyTagged(), - c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), - c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - - kHeapObjectTag)); - EXPECT_THAT( - load_constant, - m.IsLoad( - MachineType::AnyTagged(), constant_pool_matcher, - c::IsIntPtrAdd( - c::IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), - c::IsWordShl(index, c::IsIntPtrConstant(kTaggedSizeLog2))), - LoadSensitivity::kCritical)); -#endif + TNode<Object> load_constant = + m.LoadConstantPoolEntry(m.ReinterpretCast<IntPtrT>(index)); + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + Matcher<Node*> constant_pool_matcher = + IsChangeCompressedToTagged(m.IsLoadFromObject( + MachineType::AnyCompressed(), + c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), + c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - + kHeapObjectTag))); + EXPECT_THAT( + load_constant, + IsChangeCompressedToTagged(m.IsLoad( + MachineType::AnyCompressed(), constant_pool_matcher, + c::IsIntPtrAdd( + c::IsIntPtrConstant(FixedArray::kHeaderSize - + kHeapObjectTag), + c::IsWordShl(index, c::IsIntPtrConstant(kTaggedSizeLog2))), + LoadSensitivity::kCritical))); + } else { + Matcher<Node*> constant_pool_matcher = m.IsLoadFromObject( + MachineType::AnyTagged(), + c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), + c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - + kHeapObjectTag)); + EXPECT_THAT( + load_constant, + m.IsLoad( + MachineType::AnyTagged(), constant_pool_matcher, + c::IsIntPtrAdd( + c::IsIntPtrConstant(FixedArray::kHeaderSize - + kHeapObjectTag), + c::IsWordShl(index, c::IsIntPtrConstant(kTaggedSizeLog2))), + LoadSensitivity::kCritical)); + } } } } @@ -517,15 +481,17 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) { m.ReinterpretCast<HeapObject>(m.IntPtrConstant(0xDEADBEEF)); int offset = 16; TNode<Object> load_field = m.LoadObjectField(object, offset); -#ifdef V8_COMPRESS_POINTERS - EXPECT_THAT(load_field, IsChangeCompressedToTagged(m.IsLoadFromObject( - MachineType::AnyCompressed(), Eq(object), - c::IsIntPtrConstant(offset - kHeapObjectTag)))); -#else - EXPECT_THAT(load_field, m.IsLoadFromObject( - MachineType::AnyTagged(), Eq(object), - c::IsIntPtrConstant(offset - kHeapObjectTag))); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + EXPECT_THAT(load_field, + IsChangeCompressedToTagged(m.IsLoadFromObject( + MachineType::AnyCompressed(), Eq(object), + c::IsIntPtrConstant(offset - kHeapObjectTag)))); + } else { + EXPECT_THAT( + load_field, + m.IsLoadFromObject(MachineType::AnyTagged(), Eq(object), + c::IsIntPtrConstant(offset - kHeapObjectTag))); + } } } @@ -554,10 +520,10 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) { Callable builtin = CodeFactory::InterpreterCEntry(isolate(), result_size); - TNode<Int32T> function_id = m.Int32Constant(0); + TNode<Uint32T> function_id = m.Uint32Constant(0); InterpreterAssembler::RegListNodePair registers(m.IntPtrConstant(1), m.Int32Constant(2)); - TNode<Object> context = m.ReinterpretCast<Object>(m.Int32Constant(4)); + TNode<Context> context = m.ReinterpretCast<Context>(m.Int32Constant(4)); Matcher<Node*> function_table = c::IsExternalConstant( ExternalReference::runtime_function_table_address_for_unittests( @@ -607,25 +573,28 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadFeedbackVector) { m.IsLoad(MachineType::Pointer(), c::IsLoadParentFramePointer(), c::IsIntPtrConstant(Register::function_closure().ToOperand() * kSystemPointerSize))); -#ifdef V8_COMPRESS_POINTERS - Matcher<Node*> load_vector_cell_matcher = - IsChangeCompressedPointerToTaggedPointer(m.IsLoadFromObject( - MachineType::CompressedPointer(), load_function_matcher, - c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - - kHeapObjectTag))); - EXPECT_THAT(load_feedback_vector, - IsChangeCompressedPointerToTaggedPointer(m.IsLoadFromObject( - MachineType::CompressedPointer(), load_vector_cell_matcher, - c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)))); -#else - Matcher<Node*> load_vector_cell_matcher = m.IsLoadFromObject( - MachineType::TaggedPointer(), load_function_matcher, - c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - kHeapObjectTag)); - EXPECT_THAT(load_feedback_vector, - m.IsLoadFromObject( - MachineType::TaggedPointer(), load_vector_cell_matcher, - c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag))); -#endif + if (COMPRESS_POINTERS_BOOL && FLAG_turbo_decompression_elimination) { + Matcher<Node*> load_vector_cell_matcher = + IsChangeCompressedPointerToTaggedPointer(m.IsLoadFromObject( + MachineType::CompressedPointer(), load_function_matcher, + c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - + kHeapObjectTag))); + EXPECT_THAT( + load_feedback_vector, + IsChangeCompressedPointerToTaggedPointer(m.IsLoadFromObject( + MachineType::CompressedPointer(), load_vector_cell_matcher, + c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)))); + } else { + Matcher<Node*> load_vector_cell_matcher = m.IsLoadFromObject( + MachineType::TaggedPointer(), load_function_matcher, + c::IsIntPtrConstant(JSFunction::kFeedbackCellOffset - + kHeapObjectTag)); + EXPECT_THAT( + load_feedback_vector, + m.IsLoadFromObject( + MachineType::TaggedPointer(), load_vector_cell_matcher, + c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag))); + } } } diff --git a/deps/v8/test/unittests/libplatform/default-worker-threads-task-runner-unittest.cc b/deps/v8/test/unittests/libplatform/default-worker-threads-task-runner-unittest.cc index 8d52e80e39453b..e9581cc80e7d17 100644 --- a/deps/v8/test/unittests/libplatform/default-worker-threads-task-runner-unittest.cc +++ b/deps/v8/test/unittests/libplatform/default-worker-threads-task-runner-unittest.cc @@ -37,10 +37,10 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, PostTaskOrder) { base::Semaphore semaphore(0); std::unique_ptr<TestTask> task1 = - base::make_unique<TestTask>([&] { order.push_back(1); }); + std::make_unique<TestTask>([&] { order.push_back(1); }); std::unique_ptr<TestTask> task2 = - base::make_unique<TestTask>([&] { order.push_back(2); }); - std::unique_ptr<TestTask> task3 = base::make_unique<TestTask>([&] { + std::make_unique<TestTask>([&] { order.push_back(2); }); + std::unique_ptr<TestTask> task3 = std::make_unique<TestTask>([&] { order.push_back(3); semaphore.Signal(); }); @@ -65,27 +65,27 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, PostTaskOrderMultipleWorkers) { std::vector<int> order; std::atomic_int count{0}; - std::unique_ptr<TestTask> task1 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task1 = std::make_unique<TestTask>([&] { base::MutexGuard guard(&vector_lock); order.push_back(1); count++; }); - std::unique_ptr<TestTask> task2 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task2 = std::make_unique<TestTask>([&] { base::MutexGuard guard(&vector_lock); order.push_back(2); count++; }); - std::unique_ptr<TestTask> task3 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task3 = std::make_unique<TestTask>([&] { base::MutexGuard guard(&vector_lock); order.push_back(3); count++; }); - std::unique_ptr<TestTask> task4 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task4 = std::make_unique<TestTask>([&] { base::MutexGuard guard(&vector_lock); order.push_back(4); count++; }); - std::unique_ptr<TestTask> task5 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task5 = std::make_unique<TestTask>([&] { base::MutexGuard guard(&vector_lock); order.push_back(5); count++; @@ -123,7 +123,7 @@ class FakeClock { // PostTask will cause the condition variable WaitFor() call to be notified // early, rather than waiting for the real amount of time. WaitFor() listens // to the system clock and not our FakeClock. - runner->PostTask(base::make_unique<TestTask>([] {})); + runner->PostTask(std::make_unique<TestTask>([] {})); } private: @@ -140,13 +140,13 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, PostDelayedTaskOrder) { base::Semaphore task1_semaphore(0); base::Semaphore task3_semaphore(0); - std::unique_ptr<TestTask> task1 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task1 = std::make_unique<TestTask>([&] { order.push_back(1); task1_semaphore.Signal(); }); std::unique_ptr<TestTask> task2 = - base::make_unique<TestTask>([&] { order.push_back(2); }); - std::unique_ptr<TestTask> task3 = base::make_unique<TestTask>([&] { + std::make_unique<TestTask>([&] { order.push_back(2); }); + std::unique_ptr<TestTask> task3 = std::make_unique<TestTask>([&] { order.push_back(3); task3_semaphore.Signal(); }); @@ -181,15 +181,15 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, PostDelayedTaskOrder2) { base::Semaphore task2_semaphore(0); base::Semaphore task3_semaphore(0); - std::unique_ptr<TestTask> task1 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task1 = std::make_unique<TestTask>([&] { order.push_back(1); task1_semaphore.Signal(); }); - std::unique_ptr<TestTask> task2 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task2 = std::make_unique<TestTask>([&] { order.push_back(2); task2_semaphore.Signal(); }); - std::unique_ptr<TestTask> task3 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task3 = std::make_unique<TestTask>([&] { order.push_back(3); task3_semaphore.Signal(); }); @@ -230,15 +230,15 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, PostAfterTerminate) { base::Semaphore task2_semaphore(0); base::Semaphore task3_semaphore(0); - std::unique_ptr<TestTask> task1 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task1 = std::make_unique<TestTask>([&] { order.push_back(1); task1_semaphore.Signal(); }); - std::unique_ptr<TestTask> task2 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task2 = std::make_unique<TestTask>([&] { order.push_back(2); task2_semaphore.Signal(); }); - std::unique_ptr<TestTask> task3 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task3 = std::make_unique<TestTask>([&] { order.push_back(3); task3_semaphore.Signal(); }); @@ -281,7 +281,7 @@ TEST(DefaultWorkerThreadsTaskRunnerUnittest, RunsTasksOnCurrentThread) { EXPECT_FALSE(runner.RunsTasksOnCurrentThread()); - std::unique_ptr<TestTask> task1 = base::make_unique<TestTask>([&] { + std::unique_ptr<TestTask> task1 = std::make_unique<TestTask>([&] { EXPECT_TRUE(runner.RunsTasksOnCurrentThread()); semaphore.Signal(); }); diff --git a/deps/v8/test/unittests/logging/counters-unittest.cc b/deps/v8/test/unittests/logging/counters-unittest.cc index dd38d80ee4c3df..67cc7df46574eb 100644 --- a/deps/v8/test/unittests/logging/counters-unittest.cc +++ b/deps/v8/test/unittests/logging/counters-unittest.cc @@ -149,16 +149,11 @@ class SnapshotNativeCounterTest : public TestWithNativeContextAndCounters { SnapshotNativeCounterTest() {} bool SupportsNativeCounters() const { -#ifdef V8_USE_SNAPSHOT #ifdef V8_SNAPSHOT_NATIVE_CODE_COUNTERS return true; #else return false; #endif // V8_SNAPSHOT_NATIVE_CODE_COUNTERS -#else - // If we do not have a snapshot then we rely on the runtime option. - return internal::FLAG_native_code_counters; -#endif // V8_USE_SNAPSHOT } #define SC(name, caption) \ diff --git a/deps/v8/test/unittests/objects/backing-store-unittest.cc b/deps/v8/test/unittests/objects/backing-store-unittest.cc new file mode 100644 index 00000000000000..d00f5632fe229f --- /dev/null +++ b/deps/v8/test/unittests/objects/backing-store-unittest.cc @@ -0,0 +1,128 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/objects/backing-store.h" +#include "src/base/platform/platform.h" +#include "test/unittests/test-utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace v8 { +namespace internal { + +class BackingStoreTest : public TestWithIsolate {}; + +TEST_F(BackingStoreTest, GrowWasmMemoryInPlace) { + auto backing_store = + BackingStore::AllocateWasmMemory(isolate(), 1, 2, SharedFlag::kNotShared); + CHECK(backing_store); + EXPECT_TRUE(backing_store->is_wasm_memory()); + EXPECT_EQ(1 * wasm::kWasmPageSize, backing_store->byte_length()); + EXPECT_EQ(2 * wasm::kWasmPageSize, backing_store->byte_capacity()); + + bool success = backing_store->GrowWasmMemoryInPlace(isolate(), 1, 2); + EXPECT_TRUE(success); + EXPECT_EQ(2 * wasm::kWasmPageSize, backing_store->byte_length()); +} + +TEST_F(BackingStoreTest, GrowWasmMemoryInPlace_neg) { + auto backing_store = + BackingStore::AllocateWasmMemory(isolate(), 1, 2, SharedFlag::kNotShared); + CHECK(backing_store); + EXPECT_TRUE(backing_store->is_wasm_memory()); + EXPECT_EQ(1 * wasm::kWasmPageSize, backing_store->byte_length()); + EXPECT_EQ(2 * wasm::kWasmPageSize, backing_store->byte_capacity()); + + bool success = backing_store->GrowWasmMemoryInPlace(isolate(), 2, 2); + EXPECT_FALSE(success); + EXPECT_EQ(1 * wasm::kWasmPageSize, backing_store->byte_length()); +} + +TEST_F(BackingStoreTest, GrowSharedWasmMemoryInPlace) { + auto backing_store = + BackingStore::AllocateWasmMemory(isolate(), 2, 3, SharedFlag::kShared); + CHECK(backing_store); + EXPECT_TRUE(backing_store->is_wasm_memory()); + EXPECT_EQ(2 * wasm::kWasmPageSize, backing_store->byte_length()); + EXPECT_EQ(3 * wasm::kWasmPageSize, backing_store->byte_capacity()); + + bool success = backing_store->GrowWasmMemoryInPlace(isolate(), 1, 3); + EXPECT_TRUE(success); + EXPECT_EQ(3 * wasm::kWasmPageSize, backing_store->byte_length()); +} + +TEST_F(BackingStoreTest, CopyWasmMemory) { + auto bs1 = + BackingStore::AllocateWasmMemory(isolate(), 1, 2, SharedFlag::kNotShared); + CHECK(bs1); + EXPECT_TRUE(bs1->is_wasm_memory()); + EXPECT_EQ(1 * wasm::kWasmPageSize, bs1->byte_length()); + EXPECT_EQ(2 * wasm::kWasmPageSize, bs1->byte_capacity()); + + auto bs2 = bs1->CopyWasmMemory(isolate(), 3); + EXPECT_TRUE(bs2->is_wasm_memory()); + EXPECT_EQ(3 * wasm::kWasmPageSize, bs2->byte_length()); + EXPECT_EQ(3 * wasm::kWasmPageSize, bs2->byte_capacity()); +} + +class GrowerThread : public base::Thread { + public: + GrowerThread(Isolate* isolate, uint32_t increment, uint32_t max, + std::shared_ptr<BackingStore> backing_store) + : base::Thread(base::Thread::Options("GrowerThread")), + isolate_(isolate), + increment_(increment), + max_(max), + backing_store_(backing_store) {} + + void Run() override { + size_t max_length = max_ * wasm::kWasmPageSize; + while (true) { + size_t current_length = backing_store_->byte_length(); + if (current_length >= max_length) break; + bool result = + backing_store_->GrowWasmMemoryInPlace(isolate_, increment_, max_); + size_t new_length = backing_store_->byte_length(); + if (result) { + CHECK_GE(new_length, current_length + increment_); + } else { + CHECK_EQ(max_length, new_length); + } + } + } + + private: + Isolate* isolate_; + uint32_t increment_; + uint32_t max_; + std::shared_ptr<BackingStore> backing_store_; +}; + +TEST_F(BackingStoreTest, RacyGrowWasmMemoryInPlace) { + constexpr int kNumThreads = 10; + constexpr int kMaxPages = 1024; + GrowerThread* threads[kNumThreads]; + + std::shared_ptr<BackingStore> backing_store = + BackingStore::AllocateWasmMemory(isolate(), 0, kMaxPages, + SharedFlag::kShared); + + for (int i = 0; i < kNumThreads; i++) { + threads[i] = new GrowerThread(isolate(), 1, kMaxPages, backing_store); + CHECK(threads[i]->Start()); + } + + for (int i = 0; i < kNumThreads; i++) { + threads[i]->Join(); + } + + EXPECT_EQ(kMaxPages * wasm::kWasmPageSize, backing_store->byte_length()); + + for (int i = 0; i < kNumThreads; i++) { + delete threads[i]; + } +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/objects/object-unittest.cc b/deps/v8/test/unittests/objects/object-unittest.cc index 67dfc0f9db91f0..b1768e09235afa 100644 --- a/deps/v8/test/unittests/objects/object-unittest.cc +++ b/deps/v8/test/unittests/objects/object-unittest.cc @@ -72,25 +72,34 @@ TEST(Object, InstanceTypeListOrder) { << " vs. current = " << current_type; \ last = current; - INSTANCE_TYPE_LIST(TEST_INSTANCE_TYPE) + // Only test hand-written portion of instance type list. The generated portion + // doesn't run the same risk of getting out of order, and it does emit type + // names out of numerical order in one case: JS_OBJECT_TYPE is emitted before + // its subclass types, because types are emitted in depth-first pre-order + // traversal order, and some of its subclass types are numerically earlier. + INSTANCE_TYPE_LIST_BASE(TEST_INSTANCE_TYPE) #undef TEST_INSTANCE_TYPE } TEST(Object, StructListOrder) { - int current = static_cast<int>(InstanceType::ACCESS_CHECK_INFO_TYPE); + int current = static_cast<int>(InstanceType::FIRST_STRUCT_TYPE); int last = current - 1; ASSERT_LT(0, last); InstanceType current_type = static_cast<InstanceType>(current); #define TEST_STRUCT(TYPE, class, name) \ current_type = InstanceType::TYPE; \ current = static_cast<int>(current_type); \ - EXPECT_EQ(last + 1, current) \ + EXPECT_LE(last + 1, current) \ << " STRUCT_LIST is not ordered: " \ << " last = " << static_cast<InstanceType>(last) \ << " vs. current = " << current_type; \ last = current; - STRUCT_LIST(TEST_STRUCT) + // Only test the _BASE portion (the hand-coded part). Note that the values are + // not necessarily consecutive because some Structs that need special + // handling, such as those that have multiple Map instances associated, are + // omitted from this list. + STRUCT_LIST_GENERATOR_BASE(STRUCT_LIST_ADAPTER, TEST_STRUCT) #undef TEST_STRUCT } diff --git a/deps/v8/test/unittests/objects/osr-optimized-code-cache-unittest.cc b/deps/v8/test/unittests/objects/osr-optimized-code-cache-unittest.cc new file mode 100644 index 00000000000000..225048de637b00 --- /dev/null +++ b/deps/v8/test/unittests/objects/osr-optimized-code-cache-unittest.cc @@ -0,0 +1,412 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <cmath> +#include <iostream> +#include <limits> + +#include "src/deoptimizer/deoptimizer.h" +#include "src/objects/objects-inl.h" +#include "src/objects/objects.h" +#include "src/objects/osr-optimized-code-cache.h" +#include "test/unittests/test-utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace v8 { +namespace internal { + +namespace { + +const char* code_template_string = + "function f%d() { return 0; };" + "%%PrepareFunctionForOptimization(f%d);" + "f%d(); f%d();" + "%%OptimizeFunctionOnNextCall(f%d);" + "f%d(); f%d;"; + +void GetSource(i::ScopedVector<char>* source, int index) { + i::SNPrintF(*source, code_template_string, index, index, index, index, index, + index, index); +} + +const int kInitialLength = OSROptimizedCodeCache::kInitialLength; +const int kInitialEntries = + kInitialLength / OSROptimizedCodeCache::kEntryLength; +const int kMaxLength = OSROptimizedCodeCache::kMaxLength; +const int kMaxEntries = kMaxLength / OSROptimizedCodeCache::kEntryLength; + +} // namespace + +TEST_F(TestWithNativeContext, AddCodeToEmptyCache) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + BailoutId bailout_id(1); + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + bailout_id); + + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kInitialLength); + + HeapObject sfi_entry; + osr_cache->Get(OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&sfi_entry); + EXPECT_EQ(sfi_entry, *shared); + HeapObject code_entry; + osr_cache->Get(OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&code_entry); + EXPECT_EQ(code_entry, *code); + Smi osr_offset_entry; + osr_cache->Get(OSROptimizedCodeCache::kOsrIdOffset)->ToSmi(&osr_offset_entry); + EXPECT_EQ(osr_offset_entry.value(), bailout_id.ToInt()); +} + +TEST_F(TestWithNativeContext, GrowCodeCache) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + int bailout_id = 0; + for (bailout_id = 0; bailout_id < kInitialEntries; bailout_id++) { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kInitialLength); + + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kInitialLength * 2); + + int index = kInitialLength; + HeapObject sfi_entry; + osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&sfi_entry); + EXPECT_EQ(sfi_entry, *shared); + HeapObject code_entry; + osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&code_entry); + EXPECT_EQ(code_entry, *code); + Smi osr_offset_entry; + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset) + ->ToSmi(&osr_offset_entry); + EXPECT_EQ(osr_offset_entry.value(), bailout_id); +} + +TEST_F(TestWithNativeContext, FindCachedEntry) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + int bailout_id = 0; + for (bailout_id = 0; bailout_id < kInitialEntries; bailout_id++) { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + + i::ScopedVector<char> source1(1024); + GetSource(&source1, 1); + Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin()); + Handle<SharedFunctionInfo> shared1(function1->shared(), isolate); + Handle<Code> code1(function1->code(), isolate); + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1, + BailoutId(bailout_id)); + + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->GetOptimizedCode(shared, BailoutId(0), isolate), *code); + EXPECT_EQ( + osr_cache->GetOptimizedCode(shared1, BailoutId(bailout_id), isolate), + *code1); + + RunJS("%DeoptimizeFunction(f1)"); + EXPECT_TRUE( + osr_cache->GetOptimizedCode(shared1, BailoutId(bailout_id), isolate) + .is_null()); + + osr_cache->Set(OSROptimizedCodeCache::kCachedCodeOffset, + HeapObjectReference::ClearedValue(isolate)); + EXPECT_TRUE( + osr_cache->GetOptimizedCode(shared, BailoutId(0), isolate).is_null()); +} + +TEST_F(TestWithNativeContext, MaxCapacityCache) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + int bailout_id = 0; + // Add max_capacity - 1 entries. + for (bailout_id = 0; bailout_id < kMaxEntries - 1; bailout_id++) { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kMaxLength); + + // Add an entry to reach max capacity. + i::ScopedVector<char> source1(1024); + GetSource(&source1, 1); + Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin()); + Handle<SharedFunctionInfo> shared1(function1->shared(), isolate); + Handle<Code> code1(function1->code(), isolate); + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1, + BailoutId(bailout_id)); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kMaxLength); + + int index = (kMaxEntries - 1) * OSROptimizedCodeCache::kEntryLength; + HeapObject object; + Smi smi; + osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *shared1); + osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *code1); + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->ToSmi(&smi); + EXPECT_EQ(smi.value(), bailout_id); + + // Add an entry beyond max capacity. + i::ScopedVector<char> source2(1024); + GetSource(&source2, 2); + Handle<JSFunction> function2 = RunJS<JSFunction>(source2.begin()); + Handle<SharedFunctionInfo> shared2(function2->shared(), isolate); + Handle<Code> code2(function2->code(), isolate); + bailout_id++; + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared2, code2, + BailoutId(bailout_id)); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kMaxLength); + + index = 0; + osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *shared2); + osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *code2); + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->ToSmi(&smi); + EXPECT_EQ(smi.value(), bailout_id); +} + +TEST_F(TestWithNativeContext, ReuseClearedEntry) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + int num_entries = kInitialEntries * 2; + int expected_length = kInitialLength * 2; + int bailout_id = 0; + for (bailout_id = 0; bailout_id < num_entries; bailout_id++) { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + int clear_index1 = 0; + int clear_index2 = (num_entries - 1) * OSROptimizedCodeCache::kEntryLength; + osr_cache->Set(clear_index1 + OSROptimizedCodeCache::kSharedOffset, + HeapObjectReference::ClearedValue(isolate)); + osr_cache->Set(clear_index2 + OSROptimizedCodeCache::kCachedCodeOffset, + HeapObjectReference::ClearedValue(isolate)); + + i::ScopedVector<char> source1(1024); + GetSource(&source1, 1); + Handle<JSFunction> function1 = RunJS<JSFunction>(source1.begin()); + Handle<SharedFunctionInfo> shared1(function1->shared(), isolate); + Handle<Code> code1(function1->code(), isolate); + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared1, code1, + BailoutId(bailout_id)); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + int index = clear_index1; + HeapObject object; + Smi smi; + osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *shared1); + osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *code1); + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->ToSmi(&smi); + EXPECT_EQ(smi.value(), bailout_id); + + i::ScopedVector<char> source2(1024); + GetSource(&source2, 2); + Handle<JSFunction> function2 = RunJS<JSFunction>(source2.begin()); + Handle<SharedFunctionInfo> shared2(function2->shared(), isolate); + Handle<Code> code2(function2->code(), isolate); + bailout_id++; + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared2, code2, + BailoutId(bailout_id)); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + index = clear_index2; + osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *shared2); + osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->GetHeapObject(&object); + EXPECT_EQ(object, *code2); + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->ToSmi(&smi); + EXPECT_EQ(smi.value(), bailout_id); +} + +TEST_F(TestWithNativeContext, EvictDeoptedEntriesNoCompact) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + i::ScopedVector<char> source1(1024); + GetSource(&source1, 1); + Handle<JSFunction> deopt_function = RunJS<JSFunction>(source1.begin()); + Handle<SharedFunctionInfo> deopt_shared(deopt_function->shared(), isolate); + Handle<Code> deopt_code(deopt_function->code(), isolate); + + int num_entries = kInitialEntries * 2; + int expected_length = kInitialLength * 2; + int deopt_id1 = num_entries - 2; + int deopt_id2 = 0; + int bailout_id = 0; + for (bailout_id = 0; bailout_id < num_entries; bailout_id++) { + if (bailout_id == deopt_id1 || bailout_id == deopt_id2) { + OSROptimizedCodeCache::AddOptimizedCode( + native_context, deopt_shared, deopt_code, BailoutId(bailout_id)); + } else { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + } + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + RunJS("%DeoptimizeFunction(f1)"); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + int index = (num_entries - 2) * OSROptimizedCodeCache::kEntryLength; + EXPECT_TRUE(osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->IsCleared()); + EXPECT_TRUE(osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->IsCleared()); + EXPECT_TRUE( + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->IsCleared()); + + index = (num_entries - 1) * OSROptimizedCodeCache::kEntryLength; + EXPECT_TRUE(osr_cache->Get(index + OSROptimizedCodeCache::kSharedOffset) + ->IsCleared()); + EXPECT_TRUE(osr_cache->Get(index + OSROptimizedCodeCache::kCachedCodeOffset) + ->IsCleared()); + EXPECT_TRUE( + osr_cache->Get(index + OSROptimizedCodeCache::kOsrIdOffset)->IsCleared()); +} + +TEST_F(TestWithNativeContext, EvictDeoptedEntriesCompact) { + if (!i::FLAG_opt) return; + + i::FLAG_allow_natives_syntax = true; + + i::ScopedVector<char> source(1024); + GetSource(&source, 0); + Handle<JSFunction> function = RunJS<JSFunction>(source.begin()); + Isolate* isolate = function->GetIsolate(); + Handle<NativeContext> native_context(function->native_context(), isolate); + Handle<SharedFunctionInfo> shared(function->shared(), isolate); + Handle<Code> code(function->code(), isolate); + + i::ScopedVector<char> source1(1024); + GetSource(&source1, 1); + Handle<JSFunction> deopt_function = RunJS<JSFunction>(source1.begin()); + Handle<SharedFunctionInfo> deopt_shared(deopt_function->shared(), isolate); + Handle<Code> deopt_code(deopt_function->code(), isolate); + + int num_entries = kInitialEntries + 1; + int expected_length = kInitialLength * 2; + int bailout_id = 0; + for (bailout_id = 0; bailout_id < num_entries; bailout_id++) { + if (bailout_id % 2 == 0) { + OSROptimizedCodeCache::AddOptimizedCode( + native_context, deopt_shared, deopt_code, BailoutId(bailout_id)); + } else { + OSROptimizedCodeCache::AddOptimizedCode(native_context, shared, code, + BailoutId(bailout_id)); + } + } + Handle<OSROptimizedCodeCache> osr_cache( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), expected_length); + + RunJS("%DeoptimizeFunction(f1)"); + osr_cache = Handle<OSROptimizedCodeCache>( + native_context->GetOSROptimizedCodeCache(), isolate); + EXPECT_EQ(osr_cache->length(), kInitialLength); +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/objects/value-serializer-unittest.cc b/deps/v8/test/unittests/objects/value-serializer-unittest.cc index a3a6fb22a7bd04..a509ae293bf77e 100644 --- a/deps/v8/test/unittests/objects/value-serializer-unittest.cc +++ b/deps/v8/test/unittests/objects/value-serializer-unittest.cc @@ -10,6 +10,7 @@ #include "include/v8.h" #include "src/api/api-inl.h" #include "src/base/build_config.h" +#include "src/objects/backing-store.h" #include "src/objects/objects-inl.h" #include "src/wasm/wasm-objects.h" #include "test/unittests/test-utils.h" @@ -1729,7 +1730,7 @@ class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest { Context::Scope scope(deserialization_context()); output_buffer_ = ArrayBuffer::New(isolate(), kTestByteLength); const uint8_t data[kTestByteLength] = {0x00, 0x01, 0x80, 0xFF}; - memcpy(output_buffer_->GetContents().Data(), data, kTestByteLength); + memcpy(output_buffer_->GetBackingStore()->Data(), data, kTestByteLength); } } @@ -1987,23 +1988,44 @@ class ValueSerializerTestWithSharedArrayBufferClone ValueSerializerTestWithSharedArrayBufferClone() : serializer_delegate_(this), deserializer_delegate_(this) {} - void InitializeData(const std::vector<uint8_t>& data) { + void InitializeData(const std::vector<uint8_t>& data, bool is_wasm_memory) { data_ = data; { Context::Scope scope(serialization_context()); input_buffer_ = - SharedArrayBuffer::New(isolate(), data_.data(), data_.size()); + NewSharedArrayBuffer(data_.data(), data_.size(), is_wasm_memory); } { Context::Scope scope(deserialization_context()); output_buffer_ = - SharedArrayBuffer::New(isolate(), data_.data(), data_.size()); + NewSharedArrayBuffer(data_.data(), data_.size(), is_wasm_memory); } } const Local<SharedArrayBuffer>& input_buffer() { return input_buffer_; } const Local<SharedArrayBuffer>& output_buffer() { return output_buffer_; } + Local<SharedArrayBuffer> NewSharedArrayBuffer(void* data, size_t byte_length, + bool is_wasm_memory) { + if (is_wasm_memory) { + // TODO(titzer): there is no way to create Wasm memory backing stores + // through the API, or to create a shared array buffer whose backing + // store is wasm memory, so use the internal API. + DCHECK_EQ(0, byte_length % i::wasm::kWasmPageSize); + auto pages = byte_length / i::wasm::kWasmPageSize; + auto i_isolate = reinterpret_cast<i::Isolate*>(isolate()); + auto backing_store = i::BackingStore::AllocateWasmMemory( + i_isolate, pages, pages, i::SharedFlag::kShared); + memcpy(backing_store->buffer_start(), data, byte_length); + i::Handle<i::JSArrayBuffer> buffer = + i_isolate->factory()->NewJSSharedArrayBuffer( + std::move(backing_store)); + return Utils::ToLocalShared(buffer); + } else { + return SharedArrayBuffer::New(isolate(), data, byte_length); + } + } + static void SetUpTestCase() { flag_was_enabled_ = i::FLAG_harmony_sharedarraybuffer; i::FLAG_harmony_sharedarraybuffer = true; @@ -2075,7 +2097,7 @@ bool ValueSerializerTestWithSharedArrayBufferClone::flag_was_enabled_ = false; TEST_F(ValueSerializerTestWithSharedArrayBufferClone, RoundTripSharedArrayBufferClone) { - InitializeData({0x00, 0x01, 0x80, 0xFF}); + InitializeData({0x00, 0x01, 0x80, 0xFF}, false); EXPECT_CALL(serializer_delegate_, GetSharedArrayBufferId(isolate(), input_buffer())) @@ -2114,7 +2136,7 @@ TEST_F(ValueSerializerTestWithSharedArrayBufferClone, std::vector<uint8_t> data = {0x00, 0x01, 0x80, 0xFF}; data.resize(65536); - InitializeData(data); + InitializeData(data, true); EXPECT_CALL(serializer_delegate_, GetSharedArrayBufferId(isolate(), input_buffer())) diff --git a/deps/v8/test/unittests/tasks/background-compile-task-unittest.cc b/deps/v8/test/unittests/tasks/background-compile-task-unittest.cc index 8c3fb017a4ec49..a9a0fac66bae5c 100644 --- a/deps/v8/test/unittests/tasks/background-compile-task-unittest.cc +++ b/deps/v8/test/unittests/tasks/background-compile-task-unittest.cc @@ -9,7 +9,6 @@ #include "src/ast/ast.h" #include "src/ast/scopes.h" #include "src/base/platform/semaphore.h" -#include "src/base/template-utils.h" #include "src/codegen/compiler.h" #include "src/execution/isolate-inl.h" #include "src/flags/flags.h" @@ -198,7 +197,7 @@ TEST_F(BackgroundCompileTaskTest, CompileOnBackgroundThread) { NewBackgroundCompileTask(isolate(), shared)); base::Semaphore semaphore(0); - auto background_task = base::make_unique<CompileTask>(task.get(), &semaphore); + auto background_task = std::make_unique<CompileTask>(task.get(), &semaphore); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(background_task)); semaphore.Wait(); diff --git a/deps/v8/test/unittests/tasks/cancelable-tasks-unittest.cc b/deps/v8/test/unittests/tasks/cancelable-tasks-unittest.cc index 2a0e7d7f90fe2f..63ddaae758d09d 100644 --- a/deps/v8/test/unittests/tasks/cancelable-tasks-unittest.cc +++ b/deps/v8/test/unittests/tasks/cancelable-tasks-unittest.cc @@ -74,7 +74,7 @@ class CancelableTaskManagerTest : public ::testing::Test { std::unique_ptr<TestTask> NewTask( ResultType* result, TestTask::Mode mode = TestTask::kDoNothing) { - return base::make_unique<TestTask>(this, result, mode); + return std::make_unique<TestTask>(this, result, mode); } void CancelAndWait() { diff --git a/deps/v8/test/unittests/test-helpers.cc b/deps/v8/test/unittests/test-helpers.cc index 614ddba4f5fec4..1011c39fc51d7b 100644 --- a/deps/v8/test/unittests/test-helpers.cc +++ b/deps/v8/test/unittests/test-helpers.cc @@ -6,7 +6,6 @@ #include "include/v8.h" #include "src/api/api.h" -#include "src/base/template-utils.h" #include "src/execution/isolate.h" #include "src/handles/handles.h" #include "src/objects/objects-inl.h" @@ -59,7 +58,7 @@ std::unique_ptr<ParseInfo> OuterParseInfoForShared( Handle<Script> script = Handle<Script>::cast(handle(shared->script(), isolate)); std::unique_ptr<ParseInfo> result = - base::make_unique<ParseInfo>(isolate, script); + std::make_unique<ParseInfo>(isolate, script); // Create a character stream to simulate the parser having done so for the // to-level ParseProgram. diff --git a/deps/v8/test/unittests/unittests.status b/deps/v8/test/unittests/unittests.status index def90fc3b5b2d7..08022d56897cea 100644 --- a/deps/v8/test/unittests/unittests.status +++ b/deps/v8/test/unittests/unittests.status @@ -14,19 +14,13 @@ 'RandomNumberGenerator.NextSampleInvalidParam': [SKIP], 'RandomNumberGenerator.NextSampleSlowInvalidParam1': [SKIP], 'RandomNumberGenerator.NextSampleSlowInvalidParam2': [SKIP], -}], # 'system == macos and asan' - -['(arch == arm or arch == mips) and not simulator_run', { - # Uses too much memory. - 'Parameterized/WasmCodeManagerTest.GrowingVsFixedModule/Fixed': [SKIP] -}], # '(arch == arm or arch == mips) and not simulator_run' +}], # system == macos and asan ############################################################################## ['lite_mode or variant == jitless', { # TODO(v8:7777): Re-enable once wasm is supported in jitless mode. 'ValueSerializerTestWithSharedArrayBufferClone.RoundTripWebAssemblyMemory': [SKIP], 'ValueSerializerTestWithWasm.*': [SKIP], - 'Parameterized/WasmCodeManagerTest.*': [SKIP], }], # lite_mode or variant == jitless ############################################################################## @@ -37,19 +31,18 @@ ['system == windows and asan', { # BUG(893437). 'Torque*': [SKIP], -}], # 'system == windows and asan' +}], # system == windows and asan ['system == windows and arch == x64 and mode == release', { # BUG(992783). 'Torque.ConditionalFields': [SKIP], 'Torque.UsingUnderscorePrefixedIdentifierError': [SKIP], -}], # 'system == windows and arch == x64 and mode == release' +}], # system == windows and arch == x64 and mode == release -############################################################################## ['tsan == True', { # https://crbug.com/v8/9380 # The test is broken and needs to be fixed to use separate isolates. 'BackingStoreTest.RacyGrowWasmMemoryInPlace': [SKIP], -}], # 'tsan == True' +}], # tsan == True ] diff --git a/deps/v8/test/unittests/wasm/OWNERS b/deps/v8/test/unittests/wasm/OWNERS index dc68b3973351c0..16b08f3b3b743a 100644 --- a/deps/v8/test/unittests/wasm/OWNERS +++ b/deps/v8/test/unittests/wasm/OWNERS @@ -1,5 +1,5 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org titzer@chromium.org # COMPONENT: Blink>JavaScript>WebAssembly diff --git a/deps/v8/test/unittests/wasm/control-transfer-unittest.cc b/deps/v8/test/unittests/wasm/control-transfer-unittest.cc index 29cb1761970b04..54f22135f1c0bc 100644 --- a/deps/v8/test/unittests/wasm/control-transfer-unittest.cc +++ b/deps/v8/test/unittests/wasm/control-transfer-unittest.cc @@ -87,8 +87,7 @@ class ControlTransferTest : public TestWithZone { } void CheckNoOtherTargets( - const byte* start, const byte* end, - ControlTransferMap& map, // NOLINT(runtime/references) + const byte* start, const byte* end, const ControlTransferMap& map, std::initializer_list<ExpectedControlTransfer> targets) { // Check there are no other control targets. for (pc_t pc = 0; start + pc < end; pc++) { diff --git a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc index 791770ee948998..7e55283b614de0 100644 --- a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc @@ -33,8 +33,8 @@ namespace function_body_decoder_unittest { #define WASM_IF_OP kExprIf, kLocalVoid #define WASM_LOOP_OP kExprLoop, kLocalVoid -static const byte kCodeGetLocal0[] = {kExprGetLocal, 0}; -static const byte kCodeGetLocal1[] = {kExprGetLocal, 1}; +static const byte kCodeGetLocal0[] = {kExprLocalGet, 0}; +static const byte kCodeGetLocal1[] = {kExprLocalGet, 1}; static const byte kCodeSetLocal0[] = {WASM_SET_LOCAL(0, WASM_ZERO)}; static const byte kCodeTeeLocal0[] = {WASM_TEE_LOCAL(0, WASM_ZERO)}; @@ -408,7 +408,7 @@ TEST_F(FunctionBodyDecoderTest, GetLocalN_local) { for (byte i = 1; i < 8; i++) { AddLocals(kWasmI32, 1); for (byte j = 0; j < i; j++) { - ExpectValidates(sigs.i_v(), {kExprGetLocal, j}); + ExpectValidates(sigs.i_v(), {kExprLocalGet, j}); } } } @@ -422,7 +422,7 @@ TEST_F(FunctionBodyDecoderTest, GetLocal1_fail_no_locals) { } TEST_F(FunctionBodyDecoderTest, GetLocal_off_end) { - ExpectFailure(sigs.i_i(), {kExprGetLocal}); + ExpectFailure(sigs.i_i(), {kExprLocalGet}); } TEST_F(FunctionBodyDecoderTest, NumLocalBelowLimit) { @@ -444,29 +444,29 @@ TEST_F(FunctionBodyDecoderTest, GetLocal_varint) { const int kMaxLocals = kV8MaxWasmFunctionLocals - 1; AddLocals(kWasmI32, kMaxLocals); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_1(66)}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_2(7777)}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_3(8888)}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(9999)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_1(66)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_2(7777)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_3(8888)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_4(9999)}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_5(kMaxLocals - 1)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_5(kMaxLocals - 1)}); - ExpectFailure(sigs.i_i(), {kExprGetLocal, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}); + ExpectFailure(sigs.i_i(), {kExprLocalGet, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals - 1)}); - ExpectValidates(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals)}); - ExpectFailure(sigs.i_i(), {kExprGetLocal, U32V_4(kMaxLocals + 1)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_4(kMaxLocals - 1)}); + ExpectValidates(sigs.i_i(), {kExprLocalGet, U32V_4(kMaxLocals)}); + ExpectFailure(sigs.i_i(), {kExprLocalGet, U32V_4(kMaxLocals + 1)}); - ExpectFailure(sigs.i_v(), {kExprGetLocal, U32V_4(kMaxLocals)}); - ExpectFailure(sigs.i_v(), {kExprGetLocal, U32V_4(kMaxLocals + 1)}); + ExpectFailure(sigs.i_v(), {kExprLocalGet, U32V_4(kMaxLocals)}); + ExpectFailure(sigs.i_v(), {kExprLocalGet, U32V_4(kMaxLocals + 1)}); } TEST_F(FunctionBodyDecoderTest, GetLocal_toomany) { AddLocals(kWasmI32, kV8MaxWasmFunctionLocals - 100); AddLocals(kWasmI32, 100); - ExpectValidates(sigs.i_v(), {kExprGetLocal, U32V_1(66)}); - ExpectFailure(sigs.i_i(), {kExprGetLocal, U32V_1(66)}); + ExpectValidates(sigs.i_v(), {kExprLocalGet, U32V_1(66)}); + ExpectFailure(sigs.i_i(), {kExprLocalGet, U32V_1(66)}); } TEST_F(FunctionBodyDecoderTest, Binops_off_end) { @@ -476,13 +476,13 @@ TEST_F(FunctionBodyDecoderTest, Binops_off_end) { ExpectFailure(sigs.i_i(), code1); } - byte code3[] = {kExprGetLocal, 0, 0}; // [expr] [opcode] + byte code3[] = {kExprLocalGet, 0, 0}; // [expr] [opcode] for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { code3[2] = kInt32BinopOpcodes[i]; ExpectFailure(sigs.i_i(), code3); } - byte code4[] = {kExprGetLocal, 0, 0, 0}; // [expr] [opcode] [opcode] + byte code4[] = {kExprLocalGet, 0, 0, 0}; // [expr] [opcode] [opcode] for (size_t i = 0; i < arraysize(kInt32BinopOpcodes); i++) { code4[2] = kInt32BinopOpcodes[i]; code4[3] = kInt32BinopOpcodes[i]; @@ -778,7 +778,7 @@ TEST_F(FunctionBodyDecoderTest, If_else_else) { } TEST_F(FunctionBodyDecoderTest, IfEmpty) { - ExpectValidates(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd}); + ExpectValidates(sigs.v_i(), {kExprLocalGet, 0, WASM_IF_OP, kExprEnd}); } TEST_F(FunctionBodyDecoderTest, IfSet) { @@ -852,15 +852,15 @@ TEST_F(FunctionBodyDecoderTest, IfNop) { } TEST_F(FunctionBodyDecoderTest, If_end) { - ExpectValidates(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd}); - ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP, kExprEnd, kExprEnd}); + ExpectValidates(sigs.v_i(), {kExprLocalGet, 0, WASM_IF_OP, kExprEnd}); + ExpectFailure(sigs.v_i(), {kExprLocalGet, 0, WASM_IF_OP, kExprEnd, kExprEnd}); } TEST_F(FunctionBodyDecoderTest, If_falloff1) { - ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, kExprIf}); - ExpectFailure(sigs.v_i(), {kExprGetLocal, 0, WASM_IF_OP}); + ExpectFailure(sigs.v_i(), {kExprLocalGet, 0, kExprIf}); + ExpectFailure(sigs.v_i(), {kExprLocalGet, 0, WASM_IF_OP}); ExpectFailure(sigs.v_i(), - {kExprGetLocal, 0, WASM_IF_OP, kExprNop, kExprElse}); + {kExprLocalGet, 0, WASM_IF_OP, kExprNop, kExprElse}); } TEST_F(FunctionBodyDecoderTest, IfElseNop) { @@ -1001,7 +1001,7 @@ TEST_F(FunctionBodyDecoderTest, ReturnVoid3) { ExpectFailure(sigs.v_v(), {kExprRefNull}); ExpectFailure(sigs.v_v(), {kExprRefFunc, 0}); - ExpectFailure(sigs.v_i(), {kExprGetLocal, 0}); + ExpectFailure(sigs.v_i(), {kExprLocalGet, 0}); } TEST_F(FunctionBodyDecoderTest, Unreachable1) { @@ -3485,10 +3485,10 @@ TEST_F(WasmOpcodeLengthTest, MiscExpressions) { ExpectLength(5, kExprF32Const); ExpectLength(9, kExprF64Const); ExpectLength(1, kExprRefNull); - ExpectLength(2, kExprGetLocal); - ExpectLength(2, kExprSetLocal); - ExpectLength(2, kExprGetGlobal); - ExpectLength(2, kExprSetGlobal); + ExpectLength(2, kExprLocalGet); + ExpectLength(2, kExprLocalSet); + ExpectLength(2, kExprGlobalGet); + ExpectLength(2, kExprGlobalSet); ExpectLength(2, kExprCallFunction); ExpectLength(3, kExprCallIndirect); } @@ -3514,11 +3514,11 @@ TEST_F(WasmOpcodeLengthTest, I64Const) { } TEST_F(WasmOpcodeLengthTest, VariableLength) { - ExpectLength(2, kExprGetGlobal, U32V_1(1)); - ExpectLength(3, kExprGetGlobal, U32V_2(33)); - ExpectLength(4, kExprGetGlobal, U32V_3(44)); - ExpectLength(5, kExprGetGlobal, U32V_4(66)); - ExpectLength(6, kExprGetGlobal, U32V_5(77)); + ExpectLength(2, kExprGlobalGet, U32V_1(1)); + ExpectLength(3, kExprGlobalGet, U32V_2(33)); + ExpectLength(4, kExprGlobalGet, U32V_3(44)); + ExpectLength(5, kExprGlobalGet, U32V_4(66)); + ExpectLength(6, kExprGlobalGet, U32V_5(77)); ExpectLength(2, kExprRefFunc, U32V_1(1)); ExpectLength(3, kExprRefFunc, U32V_2(33)); diff --git a/deps/v8/test/unittests/wasm/loop-assignment-analysis-unittest.cc b/deps/v8/test/unittests/wasm/loop-assignment-analysis-unittest.cc index 5f56da3a239cc8..97e7dee27e598f 100644 --- a/deps/v8/test/unittests/wasm/loop-assignment-analysis-unittest.cc +++ b/deps/v8/test/unittests/wasm/loop-assignment-analysis-unittest.cc @@ -111,7 +111,7 @@ TEST_F(WasmLoopAssignmentAnalyzerTest, NestedIf) { TEST_F(WasmLoopAssignmentAnalyzerTest, BigLocal) { num_locals = 65000; for (int i = 13; i < 65000; i = static_cast<int>(i * 1.5)) { - byte code[] = {WASM_LOOP(WASM_I32V_1(11), kExprSetLocal, U32V_3(i))}; + byte code[] = {WASM_LOOP(WASM_I32V_1(11), kExprLocalSet, U32V_3(i))}; BitVector* assigned = Analyze(code, code + arraysize(code)); for (int j = 0; j < assigned->length(); j++) { @@ -185,7 +185,7 @@ TEST_F(WasmLoopAssignmentAnalyzerTest, Malformed) { TEST_F(WasmLoopAssignmentAnalyzerTest, regress_642867) { static const byte code[] = { - WASM_LOOP(WASM_ZERO, kExprSetLocal, 0xFA, 0xFF, 0xFF, 0xFF, + WASM_LOOP(WASM_ZERO, kExprLocalSet, 0xFA, 0xFF, 0xFF, 0xFF, 0x0F)}; // local index LEB128 0xFFFFFFFA // Just make sure that the analysis does not crash. Analyze(code, code + arraysize(code)); diff --git a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc index 4493fcf1dd5927..25eb1210749cc5 100644 --- a/deps/v8/test/unittests/wasm/module-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/module-decoder-unittest.cc @@ -343,6 +343,22 @@ TEST_F(WasmModuleVerifyTest, FuncRefGlobal) { } } +TEST_F(WasmModuleVerifyTest, InvalidFuncRefGlobal) { + WASM_FEATURE_SCOPE(anyref); + static const byte data[] = { + // sig#0 --------------------------------------------------------------- + SIGNATURES_SECTION_VOID_VOID, + // funcs --------------------------------------------------------------- + TWO_EMPTY_FUNCTIONS(SIG_INDEX(0)), + SECTION(Global, // -- + ENTRY_COUNT(1), // -- + kLocalFuncRef, // local type + 0, // immutable + WASM_INIT_EXPR_REF_FUNC(7)), // invalid function index + TWO_EMPTY_BODIES}; + EXPECT_FAILURE(data); +} + TEST_F(WasmModuleVerifyTest, AnyRefGlobalWithGlobalInit) { WASM_FEATURE_SCOPE(anyref); static const byte data[] = { @@ -439,17 +455,15 @@ TEST_F(WasmModuleVerifyTest, ExportMutableGlobal) { } } -static void AppendUint32v( - std::vector<byte>& buffer, // NOLINT(runtime/references) - uint32_t val) { +static void AppendUint32v(std::vector<byte>* buffer, uint32_t val) { while (true) { uint32_t next = val >> 7; uint32_t out = val & 0x7F; if (next) { - buffer.push_back(static_cast<byte>(0x80 | out)); + buffer->push_back(static_cast<byte>(0x80 | out)); val = next; } else { - buffer.push_back(static_cast<byte>(out)); + buffer->push_back(static_cast<byte>(out)); break; } } @@ -469,7 +483,7 @@ TEST_F(WasmModuleVerifyTest, NGlobals) { for (size_t g = 0; g != sizeof(globals); ++g) { buffer.push_back(globals[g]); } - AppendUint32v(buffer, i); // Number of globals. + AppendUint32v(&buffer, i); // Number of globals. for (uint32_t j = 0; j < i; j++) { buffer.insert(buffer.end(), data, data + sizeof(data)); } @@ -1072,6 +1086,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionMultipleTables) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 1 WASM_INIT_EXPR_I32V_1(7), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0)), // entry 1 @@ -1118,15 +1133,18 @@ TEST_F(WasmModuleVerifyTest, ElementSectionMixedTables) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 1 WASM_INIT_EXPR_I32V_1(7), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0), // entry 1 TABLE_INDEX(2), // element for table 2 WASM_INIT_EXPR_I32V_1(12), // index + kExternalFunction, // type 1, // elements count FUNC_INDEX(0), // function TABLE_INDEX(3), // element for table 1 WASM_INIT_EXPR_I32V_1(17), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0)), // entry 1 @@ -1159,6 +1177,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionMultipleTablesArbitraryOrder) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 0 WASM_INIT_EXPR_I32V_1(7), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0), // entry 1 @@ -1205,10 +1224,12 @@ TEST_F(WasmModuleVerifyTest, ElementSectionMixedTablesArbitraryOrder) { 4, // entry count TABLE_INDEX(2), // element for table 0 WASM_INIT_EXPR_I32V_1(10), // index + kExternalFunction, // type 1, // elements count FUNC_INDEX(0), // function TABLE_INDEX(3), // element for table 1 WASM_INIT_EXPR_I32V_1(17), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0), // entry 1 @@ -1218,6 +1239,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionMixedTablesArbitraryOrder) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 1 WASM_INIT_EXPR_I32V_1(7), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0)), // entry 1 @@ -1248,6 +1270,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionInitAnyRefTableWithFuncRef) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 1 WASM_INIT_EXPR_I32V_1(7), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0)), // entry 1 @@ -1295,6 +1318,7 @@ TEST_F(WasmModuleVerifyTest, ElementSectionDontInitAnyRefImportedTable) { FUNC_INDEX(0), // function TABLE_INDEX(1), // element for table 1 WASM_INIT_EXPR_I32V_1(17), // index + kExternalFunction, // type 2, // elements count FUNC_INDEX(0), // entry 0 FUNC_INDEX(0)), // entry 1 @@ -2345,7 +2369,7 @@ TEST_F(WasmModuleVerifyTest, PassiveDataSegment) { EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5); } -TEST_F(WasmModuleVerifyTest, PassiveElementSegment) { +TEST_F(WasmModuleVerifyTest, ActiveElementSegmentWithElements) { static const byte data[] = { // sig#0 ----------------------------------------------------------------- SIGNATURES_SECTION_VOID_VOID, @@ -2354,7 +2378,8 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegment) { // table declaration ----------------------------------------------------- SECTION(Table, ENTRY_COUNT(1), kLocalFuncRef, 0, 1), // element segments ----------------------------------------------------- - SECTION(Element, ENTRY_COUNT(1), PASSIVE, kLocalFuncRef, U32V_1(3), + SECTION(Element, ENTRY_COUNT(1), ACTIVE_WITH_ELEMENTS, TABLE_INDEX0, + WASM_INIT_EXPR_I32V_1(0), kLocalFuncRef, U32V_1(3), REF_FUNC_ELEMENT(0), REF_FUNC_ELEMENT(0), REF_NULL_ELEMENT), // code ------------------------------------------------------------------ ONE_EMPTY_BODY}; @@ -2364,6 +2389,26 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegment) { EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5); } +TEST_F(WasmModuleVerifyTest, PassiveElementSegment) { + static const byte data[] = { + // sig#0 ----------------------------------------------------------------- + SIGNATURES_SECTION_VOID_VOID, + // funcs ----------------------------------------------------------------- + ONE_EMPTY_FUNCTION(SIG_INDEX(0)), + // table declaration ----------------------------------------------------- + SECTION(Table, ENTRY_COUNT(1), kLocalFuncRef, 0, 1), + // element segments ----------------------------------------------------- + SECTION(Element, ENTRY_COUNT(1), PASSIVE_WITH_ELEMENTS, kLocalFuncRef, + U32V_1(3), REF_FUNC_ELEMENT(0), REF_FUNC_ELEMENT(0), + REF_NULL_ELEMENT), + // code ------------------------------------------------------------------ + ONE_EMPTY_BODY}; + EXPECT_FAILURE(data); + WASM_FEATURE_SCOPE(bulk_memory); + EXPECT_VERIFIES(data); + EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5); +} + TEST_F(WasmModuleVerifyTest, PassiveElementSegmentAnyRef) { static const byte data[] = { // sig#0 ----------------------------------------------------------------- @@ -2373,13 +2418,33 @@ TEST_F(WasmModuleVerifyTest, PassiveElementSegmentAnyRef) { // table declaration ----------------------------------------------------- SECTION(Table, ENTRY_COUNT(1), kLocalFuncRef, 0, 1), // element segments ----------------------------------------------------- - SECTION(Element, ENTRY_COUNT(1), PASSIVE, kLocalAnyRef, U32V_1(0)), + SECTION(Element, ENTRY_COUNT(1), PASSIVE_WITH_ELEMENTS, kLocalAnyRef, + U32V_1(0)), // code ------------------------------------------------------------------ ONE_EMPTY_BODY}; WASM_FEATURE_SCOPE(bulk_memory); EXPECT_FAILURE(data); } +TEST_F(WasmModuleVerifyTest, PassiveElementSegmentWithIndices) { + static const byte data[] = { + // sig#0 ----------------------------------------------------------------- + SIGNATURES_SECTION_VOID_VOID, + // funcs ----------------------------------------------------------------- + ONE_EMPTY_FUNCTION(SIG_INDEX(0)), + // table declaration ----------------------------------------------------- + SECTION(Table, ENTRY_COUNT(1), kLocalFuncRef, 0, 1), + // element segments ----------------------------------------------------- + SECTION(Element, ENTRY_COUNT(1), PASSIVE, kExternalFunction, + ENTRY_COUNT(3), U32V_1(0), U32V_1(0), U32V_1(0)), + // code ------------------------------------------------------------------ + ONE_EMPTY_BODY}; + EXPECT_FAILURE(data); + WASM_FEATURE_SCOPE(bulk_memory); + EXPECT_VERIFIES(data); + EXPECT_OFF_END_FAILURE(data, arraysize(data) - 5); +} + TEST_F(WasmModuleVerifyTest, DataCountSectionCorrectPlacement) { static const byte data[] = {SECTION(Element, ENTRY_COUNT(0)), SECTION(DataCount, ENTRY_COUNT(0)), diff --git a/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc b/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc index 5166b13628a5e4..7e8068095e8d31 100644 --- a/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc +++ b/deps/v8/test/unittests/wasm/streaming-decoder-unittest.cc @@ -99,7 +99,7 @@ class WasmStreamingDecoderTest : public ::testing::Test { for (int split = 0; split <= data.length(); ++split) { MockStreamingResult result; StreamingDecoder stream( - base::make_unique<MockStreamingProcessor>(&result)); + std::make_unique<MockStreamingProcessor>(&result)); stream.OnBytesReceived(data.SubVector(0, split)); stream.OnBytesReceived(data.SubVector(split, data.length())); stream.Finish(); @@ -115,7 +115,7 @@ class WasmStreamingDecoderTest : public ::testing::Test { for (int split = 0; split <= data.length(); ++split) { MockStreamingResult result; StreamingDecoder stream( - base::make_unique<MockStreamingProcessor>(&result)); + std::make_unique<MockStreamingProcessor>(&result)); stream.OnBytesReceived(data.SubVector(0, split)); stream.OnBytesReceived(data.SubVector(split, data.length())); stream.Finish(); @@ -128,7 +128,7 @@ class WasmStreamingDecoderTest : public ::testing::Test { TEST_F(WasmStreamingDecoderTest, EmptyStream) { MockStreamingResult result; - StreamingDecoder stream(base::make_unique<MockStreamingProcessor>(&result)); + StreamingDecoder stream(std::make_unique<MockStreamingProcessor>(&result)); stream.Finish(); EXPECT_FALSE(result.ok()); } @@ -137,7 +137,7 @@ TEST_F(WasmStreamingDecoderTest, IncompleteModuleHeader) { const uint8_t data[] = {U32_LE(kWasmMagic), U32_LE(kWasmVersion)}; { MockStreamingResult result; - StreamingDecoder stream(base::make_unique<MockStreamingProcessor>(&result)); + StreamingDecoder stream(std::make_unique<MockStreamingProcessor>(&result)); stream.OnBytesReceived(VectorOf(data, 1)); stream.Finish(); EXPECT_FALSE(result.ok()); diff --git a/deps/v8/test/unittests/wasm/trap-handler-x64-unittest.cc b/deps/v8/test/unittests/wasm/trap-handler-x64-unittest.cc index 9f7cfc6b1d284d..d43ade2b0e22d8 100644 --- a/deps/v8/test/unittests/wasm/trap-handler-x64-unittest.cc +++ b/deps/v8/test/unittests/wasm/trap-handler-x64-unittest.cc @@ -25,11 +25,11 @@ #include "src/codegen/assembler-inl.h" #include "src/codegen/macro-assembler-inl.h" #include "src/execution/simulator.h" +#include "src/objects/backing-store.h" #include "src/trap-handler/trap-handler.h" #include "src/utils/allocation.h" #include "src/utils/vector.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" #include "test/common/assembler-tester.h" #include "test/unittests/test-utils.h" @@ -80,19 +80,13 @@ class TrapHandlerTest : public TestWithIsolate, public ::testing::WithParamInterface<TrapHandlerStyle> { protected: void SetUp() override { - void* base = nullptr; - size_t length = 0; - accessible_memory_start_ = - i_isolate() - ->wasm_engine() - ->memory_tracker() - ->TryAllocateBackingStoreForTesting( - i_isolate()->heap(), 1 * kWasmPageSize, &base, &length); - memory_buffer_ = - base::AddressRegion(reinterpret_cast<Address>(base), length); - - // The allocated memory buffer ends with a guard page. - crash_address_ = memory_buffer_.end() - 32; + backing_store_ = BackingStore::AllocateWasmMemory(i_isolate(), 1, 1, + SharedFlag::kNotShared); + CHECK(backing_store_); + CHECK(backing_store_->has_guard_regions()); + // The allocated backing store ends with a guard page. + crash_address_ = reinterpret_cast<Address>(backing_store_->buffer_start()) + + backing_store_->byte_length() + 32; // Allocate a buffer for the generated code. buffer_ = AllocateAssemblerBuffer(AssemblerBase::kMinimalBufferSize, GetRandomMmapAddr()); @@ -122,10 +116,7 @@ class TrapHandlerTest : public TestWithIsolate, CHECK(!GetThreadInWasmFlag()); buffer_.reset(); recovery_buffer_.reset(); - - // Free the allocated backing store. - i_isolate()->wasm_engine()->memory_tracker()->FreeBackingStoreForTesting( - memory_buffer_, accessible_memory_start_); + backing_store_.reset(); // Clean up the trap handler trap_handler::RemoveTrapHandler(); @@ -252,14 +243,12 @@ class TrapHandlerTest : public TestWithIsolate, bool test_handler_executed() { return g_test_handler_executed; } - // Allocated memory which corresponds to wasm memory with guard regions. - base::AddressRegion memory_buffer_; + // The backing store used for testing the trap handler. + std::unique_ptr<BackingStore> backing_store_; + // Address within the guard region of the wasm memory. Accessing this memory // address causes a signal or exception. Address crash_address_; - // The start of the accessible region in the allocated memory. This pointer is - // needed to de-register the memory from the wasm memory tracker again. - void* accessible_memory_start_; // Buffer for generated code. std::unique_ptr<TestingAssemblerBuffer> buffer_; @@ -472,7 +461,7 @@ TEST_P(TrapHandlerTest, TestCrashInOtherThread) { *trap_handler::GetThreadInWasmThreadLocalAddress() = 0; } -INSTANTIATE_TEST_SUITE_P(/* no prefix */, TrapHandlerTest, +INSTANTIATE_TEST_SUITE_P(Traps, TrapHandlerTest, ::testing::Values(kDefault, kCallback), PrintTrapHandlerTestParam); diff --git a/deps/v8/test/unittests/wasm/wasm-code-manager-unittest.cc b/deps/v8/test/unittests/wasm/wasm-code-manager-unittest.cc index a6b29ffc6c93d0..e0abf7adb4ff41 100644 --- a/deps/v8/test/unittests/wasm/wasm-code-manager-unittest.cc +++ b/deps/v8/test/unittests/wasm/wasm-code-manager-unittest.cc @@ -9,7 +9,6 @@ #include "src/wasm/jump-table-assembler.h" #include "src/wasm/wasm-code-manager.h" #include "src/wasm/wasm-engine.h" -#include "src/wasm/wasm-memory.h" namespace v8 { namespace internal { @@ -139,230 +138,6 @@ TEST_F(DisjointAllocationPoolTest, MergingSkipLargerSrcWithGap) { CheckPool(a, {{10, 5}, {20, 15}, {36, 4}}); } -enum ModuleStyle : int { Fixed = 0, Growable = 1 }; - -std::string PrintWasmCodeManageTestParam( - ::testing::TestParamInfo<ModuleStyle> info) { - switch (info.param) { - case Fixed: - return "Fixed"; - case Growable: - return "Growable"; - } - UNREACHABLE(); -} - -class WasmCodeManagerTest : public TestWithContext, - public ::testing::WithParamInterface<ModuleStyle> { - public: - static constexpr uint32_t kNumFunctions = 10; - static size_t allocate_page_size; - static size_t commit_page_size; - - WasmCodeManagerTest() { - CHECK_EQ(allocate_page_size == 0, commit_page_size == 0); - if (allocate_page_size == 0) { - allocate_page_size = AllocatePageSize(); - commit_page_size = CommitPageSize(); - } - CHECK_NE(0, allocate_page_size); - CHECK_NE(0, commit_page_size); - manager()->DisableImplicitAllocationsForTesting(); - } - - using NativeModulePtr = std::shared_ptr<NativeModule>; - - NativeModulePtr AllocModule(size_t size, ModuleStyle style) { - std::shared_ptr<WasmModule> module(new WasmModule); - module->num_declared_functions = kNumFunctions; - bool can_request_more = style == Growable; - return engine()->NewNativeModule(i_isolate(), kAllWasmFeatures, size, - can_request_more, std::move(module)); - } - - WasmCode* AddCode(NativeModule* native_module, uint32_t index, size_t size) { - CodeDesc desc; - memset(reinterpret_cast<void*>(&desc), 0, sizeof(CodeDesc)); - std::unique_ptr<byte[]> exec_buff(new byte[size]); - desc.buffer = exec_buff.get(); - desc.instr_size = static_cast<int>(size); - std::unique_ptr<WasmCode> code = native_module->AddCode( - index, desc, 0, 0, {}, {}, WasmCode::kFunction, ExecutionTier::kNone); - return native_module->PublishCode(std::move(code)); - } - - WasmEngine* engine() { return i_isolate()->wasm_engine(); } - - WasmCodeManager* manager() { return engine()->code_manager(); } - - void SetMaxCommittedMemory(size_t limit) { - manager()->SetMaxCommittedMemoryForTesting(limit); - } -}; - -// static -size_t WasmCodeManagerTest::allocate_page_size = 0; -size_t WasmCodeManagerTest::commit_page_size = 0; - -INSTANTIATE_TEST_SUITE_P(Parameterized, WasmCodeManagerTest, - ::testing::Values(Fixed, Growable), - PrintWasmCodeManageTestParam); - -TEST_P(WasmCodeManagerTest, EmptyCase) { - SetMaxCommittedMemory(0); - CHECK_EQ(0, manager()->committed_code_space()); - - NativeModulePtr native_module = AllocModule(allocate_page_size, GetParam()); - ASSERT_DEATH_IF_SUPPORTED(AddCode(native_module.get(), 0, kCodeAlignment), - "OOM in wasm code commit"); -} - -TEST_P(WasmCodeManagerTest, AllocateAndGoOverLimit) { - SetMaxCommittedMemory(allocate_page_size); - - CHECK_EQ(0, manager()->committed_code_space()); - NativeModulePtr native_module = AllocModule(allocate_page_size, GetParam()); - CHECK(native_module); - CHECK_EQ(0, manager()->committed_code_space()); - WasmCodeRefScope code_ref_scope; - uint32_t index = 0; - WasmCode* code = AddCode(native_module.get(), index++, 1 * kCodeAlignment); - CHECK_NOT_NULL(code); - CHECK_EQ(commit_page_size, manager()->committed_code_space()); - - code = AddCode(native_module.get(), index++, 3 * kCodeAlignment); - CHECK_NOT_NULL(code); - CHECK_EQ(commit_page_size, manager()->committed_code_space()); - - code = AddCode(native_module.get(), index++, - allocate_page_size - 4 * kCodeAlignment); - CHECK_NOT_NULL(code); - CHECK_EQ(allocate_page_size, manager()->committed_code_space()); - - // This fails in "reservation" if we cannot extend the code space, or in - // "commit" it we can (since we hit the allocation limit in the - // WasmCodeManager). Hence don't check for that part of the OOM message. - ASSERT_DEATH_IF_SUPPORTED( - AddCode(native_module.get(), index++, 1 * kCodeAlignment), - "OOM in wasm code"); -} - -TEST_P(WasmCodeManagerTest, TotalLimitIrrespectiveOfModuleCount) { - SetMaxCommittedMemory(3 * allocate_page_size); - - NativeModulePtr nm1 = AllocModule(2 * allocate_page_size, GetParam()); - NativeModulePtr nm2 = AllocModule(2 * allocate_page_size, GetParam()); - CHECK(nm1); - CHECK(nm2); - WasmCodeRefScope code_ref_scope; - WasmCode* code = AddCode(nm1.get(), 0, 2 * allocate_page_size); - CHECK_NOT_NULL(code); - ASSERT_DEATH_IF_SUPPORTED(AddCode(nm2.get(), 0, 2 * allocate_page_size), - "OOM in wasm code commit"); -} - -TEST_P(WasmCodeManagerTest, GrowingVsFixedModule) { - SetMaxCommittedMemory(3 * allocate_page_size); - - NativeModulePtr nm = AllocModule(allocate_page_size, GetParam()); - size_t module_size = - GetParam() == Fixed ? kMaxWasmCodeMemory : allocate_page_size; - size_t remaining_space_in_module = module_size; - if (GetParam() == Fixed) { - // Requesting more than the remaining space fails because the module cannot - // grow. - ASSERT_DEATH_IF_SUPPORTED( - AddCode(nm.get(), 0, remaining_space_in_module + kCodeAlignment), - "OOM in wasm code reservation"); - } else { - // The module grows by one page. One page remains uncommitted. - WasmCodeRefScope code_ref_scope; - CHECK_NOT_NULL( - AddCode(nm.get(), 0, remaining_space_in_module + kCodeAlignment)); - CHECK_EQ(commit_page_size + allocate_page_size, - manager()->committed_code_space()); - } -} - -TEST_P(WasmCodeManagerTest, CommitIncrements) { - SetMaxCommittedMemory(10 * allocate_page_size); - - NativeModulePtr nm = AllocModule(3 * allocate_page_size, GetParam()); - WasmCodeRefScope code_ref_scope; - WasmCode* code = AddCode(nm.get(), 0, kCodeAlignment); - CHECK_NOT_NULL(code); - CHECK_EQ(commit_page_size, manager()->committed_code_space()); - code = AddCode(nm.get(), 1, 2 * allocate_page_size); - CHECK_NOT_NULL(code); - CHECK_EQ(commit_page_size + 2 * allocate_page_size, - manager()->committed_code_space()); - code = AddCode(nm.get(), 2, allocate_page_size - kCodeAlignment); - CHECK_NOT_NULL(code); - CHECK_EQ(3 * allocate_page_size, manager()->committed_code_space()); -} - -TEST_P(WasmCodeManagerTest, Lookup) { - SetMaxCommittedMemory(2 * allocate_page_size); - - NativeModulePtr nm1 = AllocModule(allocate_page_size, GetParam()); - NativeModulePtr nm2 = AllocModule(allocate_page_size, GetParam()); - Address mid_code1_1; - { - // The {WasmCodeRefScope} needs to die before {nm1} dies. - WasmCodeRefScope code_ref_scope; - WasmCode* code1_0 = AddCode(nm1.get(), 0, kCodeAlignment); - CHECK_EQ(nm1.get(), code1_0->native_module()); - WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment); - WasmCode* code2_0 = AddCode(nm2.get(), 0, kCodeAlignment); - WasmCode* code2_1 = AddCode(nm2.get(), 1, kCodeAlignment); - CHECK_EQ(nm2.get(), code2_1->native_module()); - - CHECK_EQ(0, code1_0->index()); - CHECK_EQ(1, code1_1->index()); - CHECK_EQ(0, code2_0->index()); - CHECK_EQ(1, code2_1->index()); - - // we know the manager object is allocated here, so we shouldn't - // find any WasmCode* associated with that ptr. - WasmCode* not_found = - manager()->LookupCode(reinterpret_cast<Address>(manager())); - CHECK_NULL(not_found); - WasmCode* found = manager()->LookupCode(code1_0->instruction_start()); - CHECK_EQ(found, code1_0); - found = manager()->LookupCode(code2_1->instruction_start() + - (code2_1->instructions().size() / 2)); - CHECK_EQ(found, code2_1); - found = manager()->LookupCode(code2_1->instruction_start() + - code2_1->instructions().size() - 1); - CHECK_EQ(found, code2_1); - found = manager()->LookupCode(code2_1->instruction_start() + - code2_1->instructions().size()); - CHECK_NULL(found); - mid_code1_1 = - code1_1->instruction_start() + (code1_1->instructions().size() / 2); - CHECK_EQ(code1_1, manager()->LookupCode(mid_code1_1)); - } - nm1.reset(); - CHECK_NULL(manager()->LookupCode(mid_code1_1)); -} - -TEST_P(WasmCodeManagerTest, LookupWorksAfterRewrite) { - SetMaxCommittedMemory(2 * allocate_page_size); - - NativeModulePtr nm1 = AllocModule(allocate_page_size, GetParam()); - - WasmCodeRefScope code_ref_scope; - WasmCode* code0 = AddCode(nm1.get(), 0, kCodeAlignment); - WasmCode* code1 = AddCode(nm1.get(), 1, kCodeAlignment); - CHECK_EQ(0, code0->index()); - CHECK_EQ(1, code1->index()); - CHECK_EQ(code1, manager()->LookupCode(code1->instruction_start())); - WasmCode* code1_1 = AddCode(nm1.get(), 1, kCodeAlignment); - CHECK_EQ(1, code1_1->index()); - CHECK_EQ(code1, manager()->LookupCode(code1->instruction_start())); - CHECK_EQ(code1_1, manager()->LookupCode(code1_1->instruction_start())); -} - } // namespace wasm_heap_unittest } // namespace wasm } // namespace internal diff --git a/deps/v8/test/wasm-js/testcfg.py b/deps/v8/test/wasm-js/testcfg.py index 197d9195f11c83..61e55477f9c565 100644 --- a/deps/v8/test/wasm-js/testcfg.py +++ b/deps/v8/test/wasm-js/testcfg.py @@ -26,7 +26,12 @@ 'name': 'js-types', 'flags': ['--experimental-wasm-type-reflection', '--no-experimental-wasm-bulk-memory'] - }] + }, + { + 'name': 'JS-BigInt-integration', + 'flags': ['--experimental-wasm-bigint'] + }, + ] class TestLoader(testsuite.JSTestLoader): diff --git a/deps/v8/test/wasm-js/tests.tar.gz.sha1 b/deps/v8/test/wasm-js/tests.tar.gz.sha1 index ec8be70e2aa179..5001675b36ede1 100644 --- a/deps/v8/test/wasm-js/tests.tar.gz.sha1 +++ b/deps/v8/test/wasm-js/tests.tar.gz.sha1 @@ -1 +1 @@ -26e59563060bd6de4adbb4021684e8cf38fe71c8 \ No newline at end of file +2ecf4038f24fc08bd9da504f15942d3abb5ec685 \ No newline at end of file diff --git a/deps/v8/test/wasm-js/wasm-js.status b/deps/v8/test/wasm-js/wasm-js.status index 42ad2a4152cec3..5d219f6eedeb55 100644 --- a/deps/v8/test/wasm-js/wasm-js.status +++ b/deps/v8/test/wasm-js/wasm-js.status @@ -7,6 +7,9 @@ # https://bugs.chromium.org/p/v8/issues/detail?id=8633 'limits': [SKIP], 'proposals/reference-types/limits': [SKIP], + # TODO(v8:9673): Enable these spec tests once they exist, and the out-dated + # tests have been removed. + 'proposals/JS-BigInt-integration/*': [SKIP], }], # ALWAYS ['arch == s390 or arch == s390x or system == aix', { diff --git a/deps/v8/test/wasm-spec-tests/OWNERS b/deps/v8/test/wasm-spec-tests/OWNERS index b347d0ae0cf827..8c66d1228872ba 100644 --- a/deps/v8/test/wasm-spec-tests/OWNERS +++ b/deps/v8/test/wasm-spec-tests/OWNERS @@ -1,4 +1,4 @@ ahaas@chromium.org -clemensh@chromium.org +clemensb@chromium.org # COMPONENT: Blink>JavaScript>WebAssembly diff --git a/deps/v8/test/wasm-spec-tests/testcfg.py b/deps/v8/test/wasm-spec-tests/testcfg.py index e0bd19f2685d04..65131327b07d9f 100644 --- a/deps/v8/test/wasm-spec-tests/testcfg.py +++ b/deps/v8/test/wasm-spec-tests/testcfg.py @@ -20,7 +20,12 @@ 'name': 'js-types', 'flags': ['--experimental-wasm-type-reflection', '--no-experimental-wasm-bulk-memory'] - }] + }, + { + 'name': 'JS-BigInt-integration', + 'flags': ['--experimental-wasm-bigint'] + }, + ] class TestLoader(testsuite.JSTestLoader): pass diff --git a/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1 b/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1 index 36c9e08ac1effc..c61881d0725463 100644 --- a/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1 +++ b/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1 @@ -1 +1 @@ -d9e649f4ea6da6bd18999795201c2bd138c0d786 \ No newline at end of file +f9bd936c708402051f87f4ac8940d1916112a15a \ No newline at end of file diff --git a/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status b/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status index 16faaaed35e827..a0b96847c0e1ae 100644 --- a/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status +++ b/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status @@ -10,19 +10,16 @@ # the bulk-memory proposal. Since we've enabled bulk-memory by default, we # need to update to use its testsuite. 'linking': [FAIL], + 'binary-leb128': [FAIL], 'elem': [FAIL], 'data': [FAIL], - # TODO(v8:9658): The encoding of element segments changed in the bulk memory - # proposal - 'proposals/bulk-memory-operations/bulk': [FAIL], - 'proposals/bulk-memory-operations/table_init': [FAIL], - 'proposals/bulk-memory-operations/table_copy': [FAIL], - 'proposals/bulk-memory-operations/elem': [FAIL], - 'proposals/bulk-memory-operations/binary': [FAIL], # TODO(mstarzinger): Roll newest tests into "js-types" repository. 'proposals/js-types/exports': [FAIL], 'proposals/js-types/globals': [FAIL], 'proposals/js-types/linking': [FAIL], + # TODO(v8:9673): Enable these spec tests once they exist, and the out-dated + # tests have been removed. + 'proposals/JS-BigInt-integration/*': [SKIP], }], # ALWAYS ['arch == mipsel or arch == mips64el or arch == mips or arch == mips64', { diff --git a/deps/v8/third_party/inspector_protocol/README.v8 b/deps/v8/third_party/inspector_protocol/README.v8 index a092e3e7a1dff3..6a75bef675ea23 100644 --- a/deps/v8/third_party/inspector_protocol/README.v8 +++ b/deps/v8/third_party/inspector_protocol/README.v8 @@ -2,7 +2,7 @@ Name: inspector protocol Short Name: inspector_protocol URL: https://chromium.googlesource.com/deps/inspector_protocol/ Version: 0 -Revision: d114a62e144cdfdae697fe0af6581ce39a31af37 +Revision: a14dad30f0e5b0fc05911856d5a20b1ffe89fd9b License: BSD License File: LICENSE Security Critical: no diff --git a/deps/v8/third_party/inspector_protocol/bindings/bindings.h b/deps/v8/third_party/inspector_protocol/bindings/bindings.h index 0fae2032e4321d..b24b59b0e18e37 100644 --- a/deps/v8/third_party/inspector_protocol/bindings/bindings.h +++ b/deps/v8/third_party/inspector_protocol/bindings/bindings.h @@ -58,10 +58,9 @@ class ValueMaybe { return is_just_ ? value_ : default_value; } bool isJust() const { return is_just_; } - // TODO(johannes): |is_just_| isn't reset by this operation - - // introduce && to ensure avoiding continued usage of |this|? T takeJust() { assert(is_just_); + is_just_ = false; return std::move(value_); } diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding.cc b/deps/v8/third_party/inspector_protocol/encoding/encoding.cc index 6e5619d00e1c7c..fcefb8dbb9c62d 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding.cc +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding.cc @@ -85,8 +85,25 @@ std::string Status::ToASCIIString() const { return ToASCIIString("CBOR: map start expected"); case Error::CBOR_MAP_STOP_EXPECTED: return ToASCIIString("CBOR: map stop expected"); + case Error::CBOR_ARRAY_START_EXPECTED: + return ToASCIIString("CBOR: array start expected"); case Error::CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED: return ToASCIIString("CBOR: envelope size limit exceeded"); + + case Error::BINDINGS_MANDATORY_FIELD_MISSING: + return ToASCIIString("BINDINGS: mandatory field missing"); + case Error::BINDINGS_BOOL_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: bool value expected"); + case Error::BINDINGS_INT32_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: int32 value expected"); + case Error::BINDINGS_DOUBLE_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: double value expected"); + case Error::BINDINGS_STRING_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: string value expected"); + case Error::BINDINGS_STRING8_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: string8 value expected"); + case Error::BINDINGS_BINARY_VALUE_EXPECTED: + return ToASCIIString("BINDINGS: binary value expected"); } // Some compilers can't figure out that we can't get here. return "INVALID ERROR CODE"; @@ -707,6 +724,12 @@ span<uint8_t> CBORTokenizer::GetBinary() const { return bytes_.subspan(status_.pos + (token_byte_length_ - length), length); } +span<uint8_t> CBORTokenizer::GetEnvelope() const { + assert(token_tag_ == CBORTokenTag::ENVELOPE); + auto length = static_cast<size_t>(token_start_internal_value_); + return bytes_.subspan(status_.pos, length + kEncodedEnvelopeHeaderSize); +} + span<uint8_t> CBORTokenizer::GetEnvelopeContents() const { assert(token_tag_ == CBORTokenTag::ENVELOPE); auto length = static_cast<size_t>(token_start_internal_value_); diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding.h b/deps/v8/third_party/inspector_protocol/encoding/encoding.h index c9ddd3a9becdf5..47f6d22e9b5186 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding.h +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding.h @@ -141,7 +141,16 @@ enum class Error { CBOR_TRAILING_JUNK = 0x1e, CBOR_MAP_START_EXPECTED = 0x1f, CBOR_MAP_STOP_EXPECTED = 0x20, - CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x21, + CBOR_ARRAY_START_EXPECTED = 0x21, + CBOR_ENVELOPE_SIZE_LIMIT_EXCEEDED = 0x22, + + BINDINGS_MANDATORY_FIELD_MISSING = 0x23, + BINDINGS_BOOL_VALUE_EXPECTED = 0x24, + BINDINGS_INT32_VALUE_EXPECTED = 0x25, + BINDINGS_DOUBLE_VALUE_EXPECTED = 0x26, + BINDINGS_STRING_VALUE_EXPECTED = 0x27, + BINDINGS_STRING8_VALUE_EXPECTED = 0x28, + BINDINGS_BINARY_VALUE_EXPECTED = 0x29, }; // A status value with position that can be copied. The default status @@ -419,6 +428,17 @@ class CBORTokenizer { span<uint8_t> GetBinary() const; // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE. + // Returns the envelope including its payload; message which + // can be passed to the CBORTokenizer constructor, which will + // then see the envelope token first (looking at it a second time, + // basically). + span<uint8_t> GetEnvelope() const; + + // To be called only if ::TokenTag() == CBORTokenTag::ENVELOPE. + // Returns only the payload inside the envelope, e.g., a map + // or an array. This is not a complete message by our + // IsCBORMessage definition, since it doesn't include the + // enclosing envelope (the header, basically). span<uint8_t> GetEnvelopeContents() const; private: diff --git a/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc b/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc index a36b200bad1053..005e9dcf172ee8 100644 --- a/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc +++ b/deps/v8/third_party/inspector_protocol/encoding/encoding_test.cc @@ -688,6 +688,71 @@ TEST(EncodeDecodeDoubleTest, RoundtripsAdditionalExamples) { } } +TEST(EncodeDecodeEnvelopesTest, MessageWithNestingAndEnvelopeContentsAccess) { + // This encodes and decodes the following message, which has some nesting + // and therefore envelopes. + // { "inner": { "foo" : "bar" } } + // The decoding is done with the Tokenizer, + // and we test both ::GetEnvelopeContents and GetEnvelope here. + std::vector<uint8_t> message; + EnvelopeEncoder envelope; + envelope.EncodeStart(&message); + size_t pos_after_header = message.size(); + message.push_back(EncodeIndefiniteLengthMapStart()); + EncodeString8(SpanFrom("inner"), &message); + size_t pos_inside_inner = message.size(); + EnvelopeEncoder inner_envelope; + inner_envelope.EncodeStart(&message); + size_t pos_inside_inner_contents = message.size(); + message.push_back(EncodeIndefiniteLengthMapStart()); + EncodeString8(SpanFrom("foo"), &message); + EncodeString8(SpanFrom("bar"), &message); + message.push_back(EncodeStop()); + size_t pos_after_inner = message.size(); + inner_envelope.EncodeStop(&message); + message.push_back(EncodeStop()); + envelope.EncodeStop(&message); + + CBORTokenizer tokenizer(SpanFrom(message)); + ASSERT_EQ(CBORTokenTag::ENVELOPE, tokenizer.TokenTag()); + EXPECT_EQ(message.size(), tokenizer.GetEnvelope().size()); + EXPECT_EQ(message.data(), tokenizer.GetEnvelope().data()); + EXPECT_EQ(message.data() + pos_after_header, + tokenizer.GetEnvelopeContents().data()); + EXPECT_EQ(message.size() - pos_after_header, + tokenizer.GetEnvelopeContents().size()); + tokenizer.EnterEnvelope(); + ASSERT_EQ(CBORTokenTag::MAP_START, tokenizer.TokenTag()); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + EXPECT_EQ("inner", std::string(tokenizer.GetString8().begin(), + tokenizer.GetString8().end())); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::ENVELOPE, tokenizer.TokenTag()); + EXPECT_EQ(message.data() + pos_inside_inner, tokenizer.GetEnvelope().data()); + EXPECT_EQ(pos_after_inner - pos_inside_inner, tokenizer.GetEnvelope().size()); + EXPECT_EQ(message.data() + pos_inside_inner_contents, + tokenizer.GetEnvelopeContents().data()); + EXPECT_EQ(pos_after_inner - pos_inside_inner_contents, + tokenizer.GetEnvelopeContents().size()); + tokenizer.EnterEnvelope(); + ASSERT_EQ(CBORTokenTag::MAP_START, tokenizer.TokenTag()); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + EXPECT_EQ("foo", std::string(tokenizer.GetString8().begin(), + tokenizer.GetString8().end())); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::STRING8, tokenizer.TokenTag()); + EXPECT_EQ("bar", std::string(tokenizer.GetString8().begin(), + tokenizer.GetString8().end())); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::STOP, tokenizer.TokenTag()); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::STOP, tokenizer.TokenTag()); + tokenizer.Next(); + ASSERT_EQ(CBORTokenTag::DONE, tokenizer.TokenTag()); +} + // ============================================================================= // cbor::NewCBOREncoder - for encoding from a streaming parser // ============================================================================= diff --git a/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_cpp.template b/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_cpp.template index 11843f433007fc..84c3efd3a0e652 100644 --- a/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_cpp.template +++ b/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_cpp.template @@ -302,15 +302,21 @@ void UberDispatcher::dispatch(int callId, const String& in_method, std::unique_p UberDispatcher::~UberDispatcher() = default; // static -std::unique_ptr<InternalResponse> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params) +std::unique_ptr<Serializable> InternalResponse::createResponse(int callId, std::unique_ptr<Serializable> params) { - return std::unique_ptr<InternalResponse>(new InternalResponse(callId, String(), std::move(params))); + return std::unique_ptr<Serializable>(new InternalResponse(callId, String(), std::move(params))); } // static -std::unique_ptr<InternalResponse> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params) +std::unique_ptr<Serializable> InternalResponse::createNotification(const String& notification, std::unique_ptr<Serializable> params) { - return std::unique_ptr<InternalResponse>(new InternalResponse(0, notification, std::move(params))); + return std::unique_ptr<Serializable>(new InternalResponse(0, notification, std::move(params))); +} + +// static +std::unique_ptr<Serializable> InternalResponse::createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& message) +{ + return ProtocolError::createErrorResponse(callId, code, message, nullptr); } String InternalResponse::serializeToJSON() diff --git a/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_h.template b/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_h.template index 4aa0688adb33fc..3862fb9a73a759 100644 --- a/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_h.template +++ b/deps/v8/third_party/inspector_protocol/lib/DispatcherBase_h.template @@ -128,8 +128,9 @@ private: class InternalResponse : public Serializable { PROTOCOL_DISALLOW_COPY(InternalResponse); public: - static std::unique_ptr<InternalResponse> createResponse(int callId, std::unique_ptr<Serializable> params); - static std::unique_ptr<InternalResponse> createNotification(const String& notification, std::unique_ptr<Serializable> params = nullptr); + static std::unique_ptr<Serializable> createResponse(int callId, std::unique_ptr<Serializable> params); + static std::unique_ptr<Serializable> createNotification(const String& notification, std::unique_ptr<Serializable> params = nullptr); + static std::unique_ptr<Serializable> createErrorResponse(int callId, DispatchResponse::ErrorCode code, const String& message); String serializeToJSON() override; std::vector<uint8_t> serializeToBinary() override; diff --git a/deps/v8/third_party/inspector_protocol/templates/TypeBuilder_cpp.template b/deps/v8/third_party/inspector_protocol/templates/TypeBuilder_cpp.template index 982e2c61b8e916..b1c3ab74e35e1d 100644 --- a/deps/v8/third_party/inspector_protocol/templates/TypeBuilder_cpp.template +++ b/deps/v8/third_party/inspector_protocol/templates/TypeBuilder_cpp.template @@ -385,7 +385,6 @@ void DispatcherImpl::{{command.name}}(int callId, const String& method, const Pr {% endif %} return; {% else %} - std::unique_ptr<DispatcherBase::WeakPtr> weak = weakPtr(); std::unique_ptr<{{command_name_title}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId, method, message)); m_backend->{{command.name | to_method_case}}( {%- for property in command.parameters -%} diff --git a/deps/v8/third_party/v8/builtins/array-sort.tq b/deps/v8/third_party/v8/builtins/array-sort.tq index 04184d967661ce..5a26bf0c640175 100644 --- a/deps/v8/third_party/v8/builtins/array-sort.tq +++ b/deps/v8/third_party/v8/builtins/array-sort.tq @@ -297,7 +297,6 @@ namespace array { transitioning builtin Delete<ElementsAccessor: type>( context: Context, sortState: SortState, index: Smi): Smi { const receiver = sortState.receiver; - if (!HasProperty_Inline(receiver, index)) return kSuccess; DeleteProperty(receiver, index, kStrict); return kSuccess; } diff --git a/deps/v8/tools/clusterfuzz/toolchain/BUILD.gn b/deps/v8/tools/clusterfuzz/toolchain/BUILD.gn new file mode 100644 index 00000000000000..ddcb4e1ad2cfa5 --- /dev/null +++ b/deps/v8/tools/clusterfuzz/toolchain/BUILD.gn @@ -0,0 +1,15 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/toolchain/gcc_toolchain.gni") + +# Fake toolchain to enable build output for a pointer-compression-comparison +# build in a nested build sub-directory. We toggle pointer compression when +# this toolchain is used in v8/BUILD.gn. +clang_toolchain("clang_x64_pointer_compression") { + toolchain_args = { + current_cpu = "x64" + current_os = "linux" + } +} diff --git a/deps/v8/tools/clusterfuzz/v8_foozzie.py b/deps/v8/tools/clusterfuzz/v8_foozzie.py index ff481e93703734..3b05d3829cb169 100755 --- a/deps/v8/tools/clusterfuzz/v8_foozzie.py +++ b/deps/v8/tools/clusterfuzz/v8_foozzie.py @@ -213,14 +213,15 @@ def parse_args(): assert os.path.exists(options.first_d8) assert os.path.exists(options.second_d8) + # Ensure we make a sane comparison. + if (options.first_d8 == options.second_d8 and + options.first_config == options.second_config): + parser.error('Need either executable or config difference.') + # Infer architecture from build artifacts. options.first_arch = infer_arch(options.first_d8) options.second_arch = infer_arch(options.second_d8) - # Ensure we make a sane comparison. - if (options.first_arch == options.second_arch and - options.first_config == options.second_config): - parser.error('Need either arch or config difference.') assert options.first_arch in SUPPORTED_ARCHS assert options.second_arch in SUPPORTED_ARCHS assert options.first_config in CONFIGS diff --git a/deps/v8/tools/clusterfuzz/v8_foozzie_test.py b/deps/v8/tools/clusterfuzz/v8_foozzie_test.py index 43b65e850b03d0..356f79a1c379b3 100755 --- a/deps/v8/tools/clusterfuzz/v8_foozzie_test.py +++ b/deps/v8/tools/clusterfuzz/v8_foozzie_test.py @@ -38,10 +38,11 @@ def random(self): return 0.5 self.assertEqual( [ - '--first-config=ignition', + '--first-config=ignition_no_ic', '--second-config=ignition_turbo', '--second-d8=d8', '--second-config-extra-flags=--stress-scavenge=100', + '--second-config-extra-flags=--no-regexp-tier-up', ], v8_fuzz_config.Config('foo', Rng(), 42).choose_foozzie_flags(), ) diff --git a/deps/v8/tools/clusterfuzz/v8_fuzz_config.py b/deps/v8/tools/clusterfuzz/v8_fuzz_config.py index 0dcacf216bdab5..92bf0dd3aacd0a 100644 --- a/deps/v8/tools/clusterfuzz/v8_fuzz_config.py +++ b/deps/v8/tools/clusterfuzz/v8_fuzz_config.py @@ -11,16 +11,18 @@ [10, 'ignition', 'jitless', 'd8'], [10, 'ignition', 'slow_path', 'd8'], [5, 'ignition', 'slow_path_opt', 'd8'], - [26, 'ignition', 'ignition_turbo', 'd8'], + [25, 'ignition', 'ignition_turbo', 'd8'], [2, 'ignition_no_ic', 'ignition_turbo', 'd8'], [2, 'ignition', 'ignition_turbo_no_ic', 'd8'], - [18, 'ignition', 'ignition_turbo_opt', 'd8'], + [15, 'ignition', 'ignition_turbo_opt', 'd8'], [2, 'ignition_no_ic', 'ignition_turbo_opt', 'd8'], - [5, 'ignition_turbo_opt', 'ignition_turbo_opt', 'clang_x86/d8'], - [5, 'ignition_turbo', 'ignition_turbo', 'clang_x86/d8'], - [5, 'ignition', 'ignition', 'clang_x86/d8'], - [5, 'ignition', 'ignition', 'clang_x64_v8_arm64/d8'], - [5, 'ignition', 'ignition', 'clang_x86_v8_arm/d8'], + [4, 'ignition_turbo_opt', 'ignition_turbo_opt', 'clang_x64_pointer_compression/d8'], + [5, 'ignition_turbo', 'ignition_turbo', 'clang_x64_pointer_compression/d8'], + [4, 'ignition_turbo_opt', 'ignition_turbo_opt', 'clang_x86/d8'], + [4, 'ignition_turbo', 'ignition_turbo', 'clang_x86/d8'], + [4, 'ignition', 'ignition', 'clang_x86/d8'], + [4, 'ignition', 'ignition', 'clang_x64_v8_arm64/d8'], + [4, 'ignition', 'ignition', 'clang_x86_v8_arm/d8'], ] # Additional flag experiments. List of tuples like @@ -37,6 +39,11 @@ (0.01, '--thread-pool-size=4'), (0.01, '--thread-pool-size=8'), (0.1, '--interrupt-budget=1000'), + (0.25, '--future'), + (0.2, '--no-regexp-tier-up'), + (0.1, '--regexp-interpret-all'), + (0.1, '--regexp-tier-up-ticks=10'), + (0.1, '--regexp-tier-up-ticks=100'), ] class Config(object): diff --git a/deps/v8/tools/debug_helper/BUILD.gn b/deps/v8/tools/debug_helper/BUILD.gn index c81fddc9e5769a..2fe5f0d8be0d21 100644 --- a/deps/v8/tools/debug_helper/BUILD.gn +++ b/deps/v8/tools/debug_helper/BUILD.gn @@ -100,5 +100,8 @@ v8_component("v8_debug_helper") { configs += [ "//third_party/icu:icu_config" ] } + remove_configs = [ "//build/config/compiler:no_rtti" ] + configs += [ "//build/config/compiler:rtti" ] + public_configs = [ ":external_config" ] } diff --git a/deps/v8/tools/debug_helper/debug-helper-internal.cc b/deps/v8/tools/debug_helper/debug-helper-internal.cc index ee5629b4383f7a..597ea7a639ddfd 100644 --- a/deps/v8/tools/debug_helper/debug-helper-internal.cc +++ b/deps/v8/tools/debug_helper/debug-helper-internal.cc @@ -12,15 +12,14 @@ namespace v8_debug_helper_internal { bool IsPointerCompressed(uintptr_t address) { #if COMPRESS_POINTERS_BOOL - STATIC_ASSERT(i::kPtrComprHeapReservationSize == uintptr_t{1} << 32); - intptr_t signed_address = static_cast<intptr_t>(address); - return signed_address >= INT32_MIN && signed_address <= INT32_MAX; + return address < i::kPtrComprHeapReservationSize; #else return false; #endif } -uintptr_t Decompress(uintptr_t address, uintptr_t any_uncompressed_ptr) { +uintptr_t EnsureDecompressed(uintptr_t address, + uintptr_t any_uncompressed_ptr) { if (!COMPRESS_POINTERS_BOOL || !IsPointerCompressed(address)) return address; return i::DecompressTaggedAny(any_uncompressed_ptr, static_cast<i::Tagged_t>(address)); @@ -55,4 +54,8 @@ void TqObject::Visit(TqObjectVisitor* visitor) const { visitor->VisitObject(this); } +bool TqObject::IsSuperclassOf(const TqObject* other) const { + return GetName() != other->GetName(); +} + } // namespace v8_debug_helper_internal diff --git a/deps/v8/tools/debug_helper/debug-helper-internal.h b/deps/v8/tools/debug_helper/debug-helper-internal.h index 82506c0941015d..e2161e25ba5cf3 100644 --- a/deps/v8/tools/debug_helper/debug-helper-internal.h +++ b/deps/v8/tools/debug_helper/debug-helper-internal.h @@ -10,6 +10,7 @@ #ifndef V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_ #define V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_INTERNAL_H_ +#include <memory> #include <string> #include <vector> @@ -27,6 +28,7 @@ struct Value { TValue value; }; +// Internal version of API class v8::debug_helper::ObjectProperty. class ObjectProperty { public: inline ObjectProperty(std::string name, std::string type, @@ -68,15 +70,20 @@ struct ObjectPropertiesResultExtended : public d::ObjectPropertiesResult { ObjectPropertiesResultInternal* base; // Back reference for cleanup }; +// Internal version of API class v8::debug_helper::ObjectPropertiesResult. class ObjectPropertiesResult { public: - inline ObjectPropertiesResult( + ObjectPropertiesResult(d::TypeCheckResult type_check_result, + std::string brief, std::string type) + : type_check_result_(type_check_result), brief_(brief), type_(type) {} + ObjectPropertiesResult( d::TypeCheckResult type_check_result, std::string brief, std::string type, - std::vector<std::unique_ptr<ObjectProperty>> properties) - : type_check_result_(type_check_result), - brief_(brief), - type_(type), - properties_(std::move(properties)) {} + std::vector<std::unique_ptr<ObjectProperty>> properties, + std::vector<std::string> guessed_types) + : ObjectPropertiesResult(type_check_result, brief, type) { + properties_ = std::move(properties); + guessed_types_ = std::move(guessed_types); + } inline void Prepend(const char* prefix) { brief_ = prefix + brief_; } @@ -85,11 +92,17 @@ class ObjectPropertiesResult { public_view_.brief = brief_.c_str(); public_view_.type = type_.c_str(); public_view_.num_properties = properties_.size(); - properties_raw_.resize(0); + properties_raw_.clear(); for (const auto& property : properties_) { properties_raw_.push_back(property->GetPublicView()); } public_view_.properties = properties_raw_.data(); + public_view_.num_guessed_types = guessed_types_.size(); + guessed_types_raw_.clear(); + for (const auto& guess : guessed_types_) { + guessed_types_raw_.push_back(guess.c_str()); + } + public_view_.guessed_types = guessed_types_raw_.data(); public_view_.base = this; return &public_view_; } @@ -99,9 +112,11 @@ class ObjectPropertiesResult { std::string brief_; std::string type_; std::vector<std::unique_ptr<ObjectProperty>> properties_; + std::vector<std::string> guessed_types_; ObjectPropertiesResultExtended public_view_; std::vector<d::ObjectProperty*> properties_raw_; + std::vector<const char*> guessed_types_raw_; }; class TqObjectVisitor; @@ -116,13 +131,24 @@ class TqObject { d::MemoryAccessor accessor) const; virtual const char* GetName() const; virtual void Visit(TqObjectVisitor* visitor) const; + virtual bool IsSuperclassOf(const TqObject* other) const; protected: uintptr_t address_; }; +// In ptr-compr builds, returns whether the address looks like a compressed +// pointer (sign-extended from 32 bits). Otherwise returns false because no +// pointers can be compressed. bool IsPointerCompressed(uintptr_t address); -uintptr_t Decompress(uintptr_t address, uintptr_t any_uncompressed_address); + +// If the given address looks like a compressed pointer, returns a decompressed +// representation of it. Otherwise returns the address unmodified. +uintptr_t EnsureDecompressed(uintptr_t address, + uintptr_t any_uncompressed_address); + +// Converts the MemoryAccessResult from attempting to read an array's length +// into the corresponding PropertyKind for the array. d::PropertyKind GetArrayKind(d::MemoryAccessResult mem_result); } // namespace v8_debug_helper_internal diff --git a/deps/v8/tools/debug_helper/debug-helper.h b/deps/v8/tools/debug_helper/debug-helper.h index 9bbec76c7cfb98..7d75843bf60374 100644 --- a/deps/v8/tools/debug_helper/debug-helper.h +++ b/deps/v8/tools/debug_helper/debug-helper.h @@ -46,6 +46,7 @@ enum class TypeCheckResult { kSmi, kWeakRef, kUsedMap, + kKnownMapPointer, kUsedTypeHint, // Failure cases: @@ -98,6 +99,16 @@ struct ObjectPropertiesResult { const char* type; // Runtime type of the object. size_t num_properties; ObjectProperty** properties; + + // If not all relevant memory is available, GetObjectProperties may respond + // with a technically correct but uninteresting type such as HeapObject, and + // use other heuristics to make reasonable guesses about what specific type + // the object actually is. You may request data about the same object again + // using any of these guesses as the type hint, but the results should be + // formatted to the user in a way that clearly indicates that they're only + // guesses. + size_t num_guessed_types; + const char** guessed_types; }; // Copies byte_count bytes of memory from the given address in the debuggee to @@ -109,7 +120,7 @@ typedef MemoryAccessResult (*MemoryAccessor)(uintptr_t address, // Additional data that can help GetObjectProperties to be more accurate. Any // fields you don't know can be set to zero and this library will do the best it // can with the information available. -struct Roots { +struct HeapAddresses { // Beginning of allocated space for various kinds of data. These can help us // to detect certain common objects that are placed in memory during startup. // These values might be provided via name-value pairs in CrashPad dumps. @@ -119,9 +130,9 @@ struct Roots { // key stored in v8::internal::Isolate::isolate_key_. // 2. Get isolate->heap_.map_space_->memory_chunk_list_.front_ and similar for // old_space_ and read_only_space_. - uintptr_t map_space; - uintptr_t old_space; - uintptr_t read_only_space; + uintptr_t map_space_first_page; + uintptr_t old_space_first_page; + uintptr_t read_only_space_first_page; // Any valid heap pointer address. On platforms where pointer compression is // enabled, this can allow us to get data from compressed pointers even if the @@ -139,7 +150,8 @@ extern "C" { V8_DEBUG_HELPER_EXPORT v8::debug_helper::ObjectPropertiesResult* _v8_debug_helper_GetObjectProperties( uintptr_t object, v8::debug_helper::MemoryAccessor memory_accessor, - const v8::debug_helper::Roots& heap_roots, const char* type_hint); + const v8::debug_helper::HeapAddresses& heap_addresses, + const char* type_hint); V8_DEBUG_HELPER_EXPORT void _v8_debug_helper_Free_ObjectPropertiesResult( v8::debug_helper::ObjectPropertiesResult* result); } @@ -159,16 +171,16 @@ using ObjectPropertiesResultPtr = // Get information about the given object pointer, which could be: // - A tagged pointer, strong or weak // - A cleared weak pointer -// - A compressed tagged pointer, sign-extended to 64 bits +// - A compressed tagged pointer, zero-extended to 64 bits // - A tagged small integer // The type hint is only used if the object's Map is missing or corrupt. It // should be the fully-qualified name of a class that inherits from // v8::internal::Object. inline ObjectPropertiesResultPtr GetObjectProperties( uintptr_t object, v8::debug_helper::MemoryAccessor memory_accessor, - const Roots& heap_roots, const char* type_hint = nullptr) { + const HeapAddresses& heap_addresses, const char* type_hint = nullptr) { return ObjectPropertiesResultPtr(_v8_debug_helper_GetObjectProperties( - object, memory_accessor, heap_roots, type_hint)); + object, memory_accessor, heap_addresses, type_hint)); } } // namespace debug_helper diff --git a/deps/v8/tools/debug_helper/gen-heap-constants.py b/deps/v8/tools/debug_helper/gen-heap-constants.py index 0fd575a994d336..1d81f2e5103c8d 100644 --- a/deps/v8/tools/debug_helper/gen-heap-constants.py +++ b/deps/v8/tools/debug_helper/gen-heap-constants.py @@ -16,6 +16,9 @@ #include <cstdint> #include <string> +#include "src/common/ptr-compr-inl.h" +#include "tools/debug_helper/debug-helper-internal.h" + namespace v8_debug_helper_internal { """ @@ -51,6 +54,22 @@ def iterate_maps(target_space, camel_space_name): iterate_maps('map_space', 'MapSpace') iterate_maps('read_only_space', 'ReadOnlySpace') +out = out + '\nvoid FillInUnknownHeapAddresses(' + \ + 'd::HeapAddresses* heap_addresses, uintptr_t any_uncompressed_ptr) {\n' +if (hasattr(v8heapconst, 'HEAP_FIRST_PAGES')): # Only exists in ptr-compr builds. + out = out + ' if (heap_addresses->any_heap_pointer == 0) {\n' + out = out + ' heap_addresses->any_heap_pointer = any_uncompressed_ptr;\n' + out = out + ' }\n' + expected_spaces = set(['map_space', 'read_only_space', 'old_space']) + for offset, space_name in v8heapconst.HEAP_FIRST_PAGES.items(): + if (space_name in expected_spaces): + out = out + ' if (heap_addresses->' + space_name + '_first_page == 0) {\n' + out = out + ' heap_addresses->' + space_name + \ + '_first_page = i::DecompressTaggedPointer(any_uncompressed_ptr, ' + \ + str(offset) + ');\n' + out = out + ' }\n' +out = out + '}\n' + out = out + '\n}\n' try: diff --git a/deps/v8/tools/debug_helper/get-object-properties.cc b/deps/v8/tools/debug_helper/get-object-properties.cc index fbe992c40ee3ea..8eeeb840932722 100644 --- a/deps/v8/tools/debug_helper/get-object-properties.cc +++ b/deps/v8/tools/debug_helper/get-object-properties.cc @@ -34,7 +34,7 @@ namespace v8_debug_helper_internal { V(Foreign, FOREIGN_TYPE) \ V(FreeSpace, FREE_SPACE_TYPE) \ V(HeapNumber, HEAP_NUMBER_TYPE) \ - V(JSArgumentsObject, JS_ARGUMENTS_TYPE) \ + V(JSArgumentsObject, JS_ARGUMENTS_OBJECT_TYPE) \ V(JSArray, JS_ARRAY_TYPE) \ V(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE) \ V(JSArrayIterator, JS_ARRAY_ITERATOR_TYPE) \ @@ -52,8 +52,8 @@ namespace v8_debug_helper_internal { V(JSModuleNamespace, JS_MODULE_NAMESPACE_TYPE) \ V(JSPromise, JS_PROMISE_TYPE) \ V(JSProxy, JS_PROXY_TYPE) \ - V(JSRegExp, JS_REGEXP_TYPE) \ - V(JSRegExpStringIterator, JS_REGEXP_STRING_ITERATOR_TYPE) \ + V(JSRegExp, JS_REG_EXP_TYPE) \ + V(JSRegExpStringIterator, JS_REG_EXP_STRING_ITERATOR_TYPE) \ V(JSSet, JS_SET_TYPE) \ V(JSStringIterator, JS_STRING_ITERATOR_TYPE) \ V(JSTypedArray, JS_TYPED_ARRAY_TYPE) \ @@ -71,27 +71,27 @@ namespace v8_debug_helper_internal { V(PropertyCell, PROPERTY_CELL_TYPE) \ V(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE) \ V(Symbol, SYMBOL_TYPE) \ - V(WasmExceptionObject, WASM_EXCEPTION_TYPE) \ - V(WasmGlobalObject, WASM_GLOBAL_TYPE) \ - V(WasmMemoryObject, WASM_MEMORY_TYPE) \ - V(WasmModuleObject, WASM_MODULE_TYPE) \ - V(WasmTableObject, WASM_TABLE_TYPE) \ + V(WasmExceptionObject, WASM_EXCEPTION_OBJECT_TYPE) \ + V(WasmGlobalObject, WASM_GLOBAL_OBJECT_TYPE) \ + V(WasmMemoryObject, WASM_MEMORY_OBJECT_TYPE) \ + V(WasmModuleObject, WASM_MODULE_OBJECT_TYPE) \ + V(WasmTableObject, WASM_TABLE_OBJECT_TYPE) \ V(WeakArrayList, WEAK_ARRAY_LIST_TYPE) \ V(WeakCell, WEAK_CELL_TYPE) #ifdef V8_INTL_SUPPORT -#define TQ_INSTANCE_TYPES_SINGLE_NOSTRUCTS(V) \ - TQ_INSTANCE_TYPES_SINGLE_BASE(V) \ - V(JSV8BreakIterator, JS_INTL_V8_BREAK_ITERATOR_TYPE) \ - V(JSCollator, JS_INTL_COLLATOR_TYPE) \ - V(JSDateTimeFormat, JS_INTL_DATE_TIME_FORMAT_TYPE) \ - V(JSListFormat, JS_INTL_LIST_FORMAT_TYPE) \ - V(JSLocale, JS_INTL_LOCALE_TYPE) \ - V(JSNumberFormat, JS_INTL_NUMBER_FORMAT_TYPE) \ - V(JSPluralRules, JS_INTL_PLURAL_RULES_TYPE) \ - V(JSRelativeTimeFormat, JS_INTL_RELATIVE_TIME_FORMAT_TYPE) \ - V(JSSegmentIterator, JS_INTL_SEGMENT_ITERATOR_TYPE) \ - V(JSSegmenter, JS_INTL_SEGMENTER_TYPE) +#define TQ_INSTANCE_TYPES_SINGLE_NOSTRUCTS(V) \ + TQ_INSTANCE_TYPES_SINGLE_BASE(V) \ + V(JSV8BreakIterator, JS_V8_BREAK_ITERATOR_TYPE) \ + V(JSCollator, JS_COLLATOR_TYPE) \ + V(JSDateTimeFormat, JS_DATE_TIME_FORMAT_TYPE) \ + V(JSListFormat, JS_LIST_FORMAT_TYPE) \ + V(JSLocale, JS_LOCALE_TYPE) \ + V(JSNumberFormat, JS_NUMBER_FORMAT_TYPE) \ + V(JSPluralRules, JS_PLURAL_RULES_TYPE) \ + V(JSRelativeTimeFormat, JS_RELATIVE_TIME_FORMAT_TYPE) \ + V(JSSegmentIterator, JS_SEGMENT_ITERATOR_TYPE) \ + V(JSSegmenter, JS_SEGMENTER_TYPE) #else @@ -99,12 +99,14 @@ namespace v8_debug_helper_internal { #endif // V8_INTL_SUPPORT +// Used in the static assertion below. enum class InstanceTypeCheckersSingle { #define ENUM_VALUE(ClassName, INSTANCE_TYPE) k##ClassName = i::INSTANCE_TYPE, INSTANCE_TYPE_CHECKERS_SINGLE(ENUM_VALUE) #undef ENUM_VALUE }; +// Verify that the instance type list above stays in sync with the truth. #define CHECK_VALUE(ClassName, INSTANCE_TYPE) \ static_assert( \ static_cast<i::InstanceType>( \ @@ -117,6 +119,9 @@ TQ_INSTANCE_TYPES_SINGLE_NOSTRUCTS(CHECK_VALUE) // Adapts one STRUCT_LIST_GENERATOR entry to (Name, NAME) format. #define STRUCT_INSTANCE_TYPE_ADAPTER(V, NAME, Name, name) V(Name, NAME) +// Pairs of (ClassName, CLASS_NAME_TYPE) for every instance type that +// corresponds to a single Torque-defined class. Note that all Struct-derived +// classes are defined in Torque. #define TQ_INSTANCE_TYPES_SINGLE(V) \ TQ_INSTANCE_TYPES_SINGLE_NOSTRUCTS(V) \ STRUCT_LIST_GENERATOR(STRUCT_INSTANCE_TYPE_ADAPTER, V) @@ -147,109 +152,154 @@ struct TypedObject { TypedObject(d::TypeCheckResult type_check_result, std::unique_ptr<TqObject> object) : type_check_result(type_check_result), object(std::move(object)) {} + + // How we discovered the object's type, or why we failed to do so. d::TypeCheckResult type_check_result; + + // Pointer to some TqObject subclass, representing the most specific known + // type for the object. std::unique_ptr<TqObject> object; + + // Collection of other guesses at more specific types than the one represented + // by |object|. + std::vector<TypedObject> possible_types; }; TypedObject GetTypedObjectByHint(uintptr_t address, std::string type_hint_string) { -#define TYPE_NAME_CASE(ClassName, ...) \ - if (type_hint_string == "v8::internal::" #ClassName) { \ - return {d::TypeCheckResult::kUsedTypeHint, \ - v8::base::make_unique<Tq##ClassName>(address)}; \ +#define TYPE_NAME_CASE(ClassName, ...) \ + if (type_hint_string == "v8::internal::" #ClassName) { \ + return {d::TypeCheckResult::kUsedTypeHint, \ + std::make_unique<Tq##ClassName>(address)}; \ } TQ_INSTANCE_TYPES_SINGLE(TYPE_NAME_CASE) TQ_INSTANCE_TYPES_RANGE(TYPE_NAME_CASE) + STRING_CLASS_TYPES(TYPE_NAME_CASE) #undef TYPE_NAME_CASE return {d::TypeCheckResult::kUnknownTypeHint, - v8::base::make_unique<TqHeapObject>(address)}; + std::make_unique<TqHeapObject>(address)}; } -TypedObject GetTypedObjectForString(uintptr_t address, i::InstanceType type) { +TypedObject GetTypedObjectForString(uintptr_t address, i::InstanceType type, + d::TypeCheckResult type_source) { class StringGetDispatcher : public i::AllStatic { public: -#define DEFINE_METHOD(ClassName) \ - static inline TypedObject Handle##ClassName(uintptr_t address) { \ - return {d::TypeCheckResult::kUsedMap, \ - v8::base::make_unique<Tq##ClassName>(address)}; \ +#define DEFINE_METHOD(ClassName) \ + static inline TypedObject Handle##ClassName( \ + uintptr_t address, d::TypeCheckResult type_source) { \ + return {type_source, std::make_unique<Tq##ClassName>(address)}; \ } STRING_CLASS_TYPES(DEFINE_METHOD) #undef DEFINE_METHOD - static inline TypedObject HandleInvalidString(uintptr_t address) { + static inline TypedObject HandleInvalidString( + uintptr_t address, d::TypeCheckResult type_source) { return {d::TypeCheckResult::kUnknownInstanceType, - v8::base::make_unique<TqString>(address)}; + std::make_unique<TqString>(address)}; } }; return i::StringShape(type) .DispatchToSpecificTypeWithoutCast<StringGetDispatcher, TypedObject>( - address); + address, type_source); +} + +TypedObject GetTypedObjectByInstanceType(uintptr_t address, + i::InstanceType type, + d::TypeCheckResult type_source) { + switch (type) { +#define INSTANCE_TYPE_CASE(ClassName, INSTANCE_TYPE) \ + case i::INSTANCE_TYPE: \ + return {type_source, std::make_unique<Tq##ClassName>(address)}; + TQ_INSTANCE_TYPES_SINGLE(INSTANCE_TYPE_CASE) +#undef INSTANCE_TYPE_CASE + + default: + + // Special case: concrete subtypes of String are not included in the + // main instance type list because they use the low bits of the instance + // type enum as flags. + if (type <= i::LAST_STRING_TYPE) { + return GetTypedObjectForString(address, type, type_source); + } + +#define INSTANCE_RANGE_CASE(ClassName, FIRST_TYPE, LAST_TYPE) \ + if (type >= i::FIRST_TYPE && type <= i::LAST_TYPE) { \ + return {type_source, std::make_unique<Tq##ClassName>(address)}; \ + } + TQ_INSTANCE_TYPES_RANGE(INSTANCE_RANGE_CASE) +#undef INSTANCE_RANGE_CASE + + return {d::TypeCheckResult::kUnknownInstanceType, + std::make_unique<TqHeapObject>(address)}; + } } TypedObject GetTypedHeapObject(uintptr_t address, d::MemoryAccessor accessor, - const char* type_hint) { - auto heap_object = v8::base::make_unique<TqHeapObject>(address); + const char* type_hint, + const d::HeapAddresses& heap_addresses) { + auto heap_object = std::make_unique<TqHeapObject>(address); Value<uintptr_t> map_ptr = heap_object->GetMapValue(accessor); if (map_ptr.validity != d::MemoryAccessResult::kOk) { + // If we can't read the Map pointer from the object, then we likely can't + // read anything else, so there's not any point in attempting to use the + // type hint. Just return a failure. return {map_ptr.validity == d::MemoryAccessResult::kAddressNotValid ? d::TypeCheckResult::kObjectPointerInvalid : d::TypeCheckResult::kObjectPointerValidButInaccessible, std::move(heap_object)}; } + Value<i::InstanceType> type = TqMap(map_ptr.value).GetInstanceTypeValue(accessor); - if (type.validity == d::MemoryAccessResult::kOk) { - // Dispatch to the appropriate method for each instance type. After calling - // the generated method to fetch properties, we can add custom properties. - switch (type.value) { -#define INSTANCE_TYPE_CASE(ClassName, INSTANCE_TYPE) \ - case i::INSTANCE_TYPE: \ - return {d::TypeCheckResult::kUsedMap, \ - v8::base::make_unique<Tq##ClassName>(address)}; - TQ_INSTANCE_TYPES_SINGLE(INSTANCE_TYPE_CASE) -#undef INSTANCE_TYPE_CASE - - default: + return GetTypedObjectByInstanceType(address, type.value, + d::TypeCheckResult::kUsedMap); + } - // Special case: concrete subtypes of String are not included in the - // main instance type list because they use the low bits of the instance - // type enum as flags. - if (type.value <= i::LAST_STRING_TYPE) { - return GetTypedObjectForString(address, type.value); - } + // We can't read the Map, so check whether it is in the list of known Maps, + // as another way to get its instance type. + KnownInstanceType known_map_type = + FindKnownMapInstanceType(map_ptr.value, heap_addresses); + if (known_map_type.confidence == KnownInstanceType::Confidence::kHigh) { + DCHECK_EQ(known_map_type.types.size(), 1); + return GetTypedObjectByInstanceType(address, known_map_type.types[0], + d::TypeCheckResult::kKnownMapPointer); + } -#define INSTANCE_RANGE_CASE(ClassName, FIRST_TYPE, LAST_TYPE) \ - if (type.value >= i::FIRST_TYPE && type.value <= i::LAST_TYPE) { \ - return {d::TypeCheckResult::kUsedMap, \ - v8::base::make_unique<Tq##ClassName>(address)}; \ + // Create a basic result that says that the object is a HeapObject and we + // couldn't read its Map. + TypedObject result = { + type.validity == d::MemoryAccessResult::kAddressNotValid + ? d::TypeCheckResult::kMapPointerInvalid + : d::TypeCheckResult::kMapPointerValidButInaccessible, + std::move(heap_object)}; + + // If a type hint is available, it may give us something more specific than + // HeapObject. However, a type hint of Object would be even less specific, so + // we'll only use the type hint if it's a subclass of HeapObject. + if (type_hint != nullptr) { + TypedObject hint_result = GetTypedObjectByHint(address, type_hint); + if (result.object->IsSuperclassOf(hint_result.object.get())) { + result = std::move(hint_result); + } } - TQ_INSTANCE_TYPES_RANGE(INSTANCE_RANGE_CASE) -#undef INSTANCE_RANGE_CASE - return {d::TypeCheckResult::kUnknownInstanceType, - std::move(heap_object)}; - break; + // If low-confidence results are available from known Maps, include them only + // if they don't contradict the primary type and would provide some additional + // specificity. + for (const i::InstanceType type_guess : known_map_type.types) { + TypedObject guess_result = GetTypedObjectByInstanceType( + address, type_guess, d::TypeCheckResult::kKnownMapPointer); + if (result.object->IsSuperclassOf(guess_result.object.get())) { + result.possible_types.push_back(std::move(guess_result)); } - } else if (type_hint != nullptr) { - // Try to use the provided type hint, since the real instance type is - // unavailable. - return GetTypedObjectByHint(address, type_hint); - } else { - // TODO(v8:9376): Use known maps here. If known map is just a guess (because - // root pointers weren't provided), then create a synthetic property with - // the more specific type. Then the caller could presumably ask us again - // with the type hint we provided. Otherwise, just go ahead and use it to - // generate properties. - return {type.validity == d::MemoryAccessResult::kAddressNotValid - ? d::TypeCheckResult::kMapPointerInvalid - : d::TypeCheckResult::kMapPointerValidButInaccessible, - std::move(heap_object)}; } + + return result; } #undef STRUCT_INSTANCE_TYPE_ADAPTER @@ -261,8 +311,13 @@ TypedObject GetTypedHeapObject(uintptr_t address, d::MemoryAccessor accessor, // An object visitor that accumulates the first few characters of a string. class ReadStringVisitor : public TqObjectVisitor { public: - ReadStringVisitor(d::MemoryAccessor accessor) - : accessor_(accessor), index_(0), limit_(INT32_MAX), done_(false) {} + ReadStringVisitor(d::MemoryAccessor accessor, + const d::HeapAddresses& heap_addresses) + : accessor_(accessor), + heap_addresses_(heap_addresses), + index_(0), + limit_(INT32_MAX), + done_(false) {} // Returns the result as UTF-8 once visiting is complete. std::string GetString() { @@ -301,7 +356,9 @@ class ReadStringVisitor : public TqObjectVisitor { void VisitConsString(const TqConsString* object) override { uintptr_t first_address = GetOrFinish(object->GetFirstValue(accessor_)); if (done_) return; - auto first = GetTypedHeapObject(first_address, accessor_, nullptr).object; + auto first = + GetTypedHeapObject(first_address, accessor_, nullptr, heap_addresses_) + .object; first->Visit(this); if (done_) return; int32_t first_length = GetOrFinish( @@ -309,7 +366,8 @@ class ReadStringVisitor : public TqObjectVisitor { uintptr_t second = GetOrFinish(object->GetSecondValue(accessor_)); if (done_) return; IndexModifier modifier(this, -first_length, -first_length); - GetTypedHeapObject(second, accessor_, nullptr).object->Visit(this); + GetTypedHeapObject(second, accessor_, nullptr, heap_addresses_) + .object->Visit(this); } void VisitSlicedString(const TqSlicedString* object) override { @@ -320,13 +378,15 @@ class ReadStringVisitor : public TqObjectVisitor { if (done_) return; int32_t limit_adjust = offset + length - limit_; IndexModifier modifier(this, offset, limit_adjust < 0 ? limit_adjust : 0); - GetTypedHeapObject(parent, accessor_, nullptr).object->Visit(this); + GetTypedHeapObject(parent, accessor_, nullptr, heap_addresses_) + .object->Visit(this); } void VisitThinString(const TqThinString* object) override { uintptr_t actual = GetOrFinish(object->GetActualValue(accessor_)); if (done_) return; - GetTypedHeapObject(actual, accessor_, nullptr).object->Visit(this); + GetTypedHeapObject(actual, accessor_, nullptr, heap_addresses_) + .object->Visit(this); } void VisitExternalString(const TqExternalString* object) override { @@ -398,6 +458,7 @@ class ReadStringVisitor : public TqObjectVisitor { std::u16string string_; // Result string. d::MemoryAccessor accessor_; + const d::HeapAddresses& heap_addresses_; int32_t index_; // Index of next char to read. int32_t limit_; // Don't read past this index (set by SlicedString). bool done_; // Whether to stop further work. @@ -406,14 +467,15 @@ class ReadStringVisitor : public TqObjectVisitor { // An object visitor that adds extra debugging information for some types. class AddInfoVisitor : public TqObjectVisitor { public: - AddInfoVisitor(const std::string& brief, d::MemoryAccessor accessor) - : accessor_(accessor), brief_(brief) {} + AddInfoVisitor(const std::string& brief, d::MemoryAccessor accessor, + const d::HeapAddresses& heap_addresses) + : accessor_(accessor), brief_(brief), heap_addresses_(heap_addresses) {} // Returns the brief object description, once visiting is complete. const std::string& GetBrief() { return brief_; } void VisitString(const TqString* object) override { - ReadStringVisitor visitor(accessor_); + ReadStringVisitor visitor(accessor_, heap_addresses_); object->Visit(&visitor); if (!brief_.empty()) brief_ += " "; brief_ += "\"" + visitor.GetString() + "\""; @@ -422,12 +484,18 @@ class AddInfoVisitor : public TqObjectVisitor { private: d::MemoryAccessor accessor_; std::string brief_; + const d::HeapAddresses& heap_addresses_; }; -std::unique_ptr<ObjectPropertiesResult> GetHeapObjectProperties( +std::unique_ptr<ObjectPropertiesResult> GetHeapObjectPropertiesNotCompressed( uintptr_t address, d::MemoryAccessor accessor, const char* type_hint, - std::string brief) { - TypedObject typed = GetTypedHeapObject(address, accessor, type_hint); + const d::HeapAddresses& heap_addresses) { + // Regardless of whether we can read the object itself, maybe we can find its + // pointer in the list of known objects. + std::string brief = FindKnownObject(address, heap_addresses); + + TypedObject typed = + GetTypedHeapObject(address, accessor, type_hint, heap_addresses); // TODO(v8:9376): Many object types need additional data that is not included // in their Torque layout definitions. For example, JSObject has an array of @@ -435,59 +503,62 @@ std::unique_ptr<ObjectPropertiesResult> GetHeapObjectProperties( // should be represented as an array in this response. If the relevant memory // is available, we should instead represent those properties (and any out-of- // object properties) using their JavaScript property names. - AddInfoVisitor visitor(brief, accessor); + AddInfoVisitor visitor(brief, accessor, heap_addresses); typed.object->Visit(&visitor); brief = visitor.GetBrief(); brief = AppendAddressAndType(brief, address, typed.object->GetName()); - return v8::base::make_unique<ObjectPropertiesResult>( + // Convert the low-confidence guessed types to a list of strings as expected + // for the response. + std::vector<std::string> guessed_types; + for (const auto& guess : typed.possible_types) { + guessed_types.push_back(guess.object->GetName()); + } + + return std::make_unique<ObjectPropertiesResult>( typed.type_check_result, brief, typed.object->GetName(), - typed.object->GetProperties(accessor)); + typed.object->GetProperties(accessor), std::move(guessed_types)); } -std::unique_ptr<ObjectPropertiesResult> GetHeapObjectProperties( - uintptr_t address, d::MemoryAccessor memory_accessor, const d::Roots& roots, - const char* type_hint) { +std::unique_ptr<ObjectPropertiesResult> GetHeapObjectPropertiesMaybeCompressed( + uintptr_t address, d::MemoryAccessor memory_accessor, + d::HeapAddresses heap_addresses, const char* type_hint) { // Try to figure out the heap range, for pointer compression (this is unused // if pointer compression is disabled). uintptr_t any_uncompressed_ptr = 0; if (!IsPointerCompressed(address)) any_uncompressed_ptr = address; - if (any_uncompressed_ptr == 0) any_uncompressed_ptr = roots.any_heap_pointer; - if (any_uncompressed_ptr == 0) any_uncompressed_ptr = roots.map_space; - if (any_uncompressed_ptr == 0) any_uncompressed_ptr = roots.old_space; - if (any_uncompressed_ptr == 0) any_uncompressed_ptr = roots.read_only_space; + if (any_uncompressed_ptr == 0) + any_uncompressed_ptr = heap_addresses.any_heap_pointer; + if (any_uncompressed_ptr == 0) + any_uncompressed_ptr = heap_addresses.map_space_first_page; + if (any_uncompressed_ptr == 0) + any_uncompressed_ptr = heap_addresses.old_space_first_page; + if (any_uncompressed_ptr == 0) + any_uncompressed_ptr = heap_addresses.read_only_space_first_page; + FillInUnknownHeapAddresses(&heap_addresses, any_uncompressed_ptr); if (any_uncompressed_ptr == 0) { // We can't figure out the heap range. Just check for known objects. - std::string brief = FindKnownObject(address, roots); + std::string brief = FindKnownObject(address, heap_addresses); brief = AppendAddressAndType(brief, address, "v8::internal::TaggedValue"); - return v8::base::make_unique<ObjectPropertiesResult>( + return std::make_unique<ObjectPropertiesResult>( d::TypeCheckResult::kUnableToDecompress, brief, - "v8::internal::TaggedValue", - std::vector<std::unique_ptr<ObjectProperty>>()); + "v8::internal::TaggedValue"); } - // TODO(v8:9376): It seems that the space roots are at predictable offsets - // within the heap reservation block when pointer compression is enabled, so - // we should be able to set those here. - - address = Decompress(address, any_uncompressed_ptr); - // From here on all addresses should be decompressed. + address = EnsureDecompressed(address, any_uncompressed_ptr); - // Regardless of whether we can read the object itself, maybe we can find its - // pointer in the list of known objects. - std::string brief = FindKnownObject(address, roots); - return GetHeapObjectProperties(address, memory_accessor, type_hint, brief); + return GetHeapObjectPropertiesNotCompressed(address, memory_accessor, + type_hint, heap_addresses); } -std::unique_ptr<ObjectPropertiesResult> GetObjectPropertiesImpl( - uintptr_t address, d::MemoryAccessor memory_accessor, const d::Roots& roots, - const char* type_hint) { - std::vector<std::unique_ptr<ObjectProperty>> props; +std::unique_ptr<ObjectPropertiesResult> GetObjectProperties( + uintptr_t address, d::MemoryAccessor memory_accessor, + const d::HeapAddresses& heap_addresses, const char* type_hint) { if (static_cast<uint32_t>(address) == i::kClearedWeakHeapObjectLower32) { - return v8::base::make_unique<ObjectPropertiesResult>( + return std::make_unique<ObjectPropertiesResult>( d::TypeCheckResult::kWeakRef, "cleared weak ref", - "v8::internal::HeapObject", std::move(props)); + "v8::internal::HeapObject"); } bool is_weak = (address & i::kHeapObjectTagMask) == i::kWeakHeapObjectTag; if (is_weak) { @@ -495,7 +566,8 @@ std::unique_ptr<ObjectPropertiesResult> GetObjectPropertiesImpl( } if (i::Internals::HasHeapObjectTag(address)) { std::unique_ptr<ObjectPropertiesResult> result = - GetHeapObjectProperties(address, memory_accessor, roots, type_hint); + GetHeapObjectPropertiesMaybeCompressed(address, memory_accessor, + heap_addresses, type_hint); if (is_weak) { result->Prepend("weak ref to "); } @@ -507,9 +579,8 @@ std::unique_ptr<ObjectPropertiesResult> GetObjectPropertiesImpl( int32_t value = i::PlatformSmiTagging::SmiToInt(address); std::stringstream stream; stream << value << " (0x" << std::hex << value << ")"; - return v8::base::make_unique<ObjectPropertiesResult>( - d::TypeCheckResult::kSmi, stream.str(), "v8::internal::Smi", - std::move(props)); + return std::make_unique<ObjectPropertiesResult>( + d::TypeCheckResult::kSmi, stream.str(), "v8::internal::Smi"); } } // namespace v8_debug_helper_internal @@ -520,10 +591,10 @@ extern "C" { V8_DEBUG_HELPER_EXPORT d::ObjectPropertiesResult* _v8_debug_helper_GetObjectProperties(uintptr_t object, d::MemoryAccessor memory_accessor, - const d::Roots& heap_roots, + const d::HeapAddresses& heap_addresses, const char* type_hint) { - return di::GetObjectPropertiesImpl(object, memory_accessor, heap_roots, - type_hint) + return di::GetObjectProperties(object, memory_accessor, heap_addresses, + type_hint) .release() ->GetPublicView(); } diff --git a/deps/v8/tools/debug_helper/heap-constants.cc b/deps/v8/tools/debug_helper/heap-constants.cc index 2bd04206900a41..9b9ed04cc1bee9 100644 --- a/deps/v8/tools/debug_helper/heap-constants.cc +++ b/deps/v8/tools/debug_helper/heap-constants.cc @@ -9,36 +9,37 @@ namespace d = v8::debug_helper; namespace v8_debug_helper_internal { -std::string FindKnownObject(uintptr_t address, const d::Roots& roots) { +std::string FindKnownObject(uintptr_t address, + const d::HeapAddresses& heap_addresses) { uintptr_t containing_page = address & ~i::kPageAlignmentMask; uintptr_t offset_in_page = address & i::kPageAlignmentMask; - // If there's a match with a known root, then search only that page. - if (containing_page == roots.map_space) { + // If there's a match with a known page, then search only that page. + if (containing_page == heap_addresses.map_space_first_page) { return FindKnownObjectInMapSpace(offset_in_page); } - if (containing_page == roots.old_space) { + if (containing_page == heap_addresses.old_space_first_page) { return FindKnownObjectInOldSpace(offset_in_page); } - if (containing_page == roots.read_only_space) { + if (containing_page == heap_addresses.read_only_space_first_page) { return FindKnownObjectInReadOnlySpace(offset_in_page); } - // For any unknown roots, compile a list of things this object might be. + // For any unknown pages, compile a list of things this object might be. std::string result; - if (roots.map_space == 0) { + if (heap_addresses.map_space_first_page == 0) { std::string sub_result = FindKnownObjectInMapSpace(offset_in_page); if (!sub_result.empty()) { result += "maybe " + sub_result; } } - if (roots.old_space == 0) { + if (heap_addresses.old_space_first_page == 0) { std::string sub_result = FindKnownObjectInOldSpace(offset_in_page); if (!sub_result.empty()) { result = (result.empty() ? "" : result + ", ") + "maybe " + sub_result; } } - if (roots.read_only_space == 0) { + if (heap_addresses.read_only_space_first_page == 0) { std::string sub_result = FindKnownObjectInReadOnlySpace(offset_in_page); if (!sub_result.empty()) { result = (result.empty() ? "" : result + ", ") + "maybe " + sub_result; @@ -48,4 +49,37 @@ std::string FindKnownObject(uintptr_t address, const d::Roots& roots) { return result; } +KnownInstanceType FindKnownMapInstanceType( + uintptr_t address, const d::HeapAddresses& heap_addresses) { + uintptr_t containing_page = address & ~i::kPageAlignmentMask; + uintptr_t offset_in_page = address & i::kPageAlignmentMask; + + // If there's a match with a known page, then search only that page. + if (containing_page == heap_addresses.map_space_first_page) { + return KnownInstanceType( + FindKnownMapInstanceTypeInMapSpace(offset_in_page)); + } + if (containing_page == heap_addresses.read_only_space_first_page) { + return KnownInstanceType( + FindKnownMapInstanceTypeInReadOnlySpace(offset_in_page)); + } + + // For any unknown pages, compile a list of things this object might be. + KnownInstanceType result; + if (heap_addresses.map_space_first_page == 0) { + int sub_result = FindKnownMapInstanceTypeInMapSpace(offset_in_page); + if (sub_result >= 0) { + result.types.push_back(static_cast<i::InstanceType>(sub_result)); + } + } + if (heap_addresses.read_only_space_first_page == 0) { + int sub_result = FindKnownMapInstanceTypeInReadOnlySpace(offset_in_page); + if (sub_result >= 0) { + result.types.push_back(static_cast<i::InstanceType>(sub_result)); + } + } + + return result; +} + } // namespace v8_debug_helper_internal diff --git a/deps/v8/tools/debug_helper/heap-constants.h b/deps/v8/tools/debug_helper/heap-constants.h index f3149bbb47802c..6c1f17dc8296a8 100644 --- a/deps/v8/tools/debug_helper/heap-constants.h +++ b/deps/v8/tools/debug_helper/heap-constants.h @@ -7,21 +7,60 @@ #include <cstdint> #include <string> +#include <vector> #include "debug-helper.h" +#include "src/objects/instance-type.h" namespace d = v8::debug_helper; namespace v8_debug_helper_internal { -// Functions generated by mkgrokdump: +// ===== Functions generated by gen-heap-constants.py: ========================= + +// Returns the name of a known object, given its offset within the first page of +// the space, or empty string on failure. std::string FindKnownObjectInOldSpace(uintptr_t offset); std::string FindKnownObjectInReadOnlySpace(uintptr_t offset); std::string FindKnownObjectInMapSpace(uintptr_t offset); -std::string FindKnownMapInstanceTypeInMapSpace(uintptr_t offset); -std::string FindKnownMapInstanceTypeInReadOnlySpace(uintptr_t offset); -std::string FindKnownObject(uintptr_t address, const d::Roots& roots); +// In builds with pointer compression enabled, sets the *_first_page members in +// the HeapAddresses object. In other builds, does nothing. +void FillInUnknownHeapAddresses(d::HeapAddresses* heap_addresses, + uintptr_t any_uncompressed_ptr); + +// Returns the instance type for the known Map, given its offset within the +// first page of the space, or empty string on failure. +int FindKnownMapInstanceTypeInMapSpace(uintptr_t offset); +int FindKnownMapInstanceTypeInReadOnlySpace(uintptr_t offset); + +// ===== End of generated functions. =========================================== + +// Returns a descriptive string if the given address matches a known object, or +// an empty string otherwise. +std::string FindKnownObject(uintptr_t address, + const d::HeapAddresses& heap_addresses); + +struct KnownInstanceType { + enum class Confidence { + kLow, + kHigh, + }; + KnownInstanceType() : confidence(Confidence::kLow) {} + KnownInstanceType(int type) : KnownInstanceType() { + if (type >= 0) { + confidence = Confidence::kHigh; + types.push_back(static_cast<v8::internal::InstanceType>(type)); + } + } + Confidence confidence; + std::vector<v8::internal::InstanceType> types; +}; + +// Returns information about the instance type of the Map at the given address, +// based on the list of known Maps. +KnownInstanceType FindKnownMapInstanceType( + uintptr_t address, const d::HeapAddresses& heap_addresses); } // namespace v8_debug_helper_internal diff --git a/deps/v8/tools/dev/gm.py b/deps/v8/tools/dev/gm.py index 0e01f4f8d7f869..8269b94cc2ffef 100755 --- a/deps/v8/tools/dev/gm.py +++ b/deps/v8/tools/dev/gm.py @@ -30,7 +30,8 @@ if USE_PTY: import pty -BUILD_TARGETS_TEST = ["d8", "cctest", "unittests"] +BUILD_TARGETS_TEST = ["d8", "cctest", "inspector-test", "unittests", + "wasm_api_tests"] BUILD_TARGETS_ALL = ["all"] # All arches that this script understands. diff --git a/deps/v8/tools/gcmole/BUILD.gn b/deps/v8/tools/gcmole/BUILD.gn index 51b9ef527f7961..ba2d67fd79cea2 100644 --- a/deps/v8/tools/gcmole/BUILD.gn +++ b/deps/v8/tools/gcmole/BUILD.gn @@ -11,6 +11,7 @@ group("v8_run_gcmole") { "gccause.lua", "GCMOLE.gn", "gcmole.lua", + "gcmole-test.cc", "gcmole-tools/", "parallel.py", "run-gcmole.py", diff --git a/deps/v8/tools/gcmole/gcmole.lua b/deps/v8/tools/gcmole/gcmole.lua index 6758973457ef6d..305a498b07d854 100644 --- a/deps/v8/tools/gcmole/gcmole.lua +++ b/deps/v8/tools/gcmole/gcmole.lua @@ -102,11 +102,12 @@ local function MakeClangCommandLine( end plugin_args = " " .. table.concat(plugin_args, " ") end - return CLANG_BIN .. "/clang++ -std=c++11 -c " + return CLANG_BIN .. "/clang++ -std=c++14 -c" .. " -Xclang -load -Xclang " .. CLANG_PLUGINS .. "/libgcmole.so" .. " -Xclang -plugin -Xclang " .. plugin .. (plugin_args or "") .. " -Xclang -triple -Xclang " .. triple + .. " -fno-exceptions" .. " -D" .. arch_define .. " -DENABLE_DEBUGGER_SUPPORT" .. " -DV8_INTL_SUPPORT" @@ -466,6 +467,10 @@ end local function TestRun() local errors, output = SafeCheckCorrectnessForArch('x64', true) + if not errors then + log("** Test file should produce errors, but none were found.") + return false + end local filename = "tools/gcmole/test-expectations.txt" local exp_file = assert(io.open(filename), "failed to open test expectations file") @@ -473,18 +478,18 @@ local function TestRun() if output ~= expectations then log("** Output mismatch from running tests. Please run them manually.") - else - log("** Tests ran successfully") + return false end -end -TestRun() + log("** Tests ran successfully") + return true +end -local errors = false +local errors = not TestRun() for _, arch in ipairs(ARCHS) do if not ARCHITECTURES[arch] then - error ("Unknown arch: " .. arch) + error("Unknown arch: " .. arch) end errors = SafeCheckCorrectnessForArch(arch, false) or errors diff --git a/deps/v8/tools/gdbinit b/deps/v8/tools/gdbinit index ad7847df318d29..53ead3e88195e7 100644 --- a/deps/v8/tools/gdbinit +++ b/deps/v8/tools/gdbinit @@ -138,7 +138,13 @@ Find the location of a given address in V8 pages. Usage: heap_find address end -set disassembly-flavor intel +# The 'disassembly-flavor' command is only available on i386 and x84_64. +python +try: + gdb.execute("set disassembly-flavor intel") +except gdb.error: + pass +end set disable-randomization off # Install a handler whenever the debugger stops due to a signal. It walks up the diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py index ceaf7798fd32c2..98ab941a415197 100644 --- a/deps/v8/tools/gen-postmortem-metadata.py +++ b/deps/v8/tools/gen-postmortem-metadata.py @@ -276,6 +276,7 @@ 'ExternalString, resource, Object, kResourceOffset', 'SeqOneByteString, chars, char, kHeaderSize', 'SeqTwoByteString, chars, char, kHeaderSize', + 'UncompiledData, inferred_name, String, kInferredNameOffset', 'UncompiledData, start_position, int32_t, kStartPositionOffset', 'UncompiledData, end_position, int32_t, kEndPositionOffset', 'SharedFunctionInfo, raw_function_token_offset, int16_t, kFunctionTokenOffsetOffset', @@ -286,6 +287,7 @@ 'Code, instruction_start, uintptr_t, kHeaderSize', 'Code, instruction_size, int, kInstructionSizeOffset', 'String, length, int32_t, kLengthOffset', + 'DescriptorArray, header_size, uintptr_t, kHeaderSize', ]; # @@ -296,7 +298,8 @@ expected_classes = [ 'ConsString', 'FixedArray', 'HeapNumber', 'JSArray', 'JSFunction', 'JSObject', 'JSRegExp', 'JSPrimitiveWrapper', 'Map', 'Oddball', 'Script', - 'SeqOneByteString', 'SharedFunctionInfo', 'ScopeInfo', 'JSPromise' + 'SeqOneByteString', 'SharedFunctionInfo', 'ScopeInfo', 'JSPromise', + 'DescriptorArray' ]; @@ -385,8 +388,10 @@ def load_objects(): def load_objects_from_file(objfilename, checktypes): objfile = io.open(objfilename, 'r', encoding='utf-8'); in_insttype = False; + in_torque_insttype = False typestr = ''; + torque_typestr = '' uncommented_file = '' # @@ -400,16 +405,28 @@ def load_objects_from_file(objfilename, checktypes): in_insttype = True; continue; + if (line.startswith('#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST')): + in_torque_insttype = True + continue + if (in_insttype and line.startswith('};')): in_insttype = False; continue; + if (in_torque_insttype and (not line or line.isspace())): + in_torque_insttype = False + continue + line = re.sub('//.*', '', line.strip()); if (in_insttype): typestr += line; continue; + if (in_torque_insttype): + torque_typestr += line + continue + uncommented_file += '\n' + line for match in re.finditer(r'\nclass(?:\s+V8_EXPORT(?:_PRIVATE)?)?' @@ -437,6 +454,9 @@ def load_objects_from_file(objfilename, checktypes): entries = typestr.split(','); for entry in entries: types[re.sub('\s*=.*', '', entry).lstrip()] = True; + entries = torque_typestr.split('\\') + for entry in entries: + types[re.sub(r' *V\(|\) *', '', entry)] = True # # Infer class names for each type based on a systematic transformation. @@ -446,10 +466,7 @@ def load_objects_from_file(objfilename, checktypes): # way around. # for type in types: - # - # REGEXP behaves like REG_EXP, as in JS_REGEXP_TYPE => JSRegExp. - # - usetype = re.sub('_REGEXP_', '_REG_EXP_', type); + usetype = type # # Remove the "_TYPE" suffix and then convert to camel case, diff --git a/deps/v8/tools/generate-header-include-checks.py b/deps/v8/tools/generate-header-include-checks.py index fa18d85bf50f14..909dafe74d4f96 100755 --- a/deps/v8/tools/generate-header-include-checks.py +++ b/deps/v8/tools/generate-header-include-checks.py @@ -22,7 +22,7 @@ import re import sys -# TODO(clemensh): Extend to tests. +# TODO(clemensb): Extend to tests. DEFAULT_INPUT = ['base', 'src'] DEFAULT_GN_FILE = 'BUILD.gn' MY_DIR = os.path.dirname(os.path.realpath(__file__)) diff --git a/deps/v8/tools/heap-stats/categories.js b/deps/v8/tools/heap-stats/categories.js index 6560758f3eced3..0e876624881682 100644 --- a/deps/v8/tools/heap-stats/categories.js +++ b/deps/v8/tools/heap-stats/categories.js @@ -32,7 +32,7 @@ const CATEGORIES = new Map([ 'GLOBAL_PROPERTIES_TYPE', 'HEAP_NUMBER_TYPE', 'INTERNALIZED_STRING_TYPE', - 'JS_ARGUMENTS_TYPE', + 'JS_ARGUMENTS_OBJECT_TYPE', 'JS_ARRAY_BUFFER_TYPE', 'JS_ARRAY_ITERATOR_TYPE', 'JS_ARRAY_TYPE', @@ -50,16 +50,16 @@ const CATEGORIES = new Map([ 'JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE', 'JS_GLOBAL_OBJECT_TYPE', 'JS_GLOBAL_PROXY_TYPE', - 'JS_INTL_COLLATOR_TYPE', - 'JS_INTL_DATE_TIME_FORMAT_TYPE', - 'JS_INTL_LIST_FORMAT_TYPE', - 'JS_INTL_LOCALE_TYPE', - 'JS_INTL_NUMBER_FORMAT_TYPE', - 'JS_INTL_PLURAL_RULES_TYPE', - 'JS_INTL_RELATIVE_TIME_FORMAT_TYPE', - 'JS_INTL_SEGMENT_ITERATOR_TYPE', - 'JS_INTL_SEGMENTER_TYPE', - 'JS_INTL_V8_BREAK_ITERATOR_TYPE', + 'JS_COLLATOR_TYPE', + 'JS_DATE_TIME_FORMAT_TYPE', + 'JS_LIST_FORMAT_TYPE', + 'JS_LOCALE_TYPE', + 'JS_NUMBER_FORMAT_TYPE', + 'JS_PLURAL_RULES_TYPE', + 'JS_RELATIVE_TIME_FORMAT_TYPE', + 'JS_SEGMENT_ITERATOR_TYPE', + 'JS_SEGMENTER_TYPE', + 'JS_V8_BREAK_ITERATOR_TYPE', 'JS_MAP_KEY_ITERATOR_TYPE', 'JS_MAP_KEY_VALUE_ITERATOR_TYPE', 'JS_MAP_TYPE', @@ -69,7 +69,7 @@ const CATEGORIES = new Map([ 'JS_PRIMITIVE_WRAPPER_TYPE', 'JS_PROMISE_TYPE', 'JS_PROXY_TYPE', - 'JS_REGEXP_TYPE', + 'JS_REG_EXP_TYPE', 'JS_SET_KEY_VALUE_ITERATOR_TYPE', 'JS_SET_TYPE', 'JS_SET_VALUE_ITERATOR_TYPE', @@ -96,9 +96,9 @@ const CATEGORIES = new Map([ 'UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE', 'UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE', 'UNCACHED_EXTERNAL_STRING_TYPE', - 'WASM_INSTANCE_TYPE', - 'WASM_MEMORY_TYPE', - 'WASM_MODULE_TYPE', + 'WASM_INSTANCE_OBJECT_TYPE', + 'WASM_MEMORY_OBJECT_TYPE', + 'WASM_MODULE_OBJECT_TYPE', ]) ], [ diff --git a/deps/v8/tools/ic-explorer.html b/deps/v8/tools/ic-explorer.html index aede91e0d0c1a8..4c725163c5f5a8 100644 --- a/deps/v8/tools/ic-explorer.html +++ b/deps/v8/tools/ic-explorer.html @@ -362,7 +362,7 @@ <h1> <div id="legend" style="padding-right: 200px"> <div style="float:right; border-style: solid; border-width: 1px; padding:20px"> 0 uninitialized<br> - . premonomorphic<br> + X no feedback<br> 1 monomorphic<br> ^ recompute handler<br> P polymorphic<br> diff --git a/deps/v8/tools/inspect-d8.js b/deps/v8/tools/inspect-d8.js new file mode 100644 index 00000000000000..b87a7586b2c1da --- /dev/null +++ b/deps/v8/tools/inspect-d8.js @@ -0,0 +1,30 @@ +// Copyright 2019 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This helper allows to debug d8 using Chrome DevTools. +// +// It runs a simple REPL for inspector messages and relies on +// websocketd (https://github.com/joewalnes/websocketd) for the WebSocket +// communication. +// +// You can start a session with a debug build of d8 like: +// +// $ websocketd out/x64.debug/d8 YOUR_SCRIPT.js tools/inspect-d8.js +// +// After that, copy the URL from console and pass it as `ws=` parameter to +// the Chrome DevTools frontend like: +// +// chrome-devtools://devtools/bundled/js_app.html?ws=localhost:80 + +function receive(msg) { + print(msg); +} + +function handleInspectorMessage() { + send(readline()); +} + +while (true) { + handleInspectorMessage(); +} diff --git a/deps/v8/tools/js2c.py b/deps/v8/tools/js2c.py index b94f3add23176b..43a876e236edbf 100755 --- a/deps/v8/tools/js2c.py +++ b/deps/v8/tools/js2c.py @@ -202,19 +202,11 @@ def PrepareSources(source_files, native_type, emit_js): Returns: An instance of Sources. """ + result = Sources() filters = BuildFilterChain() source_files_and_contents = [(f, ReadFile(f)) for f in source_files] - # Have a single not-quite-empty source file if there are none present; - # otherwise you get errors trying to compile an empty C++ array. - # It cannot be empty (or whitespace, which gets trimmed to empty), as - # the deserialization code assumes each file is nonempty. - if not source_files_and_contents: - source_files_and_contents = [("dummy.js", "(function() {})")] - - result = Sources() - for (source, contents) in source_files_and_contents: try: lines = filters(contents) @@ -273,7 +265,9 @@ def BuildMetadata(sources, source_bytes, native_type): metadata = { "builtin_count": len(sources.modules), - "sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes), + "sources_declaration": + SOURCES_DECLARATION % ToCArray( + source_bytes if len(source_bytes) != 0 else "\0"), "total_length": total_length, "get_index_cases": "".join(get_index_cases), "get_script_source_cases": "".join(get_script_source_cases), diff --git a/deps/v8/tools/mips_toolchain.tar.gz.sha1 b/deps/v8/tools/mips_toolchain.tar.gz.sha1 deleted file mode 100644 index 8d4572336a8cbd..00000000000000 --- a/deps/v8/tools/mips_toolchain.tar.gz.sha1 +++ /dev/null @@ -1 +0,0 @@ -d51b5d903340262d8d13ecd51054c16a901b3cf3 \ No newline at end of file diff --git a/deps/v8/tools/regexp-sequences.py b/deps/v8/tools/regexp-sequences.py new file mode 100755 index 00000000000000..56e83679a912aa --- /dev/null +++ b/deps/v8/tools/regexp-sequences.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# Copyright 2019 the V8 project authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +python %prog trace-file + +Parses output generated by v8 with flag --trace-regexp-bytecodes and generates +a list of the most common sequences. +""" + +from __future__ import print_function + +import sys +import re +import collections + +def parse(file, seqlen): + # example: + # pc = 00, sp = 0, curpos = 0, curchar = 0000000a ..., bc = PUSH_BT, 02, 00, 00, 00, e8, 00, 00, 00 ....... + rx = re.compile(r'pc = (?P<pc>[0-9a-f]+), sp = (?P<sp>\d+), ' + r'curpos = (?P<curpos>\d+), curchar = (?P<char_hex>[0-9a-f]+) ' + r'(:?\.|\()(?P<char>\.|\w)(:?\.|\)), bc = (?P<bc>\w+), .*') + total = 0 + bc_cnt = [None] * seqlen + for i in xrange(seqlen): + bc_cnt[i] = {} + last = [None] * seqlen + with open(file) as f: + l = f.readline() + while l: + l = l.strip() + if l.startswith("Start bytecode interpreter"): + for i in xrange(seqlen): + last[i] = collections.deque(maxlen=i+1) + + match = rx.search(l) + if match: + total += 1 + bc = match.group('bc') + for i in xrange(seqlen): + last[i].append(bc) + key = ' --> '.join(last[i]) + bc_cnt[i][key] = bc_cnt[i].get(key,0) + 1 + + l = f.readline() + return bc_cnt, total + +def print_most_common(d, seqlen, total): + sorted_d = sorted(d.items(), key=lambda kv: kv[1], reverse=True) + for (k,v) in sorted_d: + if v*100/total < 1.0: + return + print("{}: {} ({} %)".format(k,v,(v*100/total))) + +def main(argv): + max_seq = 7 + bc_cnt, total = parse(argv[1],max_seq) + for i in xrange(max_seq): + print() + print("Most common of length {}".format(i+1)) + print() + print_most_common(bc_cnt[i], i, total) + +if __name__ == '__main__': + main(sys.argv) diff --git a/deps/v8/tools/release/merge_to_branch.py b/deps/v8/tools/release/merge_to_branch.py index c9594292b1e76c..64f2a1981d8db1 100755 --- a/deps/v8/tools/release/merge_to_branch.py +++ b/deps/v8/tools/release/merge_to_branch.py @@ -47,7 +47,7 @@ def RunStep(self): if self._options.force: os.remove(self.Config("ALREADY_MERGING_SENTINEL_FILE")) elif self._options.step == 0: # pragma: no cover - self.Die("A merge is already in progress") + self.Die("A merge is already in progress. Use -f to continue") open(self.Config("ALREADY_MERGING_SENTINEL_FILE"), "a").close() self.InitialEnvironmentChecks(self.default_cwd) diff --git a/deps/v8/tools/testrunner/base_runner.py b/deps/v8/tools/testrunner/base_runner.py index cb23366aa4c5b5..6c2bcf8ae4c511 100644 --- a/deps/v8/tools/testrunner/base_runner.py +++ b/deps/v8/tools/testrunner/base_runner.py @@ -46,8 +46,10 @@ # Map of test name synonyms to lists of test suites. Should be ordered by # expected runtimes (suites with slow test cases first). These groups are # invoked in separate steps on the bots. +# The mapping from names used here to GN targets (which must stay in sync) +# is defined in infra/mb/gn_isolate_map.pyl. TEST_MAP = { - # This needs to stay in sync with test/bot_default.isolate. + # This needs to stay in sync with group("v8_bot_default") in test/BUILD.gn. "bot_default": [ "debugger", "mjsunit", @@ -62,8 +64,9 @@ "preparser", "intl", "unittests", + "wasm-api-tests", ], - # This needs to stay in sync with test/default.isolate. + # This needs to stay in sync with group("v8_default") in test/BUILD.gn. "default": [ "debugger", "mjsunit", @@ -77,8 +80,9 @@ "preparser", "intl", "unittests", + "wasm-api-tests", ], - # This needs to stay in sync with test/d8_default.isolate. + # This needs to stay in sync with group("v8_d8_default") in test/BUILD.gn. "d8_default": [ "debugger", "mjsunit", @@ -87,7 +91,7 @@ "preparser", "intl", ], - # This needs to stay in sync with test/optimize_for_size.isolate. + # This needs to stay in sync with "v8_optimize_for_size" in test/BUILD.gn. "optimize_for_size": [ "debugger", "mjsunit", @@ -190,7 +194,9 @@ def __init__(self, build_config): self.is_full_debug = build_config['is_full_debug'] self.msan = build_config['is_msan'] self.no_i18n = not build_config['v8_enable_i18n_support'] - self.no_snap = not build_config['v8_use_snapshot'] + # TODO(https://crbug.com/v8/8531) + # 'v8_use_snapshot' was removed, 'no_snap' can be removed as well. + self.no_snap = False self.predictable = build_config['v8_enable_verify_predictable'] self.tsan = build_config['is_tsan'] # TODO(machenbach): We only have ubsan not ubsan_vptr. @@ -315,13 +321,11 @@ def _add_parser_default_options(self, parser): default=False, action="store_true") parser.add_option("--outdir", help="Base directory with compile output", default="out") - parser.add_option("--buildbot", help="DEPRECATED!", - default=False, action="store_true") parser.add_option("--arch", help="The architecture to run tests for") parser.add_option("-m", "--mode", - help="The test mode in which to run (uppercase for ninja" - " and buildbot builds): %s" % MODES.keys()) + help="The test mode in which to run (uppercase for builds" + " in CI): %s" % MODES.keys()) parser.add_option("--shell-dir", help="DEPRECATED! Executables from build " "directory will be used") parser.add_option("--test-root", help="Root directory of the test suites", @@ -436,7 +440,7 @@ def _load_build_config(self, options): # gn # outdir # outdir/arch.mode - # Each path is provided in two versions: <path> and <path>/mode for buildbot. + # Each path is provided in two versions: <path> and <path>/mode for bots. def _possible_outdirs(self, options): def outdirs(): if options.gn: @@ -451,7 +455,7 @@ def outdirs(): for outdir in outdirs(): yield os.path.join(self.basedir, outdir) - # buildbot option + # bot option if options.mode: yield os.path.join(self.basedir, outdir, options.mode) @@ -493,9 +497,9 @@ def _do_load_build_config(self, outdir, verbose=False): def _process_default_options(self, options): # We don't use the mode for more path-magic. - # Therefore transform the buildbot mode here to fix build_config value. + # Therefore transform the bot mode here to fix build_config value. if options.mode: - options.mode = self._buildbot_to_v8_mode(options.mode) + options.mode = self._bot_to_v8_mode(options.mode) build_config_mode = 'debug' if self.build_config.is_debug else 'release' if options.mode: @@ -535,8 +539,8 @@ def _process_default_options(self, options): options.command_prefix = shlex.split(options.command_prefix) options.extra_flags = sum(map(shlex.split, options.extra_flags), []) - def _buildbot_to_v8_mode(self, config): - """Convert buildbot build configs to configs understood by the v8 runner. + def _bot_to_v8_mode(self, config): + """Convert build configs from bots to configs understood by the v8 runner. V8 configs are always lower case and without the additional _x64 suffix for 64 bit builds on windows with ninja. diff --git a/deps/v8/tools/testrunner/local/statusfile.py b/deps/v8/tools/testrunner/local/statusfile.py index e4778326a90962..db07a628858857 100644 --- a/deps/v8/tools/testrunner/local/statusfile.py +++ b/deps/v8/tools/testrunner/local/statusfile.py @@ -300,6 +300,8 @@ def _ReadSection(section, variables, rules, prefix_rules): 'webkit': [[]], } +FILE_EXTENSIONS = [".js", ".mjs"] + def PresubmitCheck(path): with open(path) as f: contents = ReadContent(f.read()) @@ -326,8 +328,11 @@ def _assert(check, message): # Like "assert", but doesn't throw. _assert('*' not in rule or (rule.count('*') == 1 and rule[-1] == '*'), "Only the last character of a rule key can be a wildcard") if basename in JS_TEST_PATHS and '*' not in rule: - _assert(any(os.path.exists(os.path.join(os.path.dirname(path), - *(paths + [rule + ".js"]))) + def _any_exist(paths): + return any(os.path.exists(os.path.join(os.path.dirname(path), + *(paths + [rule + ext]))) + for ext in FILE_EXTENSIONS) + _assert(any(_any_exist(paths) for paths in JS_TEST_PATHS[basename]), "missing file for %s test %s" % (basename, rule)) return status["success"] diff --git a/deps/v8/tools/testrunner/local/variants.py b/deps/v8/tools/testrunner/local/variants.py index fe63d0b93549ea..57c16c0af15971 100644 --- a/deps/v8/tools/testrunner/local/variants.py +++ b/deps/v8/tools/testrunner/local/variants.py @@ -32,6 +32,8 @@ "stress_sampling": [["--stress-sampling-allocation-profiler=16384"]], "trusted": [["--no-untrusted-code-mitigations"]], "no_wasm_traps": [["--no-wasm-trap-handler"]], + "turboprop": [["--turboprop"]], + "top_level_await": [["--harmony-top-level-await"]], } SLOW_VARIANTS = set([ diff --git a/deps/v8/tools/testrunner/standard_runner.py b/deps/v8/tools/testrunner/standard_runner.py index 51e78608cb554f..4d9c73f2fc06e0 100755 --- a/deps/v8/tools/testrunner/standard_runner.py +++ b/deps/v8/tools/testrunner/standard_runner.py @@ -8,8 +8,11 @@ from __future__ import print_function from functools import reduce +import datetime +import json import os import sys +import tempfile # Adds testrunner to the path hence it has to be imported at the beggining. import base_runner @@ -43,7 +46,7 @@ # Shortcut for the two above ('more' first - it has the longer running tests) 'exhaustive': MORE_VARIANTS + VARIANTS, # Additional variants, run on a subset of bots. - 'extra': ['nooptimization', 'future', 'no_wasm_traps'], + 'extra': ['nooptimization', 'future', 'no_wasm_traps', 'turboprop'], } GC_STRESS_FLAGS = ['--gc-interval=500', '--stress-compaction', @@ -120,6 +123,10 @@ def _add_parser_options(self, parser): 'with test processors: 0 means infinite ' 'generation.') + # Extra features. + parser.add_option('--time', help='Print timing information after running', + default=False, action='store_true') + # Noop parser.add_option('--cfi-vptr', help='Run tests with UBSAN cfi_vptr option.', @@ -146,8 +153,6 @@ def _add_parser_options(self, parser): default=False, action='store_true') parser.add_option('--flakiness-results', help='Path to a file for storing flakiness json.') - parser.add_option('--time', help='Print timing information after running', - default=False, action='store_true') parser.add_option('--warn-unused', help='Report unused rules', default=False, action='store_true') parser.add_option('--report', default=False, action='store_true', @@ -168,7 +173,6 @@ def _process_options(self, options): if self.build_config.asan: options.extra_flags.append('--invoke-weak-callbacks') - options.extra_flags.append('--omit-quit') if self.build_config.no_snap: # Speed up slow nosnap runs. Allocation verification is covered by @@ -231,6 +235,14 @@ def CheckTestMode(name, option): # pragma: no cover # TODO(machenbach): uncomment after infra side lands. # base_runner.TEST_MAP['d8_default'].remove('intl') + if options.time and not options.json_test_results: + # We retrieve the slowest tests from the JSON output file, so create + # a temporary output file (which will automatically get deleted on exit) + # if the user didn't specify one. + self._temporary_json_output_file = tempfile.NamedTemporaryFile( + prefix="v8-test-runner-") + options.json_test_results = self._temporary_json_output_file.name + def _parse_variants(self, aliases_str): # Use developer defaults if no variant was specified. aliases_str = aliases_str or 'dev' @@ -341,9 +353,47 @@ def _do_execute(self, tests, args, options): if not results.total: exit_code = utils.EXIT_CODE_NO_TESTS + if options.time: + self._print_durations(options) + # Indicate if a SIGINT or SIGTERM happened. return max(exit_code, sigproc.exit_code) + def _print_durations(self, options): + + def format_duration(duration_in_seconds): + duration = datetime.timedelta(seconds=duration_in_seconds) + time = (datetime.datetime.min + duration).time() + return time.strftime('%M:%S:') + '%03i' % int(time.microsecond / 1000) + + def _duration_results_text(test): + return [ + 'Test: %s' % test['name'], + 'Flags: %s' % ' '.join(test['flags']), + 'Command: %s' % test['command'], + 'Duration: %s' % format_duration(test['duration']), + ] + + assert os.path.exists(options.json_test_results) + complete_results = [] + with open(options.json_test_results, "r") as f: + complete_results = json.loads(f.read()) + output = complete_results[0] + lines = [] + for test in output['slowest_tests']: + suffix = '' + if test.get('marked_slow') is False: + suffix = ' *' + lines.append( + '%s %s%s' % (format_duration(test['duration']), + test['name'], suffix)) + + # Slowest tests duration details. + lines.extend(['', 'Details:', '']) + for test in output['slowest_tests']: + lines.extend(_duration_results_text(test)) + print("\n".join(lines)) + def _create_predictable_filter(self): if not self.build_config.predictable: return None diff --git a/deps/v8/tools/testrunner/testproc/progress.py b/deps/v8/tools/testrunner/testproc/progress.py index 6957cdc423f322..3bb9744f1e4f0d 100644 --- a/deps/v8/tools/testrunner/testproc/progress.py +++ b/deps/v8/tools/testrunner/testproc/progress.py @@ -5,6 +5,7 @@ # for py2/py3 compatibility from __future__ import print_function +import datetime import json import os import platform @@ -152,8 +153,11 @@ def _print_processes_linux(self): except: pass + def _ensure_delay(self, delay): + return time.time() - self._last_printed_time > delay + def _on_heartbeat(self): - if time.time() - self._last_printed_time > 30: + if self._ensure_delay(30): # Print something every 30 seconds to not get killed by an output # timeout. self._print('Still working...') @@ -170,6 +174,16 @@ def _on_result_for(self, test, result): if self.options.ci_test_completion: with open(self.options.ci_test_completion, "a") as f: f.write(self._message(test, result) + "\n") + self._output_feedback() + + def _output_feedback(self): + """Reduced the verbosity leads to getting killed by an ouput timeout. + We ensure output every minute. + """ + if self._ensure_delay(60): + dt = time.time() + st = datetime.datetime.fromtimestamp(dt).strftime('%Y-%m-%d %H:%M:%S') + self._print(st) class DotsProgressIndicator(SimpleProgressIndicator): @@ -400,7 +414,7 @@ def finished(self): complete_results = [] if os.path.exists(self.json_test_results): with open(self.json_test_results, "r") as f: - # Buildbot might start out with an empty file. + # On bots we might start out with an empty file. complete_results = json.loads(f.read() or "[]") duration_mean = None diff --git a/deps/v8/tools/torque/format-torque.py b/deps/v8/tools/torque/format-torque.py index 2e04e659c1305e..3b90faa73ce392 100755 --- a/deps/v8/tools/torque/format-torque.py +++ b/deps/v8/tools/torque/format-torque.py @@ -33,7 +33,7 @@ def preprocess(input): break; input = re.sub(r'\bgenerates\s+\'([^\']+)\'\s*', - r' _GeNeRaTeS00_/*\1@*/', input) + r'_GeNeRaTeS00_/*\1@*/', input) input = re.sub(r'\bconstexpr\s+\'([^\']+)\'\s*', r' _CoNsExP_/*\1@*/', input) input = re.sub(r'\notherwise', diff --git a/deps/v8/tools/ubsan/blacklist.txt b/deps/v8/tools/ubsan/blacklist.txt index 0705adc0b4eaa3..ea4e79bf522a88 100644 --- a/deps/v8/tools/ubsan/blacklist.txt +++ b/deps/v8/tools/ubsan/blacklist.txt @@ -9,3 +9,9 @@ fun:*v8*internal*InvokeAccessorGetterCallback* # Bug 8735: WeakCallbackInfo<void> vs. WeakCallbackInfo<T>. fun:*v8*internal*GlobalHandles*PendingPhantomCallback*Invoke* fun:*v8*internal*GlobalHandles*Node*PostGarbageCollectionProcessing* + +# Simulators casting C++ functions to a generic signature. +fun:*v8*internal*UnsafeDirectApiCall* +fun:*v8*internal*UnsafeDirectGetterCall* +fun:*v8*internal*UnsafeGenericFunctionCall* +fun:*v8*internal*UnsafeProfilingApiCall* diff --git a/deps/v8/tools/unittests/run_tests_test.py b/deps/v8/tools/unittests/run_tests_test.py index 93b10f5fd93971..a40bb6756defae 100755 --- a/deps/v8/tools/unittests/run_tests_test.py +++ b/deps/v8/tools/unittests/run_tests_test.py @@ -338,7 +338,7 @@ def testAutoDetect(self): basedir, dcheck_always_on=True, is_asan=True, is_cfi=True, is_msan=True, is_tsan=True, is_ubsan_vptr=True, target_cpu='x86', v8_enable_i18n_support=False, v8_target_cpu='x86', - v8_use_snapshot=False, v8_enable_embedded_builtins=False, + v8_enable_embedded_builtins=False, v8_enable_verify_csa=False, v8_enable_lite_mode=False, v8_enable_pointer_compression=False) result = run_tests( @@ -355,7 +355,6 @@ def testAutoDetect(self): 'dcheck_always_on\n' 'msan\n' 'no_i18n\n' - 'no_snap\n' 'tsan\n' 'ubsan_vptr\n' '>>> Running tests for ia32.release') @@ -572,7 +571,7 @@ def testSpecificVariants(self): variants. """ with temp_base() as basedir: - override_build_config(basedir, v8_use_snapshot=False) + override_build_config(basedir, is_asan=True) result = run_tests( basedir, '--mode=Release', diff --git a/deps/v8/tools/unittests/testdata/testroot1/test/sweet/sweet.status b/deps/v8/tools/unittests/testdata/testroot1/test/sweet/sweet.status index d823cfd231bc08..a0bd5177398fcc 100644 --- a/deps/v8/tools/unittests/testdata/testroot1/test/sweet/sweet.status +++ b/deps/v8/tools/unittests/testdata/testroot1/test/sweet/sweet.status @@ -29,7 +29,7 @@ 'regress/*': [CRASH], }], -['no_snap', { +['asan', { 'bananas': [PASS, NO_VARIANTS], 'raspberries': [FAIL, NO_VARIANTS], }], diff --git a/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json b/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json index 0192fd8ee3894b..0d2148bc21de12 100644 --- a/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json +++ b/deps/v8/tools/unittests/testdata/testroot1/v8_build_config.json @@ -17,7 +17,6 @@ "v8_enable_i18n_support": true, "v8_enable_verify_predictable": false, "v8_target_cpu": "x64", - "v8_use_snapshot": true, "v8_enable_embedded_builtins": false, "v8_enable_verify_csa": false, "v8_enable_lite_mode": false, diff --git a/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json b/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json index f19c310bf8420d..8066096781a643 100644 --- a/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json +++ b/deps/v8/tools/unittests/testdata/testroot2/v8_build_config.json @@ -17,7 +17,6 @@ "v8_enable_i18n_support": true, "v8_enable_verify_predictable": false, "v8_target_cpu": "x64", - "v8_use_snapshot": true, "v8_enable_embedded_builtins": false, "v8_enable_verify_csa": false, "v8_enable_lite_mode": false, diff --git a/deps/v8/tools/v8heapconst.py b/deps/v8/tools/v8heapconst.py index 53aaaf74dfbba8..102f5a075364df 100644 --- a/deps/v8/tools/v8heapconst.py +++ b/deps/v8/tools/v8heapconst.py @@ -26,401 +26,402 @@ 50: "UNCACHED_EXTERNAL_STRING_TYPE", 58: "UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE", 64: "SYMBOL_TYPE", - 65: "HEAP_NUMBER_TYPE", - 66: "BIGINT_TYPE", + 65: "BIG_INT_BASE_TYPE", + 66: "HEAP_NUMBER_TYPE", 67: "ODDBALL_TYPE", - 68: "MAP_TYPE", - 69: "CODE_TYPE", + 68: "SOURCE_TEXT_MODULE_TYPE", + 69: "SYNTHETIC_MODULE_TYPE", 70: "FOREIGN_TYPE", - 71: "BYTE_ARRAY_TYPE", - 72: "BYTECODE_ARRAY_TYPE", - 73: "FREE_SPACE_TYPE", - 74: "FIXED_DOUBLE_ARRAY_TYPE", - 75: "FEEDBACK_METADATA_TYPE", - 76: "FILLER_TYPE", - 77: "ACCESS_CHECK_INFO_TYPE", - 78: "ACCESSOR_INFO_TYPE", - 79: "ACCESSOR_PAIR_TYPE", - 80: "ALIASED_ARGUMENTS_ENTRY_TYPE", - 81: "ALLOCATION_MEMENTO_TYPE", - 82: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE", - 83: "ASM_WASM_DATA_TYPE", - 84: "ASYNC_GENERATOR_REQUEST_TYPE", - 85: "CLASS_POSITIONS_TYPE", - 86: "DEBUG_INFO_TYPE", - 87: "ENUM_CACHE_TYPE", - 88: "FUNCTION_TEMPLATE_INFO_TYPE", - 89: "FUNCTION_TEMPLATE_RARE_DATA_TYPE", - 90: "INTERCEPTOR_INFO_TYPE", - 91: "INTERPRETER_DATA_TYPE", - 92: "OBJECT_TEMPLATE_INFO_TYPE", - 93: "PROMISE_CAPABILITY_TYPE", - 94: "PROMISE_REACTION_TYPE", - 95: "PROTOTYPE_INFO_TYPE", - 96: "SCRIPT_TYPE", - 97: "SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE", - 98: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE", - 99: "STACK_FRAME_INFO_TYPE", - 100: "STACK_TRACE_FRAME_TYPE", - 101: "TEMPLATE_OBJECT_DESCRIPTION_TYPE", - 102: "TUPLE2_TYPE", - 103: "TUPLE3_TYPE", - 104: "WASM_CAPI_FUNCTION_DATA_TYPE", - 105: "WASM_DEBUG_INFO_TYPE", - 106: "WASM_EXCEPTION_TAG_TYPE", - 107: "WASM_EXPORTED_FUNCTION_DATA_TYPE", - 108: "WASM_INDIRECT_FUNCTION_TABLE_TYPE", - 109: "WASM_JS_FUNCTION_DATA_TYPE", - 110: "CALLABLE_TASK_TYPE", - 111: "CALLBACK_TASK_TYPE", - 112: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE", - 113: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE", - 114: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE", - 115: "INTERNAL_CLASS_TYPE", - 116: "SMI_PAIR_TYPE", - 117: "SMI_BOX_TYPE", - 118: "SORT_STATE_TYPE", - 119: "SOURCE_TEXT_MODULE_TYPE", - 120: "SYNTHETIC_MODULE_TYPE", - 121: "ALLOCATION_SITE_TYPE", - 122: "EMBEDDER_DATA_ARRAY_TYPE", - 123: "FIXED_ARRAY_TYPE", - 124: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", - 125: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", - 126: "HASH_TABLE_TYPE", - 127: "ORDERED_HASH_MAP_TYPE", - 128: "ORDERED_HASH_SET_TYPE", - 129: "ORDERED_NAME_DICTIONARY_TYPE", - 130: "NAME_DICTIONARY_TYPE", - 131: "GLOBAL_DICTIONARY_TYPE", - 132: "NUMBER_DICTIONARY_TYPE", - 133: "SIMPLE_NUMBER_DICTIONARY_TYPE", - 134: "STRING_TABLE_TYPE", - 135: "EPHEMERON_HASH_TABLE_TYPE", - 136: "SCOPE_INFO_TYPE", - 137: "SCRIPT_CONTEXT_TABLE_TYPE", - 138: "AWAIT_CONTEXT_TYPE", - 139: "BLOCK_CONTEXT_TYPE", - 140: "CATCH_CONTEXT_TYPE", - 141: "DEBUG_EVALUATE_CONTEXT_TYPE", - 142: "EVAL_CONTEXT_TYPE", - 143: "FUNCTION_CONTEXT_TYPE", - 144: "MODULE_CONTEXT_TYPE", - 145: "NATIVE_CONTEXT_TYPE", - 146: "SCRIPT_CONTEXT_TYPE", - 147: "WITH_CONTEXT_TYPE", - 148: "WEAK_FIXED_ARRAY_TYPE", - 149: "TRANSITION_ARRAY_TYPE", - 150: "CALL_HANDLER_INFO_TYPE", - 151: "CELL_TYPE", - 152: "CODE_DATA_CONTAINER_TYPE", - 153: "DESCRIPTOR_ARRAY_TYPE", - 154: "FEEDBACK_CELL_TYPE", - 155: "FEEDBACK_VECTOR_TYPE", - 156: "LOAD_HANDLER_TYPE", - 157: "PREPARSE_DATA_TYPE", - 158: "PROPERTY_ARRAY_TYPE", - 159: "PROPERTY_CELL_TYPE", - 160: "SHARED_FUNCTION_INFO_TYPE", - 161: "SMALL_ORDERED_HASH_MAP_TYPE", - 162: "SMALL_ORDERED_HASH_SET_TYPE", - 163: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", - 164: "STORE_HANDLER_TYPE", - 165: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", - 166: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", + 71: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE", + 72: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE", + 73: "CALLABLE_TASK_TYPE", + 74: "CALLBACK_TASK_TYPE", + 75: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE", + 76: "LOAD_HANDLER_TYPE", + 77: "STORE_HANDLER_TYPE", + 78: "FUNCTION_TEMPLATE_INFO_TYPE", + 79: "OBJECT_TEMPLATE_INFO_TYPE", + 80: "TUPLE2_TYPE", + 81: "TUPLE3_TYPE", + 82: "ACCESS_CHECK_INFO_TYPE", + 83: "ACCESSOR_INFO_TYPE", + 84: "ACCESSOR_PAIR_TYPE", + 85: "ALIASED_ARGUMENTS_ENTRY_TYPE", + 86: "ALLOCATION_MEMENTO_TYPE", + 87: "ALLOCATION_SITE_TYPE", + 88: "ARRAY_BOILERPLATE_DESCRIPTION_TYPE", + 89: "ASM_WASM_DATA_TYPE", + 90: "ASYNC_GENERATOR_REQUEST_TYPE", + 91: "CALL_HANDLER_INFO_TYPE", + 92: "CLASS_POSITIONS_TYPE", + 93: "DEBUG_INFO_TYPE", + 94: "ENUM_CACHE_TYPE", + 95: "FEEDBACK_CELL_TYPE", + 96: "FUNCTION_TEMPLATE_RARE_DATA_TYPE", + 97: "INTERCEPTOR_INFO_TYPE", + 98: "INTERNAL_CLASS_TYPE", + 99: "INTERPRETER_DATA_TYPE", + 100: "PROMISE_CAPABILITY_TYPE", + 101: "PROMISE_REACTION_TYPE", + 102: "PROTOTYPE_INFO_TYPE", + 103: "SCRIPT_TYPE", + 104: "SMI_BOX_TYPE", + 105: "SMI_PAIR_TYPE", + 106: "SORT_STATE_TYPE", + 107: "SOURCE_POSITION_TABLE_WITH_FRAME_CACHE_TYPE", + 108: "SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE", + 109: "STACK_FRAME_INFO_TYPE", + 110: "STACK_TRACE_FRAME_TYPE", + 111: "TEMPLATE_OBJECT_DESCRIPTION_TYPE", + 112: "WASM_CAPI_FUNCTION_DATA_TYPE", + 113: "WASM_DEBUG_INFO_TYPE", + 114: "WASM_EXCEPTION_TAG_TYPE", + 115: "WASM_EXPORTED_FUNCTION_DATA_TYPE", + 116: "WASM_INDIRECT_FUNCTION_TABLE_TYPE", + 117: "WASM_JS_FUNCTION_DATA_TYPE", + 118: "FIXED_ARRAY_TYPE", + 119: "HASH_TABLE_TYPE", + 120: "EPHEMERON_HASH_TABLE_TYPE", + 121: "GLOBAL_DICTIONARY_TYPE", + 122: "NAME_DICTIONARY_TYPE", + 123: "NUMBER_DICTIONARY_TYPE", + 124: "ORDERED_HASH_MAP_TYPE", + 125: "ORDERED_HASH_SET_TYPE", + 126: "ORDERED_NAME_DICTIONARY_TYPE", + 127: "SIMPLE_NUMBER_DICTIONARY_TYPE", + 128: "STRING_TABLE_TYPE", + 129: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE", + 130: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE", + 131: "SCOPE_INFO_TYPE", + 132: "SCRIPT_CONTEXT_TABLE_TYPE", + 133: "BYTE_ARRAY_TYPE", + 134: "BYTECODE_ARRAY_TYPE", + 135: "FIXED_DOUBLE_ARRAY_TYPE", + 136: "AWAIT_CONTEXT_TYPE", + 137: "BLOCK_CONTEXT_TYPE", + 138: "CATCH_CONTEXT_TYPE", + 139: "DEBUG_EVALUATE_CONTEXT_TYPE", + 140: "EVAL_CONTEXT_TYPE", + 141: "FUNCTION_CONTEXT_TYPE", + 142: "MODULE_CONTEXT_TYPE", + 143: "NATIVE_CONTEXT_TYPE", + 144: "SCRIPT_CONTEXT_TYPE", + 145: "WITH_CONTEXT_TYPE", + 146: "SMALL_ORDERED_HASH_MAP_TYPE", + 147: "SMALL_ORDERED_HASH_SET_TYPE", + 148: "SMALL_ORDERED_NAME_DICTIONARY_TYPE", + 149: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE", + 150: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE", + 151: "WEAK_FIXED_ARRAY_TYPE", + 152: "TRANSITION_ARRAY_TYPE", + 153: "CELL_TYPE", + 154: "CODE_TYPE", + 155: "CODE_DATA_CONTAINER_TYPE", + 156: "DESCRIPTOR_ARRAY_TYPE", + 157: "EMBEDDER_DATA_ARRAY_TYPE", + 158: "FEEDBACK_METADATA_TYPE", + 159: "FEEDBACK_VECTOR_TYPE", + 160: "FILLER_TYPE", + 161: "FREE_SPACE_TYPE", + 162: "MAP_TYPE", + 163: "PREPARSE_DATA_TYPE", + 164: "PROPERTY_ARRAY_TYPE", + 165: "PROPERTY_CELL_TYPE", + 166: "SHARED_FUNCTION_INFO_TYPE", 167: "WEAK_ARRAY_LIST_TYPE", 168: "WEAK_CELL_TYPE", - 1024: "JS_PROXY_TYPE", - 1025: "JS_GLOBAL_OBJECT_TYPE", - 1026: "JS_GLOBAL_PROXY_TYPE", - 1027: "JS_MODULE_NAMESPACE_TYPE", + 169: "JS_PROXY_TYPE", + 1057: "JS_OBJECT_TYPE", + 170: "JS_GLOBAL_OBJECT_TYPE", + 171: "JS_GLOBAL_PROXY_TYPE", + 172: "JS_MODULE_NAMESPACE_TYPE", 1040: "JS_SPECIAL_API_OBJECT_TYPE", 1041: "JS_PRIMITIVE_WRAPPER_TYPE", + 1042: "JS_MAP_KEY_ITERATOR_TYPE", + 1043: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", + 1044: "JS_MAP_VALUE_ITERATOR_TYPE", + 1045: "JS_SET_KEY_VALUE_ITERATOR_TYPE", + 1046: "JS_SET_VALUE_ITERATOR_TYPE", + 1047: "JS_GENERATOR_OBJECT_TYPE", + 1048: "JS_ASYNC_FUNCTION_OBJECT_TYPE", + 1049: "JS_ASYNC_GENERATOR_OBJECT_TYPE", + 1050: "JS_DATA_VIEW_TYPE", + 1051: "JS_TYPED_ARRAY_TYPE", + 1052: "JS_MAP_TYPE", + 1053: "JS_SET_TYPE", + 1054: "JS_WEAK_MAP_TYPE", + 1055: "JS_WEAK_SET_TYPE", 1056: "JS_API_OBJECT_TYPE", - 1057: "JS_OBJECT_TYPE", - 1058: "JS_ARGUMENTS_TYPE", - 1059: "JS_ARRAY_BUFFER_TYPE", - 1060: "JS_ARRAY_ITERATOR_TYPE", - 1061: "JS_ARRAY_TYPE", + 1058: "JS_ARGUMENTS_OBJECT_TYPE", + 1059: "JS_ARRAY_TYPE", + 1060: "JS_ARRAY_BUFFER_TYPE", + 1061: "JS_ARRAY_ITERATOR_TYPE", 1062: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE", - 1063: "JS_ASYNC_FUNCTION_OBJECT_TYPE", - 1064: "JS_ASYNC_GENERATOR_OBJECT_TYPE", - 1065: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", - 1066: "JS_DATE_TYPE", + 1063: "JS_COLLATOR_TYPE", + 1064: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", + 1065: "JS_DATE_TYPE", + 1066: "JS_DATE_TIME_FORMAT_TYPE", 1067: "JS_ERROR_TYPE", - 1068: "JS_GENERATOR_OBJECT_TYPE", - 1069: "JS_MAP_TYPE", - 1070: "JS_MAP_KEY_ITERATOR_TYPE", - 1071: "JS_MAP_KEY_VALUE_ITERATOR_TYPE", - 1072: "JS_MAP_VALUE_ITERATOR_TYPE", - 1073: "JS_MESSAGE_OBJECT_TYPE", - 1074: "JS_PROMISE_TYPE", - 1075: "JS_REGEXP_TYPE", - 1076: "JS_REGEXP_STRING_ITERATOR_TYPE", - 1077: "JS_SET_TYPE", - 1078: "JS_SET_KEY_VALUE_ITERATOR_TYPE", - 1079: "JS_SET_VALUE_ITERATOR_TYPE", - 1080: "JS_STRING_ITERATOR_TYPE", - 1081: "JS_WEAK_REF_TYPE", - 1082: "JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE", - 1083: "JS_FINALIZATION_GROUP_TYPE", - 1084: "JS_WEAK_MAP_TYPE", - 1085: "JS_WEAK_SET_TYPE", - 1086: "JS_TYPED_ARRAY_TYPE", - 1087: "JS_DATA_VIEW_TYPE", - 1088: "JS_INTL_V8_BREAK_ITERATOR_TYPE", - 1089: "JS_INTL_COLLATOR_TYPE", - 1090: "JS_INTL_DATE_TIME_FORMAT_TYPE", - 1091: "JS_INTL_LIST_FORMAT_TYPE", - 1092: "JS_INTL_LOCALE_TYPE", - 1093: "JS_INTL_NUMBER_FORMAT_TYPE", - 1094: "JS_INTL_PLURAL_RULES_TYPE", - 1095: "JS_INTL_RELATIVE_TIME_FORMAT_TYPE", - 1096: "JS_INTL_SEGMENT_ITERATOR_TYPE", - 1097: "JS_INTL_SEGMENTER_TYPE", - 1098: "WASM_EXCEPTION_TYPE", - 1099: "WASM_GLOBAL_TYPE", - 1100: "WASM_INSTANCE_TYPE", - 1101: "WASM_MEMORY_TYPE", - 1102: "WASM_MODULE_TYPE", - 1103: "WASM_TABLE_TYPE", - 1104: "JS_BOUND_FUNCTION_TYPE", - 1105: "JS_FUNCTION_TYPE", + 1068: "JS_FINALIZATION_GROUP_TYPE", + 1069: "JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE", + 1070: "JS_LIST_FORMAT_TYPE", + 1071: "JS_LOCALE_TYPE", + 1072: "JS_MESSAGE_OBJECT_TYPE", + 1073: "JS_NUMBER_FORMAT_TYPE", + 1074: "JS_PLURAL_RULES_TYPE", + 1075: "JS_PROMISE_TYPE", + 1076: "JS_REG_EXP_TYPE", + 1077: "JS_REG_EXP_STRING_ITERATOR_TYPE", + 1078: "JS_RELATIVE_TIME_FORMAT_TYPE", + 1079: "JS_SEGMENT_ITERATOR_TYPE", + 1080: "JS_SEGMENTER_TYPE", + 1081: "JS_STRING_ITERATOR_TYPE", + 1082: "JS_V8_BREAK_ITERATOR_TYPE", + 1083: "JS_WEAK_REF_TYPE", + 1084: "WASM_EXCEPTION_OBJECT_TYPE", + 1085: "WASM_GLOBAL_OBJECT_TYPE", + 1086: "WASM_INSTANCE_OBJECT_TYPE", + 1087: "WASM_MEMORY_OBJECT_TYPE", + 1088: "WASM_MODULE_OBJECT_TYPE", + 1089: "WASM_TABLE_OBJECT_TYPE", + 1090: "JS_BOUND_FUNCTION_TYPE", + 1091: "JS_FUNCTION_TYPE", } # List of known V8 maps. KNOWN_MAPS = { - ("read_only_space", 0x00119): (73, "FreeSpaceMap"), - ("read_only_space", 0x00169): (68, "MetaMap"), - ("read_only_space", 0x001e9): (67, "NullMap"), - ("read_only_space", 0x00251): (153, "DescriptorArrayMap"), - ("read_only_space", 0x002b1): (148, "WeakFixedArrayMap"), - ("read_only_space", 0x00301): (76, "OnePointerFillerMap"), - ("read_only_space", 0x00351): (76, "TwoPointerFillerMap"), - ("read_only_space", 0x003d1): (67, "UninitializedMap"), - ("read_only_space", 0x00441): (8, "OneByteInternalizedStringMap"), - ("read_only_space", 0x004e1): (67, "UndefinedMap"), - ("read_only_space", 0x00541): (65, "HeapNumberMap"), - ("read_only_space", 0x005c1): (67, "TheHoleMap"), - ("read_only_space", 0x00669): (67, "BooleanMap"), - ("read_only_space", 0x00741): (71, "ByteArrayMap"), - ("read_only_space", 0x00791): (123, "FixedArrayMap"), - ("read_only_space", 0x007e1): (123, "FixedCOWArrayMap"), - ("read_only_space", 0x00831): (126, "HashTableMap"), - ("read_only_space", 0x00881): (64, "SymbolMap"), - ("read_only_space", 0x008d1): (40, "OneByteStringMap"), - ("read_only_space", 0x00921): (136, "ScopeInfoMap"), - ("read_only_space", 0x00971): (160, "SharedFunctionInfoMap"), - ("read_only_space", 0x009c1): (69, "CodeMap"), - ("read_only_space", 0x00a11): (143, "FunctionContextMap"), - ("read_only_space", 0x00a61): (151, "CellMap"), - ("read_only_space", 0x00ab1): (159, "GlobalPropertyCellMap"), - ("read_only_space", 0x00b01): (70, "ForeignMap"), - ("read_only_space", 0x00b51): (149, "TransitionArrayMap"), - ("read_only_space", 0x00ba1): (155, "FeedbackVectorMap"), - ("read_only_space", 0x00c41): (67, "ArgumentsMarkerMap"), - ("read_only_space", 0x00ce1): (67, "ExceptionMap"), - ("read_only_space", 0x00d81): (67, "TerminationExceptionMap"), - ("read_only_space", 0x00e29): (67, "OptimizedOutMap"), - ("read_only_space", 0x00ec9): (67, "StaleRegisterMap"), - ("read_only_space", 0x00f39): (145, "NativeContextMap"), - ("read_only_space", 0x00f89): (144, "ModuleContextMap"), - ("read_only_space", 0x00fd9): (142, "EvalContextMap"), - ("read_only_space", 0x01029): (146, "ScriptContextMap"), - ("read_only_space", 0x01079): (138, "AwaitContextMap"), - ("read_only_space", 0x010c9): (139, "BlockContextMap"), - ("read_only_space", 0x01119): (140, "CatchContextMap"), - ("read_only_space", 0x01169): (147, "WithContextMap"), - ("read_only_space", 0x011b9): (141, "DebugEvaluateContextMap"), - ("read_only_space", 0x01209): (137, "ScriptContextTableMap"), - ("read_only_space", 0x01259): (125, "ClosureFeedbackCellArrayMap"), - ("read_only_space", 0x012a9): (75, "FeedbackMetadataArrayMap"), - ("read_only_space", 0x012f9): (123, "ArrayListMap"), - ("read_only_space", 0x01349): (66, "BigIntMap"), - ("read_only_space", 0x01399): (124, "ObjectBoilerplateDescriptionMap"), - ("read_only_space", 0x013e9): (72, "BytecodeArrayMap"), - ("read_only_space", 0x01439): (152, "CodeDataContainerMap"), - ("read_only_space", 0x01489): (74, "FixedDoubleArrayMap"), - ("read_only_space", 0x014d9): (131, "GlobalDictionaryMap"), - ("read_only_space", 0x01529): (154, "ManyClosuresCellMap"), - ("read_only_space", 0x01579): (123, "ModuleInfoMap"), - ("read_only_space", 0x015c9): (130, "NameDictionaryMap"), - ("read_only_space", 0x01619): (154, "NoClosuresCellMap"), - ("read_only_space", 0x01669): (132, "NumberDictionaryMap"), - ("read_only_space", 0x016b9): (154, "OneClosureCellMap"), - ("read_only_space", 0x01709): (127, "OrderedHashMapMap"), - ("read_only_space", 0x01759): (128, "OrderedHashSetMap"), - ("read_only_space", 0x017a9): (129, "OrderedNameDictionaryMap"), - ("read_only_space", 0x017f9): (157, "PreparseDataMap"), - ("read_only_space", 0x01849): (158, "PropertyArrayMap"), - ("read_only_space", 0x01899): (150, "SideEffectCallHandlerInfoMap"), - ("read_only_space", 0x018e9): (150, "SideEffectFreeCallHandlerInfoMap"), - ("read_only_space", 0x01939): (150, "NextCallSideEffectFreeCallHandlerInfoMap"), - ("read_only_space", 0x01989): (133, "SimpleNumberDictionaryMap"), - ("read_only_space", 0x019d9): (123, "SloppyArgumentsElementsMap"), - ("read_only_space", 0x01a29): (161, "SmallOrderedHashMapMap"), - ("read_only_space", 0x01a79): (162, "SmallOrderedHashSetMap"), - ("read_only_space", 0x01ac9): (163, "SmallOrderedNameDictionaryMap"), - ("read_only_space", 0x01b19): (119, "SourceTextModuleMap"), - ("read_only_space", 0x01b69): (134, "StringTableMap"), - ("read_only_space", 0x01bb9): (120, "SyntheticModuleMap"), - ("read_only_space", 0x01c09): (165, "UncompiledDataWithoutPreparseDataMap"), - ("read_only_space", 0x01c59): (166, "UncompiledDataWithPreparseDataMap"), - ("read_only_space", 0x01ca9): (167, "WeakArrayListMap"), - ("read_only_space", 0x01cf9): (135, "EphemeronHashTableMap"), - ("read_only_space", 0x01d49): (122, "EmbedderDataArrayMap"), - ("read_only_space", 0x01d99): (168, "WeakCellMap"), - ("read_only_space", 0x01de9): (58, "NativeSourceStringMap"), - ("read_only_space", 0x01e39): (32, "StringMap"), - ("read_only_space", 0x01e89): (41, "ConsOneByteStringMap"), - ("read_only_space", 0x01ed9): (33, "ConsStringMap"), - ("read_only_space", 0x01f29): (45, "ThinOneByteStringMap"), - ("read_only_space", 0x01f79): (37, "ThinStringMap"), - ("read_only_space", 0x01fc9): (35, "SlicedStringMap"), - ("read_only_space", 0x02019): (43, "SlicedOneByteStringMap"), - ("read_only_space", 0x02069): (34, "ExternalStringMap"), - ("read_only_space", 0x020b9): (42, "ExternalOneByteStringMap"), - ("read_only_space", 0x02109): (50, "UncachedExternalStringMap"), - ("read_only_space", 0x02159): (0, "InternalizedStringMap"), - ("read_only_space", 0x021a9): (2, "ExternalInternalizedStringMap"), - ("read_only_space", 0x021f9): (10, "ExternalOneByteInternalizedStringMap"), - ("read_only_space", 0x02249): (18, "UncachedExternalInternalizedStringMap"), - ("read_only_space", 0x02299): (26, "UncachedExternalOneByteInternalizedStringMap"), - ("read_only_space", 0x022e9): (58, "UncachedExternalOneByteStringMap"), - ("read_only_space", 0x02339): (67, "SelfReferenceMarkerMap"), - ("read_only_space", 0x023a1): (87, "EnumCacheMap"), - ("read_only_space", 0x02441): (82, "ArrayBoilerplateDescriptionMap"), - ("read_only_space", 0x02631): (90, "InterceptorInfoMap"), - ("read_only_space", 0x04eb1): (77, "AccessCheckInfoMap"), - ("read_only_space", 0x04f01): (78, "AccessorInfoMap"), - ("read_only_space", 0x04f51): (79, "AccessorPairMap"), - ("read_only_space", 0x04fa1): (80, "AliasedArgumentsEntryMap"), - ("read_only_space", 0x04ff1): (81, "AllocationMementoMap"), - ("read_only_space", 0x05041): (83, "AsmWasmDataMap"), - ("read_only_space", 0x05091): (84, "AsyncGeneratorRequestMap"), - ("read_only_space", 0x050e1): (85, "ClassPositionsMap"), - ("read_only_space", 0x05131): (86, "DebugInfoMap"), - ("read_only_space", 0x05181): (88, "FunctionTemplateInfoMap"), - ("read_only_space", 0x051d1): (89, "FunctionTemplateRareDataMap"), - ("read_only_space", 0x05221): (91, "InterpreterDataMap"), - ("read_only_space", 0x05271): (92, "ObjectTemplateInfoMap"), - ("read_only_space", 0x052c1): (93, "PromiseCapabilityMap"), - ("read_only_space", 0x05311): (94, "PromiseReactionMap"), - ("read_only_space", 0x05361): (95, "PrototypeInfoMap"), - ("read_only_space", 0x053b1): (96, "ScriptMap"), - ("read_only_space", 0x05401): (97, "SourcePositionTableWithFrameCacheMap"), - ("read_only_space", 0x05451): (98, "SourceTextModuleInfoEntryMap"), - ("read_only_space", 0x054a1): (99, "StackFrameInfoMap"), - ("read_only_space", 0x054f1): (100, "StackTraceFrameMap"), - ("read_only_space", 0x05541): (101, "TemplateObjectDescriptionMap"), - ("read_only_space", 0x05591): (102, "Tuple2Map"), - ("read_only_space", 0x055e1): (103, "Tuple3Map"), - ("read_only_space", 0x05631): (104, "WasmCapiFunctionDataMap"), - ("read_only_space", 0x05681): (105, "WasmDebugInfoMap"), - ("read_only_space", 0x056d1): (106, "WasmExceptionTagMap"), - ("read_only_space", 0x05721): (107, "WasmExportedFunctionDataMap"), - ("read_only_space", 0x05771): (108, "WasmIndirectFunctionTableMap"), - ("read_only_space", 0x057c1): (109, "WasmJSFunctionDataMap"), - ("read_only_space", 0x05811): (110, "CallableTaskMap"), - ("read_only_space", 0x05861): (111, "CallbackTaskMap"), - ("read_only_space", 0x058b1): (112, "PromiseFulfillReactionJobTaskMap"), - ("read_only_space", 0x05901): (113, "PromiseRejectReactionJobTaskMap"), - ("read_only_space", 0x05951): (114, "PromiseResolveThenableJobTaskMap"), - ("read_only_space", 0x059a1): (115, "InternalClassMap"), - ("read_only_space", 0x059f1): (116, "SmiPairMap"), - ("read_only_space", 0x05a41): (117, "SmiBoxMap"), - ("read_only_space", 0x05a91): (118, "SortStateMap"), - ("read_only_space", 0x05ae1): (121, "AllocationSiteWithWeakNextMap"), - ("read_only_space", 0x05b31): (121, "AllocationSiteWithoutWeakNextMap"), - ("read_only_space", 0x05b81): (156, "LoadHandler1Map"), - ("read_only_space", 0x05bd1): (156, "LoadHandler2Map"), - ("read_only_space", 0x05c21): (156, "LoadHandler3Map"), - ("read_only_space", 0x05c71): (164, "StoreHandler0Map"), - ("read_only_space", 0x05cc1): (164, "StoreHandler1Map"), - ("read_only_space", 0x05d11): (164, "StoreHandler2Map"), - ("read_only_space", 0x05d61): (164, "StoreHandler3Map"), - ("map_space", 0x00119): (1057, "ExternalMap"), - ("map_space", 0x00169): (1073, "JSMessageObjectMap"), + ("read_only_space", 0x00121): (161, "FreeSpaceMap"), + ("read_only_space", 0x00171): (162, "MetaMap"), + ("read_only_space", 0x001f1): (67, "NullMap"), + ("read_only_space", 0x00259): (156, "DescriptorArrayMap"), + ("read_only_space", 0x002b9): (151, "WeakFixedArrayMap"), + ("read_only_space", 0x00309): (160, "OnePointerFillerMap"), + ("read_only_space", 0x00359): (160, "TwoPointerFillerMap"), + ("read_only_space", 0x003d9): (67, "UninitializedMap"), + ("read_only_space", 0x00449): (8, "OneByteInternalizedStringMap"), + ("read_only_space", 0x004e9): (67, "UndefinedMap"), + ("read_only_space", 0x00549): (66, "HeapNumberMap"), + ("read_only_space", 0x005c9): (67, "TheHoleMap"), + ("read_only_space", 0x00671): (67, "BooleanMap"), + ("read_only_space", 0x00749): (133, "ByteArrayMap"), + ("read_only_space", 0x00799): (118, "FixedArrayMap"), + ("read_only_space", 0x007e9): (118, "FixedCOWArrayMap"), + ("read_only_space", 0x00839): (119, "HashTableMap"), + ("read_only_space", 0x00889): (64, "SymbolMap"), + ("read_only_space", 0x008d9): (40, "OneByteStringMap"), + ("read_only_space", 0x00929): (131, "ScopeInfoMap"), + ("read_only_space", 0x00979): (166, "SharedFunctionInfoMap"), + ("read_only_space", 0x009c9): (154, "CodeMap"), + ("read_only_space", 0x00a19): (141, "FunctionContextMap"), + ("read_only_space", 0x00a69): (153, "CellMap"), + ("read_only_space", 0x00ab9): (165, "GlobalPropertyCellMap"), + ("read_only_space", 0x00b09): (70, "ForeignMap"), + ("read_only_space", 0x00b59): (152, "TransitionArrayMap"), + ("read_only_space", 0x00ba9): (159, "FeedbackVectorMap"), + ("read_only_space", 0x00c49): (67, "ArgumentsMarkerMap"), + ("read_only_space", 0x00ce9): (67, "ExceptionMap"), + ("read_only_space", 0x00d89): (67, "TerminationExceptionMap"), + ("read_only_space", 0x00e31): (67, "OptimizedOutMap"), + ("read_only_space", 0x00ed1): (67, "StaleRegisterMap"), + ("read_only_space", 0x00f41): (143, "NativeContextMap"), + ("read_only_space", 0x00f91): (142, "ModuleContextMap"), + ("read_only_space", 0x00fe1): (140, "EvalContextMap"), + ("read_only_space", 0x01031): (144, "ScriptContextMap"), + ("read_only_space", 0x01081): (136, "AwaitContextMap"), + ("read_only_space", 0x010d1): (137, "BlockContextMap"), + ("read_only_space", 0x01121): (138, "CatchContextMap"), + ("read_only_space", 0x01171): (145, "WithContextMap"), + ("read_only_space", 0x011c1): (139, "DebugEvaluateContextMap"), + ("read_only_space", 0x01211): (132, "ScriptContextTableMap"), + ("read_only_space", 0x01261): (129, "ClosureFeedbackCellArrayMap"), + ("read_only_space", 0x012b1): (158, "FeedbackMetadataArrayMap"), + ("read_only_space", 0x01301): (118, "ArrayListMap"), + ("read_only_space", 0x01351): (65, "BigIntMap"), + ("read_only_space", 0x013a1): (130, "ObjectBoilerplateDescriptionMap"), + ("read_only_space", 0x013f1): (134, "BytecodeArrayMap"), + ("read_only_space", 0x01441): (155, "CodeDataContainerMap"), + ("read_only_space", 0x01491): (135, "FixedDoubleArrayMap"), + ("read_only_space", 0x014e1): (121, "GlobalDictionaryMap"), + ("read_only_space", 0x01531): (95, "ManyClosuresCellMap"), + ("read_only_space", 0x01581): (118, "ModuleInfoMap"), + ("read_only_space", 0x015d1): (122, "NameDictionaryMap"), + ("read_only_space", 0x01621): (95, "NoClosuresCellMap"), + ("read_only_space", 0x01671): (123, "NumberDictionaryMap"), + ("read_only_space", 0x016c1): (95, "OneClosureCellMap"), + ("read_only_space", 0x01711): (124, "OrderedHashMapMap"), + ("read_only_space", 0x01761): (125, "OrderedHashSetMap"), + ("read_only_space", 0x017b1): (126, "OrderedNameDictionaryMap"), + ("read_only_space", 0x01801): (163, "PreparseDataMap"), + ("read_only_space", 0x01851): (164, "PropertyArrayMap"), + ("read_only_space", 0x018a1): (91, "SideEffectCallHandlerInfoMap"), + ("read_only_space", 0x018f1): (91, "SideEffectFreeCallHandlerInfoMap"), + ("read_only_space", 0x01941): (91, "NextCallSideEffectFreeCallHandlerInfoMap"), + ("read_only_space", 0x01991): (127, "SimpleNumberDictionaryMap"), + ("read_only_space", 0x019e1): (118, "SloppyArgumentsElementsMap"), + ("read_only_space", 0x01a31): (146, "SmallOrderedHashMapMap"), + ("read_only_space", 0x01a81): (147, "SmallOrderedHashSetMap"), + ("read_only_space", 0x01ad1): (148, "SmallOrderedNameDictionaryMap"), + ("read_only_space", 0x01b21): (68, "SourceTextModuleMap"), + ("read_only_space", 0x01b71): (128, "StringTableMap"), + ("read_only_space", 0x01bc1): (69, "SyntheticModuleMap"), + ("read_only_space", 0x01c11): (150, "UncompiledDataWithoutPreparseDataMap"), + ("read_only_space", 0x01c61): (149, "UncompiledDataWithPreparseDataMap"), + ("read_only_space", 0x01cb1): (167, "WeakArrayListMap"), + ("read_only_space", 0x01d01): (120, "EphemeronHashTableMap"), + ("read_only_space", 0x01d51): (157, "EmbedderDataArrayMap"), + ("read_only_space", 0x01da1): (168, "WeakCellMap"), + ("read_only_space", 0x01df1): (58, "NativeSourceStringMap"), + ("read_only_space", 0x01e41): (32, "StringMap"), + ("read_only_space", 0x01e91): (41, "ConsOneByteStringMap"), + ("read_only_space", 0x01ee1): (33, "ConsStringMap"), + ("read_only_space", 0x01f31): (45, "ThinOneByteStringMap"), + ("read_only_space", 0x01f81): (37, "ThinStringMap"), + ("read_only_space", 0x01fd1): (35, "SlicedStringMap"), + ("read_only_space", 0x02021): (43, "SlicedOneByteStringMap"), + ("read_only_space", 0x02071): (34, "ExternalStringMap"), + ("read_only_space", 0x020c1): (42, "ExternalOneByteStringMap"), + ("read_only_space", 0x02111): (50, "UncachedExternalStringMap"), + ("read_only_space", 0x02161): (0, "InternalizedStringMap"), + ("read_only_space", 0x021b1): (2, "ExternalInternalizedStringMap"), + ("read_only_space", 0x02201): (10, "ExternalOneByteInternalizedStringMap"), + ("read_only_space", 0x02251): (18, "UncachedExternalInternalizedStringMap"), + ("read_only_space", 0x022a1): (26, "UncachedExternalOneByteInternalizedStringMap"), + ("read_only_space", 0x022f1): (58, "UncachedExternalOneByteStringMap"), + ("read_only_space", 0x02341): (67, "SelfReferenceMarkerMap"), + ("read_only_space", 0x023a9): (94, "EnumCacheMap"), + ("read_only_space", 0x02449): (88, "ArrayBoilerplateDescriptionMap"), + ("read_only_space", 0x02639): (97, "InterceptorInfoMap"), + ("read_only_space", 0x04f79): (71, "PromiseFulfillReactionJobTaskMap"), + ("read_only_space", 0x04fc9): (72, "PromiseRejectReactionJobTaskMap"), + ("read_only_space", 0x05019): (73, "CallableTaskMap"), + ("read_only_space", 0x05069): (74, "CallbackTaskMap"), + ("read_only_space", 0x050b9): (75, "PromiseResolveThenableJobTaskMap"), + ("read_only_space", 0x05109): (78, "FunctionTemplateInfoMap"), + ("read_only_space", 0x05159): (79, "ObjectTemplateInfoMap"), + ("read_only_space", 0x051a9): (80, "Tuple2Map"), + ("read_only_space", 0x051f9): (81, "Tuple3Map"), + ("read_only_space", 0x05249): (82, "AccessCheckInfoMap"), + ("read_only_space", 0x05299): (83, "AccessorInfoMap"), + ("read_only_space", 0x052e9): (84, "AccessorPairMap"), + ("read_only_space", 0x05339): (85, "AliasedArgumentsEntryMap"), + ("read_only_space", 0x05389): (86, "AllocationMementoMap"), + ("read_only_space", 0x053d9): (89, "AsmWasmDataMap"), + ("read_only_space", 0x05429): (90, "AsyncGeneratorRequestMap"), + ("read_only_space", 0x05479): (92, "ClassPositionsMap"), + ("read_only_space", 0x054c9): (93, "DebugInfoMap"), + ("read_only_space", 0x05519): (96, "FunctionTemplateRareDataMap"), + ("read_only_space", 0x05569): (99, "InterpreterDataMap"), + ("read_only_space", 0x055b9): (100, "PromiseCapabilityMap"), + ("read_only_space", 0x05609): (101, "PromiseReactionMap"), + ("read_only_space", 0x05659): (102, "PrototypeInfoMap"), + ("read_only_space", 0x056a9): (103, "ScriptMap"), + ("read_only_space", 0x056f9): (107, "SourcePositionTableWithFrameCacheMap"), + ("read_only_space", 0x05749): (108, "SourceTextModuleInfoEntryMap"), + ("read_only_space", 0x05799): (109, "StackFrameInfoMap"), + ("read_only_space", 0x057e9): (110, "StackTraceFrameMap"), + ("read_only_space", 0x05839): (111, "TemplateObjectDescriptionMap"), + ("read_only_space", 0x05889): (112, "WasmCapiFunctionDataMap"), + ("read_only_space", 0x058d9): (113, "WasmDebugInfoMap"), + ("read_only_space", 0x05929): (114, "WasmExceptionTagMap"), + ("read_only_space", 0x05979): (115, "WasmExportedFunctionDataMap"), + ("read_only_space", 0x059c9): (116, "WasmIndirectFunctionTableMap"), + ("read_only_space", 0x05a19): (117, "WasmJSFunctionDataMap"), + ("read_only_space", 0x05a69): (98, "InternalClassMap"), + ("read_only_space", 0x05ab9): (105, "SmiPairMap"), + ("read_only_space", 0x05b09): (104, "SmiBoxMap"), + ("read_only_space", 0x05b59): (106, "SortStateMap"), + ("read_only_space", 0x05ba9): (87, "AllocationSiteWithWeakNextMap"), + ("read_only_space", 0x05bf9): (87, "AllocationSiteWithoutWeakNextMap"), + ("read_only_space", 0x05c49): (76, "LoadHandler1Map"), + ("read_only_space", 0x05c99): (76, "LoadHandler2Map"), + ("read_only_space", 0x05ce9): (76, "LoadHandler3Map"), + ("read_only_space", 0x05d39): (77, "StoreHandler0Map"), + ("read_only_space", 0x05d89): (77, "StoreHandler1Map"), + ("read_only_space", 0x05dd9): (77, "StoreHandler2Map"), + ("read_only_space", 0x05e29): (77, "StoreHandler3Map"), + ("map_space", 0x00121): (1057, "ExternalMap"), + ("map_space", 0x00171): (1072, "JSMessageObjectMap"), } # List of known V8 objects. KNOWN_OBJECTS = { - ("read_only_space", 0x001b9): "NullValue", - ("read_only_space", 0x00239): "EmptyDescriptorArray", - ("read_only_space", 0x002a1): "EmptyWeakFixedArray", - ("read_only_space", 0x003a1): "UninitializedValue", - ("read_only_space", 0x004b1): "UndefinedValue", - ("read_only_space", 0x00531): "NanValue", - ("read_only_space", 0x00591): "TheHoleValue", - ("read_only_space", 0x00629): "HoleNanValue", - ("read_only_space", 0x00639): "TrueValue", - ("read_only_space", 0x006e9): "FalseValue", - ("read_only_space", 0x00731): "empty_string", - ("read_only_space", 0x00bf1): "EmptyScopeInfo", - ("read_only_space", 0x00c01): "EmptyFixedArray", - ("read_only_space", 0x00c11): "ArgumentsMarker", - ("read_only_space", 0x00cb1): "Exception", - ("read_only_space", 0x00d51): "TerminationException", - ("read_only_space", 0x00df9): "OptimizedOut", - ("read_only_space", 0x00e99): "StaleRegister", - ("read_only_space", 0x02389): "EmptyEnumCache", - ("read_only_space", 0x023f1): "EmptyPropertyArray", - ("read_only_space", 0x02401): "EmptyByteArray", - ("read_only_space", 0x02411): "EmptyObjectBoilerplateDescription", - ("read_only_space", 0x02429): "EmptyArrayBoilerplateDescription", - ("read_only_space", 0x02491): "EmptyClosureFeedbackCellArray", - ("read_only_space", 0x024a1): "EmptySloppyArgumentsElements", - ("read_only_space", 0x024c1): "EmptySlowElementDictionary", - ("read_only_space", 0x02509): "EmptyOrderedHashMap", - ("read_only_space", 0x02531): "EmptyOrderedHashSet", - ("read_only_space", 0x02559): "EmptyFeedbackMetadata", - ("read_only_space", 0x02569): "EmptyPropertyCell", - ("read_only_space", 0x02591): "EmptyPropertyDictionary", - ("read_only_space", 0x025e1): "NoOpInterceptorInfo", - ("read_only_space", 0x02681): "EmptyWeakArrayList", - ("read_only_space", 0x02699): "InfinityValue", - ("read_only_space", 0x026a9): "MinusZeroValue", - ("read_only_space", 0x026b9): "MinusInfinityValue", - ("read_only_space", 0x026c9): "SelfReferenceMarker", - ("read_only_space", 0x02721): "OffHeapTrampolineRelocationInfo", - ("read_only_space", 0x02739): "TrampolineTrivialCodeDataContainer", - ("read_only_space", 0x02751): "TrampolinePromiseRejectionCodeDataContainer", - ("read_only_space", 0x02769): "GlobalThisBindingScopeInfo", - ("read_only_space", 0x027d1): "EmptyFunctionScopeInfo", - ("read_only_space", 0x02821): "HashSeed", - ("old_space", 0x00119): "ArgumentsIteratorAccessor", - ("old_space", 0x00189): "ArrayLengthAccessor", - ("old_space", 0x001f9): "BoundFunctionLengthAccessor", - ("old_space", 0x00269): "BoundFunctionNameAccessor", - ("old_space", 0x002d9): "ErrorStackAccessor", - ("old_space", 0x00349): "FunctionArgumentsAccessor", - ("old_space", 0x003b9): "FunctionCallerAccessor", - ("old_space", 0x00429): "FunctionNameAccessor", - ("old_space", 0x00499): "FunctionLengthAccessor", - ("old_space", 0x00509): "FunctionPrototypeAccessor", - ("old_space", 0x00579): "StringLengthAccessor", - ("old_space", 0x005e9): "InvalidPrototypeValidityCell", - ("old_space", 0x005f9): "EmptyScript", - ("old_space", 0x00679): "ManyClosuresCell", - ("old_space", 0x00691): "ArrayConstructorProtector", - ("old_space", 0x006a1): "NoElementsProtector", - ("old_space", 0x006c9): "IsConcatSpreadableProtector", - ("old_space", 0x006d9): "ArraySpeciesProtector", - ("old_space", 0x00701): "TypedArraySpeciesProtector", - ("old_space", 0x00729): "PromiseSpeciesProtector", - ("old_space", 0x00751): "StringLengthProtector", - ("old_space", 0x00761): "ArrayIteratorProtector", - ("old_space", 0x00789): "ArrayBufferDetachingProtector", - ("old_space", 0x007b1): "PromiseHookProtector", - ("old_space", 0x007d9): "PromiseResolveProtector", - ("old_space", 0x007e9): "MapIteratorProtector", - ("old_space", 0x00811): "PromiseThenProtector", - ("old_space", 0x00839): "SetIteratorProtector", - ("old_space", 0x00861): "StringIteratorProtector", - ("old_space", 0x00889): "SingleCharacterStringCache", - ("old_space", 0x01099): "StringSplitCache", - ("old_space", 0x018a9): "RegExpMultipleCache", - ("old_space", 0x020b9): "BuiltinsConstantsTable", + ("read_only_space", 0x001c1): "NullValue", + ("read_only_space", 0x00241): "EmptyDescriptorArray", + ("read_only_space", 0x002a9): "EmptyWeakFixedArray", + ("read_only_space", 0x003a9): "UninitializedValue", + ("read_only_space", 0x004b9): "UndefinedValue", + ("read_only_space", 0x00539): "NanValue", + ("read_only_space", 0x00599): "TheHoleValue", + ("read_only_space", 0x00631): "HoleNanValue", + ("read_only_space", 0x00641): "TrueValue", + ("read_only_space", 0x006f1): "FalseValue", + ("read_only_space", 0x00739): "empty_string", + ("read_only_space", 0x00bf9): "EmptyScopeInfo", + ("read_only_space", 0x00c09): "EmptyFixedArray", + ("read_only_space", 0x00c19): "ArgumentsMarker", + ("read_only_space", 0x00cb9): "Exception", + ("read_only_space", 0x00d59): "TerminationException", + ("read_only_space", 0x00e01): "OptimizedOut", + ("read_only_space", 0x00ea1): "StaleRegister", + ("read_only_space", 0x02391): "EmptyEnumCache", + ("read_only_space", 0x023f9): "EmptyPropertyArray", + ("read_only_space", 0x02409): "EmptyByteArray", + ("read_only_space", 0x02419): "EmptyObjectBoilerplateDescription", + ("read_only_space", 0x02431): "EmptyArrayBoilerplateDescription", + ("read_only_space", 0x02499): "EmptyClosureFeedbackCellArray", + ("read_only_space", 0x024a9): "EmptySloppyArgumentsElements", + ("read_only_space", 0x024c9): "EmptySlowElementDictionary", + ("read_only_space", 0x02511): "EmptyOrderedHashMap", + ("read_only_space", 0x02539): "EmptyOrderedHashSet", + ("read_only_space", 0x02561): "EmptyFeedbackMetadata", + ("read_only_space", 0x02571): "EmptyPropertyCell", + ("read_only_space", 0x02599): "EmptyPropertyDictionary", + ("read_only_space", 0x025e9): "NoOpInterceptorInfo", + ("read_only_space", 0x02689): "EmptyWeakArrayList", + ("read_only_space", 0x026a1): "InfinityValue", + ("read_only_space", 0x026b1): "MinusZeroValue", + ("read_only_space", 0x026c1): "MinusInfinityValue", + ("read_only_space", 0x026d1): "SelfReferenceMarker", + ("read_only_space", 0x02729): "OffHeapTrampolineRelocationInfo", + ("read_only_space", 0x02741): "TrampolineTrivialCodeDataContainer", + ("read_only_space", 0x02759): "TrampolinePromiseRejectionCodeDataContainer", + ("read_only_space", 0x02771): "GlobalThisBindingScopeInfo", + ("read_only_space", 0x027d9): "EmptyFunctionScopeInfo", + ("read_only_space", 0x02829): "HashSeed", + ("old_space", 0x00121): "ArgumentsIteratorAccessor", + ("old_space", 0x00191): "ArrayLengthAccessor", + ("old_space", 0x00201): "BoundFunctionLengthAccessor", + ("old_space", 0x00271): "BoundFunctionNameAccessor", + ("old_space", 0x002e1): "ErrorStackAccessor", + ("old_space", 0x00351): "FunctionArgumentsAccessor", + ("old_space", 0x003c1): "FunctionCallerAccessor", + ("old_space", 0x00431): "FunctionNameAccessor", + ("old_space", 0x004a1): "FunctionLengthAccessor", + ("old_space", 0x00511): "FunctionPrototypeAccessor", + ("old_space", 0x00581): "RegExpResultIndicesAccessor", + ("old_space", 0x005f1): "StringLengthAccessor", + ("old_space", 0x00661): "InvalidPrototypeValidityCell", + ("old_space", 0x00671): "EmptyScript", + ("old_space", 0x006f1): "ManyClosuresCell", + ("old_space", 0x00709): "ArrayConstructorProtector", + ("old_space", 0x00731): "NoElementsProtector", + ("old_space", 0x00759): "IsConcatSpreadableProtector", + ("old_space", 0x00781): "ArraySpeciesProtector", + ("old_space", 0x007a9): "TypedArraySpeciesProtector", + ("old_space", 0x007d1): "PromiseSpeciesProtector", + ("old_space", 0x007f9): "StringLengthProtector", + ("old_space", 0x00821): "ArrayIteratorProtector", + ("old_space", 0x00849): "ArrayBufferDetachingProtector", + ("old_space", 0x00871): "PromiseHookProtector", + ("old_space", 0x00899): "PromiseResolveProtector", + ("old_space", 0x008c1): "MapIteratorProtector", + ("old_space", 0x008e9): "PromiseThenProtector", + ("old_space", 0x00911): "SetIteratorProtector", + ("old_space", 0x00939): "StringIteratorProtector", + ("old_space", 0x00961): "SingleCharacterStringCache", + ("old_space", 0x01171): "StringSplitCache", + ("old_space", 0x01981): "RegExpMultipleCache", + ("old_space", 0x02191): "BuiltinsConstantsTable", } # List of known V8 Frame Markers. diff --git a/deps/v8/tools/wasm-compilation-hints/OWNERS b/deps/v8/tools/wasm-compilation-hints/OWNERS index 4c00a60a00f4cf..89abec33f34ce2 100644 --- a/deps/v8/tools/wasm-compilation-hints/OWNERS +++ b/deps/v8/tools/wasm-compilation-hints/OWNERS @@ -1,2 +1,2 @@ -clemensh@chromium.org +clemensb@chromium.org mstarzinger@chromium.org diff --git a/deps/v8/tools/wasm/update-wasm-spec-tests.sh b/deps/v8/tools/wasm/update-wasm-spec-tests.sh index 01688648eb0315..b3e9185c4dfaa8 100755 --- a/deps/v8/tools/wasm/update-wasm-spec-tests.sh +++ b/deps/v8/tools/wasm/update-wasm-spec-tests.sh @@ -71,7 +71,7 @@ log_and_run cp -r ${TMP_DIR}/spec/test/js-api/* ${JS_API_TEST_DIR}/tests # Generate the proposal tests. ############################################################################### -repos='bulk-memory-operations reference-types js-types' +repos='bulk-memory-operations reference-types js-types JS-BigInt-integration' for repo in ${repos}; do echo "Process ${repo}" diff --git a/deps/v8/tools/whitespace.txt b/deps/v8/tools/whitespace.txt index 1540f5f52a5dfb..c9a3400c497498 100644 --- a/deps/v8/tools/whitespace.txt +++ b/deps/v8/tools/whitespace.txt @@ -7,6 +7,6 @@ A Smi balks into a war and says: The doubles heard this and started to unbox. The Smi looked at them when a crazy v8-autoroll account showed up... The autoroller bought a round of Himbeerbrause. Suddenly..... -The bartender starts to shake the bottles.............. +The bartender starts to shake the bottles.................. I can't add trailing whitespaces, so I'm adding this line. I'm starting to think that just adding trailing whitespaces might not be bad. diff --git a/deps/v8/tools/windbg.js b/deps/v8/tools/windbg.js index 91877b4c616370..bcf45a496b45ad 100644 --- a/deps/v8/tools/windbg.js +++ b/deps/v8/tools/windbg.js @@ -20,9 +20,6 @@ function help() { print(" e.g. !jlh(\"key\") or !jlh(\"this->receiver_\")"); print(" !job(address_or_taggedint)"); print(" prints object at the address, e.g. !job(0x235cb869f9)"); - print(" !jobs(start_address, count)"); - print(" prints 'count' objects from a continuous range of Object"); - print(" pointers, e.g. !jobs(0x5f7270, 42)"); print(" !jst() or !jst"); print(" prints javascript stack (output goes into the console)"); print(" !jsbp() or !jsbp"); @@ -53,6 +50,11 @@ function help() { print(" !where(address)"); print(" prints name of the space and address of the MemoryChunk the"); print(" 'address' is from, e.g. !where(0x235cb869f9)"); + print(" !rs(chunk_address, set_id = 0)"); + print(" prints slots from the remembered set in the MemoryChunk. If"); + print(" 'chunk_address' isn't specified, prints for all chunks in the"); + print(" old space; 'set_id' should match RememberedSetType enum,"); + print(" e.g. !rs, !rs 0x2fb14780000, !rs(0x2fb14780000, 1)"); print(""); print("--------------------------------------------------------------------"); @@ -114,14 +116,6 @@ function print(s) { host.diagnostics.debugLog(s + "\n"); } -function print_filtered(obj, filter) { - for (let line of obj) { - if (!filter || line.indexOf(filter) != -1) { - print(line); - } - } -} - function inspect(s) { for (let k of Reflect.ownKeys(s)) { // Attempting to print either of: @@ -140,10 +134,23 @@ function hex(number) { /*============================================================================= Utils (postmortem and live) =============================================================================*/ -// WinDbg wraps large integers into objects that fail isInteger test (and, -// consequently fail isSafeInteger test even if the original value was a safe -// integer). I cannot figure out how to extract the original value from the -// wrapper object so doing it via conversion to a string. Brrr. Ugly. +// WinDbg wraps large integers (0x80000000+) into an object of library type that +// fails isInteger test (and, consequently fail isSafeInteger test even if the +// original value was a safe integer). +// However, that library type does have a set of methods on it which you can use +// to force conversion: +// .asNumber() / .valueOf(): Performs conversion to JavaScript number. +// Throws if the ordinal part of the 64-bit number does not pack into JavaScript +// number without loss of precision. +// .convertToNumber(): Performs conversion to JavaScript number. +// Does NOT throw if the ordinal part of the 64-bit number does not pack into +// JavaScript number. This will simply result in loss of precision. +// The library will also add these methods to the prototype for the standard +// number prototype. Meaning you can always .asNumber() / .convertToNumber() to +// get either JavaScript number or the private Int64 type into a JavaScript +// number. +// We could use the conversion functions but it seems that doing the conversion +// via toString is just as good and slightly more generic... function int(val) { if (typeof val === 'number') { return Number.isInteger(val) ? val : undefined; @@ -192,6 +199,26 @@ function get_register(name) { .Registers.User[name]; } +// JS doesn't do bitwise operations on large integers, so let's do it ourselves +// using hex string representation. +function bitwise_and(l, r) { + l = hex(l); + let l_length = l.length; + r = hex(r); + let r_length = r.length; + let res = ""; + let length = Math.min(l_length, r_length) - 2; // to account for "0x" + for (let i = 1; i <= length; i++) { + res = (parseInt(l[l_length - i], 16) & parseInt(r[r_length - i], 16)) + .toString(16) + res; + } + return parseInt(res, 16); +} + + +/*============================================================================= + Script setup +=============================================================================*/ // In debug builds v8 code is compiled into v8.dll, and in release builds // the code is compiled directly into the executable. If you are debugging some // other embedder, run !set_module and provide the module name to use. @@ -209,9 +236,18 @@ function module_name(use_this_module) { return m.Name.indexOf("\\v8.dll") !== -1; }); - if (v8) { + let v8_test = host.namespace.Debugger.State.DebuggerVariables.curprocess + .Modules.Where( + function(m) { + return m.Name.indexOf("\\v8_for_testing.dll") !== -1; + }); + + if (v8.Count() > 0) { module_name_cache = "v8"; } + else if (v8_test.Count() > 0) { + module_name_cache = "v8_for_testing"; + } else { for (let exe_name in known_exes) { let exe = host.namespace.Debugger.State.DebuggerVariables.curprocess @@ -219,7 +255,7 @@ function module_name(use_this_module) { function(m) { return m.Name.indexOf(`\\${exe_name}.exe`) !== -1; }); - if (exe) { + if (exe.Count() > 0) { module_name_cache = exe_name; break; } @@ -234,6 +270,25 @@ function module_name(use_this_module) { return module_name_cache; }; +let using_ptr_compr = false; +let isolate_address = 0; +function set_isolate_address(addr, ptr_compr) { + isolate_address = addr; + + if (typeof ptr_compr === 'undefined') { + ptr_compr = (bitwise_and(isolate_address, 0xffffffff) == 0); + } + using_ptr_compr = ptr_compr; + + if (using_ptr_compr) { + print("The target is using pointer compression."); + } +} + + +/*============================================================================= + Wrappers around V8's printing functions and other utils for live-debugging +=============================================================================*/ function make_call(fn) { if (!supports_call_command()) { print("ERROR: This command is supported in live sessions only!"); @@ -249,16 +304,8 @@ function make_call(fn) { return output; } - -/*============================================================================= - Wrappers around V8's printing functions and other utils for live-debugging -=============================================================================*/ - -/*----------------------------------------------------------------------------- - 'address' should be an int (so in hex must include '0x' prefix). ------------------------------------------------------------------------------*/ function print_object(address) { - let output = make_call(`_v8_internal_Print_Object(${address})`); + let output = make_call(`_v8_internal_Print_Object(${decomp(address)})`); // skip the first few lines with meta info of .call command let skip_line = true; @@ -273,43 +320,13 @@ function print_object(address) { } } -/*----------------------------------------------------------------------------- - 'handle_to_object' should be a name of a Handle which can be a local - variable or it can be a member variable like "this->receiver_". ------------------------------------------------------------------------------*/ function print_object_from_handle(handle_to_object) { let handle = host.evaluateExpression(handle_to_object); let location = handle.location_; - let pobj = poi(location.address); + let pobj = poi(location.address); // handles use uncompressed pointers print_object(pobj); } -/*----------------------------------------------------------------------------- - 'start_address' should be an int (so in hex must include '0x' prefix), it can - point at any continuous memory that contains Object pointers. ------------------------------------------------------------------------------*/ -function print_objects_array(start_address, count) { - const ptr_size = pointer_size(); - let ctl = host.namespace.Debugger.Utility.Control; - let addr_int = start_address; - for (let i = 0; i < count; i++) { - const addr_hex = hex(addr_int); - - // TODO: Tried using createPointerObject but it throws unknown exception - // from ChakraCore. Why? - //let obj = host.createPointerObject(addr_hex, module, "void*"); - - let output = ctl.ExecuteCommand(`dp ${addr_hex} l1`); - let item = ""; - for (item of output) {} // 005f7270 34604101 - let deref = `0x${item.split(" ").pop()}`; - print(`${addr_hex} -> ${deref}`); - print_object(deref); - - addr_int += ptr_size; - } -} - function print_js_stack() { make_call("_v8_internal_Print_StackTrace()"); } @@ -323,21 +340,47 @@ function set_user_js_bp() { /*============================================================================= Managed heap related functions (live and post-mortem debugging) =============================================================================*/ -let isolate_address = 0; -function set_isolate_address(addr) { - isolate_address = addr; +/*----------------------------------------------------------------------------- + Pointer compression +-----------------------------------------------------------------------------*/ +function tagged_size() { + return using_ptr_compr ? 4 : pointer_size(); } +function get_compressed_ptr_base() { + if (!using_ptr_compr) return 0; + + return isolate_address; +} + +function decomp(value) { + if (value > 0xffffffff) return value; + return get_compressed_ptr_base() + value; +} + +// Adjust for possible pointer compression ('address' is assumed to be on the +// managed heap). +function poim(address) { + try { + // readMemoryValues throws if cannot read from 'address'. + return host.memory.readMemoryValues(decomp(address), 1, tagged_size())[0]; + } + catch (e){} +} + +/*----------------------------------------------------------------------------- + Exploring objects +-----------------------------------------------------------------------------*/ function is_map(addr) { let address = int(addr); if (!Number.isSafeInteger(address) || address % 2 == 0) return false; // the first field in all objects, including maps, is a map pointer, but for // maps the pointer is always the same - the meta map that points to itself. - const map_addr = int(poi(address - 1)); + const map_addr = int(poim(address - 1)); if (!Number.isSafeInteger(map_addr)) return false; - const map_map_addr = int(poi(map_addr - 1)); + const map_map_addr = int(poim(map_addr - 1)); if (!Number.isSafeInteger(map_map_addr)) return false; return (map_addr === map_map_addr); @@ -348,12 +391,12 @@ function is_likely_object(addr) { if (!Number.isSafeInteger(address) || address % 2 == 0) return false; // the first field in all objects must be a map pointer - return is_map(poi(address - 1)); + return is_map(poim(address - 1)); } function find_object_near(aligned_addr, max_distance, step_op) { if (!step_op) { - const step = pointer_size(); + const step = tagged_size(); const prev = find_object_near(aligned_addr, max_distance, x => x - step); const next = @@ -364,14 +407,14 @@ function find_object_near(aligned_addr, max_distance, step_op) { return (addr - prev <= next - addr) ? prev : next; } - let maybe_map_addr = poi(aligned_addr); + let maybe_map_addr = poim(aligned_addr); let iters = 0; while (maybe_map_addr && iters < max_distance) { if (is_map(maybe_map_addr)) { return aligned_addr; } aligned_addr = step_op(aligned_addr); - maybe_map_addr = poi(aligned_addr); + maybe_map_addr = poim(aligned_addr); iters++; } } @@ -379,7 +422,7 @@ function find_object_near(aligned_addr, max_distance, step_op) { function find_object_prev(addr, max_distance) { if (!Number.isSafeInteger(int(addr))) return; - const ptr_size = pointer_size(); + const ptr_size = tagged_size(); const aligned_addr = addr - (addr % ptr_size); return find_object_near(aligned_addr, max_distance, x => x - ptr_size); } @@ -387,7 +430,7 @@ function find_object_prev(addr, max_distance) { function find_object_next(addr, max_distance) { if (!Number.isSafeInteger(int(addr))) return; - const ptr_size = pointer_size(); + const ptr_size = tagged_size(); const aligned_addr = addr - (addr % ptr_size) + ptr_size; return find_object_near(aligned_addr, max_distance, x => x + ptr_size); } @@ -400,7 +443,7 @@ function print_object_prev(addr, max_slots = 100) { } else { print( - `found object: ${hex(obj_addr + 1)} : ${hex(poi(obj_addr))}`); + `found object: ${hex(obj_addr + 1)} : ${hex(poim(obj_addr))}`); } } @@ -412,7 +455,7 @@ function print_object_next(addr, max_slots = 100) { } else { print( - `found object: ${hex(obj_addr + 1)} : ${hex(poi(obj_addr))}`); + `found object: ${hex(obj_addr + 1)} : ${hex(poim(obj_addr))}`); } } @@ -422,10 +465,11 @@ function print_objects_in_range(start, end){ if (!Number.isSafeInteger(int(start)) || !Number.isSafeInteger(int(end))) { return; } - const ptr_size = pointer_size(); + if (start < ptr_size || end <= start) return; + let iters = (end - start) / ptr_size; - let cur = start; + let cur = start - ptr_size; print(`===============================================`); print(`objects in range ${hex(start)} - ${hex(end)}`); print(`===============================================`); @@ -434,7 +478,7 @@ function print_objects_in_range(start, end){ let obj = find_object_next(cur, iters); if (obj) { count++; - print(`${hex(obj + 1)} : ${hex(poi(obj))}`); + print(`${hex(obj + 1)} : ${hex(poim(obj))}`); iters = (end - cur) / ptr_size; } cur = obj + ptr_size; @@ -454,10 +498,10 @@ function print_objects_tree(root, depth_limit) { let path = []; function impl(obj, depth, depth_limit) { - const ptr_size = pointer_size(); + const ptr_size = tagged_size(); // print the current object and its map pointer const this_obj = - `${" ".repeat(2 * depth)}${hex(obj)} : ${hex(poi(obj - 1))}`; + `${" ".repeat(2 * depth)}${hex(obj)} : ${hex(poim(obj - 1))}`; const cutoff = depth_limit && depth == depth_limit - 1; print(`${this_obj}${cutoff ? " (...)" : ""}`); if (cutoff) return; @@ -472,7 +516,7 @@ function print_objects_tree(root, depth_limit) { let seen = new Set(path); while (!is_likely_object(cur + 1) && iter < 100) { iter++; - let field = poi(cur); + let field = poim(cur); if (is_likely_object(field)) { if (seen.has(field)) { print( @@ -491,7 +535,7 @@ function print_objects_tree(root, depth_limit) { } /*----------------------------------------------------------------------------- - Memory in each Space is organized into a linked list of memory chunks + Memory spaces -----------------------------------------------------------------------------*/ const NEVER_EVACUATE = 1 << 7; // see src\heap\spaces.h @@ -564,12 +608,6 @@ function find_chunk(address) { return undefined; } -/*----------------------------------------------------------------------------- - Print memory chunks from spaces in the current Heap - 'isolate_address' should be an int (so in hex must include '0x' prefix). - 'space': space separated string containing "all", "old", "new", "map", - "code", "ro [readonly]", "lo [large]", "nlo [newlarge]" ------------------------------------------------------------------------------*/ function print_memory(space = "all") { if (isolate_address == 0) { print("Please call !set_iso(isolate_address) first."); @@ -622,16 +660,13 @@ function print_memory(space = "all") { } } -/*----------------------------------------------------------------------------- - 'isolate_address' and 'address' should be ints (so in hex must include '0x' - prefix). ------------------------------------------------------------------------------*/ function print_owning_space(address) { if (isolate_address == 0) { print("Please call !set_iso(isolate_address) first."); return; } + address = decomp(address); let c = find_chunk(address); if (c) { print(`${hex(address)} is in ${c.space} (chunk: ${hex(c.address)})`); @@ -642,7 +677,7 @@ function print_owning_space(address) { } /*----------------------------------------------------------------------------- - + Handles -----------------------------------------------------------------------------*/ function print_handles_data(print_handles = false) { if (isolate_address == 0) { @@ -705,6 +740,9 @@ function print_handles_data(print_handles = false) { } } +/*----------------------------------------------------------------------------- + dp +-----------------------------------------------------------------------------*/ function pad_right(addr) { let addr_hex = hex(addr); return `${addr_hex}${" ".repeat(pointer_size() * 2 + 2 - addr_hex.length)}`; @@ -721,26 +759,109 @@ function dp(addr, count = 10) { return; } - const ptr_size = pointer_size(); + const ptr_size = tagged_size(); let aligned_addr = addr - (addr % ptr_size); - let val = poi(aligned_addr); + let val = poim(aligned_addr); let iter = 0; while (val && iter < count) { - const augm_map = is_map(val) ? "map" : ""; - const augm_obj = is_likely_object(val) && !is_map(val) ? "obj" : ""; - const augm_other = !is_map(val) && !is_likely_object(val) ? "val" : ""; - let c = find_chunk(val); + const map = is_map(val); + const obj = is_likely_object(val) && !map; + + const augm_map = map ? "map" : ""; + const augm_obj = obj ? "obj" : ""; + const augm_other = !map && !obj ? "val" : ""; + + let c = find_chunk(decomp(val)); const augm_space = c ? ` in ${c.space}` : ""; const augm = `${augm_map}${augm_obj}${augm_other}${augm_space}`; - print(`${pad_right(aligned_addr)} ${pad_right(val)} ${augm}`); + const full_ptr = using_ptr_compr ? + pad_right((map || obj) ? decomp(val) : val) : ""; + print(`${pad_right(aligned_addr)} ${pad_right(val)} ${full_ptr} ${augm}`); aligned_addr += ptr_size; - val = poi(aligned_addr); + val = poim(aligned_addr); iter++; } } +/*----------------------------------------------------------------------------- + Remembered Sets +-----------------------------------------------------------------------------*/ +// set ids: 0 = OLD_TO_NEW, 1 = 0 = OLD_TO_OLD +function print_remembered_set(chunk_addr, set_id = 0) { + if (!chunk_addr) { + if (isolate_address == 0) { + print("Please call !set_iso(isolate_address) or provide chunk address."); + return; + } + + let iso = cast(isolate_address, "v8::internal::Isolate"); + let h = iso.heap_; + let chunks = []; + get_chunks_space('old', h.old_space_.memory_chunk_list_.front_, chunks); + get_chunks_space('lo', h.lo_space_.memory_chunk_list_.front_, chunks); + for (let c of chunks) { + try { + print_remembered_set(c.address); + } + catch (e) { + print(`failed to process chunk ${hex(c.address)} due to ${e.message}`); + } + } + return; + } + + print(`Remembered set in chunk ${hex(chunk_addr)}`); + let chunk = cast(chunk_addr, "v8::internal::MemoryChunk"); + + // chunk.slot_set_ is an array of SlotSet's. For standard pages there is 0 or + // 1 item in the array, but for large pages there will be more. + const page_size = 256 * 1024; + const sets_count = Math.floor((chunk.size_ + page_size - 1) / page_size); + let rs = chunk.slot_set_[set_id]; + if (rs.isNull) { + print(` <empty>`); + return; + } + if (rs[0].page_start_ != chunk_addr) { + print(`page_start_ [${hex(rs.page_start_)}] doesn't match chunk_addr!`); + return; + } + + const ptr_size = tagged_size(); + let count = 0; + for (let s = 0; s < sets_count; s++){ + const buckets_count = rs[s].buckets_.Count(); + for (let b = 0; b < buckets_count; b++) { + let bucket = rs[s].buckets_[b]; + if (bucket.isNull) continue; + // there are 32 cells in each bucket, cell's size is 32 bits + print(` bucket ${hex(bucket.address.asNumber())}:`); + const first_cell = bucket.address.asNumber(); + for (let c = 0; c < 32; c++) { + let cell = host.memory.readMemoryValues( + first_cell + c * 4, 1, 4 /*size to read*/)[0]; + if (cell == 0) continue; + let mask = 1; + for (let bit = 0; bit < 32; bit++){ + if (cell & mask) { + count++; + const slot_offset = (b * 32 * 32 + c * 32 + bit) * ptr_size; + const slot = rs[s].page_start_ + slot_offset; + print(` ${hex(slot)} -> ${hex(poim(slot))}`); + } + mask = mask << 1; + } + } + } + } + + if (count == 0) print(` <empty>`); + else print(` ${count} remembered pointers in chunk ${hex(chunk_addr)}`); +} + + /*============================================================================= Initialize short aliased names for the most common commands =============================================================================*/ @@ -749,7 +870,6 @@ function initializeScript() { new host.functionAlias(help, "help"), new host.functionAlias(print_object_from_handle, "jlh"), new host.functionAlias(print_object, "job"), - new host.functionAlias(print_objects_array, "jobs"), new host.functionAlias(print_js_stack, "jst"), new host.functionAlias(set_isolate_address, "set_iso"), @@ -757,6 +877,7 @@ function initializeScript() { new host.functionAlias(print_memory, "mem"), new host.functionAlias(print_owning_space, "where"), new host.functionAlias(print_handles_data, "handles"), + new host.functionAlias(print_remembered_set, "rs"), new host.functionAlias(print_object_prev, "jo_prev"), new host.functionAlias(print_object_next, "jo_next"), diff --git a/doc/api/addons.md b/doc/api/addons.md index cf2798c3a43637..6e5e9bf18c8418 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -241,6 +241,12 @@ NODE_MODULE_INIT(/* exports, module, context */) { #### Worker support +In order to be loaded from multiple Node.js environments, +such as a main thread and a Worker thread, an add-on needs to either: + +* Be an N-API addon, or +* Be declared as context-aware using `NODE_MODULE_INIT()` as described above + In order to support [`Worker`][] threads, addons need to clean up any resources they may have allocated when such a thread exists. This can be achieved through the usage of the `AddEnvironmentCleanupHook()` function: @@ -254,13 +260,62 @@ void AddEnvironmentCleanupHook(v8::Isolate* isolate, This function adds a hook that will run before a given Node.js instance shuts down. If necessary, such hooks can be removed using `RemoveEnvironmentCleanupHook()` before they are run, which has the same -signature. +signature. Callbacks are run in last-in first-out order. -In order to be loaded from multiple Node.js environments, -such as a main thread and a Worker thread, an add-on needs to either: +The following `addon.cc` uses `AddEnvironmentCleanupHook`: -* Be an N-API addon, or -* Be declared as context-aware using `NODE_MODULE_INIT()` as described above +```cpp +// addon.cc +#include <assert.h> +#include <stdlib.h> +#include <node.h> + +using node::AddEnvironmentCleanupHook; +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::Object; + +// Note: In a real-world application, do not rely on static/global data. +static char cookie[] = "yum yum"; +static int cleanup_cb1_called = 0; +static int cleanup_cb2_called = 0; + +static void cleanup_cb1(void* arg) { + Isolate* isolate = static_cast<Isolate*>(arg); + HandleScope scope(isolate); + Local<Object> obj = Object::New(isolate); + assert(!obj.IsEmpty()); // assert VM is still alive + assert(obj->IsObject()); + cleanup_cb1_called++; +} + +static void cleanup_cb2(void* arg) { + assert(arg == static_cast<void*>(cookie)); + cleanup_cb2_called++; +} + +static void sanity_check(void*) { + assert(cleanup_cb1_called == 1); + assert(cleanup_cb2_called == 1); +} + +// Initialize this addon to be context-aware. +NODE_MODULE_INIT(/* exports, module, context */) { + Isolate* isolate = context->GetIsolate(); + + AddEnvironmentCleanupHook(isolate, sanity_check, nullptr); + AddEnvironmentCleanupHook(isolate, cleanup_cb2, cookie); + AddEnvironmentCleanupHook(isolate, cleanup_cb1, isolate); +} +``` + +Test in JavaScript by running: + +```js +// test.js +require('./build/Release/addon'); +``` ### Building @@ -1293,85 +1348,6 @@ console.log(result); // Prints: 30 ``` -### AtExit hooks - -An `AtExit` hook is a function that is invoked after the Node.js event loop -has ended but before the JavaScript VM is terminated and Node.js shuts down. -`AtExit` hooks are registered using the `node::AtExit` API. - -#### void AtExit(callback, args) - -* `callback` <span class="type"><void (\*)(void\*)></span> - A pointer to the function to call at exit. -* `args` <span class="type"><void\*></span> - A pointer to pass to the callback at exit. - -Registers exit hooks that run after the event loop has ended but before the VM -is killed. - -`AtExit` takes two parameters: a pointer to a callback function to run at exit, -and a pointer to untyped context data to be passed to that callback. - -Callbacks are run in last-in first-out order. - -The following `addon.cc` implements `AtExit`: - -```cpp -// addon.cc -#include <assert.h> -#include <stdlib.h> -#include <node.h> - -namespace demo { - -using node::AtExit; -using v8::HandleScope; -using v8::Isolate; -using v8::Local; -using v8::Object; - -static char cookie[] = "yum yum"; -static int at_exit_cb1_called = 0; -static int at_exit_cb2_called = 0; - -static void at_exit_cb1(void* arg) { - Isolate* isolate = static_cast<Isolate*>(arg); - HandleScope scope(isolate); - Local<Object> obj = Object::New(isolate); - assert(!obj.IsEmpty()); // assert VM is still alive - assert(obj->IsObject()); - at_exit_cb1_called++; -} - -static void at_exit_cb2(void* arg) { - assert(arg == static_cast<void*>(cookie)); - at_exit_cb2_called++; -} - -static void sanity_check(void*) { - assert(at_exit_cb1_called == 1); - assert(at_exit_cb2_called == 2); -} - -void init(Local<Object> exports) { - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb1, exports->GetIsolate()); - AtExit(sanity_check); -} - -NODE_MODULE(NODE_GYP_MODULE_NAME, init) - -} // namespace demo -``` - -Test in JavaScript by running: - -```js -// test.js -require('./build/Release/addon'); -``` - [`Worker`]: worker_threads.html#worker_threads_class_worker [Electron]: https://electronjs.org/ [Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide diff --git a/doc/api/assert.md b/doc/api/assert.md index 7df70f60c35952..d27094fec53425 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -114,9 +114,13 @@ assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]); // ] ``` -To deactivate the colors, use the `NODE_DISABLE_COLORS` environment variable. +To deactivate the colors, use the `NO_COLOR` or +`NODE_DISABLE_COLORS` environment variable. This will also deactivate the colors in the REPL. +For more on the color support in terminal environments, read +the tty [getColorDepth()](tty.html#tty_writestream_getcolordepth_env) doc. + ## Legacy mode Legacy mode uses the [Abstract Equality Comparison][] in: diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 24dd6269f16674..7a025f94fade93 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -321,6 +321,9 @@ arbitrary command execution.** <!-- YAML added: v0.5.0 changes: + - version: v13.2.0 + pr-url: https://github.com/nodejs/node/pull/30162 + description: The `serialization` option is supported now. - version: v8.0.0 pr-url: https://github.com/nodejs/node/pull/10866 description: The `stdio` option can now be a string. @@ -340,6 +343,9 @@ changes: * `execPath` {string} Executable used to create the child process. * `execArgv` {string[]} List of string arguments passed to the executable. **Default:** `process.execArgv`. + * `serialization` {string} Specify the kind of serialization used for sending + messages between processes. Possible values are `'json'` and `'advanced'`. + See [Advanced Serialization][] for more details. **Default:** `'json'`. * `silent` {boolean} If `true`, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`child_process.spawn()`][]'s @@ -386,6 +392,9 @@ The `shell` option available in [`child_process.spawn()`][] is not supported by <!-- YAML added: v0.1.90 changes: + - version: v13.2.0 + pr-url: https://github.com/nodejs/node/pull/30162 + description: The `serialization` option is supported now. - version: v8.8.0 pr-url: https://github.com/nodejs/node/pull/15380 description: The `windowsHide` option is supported now. @@ -411,6 +420,9 @@ changes: [`options.detached`][]). * `uid` {number} Sets the user identity of the process (see setuid(2)). * `gid` {number} Sets the group identity of the process (see setgid(2)). + * `serialization` {string} Specify the kind of serialization used for sending + messages between processes. Possible values are `'json'` and `'advanced'`. + See [Advanced Serialization][] for more details. **Default:** `'json'`. * `shell` {boolean|string} If `true`, runs `command` inside of a shell. Uses `'/bin/sh'` on Unix, and `process.env.ComSpec` on Windows. A different shell can be specified as a string. See [Shell Requirements][] and @@ -998,6 +1010,11 @@ The `'message'` event is triggered when a child process uses The message goes through serialization and parsing. The resulting message might not be the same as what is originally sent. +If the `serialization` option was set to `'advanced'` used when spawning the +child process, the `message` argument can contain data that JSON is not able +to represent. +See [Advanced Serialization][] for more details. + ### subprocess.channel <!-- YAML added: v7.1.0 @@ -1472,6 +1489,26 @@ the same requirement. Thus, in `child_process` functions where a shell can be spawned, `'cmd.exe'` is used as a fallback if `process.env.ComSpec` is unavailable. +## Advanced Serialization +<!-- YAML +added: v13.2.0 +--> + +Child processes support a serialization mechanism for IPC that is based on the +[serialization API of the `v8` module][v8.serdes], based on the +[HTML structured clone algorithm][]. This is generally more powerful and +supports more built-in JavaScript object types, such as `BigInt`, `Map` +and `Set`, `ArrayBuffer` and `TypedArray`, `Buffer`, `Error`, `RegExp` etc. + +However, this format is not a full superset of JSON, and e.g. properties set on +objects of such built-in types will not be passed on through the serialization +step. Additionally, performance may not be equivalent to that of JSON, depending +on the structure of the passed data. +Therefore, this feature requires opting in by setting the +`serialization` option to `'advanced'` when calling [`child_process.spawn()`][] +or [`child_process.fork()`][]. + +[Advanced Serialization]: #child_process_advanced_serialization [`'disconnect'`]: process.html#process_event_disconnect [`'error'`]: #child_process_event_error [`'exit'`]: #child_process_event_exit @@ -1505,5 +1542,7 @@ unavailable. [`subprocess.stdout`]: #child_process_subprocess_stdout [`util.promisify()`]: util.html#util_util_promisify_original [Default Windows Shell]: #child_process_default_windows_shell +[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm [Shell Requirements]: #child_process_shell_requirements [synchronous counterparts]: #child_process_synchronous_process_creation +[v8.serdes]: v8.html#v8_serialization_api diff --git a/doc/api/cli.md b/doc/api/cli.md index fa46a00aff8f0f..c2bf666c9288d4 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -161,14 +161,23 @@ Currently, overriding `Error.prepareStackTrace` is ignored when the added: v12.0.0 --> -To be used in conjunction with `--experimental-modules`. Sets the resolution -algorithm for resolving specifiers. Valid options are `explicit` and `node`. +Sets the resolution algorithm for resolving ES module specifiers. Valid options +are `explicit` and `node`. The default is `explicit`, which requires providing the full path to a module. The `node` mode will enable support for optional file extensions and the ability to import a directory that has an index file. -Please see [customizing esm specifier resolution][] for example usage. +Please see [customizing ESM specifier resolution][] for example usage. + +### `--experimental-conditional-exports` +<!-- YAML +added: v13.2.0 +--> + +Enable experimental support for the `"require"` and `"node"` conditional +package export resolutions. +See [Conditional Exports][] for more information. ### `--experimental-json-modules` <!-- YAML @@ -182,7 +191,8 @@ Enable experimental JSON support for the ES Module loader. added: v8.5.0 --> -Enable experimental ES module support and caching modules. +Enable latest experimental modules features (currently +`--experimental-conditional-exports` and `--experimental-self-resolve`). ### `--experimental-policy` <!-- YAML @@ -333,9 +343,8 @@ Specify ICU data load path. (Overrides `NODE_ICU_DATA`.) added: v12.0.0 --> -Used with `--experimental-modules`, this configures Node.js to interpret string -input as CommonJS or as an ES module. String input is input via `--eval`, -`--print`, or `STDIN`. +This configures Node.js to interpret string input as CommonJS or as an ES +module. String input is input via `--eval`, `--print`, or `STDIN`. Valid values are `"commonjs"` and `"module"`. The default is `"commonjs"`. @@ -400,7 +409,7 @@ endpoint on `http://host:port/json/list`. added: v9.0.0 --> -Specify the `module` of a custom [experimental ECMAScript Module][] loader. +Specify the `module` of a custom [experimental ECMAScript Module loader][]. `module` may be either a path to a file, or an ECMAScript Module name. ### `--max-http-header-size=size` @@ -670,6 +679,15 @@ added: v4.0.0 Specify an alternative default TLS cipher list. Requires Node.js to be built with crypto support (default). +### `--tls-keylog=file` +<!-- YAML +added: v13.2.0 +--> + +Log TLS key material to a file. The key material is in NSS `SSLKEYLOGFILE` +format and can be used by software (such as Wireshark) to decrypt the TLS +traffic. + ### `--tls-max-v1.2` <!-- YAML added: v12.0.0 @@ -1021,6 +1039,7 @@ Node.js options that are allowed are: * `--enable-fips` * `--enable-source-maps` * `--es-module-specifier-resolution` +* `--experimental-conditional-exports` * `--experimental-json-modules` * `--experimental-loader` * `--experimental-modules` @@ -1063,6 +1082,7 @@ Node.js options that are allowed are: * `--throw-deprecation` * `--title` * `--tls-cipher-list` +* `--tls-keylog` * `--tls-max-v1.2` * `--tls-max-v1.3` * `--tls-min-v1.0` @@ -1311,16 +1331,17 @@ greater than `4` (its current default value). For more information, see the [`tls.DEFAULT_MIN_VERSION`]: tls.html#tls_tls_default_min_version [`unhandledRejection`]: process.html#process_event_unhandledrejection [Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/ +[Conditional Exports]: esm.html#esm_conditional_exports [REPL]: repl.html [ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage [Source Map]: https://sourcemaps.info/spec.html [Subresource Integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity [V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html -[customizing esm specifier resolution]: esm.html#esm_customizing_esm_specifier_resolution_algorithm +[context-aware]: addons.html#addons_context_aware_addons +[customizing ESM specifier resolution]: esm.html#esm_customizing_esm_specifier_resolution_algorithm [debugger]: debugger.html [debugging security implications]: https://nodejs.org/en/docs/guides/debugging-getting-started/#security-implications [emit_warning]: process.html#process_process_emitwarning_warning_type_code_ctor -[experimental ECMAScript Module]: esm.html#esm_resolve_hook +[experimental ECMAScript Module loader]: esm.html#esm_resolve_hook [libuv threadpool documentation]: http://docs.libuv.org/en/latest/threadpool.html [remote code execution]: https://www.owasp.org/index.php/Code_Injection -[context-aware]: addons.html#addons_context_aware_addons diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 112da9b2aa402e..a535f8296133f5 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -724,6 +724,9 @@ values are `'rr'` and `'none'`. <!-- YAML added: v0.7.1 changes: + - version: v13.2.0 + pr-url: https://github.com/nodejs/node/pull/30162 + description: The `serialization` option is supported now. - version: v9.5.0 pr-url: https://github.com/nodejs/node/pull/18399 description: The `cwd` option is supported now. @@ -746,6 +749,10 @@ changes: **Default:** `process.argv.slice(2)`. * `cwd` {string} Current working directory of the worker process. **Default:** `undefined` (inherits from parent process). + * `serialization` {string} Specify the kind of serialization used for sending + messages between processes. Possible values are `'json'` and `'advanced'`. + See [Advanced Serialization for `child_process`][] for more details. + **Default:** `false`. * `silent` {boolean} Whether or not to send output to parent's stdio. **Default:** `false`. * `stdio` {Array} Configures the stdio of forked processes. Because the @@ -874,4 +881,5 @@ socket.on('data', (id) => { [`process` event: `'message'`]: process.html#process_event_message [`server.close()`]: net.html#net_event_close [`worker.exitedAfterDisconnect`]: #cluster_worker_exitedafterdisconnect +[Advanced Serialization for `child_process`]: child_process.html#child_process_advanced_serialization [Child Process module]: child_process.html#child_process_child_process_fork_modulepath_args_options diff --git a/doc/api/console.md b/doc/api/console.md index 5700e914113c3d..45b8dad997873d 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -490,17 +490,6 @@ The following methods are exposed by the V8 engine in the general API but do not display anything unless used in conjunction with the [inspector][] (`--inspect` flag). -### console.markTimeline(\[label\]) -<!-- YAML -added: v8.0.0 ---> - -* `label` {string} **Default:** `'default'` - -This method does not display anything unless used in the inspector. The -`console.markTimeline()` method is the deprecated form of -[`console.timeStamp()`][]. - ### console.profile(\[label\]) <!-- YAML added: v8.0.0 @@ -546,27 +535,6 @@ This method does not display anything unless used in the inspector. The `console.timeStamp()` method adds an event with the label `'label'` to the **Timeline** panel of the inspector. -### console.timeline(\[label\]) -<!-- YAML -added: v8.0.0 ---> - -* `label` {string} **Default:** `'default'` - -This method does not display anything unless used in the inspector. The -`console.timeline()` method is the deprecated form of [`console.time()`][]. - -### console.timelineEnd(\[label\]) -<!-- YAML -added: v8.0.0 ---> - -* `label` {string} **Default:** `'default'` - -This method does not display anything unless used in the inspector. The -`console.timelineEnd()` method is the deprecated form of -[`console.timeEnd()`][]. - [`console.error()`]: #console_console_error_data_args [`console.group()`]: #console_console_group_label [`console.log()`]: #console_console_log_data_args @@ -574,7 +542,6 @@ This method does not display anything unless used in the inspector. The [`console.profileEnd()`]: #console_console_profileend_label [`console.time()`]: #console_console_time_label [`console.timeEnd()`]: #console_console_timeend_label -[`console.timeStamp()`]: #console_console_timestamp_label [`process.stderr`]: process.html#process_process_stderr [`process.stdout`]: process.html#process_process_stdout [`util.format()`]: util.html#util_util_format_format_args diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 91eefa7f161119..6bf1dcea365d93 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1405,6 +1405,7 @@ changes: --> * `privateKey` {Object | string | Buffer | KeyObject} + * `dsaEncoding` {string} * `padding` {integer} * `saltLength` {integer} * `outputEncoding` {string} The [encoding][] of the return value. @@ -1417,6 +1418,10 @@ If `privateKey` is not a [`KeyObject`][], this function behaves as if `privateKey` had been passed to [`crypto.createPrivateKey()`][]. If it is an object, the following additional properties can be passed: +* `dsaEncoding` {string} For DSA and ECDSA, this option specifies the + format of the generated signature. It can be one of the following: + * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. + * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. * `padding` {integer} Optional padding value for RSA, one of the following: * `crypto.constants.RSA_PKCS1_PADDING` (default) * `crypto.constants.RSA_PKCS1_PSS_PADDING` @@ -1513,6 +1518,7 @@ changes: --> * `object` {Object | string | Buffer | KeyObject} + * `dsaEncoding` {string} * `padding` {integer} * `saltLength` {integer} * `signature` {string | Buffer | TypedArray | DataView} @@ -1526,6 +1532,10 @@ If `object` is not a [`KeyObject`][], this function behaves as if `object` had been passed to [`crypto.createPublicKey()`][]. If it is an object, the following additional properties can be passed: +* `dsaEncoding` {string} For DSA and ECDSA, this option specifies the + format of the generated signature. It can be one of the following: + * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. + * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. * `padding` {integer} Optional padding value for RSA, one of the following: * `crypto.constants.RSA_PKCS1_PADDING` (default) * `crypto.constants.RSA_PKCS1_PSS_PADDING` @@ -2891,6 +2901,10 @@ If `key` is not a [`KeyObject`][], this function behaves as if `key` had been passed to [`crypto.createPrivateKey()`][]. If it is an object, the following additional properties can be passed: +* `dsaEncoding` {string} For DSA and ECDSA, this option specifies the + format of the generated signature. It can be one of the following: + * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. + * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. * `padding` {integer} Optional padding value for RSA, one of the following: * `crypto.constants.RSA_PKCS1_PADDING` (default) * `crypto.constants.RSA_PKCS1_PSS_PADDING` @@ -2944,6 +2958,10 @@ If `key` is not a [`KeyObject`][], this function behaves as if `key` had been passed to [`crypto.createPublicKey()`][]. If it is an object, the following additional properties can be passed: +* `dsaEncoding` {string} For DSA and ECDSA, this option specifies the + format of the generated signature. It can be one of the following: + * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. + * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. * `padding` {integer} Optional padding value for RSA, one of the following: * `crypto.constants.RSA_PKCS1_PADDING` (default) * `crypto.constants.RSA_PKCS1_PSS_PADDING` diff --git a/doc/api/errors.md b/doc/api/errors.md index 69b3745c78b88f..f2aace2c5e6636 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1998,6 +1998,11 @@ meaning of the error depends on the specific function. The `execArgv` option passed to the `Worker` constructor contains invalid flags. +<a id="ERR_WORKER_OUT_OF_MEMORY"></a> +### ERR_WORKER_OUT_OF_MEMORY + +The `Worker` instance terminated because it reached its memory limit. + <a id="ERR_WORKER_PATH"></a> ### ERR_WORKER_PATH diff --git a/doc/api/esm.md b/doc/api/esm.md index 5cb44868e8d47c..caaecaa0b41498 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -27,12 +27,9 @@ specifier resolution, and default behavior. <!-- type=misc --> -The `--experimental-modules` flag can be used to enable support for -ECMAScript modules (ES modules). - -Once enabled, Node.js will treat the following as ES modules when passed to -`node` as the initial input, or when referenced by `import` statements within -ES module code: +Experimental support for ECMAScript modules is enabled by default. +Node.js will treat the following as ES modules when passed to `node` as the +initial input, or when referenced by `import` statements within ES module code: * Files ending in `.mjs`. @@ -80,7 +77,7 @@ until the root of the volume is reached. ```sh # In same folder as above package.json -node --experimental-modules my-app.js # Runs as ES module +node my-app.js # Runs as ES module ``` If the nearest parent `package.json` lacks a `"type"` field, or contains @@ -114,9 +111,8 @@ own `package.json` file, so each project’s dependencies have their own package scopes. A `package.json` lacking a `"type"` field is treated as if it contained `"type": "commonjs"`. -The package scope applies not only to initial entry points (`node ---experimental-modules my-app.js`) but also to files referenced by `import` -statements and `import()` expressions. +The package scope applies not only to initial entry points (`node my-app.js`) +but also to files referenced by `import` statements and `import()` expressions. ```js // my-app.js, in an ES module package scope because there is a package.json @@ -169,11 +165,9 @@ piped to `node` via `STDIN`, will be treated as ES modules when the `--input-type=module` flag is set. ```sh -node --experimental-modules --input-type=module --eval \ - "import { sep } from 'path'; console.log(sep);" +node --input-type=module --eval "import { sep } from 'path'; console.log(sep);" -echo "import { sep } from 'path'; console.log(sep);" | \ - node --experimental-modules --input-type=module +echo "import { sep } from 'path'; console.log(sep);" | node --input-type=module ``` For completeness there is also `--input-type=commonjs`, for explicitly running @@ -184,6 +178,19 @@ unspecified. ### Package Entry Points +There are two fields that can define entry points for a package: `"main"` and +`"exports"`. The `"main"` field is supported in all versions of Node.js, but its +capabilities are limited: it only defines the main entry point of the package. +The `"exports"` field, part of [Package Exports][], provides an alternative to +`"main"` where the package main entry point can be defined while also +encapsulating the package, preventing any other entry points besides those +defined in `"exports"`. If package entry points are defined in both `"main"` and +`"exports"`, the latter takes precedence in versions of Node.js that support +`"exports"`. [Conditional Exports][] can also be used within `"exports"` to +define different package entry points per environment. + +#### <code>package.json</code> <code>"main"</code> + The `package.json` `"main"` field defines the entry point for a package, whether the package is included into CommonJS via `require` or into an ES module via `import`. @@ -219,48 +226,7 @@ The `"main"` field can point to exactly one file, regardless of whether the package is referenced via `require` (in a CommonJS context) or `import` (in an ES module context). -#### Compatibility with CommonJS-Only Versions of Node.js - -Prior to the introduction of support for ES modules in Node.js, it was a common -pattern for package authors to include both CommonJS and ES module JavaScript -sources in their package, with `package.json` `"main"` specifying the CommonJS -entry point and `package.json` `"module"` specifying the ES module entry point. -This enabled Node.js to run the CommonJS entry point while build tools such as -bundlers used the ES module entry point, since Node.js ignored (and still -ignores) `"module"`. - -Node.js can now run ES module entry points, but it remains impossible for a -package to define separate CommonJS and ES module entry points. This is for good -reason: the `pkg` variable created from `import pkg from 'pkg'` is not the same -singleton as the `pkg` variable created from `const pkg = require('pkg')`, so if -both are referenced within the same app (including dependencies), unexpected -behavior might occur. - -There are two general approaches to addressing this limitation while still -publishing a package that contains both CommonJS and ES module sources: - -1. Document a new ES module entry point that’s not the package `"main"`, e.g. - `import pkg from 'pkg/module.mjs'` (or `import 'pkg/esm'`, if using [package - exports][]). The package `"main"` would still point to a CommonJS file, and - thus the package would remain compatible with older versions of Node.js that - lack support for ES modules. - -1. Switch the package `"main"` entry point to an ES module file as part of a - breaking change version bump. This version and above would only be usable on - ES module-supporting versions of Node.js. If the package still contains a - CommonJS version, it would be accessible via a path within the package, e.g. - `require('pkg/commonjs')`; this is essentially the inverse of the previous - approach. Package consumers who are using CommonJS-only versions of Node.js - would need to update their code from `require('pkg')` to e.g. - `require('pkg/commonjs')`. - -Of course, a package could also include only CommonJS or only ES module sources. -An existing package could make a semver major bump to an ES module-only version, -that would only be supported in ES module-supporting versions of Node.js (and -other runtimes). New packages could be published containing only ES module -sources, and would be compatible only with ES module-supporting runtimes. - -### Package Exports +#### Package Exports By default, all subpaths from a package can be imported (`import 'pkg/x.js'`). Custom subpath aliasing and encapsulation can be provided through the @@ -313,50 +279,425 @@ If a package has no exports, setting `"exports": false` can be used instead of `"exports": {}` to indicate the package does not intend for submodules to be exposed. -Exports can also be used to map the main entry point of a package: +Any invalid exports entries will be ignored. This includes exports not +starting with `"./"` or a missing trailing `"/"` for directory exports. + +Array fallback support is provided for exports, similarly to import maps +in order to be forwards-compatible with possible fallback workflows in future: <!-- eslint-skip --> ```js -// ./node_modules/es-module-package/package.json { "exports": { - ".": "./main.js" + "./submodule": ["not:valid", "./submodule.js"] } } ``` -where the "." indicates loading the package without any subpath. Exports will -always override any existing `"main"` value for both CommonJS and -ES module packages. +Since `"not:valid"` is not a supported target, `"./submodule.js"` is used +instead as the fallback, as if it were the only target. + +Defining a `"."` export will define the main entry point for the package, +and will always take precedence over the `"main"` field in the `package.json`. -For packages with only a main entry point, an `"exports"` value of just -a string is also supported: +This allows defining a different entry point for Node.js versions that support +ECMAScript modules and versions that don't, for example: + +<!-- eslint-skip --> +```js +{ + "main": "./main-legacy.cjs", + "exports": { + ".": "./main-modern.cjs" + } +} +``` + +#### Conditional Exports + +Conditional exports provide a way to map to different paths depending on +certain conditions. They are supported for both CommonJS and ES module imports. + +For example, a package that wants to provide different ES module exports for +Node.js and the browser can be written: + +<!-- eslint-skip --> +```js +// ./node_modules/pkg/package.json +{ + "type": "module", + "main": "./index.js", + "exports": { + "./feature": { + "browser": "./feature-browser.js", + "default": "./feature-default.js" + } + } +} +``` + +When resolving the `"."` export, if no matching target is found, the `"main"` +will be used as the final fallback. + +The conditions supported in Node.js are matched in the following order: + +1. `"require"` - matched when the package is loaded via `require()`. + _This is currently only supported behind the + `--experimental-conditional-exports` flag._ +2. `"node"` - matched for any Node.js environment. Can be a CommonJS or ES + module file. _This is currently only supported behind the + `--experimental-conditional-exports` flag._ +3. `"default"` - the generic fallback that will always match if no other + more specific condition is matched first. Can be a CommonJS or ES module + file. + +Using the `"require"` condition it is possible to define a package that will +have a different exported value for CommonJS and ES modules, which can be a +hazard in that it can result in having two separate instances of the same +package in use in an application, which can cause a number of bugs. + +Other conditions such as `"browser"`, `"electron"`, `"deno"`, `"react-native"`, +etc. could be defined in other runtimes or tools. + +#### Exports Sugar + +If the `"."` export is the only export, the `"exports"` field provides sugar +for this case being the direct `"exports"` field value. + +If the `"."` export has a fallback array or string value, then the `"exports"` +field can be set to this value directly. + +<!-- eslint-skip --> +```js +{ + "exports": { + ".": "./main.js" + } +} +``` + +can be written: <!-- eslint-skip --> ```js -// ./node_modules/es-module-package/package.json { "exports": "./main.js" } ``` -Any invalid exports entries will be ignored. This includes exports not -starting with `"./"` or a missing trailing `"/"` for directory exports. +When using [Conditional Exports][], the rule is that all keys in the object +mapping must not start with a `"."` otherwise they would be indistinguishable +from exports subpaths. -Array fallback support is provided for exports, similarly to import maps -in order to be forward-compatible with fallback workflows in future: +<!-- eslint-skip --> +```js +{ + "exports": { + ".": { + "require": "./main.cjs", + "default": "./main.js" + } + } +} +``` + +can be written: <!-- eslint-skip --> ```js { "exports": { - "./submodule": ["not:valid", "./submodule.js"] + "require": "./main.cjs", + "default": "./main.js" } } ``` -Since `"not:valid"` is not a supported target, `"./submodule.js"` is used -instead as the fallback, as if it were the only target. +If writing any exports value that mixes up these two forms, an error will be +thrown: + +<!-- eslint-skip --> +```js +{ + // Throws on resolution! + "exports": { + "./feature": "./lib/feature.js", + "require": "./main.cjs", + "default": "./main.js" + } +} +``` + +### Dual CommonJS/ES Module Packages + +Prior to the introduction of support for ES modules in Node.js, it was a common +pattern for package authors to include both CommonJS and ES module JavaScript +sources in their package, with `package.json` `"main"` specifying the CommonJS +entry point and `package.json` `"module"` specifying the ES module entry point. +This enabled Node.js to run the CommonJS entry point while build tools such as +bundlers used the ES module entry point, since Node.js ignored (and still +ignores) the top-level `"module"` field. + +Node.js can now run ES module entry points, and a package can contain both +CommonJS and ES module entry points (either via separate specifiers such as +`'pkg'` and `'pkg/es-module'`, or both at the same specifier via [Conditional +Exports][] with the `--experimental-conditional-exports` flag). Unlike in the +scenario where `"module"` is only used by bundlers, or ES module files are +transpiled into CommonJS on the fly before evaluation by Node.js, the files +referenced by the ES module entry point are evaluated as ES modules. + +#### Dual Package Hazard + +When an application is using a package that provides both CommonJS and ES module +sources, there is a risk of certain bugs if both versions of the package get +loaded. This potential comes from the fact that the `pkgInstance` created by +`const pkgInstance = require('pkg')` is not the same as the `pkgInstance` +created by `import pkgInstance from 'pkg'` (or an alternative main path like +`'pkg/module'`). This is the “dual package hazard,” where two versions of the +same package can be loaded within the same runtime environment. While it is +unlikely that an application or package would intentionally load both versions +directly, it is common for an application to load one version while a dependency +of the application loads the other version. This hazard can happen because +Node.js supports intermixing CommonJS and ES modules, and can lead to unexpected +behavior. + +If the package main export is a constructor, an `instanceof` comparison of +instances created by the two versions returns `false`, and if the export is an +object, properties added to one (like `pkgInstance.foo = 3`) are not present on +the other. This differs from how `import` and `require` statements work in +all-CommonJS or all-ES module environments, respectively, and therefore is +surprising to users. It also differs from the behavior users are familiar with +when using transpilation via tools like [Babel][] or [`esm`][]. + +#### Writing Dual Packages While Avoiding or Minimizing Hazards + +First, the hazard described in the previous section occurs when a package +contains both CommonJS and ES module sources and both sources are provided for +use in Node.js, either via separate main entry points or exported paths. A +package could instead be written where any version of Node.js receives only +CommonJS sources, and any separate ES module sources the package may contain +could be intended only for other environments such as browsers. Such a package +would be usable by any version of Node.js, since `import` can refer to CommonJS +files; but it would not provide any of the advantages of using ES module syntax. + +A package could also switch from CommonJS to ES module syntax in a breaking +change version bump. This has the obvious disadvantage that the newest version +of the package would only be usable in ES module-supporting versions of Node.js. + +Every pattern has tradeoffs, but there are two broad approaches that satisfy the +following conditions: + +1. The package is usable via both `require` and `import`. +1. The package is usable in both current Node.js and older versions of Node.js + that lack support for ES modules. +1. The package main entry point, e.g. `'pkg'` can be used by both `require` to + resolve to a CommonJS file and by `import` to resolve to an ES module file. + (And likewise for exported paths, e.g. `'pkg/feature'`.) +1. The package provides named exports, e.g. `import { name } from 'pkg'` rather + than `import pkg from 'pkg'; pkg.name`. +1. The package is potentially usable in other ES module environments such as + browsers. +1. The hazards described in the previous section are avoided or minimized. + +##### Approach #1: Use an ES Module Wrapper + +Write the package in CommonJS or transpile ES module sources into CommonJS, and +create an ES module wrapper file that defines the named exports. Using +[Conditional Exports][] via the `--experimental-conditional-exports` flag, the +ES module wrapper is used for `import` and the CommonJS entry point for +`require`. + +> Note: While `--experimental-conditional-exports` is flagged, a package +> using this pattern will throw when loaded via `require()` in modern +> Node.js, unless package consumers use the `--experimental-conditional-exports` +> flag. + +<!-- eslint-skip --> +```js +// ./node_modules/pkg/package.json +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "require": "./index.cjs", + "default": "./wrapper.mjs" + } +} +``` + +```js +// ./node_modules/pkg/index.cjs +exports.name = 'value'; +``` + +```js +// ./node_modules/pkg/wrapper.mjs +import cjsModule from './index.cjs'; +export const name = cjsModule.name; +``` + +In this example, the `name` from `import { name } from 'pkg'` is the same +singleton as the `name` from `const { name } = require('pkg')`. Therefore `===` +returns `true` when comparing the two `name`s and the divergent specifier hazard +is avoided. + +If the module is not simply a list of named exports, but rather contains a +unique function or object export like `module.exports = function () { ... }`, +or if support in the wrapper for the `import pkg from 'pkg'` pattern is desired, +then the wrapper would instead be written to export the default optionally +along with any named exports as well: + +```js +import cjsModule from './index.cjs'; +export const name = cjsModule.name; +export default cjsModule; +``` + +This approach is appropriate for any of the following use cases: +* The package is currently written in CommonJS and the author would prefer not + to refactor it into ES module syntax, but wishes to provide named exports for + ES module consumers. +* The package has other packages that depend on it, and the end user might + install both this package and those other packages. For example a `utilities` + package is used directly in an application, and a `utilities-plus` package + adds a few more functions to `utilities`. Because the wrapper exports + underlying CommonJS files, it doesn’t matter if `utilities-plus` is written in + CommonJS or ES module syntax; it will work either way. +* The package stores internal state, and the package author would prefer not to + refactor the package to isolate its state management. See the next section. + +A variant of this approach not requiring `--experimental-conditional-exports` +for consumers could be to add an export, e.g. `"./module"`, to point to an +all-ES module-syntax version of the package. This could be used via `import +'pkg/module'` by users who are certain that the CommonJS version will not be +loaded anywhere in the application, such as by dependencies; or if the CommonJS +version can be loaded but doesn’t affect the ES module version (for example, +because the package is stateless): + +<!-- eslint-skip --> +```js +// ./node_modules/pkg/package.json +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./wrapper.mjs" + } +} +``` + +If the `--experimental-conditional-exports` flag is dropped and therefore +[Conditional Exports][] become available without a flag, this variant could be +easily updated to use conditional exports by adding conditions to the `"."` +path; while keeping `"./module"` for backward compatibility. + +##### Approach #2: Isolate State + +The most straightforward `package.json` would be one that defines the separate +CommonJS and ES module entry points directly (requires +`--experimental-conditional-exports`): + +<!-- eslint-skip --> +```js +// ./node_modules/pkg/package.json +{ + "type": "module", + "main": "./index.cjs", + "exports": { + "require": "./index.cjs", + "default": "./index.mjs" + } +} +``` + +This can be done if both the CommonJS and ES module versions of the package are +equivalent, for example because one is the transpiled output of the other; and +the package’s management of state is carefully isolated (or the package is +stateless). + +The reason that state is an issue is because both the CommonJS and ES module +versions of the package may get used within an application; for example, the +user’s application code could `import` the ES module version while a dependency +`require`s the CommonJS version. If that were to occur, two copies of the +package would be loaded in memory and therefore two separate states would be +present. This would likely cause hard-to-troubleshoot bugs. + +Aside from writing a stateless package (if JavaScript’s `Math` were a package, +for example, it would be stateless as all of its methods are static), there are +some ways to isolate state so that it’s shared between the potentially loaded +CommonJS and ES module instances of the package: + +1. If possible, contain all state within an instantiated object. JavaScript’s + `Date`, for example, needs to be instantiated to contain state; if it were a + package, it would be used like this: + + ```js + import Date from 'date'; + const someDate = new Date(); + // someDate contains state; Date does not + ``` + + The `new` keyword isn’t required; a package’s function can return a new + object, or modify a passed-in object, to keep the state external to the + package. + +1. Isolate the state in one or more CommonJS files that are shared between the + CommonJS and ES module versions of the package. For example, if the CommonJS + and ES module entry points are `index.cjs` and `index.mjs`, respectively: + + ```js + // ./node_modules/pkg/index.cjs + const state = require('./state.cjs'); + module.exports.state = state; + ``` + + ```js + // ./node_modules/pkg/index.mjs + export state from './state.cjs'; + ``` + + Even if `pkg` is used via both `require` and `import` in an application (for + example, via `import` in application code and via `require` by a dependency) + each reference of `pkg` will contain the same state; and modifying that + state from either module system will apply to both. + +Any plugins that attach to the package’s singleton would need to separately +attach to both the CommonJS and ES module singletons. + +This approach is appropriate for any of the following use cases: +* The package is currently written in ES module syntax and the package author + wants that version to be used wherever such syntax is supported. +* The package is stateless or its state can be isolated without too much + difficulty. +* The package is unlikely to have other public packages that depend on it, or if + it does, the package is stateless or has state that need not be shared between + dependencies or with the overall application. + +Even with isolated state, there is still the cost of possible extra code +execution between the CommonJS and ES module versions of a package. + +As with the previous approach, a variant of this approach not requiring +`--experimental-conditional-exports` for consumers could be to add an export, +e.g. `"./module"`, to point to an all-ES module-syntax version of the package: + +<!-- eslint-skip --> +```js +// ./node_modules/pkg/package.json +{ + "type": "module", + "main": "./index.cjs", + "exports": { + ".": "./index.cjs", + "./module": "./index.mjs" + } +} +``` + +If the `--experimental-conditional-exports` flag is dropped and therefore +[Conditional Exports][] become available without a flag, this variant could be +easily updated to use conditional exports by adding conditions to the `"."` +path; while keeping `"./module"` for backward compatibility. ## <code>import</code> Specifiers @@ -493,9 +834,9 @@ To include an ES module into CommonJS, use [`import()`][]. ### <code>import</code> statements -An `import` statement can reference an ES module, a CommonJS module, or JSON. -Other file types such as Native modules are not supported. For those, -use [`module.createRequire()`][]. +An `import` statement can reference an ES module or a CommonJS module. Other +file types such as JSON or Native modules are not supported. For those, use +[`module.createRequire()`][]. `import` statements are permitted only in ES modules. For similar functionality in CommonJS, see [`import()`][]. @@ -505,23 +846,22 @@ can either be an URL-style relative path like `'./file.mjs'` or a package name like `'fs'`. Like in CommonJS, files within packages can be accessed by appending a path to -the package name. +the package name; unless the package’s `package.json` contains an [`"exports"` +field][], in which case files within packages need to be accessed via the path +defined in `"exports"`. ```js import { sin, cos } from 'geometry/trigonometry-functions.mjs'; ``` -> Currently only the “default export” is supported for CommonJS files or -> packages: -> -> <!-- eslint-disable no-duplicate-imports --> -> ```js -> import packageMain from 'commonjs-package'; // Works -> -> import { method } from 'commonjs-package'; // Errors -> ``` -> -> There are ongoing efforts to make the latter code possible. +Only the “default export” is supported for CommonJS files or packages: + +<!-- eslint-disable no-duplicate-imports --> +```js +import packageMain from 'commonjs-package'; // Works + +import { method } from 'commonjs-package'; // Errors +``` ### <code>import()</code> expressions @@ -540,16 +880,15 @@ CommonJS, JSON, and Native modules can be used with [`module.createRequire()`][]. ```js -// cjs.js +// cjs.cjs module.exports = 'cjs'; // esm.mjs import { createRequire } from 'module'; -import { fileURLToPath as fromURL } from 'url'; -const require = createRequire(fromURL(import.meta.url)); +const require = createRequire(import.meta.url); -const cjs = require('./cjs'); +const cjs = require('./cjs.cjs'); cjs === 'cjs'; // true ``` @@ -613,8 +952,8 @@ The `--experimental-json-modules` flag is needed for the module to work. ```bash -node --experimental-modules index.mjs # fails -node --experimental-modules --experimental-json-modules index.mjs # works +node index.mjs # fails +node --experimental-json-modules index.mjs # works ``` ## Experimental Wasm Modules @@ -636,7 +975,7 @@ console.log(M); executed under: ```bash -node --experimental-modules --experimental-wasm-modules index.mjs +node --experimental-wasm-modules index.mjs ``` would provide the exports interface for the instantiation of `module.wasm`. @@ -747,7 +1086,7 @@ export async function resolve(specifier, With this loader, running: ```console -NODE_OPTIONS='--experimental-modules --experimental-loader ./custom-loader.mjs' node x.js +NODE_OPTIONS='--experimental-loader ./custom-loader.mjs' node x.js ``` would load the module `x.js` as an ES module with relative resolution support @@ -806,6 +1145,9 @@ of these top-level routines unless stated otherwise. _isMain_ is **true** when resolving the Node.js application entry point. +_defaultEnv_ is the conditional environment name priority array, +`["node", "default"]`. + <details> <summary>Resolver algorithm specification</summary> @@ -905,14 +1247,16 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. If _pjson_ is **null**, then > 1. Throw a _Module Not Found_ error. > 1. If _pjson.exports_ is not **null** or **undefined**, then -> 1. If _pjson.exports_ is a String or Array, then +> 1. If _exports_ is an Object with both a key starting with _"."_ and a key +> not starting with _"."_, throw an "Invalid Package Configuration" error. +> 1. If _pjson.exports_ is a String or Array, or an Object containing no +> keys starting with _"."_, then > 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, -> _pjson.exports_, "")_. -> 1. If _pjson.exports is an Object, then -> 1. If _pjson.exports_ contains a _"."_ property, then -> 1. Let _mainExport_ be the _"."_ property in _pjson.exports_. -> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, -> _mainExport_, "")_. +> _pjson.exports_, _""_). +> 1. If _pjson.exports_ is an Object containing a _"."_ property, then +> 1. Let _mainExport_ be the _"."_ property in _pjson.exports_. +> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, +> _mainExport_, _""_). > 1. If _pjson.main_ is a String, then > 1. Let _resolvedMain_ be the URL resolution of _packageURL_, "/", and > _pjson.main_. @@ -926,13 +1270,14 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. Return _legacyMainURL_. **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _packagePath_, _exports_) - -> 1. If _exports_ is an Object, then +> 1. If _exports_ is an Object with both a key starting with _"."_ and a key not +> starting with _"."_, throw an "Invalid Package Configuration" error. +> 1. If _exports_ is an Object and all keys of _exports_ start with _"."_, then > 1. Set _packagePath_ to _"./"_ concatenated with _packagePath_. > 1. If _packagePath_ is a key of _exports_, then > 1. Let _target_ be the value of _exports\[packagePath\]_. > 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, -> _""_). +> _""_, _defaultEnv_). > 1. Let _directoryKeys_ be the list of keys of _exports_ ending in > _"/"_, sorted by length descending. > 1. For each key _directory_ in _directoryKeys_, do @@ -941,10 +1286,10 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. Let _subpath_ be the substring of _target_ starting at the index > of the length of _directory_. > 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, -> _subpath_). +> _subpath_, _defaultEnv_). > 1. Throw a _Module Not Found_ error. -**PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_) +**PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_, _env_) > 1. If _target_ is a String, then > 1. If _target_ does not start with _"./"_, throw a _Module Not Found_ @@ -960,12 +1305,20 @@ _isMain_ is **true** when resolving the Node.js application entry point. > _subpath_ and _resolvedTarget_. > 1. If _resolved_ is contained in _resolvedTarget_, then > 1. Return _resolved_. +> 1. Otherwise, if _target_ is a non-null Object, then +> 1. If _target_ has an object key matching one of the names in _env_, then +> 1. Let _targetValue_ be the corresponding value of the first object key +> of _target_ in _env_. +> 1. Let _resolved_ be the result of **PACKAGE_EXPORTS_TARGET_RESOLVE** +> (_packageURL_, _targetValue_, _subpath_, _env_). +> 1. Assert: _resolved_ is a String. +> 1. Return _resolved_. > 1. Otherwise, if _target_ is an Array, then > 1. For each item _targetValue_ in _target_, do -> 1. If _targetValue_ is not a String, continue the loop. +> 1. If _targetValue_ is an Array, continue the loop. > 1. Let _resolved_ be the result of > **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _targetValue_, -> _subpath_), continuing the loop on abrupt completion. +> _subpath_, _env_), continuing the loop on abrupt completion. > 1. Assert: _resolved_ is a String. > 1. Return _resolved_. > 1. Throw a _Module Not Found_ error. @@ -983,8 +1336,7 @@ _isMain_ is **true** when resolving the Node.js application entry point. > 1. Return _"module"_. > 1. Throw an _Unsupported File Extension_ error. > 1. Otherwise, -> 1. If _isMain_ is **true** or _url_ ends in _".js"_, _".json"_ or -> _".node"_, then +> 1. If _isMain_ is **true**, then > 1. Return _"commonjs"_. > 1. Throw an _Unsupported File Extension_ error. @@ -1024,21 +1376,26 @@ automatic extension resolution and importing from directories that include an index file use the `node` mode. ```bash -$ node --experimental-modules index.mjs +$ node index.mjs success! -$ node --experimental-modules index #Failure! +$ node index # Failure! Error: Cannot find module -$ node --experimental-modules --es-module-specifier-resolution=node index +$ node --es-module-specifier-resolution=node index success! ``` +[Babel]: https://babeljs.io/ [CommonJS]: modules.html +[Conditional Exports]: #esm_conditional_exports [ECMAScript-modules implementation]: https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md [ES Module Integration Proposal for Web Assembly]: https://github.com/webassembly/esm-integration [Node.js EP for ES Modules]: https://github.com/nodejs/node-eps/blob/master/002-es-modules.md +[Package Exports]: #esm_package_exports [Terminology]: #esm_terminology [WHATWG JSON modules specification]: https://html.spec.whatwg.org/#creating-a-json-module-script +[`"exports"` field]: #esm_package_exports [`data:` URLs]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs +[`esm`]: https://github.com/standard-things/esm#readme [`export`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export [`import()`]: #esm_import-expressions [`import.meta.url`]: #esm_import_meta @@ -1046,6 +1403,5 @@ success! [`module.createRequire()`]: modules.html#modules_module_createrequire_filename [`module.syncBuiltinESMExports()`]: modules.html#modules_module_syncbuiltinesmexports [dynamic instantiate hook]: #esm_dynamic_instantiate_hook -[package exports]: #esm_package_exports [special scheme]: https://url.spec.whatwg.org/#special-scheme [the official standard format]: https://tc39.github.io/ecma262/#sec-modules diff --git a/doc/api/http.md b/doc/api/http.md index 81e07b482af8d4..44bea87e3bc6ca 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -157,7 +157,7 @@ added: v0.11.4 * `options` {Object} Options containing connection details. Check [`net.createConnection()`][] for the format of the options * `callback` {Function} Callback function that receives the created socket -* Returns: {net.Socket} +* Returns: {stream.Duplex} Produces a socket/stream to be used for HTTP requests. @@ -167,6 +167,10 @@ custom agents may override this method in case greater flexibility is desired. A socket/stream can be supplied in one of two ways: by returning the socket/stream from this function, or by passing the socket/stream to `callback`. +This method is guaranteed to return an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + `callback` has a signature of `(err, stream)`. ### agent.keepSocketAlive(socket) @@ -174,7 +178,7 @@ socket/stream from this function, or by passing the socket/stream to `callback`. added: v8.1.0 --> -* `socket` {net.Socket} +* `socket` {stream.Duplex} Called when `socket` is detached from a request and could be persisted by the `Agent`. Default behavior is to: @@ -189,12 +193,15 @@ This method can be overridden by a particular `Agent` subclass. If this method returns a falsy value, the socket will be destroyed instead of persisting it for use with the next request. +The `socket` argument can be an instance of {net.Socket}, a subclass of +{stream.Duplex}. + ### agent.reuseSocket(socket, request) <!-- YAML added: v8.1.0 --> -* `socket` {net.Socket} +* `socket` {stream.Duplex} * `request` {http.ClientRequest} Called when `socket` is attached to `request` after being persisted because of @@ -206,6 +213,9 @@ socket.ref(); This method can be overridden by a particular `Agent` subclass. +The `socket` argument can be an instance of {net.Socket}, a subclass of +{stream.Duplex}. + ### agent.destroy() <!-- YAML added: v0.11.4 @@ -341,13 +351,17 @@ added: v0.7.0 --> * `response` {http.IncomingMessage} -* `socket` {net.Socket} +* `socket` {stream.Duplex} * `head` {Buffer} Emitted each time a server responds to a request with a `CONNECT` method. If this event is not being listened for, clients receiving a `CONNECT` method will have their connections closed. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + A client and server pair demonstrating how to listen for the `'connect'` event: ```js @@ -471,9 +485,11 @@ once. added: v0.5.3 --> -* `socket` {net.Socket} +* `socket` {stream.Duplex} -Emitted after a socket is assigned to this request. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. ### Event: 'timeout' <!-- YAML @@ -491,7 +507,7 @@ added: v0.1.94 --> * `response` {http.IncomingMessage} -* `socket` {net.Socket} +* `socket` {stream.Duplex} * `head` {Buffer} Emitted each time a server responds to a request with an upgrade. If this @@ -499,6 +515,10 @@ event is not being listened for and the response status code is 101 Switching Protocols, clients receiving an upgrade header will have their connections closed. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + A client server pair demonstrating how to listen for the `'upgrade'` event. ```js @@ -572,7 +592,7 @@ deprecated: v13.0.0 > Stability: 0 - Deprecated. Use [`request.socket`][]. -* {net.Socket} +* {stream.Duplex} See [`request.socket`][]. @@ -800,7 +820,7 @@ Once a socket is assigned to this request and is connected added: v0.3.0 --> -* {net.Socket} +* {stream.Duplex} Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit `'readable'` events @@ -822,6 +842,10 @@ req.once('response', (res) => { }); ``` +This property is guaranteed to be an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specified a socket +type other than {net.Socket}. + ### request.writableEnded <!-- YAML added: v12.9.0 @@ -935,13 +959,17 @@ changes: --> * `exception` {Error} -* `socket` {net.Socket} +* `socket` {stream.Duplex} If a client connection emits an `'error'` event, it will be forwarded here. Listener of this event is responsible for closing/destroying the underlying socket. For example, one may wish to more gracefully close the socket with a custom HTTP response instead of abruptly severing the connection. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + Default behavior is to try close the socket with a HTTP '400 Bad Request', or a HTTP '431 Request Header Fields Too Large' in the case of a [`HPE_HEADER_OVERFLOW`][] error. If the socket is not writable it is @@ -986,13 +1014,17 @@ added: v0.7.0 * `request` {http.IncomingMessage} Arguments for the HTTP request, as it is in the [`'request'`][] event -* `socket` {net.Socket} Network socket between the server and client +* `socket` {stream.Duplex} Network socket between the server and client * `head` {Buffer} The first packet of the tunneling stream (may be empty) Emitted each time a client requests an HTTP `CONNECT` method. If this event is not listened for, then clients requesting a `CONNECT` method will have their connections closed. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + After this event is emitted, the request's socket will not have a `'data'` event listener, meaning it will need to be bound in order to handle data sent to the server on that socket. @@ -1002,7 +1034,7 @@ sent to the server on that socket. added: v0.1.0 --> -* `socket` {net.Socket} +* `socket` {stream.Duplex} This event is emitted when a new TCP stream is established. `socket` is typically an object of type [`net.Socket`][]. Usually users will not want to @@ -1017,6 +1049,10 @@ If `socket.setTimeout()` is called here, the timeout will be replaced with `server.keepAliveTimeout` when the socket has served a request (if `server.keepAliveTimeout` is non-zero). +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + ### Event: 'request' <!-- YAML added: v0.1.0 @@ -1040,7 +1076,7 @@ changes: * `request` {http.IncomingMessage} Arguments for the HTTP request, as it is in the [`'request'`][] event -* `socket` {net.Socket} Network socket between the server and client +* `socket` {stream.Duplex} Network socket between the server and client * `head` {Buffer} The first packet of the upgraded stream (may be empty) Emitted each time a client requests an HTTP upgrade. Listening to this event @@ -1050,6 +1086,10 @@ After this event is emitted, the request's socket will not have a `'data'` event listener, meaning it will need to be bound in order to handle data sent to the server on that socket. +This event is guaranteed to be passed an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specifies a socket +type other than {net.Socket}. + ### server.close(\[callback\]) <!-- YAML added: v0.1.90 @@ -1227,10 +1267,17 @@ deprecated: v13.0.0 > Stability: 0 - Deprecated. Use [`response.socket`][]. -* {net.Socket} +* {stream.Duplex} See [`response.socket`][]. +### response.cork() +<!-- YAML +added: v13.2.0 +--> + +See [`writable.cork()`][]. + ### response.end(\[data\[, encoding\]\]\[, callback\]) <!-- YAML added: v0.1.90 @@ -1462,7 +1509,7 @@ timed out sockets must be handled explicitly. added: v0.3.0 --> -* {net.Socket} +* {stream.Duplex} Reference to the underlying socket. Usually users will not want to access this property. In particular, the socket will not emit `'readable'` events @@ -1479,6 +1526,10 @@ const server = http.createServer((req, res) => { }).listen(3000); ``` +This property is guaranteed to be an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specified a socket +type other than {net.Socket}. + ### response.statusCode <!-- YAML added: v0.4.0 @@ -1516,6 +1567,13 @@ response.statusMessage = 'Not found'; After response header was sent to the client, this property indicates the status message which was sent out. +### response.uncork() +<!-- YAML +added: v13.2.0 +--> + +See [`writable.uncork()`][]. + ### response.writableEnded <!-- YAML added: v12.9.0 @@ -1854,13 +1912,17 @@ Calls `message.connection.setTimeout(msecs, callback)`. added: v0.3.0 --> -* {net.Socket} +* {stream.Duplex} The [`net.Socket`][] object associated with the connection. With HTTPS support, use [`request.socket.getPeerCertificate()`][] to obtain the client's authentication details. +This property is guaranteed to be an instance of the {net.Socket} class, +a subclass of {stream.Duplex}, unless the user specified a socket +type other than {net.Socket}. + ### message.statusCode <!-- YAML added: v0.1.1 @@ -2133,6 +2195,7 @@ changes: * `hostname` {string} Alias for `host`. To support [`url.parse()`][], `hostname` will be used if both `host` and `hostname` are specified. * `localAddress` {string} Local interface to bind for network connections. + * `lookup` {Function} Custom lookup function. **Default:** [`dns.lookup()`][]. * `method` {string} A string specifying the HTTP request method. **Default:** `'GET'`. * `path` {string} Request path. Should include query string if any. @@ -2312,6 +2375,7 @@ not abort the request or do anything besides add a `'timeout'` event. [`agent.createConnection()`]: #http_agent_createconnection_options_callback [`agent.getName()`]: #http_agent_getname_options [`destroy()`]: #http_agent_destroy +[`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback [`'finish'`]: #http_event_finish [`getHeader(name)`]: #http_request_getheader_name [`http.Agent`]: #http_class_http_agent @@ -2356,3 +2420,5 @@ not abort the request or do anything besides add a `'timeout'` event. [`socket.unref()`]: net.html#net_socket_unref [`url.parse()`]: url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost [`HPE_HEADER_OVERFLOW`]: errors.html#errors_hpe_header_overflow +[`writable.cork()`]: stream.html#stream_writable_cork +[`writable.uncork()`]: stream.html#stream_writable_uncork diff --git a/doc/api/https.md b/doc/api/https.md index 0d8f859e9c7517..01e07a24d8a3a9 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -45,6 +45,31 @@ changes: See [`Session Resumption`][] for information about TLS session reuse. +#### Event: 'keylog' +<!-- YAML +added: v13.2.0 +--> + +* `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format. +* `tlsSocket` {tls.TLSSocket} The `tls.TLSSocket` instance on which it was + generated. + +The `keylog` event is emitted when key material is generated or received by a +connection managed by this agent (typically before handshake has completed, but +not necessarily). This keying material can be stored for debugging, as it +allows captured TLS traffic to be decrypted. It may be emitted multiple times +for each socket. + +A typical use case is to append received lines to a common text file, which is +later used by software (such as Wireshark) to decrypt the traffic: + +```js +// ... +https.globalAgent.on('keylog', (line, tlsSocket) => { + fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 }); +}); +``` + ## Class: https.Server <!-- YAML added: v0.3.4 diff --git a/doc/api/modules.md b/doc/api/modules.md index 8715218b32c8a4..ff7191e462e8bb 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -232,12 +232,17 @@ RESOLVE_BARE_SPECIFIER(DIR, X) 2. If X matches this pattern and DIR/name/package.json is a file: a. Parse DIR/name/package.json, and look for "exports" field. b. If "exports" is null or undefined, GOTO 3. - c. Find the longest key in "exports" that the subpath starts with. - d. If no such key can be found, throw "not found". - e. let RESOLVED_URL = + c. If "exports" is an object with some keys starting with "." and some keys + not starting with ".", throw "invalid config". + d. If "exports" is a string, or object with no keys starting with ".", treat + it as having that value as its "." object property. + e. If subpath is "." and "exports" does not have a "." entry, GOTO 3. + f. Find the longest key in "exports" that the subpath starts with. + g. If no such key can be found, throw "not found". + h. let RESOLVED_URL = PACKAGE_EXPORTS_TARGET_RESOLVE(pathToFileURL(DIR/name), exports[key], - subpath.slice(key.length)), as defined in the esm resolver. - f. return fileURLToPath(RESOLVED_URL) + subpath.slice(key.length)), as defined in the ESM resolver. + i. return fileURLToPath(RESOLVED_URL) 3. return DIR/X ``` diff --git a/doc/api/n-api.md b/doc/api/n-api.md index e04283fdba968b..28ed048689e2ff 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -729,8 +729,8 @@ is provided which returns a `napi_extended_error_info` structure. The format of the `napi_extended_error_info` structure is as follows: <!-- YAML -added: v10.6.0 -napiVersion: 4 +added: v8.0.0 +napiVersion: 1 --> ```C @@ -1369,7 +1369,7 @@ napiVersion: 1 ```C NAPI_EXTERN napi_status napi_create_reference(napi_env env, napi_value value, - int initial_refcount, + uint32_t initial_refcount, napi_ref* result); ``` @@ -1412,7 +1412,7 @@ napiVersion: 1 ```C NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, - int* result); + uint32_t* result); ``` * `[in] env`: The environment that the API is invoked under. @@ -1433,7 +1433,7 @@ napiVersion: 1 ```C NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, - int* result); + uint32_t* result);); ``` * `[in] env`: The environment that the API is invoked under. @@ -1840,6 +1840,7 @@ structure, in most cases using a `TypedArray` will suffice. #### napi_create_date <!-- YAML added: v11.11.0 +napiVersion: 5 --> ```C @@ -2519,6 +2520,7 @@ This API returns various properties of a `DataView`. #### napi_get_date_value <!-- YAML added: v11.11.0 +napiVersion: 5 --> ```C @@ -3139,6 +3141,7 @@ This API checks if the `Object` passed in is a buffer. ### napi_is_date <!-- YAML added: v11.11.0 +napiVersion: 5 --> ```C @@ -3829,12 +3832,12 @@ napiVersion: 1 --> ```C -napi_status napi_call_function(napi_env env, - napi_value recv, - napi_value func, - int argc, - const napi_value* argv, - napi_value* result) +NAPI_EXTERN napi_status napi_call_function(napi_env env, + napi_value recv, + napi_value func, + size_t argc, + const napi_value* argv, + napi_value* result); ``` * `[in] env`: The environment that the API is invoked under. @@ -4299,6 +4302,7 @@ JavaScript object becomes garbage-collected. <!-- YAML added: v8.0.0 +napiVersion: 5 --> ```C @@ -4565,13 +4569,13 @@ changes: --> ```C -napi_status napi_make_callback(napi_env env, - napi_async_context async_context, - napi_value recv, - napi_value func, - int argc, - const napi_value* argv, - napi_value* result) +NAPI_EXTERN napi_status napi_make_callback(napi_env env, + napi_async_context async_context, + napi_value recv, + napi_value func, + size_t argc, + const napi_value* argv, + napi_value* result); ``` * `[in] env`: The environment that the API is invoked under. diff --git a/doc/api/process.md b/doc/api/process.md index 9fa2b786547e52..a9b5c4af09215b 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -119,6 +119,11 @@ the child process. The message goes through serialization and parsing. The resulting message might not be the same as what is originally sent. +If the `serialization` option was set to `advanced` used when spawning the +process, the `message` argument can contain data that JSON is not able +to represent. +See [Advanced Serialization for `child_process`][] for more details. + ### Event: 'multipleResolves' <!-- YAML added: v10.12.0 @@ -2456,6 +2461,7 @@ cases: [`require.resolve()`]: modules.html#modules_require_resolve_request_options [`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal [`v8.setFlagsFromString()`]: v8.html#v8_v8_setflagsfromstring_flags +[Advanced Serialization for `child_process`]: child_process.html#child_process_advanced_serialization [Android building]: https://github.com/nodejs/node/blob/master/BUILDING.md#androidandroid-based-devices-eg-firefox-os [Child Process]: child_process.html [Cluster]: cluster.html diff --git a/doc/api/stream.md b/doc/api/stream.md index 54521737704990..2143a84926c8db 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -505,6 +505,16 @@ Is `true` after [`writable.end()`][] has been called. This property does not indicate whether the data has been flushed, for this use [`writable.writableFinished`][] instead. +##### writable.writableCorked +<!-- YAML +added: v13.2.0 +--> + +* {integer} + +Number of times [`writable.uncork()`][stream-uncork] needs to be +called in order to fully uncork the stream. + ##### writable.writableFinished <!-- YAML added: v12.6.0 @@ -1084,6 +1094,8 @@ buffer will be returned. If the `size` argument is not specified, all of the data contained in the internal buffer will be returned. +The `size` argument must be less than or equal to 1 GB. + The `readable.read()` method should only be called on `Readable` streams operating in paused mode. In flowing mode, `readable.read()` is called automatically until the internal buffer is fully drained. @@ -2838,6 +2850,7 @@ contain multi-byte characters. [stream-push]: #stream_readable_push_chunk_encoding [stream-read]: #stream_readable_read_size [stream-resume]: #stream_readable_resume +[stream-uncork]: #stream_writable_uncork [stream-write]: #stream_writable_write_chunk_encoding_callback [Stream Three States]: #stream_three_states [writable-_destroy]: #stream_writable_destroy_err_callback diff --git a/doc/api/url.md b/doc/api/url.md index d50061abe1153e..80deff6f4b9984 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -1185,6 +1185,11 @@ The formatting process operates as follows: <!-- YAML added: v0.1.25 changes: + - version: v11.14.0 + pr-url: https://github.com/nodejs/node/pull/26941 + description: The `pathname` property on the returned URL object is now `/` + when there is no path and the protocol scheme is `ws:` or + `wss:`. - version: v11.0.0 pr-url: https://github.com/nodejs/node/pull/22715 description: The Legacy URL API is deprecated. Use the WHATWG URL API. diff --git a/doc/api/util.md b/doc/api/util.md index a38288d4585867..ac23f138ad0d17 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -862,6 +862,34 @@ will throw an error. If `original` is a function but its last argument is not an error-first callback, it will still be passed an error-first callback as its last argument. +Using `promisify()` on class methods or other methods that use `this` may not +work as expected unless handled specially: + +```js +const util = require('util'); + +class Foo { + constructor() { + this.a = 42; + } + + bar(callback) { + callback(null, this.a); + } +} + +const foo = new Foo(); + +const naiveBar = util.promisify(foo.bar); +// TypeError: Cannot read property 'a' of undefined +// naiveBar().then(a => console.log(a)); + +naiveBar.call(foo).then((a) => console.log(a)); // '42' + +const bindBar = naiveBar.bind(foo); +bindBar().then((a) => console.log(a)); // '42' +``` + ### Custom promisified functions Using the `util.promisify.custom` symbol one can override the return value of diff --git a/doc/api/v8.md b/doc/api/v8.md index 459df5597bc884..40b7c77d302971 100644 --- a/doc/api/v8.md +++ b/doc/api/v8.md @@ -266,8 +266,6 @@ if (isMainThread) { ## Serialization API -> Stability: 1 - Experimental - The serialization API provides means of serializing JavaScript values in a way that is compatible with the [HTML structured clone algorithm][]. The format is backward-compatible (i.e. safe to store to disk). diff --git a/doc/api/vm.md b/doc/api/vm.md index f1b993996f3173..7712ea78abce0c 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -88,8 +88,8 @@ changes: * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. - This option is part of the experimental API for the `--experimental-modules` - flag, and should not be considered stable. + This option is part of the experimental modules API, and should not be + considered stable. * `specifier` {string} specifier passed to `import()` * `module` {vm.Module} * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -854,8 +854,8 @@ changes: * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. - This option is part of the experimental API for the `--experimental-modules` - flag, and should not be considered stable. + This option is part of the experimental modules API, and should not be + considered stable. * `specifier` {string} specifier passed to `import()` * `module` {vm.Module} * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -951,8 +951,8 @@ changes: * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. - This option is part of the experimental API for the `--experimental-modules` - flag, and should not be considered stable. + This option is part of the experimental modules API, and should not be + considered stable. * `specifier` {string} specifier passed to `import()` * `module` {vm.Module} * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is @@ -1028,8 +1028,8 @@ changes: * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. - This option is part of the experimental API for the `--experimental-modules` - flag, and should not be considered stable. + This option is part of the experimental modules API, and should not be + considered stable. * `specifier` {string} specifier passed to `import()` * `module` {vm.Module} * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index b5b74996378410..af01ed7f7fba0b 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -157,6 +157,22 @@ console.log(receiveMessageOnPort(port2)); When this function is used, no `'message'` event will be emitted and the `onmessage` listener will not be invoked. +### worker.resourceLimits +<!-- YAML +added: v13.2.0 +--> + +* {Object|undefined} + * `maxYoungGenerationSizeMb` {number} + * `maxOldGenerationSizeMb` {number} + * `codeRangeSizeMb` {number} + +Provides the set of JS engine resource constraints inside this Worker thread. +If the `resourceLimits` option was passed to the [`Worker`][] constructor, +this matches its values. + +If this is used in the main thread, its value is an empty object. + ## worker.SHARE_ENV <!-- YAML added: v11.14.0 @@ -488,6 +504,13 @@ if (isMainThread) { ``` ### new Worker(filename\[, options\]) +<!-- YAML +added: v10.5.0 +changes: + - version: v13.2.0 + pr-url: https://github.com/nodejs/node/pull/26628 + description: The `resourceLimits` option was introduced. +--> * `filename` {string} The path to the Worker’s main script. Must be either an absolute path or a relative path (i.e. relative to the @@ -519,6 +542,16 @@ if (isMainThread) { occur as described in the [HTML structured clone algorithm][], and an error will be thrown if the object cannot be cloned (e.g. because it contains `function`s). + * `resourceLimits` {Object} An optional set of resource limits for the new + JS engine instance. Reaching these limits will lead to termination of the + `Worker` instance. These limits only affect the JS engine, and no external + data, including no `ArrayBuffer`s. Even if these limits are set, the process + may still abort if it encounters a global out-of-memory situation. + * `maxOldGenerationSizeMb` {number} The maximum size of the main heap in MB. + * `maxYoungGenerationSizeMb` {number} The maximum size of a heap space for + recently created objects. + * `codeRangeSizeMb` {number} The size of a pre-allocated memory range + used for generated code. ### Event: 'error' <!-- YAML @@ -583,6 +616,22 @@ Opposite of `unref()`, calling `ref()` on a previously `unref()`ed worker will behavior). If the worker is `ref()`ed, calling `ref()` again will have no effect. +### worker.resourceLimits +<!-- YAML +added: v13.2.0 +--> + +* {Object} + * `maxYoungGenerationSizeMb` {number} + * `maxOldGenerationSizeMb` {number} + * `codeRangeSizeMb` {number} + +Provides the set of JS engine resource constraints for this Worker thread. +If the `resourceLimits` option was passed to the [`Worker`][] constructor, +this matches its values. + +If the worker has stopped, the return value is an empty object. + ### worker.stderr <!-- YAML added: v10.5.0 diff --git a/doc/changelogs/CHANGELOG_V13.md b/doc/changelogs/CHANGELOG_V13.md index 74b7294bee8c78..ec3a37fbc2d380 100644 --- a/doc/changelogs/CHANGELOG_V13.md +++ b/doc/changelogs/CHANGELOG_V13.md @@ -9,6 +9,7 @@ </tr> <tr> <td> +<a href="#13.2.0">13.2.0</a><br/> <a href="#13.1.0">13.1.0</a><br/> <a href="#13.0.1">13.0.1</a><br/> <a href="#13.0.0">13.0.0</a><br/> @@ -31,6 +32,208 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) +<a id="13.2.0"></a> +## 2019-21-19, Version 13.2.0 (Current), @MylesBorins + +### Notable Changes + +* **addons**: + * Deprecate one- and two-argument `AtExit()`. Use the three-argument variant of `AtExit()` or `AddEnvironmentCleanupHook()` instead (Anna Henningsen) [#30227](https://github.com/nodejs/node/pull/30227) +* **child_process,cluster**: + * The `serialization` option is added that allows child process IPC to use the V8 serialization API (to e.g., pass through data types like sets or maps) (Anna Henningsen) [#30162](https://github.com/nodejs/node/pull/30162) +* **deps**: + * Update V8 to 7.9 + * Update `npm` to 6.13.1 (Ruy Adorno) [#30271](https://github.com/nodejs/node/pull/30271) +* **embedder**: + * Exposes the ability to pass cli flags / options through an API as embedder (Shelley Vohr) [#30466](https://github.com/nodejs/node/pull/30466) + * Allow adding linked bindings to Environment (Anna Henningsen) [#30274](https://github.com/nodejs/node/pull/30274) +* **esm**: + * Unflag `--experimental-modules` (Guy Bedford) [#29866](https://github.com/nodejs/node/pull/29866) +* **stream**: + * Add `writable.writableCorked` property (Robert Nagy) [#29012](https://github.com/nodejs/node/pull/29012) +* **worker**: + * Allow specifying resource limits (Anna Henningsen) [#26628](https://github.com/nodejs/node/pull/26628) +* **v8**: + * The Serialization API is now stable (Anna Henningsen) [#30234](https://github.com/nodejs/node/pull/30234) + +### Commits + +* [[`b76c13ec86`](https://github.com/nodejs/node/commit/b76c13ec86)] - **assert**: replace var with let in lib/assert.js (PerfectPan) [#30261](https://github.com/nodejs/node/pull/30261) +* [[`7f49816e8a`](https://github.com/nodejs/node/commit/7f49816e8a)] - **benchmark**: use let instead of var in async\_hooks (dnlup) [#30470](https://github.com/nodejs/node/pull/30470) +* [[`0130d2b6e0`](https://github.com/nodejs/node/commit/0130d2b6e0)] - **benchmark**: use let instead of var in assert (dnlup) [#30450](https://github.com/nodejs/node/pull/30450) +* [[`9cae205f4d`](https://github.com/nodejs/node/commit/9cae205f4d)] - **buffer**: change var to let (Vladislav Botvin) [#30292](https://github.com/nodejs/node/pull/30292) +* [[`b5198cd3b0`](https://github.com/nodejs/node/commit/b5198cd3b0)] - **(SEMVER-MINOR)** **build**: reset embedder string to "-node.0" (Michaël Zasso) [#30513](https://github.com/nodejs/node/pull/30513) +* [[`f4f210adc1`](https://github.com/nodejs/node/commit/f4f210adc1)] - **build**: store cache on timed out builds on Travis (Richard Lau) [#30469](https://github.com/nodejs/node/pull/30469) +* [[`277e5fadf8`](https://github.com/nodejs/node/commit/277e5fadf8)] - **(SEMVER-MINOR)** **build,tools**: update V8 gypfiles for V8 7.9 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`e51beef8d4`](https://github.com/nodejs/node/commit/e51beef8d4)] - **(SEMVER-MINOR)** **child_process,cluster**: allow using V8 serialization API (Anna Henningsen) [#30162](https://github.com/nodejs/node/pull/30162) +* [[`6bf0e40bad`](https://github.com/nodejs/node/commit/6bf0e40bad)] - **cluster**: destruct primordials in lib/internal/cluster/worker.js (peze) [#30246](https://github.com/nodejs/node/pull/30246) +* [[`18ec8a84be`](https://github.com/nodejs/node/commit/18ec8a84be)] - **(SEMVER-MINOR)** **crypto**: add support for IEEE-P1363 DSA signatures (Tobias Nießen) [#29292](https://github.com/nodejs/node/pull/29292) +* [[`39d0a25ddd`](https://github.com/nodejs/node/commit/39d0a25ddd)] - **crypto**: fix key requirements in asymmetric cipher (Tobias Nießen) [#30249](https://github.com/nodejs/node/pull/30249) +* [[`8c2e2ce6bf`](https://github.com/nodejs/node/commit/8c2e2ce6bf)] - **crypto**: update root certificates (AshCripps) [#30195](https://github.com/nodejs/node/pull/30195) +* [[`4f282f52f0`](https://github.com/nodejs/node/commit/4f282f52f0)] - **deps**: patch V8 to 7.9.317.23 (Myles Borins) [#30560](https://github.com/nodejs/node/pull/30560) +* [[`9b71534d23`](https://github.com/nodejs/node/commit/9b71534d23)] - **deps**: upgrade npm to 6.13.1 (claudiahdz) [#30533](https://github.com/nodejs/node/pull/30533) +* [[`f17c794faf`](https://github.com/nodejs/node/commit/f17c794faf)] - **(SEMVER-MINOR)** **deps**: patch V8 to be API/ABI compatible with 7.8 (from 7.9) (Michaël Zasso) [#30513](https://github.com/nodejs/node/pull/30513) +* [[`5a1ad570ea`](https://github.com/nodejs/node/commit/5a1ad570ea)] - **deps**: V8: cherry-pick a7dffcd767be (Christian Clauss) [#30218](https://github.com/nodejs/node/pull/30218) +* [[`2c6cf902b0`](https://github.com/nodejs/node/commit/2c6cf902b0)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 50031fae736f (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`1e5e8c3922`](https://github.com/nodejs/node/commit/1e5e8c3922)] - **deps**: V8: cherry-pick e5dbc95 (Gabriel Schulhof) [#30130](https://github.com/nodejs/node/pull/30130) +* [[`9c356ba91c`](https://github.com/nodejs/node/commit/9c356ba91c)] - **(SEMVER-MINOR)** **deps**: V8: backport 5e755c6ee6d3 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`fe99841c88`](https://github.com/nodejs/node/commit/fe99841c88)] - **(SEMVER-MINOR)** **deps**: V8: backport 07ee86a5a28b (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`5131bbe477`](https://github.com/nodejs/node/commit/5131bbe477)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 777fa98 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`824e8b6f9b`](https://github.com/nodejs/node/commit/824e8b6f9b)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 7228ef8 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`4c7acc256a`](https://github.com/nodejs/node/commit/4c7acc256a)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 6b0a953 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`ebef1b2308`](https://github.com/nodejs/node/commit/ebef1b2308)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick bba5f1f (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`28ca44c724`](https://github.com/nodejs/node/commit/28ca44c724)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick cfe9172 (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`ba4abfd198`](https://github.com/nodejs/node/commit/ba4abfd198)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 3e82c8d (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`2abdcbbe5e`](https://github.com/nodejs/node/commit/2abdcbbe5e)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick f2d92ec (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`46383616e3`](https://github.com/nodejs/node/commit/46383616e3)] - **(SEMVER-MINOR)** **deps**: make v8.h compatible with VS2015 (Joao Reis) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`5bc35732aa`](https://github.com/nodejs/node/commit/5bc35732aa)] - **(SEMVER-MINOR)** **deps**: V8: forward declaration of `Rtl\*FunctionTable` (Refael Ackermann) [#27375](https://github.com/nodejs/node/pull/27375) +* [[`627a804627`](https://github.com/nodejs/node/commit/627a804627)] - **(SEMVER-MINOR)** **deps**: V8: patch register-arm64.h (Refael Ackermann) [#27375](https://github.com/nodejs/node/pull/27375) +* [[`13e6b0b82a`](https://github.com/nodejs/node/commit/13e6b0b82a)] - **(SEMVER-MINOR)** **deps**: update V8's postmortem script (Colin Ihrig) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`a4a6565348`](https://github.com/nodejs/node/commit/a4a6565348)] - **(SEMVER-MINOR)** **deps**: update V8's postmortem script (Colin Ihrig) [#29694](https://github.com/nodejs/node/pull/29694) +* [[`4182e3bad7`](https://github.com/nodejs/node/commit/4182e3bad7)] - **(SEMVER-MINOR)** **deps**: patch V8 to run on older XCode versions (Ujjwal Sharma) [#29694](https://github.com/nodejs/node/pull/29694) +* [[`6566c15157`](https://github.com/nodejs/node/commit/6566c15157)] - **(SEMVER-MINOR)** **deps**: V8: silence irrelevant warnings (Michaël Zasso) [#26685](https://github.com/nodejs/node/pull/26685) +* [[`6018db2ef9`](https://github.com/nodejs/node/commit/6018db2ef9)] - **(SEMVER-MINOR)** **deps**: V8: un-cherry-pick bd019bd (Refael Ackermann) [#26685](https://github.com/nodejs/node/pull/26685) +* [[`605cb9f0fc`](https://github.com/nodejs/node/commit/605cb9f0fc)] - **(SEMVER-MINOR)** **deps**: update V8 to 7.9.317.22 (Michaël Zasso) [#30513](https://github.com/nodejs/node/pull/30513) +* [[`b82f63d9ca`](https://github.com/nodejs/node/commit/b82f63d9ca)] - **deps**: update nghttp2 to 1.40.0 (gengjiawen) [#30493](https://github.com/nodejs/node/pull/30493) +* [[`401d2e9115`](https://github.com/nodejs/node/commit/401d2e9115)] - **deps**: update npm to 6.13.0 (Ruy Adorno) [#30271](https://github.com/nodejs/node/pull/30271) +* [[`f8ee70c94d`](https://github.com/nodejs/node/commit/f8ee70c94d)] - **dgram**: remove listeners on bind error (Anna Henningsen) [#30210](https://github.com/nodejs/node/pull/30210) +* [[`0433d7995a`](https://github.com/nodejs/node/commit/0433d7995a)] - **dgram**: reset bind state before emitting error (Anna Henningsen) [#30210](https://github.com/nodejs/node/pull/30210) +* [[`0f8662d615`](https://github.com/nodejs/node/commit/0f8662d615)] - **dns**: switch var to const/let (Dmitriy Kikinskiy) [#30302](https://github.com/nodejs/node/pull/30302) +* [[`ab887bd5f6`](https://github.com/nodejs/node/commit/ab887bd5f6)] - **doc**: add mention for using promisify on class methods (Denys Otrishko) [#30355](https://github.com/nodejs/node/pull/30355) +* [[`9940116aba`](https://github.com/nodejs/node/commit/9940116aba)] - **doc**: explain GIT\_REMOTE\_REF in COLLABORATOR\_GUIDE (Denys Otrishko) [#30371](https://github.com/nodejs/node/pull/30371) +* [[`027bde563d`](https://github.com/nodejs/node/commit/027bde563d)] - **doc**: fix overriding of prefix option (Luigi Pinca) [#30518](https://github.com/nodejs/node/pull/30518) +* [[`b7757533bc`](https://github.com/nodejs/node/commit/b7757533bc)] - **doc**: update http.md mention of socket (Jesse O'Connor) [#30155](https://github.com/nodejs/node/pull/30155) +* [[`7f664e454b`](https://github.com/nodejs/node/commit/7f664e454b)] - **doc**: adds NO\_COLOR to assert doc page (Shobhit Chittora) [#30483](https://github.com/nodejs/node/pull/30483) +* [[`fba2f9a3d6`](https://github.com/nodejs/node/commit/fba2f9a3d6)] - **doc**: document timed out Travis CI builds (Richard Lau) [#30469](https://github.com/nodejs/node/pull/30469) +* [[`c40e242b32`](https://github.com/nodejs/node/commit/c40e242b32)] - **doc**: replace const / var with let (Duncan Healy) [#30446](https://github.com/nodejs/node/pull/30446) +* [[`a93345b7cd`](https://github.com/nodejs/node/commit/a93345b7cd)] - **doc**: update outdated commonjs compat info (Geoffrey Booth) [#30512](https://github.com/nodejs/node/pull/30512) +* [[`b590533253`](https://github.com/nodejs/node/commit/b590533253)] - **doc**: esm: improve dual package hazard docs (Geoffrey Booth) [#30345](https://github.com/nodejs/node/pull/30345) +* [[`d631a0a3e4`](https://github.com/nodejs/node/commit/d631a0a3e4)] - **doc**: update 8.x to 10.x in backporting guide (garygsc) [#30481](https://github.com/nodejs/node/pull/30481) +* [[`7e603bed52`](https://github.com/nodejs/node/commit/7e603bed52)] - **doc**: createRequire can take import.meta.url directly (Geoffrey Booth) [#30495](https://github.com/nodejs/node/pull/30495) +* [[`e4a296ce8d`](https://github.com/nodejs/node/commit/e4a296ce8d)] - **doc**: add entry to url.parse() changes metadata (Luigi Pinca) [#30348](https://github.com/nodejs/node/pull/30348) +* [[`64cf00b0b9`](https://github.com/nodejs/node/commit/64cf00b0b9)] - **doc**: simplify text in pull-requests.md (Rich Trott) [#30458](https://github.com/nodejs/node/pull/30458) +* [[`1e2672012f`](https://github.com/nodejs/node/commit/1e2672012f)] - **doc**: remove "multiple variants" from BUILDING.md (Rich Trott) [#30366](https://github.com/nodejs/node/pull/30366) +* [[`2d16a74ff9`](https://github.com/nodejs/node/commit/2d16a74ff9)] - **doc**: remove "maintenance is supported by" text in BUILDING.md (Rich Trott) [#30365](https://github.com/nodejs/node/pull/30365) +* [[`c832565290`](https://github.com/nodejs/node/commit/c832565290)] - **doc**: add lookup to http.request() options (Luigi Pinca) [#30353](https://github.com/nodejs/node/pull/30353) +* [[`b8afe57e85`](https://github.com/nodejs/node/commit/b8afe57e85)] - **doc**: fix up N-API doc (Michael Dawson) [#30254](https://github.com/nodejs/node/pull/30254) +* [[`b558d941bd`](https://github.com/nodejs/node/commit/b558d941bd)] - **doc**: fix some recent doc nits (vsemozhetbyt) [#30341](https://github.com/nodejs/node/pull/30341) +* [[`1133981eac`](https://github.com/nodejs/node/commit/1133981eac)] - **doc**: add link to node-code-ide-configs in testing (Trivikram Kamat) [#24012](https://github.com/nodejs/node/pull/24012) +* [[`041f3a306e`](https://github.com/nodejs/node/commit/041f3a306e)] - **doc**: update divergent specifier hazard guidance (Geoffrey Booth) [#30051](https://github.com/nodejs/node/pull/30051) +* [[`085af30361`](https://github.com/nodejs/node/commit/085af30361)] - **doc**: include --experimental-resolve-self in manpage (Guy Bedford) [#29978](https://github.com/nodejs/node/pull/29978) +* [[`31a3b724f0`](https://github.com/nodejs/node/commit/31a3b724f0)] - **doc**: update GOVERNANCE.md (Rich Trott) [#30259](https://github.com/nodejs/node/pull/30259) +* [[`15a7032d44`](https://github.com/nodejs/node/commit/15a7032d44)] - **doc**: move inactive Collaborators to emeriti (Rich Trott) [#30243](https://github.com/nodejs/node/pull/30243) +* [[`fabc489dba`](https://github.com/nodejs/node/commit/fabc489dba)] - **doc**: update examples in writing-tests.md (garygsc) [#30126](https://github.com/nodejs/node/pull/30126) +* [[`1836eae7a6`](https://github.com/nodejs/node/commit/1836eae7a6)] - **doc, console**: remove non-existant methods from docs (Simon Schick) [#30346](https://github.com/nodejs/node/pull/30346) +* [[`7ad2e024dd`](https://github.com/nodejs/node/commit/7ad2e024dd)] - **doc,meta**: allow Travis results for doc/comment changes (Rich Trott) [#30330](https://github.com/nodejs/node/pull/30330) +* [[`2deea28070`](https://github.com/nodejs/node/commit/2deea28070)] - **doc,meta**: remove wait period for npm pull requests (Rich Trott) [#30329](https://github.com/nodejs/node/pull/30329) +* [[`7e0f90e286`](https://github.com/nodejs/node/commit/7e0f90e286)] - **domain**: rename var to let and const (Maria Stogova) [#30312](https://github.com/nodejs/node/pull/30312) +* [[`c2c74fc93e`](https://github.com/nodejs/node/commit/c2c74fc93e)] - **encoding**: make TextDecoder handle BOM correctly (Anna Henningsen) [#30132](https://github.com/nodejs/node/pull/30132) +* [[`f9eab48dd0`](https://github.com/nodejs/node/commit/f9eab48dd0)] - **esm**: disable non-js exts outside package scopes (Guy Bedford) [#30501](https://github.com/nodejs/node/pull/30501) +* [[`3d8cdf191d`](https://github.com/nodejs/node/commit/3d8cdf191d)] - **esm**: unflag --experimental-modules (Guy Bedford) [#29866](https://github.com/nodejs/node/pull/29866) +* [[`293e8a2384`](https://github.com/nodejs/node/commit/293e8a2384)] - **esm**: exit the process with an error if loader has an issue (Michaël Zasso) [#30219](https://github.com/nodejs/node/pull/30219) +* [[`45fd44c6ec`](https://github.com/nodejs/node/commit/45fd44c6ec)] - **fs**: change var to let (Nadya) [#30318](https://github.com/nodejs/node/pull/30318) +* [[`bb6f944607`](https://github.com/nodejs/node/commit/bb6f944607)] - **fs**: add noop stub for FSWatcher.prototype.start (Lucas Holmquist) [#30160](https://github.com/nodejs/node/pull/30160) +* [[`4fe62c1620`](https://github.com/nodejs/node/commit/4fe62c1620)] - **http**: revise \_http\_server.js (telenord) [#30279](https://github.com/nodejs/node/pull/30279) +* [[`62e15a793a`](https://github.com/nodejs/node/commit/62e15a793a)] - **http**: outgoing cork (Robert Nagy) [#29053](https://github.com/nodejs/node/pull/29053) +* [[`50f9476a44`](https://github.com/nodejs/node/commit/50f9476a44)] - **http**: http\_common rename var to let and const (telenord) [#30288](https://github.com/nodejs/node/pull/30288) +* [[`b8aceace95`](https://github.com/nodejs/node/commit/b8aceace95)] - **http**: http\_incoming rename var to let and const (telenord) [#30285](https://github.com/nodejs/node/pull/30285) +* [[`a37ade8648`](https://github.com/nodejs/node/commit/a37ade8648)] - **http**: replace vars with lets and consts in lib/\_http\_agent.js (palmires) [#30301](https://github.com/nodejs/node/pull/30301) +* [[`e59cc8aad8`](https://github.com/nodejs/node/commit/e59cc8aad8)] - **http,async_hooks**: keep resource object alive from socket (Anna Henningsen) [#30196](https://github.com/nodejs/node/pull/30196) +* [[`1b84175924`](https://github.com/nodejs/node/commit/1b84175924)] - **http2**: remove duplicated assertIsObject (Yongsheng Zhang) [#30541](https://github.com/nodejs/node/pull/30541) +* [[`666588143e`](https://github.com/nodejs/node/commit/666588143e)] - **http2**: use custom BaseObject smart pointers (Anna Henningsen) [#30374](https://github.com/nodejs/node/pull/30374) +* [[`f25b00aaca`](https://github.com/nodejs/node/commit/f25b00aaca)] - **(SEMVER-MINOR)** **https**: add client support for TLS keylog events (Sam Roberts) [#30053](https://github.com/nodejs/node/pull/30053) +* [[`88da3af6f6`](https://github.com/nodejs/node/commit/88da3af6f6)] - **https**: change var to let in lib/https.js (galina.prokofeva) [#30320](https://github.com/nodejs/node/pull/30320) +* [[`f15a3b0281`](https://github.com/nodejs/node/commit/f15a3b0281)] - **lib**: replace var with let (David OLIVIER) [#30381](https://github.com/nodejs/node/pull/30381) +* [[`31a63ab1ec`](https://github.com/nodejs/node/commit/31a63ab1ec)] - **lib**: replace var with let and const in readline.js (VinceOPS) [#30377](https://github.com/nodejs/node/pull/30377) +* [[`3eeeea419d`](https://github.com/nodejs/node/commit/3eeeea419d)] - **lib**: change var to let/const in internal/querystring.js (Artem Maksimov) [#30286](https://github.com/nodejs/node/pull/30286) +* [[`f10608655b`](https://github.com/nodejs/node/commit/f10608655b)] - **lib**: change var to let in internal/streams (Kyriakos Markakis) [#30430](https://github.com/nodejs/node/pull/30430) +* [[`3ce6e15844`](https://github.com/nodejs/node/commit/3ce6e15844)] - **lib**: replace var with let/const (Kenza Houmani) [#30440](https://github.com/nodejs/node/pull/30440) +* [[`d37d340472`](https://github.com/nodejs/node/commit/d37d340472)] - **lib**: change var to let in string\_decoder (mkdorff) [#30393](https://github.com/nodejs/node/pull/30393) +* [[`9a1c16eda4`](https://github.com/nodejs/node/commit/9a1c16eda4)] - **lib**: replaced var to let in lib/v8.js (Vadim Gorbachev) [#30305](https://github.com/nodejs/node/pull/30305) +* [[`3e4a6a5968`](https://github.com/nodejs/node/commit/3e4a6a5968)] - **lib**: change var to let in lib/\_stream\_duplex.js (Ilia Safronov) [#30297](https://github.com/nodejs/node/pull/30297) +* [[`c7c566023f`](https://github.com/nodejs/node/commit/c7c566023f)] - **module**: reduce circular dependency of internal/modules/cjs/loader (Joyee Cheung) [#30349](https://github.com/nodejs/node/pull/30349) +* [[`e98d89cef9`](https://github.com/nodejs/node/commit/e98d89cef9)] - **module**: conditional exports with flagged conditions (Guy Bedford) [#29978](https://github.com/nodejs/node/pull/29978) +* [[`caedcd9ef9`](https://github.com/nodejs/node/commit/caedcd9ef9)] - **module**: fix for empty object in InternalModuleReadJSON (Guy Bedford) [#30256](https://github.com/nodejs/node/pull/30256) +* [[`66e1adf200`](https://github.com/nodejs/node/commit/66e1adf200)] - **net**: destructure primordials (Guilherme Goncalves) [#30447](https://github.com/nodejs/node/pull/30447) +* [[`9230ffffd0`](https://github.com/nodejs/node/commit/9230ffffd0)] - **net**: replaced vars to lets and consts (alexahdp) [#30287](https://github.com/nodejs/node/pull/30287) +* [[`9248c8b960`](https://github.com/nodejs/node/commit/9248c8b960)] - **path**: replace var with let in lib/path.js (peze) [#30260](https://github.com/nodejs/node/pull/30260) +* [[`e363f8e17f`](https://github.com/nodejs/node/commit/e363f8e17f)] - **process**: add coverage tests for sourceMapFromDataUrl method (Nolik) [#30319](https://github.com/nodejs/node/pull/30319) +* [[`7b4187413e`](https://github.com/nodejs/node/commit/7b4187413e)] - **process**: make source map getter resistant against prototype tampering (Anna Henningsen) [#30228](https://github.com/nodejs/node/pull/30228) +* [[`183464a24d`](https://github.com/nodejs/node/commit/183464a24d)] - **querystring**: replace var with let/const (Raoul Jaeckel) [#30429](https://github.com/nodejs/node/pull/30429) +* [[`7188b9599d`](https://github.com/nodejs/node/commit/7188b9599d)] - **src**: fix -Winconsistent-missing-override warning (Colin Ihrig) [#30549](https://github.com/nodejs/node/pull/30549) +* [[`966404fd24`](https://github.com/nodejs/node/commit/966404fd24)] - **src**: add file name to 'Module did not self-register' error (Jeremy Apthorp) [#30125](https://github.com/nodejs/node/pull/30125) +* [[`21dd6019ec`](https://github.com/nodejs/node/commit/21dd6019ec)] - **(SEMVER-MINOR)** **src**: expose ArrayBuffer version of Buffer::New() (Anna Henningsen) [#30476](https://github.com/nodejs/node/pull/30476) +* [[`2e43686c5a`](https://github.com/nodejs/node/commit/2e43686c5a)] - **src**: mark ArrayBuffers with free callbacks as untransferable (Anna Henningsen) [#30475](https://github.com/nodejs/node/pull/30475) +* [[`564c18e214`](https://github.com/nodejs/node/commit/564c18e214)] - **src**: remove HandleWrap instances from list once closed (Anna Henningsen) [#30374](https://github.com/nodejs/node/pull/30374) +* [[`4222f2400a`](https://github.com/nodejs/node/commit/4222f2400a)] - **src**: remove keep alive option from SetImmediate() (Anna Henningsen) [#30374](https://github.com/nodejs/node/pull/30374) +* [[`940a2972b2`](https://github.com/nodejs/node/commit/940a2972b2)] - **src**: use BaseObjectPtr for keeping channel alive in dns bindings (Anna Henningsen) [#30374](https://github.com/nodejs/node/pull/30374) +* [[`a2dbadc1ce`](https://github.com/nodejs/node/commit/a2dbadc1ce)] - **src**: introduce custom smart pointers for `BaseObject`s (Anna Henningsen) [#30374](https://github.com/nodejs/node/pull/30374) +* [[`1a92c88418`](https://github.com/nodejs/node/commit/1a92c88418)] - **src**: migrate off ArrayBuffer::GetContents (Anna Henningsen) [#30339](https://github.com/nodejs/node/pull/30339) +* [[`0d5de1a20e`](https://github.com/nodejs/node/commit/0d5de1a20e)] - **(SEMVER-MINOR)** **src**: remove custom tracking for SharedArrayBuffers (Anna Henningsen) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`f0ff2ed9d5`](https://github.com/nodejs/node/commit/f0ff2ed9d5)] - **(SEMVER-MINOR)** **src**: update v8abbr.h for V8 update (Colin Ihrig) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`2c8276eda8`](https://github.com/nodejs/node/commit/2c8276eda8)] - **(SEMVER-MINOR)** **src**: expose ability to set options (Shelley Vohr) [#30466](https://github.com/nodejs/node/pull/30466) +* [[`592d51cb23`](https://github.com/nodejs/node/commit/592d51cb23)] - **src**: enhance feature access `CHECK`s during bootstrap (Anna Henningsen) [#30452](https://github.com/nodejs/node/pull/30452) +* [[`d648c933b5`](https://github.com/nodejs/node/commit/d648c933b5)] - **src**: lib/internal/timers.js var -\> let/const (Nikolay Krashnikov) [#30314](https://github.com/nodejs/node/pull/30314) +* [[`70ad676023`](https://github.com/nodejs/node/commit/70ad676023)] - **src**: persist strings that are used multiple times in the environment (Vadim Gorbachev) [#30321](https://github.com/nodejs/node/pull/30321) +* [[`b744070d74`](https://github.com/nodejs/node/commit/b744070d74)] - **(SEMVER-MINOR)** **src**: allow adding linked bindings to Environment (Anna Henningsen) [#30274](https://github.com/nodejs/node/pull/30274) +* [[`058a8d5363`](https://github.com/nodejs/node/commit/058a8d5363)] - **src**: do not use `std::function` for `OnScopeLeave` (Anna Henningsen) [#30134](https://github.com/nodejs/node/pull/30134) +* [[`906d279e69`](https://github.com/nodejs/node/commit/906d279e69)] - **src**: run RunBeforeExitCallbacks as part of EmitBeforeExit (Anna Henningsen) [#30229](https://github.com/nodejs/node/pull/30229) +* [[`66b3619b4e`](https://github.com/nodejs/node/commit/66b3619b4e)] - **src**: use unique\_ptr for InitializeInspector() (Anna Henningsen) [#30229](https://github.com/nodejs/node/pull/30229) +* [[`db7deb6e7a`](https://github.com/nodejs/node/commit/db7deb6e7a)] - **src**: make WaitForInspectorDisconnect an exit hook (Anna Henningsen) [#30229](https://github.com/nodejs/node/pull/30229) +* [[`cd233e3f16`](https://github.com/nodejs/node/commit/cd233e3f16)] - **src**: make EndStartedProfilers an exit hook (Anna Henningsen) [#30229](https://github.com/nodejs/node/pull/30229) +* [[`8234d04b56`](https://github.com/nodejs/node/commit/8234d04b56)] - **src**: track no of active JS signal handlers (Anna Henningsen) [#30229](https://github.com/nodejs/node/pull/30229) +* [[`0072a8eddf`](https://github.com/nodejs/node/commit/0072a8eddf)] - **src**: remove AsyncScope and AsyncCallbackScope (Anna Henningsen) [#30236](https://github.com/nodejs/node/pull/30236) +* [[`e3371f0c93`](https://github.com/nodejs/node/commit/e3371f0c93)] - **src**: use callback scope for main script (Anna Henningsen) [#30236](https://github.com/nodejs/node/pull/30236) +* [[`cd6d6215cc`](https://github.com/nodejs/node/commit/cd6d6215cc)] - **(SEMVER-MINOR)** **src**: deprecate two- and one-argument AtExit() (Anna Henningsen) [#30227](https://github.com/nodejs/node/pull/30227) +* [[`5f4535a97c`](https://github.com/nodejs/node/commit/5f4535a97c)] - **src**: make AtExit() callbacks run in reverse order (Anna Henningsen) [#30230](https://github.com/nodejs/node/pull/30230) +* [[`44968f0edc`](https://github.com/nodejs/node/commit/44968f0edc)] - **src**: remove unimplemented method from node.h (Anna Henningsen) [#30098](https://github.com/nodejs/node/pull/30098) +* [[`4524c7ad36`](https://github.com/nodejs/node/commit/4524c7ad36)] - **stream**: replace var with let (daern91) [#30379](https://github.com/nodejs/node/pull/30379) +* [[`41720d78c9`](https://github.com/nodejs/node/commit/41720d78c9)] - **stream**: add writableCorked to Duplex (Anna Henningsen) [#29053](https://github.com/nodejs/node/pull/29053) +* [[`7cbdac9a71`](https://github.com/nodejs/node/commit/7cbdac9a71)] - **stream**: increase MAX\_HWM (Robert Nagy) [#29938](https://github.com/nodejs/node/pull/29938) +* [[`c254d7469d`](https://github.com/nodejs/node/commit/c254d7469d)] - **(SEMVER-MINOR)** **stream**: add writableCorked property (Robert Nagy) [#29012](https://github.com/nodejs/node/pull/29012) +* [[`cb9c64a6e0`](https://github.com/nodejs/node/commit/cb9c64a6e0)] - **test**: move test not requiring internet from internet to parallel (Rich Trott) [#30545](https://github.com/nodejs/node/pull/30545) +* [[`902c6702df`](https://github.com/nodejs/node/commit/902c6702df)] - **test**: use reserved .invalid TLD for invalid address in test (Rich Trott) [#30545](https://github.com/nodejs/node/pull/30545) +* [[`92f766bd83`](https://github.com/nodejs/node/commit/92f766bd83)] - **test**: improve assertion message in internet dgram test (Rich Trott) [#30545](https://github.com/nodejs/node/pull/30545) +* [[`a5f25ecf07`](https://github.com/nodejs/node/commit/a5f25ecf07)] - **test**: cover 'close' method in Dir class (Artem Maksimov) [#30310](https://github.com/nodejs/node/pull/30310) +* [[`45e57303f3`](https://github.com/nodejs/node/commit/45e57303f3)] - **test**: add test for options validation of createServer (Yongsheng Zhang) [#30541](https://github.com/nodejs/node/pull/30541) +* [[`6be03981b2`](https://github.com/nodejs/node/commit/6be03981b2)] - **test**: clean up http-set-trailers (Denys Otrishko) [#30522](https://github.com/nodejs/node/pull/30522) +* [[`2952c5d72b`](https://github.com/nodejs/node/commit/2952c5d72b)] - **(SEMVER-MINOR)** **test**: increase limit again for network space overhead test (Michaël Zasso) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`4131b14011`](https://github.com/nodejs/node/commit/4131b14011)] - **(SEMVER-MINOR)** **test**: update test-postmortem-metadata.js (Colin Ihrig) [#30020](https://github.com/nodejs/node/pull/30020) +* [[`c464ede598`](https://github.com/nodejs/node/commit/c464ede598)] - **test**: handle undefined default\_configuration (Shelley Vohr) [#30465](https://github.com/nodejs/node/pull/30465) +* [[`5ec550de02`](https://github.com/nodejs/node/commit/5ec550de02)] - **test**: Change from var to const (Jure Stepisnik) [#30431](https://github.com/nodejs/node/pull/30431) +* [[`13bac0ac0f`](https://github.com/nodejs/node/commit/13bac0ac0f)] - **test**: changed var to let in test-repl-editor (JL Phillips) [#30443](https://github.com/nodejs/node/pull/30443) +* [[`0d12e9cc29`](https://github.com/nodejs/node/commit/0d12e9cc29)] - **test**: improve test-fs-open (Artem Maksimov) [#30280](https://github.com/nodejs/node/pull/30280) +* [[`89bc2526ab`](https://github.com/nodejs/node/commit/89bc2526ab)] - **test**: change var to let (nathias) [#30444](https://github.com/nodejs/node/pull/30444) +* [[`fa071efea4`](https://github.com/nodejs/node/commit/fa071efea4)] - **test**: changed var to const in test (Kerry Mahne) [#30434](https://github.com/nodejs/node/pull/30434) +* [[`13a22432fc`](https://github.com/nodejs/node/commit/13a22432fc)] - **test**: var to const in test-repl-multiline.js (SoulMonk) [#30433](https://github.com/nodejs/node/pull/30433) +* [[`109da52141`](https://github.com/nodejs/node/commit/109da52141)] - **test**: deflake test-http-dump-req-when-res-ends.js (Luigi Pinca) [#30360](https://github.com/nodejs/node/pull/30360) +* [[`72bbd5cdb0`](https://github.com/nodejs/node/commit/72bbd5cdb0)] - **test**: change var to const in parallel/test-stream-transform-final\* (Kenza Houmani) [#30448](https://github.com/nodejs/node/pull/30448) +* [[`cd82e4d9d8`](https://github.com/nodejs/node/commit/cd82e4d9d8)] - **test**: replace Object.assign with object spread (Grigoriy Levanov) [#30306](https://github.com/nodejs/node/pull/30306) +* [[`aec695eb6c`](https://github.com/nodejs/node/commit/aec695eb6c)] - **test**: fix Python unittests in ./test and ./tools (Christian Clauss) [#30340](https://github.com/nodejs/node/pull/30340) +* [[`ea0c1a67c5`](https://github.com/nodejs/node/commit/ea0c1a67c5)] - **test**: mark test-http-dump-req-when-res-ends as flaky on windows (AshCripps) [#30316](https://github.com/nodejs/node/pull/30316) +* [[`308f5e4710`](https://github.com/nodejs/node/commit/308f5e4710)] - **test**: fix test-benchmark-cluster (Rich Trott) [#30342](https://github.com/nodejs/node/pull/30342) +* [[`bb0727a132`](https://github.com/nodejs/node/commit/bb0727a132)] - **test**: do not run release-npm test without crypto (Michaël Zasso) [#30265](https://github.com/nodejs/node/pull/30265) +* [[`ab5bca379f`](https://github.com/nodejs/node/commit/ab5bca379f)] - **test**: remove AtExit() addon test (Anna Henningsen) [#30275](https://github.com/nodejs/node/pull/30275) +* [[`de68720908`](https://github.com/nodejs/node/commit/de68720908)] - **test**: deflake test-tls-close-notify.js (Luigi Pinca) [#30202](https://github.com/nodejs/node/pull/30202) +* [[`8fe684961b`](https://github.com/nodejs/node/commit/8fe684961b)] - ***Revert*** "**test**: test configure ninja" (Anna Henningsen) [#30295](https://github.com/nodejs/node/pull/30295) +* [[`0dedecc7e0`](https://github.com/nodejs/node/commit/0dedecc7e0)] - **test**: test configure ninja (Patrick Housley) [#30033](https://github.com/nodejs/node/pull/30033) +* [[`01fa18c99c`](https://github.com/nodejs/node/commit/01fa18c99c)] - **(SEMVER-MINOR)** **tls**: cli option to enable TLS key logging to file (Sam Roberts) [#30055](https://github.com/nodejs/node/pull/30055) +* [[`5869f2bee7`](https://github.com/nodejs/node/commit/5869f2bee7)] - **tls**: change loop var to let (Xavier Redondo) [#30445](https://github.com/nodejs/node/pull/30445) +* [[`26a9bdfca3`](https://github.com/nodejs/node/commit/26a9bdfca3)] - **tls**: replace var with let (Daniil Pletnev) [#30308](https://github.com/nodejs/node/pull/30308) +* [[`bad0b66580`](https://github.com/nodejs/node/commit/bad0b66580)] - **tls**: replace var with let and const (Nolik) [#30299](https://github.com/nodejs/node/pull/30299) +* [[`ae5aa3ee83`](https://github.com/nodejs/node/commit/ae5aa3ee83)] - **tls**: refactor tls\_wrap.cc (Artem Maksimov) [#30303](https://github.com/nodejs/node/pull/30303) +* [[`80b1717c0f`](https://github.com/nodejs/node/commit/80b1717c0f)] - **tools**: fix build at non-English windows (Rongjian Zhang) [#30492](https://github.com/nodejs/node/pull/30492) +* [[`642b0b883f`](https://github.com/nodejs/node/commit/642b0b883f)] - **tools**: update tzdata to 2019c (Albert Wang) [#30356](https://github.com/nodejs/node/pull/30356) +* [[`3a44adebf8`](https://github.com/nodejs/node/commit/3a44adebf8)] - **tools**: pull xcode\_emulation.py from node-gyp (Christian Clauss) [#30272](https://github.com/nodejs/node/pull/30272) +* [[`92fa4e0096`](https://github.com/nodejs/node/commit/92fa4e0096)] - **tools**: make doctool work if no internet available (Richard Lau) [#30214](https://github.com/nodejs/node/pull/30214) +* [[`0f9f18aabe`](https://github.com/nodejs/node/commit/0f9f18aabe)] - **tools**: update certdata.txt (AshCripps) [#30195](https://github.com/nodejs/node/pull/30195) +* [[`dbdc3818e0`](https://github.com/nodejs/node/commit/dbdc3818e0)] - **tools**: check-imports using utf-8 (Christian Clauss) [#30220](https://github.com/nodejs/node/pull/30220) +* [[`3b45f8fd9c`](https://github.com/nodejs/node/commit/3b45f8fd9c)] - **url**: replace var with let in lib/url.js (xefimx) [#30281](https://github.com/nodejs/node/pull/30281) +* [[`35dc84859f`](https://github.com/nodejs/node/commit/35dc84859f)] - **util**: replace var with let (Susana Ferreira) [#30439](https://github.com/nodejs/node/pull/30439) +* [[`3727a6572b`](https://github.com/nodejs/node/commit/3727a6572b)] - **v8**: mark serdes API as stable (Anna Henningsen) [#30234](https://github.com/nodejs/node/pull/30234) +* [[`9b11bdb001`](https://github.com/nodejs/node/commit/9b11bdb001)] - **v8**: inspect unserializable objects (Anna Henningsen) [#30167](https://github.com/nodejs/node/pull/30167) +* [[`2ec40c265a`](https://github.com/nodejs/node/commit/2ec40c265a)] - **(SEMVER-MINOR)** **worker**: allow specifying resource limits (Anna Henningsen) [#26628](https://github.com/nodejs/node/pull/26628) + <a id="13.1.0"></a> ## 2019-11-05, Version 13.1.0 (Current), @targos diff --git a/doc/guides/backporting-to-release-lines.md b/doc/guides/backporting-to-release-lines.md index ab3783672ea3f5..4a4657d0815a21 100644 --- a/doc/guides/backporting-to-release-lines.md +++ b/doc/guides/backporting-to-release-lines.md @@ -26,8 +26,8 @@ commits be cherry-picked or backported. ## How to submit a backport pull request -For the following steps, let's assume that a backport is needed for the v8.x -release line. All commands will use the `v8.x-staging` branch as the target +For the following steps, let's assume that a backport is needed for the v10.x +release line. All commands will use the `v10.x-staging` branch as the target branch. In order to submit a backport pull request to another branch, simply replace that with the staging branch for the targeted release line. @@ -40,10 +40,10 @@ replace that with the staging branch for the targeted release line. # the origin remote points to your fork, and the upstream remote points # to git://github.com/nodejs/node cd $NODE_DIR - # If v8.x-staging is checked out `pull` should be used instead of `fetch` - git fetch upstream v8.x-staging:v8.x-staging -f + # If v10.x-staging is checked out `pull` should be used instead of `fetch` + git fetch upstream v10.x-staging:v10.x-staging -f # Assume we want to backport PR #10157 - git checkout -b backport-10157-to-v8.x v8.x-staging + git checkout -b backport-10157-to-v10.x v10.x-staging # Ensure there are no test artifacts from previous builds # Note that this command deletes all files and directories # not under revision control below the ./test directory. @@ -73,10 +73,10 @@ replace that with the staging branch for the targeted release line. 7. Make sure `make -j4 test` passes. 8. Push the changes to your fork 9. Open a pull request: - 1. Be sure to target the `v8.x-staging` branch in the pull request. + 1. Be sure to target the `v10.x-staging` branch in the pull request. 1. Include the backport target in the pull request title in the following - format — `[v8.x backport] <commit title>`. - Example: `[v8.x backport] process: improve performance of nextTick` + format — `[v10.x backport] <commit title>`. + Example: `[v10.x backport] process: improve performance of nextTick` 1. Check the checkbox labeled "Allow edits from maintainers". 1. In the description add a reference to the original PR. 1. Amend the commit message and include a `Backport-PR-URL:` metadata and @@ -84,10 +84,10 @@ replace that with the staging branch for the targeted release line. 1. Run a [`node-test-pull-request`][] CI job (with `REBASE_ONTO` set to the default `<pr base branch>`) 10. If during the review process conflicts arise, use the following to rebase: - `git pull --rebase upstream v8.x-staging` + `git pull --rebase upstream v10.x-staging` -After the PR lands replace the `backport-requested-v8.x` label on the original -PR with `backported-to-v8.x`. +After the PR lands replace the `backport-requested-v10.x` label on the original +PR with `backported-to-v10.x`. [Release Schedule]: https://github.com/nodejs/Release#release-schedule1 [Release Plan]: https://github.com/nodejs/Release#release-plan diff --git a/doc/guides/contributing/pull-requests.md b/doc/guides/contributing/pull-requests.md index 17257674a3b546..f23c92fa024e63 100644 --- a/doc/guides/contributing/pull-requests.md +++ b/doc/guides/contributing/pull-requests.md @@ -73,7 +73,7 @@ $ git remote add upstream https://github.com/nodejs/node.git $ git fetch upstream ``` -It is recommended to configure `git` so that it knows who you are: +Configure `git` so that it knows who you are: ```text $ git config user.name "J. Random User" @@ -125,7 +125,7 @@ For contributing C++ code, you may want to look at the ### Step 4: Commit -It is a recommended best practice to keep your changes as logically grouped +It is a best practice to keep your changes as logically grouped as possible within individual commits. There is no limit to the number of commits any single Pull Request may have, and many contributors find it easier to review changes that are split across multiple commits. diff --git a/doc/guides/maintaining-npm.md b/doc/guides/maintaining-npm.md index 3be5528ad1907e..986c202bb17a97 100644 --- a/doc/guides/maintaining-npm.md +++ b/doc/guides/maintaining-npm.md @@ -4,10 +4,6 @@ New pull requests should be opened when a "next" version of npm has been released. Once the "next" version has been promoted to "latest" the PR should be updated as necessary. -One week after the "latest" release has been promoted, it can land on master -assuming no major regressions are found. There are no additional constraints -for Semver-Major releases. - The specific Node.js release streams the new version will be able to land into are at the discretion of the release and LTS teams. diff --git a/doc/guides/writing-tests.md b/doc/guides/writing-tests.md index 584b1d2373ce1b..7022bf8f938f78 100644 --- a/doc/guides/writing-tests.md +++ b/doc/guides/writing-tests.md @@ -162,19 +162,22 @@ const assert = require('assert'); const http = require('http'); let request = 0; +let listening = 0; let response = 0; -process.on('exit', function() { +process.on('exit', () => { assert.equal(request, 1, 'http server "request" callback was not called'); + assert.equal(listening, 1, 'http server "listening" callback was not called'); assert.equal(response, 1, 'http request "response" callback was not called'); }); const server = http.createServer((req, res) => { request++; res.end(); -}).listen(0, function() { +}).listen(0, () => { + listening++; const options = { agent: null, - port: this.address().port + port: server.address().port }; http.get(options, (res) => { response++; @@ -193,16 +196,16 @@ const http = require('http'); const server = http.createServer(common.mustCall((req, res) => { res.end(); -})).listen(0, function() { +})).listen(0, common.mustCall(() => { const options = { agent: null, - port: this.address().port + port: server.address().port }; http.get(options, common.mustCall((res) => { res.resume(); server.close(); })); -}); +})); ``` @@ -216,7 +219,7 @@ shutting down an HTTP server after a specific number of requests). ```javascript const Countdown = require('../common/countdown'); -const countdown = new Countdown(2, function() { +const countdown = new Countdown(2, () => { console.log('.'); }); diff --git a/doc/node.1 b/doc/node.1 index e9b7855b9be483..e3628034e832e5 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -113,11 +113,14 @@ Requires Node.js to be built with .It Fl -es-module-specifier-resolution Select extension resolution algorithm for ES Modules; either 'explicit' (default) or 'node' . +.It Fl -experimental-conditional-exports +Enable experimental support for "require" and "node" conditional export targets. +. .It Fl -experimental-json-modules Enable experimental JSON interop support for the ES Module loader. . .It Fl -experimental-modules -Enable experimental ES module support and caching modules. +Enable experimental latest experimental modules features. . .It Fl -experimental-policy Use the specified file as a security policy. @@ -132,6 +135,9 @@ Enable experimental .Sy diagnostic report feature. . +.It Fl -experimental-resolve-self +Enable experimental support for a package to load itself. +. .It Fl -experimental-vm-modules Enable experimental ES module support in VM module. . @@ -202,8 +208,7 @@ It uses the Chrome DevTools Protocol. .It Fl -experimental-loader Ns = Ns Ar module Specify the .Ar module -as a custom loader, to load -.Fl -experimental-modules . +to use as a custom module loader. . .It Fl -max-http-header-size Ns = Ns Ar size Specify the maximum size of HTTP headers in bytes. Defaults to 8KB. @@ -297,6 +302,11 @@ Specify process.title on startup. Specify an alternative default TLS cipher list. Requires Node.js to be built with crypto support. (Default) . +.It Fl -tls-keylog Ns = Ns Ar file +Log TLS key material to a file. The key material is in NSS SSLKEYLOGFILE +format and can be used by software (such as Wireshark) to decrypt the TLS +traffic. +. .It Fl -tls-max-v1.2 Set default maxVersion to 'TLSv1.2'. Use to disable support for TLSv1.3. . diff --git a/lib/_http_agent.js b/lib/_http_agent.js index dcb5ed376de835..f8aa395aefdb38 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -32,6 +32,7 @@ const { ERR_INVALID_ARG_TYPE, }, } = require('internal/errors'); +const kOnKeylog = Symbol('onkeylog'); // New Agent code. // The largest departure from the previous implementation is that @@ -44,10 +45,18 @@ const { // ClientRequest.onSocket(). The Agent is now *strictly* // concerned with managing a connection pool. +const kReusedHandle = Symbol('kReusedHandle'); class ReusedHandle { constructor(type, handle) { this.type = type; this.handle = handle; + // We need keep the resource object alive from this object, because + // domains rely on GC of the resource object for lifetime tracking. + // TODO(addaleax): This should really apply to all uses of + // AsyncWrap::AsyncReset() when the resource is not the AsyncWrap object + // itself. However, HTTPClientAsyncResource and HTTPServerAsyncResource + // hold on to other objects, inhibiting GC. + handle[kReusedHandle] = this; } } @@ -87,14 +96,14 @@ function Agent(options) { } else { // If there are no pending requests, then put it in // the freeSockets pool, but only if we're allowed to do so. - var req = socket._httpMessage; + const req = socket._httpMessage; if (req && req.shouldKeepAlive && socket.writable && this.keepAlive) { - var freeSockets = this.freeSockets[name]; - var freeLen = freeSockets ? freeSockets.length : 0; - var count = freeLen; + let freeSockets = this.freeSockets[name]; + const freeLen = freeSockets ? freeSockets.length : 0; + let count = freeLen; if (this.sockets[name]) count += this.sockets[name].length; @@ -116,17 +125,36 @@ function Agent(options) { } } }); + + // Don't emit keylog events unless there is a listener for them. + this.on('newListener', maybeEnableKeylog); } Object.setPrototypeOf(Agent.prototype, EventEmitter.prototype); Object.setPrototypeOf(Agent, EventEmitter); +function maybeEnableKeylog(eventName) { + if (eventName === 'keylog') { + this.removeListener('newListener', maybeEnableKeylog); + // Future sockets will listen on keylog at creation. + const agent = this; + this[kOnKeylog] = function onkeylog(keylog) { + agent.emit('keylog', keylog, this); + }; + // Existing sockets will start listening on keylog now. + const sockets = Object.values(this.sockets); + for (let i = 0; i < sockets.length; i++) { + sockets[i].on('keylog', this[kOnKeylog]); + } + } +} + Agent.defaultMaxSockets = Infinity; Agent.prototype.createConnection = net.createConnection; // Get the key for a given set of request options Agent.prototype.getName = function getName(options) { - var name = options.host || 'localhost'; + let name = options.host || 'localhost'; name += ':'; if (options.port) @@ -175,7 +203,7 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, if (freeLen) { // We have a free socket, so use that. - var socket = this.freeSockets[name].shift(); + const socket = this.freeSockets[name].shift(); // Guard against an uninitialized or user supplied Socket. const handle = socket._handle; if (handle && typeof handle.asyncReset === 'function') { @@ -218,7 +246,7 @@ Agent.prototype.createSocket = function createSocket(req, options, cb) { debug('createConnection', name, options); options.encoding = null; - var called = false; + let called = false; const oncreate = (err, s) => { if (called) @@ -298,6 +326,10 @@ function installListeners(agent, s, options) { s.removeListener('agentRemove', onRemove); } s.on('agentRemove', onRemove); + + if (agent[kOnKeylog]) { + s.on('keylog', agent[kOnKeylog]); + } } Agent.prototype.removeSocket = function removeSocket(s, options) { @@ -309,11 +341,11 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { if (!s.writable) sets.push(this.freeSockets); - for (var sk = 0; sk < sets.length; sk++) { - var sockets = sets[sk]; + for (let sk = 0; sk < sets.length; sk++) { + const sockets = sets[sk]; if (sockets[name]) { - var index = sockets[name].indexOf(s); + const index = sockets[name].indexOf(s); if (index !== -1) { sockets[name].splice(index, 1); // Don't leak @@ -347,12 +379,12 @@ Agent.prototype.reuseSocket = function reuseSocket(socket, req) { Agent.prototype.destroy = function destroy() { const sets = [this.freeSockets, this.sockets]; - for (var s = 0; s < sets.length; s++) { - var set = sets[s]; - var keys = Object.keys(set); - for (var v = 0; v < keys.length; v++) { - var setName = set[keys[v]]; - for (var n = 0; n < setName.length; n++) { + for (let s = 0; s < sets.length; s++) { + const set = sets[s]; + const keys = Object.keys(set); + for (let v = 0; v < keys.length; v++) { + const setName = set[keys[v]]; + for (let n = 0; n < setName.length; n++) { setName[n].destroy(); } } diff --git a/lib/_http_client.js b/lib/_http_client.js index d55bc850bcb9e5..4e2b8e9883bfc7 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -110,7 +110,7 @@ function ClientRequest(input, options, cb) { options = Object.assign(input || {}, options); } - var agent = options.agent; + let agent = options.agent; const defaultAgent = options._defaultAgent || Agent.globalAgent; if (agent === false) { agent = new defaultAgent.constructor(); @@ -128,11 +128,11 @@ function ClientRequest(input, options, cb) { this.agent = agent; const protocol = options.protocol || defaultAgent.protocol; - var expectedProtocol = defaultAgent.protocol; + let expectedProtocol = defaultAgent.protocol; if (this.agent && this.agent.protocol) expectedProtocol = this.agent.protocol; - var path; + let path; if (options.path) { path = String(options.path); if (INVALID_PATH_REGEX.test(path)) @@ -157,7 +157,7 @@ function ClientRequest(input, options, cb) { if (options.timeout !== undefined) this.timeout = getTimerDuration(options.timeout, 'timeout'); - var method = options.method; + let method = options.method; const methodIsString = (typeof method === 'string'); if (method !== null && method !== undefined && !methodIsString) { throw new ERR_INVALID_ARG_TYPE('method', 'string', method); @@ -197,7 +197,7 @@ function ClientRequest(input, options, cb) { this.maxHeadersCount = null; this.reusedSocket = false; - var called = false; + let called = false; if (this.agent) { // If there is an agent we should default to Connection:keep-alive, @@ -216,20 +216,20 @@ function ClientRequest(input, options, cb) { const headersArray = Array.isArray(options.headers); if (!headersArray) { if (options.headers) { - var keys = Object.keys(options.headers); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; + const keys = Object.keys(options.headers); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; this.setHeader(key, options.headers[key]); } } if (host && !this.getHeader('host') && setHost) { - var hostHeader = host; + let hostHeader = host; // For the Host header, ensure that IPv6 addresses are enclosed // in square brackets, as defined by URI formatting // https://tools.ietf.org/html/rfc3986#section-3.2.2 - var posColon = hostHeader.indexOf(':'); + const posColon = hostHeader.indexOf(':'); if (posColon !== -1 && hostHeader.includes(':', posColon + 1) && hostHeader.charCodeAt(0) !== 91/* '[' */) { @@ -461,8 +461,8 @@ function socketOnData(d) { req.emit('error', ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade (if status code 101) or CONNECT - var bytesParsed = ret; - var res = parser.incoming; + const bytesParsed = ret; + const res = parser.incoming; req.res = res; socket.removeListener('data', socketOnData); @@ -475,9 +475,9 @@ function socketOnData(d) { parser.finish(); freeParser(parser, req, socket); - var bodyHead = d.slice(bytesParsed, d.length); + const bodyHead = d.slice(bytesParsed, d.length); - var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; + const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; if (req.listenerCount(eventName) > 0) { req.upgradeOrConnect = true; diff --git a/lib/_http_common.js b/lib/_http_common.js index 732f4f29c42758..8c88a90568be4c 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -91,7 +91,7 @@ function parserOnHeadersComplete(versionMajor, versionMinor, headers, method, incoming.url = url; incoming.upgrade = upgrade; - var n = headers.length; + let n = headers.length; // If parser.maxHeaderPairs <= 0 assume that there's no limit. if (parser.maxHeaderPairs > 0) @@ -120,8 +120,8 @@ function parserOnBody(b, start, len) { // Pretend this was the result of a stream._read call. if (len > 0 && !stream._dumped) { - var slice = b.slice(start, start + len); - var ret = stream.push(slice); + const slice = b.slice(start, start + len); + const ret = stream.push(slice); if (!ret) readStop(this.socket); } diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 3e8bd69c04f0cf..36d81153fe7e8f 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -126,7 +126,7 @@ IncomingMessage.prototype.destroy = function destroy(error) { IncomingMessage.prototype._addHeaderLines = _addHeaderLines; function _addHeaderLines(headers, n) { if (headers && headers.length) { - var dest; + let dest; if (this.complete) { this.rawTrailers = headers; dest = this.trailers; @@ -135,7 +135,7 @@ function _addHeaderLines(headers, n) { dest = this.headers; } - for (var i = 0; i < n; i += 2) { + for (let i = 0; i < n; i += 2) { this._addHeaderLine(headers[i], headers[i + 1], dest); } } diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 32a51d120bad2b..0dc13f19fe918c 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -56,7 +56,7 @@ const { validateString } = require('internal/validators'); const HIGH_WATER_MARK = getDefaultHighWaterMark(); const { CRLF, debug } = common; -const kIsCorked = Symbol('isCorked'); +const kCorked = Symbol('corked'); const RE_CONN_CLOSE = /(?:^|\W)close(?:$|\W)/i; const RE_TE_CHUNKED = common.chunkExpression; @@ -101,7 +101,7 @@ function OutgoingMessage() { this.finished = false; this._headerSent = false; - this[kIsCorked] = false; + this[kCorked] = 0; this.socket = null; this._header = null; @@ -140,6 +140,13 @@ Object.defineProperty(OutgoingMessage.prototype, 'writableHighWaterMark', { } }); +Object.defineProperty(OutgoingMessage.prototype, 'writableCorked', { + get() { + const corked = this.socket ? this.socket.writableCorked : 0; + return corked + this[kCorked]; + } +}); + Object.defineProperty(OutgoingMessage.prototype, '_headers', { get: internalUtil.deprecate(function() { return this.getHeaders(); @@ -216,6 +223,21 @@ OutgoingMessage.prototype._renderHeaders = function _renderHeaders() { return headers; }; +OutgoingMessage.prototype.cork = function() { + if (this.socket) { + this.socket.cork(); + } else { + this[kCorked]++; + } +}; + +OutgoingMessage.prototype.uncork = function() { + if (this.socket) { + this.socket.uncork(); + } else if (this[kCorked]) { + this[kCorked]--; + } +}; OutgoingMessage.prototype.setTimeout = function setTimeout(msecs, callback) { @@ -628,10 +650,9 @@ function write_(msg, chunk, encoding, callback, fromEnd) { ['string', 'Buffer'], chunk); } - if (!fromEnd && msg.socket && !msg[kIsCorked]) { + if (!fromEnd && msg.socket && !msg.socket.writableCorked) { msg.socket.cork(); - msg[kIsCorked] = true; - process.nextTick(connectionCorkNT, msg, msg.socket); + process.nextTick(connectionCorkNT, msg.socket); } var len, ret; @@ -660,8 +681,7 @@ function writeAfterEndNT(msg, err, callback) { } -function connectionCorkNT(msg, conn) { - msg[kIsCorked] = false; +function connectionCorkNT(conn) { conn.uncork(); } @@ -715,7 +735,10 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) { return this; } - var uncork; + if (this.socket) { + this.socket.cork(); + } + if (chunk) { if (typeof chunk !== 'string' && !(chunk instanceof Buffer)) { throw new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); @@ -726,10 +749,6 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) { else this._contentLength = chunk.length; } - if (this.socket) { - this.socket.cork(); - uncork = true; - } write_(this, chunk, encoding, null, true); } else if (!this._header) { this._contentLength = 0; @@ -748,8 +767,12 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) { this._send('', 'latin1', finish); } - if (uncork) + if (this.socket) { + // Fully uncork connection on end(). + this.socket._writableState.corked = 1; this.socket.uncork(); + } + this[kCorked] = 0; this.finished = true; @@ -810,6 +833,11 @@ OutgoingMessage.prototype._flush = function _flush() { }; OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) { + while (this[kCorked]) { + this[kCorked]--; + socket.cork(); + } + const outputLength = this.outputData.length; if (outputLength <= 0) return undefined; diff --git a/lib/_http_server.js b/lib/_http_server.js index 82f9b91795d8a0..bc956a01147ad1 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -249,13 +249,13 @@ function writeHead(statusCode, reason, obj) { } this.statusCode = statusCode; - var headers; + let headers; if (this[kOutHeaders]) { // Slow-case: when progressive API and header fields are passed. - var k; + let k; if (obj) { - var keys = Object.keys(obj); - for (var i = 0; i < keys.length; i++) { + const keys = Object.keys(obj); + for (let i = 0; i < keys.length; i++) { k = keys[i]; if (k) this.setHeader(k, obj[k]); } @@ -483,7 +483,7 @@ function socketOnClose(socket, state) { function abortIncoming(incoming) { while (incoming.length) { - var req = incoming.shift(); + const req = incoming.shift(); req.aborted = true; req.emit('aborted'); req.emit('close'); @@ -573,8 +573,7 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { socketOnError.call(socket, ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT - var bytesParsed = ret; - var req = parser.incoming; + const req = parser.incoming; debug('SERVER upgrade or connect', req.method); if (!d) @@ -591,10 +590,10 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { freeParser(parser, req, socket); parser = null; - var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; + const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) { debug('SERVER have listener for %s', eventName); - var bodyHead = d.slice(bytesParsed, d.length); + const bodyHead = d.slice(ret, d.length); socket.readableFlowing = null; server.emit(eventName, req, socket, bodyHead); @@ -656,7 +655,7 @@ function resOnFinish(req, res, socket, state, server) { } } else { // Start sending the next message - var m = state.outgoing.shift(); + const m = state.outgoing.shift(); if (m) { m.assignSocket(socket); } @@ -693,7 +692,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { // so that we don't become overwhelmed by a flood of // pipelined requests that may never be resolved. if (!socket._paused) { - var ws = socket._writableState; + const ws = socket._writableState; if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) { socket._paused = true; // We also need to pause the parser, but don't do that until after diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index b96a0439f785fa..858dc938f01cd1 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -39,7 +39,7 @@ Object.setPrototypeOf(Duplex, Readable); { // Allow the keys array to be GC'ed. const keys = Object.keys(Writable.prototype); - for (var v = 0; v < keys.length; v++) { + for (let v = 0; v < keys.length; v++) { const method = keys[v]; if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; @@ -108,6 +108,16 @@ Object.defineProperty(Duplex.prototype, 'writableFinished', { } }); +Object.defineProperty(Duplex.prototype, 'writableCorked', { + // Making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get() { + return this._writableState ? this._writableState.corked : 0; + } +}); + Object.defineProperty(Duplex.prototype, 'writableEnded', { // Making it explicit this property is not enumerable // because otherwise some prototype manipulation in diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 91cf2f75b07125..71fd74b07bea70 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -375,10 +375,11 @@ Readable.prototype.setEncoding = function(enc) { return this; }; -// Don't raise the hwm > 8MB -const MAX_HWM = 0x800000; +// Don't raise the hwm > 1GB +const MAX_HWM = 0x40000000; function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { + // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. n = MAX_HWM; } else { // Get the next highest power of 2 to prevent increasing hwm excessively in diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 9b75b672cbd843..9b4036e4764418 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -385,6 +385,16 @@ Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { } }); +Object.defineProperty(Writable.prototype, 'writableCorked', { + // Making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function() { + return this._writableState ? this._writableState.corked : 0; + } +}); + // If we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. diff --git a/lib/_tls_common.js b/lib/_tls_common.js index ef67d23ac85f3f..981503e6e96658 100644 --- a/lib/_tls_common.js +++ b/lib/_tls_common.js @@ -91,14 +91,14 @@ exports.SecureContext = SecureContext; exports.createSecureContext = function createSecureContext(options) { if (!options) options = {}; - var secureOptions = options.secureOptions; + let secureOptions = options.secureOptions; if (options.honorCipherOrder) secureOptions |= SSL_OP_CIPHER_SERVER_PREFERENCE; const c = new SecureContext(options.secureProtocol, secureOptions, options.minVersion, options.maxVersion); - var i; - var val; + let i; + let val; // Add CA before the cert to be able to load cert's issuer in C++ code. const { ca } = options; @@ -313,7 +313,7 @@ exports.translatePeerCertificate = function translatePeerCertificate(c) { } if (c.subject != null) c.subject = parseCertString(c.subject); if (c.infoAccess != null) { - var info = c.infoAccess; + const info = c.infoAccess; c.infoAccess = Object.create(null); // XXX: More key validation? diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 9c3fe656a7ce80..69fc05475896a1 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -60,6 +60,8 @@ const { const { getOptionValue } = require('internal/options'); const { validateString } = require('internal/validators'); const traceTls = getOptionValue('--trace-tls'); +const tlsKeylog = getOptionValue('--tls-keylog'); +const { appendFile } = require('fs'); const kConnectOptions = Symbol('connect-options'); const kDisableRenegotiation = Symbol('disable-renegotiation'); const kErrorEmitted = Symbol('error-emitted'); @@ -129,7 +131,7 @@ function loadSession(hello) { ); const owner = this[owner_symbol]; - var once = false; + let once = false; function onSession(err, session) { debug('server resumeSession callback(err %j, sess? %s)', err, !!session); if (once) @@ -263,7 +265,7 @@ function onnewsession(sessionId, session) { if (!owner.server) return; - var once = false; + let once = false; const done = () => { debug('onnewsession done'); if (once) @@ -345,7 +347,7 @@ function initRead(tlsSocket, socket) { // Socket already has some buffered data - emulate receiving it if (socket && socket.readableLength) { - var buf; + let buf; while ((buf = socket.read()) !== null) tlsSocket._handle.receive(buf); } @@ -389,7 +391,7 @@ function TLSSocket(socket, opts) { this.authorizationError = null; this[kRes] = null; - var wrap; + let wrap; if ((socket instanceof net.Socket && socket._handle) || !socket) { // 1. connected socket // 2. no socket, one will be created with net.Socket().connect @@ -455,7 +457,7 @@ function makeMethodProxy(name) { return this._parent[name].apply(this._parent, args); }; } -for (var n = 0; n < proxiedMethods.length; n++) { +for (let n = 0; n < proxiedMethods.length; n++) { tls_wrap.TLSWrap.prototype[proxiedMethods[n]] = makeMethodProxy(proxiedMethods[n]); } @@ -493,7 +495,7 @@ TLSSocket.prototype.disableRenegotiation = function disableRenegotiation() { }; TLSSocket.prototype._wrapHandle = function(wrap) { - var handle; + let handle; if (wrap) handle = wrap._handle; @@ -560,6 +562,8 @@ TLSSocket.prototype._destroySSL = function _destroySSL() { }; // Constructor guts, arbitrarily factored out. +let warnOnTlsKeylog = true; +let warnOnTlsKeylogError = true; TLSSocket.prototype._init = function(socket, wrap) { const options = this._tlsOptions; const ssl = this._handle; @@ -643,6 +647,24 @@ TLSSocket.prototype._init = function(socket, wrap) { } } + if (tlsKeylog) { + if (warnOnTlsKeylog) { + warnOnTlsKeylog = false; + process.emitWarning('Using --tls-keylog makes TLS connections insecure ' + + 'by writing secret key material to file ' + tlsKeylog); + ssl.enableKeylogCallback(); + this.on('keylog', (line) => { + appendFile(tlsKeylog, line, { mode: 0o600 }, (err) => { + if (err && warnOnTlsKeylogError) { + warnOnTlsKeylogError = false; + process.emitWarning('Failed to write TLS keylog (this warning ' + + 'will not be repeated): ' + err); + } + }); + }); + } + } + ssl.onerror = onerror; // If custom SNICallback was given, or if @@ -1259,7 +1281,7 @@ Server.prototype.addContext = function(servername, context) { function SNICallback(servername, callback) { const contexts = this.server._contexts; - for (var i = 0; i < contexts.length; i++) { + for (let i = 0; i < contexts.length; i++) { const elem = contexts[i]; if (elem[0].test(servername)) { callback(null, elem[1]); @@ -1273,7 +1295,7 @@ function SNICallback(servername, callback) { // Target API: // -// var s = tls.connect({port: 8000, host: "google.com"}, function() { +// let s = tls.connect({port: 8000, host: "google.com"}, function() { // if (!s.authorized) { // s.destroy(); // return; @@ -1374,7 +1396,7 @@ let warnOnAllowUnauthorized = true; // Arguments: [port,] [host,] [options,] [cb] exports.connect = function connect(...args) { args = normalizeConnectArgs(args); - var options = args[0]; + let options = args[0]; const cb = args[1]; const allowUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0'; diff --git a/lib/assert.js b/lib/assert.js index d307582d1fde7d..4ce3c3bfdeff03 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -186,7 +186,7 @@ function getCode(fd, line, column) { buffer = lines < line ? buffer : Buffer.allocUnsafe(bytesPerRead); bytesRead = readSync(fd, buffer, 0, bytesPerRead); // Read the buffer until the required code line is found. - for (var i = 0; i < bytesRead; i++) { + for (let i = 0; i < bytesRead; i++) { if (buffer[i] === 10 && ++lines === line) { // If the end of file is reached, directly parse the code and return. if (bytesRead < bytesPerRead) { @@ -863,7 +863,7 @@ assert.ifError = function ifError(err) { tmp2.shift(); // Filter all frames existing in err.stack. let tmp1 = newErr.stack.split('\n'); - for (var i = 0; i < tmp2.length; i++) { + for (let i = 0; i < tmp2.length; i++) { // Find the first occurrence of the frame. const pos = tmp1.indexOf(tmp2[i]); if (pos !== -1) { diff --git a/lib/buffer.js b/lib/buffer.js index ab30db67010107..a751677a7344ea 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -317,7 +317,7 @@ Buffer.from = function from(value, encodingOrOffset, length) { // Refs: https://esdiscuss.org/topic/isconstructor#content-11 const of = (...items) => { const newObj = createUnsafeBuffer(items.length); - for (var k = 0; k < items.length; k++) + for (let k = 0; k < items.length; k++) newObj[k] = items[k]; return newObj; }; @@ -433,7 +433,7 @@ function fromString(string, encoding) { function fromArrayLike(obj) { const length = obj.length; const b = allocate(length); - for (var i = 0; i < length; i++) + for (let i = 0; i < length; i++) b[i] = obj[i]; return b; } @@ -1044,7 +1044,7 @@ Buffer.prototype.write = function write(string, offset, length, encoding) { Buffer.prototype.toJSON = function toJSON() { if (this.length > 0) { const data = new Array(this.length); - for (var i = 0; i < this.length; ++i) + for (let i = 0; i < this.length; ++i) data[i] = this[i]; return { type: 'Buffer', data }; } @@ -1090,7 +1090,7 @@ Buffer.prototype.swap16 = function swap16() { if (len % 2 !== 0) throw new ERR_INVALID_BUFFER_SIZE('16-bits'); if (len < 128) { - for (var i = 0; i < len; i += 2) + for (let i = 0; i < len; i += 2) swap(this, i, i + 1); return this; } @@ -1105,7 +1105,7 @@ Buffer.prototype.swap32 = function swap32() { if (len % 4 !== 0) throw new ERR_INVALID_BUFFER_SIZE('32-bits'); if (len < 192) { - for (var i = 0; i < len; i += 4) { + for (let i = 0; i < len; i += 4) { swap(this, i, i + 3); swap(this, i + 1, i + 2); } @@ -1122,7 +1122,7 @@ Buffer.prototype.swap64 = function swap64() { if (len % 8 !== 0) throw new ERR_INVALID_BUFFER_SIZE('64-bits'); if (len < 192) { - for (var i = 0; i < len; i += 8) { + for (let i = 0; i < len; i += 8) { swap(this, i, i + 7); swap(this, i + 1, i + 6); swap(this, i + 2, i + 5); diff --git a/lib/child_process.js b/lib/child_process.js index 3df73ab5e887ff..16dc30856a96f5 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -108,12 +108,12 @@ function fork(modulePath /* , args, options */) { return spawn(options.execPath, args, options); } -function _forkChild(fd) { +function _forkChild(fd, serializationMode) { // set process.send() const p = new Pipe(PipeConstants.IPC); p.open(fd); p.unref(); - const control = setupChannel(process, p); + const control = setupChannel(process, p, serializationMode); process.on('newListener', function onNewListener(name) { if (name === 'message' || name === 'disconnect') control.ref(); }); diff --git a/lib/dgram.js b/lib/dgram.js index d29d1e7b190f3a..94f44d520220ff 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -211,8 +211,21 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { state.bindState = BIND_STATE_BINDING; - if (arguments.length && typeof arguments[arguments.length - 1] === 'function') - this.once('listening', arguments[arguments.length - 1]); + const cb = arguments.length && arguments[arguments.length - 1]; + if (typeof cb === 'function') { + function removeListeners() { + this.removeListener('error', removeListeners); + this.removeListener('listening', onListening); + } + + function onListening() { + removeListeners.call(this); + cb.call(this); + } + + this.on('error', removeListeners); + this.on('listening', onListening); + } if (port instanceof UDP) { replaceHandle(this, port); @@ -240,8 +253,8 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { }, (err) => { // Callback to handle error. const ex = errnoException(err, 'open'); - this.emit('error', ex); state.bindState = BIND_STATE_UNBOUND; + this.emit('error', ex); }); return this; } @@ -309,8 +322,8 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { }, (err) => { // Callback to handle error. const ex = exceptionWithHostPort(err, 'bind', ip, port); - this.emit('error', ex); state.bindState = BIND_STATE_UNBOUND; + this.emit('error', ex); }); } else { if (!state.handle) @@ -319,8 +332,8 @@ Socket.prototype.bind = function(port_, address_ /* , callback */) { const err = state.handle.bind(ip, port || 0, flags); if (err) { const ex = exceptionWithHostPort(err, 'bind', ip, port); - this.emit('error', ex); state.bindState = BIND_STATE_UNBOUND; + this.emit('error', ex); // Todo: close? return; } diff --git a/lib/dns.js b/lib/dns.js index b5a528ead13798..2a4dd15c5edeac 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -73,7 +73,7 @@ function onlookupall(err, addresses) { } const family = this.family; - for (var i = 0; i < addresses.length; i++) { + for (let i = 0; i < addresses.length; i++) { const addr = addresses[i]; addresses[i] = { address: addr, @@ -88,10 +88,10 @@ function onlookupall(err, addresses) { // Easy DNS A/AAAA look up // lookup(hostname, [options,] callback) function lookup(hostname, options, callback) { - var hints = 0; - var family = -1; - var all = false; - var verbatim = false; + let hints = 0; + let family = -1; + let all = false; + let verbatim = false; // Parse arguments if (hostname && typeof hostname !== 'string') { @@ -206,7 +206,7 @@ function onresolve(err, result, ttls) { function resolver(bindingName) { function query(name, /* options, */ callback) { - var options; + let options; if (arguments.length > 2) { options = callback; callback = arguments[2]; @@ -248,7 +248,7 @@ Resolver.prototype.reverse = resolver('getHostByAddr'); Resolver.prototype.resolve = resolve; function resolve(hostname, rrtype, callback) { - var resolver; + let resolver; if (typeof rrtype === 'string') { resolver = resolveMap[rrtype]; } else if (typeof rrtype === 'function') { diff --git a/lib/domain.js b/lib/domain.js index 697ef6d8aded8b..c3e38ba832c879 100644 --- a/lib/domain.js +++ b/lib/domain.js @@ -204,7 +204,7 @@ Domain.prototype.members = undefined; // Called by process._fatalException in case an error was thrown. Domain.prototype._errorHandler = function(er) { - var caught = false; + let caught = false; if ((typeof er === 'object' && er !== null) || typeof er === 'function') { Object.defineProperty(er, 'domain', { @@ -327,7 +327,7 @@ Domain.prototype.add = function(ee) { // e.add(d); // e.emit('error', er); // RangeError, stack overflow! if (this.domain && (ee instanceof Domain)) { - for (var d = this.domain; d; d = d.domain) { + for (let d = this.domain; d; d = d.domain) { if (ee === d) return; } } @@ -351,14 +351,14 @@ Domain.prototype.remove = function(ee) { Domain.prototype.run = function(fn) { - var ret; + let ret; this.enter(); if (arguments.length >= 2) { - var len = arguments.length; - var args = new Array(len - 1); + const len = arguments.length; + const args = new Array(len - 1); - for (var i = 1; i < len; i++) + for (let i = 1; i < len; i++) args[i - 1] = arguments[i]; ret = fn.apply(this, args); @@ -373,7 +373,7 @@ Domain.prototype.run = function(fn) { function intercepted(_this, self, cb, fnargs) { if (fnargs[0] && fnargs[0] instanceof Error) { - var er = fnargs[0]; + const er = fnargs[0]; er.domainBound = cb; er.domainThrown = false; Object.defineProperty(er, 'domain', { @@ -387,11 +387,11 @@ function intercepted(_this, self, cb, fnargs) { } const args = []; - var i, ret; + let ret; self.enter(); if (fnargs.length > 1) { - for (i = 1; i < fnargs.length; i++) + for (let i = 1; i < fnargs.length; i++) args.push(fnargs[i]); ret = cb.apply(_this, args); } else { @@ -415,7 +415,7 @@ Domain.prototype.intercept = function(cb) { function bound(_this, self, cb, fnargs) { - var ret; + let ret; self.enter(); if (fnargs.length > 0) diff --git a/lib/fs.js b/lib/fs.js index 1b3df1119f3aa5..2944a44a317f76 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1424,7 +1424,7 @@ if (isWindows) { }; } else { splitRoot = function splitRoot(str) { - for (var i = 0; i < str.length; ++i) { + for (let i = 0; i < str.length; ++i) { if (str.charCodeAt(i) !== CHAR_FORWARD_SLASH) return str.slice(0, i); } diff --git a/lib/https.js b/lib/https.js index e1fc91fd966ad9..6d799d0c925f2b 100644 --- a/lib/https.js +++ b/lib/https.js @@ -158,7 +158,7 @@ Object.setPrototypeOf(Agent, HttpAgent); Agent.prototype.createConnection = createConnection; Agent.prototype.getName = function getName(options) { - var name = HttpAgent.prototype.getName.call(this, options); + let name = HttpAgent.prototype.getName.call(this, options); name += ':'; if (options.ca) diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js index 48afed2556a51b..1915dc667461e3 100644 --- a/lib/internal/bootstrap/loaders.js +++ b/lib/internal/bootstrap/loaders.js @@ -211,23 +211,21 @@ function requireWithFallbackInDeps(request) { } // This is exposed for public loaders -NativeModule.prototype.compileForPublicLoader = function(needToSyncExports) { +NativeModule.prototype.compileForPublicLoader = function() { if (!this.canBeRequiredByUsers) { // No code because this is an assertion against bugs // eslint-disable-next-line no-restricted-syntax throw new Error(`Should not compile ${this.id} for public use`); } this.compile(); - if (needToSyncExports) { - if (!this.exportKeys) { - // When using --expose-internals, we do not want to reflect the named - // exports from core modules as this can trigger unnecessary getters. - const internal = this.id.startsWith('internal/'); - this.exportKeys = internal ? [] : Object.keys(this.exports); - } - this.getESMFacade(); - this.syncExports(); + if (!this.exportKeys) { + // When using --expose-internals, we do not want to reflect the named + // exports from core modules as this can trigger unnecessary getters. + const internal = this.id.startsWith('internal/'); + this.exportKeys = internal ? [] : Object.keys(this.exports); } + this.getESMFacade(); + this.syncExports(); return this.exports; }; diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index 80ac97ee450efa..8edec86a3e3c96 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -5,7 +5,7 @@ const { Object, SafeWeakMap } = primordials; const { getOptionValue } = require('internal/options'); const { Buffer } = require('buffer'); const { ERR_MANIFEST_ASSERT_INTEGRITY } = require('internal/errors').codes; -const path = require('path'); +const assert = require('internal/assert'); function prepareMainThreadExecution(expandArgv1 = false) { // Patch the process object with legacy properties and normalizations @@ -60,6 +60,9 @@ function prepareMainThreadExecution(expandArgv1 = false) { initializeDeprecations(); initializeCJSLoader(); initializeESMLoader(); + + const CJSLoader = require('internal/modules/cjs/loader'); + assert(!CJSLoader.hasLoadedAnyUserCJSModule); loadPreloadModules(); initializeFrozenIntrinsics(); } @@ -326,7 +329,11 @@ function setupChildProcessIpcChannel() { // Make sure it's not accidentally inherited by child processes. delete process.env.NODE_CHANNEL_FD; - require('child_process')._forkChild(fd); + const serializationMode = + process.env.NODE_CHANNEL_SERIALIZATION_MODE || 'json'; + delete process.env.NODE_CHANNEL_SERIALIZATION_MODE; + + require('child_process')._forkChild(fd, serializationMode); assert(process.send); } } @@ -390,31 +397,26 @@ function initializePolicy() { } function initializeCJSLoader() { - require('internal/modules/cjs/loader').Module._initPaths(); + const CJSLoader = require('internal/modules/cjs/loader'); + CJSLoader.Module._initPaths(); + // TODO(joyeecheung): deprecate this in favor of a proper hook? + CJSLoader.Module.runMain = + require('internal/modules/run_main').executeUserEntryPoint; } function initializeESMLoader() { // Create this WeakMap in js-land because V8 has no C++ API for WeakMap. internalBinding('module_wrap').callbackMap = new SafeWeakMap(); - const experimentalModules = getOptionValue('--experimental-modules'); - const experimentalVMModules = getOptionValue('--experimental-vm-modules'); - if (experimentalModules || experimentalVMModules) { - if (experimentalModules) { - process.emitWarning( - 'The ESM module loader is experimental.', - 'ExperimentalWarning', undefined); - } - const { - setImportModuleDynamicallyCallback, - setInitializeImportMetaObjectCallback - } = internalBinding('module_wrap'); - const esm = require('internal/process/esm_loader'); - // Setup per-isolate callbacks that locate data or callbacks that we keep - // track of for different ESM modules. - setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject); - setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback); - } + const { + setImportModuleDynamicallyCallback, + setInitializeImportMetaObjectCallback + } = internalBinding('module_wrap'); + const esm = require('internal/process/esm_loader'); + // Setup per-isolate callbacks that locate data or callbacks that we keep + // track of for different ESM modules. + setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject); + setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback); } function initializeFrozenIntrinsics() { @@ -438,70 +440,11 @@ function loadPreloadModules() { } } -function resolveMainPath(main) { - const { toRealPath, Module: CJSModule } = - require('internal/modules/cjs/loader'); - - // Note extension resolution for the main entry point can be deprecated in a - // future major. - let mainPath = CJSModule._findPath(path.resolve(main), null, true); - if (!mainPath) - return; - - const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); - if (!preserveSymlinksMain) - mainPath = toRealPath(mainPath); - - return mainPath; -} - -function shouldUseESMLoader(mainPath) { - const experimentalModules = getOptionValue('--experimental-modules'); - if (!experimentalModules) - return false; - const userLoader = getOptionValue('--experimental-loader'); - if (userLoader) - return true; - // Determine the module format of the main - if (mainPath && mainPath.endsWith('.mjs')) - return true; - if (!mainPath || mainPath.endsWith('.cjs')) - return false; - const { readPackageScope } = require('internal/modules/cjs/loader'); - const pkg = readPackageScope(mainPath); - return pkg && pkg.data.type === 'module'; -} - -function runMainESM(mainPath) { - const esmLoader = require('internal/process/esm_loader'); - const { pathToFileURL } = require('internal/url'); - const { hasUncaughtExceptionCaptureCallback } = - require('internal/process/execution'); - return esmLoader.initializeLoader().then(() => { - const main = path.isAbsolute(mainPath) ? - pathToFileURL(mainPath).href : mainPath; - return esmLoader.ESMLoader.import(main).catch((e) => { - if (hasUncaughtExceptionCaptureCallback()) { - process._fatalException(e); - return; - } - internalBinding('errors').triggerUncaughtException( - e, - true /* fromPromise */ - ); - }); - }); -} - - module.exports = { patchProcessObject, - resolveMainPath, - runMainESM, setupCoverageHooks, setupWarningHandler, setupDebugEnv, - shouldUseESMLoader, prepareMainThreadExecution, initializeDeprecations, initializeESMLoader, diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index 22f7da92ce8071..9e13650fa3d56a 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -1,6 +1,6 @@ 'use strict'; -const { JSON, Object } = primordials; +const { Object } = primordials; const { errnoException, @@ -55,8 +55,6 @@ const { const { SocketListSend, SocketListReceive } = SocketList; -// Lazy loaded for startup performance. -let StringDecoder; // Lazy loaded for startup performance and to allow monkey patching of // internalBinding('http_parser').HTTPParser. let freeParser; @@ -343,6 +341,15 @@ ChildProcess.prototype.spawn = function(options) { const ipcFd = stdio.ipcFd; stdio = options.stdio = stdio.stdio; + if (options.serialization !== undefined && + options.serialization !== 'json' && + options.serialization !== 'advanced') { + throw new ERR_INVALID_OPT_VALUE('options.serialization', + options.serialization); + } + + const serialization = options.serialization || 'json'; + if (ipc !== undefined) { // Let child process know about opened IPC channel if (options.envPairs === undefined) @@ -353,7 +360,8 @@ ChildProcess.prototype.spawn = function(options) { options.envPairs); } - options.envPairs.push('NODE_CHANNEL_FD=' + ipcFd); + options.envPairs.push(`NODE_CHANNEL_FD=${ipcFd}`); + options.envPairs.push(`NODE_CHANNEL_SERIALIZATION_MODE=${serialization}`); } validateString(options.file, 'options.file'); @@ -446,7 +454,7 @@ ChildProcess.prototype.spawn = function(options) { this.stdio.push(stdio[i].socket === undefined ? null : stdio[i].socket); // Add .send() method and start listening for IPC data - if (ipc !== undefined) setupChannel(this, ipc); + if (ipc !== undefined) setupChannel(this, ipc, serialization); return err; }; @@ -516,7 +524,8 @@ class Control extends EventEmitter { const channelDeprecationMsg = '_channel is deprecated. ' + 'Use ChildProcess.channel instead.'; -function setupChannel(target, channel) { +let serialization; +function setupChannel(target, channel, serializationMode) { target.channel = channel; Object.defineProperty(target, '_channel', { @@ -535,12 +544,16 @@ function setupChannel(target, channel) { const control = new Control(channel); - if (StringDecoder === undefined) - StringDecoder = require('string_decoder').StringDecoder; - const decoder = new StringDecoder('utf8'); - var jsonBuffer = ''; - var pendingHandle = null; - channel.buffering = false; + if (serialization === undefined) + serialization = require('internal/child_process/serialization'); + const { + initMessageChannel, + parseChannelMessages, + writeChannelMessage + } = serialization[serializationMode]; + + let pendingHandle = null; + initMessageChannel(channel); channel.pendingHandle = null; channel.onread = function(arrayBuffer) { const recvHandle = channel.pendingHandle; @@ -552,21 +565,7 @@ function setupChannel(target, channel) { if (recvHandle) pendingHandle = recvHandle; - // Linebreak is used as a message end sign - var chunks = decoder.write(pool).split('\n'); - var numCompleteChunks = chunks.length - 1; - // Last line does not have trailing linebreak - var incompleteChunk = chunks[numCompleteChunks]; - if (numCompleteChunks === 0) { - jsonBuffer += incompleteChunk; - this.buffering = jsonBuffer.length !== 0; - return; - } - chunks[0] = jsonBuffer + chunks[0]; - - for (var i = 0; i < numCompleteChunks; i++) { - var message = JSON.parse(chunks[i]); - + for (const message of parseChannelMessages(channel, pool)) { // There will be at most one NODE_HANDLE message in every chunk we // read because SCM_RIGHTS messages don't get coalesced. Make sure // that we deliver the handle with the right message however. @@ -581,9 +580,6 @@ function setupChannel(target, channel) { handleMessage(message, undefined, false); } } - jsonBuffer = incompleteChunk; - this.buffering = jsonBuffer.length !== 0; - } else { this.buffering = false; target.disconnect(); @@ -782,8 +778,7 @@ function setupChannel(target, channel) { const req = new WriteWrap(); - const string = JSON.stringify(message) + '\n'; - const err = channel.writeUtf8String(req, string, handle); + const err = writeChannelMessage(channel, req, message, handle); const wasAsyncWrite = streamBaseState[kLastWriteWasAsync]; if (err === 0) { diff --git a/lib/internal/child_process/serialization.js b/lib/internal/child_process/serialization.js new file mode 100644 index 00000000000000..1381f299265e4c --- /dev/null +++ b/lib/internal/child_process/serialization.js @@ -0,0 +1,119 @@ +'use strict'; + +const { JSON } = primordials; +const { Buffer } = require('buffer'); +const { StringDecoder } = require('string_decoder'); +const v8 = require('v8'); +const { isArrayBufferView } = require('internal/util/types'); +const assert = require('internal/assert'); + +const kMessageBuffer = Symbol('kMessageBuffer'); +const kJSONBuffer = Symbol('kJSONBuffer'); +const kStringDecoder = Symbol('kStringDecoder'); + +// Extend V8's serializer APIs to give more JSON-like behaviour in +// some cases; in particular, for native objects this serializes them the same +// way that JSON does rather than throwing an exception. +const kArrayBufferViewTag = 0; +const kNotArrayBufferViewTag = 1; +class ChildProcessSerializer extends v8.DefaultSerializer { + _writeHostObject(object) { + if (isArrayBufferView(object)) { + this.writeUint32(kArrayBufferViewTag); + return super._writeHostObject(object); + } else { + this.writeUint32(kNotArrayBufferViewTag); + this.writeValue({ ...object }); + } + } +} + +class ChildProcessDeserializer extends v8.DefaultDeserializer { + _readHostObject() { + const tag = this.readUint32(); + if (tag === kArrayBufferViewTag) + return super._readHostObject(); + + assert(tag === kNotArrayBufferViewTag); + return this.readValue(); + } +} + +// Messages are parsed in either of the following formats: +// - Newline-delimited JSON, or +// - V8-serialized buffers, prefixed with their length as a big endian uint32 +// (aka 'advanced') +const advanced = { + initMessageChannel(channel) { + channel[kMessageBuffer] = Buffer.alloc(0); + channel.buffering = false; + }, + + *parseChannelMessages(channel, readData) { + if (readData.length === 0) return; + + let messageBuffer = Buffer.concat([channel[kMessageBuffer], readData]); + while (messageBuffer.length > 4) { + const size = messageBuffer.readUInt32BE(); + if (messageBuffer.length < 4 + size) { + break; + } + + const deserializer = new ChildProcessDeserializer( + messageBuffer.subarray(4, 4 + size)); + messageBuffer = messageBuffer.subarray(4 + size); + + deserializer.readHeader(); + yield deserializer.readValue(); + } + channel[kMessageBuffer] = messageBuffer; + channel.buffering = messageBuffer.length > 0; + }, + + writeChannelMessage(channel, req, message, handle) { + const ser = new ChildProcessSerializer(); + ser.writeHeader(); + ser.writeValue(message); + const serializedMessage = ser.releaseBuffer(); + const sizeBuffer = Buffer.allocUnsafe(4); + sizeBuffer.writeUInt32BE(serializedMessage.length); + return channel.writeBuffer(req, Buffer.concat([ + sizeBuffer, + serializedMessage + ]), handle); + }, +}; + +const json = { + initMessageChannel(channel) { + channel[kJSONBuffer] = ''; + channel[kStringDecoder] = undefined; + }, + + *parseChannelMessages(channel, readData) { + if (readData.length === 0) return; + + if (channel[kStringDecoder] === undefined) + channel[kStringDecoder] = new StringDecoder('utf8'); + const chunks = channel[kStringDecoder].write(readData).split('\n'); + const numCompleteChunks = chunks.length - 1; + // Last line does not have trailing linebreak + const incompleteChunk = chunks[numCompleteChunks]; + if (numCompleteChunks === 0) { + channel[kJSONBuffer] += incompleteChunk; + } else { + chunks[0] = channel[kJSONBuffer] + chunks[0]; + for (let i = 0; i < numCompleteChunks; i++) + yield JSON.parse(chunks[i]); + channel[kJSONBuffer] = incompleteChunk; + } + channel.buffering = channel[kJSONBuffer].length !== 0; + }, + + writeChannelMessage(channel, req, message, handle) { + const string = JSON.stringify(message) + '\n'; + return channel.writeUtf8String(req, string, handle); + }, +}; + +module.exports = { advanced, json }; diff --git a/lib/internal/cluster/master.js b/lib/internal/cluster/master.js index a881021c5e01ce..005de8aa1b3cbf 100644 --- a/lib/internal/cluster/master.js +++ b/lib/internal/cluster/master.js @@ -130,6 +130,7 @@ function createWorkerProcess(id, env) { return fork(cluster.settings.exec, cluster.settings.args, { cwd: cluster.settings.cwd, env: workerEnv, + serialization: cluster.settings.serialization, silent: cluster.settings.silent, windowsHide: cluster.settings.windowsHide, execArgv: execArgv, diff --git a/lib/internal/cluster/worker.js b/lib/internal/cluster/worker.js index 9d9c5dce839035..4563b2e663b686 100644 --- a/lib/internal/cluster/worker.js +++ b/lib/internal/cluster/worker.js @@ -1,6 +1,10 @@ 'use strict'; -const { Object } = primordials; +const { + Object: { + setPrototypeOf: ObjectSetPrototypeOf + } +} = primordials; const EventEmitter = require('events'); @@ -32,8 +36,8 @@ function Worker(options) { } } -Object.setPrototypeOf(Worker.prototype, EventEmitter.prototype); -Object.setPrototypeOf(Worker, EventEmitter); +ObjectSetPrototypeOf(Worker.prototype, EventEmitter.prototype); +ObjectSetPrototypeOf(Worker, EventEmitter); Worker.prototype.kill = function() { this.destroy.apply(this, arguments); diff --git a/lib/internal/crypto/cipher.js b/lib/internal/crypto/cipher.js index 4eb1aee69c9ecc..133b1e51532fc7 100644 --- a/lib/internal/crypto/cipher.js +++ b/lib/internal/crypto/cipher.js @@ -66,11 +66,11 @@ function rsaFunctionFor(method, defaultPadding, keyType) { const publicEncrypt = rsaFunctionFor(_publicEncrypt, RSA_PKCS1_OAEP_PADDING, 'public'); const publicDecrypt = rsaFunctionFor(_publicDecrypt, RSA_PKCS1_PADDING, - 'private'); + 'public'); const privateEncrypt = rsaFunctionFor(_privateEncrypt, RSA_PKCS1_PADDING, 'private'); const privateDecrypt = rsaFunctionFor(_privateDecrypt, RSA_PKCS1_OAEP_PADDING, - 'public'); + 'private'); function getDecoder(decoder, encoding) { encoding = normalizeEncoding(encoding); diff --git a/lib/internal/crypto/sig.js b/lib/internal/crypto/sig.js index 9b9c32e59c8fd0..6eda8455643848 100644 --- a/lib/internal/crypto/sig.js +++ b/lib/internal/crypto/sig.js @@ -11,6 +11,8 @@ const { validateString } = require('internal/validators'); const { Sign: _Sign, Verify: _Verify, + kSigEncDER, + kSigEncP1363, signOneShot: _signOneShot, verifyOneShot: _verifyOneShot } = internalBinding('crypto'); @@ -59,6 +61,20 @@ function getSaltLength(options) { return getIntOption('saltLength', options); } +function getDSASignatureEncoding(options) { + if (typeof options === 'object') { + const { dsaEncoding = 'der' } = options; + if (dsaEncoding === 'der') + return kSigEncDER; + else if (dsaEncoding === 'ieee-p1363') + return kSigEncP1363; + else + throw new ERR_INVALID_OPT_VALUE('dsaEncoding', dsaEncoding); + } + + return kSigEncDER; +} + function getIntOption(name, options) { const value = options[name]; if (value !== undefined) { @@ -81,8 +97,11 @@ Sign.prototype.sign = function sign(options, encoding) { const rsaPadding = getPadding(options); const pssSaltLength = getSaltLength(options); + // Options specific to (EC)DSA + const dsaSigEnc = getDSASignatureEncoding(options); + const ret = this[kHandle].sign(data, format, type, passphrase, rsaPadding, - pssSaltLength); + pssSaltLength, dsaSigEnc); encoding = encoding || getDefaultEncoding(); if (encoding && encoding !== 'buffer') @@ -117,8 +136,11 @@ function signOneShot(algorithm, data, key) { const rsaPadding = getPadding(key); const pssSaltLength = getSaltLength(key); + // Options specific to (EC)DSA + const dsaSigEnc = getDSASignatureEncoding(key); + return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data, - algorithm, rsaPadding, pssSaltLength); + algorithm, rsaPadding, pssSaltLength, dsaSigEnc); } function Verify(algorithm, options) { @@ -149,13 +171,15 @@ Verify.prototype.verify = function verify(options, signature, sigEncoding) { // Options specific to RSA const rsaPadding = getPadding(options); - const pssSaltLength = getSaltLength(options); + // Options specific to (EC)DSA + const dsaSigEnc = getDSASignatureEncoding(options); + signature = getArrayBufferView(signature, 'signature', sigEncoding); return this[kHandle].verify(data, format, type, passphrase, signature, - rsaPadding, pssSaltLength); + rsaPadding, pssSaltLength, dsaSigEnc); }; function verifyOneShot(algorithm, data, key, signature) { @@ -181,6 +205,9 @@ function verifyOneShot(algorithm, data, key, signature) { const rsaPadding = getPadding(key); const pssSaltLength = getSaltLength(key); + // Options specific to (EC)DSA + const dsaSigEnc = getDSASignatureEncoding(key); + if (!isArrayBufferView(signature)) { throw new ERR_INVALID_ARG_TYPE( 'signature', @@ -190,7 +217,7 @@ function verifyOneShot(algorithm, data, key, signature) { } return _verifyOneShot(keyData, keyFormat, keyType, keyPassphrase, signature, - data, algorithm, rsaPadding, pssSaltLength); + data, algorithm, rsaPadding, pssSaltLength, dsaSigEnc); } module.exports = { diff --git a/lib/internal/encoding.js b/lib/internal/encoding.js index dabcd5eaccebe0..16de0c986e6cb1 100644 --- a/lib/internal/encoding.js +++ b/lib/internal/encoding.js @@ -484,25 +484,22 @@ function makeTextDecoderJS() { this[kFlags] |= CONVERTER_FLAGS_FLUSH; } - if (!this[kBOMSeen] && !(this[kFlags] & CONVERTER_FLAGS_IGNORE_BOM)) { - if (this[kEncoding] === 'utf-8') { - if (input.length >= 3 && - input[0] === 0xEF && input[1] === 0xBB && input[2] === 0xBF) { - input = input.slice(3); - } - } else if (this[kEncoding] === 'utf-16le') { - if (input.length >= 2 && input[0] === 0xFF && input[1] === 0xFE) { - input = input.slice(2); - } + let result = this[kFlags] & CONVERTER_FLAGS_FLUSH ? + this[kHandle].end(input) : + this[kHandle].write(input); + + if (result.length > 0 && + !this[kBOMSeen] && + !(this[kFlags] & CONVERTER_FLAGS_IGNORE_BOM)) { + // If the very first result in the stream is a BOM, and we are not + // explicitly told to ignore it, then we discard it. + if (result[0] === '\ufeff') { + result = result.slice(1); } this[kBOMSeen] = true; } - if (this[kFlags] & CONVERTER_FLAGS_FLUSH) { - return this[kHandle].end(input); - } - - return this[kHandle].write(input); + return result; } } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index cd3c162183292c..6d4a582631810c 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -981,7 +981,7 @@ E('ERR_INVALID_OPT_VALUE', (name, value) => E('ERR_INVALID_OPT_VALUE_ENCODING', 'The value "%s" is invalid for option "encoding"', TypeError); E('ERR_INVALID_PACKAGE_CONFIG', - 'Invalid package config in \'%s\' imported from %s', Error); + 'Invalid package config for \'%s\', %s', Error); E('ERR_INVALID_PERFORMANCE_MARK', 'The "%s" performance mark has not been set', Error); E('ERR_INVALID_PROTOCOL', @@ -1226,6 +1226,8 @@ E('ERR_VM_MODULE_STATUS', 'Module status %s', Error); E('ERR_WORKER_INVALID_EXEC_ARGV', (errors) => `Initiated Worker with invalid execArgv flags: ${errors.join(', ')}`, Error); +E('ERR_WORKER_OUT_OF_MEMORY', 'Worker terminated due to reaching memory limit', + Error); E('ERR_WORKER_PATH', 'The worker script filename must be an absolute path or a relative ' + 'path starting with \'./\' or \'../\'. Received "%s"', diff --git a/lib/internal/fs/watchers.js b/lib/internal/fs/watchers.js index 4dfa83c3b218e2..c974f40aae104f 100644 --- a/lib/internal/fs/watchers.js +++ b/lib/internal/fs/watchers.js @@ -174,6 +174,12 @@ FSWatcher.prototype[kFSWatchStart] = function(filename, } }; +// To maximize backward-compatiblity for the end user, +// a no-op stub method has been added instead of +// totally removing FSWatcher.prototpye.start. +// This should not be documented. +FSWatcher.prototype.start = () => {}; + // This method is a noop if the watcher has not been started or // has already been closed. FSWatcher.prototype.close = function() { diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 2d6ed47d74e29f..5bc64504cd3d74 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -503,6 +503,10 @@ class Http2ServerResponse extends Stream { return this[kState].statusCode; } + get writableCorked() { + return this[kStream].writableCorked; + } + set statusCode(code) { code |= 0; if (code >= 100 && code < 200) @@ -627,6 +631,14 @@ class Http2ServerResponse extends Stream { return this; } + cork() { + this[kStream].cork(); + } + + uncork() { + this[kStream].uncork(); + } + write(chunk, encoding, cb) { if (typeof encoding === 'function') { cb = encoding; diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 95ce8bcdb4ede8..fded7067b5b3dd 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -2932,7 +2932,6 @@ Object.defineProperty(connect, promisify.custom, { }); function createSecureServer(options, handler) { - assertIsObject(options, 'options'); return new Http2SecureServer(options, handler); } @@ -2941,7 +2940,6 @@ function createServer(options, handler) { handler = options; options = {}; } - assertIsObject(options, 'options'); return new Http2Server(options, handler); } diff --git a/lib/internal/main/check_syntax.js b/lib/internal/main/check_syntax.js index a3aba9a00fb5e2..c5d919bd15bfab 100644 --- a/lib/internal/main/check_syntax.js +++ b/lib/internal/main/check_syntax.js @@ -47,21 +47,18 @@ if (process.argv[1] && process.argv[1] !== '-') { function checkSyntax(source, filename) { const { getOptionValue } = require('internal/options'); - const experimentalModules = getOptionValue('--experimental-modules'); - if (experimentalModules) { - let isModule = false; - if (filename === '[stdin]' || filename === '[eval]') { - isModule = getOptionValue('--input-type') === 'module'; - } else { - const resolve = require('internal/modules/esm/default_resolve'); - const { format } = resolve(pathToFileURL(filename).toString()); - isModule = format === 'module'; - } - if (isModule) { - const { ModuleWrap } = internalBinding('module_wrap'); - new ModuleWrap(filename, undefined, source, 0, 0); - return; - } + let isModule = false; + if (filename === '[stdin]' || filename === '[eval]') { + isModule = getOptionValue('--input-type') === 'module'; + } else { + const resolve = require('internal/modules/esm/default_resolve'); + const { format } = resolve(pathToFileURL(filename).toString()); + isModule = format === 'module'; + } + if (isModule) { + const { ModuleWrap } = internalBinding('module_wrap'); + new ModuleWrap(filename, undefined, source, 0, 0); + return; } wrapSafe(filename, source); diff --git a/lib/internal/main/run_main_module.js b/lib/internal/main/run_main_module.js index 77d997b97a1c7a..ca5d1122c59d94 100644 --- a/lib/internal/main/run_main_module.js +++ b/lib/internal/main/run_main_module.js @@ -6,11 +6,12 @@ const { prepareMainThreadExecution(true); -const CJSModule = require('internal/modules/cjs/loader').Module; - markBootstrapComplete(); -// Note: this loads the module through the ESM loader if -// --experimental-loader is provided or --experimental-modules is on -// and the module is determined to be an ES module -CJSModule.runMain(process.argv[1]); +// Note: this loads the module through the ESM loader if the module is +// determined to be an ES module. This hangs from the CJS module loader +// because we currently allow monkey-patching of the module loaders +// in the preloaded scripts through require('module'). +// runMain here might be monkey-patched by users in --require. +// XXX: the monkey-patchability here should probably be deprecated. +require('internal/modules/cjs/loader').Module.runMain(process.argv[1]); diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index 7cf8ffb8b401f5..13d7e8de0ec75c 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -108,6 +108,9 @@ port.on('message', (message) => { initializeDeprecations(); initializeCJSLoader(); initializeESMLoader(); + + const CJSLoader = require('internal/modules/cjs/loader'); + assert(!CJSLoader.hasLoadedAnyUserCJSModule); loadPreloadModules(); initializeFrozenIntrinsics(); publicWorker.parentPort = publicPort; @@ -141,8 +144,9 @@ port.on('message', (message) => { evalScript('[worker eval]', filename); } else { // script filename - const CJSModule = require('internal/modules/cjs/loader').Module; - CJSModule.runMain(process.argv[1] = filename); + // runMain here might be monkey-patched by users in --require. + // XXX: the monkey-patchability here should probably be deprecated. + CJSLoader.Module.runMain(process.argv[1] = filename); } } else if (message.type === STDIO_PAYLOAD) { const { stream, chunk, encoding } = message; diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index 7a9870024515ed..b75f67c0a4ddad 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -6,8 +6,6 @@ const { ERR_UNKNOWN_BUILTIN_MODULE } = require('internal/errors').codes; const { NativeModule } = require('internal/bootstrap/loaders'); -const { getOptionValue } = require('internal/options'); -const experimentalModules = getOptionValue('--experimental-modules'); const { validateString } = require('internal/validators'); const path = require('path'); @@ -16,11 +14,11 @@ const { URL } = require('url'); const debug = require('internal/util/debuglog').debuglog('module'); -function loadNativeModule(filename, request, experimentalModules) { +function loadNativeModule(filename, request) { const mod = NativeModule.map.get(filename); if (mod) { debug('load native module %s', request); - mod.compileForPublicLoader(experimentalModules); + mod.compileForPublicLoader(); return mod; } } @@ -45,10 +43,7 @@ function makeRequireFunction(mod, redirects) { const href = destination.href; if (destination.protocol === 'node:') { const specifier = destination.pathname; - const mod = loadNativeModule( - specifier, - href, - experimentalModules); + const mod = loadNativeModule(specifier, href); if (mod && mod.canBeRequiredByUsers) { return mod.exports; } diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 7df91ce4fd1c67..ae9e839523b754 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -57,27 +57,31 @@ const { getOptionValue } = require('internal/options'); const enableSourceMaps = getOptionValue('--enable-source-maps'); const preserveSymlinks = getOptionValue('--preserve-symlinks'); const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); -const experimentalModules = getOptionValue('--experimental-modules'); const experimentalSelf = getOptionValue('--experimental-resolve-self'); +const experimentalConditionalExports = + getOptionValue('--experimental-conditional-exports'); const manifest = getOptionValue('--experimental-policy') ? require('internal/process/policy').manifest : null; const { compileFunction } = internalBinding('contextify'); +// Whether any user-provided CJS modules had been loaded (executed). +// Used for internal assertions. +let hasLoadedAnyUserCJSModule = false; + const { ERR_INVALID_ARG_VALUE, ERR_INVALID_OPT_VALUE, + ERR_INVALID_PACKAGE_CONFIG, ERR_REQUIRE_ESM } = require('internal/errors').codes; const { validateString } = require('internal/validators'); -const { - resolveMainPath, - shouldUseESMLoader, - runMainESM -} = require('internal/bootstrap/pre_execution'); const pendingDeprecation = getOptionValue('--pending-deprecation'); -module.exports = { wrapSafe, Module, toRealPath, readPackageScope }; +module.exports = { + wrapSafe, Module, toRealPath, readPackageScope, + get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; } +}; let asyncESM, ModuleJob, ModuleWrap, kInstantiated; @@ -157,7 +161,7 @@ Module.builtinModules = builtinModules; Module._cache = Object.create(null); Module._pathCache = Object.create(null); Module._extensions = Object.create(null); -var modulePaths = []; +let modulePaths = []; Module.globalPaths = []; let patched = false; @@ -346,7 +350,7 @@ function toRealPath(requestPath) { // Given a path, check if the file exists with any of the set extensions function tryExtensions(p, exts, isMain) { - for (var i = 0; i < exts.length; i++) { + for (let i = 0; i < exts.length; i++) { const filename = tryFile(p + exts[i], isMain); if (filename) { @@ -441,7 +445,6 @@ function trySelf(paths, exts, isMain, trailingSlash, request) { if (expansion) { // Use exports const fromExports = applyExports(basePath, expansion); - if (!fromExports) return false; return resolveBasePath(fromExports, exts, isMain, trailingSlash, request); } else { // Use main field @@ -449,17 +452,51 @@ function trySelf(paths, exts, isMain, trailingSlash, request) { } } +function isConditionalDotExportSugar(exports, basePath) { + if (typeof exports === 'string') + return true; + if (Array.isArray(exports)) + return true; + if (typeof exports !== 'object') + return false; + let isConditional = false; + let firstCheck = true; + for (const key of Object.keys(exports)) { + const curIsConditional = key[0] !== '.'; + if (firstCheck) { + firstCheck = false; + isConditional = curIsConditional; + } else if (isConditional !== curIsConditional) { + throw new ERR_INVALID_PACKAGE_CONFIG(basePath, '"exports" cannot ' + + 'contain some keys starting with \'.\' and some not. The exports ' + + 'object must either be an object of package subpath keys or an ' + + 'object of main entry condition name keys only.'); + } + } + return isConditional; +} + function applyExports(basePath, expansion) { - const pkgExports = readPackageExports(basePath); const mappingKey = `.${expansion}`; - if (typeof pkgExports === 'object' && pkgExports !== null) { + let pkgExports = readPackageExports(basePath); + if (pkgExports === undefined || pkgExports === null) + return path.resolve(basePath, mappingKey); + + if (isConditionalDotExportSugar(pkgExports, basePath)) + pkgExports = { '.': pkgExports }; + + if (typeof pkgExports === 'object') { if (ObjectPrototype.hasOwnProperty(pkgExports, mappingKey)) { const mapping = pkgExports[mappingKey]; return resolveExportsTarget(pathToFileURL(basePath + '/'), mapping, '', basePath, mappingKey); } + // Fallback to CJS main lookup when no main export is defined + if (mappingKey === '.') + return basePath; + let dirMatch = ''; for (const candidateKey of Object.keys(pkgExports)) { if (candidateKey[candidateKey.length - 1] !== '/') continue; @@ -476,19 +513,15 @@ function applyExports(basePath, expansion) { subpath, basePath, mappingKey); } } - if (mappingKey === '.' && typeof pkgExports === 'string') { - return resolveExportsTarget(pathToFileURL(basePath + '/'), pkgExports, - '', basePath, mappingKey); - } - if (pkgExports != null) { - // eslint-disable-next-line no-restricted-syntax - const e = new Error(`Package exports for '${basePath}' do not define ` + - `a '${mappingKey}' subpath`); - e.code = 'MODULE_NOT_FOUND'; - throw e; - } + // Fallback to CJS main lookup when no main export is defined + if (mappingKey === '.') + return basePath; - return path.resolve(basePath, mappingKey); + // eslint-disable-next-line no-restricted-syntax + const e = new Error(`Package exports for '${basePath}' do not define ` + + `a '${mappingKey}' subpath`); + e.code = 'MODULE_NOT_FOUND'; + throw e; } // This only applies to requests of a specific form: @@ -532,7 +565,7 @@ function resolveExportsTarget(pkgPath, target, subpath, basePath, mappingKey) { } } else if (Array.isArray(target)) { for (const targetValue of target) { - if (typeof targetValue !== 'string') continue; + if (Array.isArray(targetValue)) continue; try { return resolveExportsTarget(pkgPath, targetValue, subpath, basePath, mappingKey); @@ -540,10 +573,43 @@ function resolveExportsTarget(pkgPath, target, subpath, basePath, mappingKey) { if (e.code !== 'MODULE_NOT_FOUND') throw e; } } + } else if (typeof target === 'object' && target !== null) { + if (experimentalConditionalExports && + ObjectPrototype.hasOwnProperty(target, 'require')) { + try { + return resolveExportsTarget(pkgPath, target.require, subpath, + basePath, mappingKey); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') throw e; + } + } + if (experimentalConditionalExports && + ObjectPrototype.hasOwnProperty(target, 'node')) { + try { + return resolveExportsTarget(pkgPath, target.node, subpath, + basePath, mappingKey); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') throw e; + } + } + if (ObjectPrototype.hasOwnProperty(target, 'default')) { + try { + return resolveExportsTarget(pkgPath, target.default, subpath, + basePath, mappingKey); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') throw e; + } + } + } + let e; + if (mappingKey !== '.') { + // eslint-disable-next-line no-restricted-syntax + e = new Error(`Package exports for '${basePath}' do not define a ` + + `valid '${mappingKey}' target${subpath ? ' for ' + subpath : ''}`); + } else { + // eslint-disable-next-line no-restricted-syntax + e = new Error(`No valid exports main found for '${basePath}'`); } - // eslint-disable-next-line no-restricted-syntax - const e = new Error(`Package exports for '${basePath}' do not define a ` + - `valid '${mappingKey}' target${subpath ? 'for ' + subpath : ''}`); e.code = 'MODULE_NOT_FOUND'; throw e; } @@ -562,22 +628,22 @@ Module._findPath = function(request, paths, isMain) { if (entry) return entry; - var exts; - var trailingSlash = request.length > 0 && + let exts; + let trailingSlash = request.length > 0 && request.charCodeAt(request.length - 1) === CHAR_FORWARD_SLASH; if (!trailingSlash) { trailingSlash = /(?:^|\/)\.?\.$/.test(request); } // For each path - for (var i = 0; i < paths.length; i++) { + for (let i = 0; i < paths.length; i++) { // Don't search further if path doesn't exist const curPath = paths[i]; if (curPath && stat(curPath) < 1) continue; - var basePath = resolveExports(curPath, request, absoluteRequest); - var filename; + const basePath = resolveExports(curPath, request, absoluteRequest); + let filename; - var rc = stat(basePath); + const rc = stat(basePath); if (!trailingSlash) { if (rc === 0) { // File. if (!isMain) { @@ -651,9 +717,7 @@ if (isWindows) { return [from + 'node_modules']; const paths = []; - var p = 0; - var last = from.length; - for (var i = from.length - 1; i >= 0; --i) { + for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { const code = from.charCodeAt(i); // The path segment separator check ('\' and '/') was used to get // node_modules path for every path segment. @@ -692,9 +756,7 @@ if (isWindows) { // to be absolute. Doing a fully-edge-case-correct path.split // that works on both Windows and Posix is non-trivial. const paths = []; - var p = 0; - var last = from.length; - for (var i = from.length - 1; i >= 0; --i) { + for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) { const code = from.charCodeAt(i); if (code === CHAR_FORWARD_SLASH) { if (p !== nmLen) @@ -790,7 +852,7 @@ Module._load = function(request, parent, isMain) { return cachedModule.exports; } - const mod = loadNativeModule(filename, request, experimentalModules); + const mod = loadNativeModule(filename, request); if (mod && mod.canBeRequiredByUsers) return mod.exports; // Don't call updateChildren(), Module constructor already does. @@ -839,7 +901,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { return request; } - var paths; + let paths; if (typeof options === 'object' && options !== null) { if (Array.isArray(options.paths)) { @@ -855,12 +917,12 @@ Module._resolveFilename = function(request, parent, isMain, options) { paths = []; - for (var i = 0; i < options.paths.length; i++) { + for (let i = 0; i < options.paths.length; i++) { const path = options.paths[i]; fakeParent.paths = Module._nodeModulePaths(path); const lookupPaths = Module._resolveLookupPaths(request, fakeParent); - for (var j = 0; j < lookupPaths.length; j++) { + for (let j = 0; j < lookupPaths.length; j++) { if (!paths.includes(lookupPaths[j])) paths.push(lookupPaths[j]); } @@ -879,7 +941,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { const filename = Module._findPath(request, paths, isMain); if (!filename) { const requireStack = []; - for (var cursor = parent; + for (let cursor = parent; cursor; cursor = cursor.parent) { requireStack.push(cursor.filename || cursor.id); @@ -889,7 +951,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { message = message + '\nRequire stack:\n- ' + requireStack.join('\n- '); } // eslint-disable-next-line no-restricted-syntax - var err = new Error(message); + const err = new Error(message); err.code = 'MODULE_NOT_FOUND'; err.requireStack = requireStack; throw err; @@ -914,31 +976,29 @@ Module.prototype.load = function(filename) { Module._extensions[extension](this, filename); this.loaded = true; - if (experimentalModules) { - const ESMLoader = asyncESM.ESMLoader; - const url = `${pathToFileURL(filename)}`; - const module = ESMLoader.moduleMap.get(url); - // Create module entry at load time to snapshot exports correctly - const exports = this.exports; - // Called from cjs translator - if (module !== undefined && module.module !== undefined) { - if (module.module.getStatus() >= kInstantiated) - module.module.setExport('default', exports); - } else { - // Preemptively cache - // We use a function to defer promise creation for async hooks. - ESMLoader.moduleMap.set( - url, - // Module job creation will start promises. - // We make it a function to lazily trigger those promises - // for async hooks compatibility. - () => new ModuleJob(ESMLoader, url, () => - new ModuleWrap(url, undefined, ['default'], function() { - this.setExport('default', exports); - }) - , false /* isMain */, false /* inspectBrk */) - ); - } + const ESMLoader = asyncESM.ESMLoader; + const url = `${pathToFileURL(filename)}`; + const module = ESMLoader.moduleMap.get(url); + // Create module entry at load time to snapshot exports correctly + const exports = this.exports; + // Called from cjs translator + if (module !== undefined && module.module !== undefined) { + if (module.module.getStatus() >= kInstantiated) + module.module.setExport('default', exports); + } else { + // Preemptively cache + // We use a function to defer promise creation for async hooks. + ESMLoader.moduleMap.set( + url, + // Module job creation will start promises. + // We make it a function to lazily trigger those promises + // for async hooks compatibility. + () => new ModuleJob(ESMLoader, url, () => + new ModuleWrap(url, undefined, ['default'], function() { + this.setExport('default', exports); + }) + , false /* isMain */, false /* inspectBrk */) + ); } }; @@ -962,7 +1022,7 @@ Module.prototype.require = function(id) { // Resolved path to process.argv[1] will be lazily placed here // (needed for setting breakpoint when called with --inspect-brk) -var resolvedArgv; +let resolvedArgv; let hasPausedEntry = false; function wrapSafe(filename, content, cjsModuleInstance) { @@ -972,10 +1032,10 @@ function wrapSafe(filename, content, cjsModuleInstance) { filename, lineOffset: 0, displayErrors: true, - importModuleDynamically: experimentalModules ? async (specifier) => { + importModuleDynamically: async (specifier) => { const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); - } : undefined, + }, }); } let compiled; @@ -998,20 +1058,18 @@ function wrapSafe(filename, content, cjsModuleInstance) { ] ); } catch (err) { - if (experimentalModules && process.mainModule === cjsModuleInstance) + if (process.mainModule === cjsModuleInstance) enrichCJSError(err); throw err; } - if (experimentalModules) { - const { callbackMap } = internalBinding('module_wrap'); - callbackMap.set(compiled.cacheKey, { - importModuleDynamically: async (specifier) => { - const loader = asyncESM.ESMLoader; - return loader.import(specifier, normalizeReferrerURL(filename)); - } - }); - } + const { callbackMap } = internalBinding('module_wrap'); + callbackMap.set(compiled.cacheKey, { + importModuleDynamically: async (specifier) => { + const loader = asyncESM.ESMLoader; + return loader.import(specifier, normalizeReferrerURL(filename)); + } + }); return compiled.function; } @@ -1032,7 +1090,7 @@ Module.prototype._compile = function(content, filename) { maybeCacheSourceMap(filename, content, this); const compiledWrapper = wrapSafe(filename, content, this); - var inspectorWrapper = null; + let inspectorWrapper = null; if (getOptionValue('--inspect-brk') && process._eval == null) { if (!resolvedArgv) { // We enter the repl if we're not given a filename argument. @@ -1051,7 +1109,7 @@ Module.prototype._compile = function(content, filename) { } const dirname = path.dirname(filename); const require = makeRequireFunction(this, redirects); - var result; + let result; const exports = this.exports; const thisValue = exports; const module = this; @@ -1063,6 +1121,7 @@ Module.prototype._compile = function(content, filename) { result = compiledWrapper.call(thisValue, exports, require, module, filename, dirname); } + hasLoadedAnyUserCJSModule = true; if (requireDepth === 0) statCache = null; return result; }; @@ -1094,9 +1153,7 @@ Module._extensions['.js'] = function(module, filename) { ); warnRequireESM = false; } - if (experimentalModules) { - throw new ERR_REQUIRE_ESM(filename); - } + throw new ERR_REQUIRE_ESM(filename); } } const content = fs.readFileSync(filename, 'utf8'); @@ -1133,17 +1190,6 @@ Module._extensions['.node'] = function(module, filename) { return process.dlopen(module, path.toNamespacedPath(filename)); }; -// Bootstrap main module. -Module.runMain = function(main = process.argv[1]) { - const resolvedMain = resolveMainPath(main); - const useESMLoader = shouldUseESMLoader(resolvedMain); - if (useESMLoader) { - runMainESM(resolvedMain || main); - } else { - Module._load(main, null, true); - } -}; - function createRequireFromPath(filename) { // Allow a directory to be passed as the filename const trailingSlash = @@ -1192,26 +1238,16 @@ function createRequire(filename) { Module.createRequire = createRequire; Module._initPaths = function() { - var homeDir; - var nodePath; - if (isWindows) { - homeDir = process.env.USERPROFILE; - nodePath = process.env.NODE_PATH; - } else { - homeDir = safeGetenv('HOME'); - nodePath = safeGetenv('NODE_PATH'); - } + const homeDir = isWindows ? process.env.USERPROFILE : safeGetenv('HOME'); + const nodePath = isWindows ? process.env.NODE_PATH : safeGetenv('NODE_PATH'); - // $PREFIX/lib/node, where $PREFIX is the root of the Node.js installation. - var prefixDir; // process.execPath is $PREFIX/bin/node except on Windows where it is - // $PREFIX\node.exe. - if (isWindows) { - prefixDir = path.resolve(process.execPath, '..'); - } else { - prefixDir = path.resolve(process.execPath, '..', '..'); - } - var paths = [path.resolve(prefixDir, 'lib', 'node')]; + // $PREFIX\node.exe where $PREFIX is the root of the Node.js installation. + const prefixDir = isWindows ? + path.resolve(process.execPath, '..') : + path.resolve(process.execPath, '..', '..'); + + let paths = [path.resolve(prefixDir, 'lib', 'node')]; if (homeDir) { paths.unshift(path.resolve(homeDir, '.node_libraries')); @@ -1245,7 +1281,7 @@ Module._preloadModules = function(requests) { throw e; } } - for (var n = 0; n < requests.length; n++) + for (let n = 0; n < requests.length; n++) parent.require(requests[n]); }; @@ -1261,8 +1297,6 @@ Module.syncBuiltinESMExports = function syncBuiltinESMExports() { Module.Module = Module; // We have to load the esm things after module.exports! -if (experimentalModules) { - ModuleJob = require('internal/modules/esm/module_job'); - asyncESM = require('internal/process/esm_loader'); - ({ ModuleWrap, kInstantiated } = internalBinding('module_wrap')); -} +asyncESM = require('internal/process/esm_loader'); +ModuleJob = require('internal/modules/esm/module_job'); +({ ModuleWrap, kInstantiated } = internalBinding('module_wrap')); diff --git a/lib/internal/modules/esm/default_resolve.js b/lib/internal/modules/esm/default_resolve.js index 88af3cb5f8d286..5271c6a0fe0a02 100644 --- a/lib/internal/modules/esm/default_resolve.js +++ b/lib/internal/modules/esm/default_resolve.js @@ -78,9 +78,19 @@ function resolve(specifier, parentURL) { } const isMain = parentURL === undefined; - if (isMain) + if (isMain) { parentURL = pathToFileURL(`${process.cwd()}/`).href; + // This is the initial entry point to the program, and --input-type has + // been passed as an option; but --input-type can only be used with + // --eval, --print or STDIN string input. It is not allowed with file + // input, to avoid user confusion over how expansive the effect of the + // flag should be (i.e. entry point only, package scope surrounding the + // entry point, etc.). + if (typeFlag) + throw new ERR_INPUT_TYPE_NOT_ALLOWED(); + } + let url = moduleWrapResolve(specifier, parentURL); if (isMain ? !preserveSymlinksMain : !preserveSymlinks) { @@ -93,27 +103,13 @@ function resolve(specifier, parentURL) { url.hash = old.hash; } - const type = getPackageType(url.href); - const ext = extname(url.pathname); - const extMap = - type !== TYPE_MODULE ? legacyExtensionFormatMap : extensionFormatMap; - let format = extMap[ext]; - - if (isMain && typeFlag) { - // This is the initial entry point to the program, and --input-type has - // been passed as an option; but --input-type can only be used with - // --eval, --print or STDIN string input. It is not allowed with file - // input, to avoid user confusion over how expansive the effect of the - // flag should be (i.e. entry point only, package scope surrounding the - // entry point, etc.). - throw new ERR_INPUT_TYPE_NOT_ALLOWED(); - } + let format = extensionFormatMap[ext]; + if (ext === '.js' || (!format && isMain)) + format = getPackageType(url.href) === TYPE_MODULE ? 'module' : 'commonjs'; if (!format) { - if (isMain) - format = type === TYPE_MODULE ? 'module' : 'commonjs'; - else if (esModuleSpecifierResolution === 'node') - format = 'commonjs'; + if (esModuleSpecifierResolution === 'node') + format = legacyExtensionFormatMap[ext]; else throw new ERR_UNKNOWN_FILE_EXTENSION(fileURLToPath(url)); } diff --git a/lib/internal/modules/run_main.js b/lib/internal/modules/run_main.js new file mode 100644 index 00000000000000..1061727c78269c --- /dev/null +++ b/lib/internal/modules/run_main.js @@ -0,0 +1,73 @@ +'use strict'; + +const CJSLoader = require('internal/modules/cjs/loader'); +const { Module, toRealPath, readPackageScope } = CJSLoader; +const { getOptionValue } = require('internal/options'); +const path = require('path'); + +function resolveMainPath(main) { + // Note extension resolution for the main entry point can be deprecated in a + // future major. + // Module._findPath is monkey-patchable here. + let mainPath = Module._findPath(path.resolve(main), null, true); + if (!mainPath) + return; + + const preserveSymlinksMain = getOptionValue('--preserve-symlinks-main'); + if (!preserveSymlinksMain) + mainPath = toRealPath(mainPath); + + return mainPath; +} + +function shouldUseESMLoader(mainPath) { + const userLoader = getOptionValue('--experimental-loader'); + if (userLoader) + return true; + // Determine the module format of the main + if (mainPath && mainPath.endsWith('.mjs')) + return true; + if (!mainPath || mainPath.endsWith('.cjs')) + return false; + const pkg = readPackageScope(mainPath); + return pkg && pkg.data.type === 'module'; +} + +function runMainESM(mainPath) { + const esmLoader = require('internal/process/esm_loader'); + const { pathToFileURL } = require('internal/url'); + const { hasUncaughtExceptionCaptureCallback } = + require('internal/process/execution'); + return esmLoader.initializeLoader().then(() => { + const main = path.isAbsolute(mainPath) ? + pathToFileURL(mainPath).href : mainPath; + return esmLoader.ESMLoader.import(main); + }).catch((e) => { + if (hasUncaughtExceptionCaptureCallback()) { + process._fatalException(e); + return; + } + internalBinding('errors').triggerUncaughtException( + e, + true /* fromPromise */ + ); + }); +} + +// For backwards compatibility, we have to run a bunch of +// monkey-patchable code that belongs to the CJS loader (exposed by +// `require('module')`) even when the entry point is ESM. +function executeUserEntryPoint(main = process.argv[1]) { + const resolvedMain = resolveMainPath(main); + const useESMLoader = shouldUseESMLoader(resolvedMain); + if (useESMLoader) { + runMainESM(resolvedMain || main); + } else { + // Module._load is the monkey-patchable CJS module loader. + Module._load(main, null, true); + } +} + +module.exports = { + executeUserEntryPoint +}; diff --git a/lib/internal/process/esm_loader.js b/lib/internal/process/esm_loader.js index 49463e284c541f..19099d9cbd58fd 100644 --- a/lib/internal/process/esm_loader.js +++ b/lib/internal/process/esm_loader.js @@ -42,6 +42,9 @@ let calledInitialize = false; exports.initializeLoader = initializeLoader; async function initializeLoader() { assert(calledInitialize === false); + process.emitWarning( + 'The ESM module loader is experimental.', + 'ExperimentalWarning', undefined); calledInitialize = true; if (!userLoader) return; diff --git a/lib/internal/querystring.js b/lib/internal/querystring.js index ca978eb69d7860..ecb4e072d83873 100644 --- a/lib/internal/querystring.js +++ b/lib/internal/querystring.js @@ -3,7 +3,7 @@ const { ERR_INVALID_URI } = require('internal/errors').codes; const hexTable = new Array(256); -for (var i = 0; i < 256; ++i) +for (let i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); const isHexTable = [ @@ -30,11 +30,11 @@ function encodeStr(str, noEscapeTable, hexTable) { if (len === 0) return ''; - var out = ''; - var lastPos = 0; + let out = ''; + let lastPos = 0; - for (var i = 0; i < len; i++) { - var c = str.charCodeAt(i); + for (let i = 0; i < len; i++) { + let c = str.charCodeAt(i); // ASCII if (c < 0x80) { @@ -73,7 +73,7 @@ function encodeStr(str, noEscapeTable, hexTable) { if (i >= len) throw new ERR_INVALID_URI(); - var c2 = str.charCodeAt(i) & 0x3FF; + const c2 = str.charCodeAt(i) & 0x3FF; lastPos = i + 1; c = 0x10000 + (((c & 0x3FF) << 10) | c2); diff --git a/lib/internal/source_map/source_map_cache.js b/lib/internal/source_map/source_map_cache.js index 0e77203e9d6f1d..340615eb6cffcd 100644 --- a/lib/internal/source_map/source_map_cache.js +++ b/lib/internal/source_map/source_map_cache.js @@ -1,5 +1,28 @@ 'use strict'; +const { + JSON, + Object: { + create: ObjectCreate, + keys: ObjectKeys, + getOwnPropertyDescriptor: ObjectGetOwnPropertyDescriptor, + }, + ObjectPrototype: { + hasOwnProperty: ObjectHasOwnProperty + }, + MapPrototype: { + entries: MapEntries + }, uncurryThis +} = primordials; + +const MapIteratorNext = uncurryThis(MapEntries(new Map()).next); +const WeakMapGet = uncurryThis(WeakMap.prototype.get); + +function ObjectGetValueSafe(obj, key) { + const desc = ObjectGetOwnPropertyDescriptor(obj, key); + return ObjectHasOwnProperty(desc, 'value') ? desc.value : undefined; +} + // See https://sourcemaps.info/spec.html for SourceMap V3 specification. const { Buffer } = require('buffer'); const debug = require('internal/util/debuglog').debuglog('source_map'); @@ -9,7 +32,6 @@ const { getOptionValue } = require('internal/options'); const { normalizeReferrerURL, } = require('internal/modules/cjs/helpers'); -const { JSON, Object } = primordials; // For cjs, since Module._cache is exposed to users, we use a WeakMap // keyed on module, facilitating garbage collection. const cjsSourceMapCache = new WeakMap(); @@ -17,6 +39,7 @@ const cjsSourceMapCache = new WeakMap(); // on filenames. const esmSourceMapCache = new Map(); const { fileURLToPath, URL } = require('url'); +let Module; let experimentalSourceMaps; function maybeCacheSourceMap(filename, content, cjsModuleInstance) { @@ -40,6 +63,7 @@ function maybeCacheSourceMap(filename, content, cjsModuleInstance) { const data = dataFromUrl(basePath, match.groups.sourceMappingURL); const url = data ? null : match.groups.sourceMappingURL; if (cjsModuleInstance) { + if (!Module) Module = require('internal/modules/cjs/loader').Module; cjsSourceMapCache.set(cjsModuleInstance, { filename, lineLengths: lineLengths(content), @@ -148,17 +172,27 @@ function rekeySourceMap(cjsModuleInstance, newInstance) { } } +// WARNING: The `sourceMapCacheToObject` and `appendCJSCache` run during +// shutdown. In particular, they also run when Workers are terminated, making +// it important that they do not call out to any user-provided code, including +// built-in prototypes that might have been tampered with. + // Get serialized representation of source-map cache, this is used // to persist a cache of source-maps to disk when NODE_V8_COVERAGE is enabled. function sourceMapCacheToObject() { - const obj = Object.create(null); + const obj = ObjectCreate(null); - for (const [k, v] of esmSourceMapCache) { + const it = MapEntries(esmSourceMapCache); + let entry; + while (!(entry = MapIteratorNext(it)).done) { + const k = entry.value[0]; + const v = entry.value[1]; obj[k] = v; } + appendCJSCache(obj); - if (Object.keys(obj).length === 0) { + if (ObjectKeys(obj).length === 0) { return undefined; } else { return obj; @@ -171,23 +205,28 @@ function sourceMapCacheToObject() { // TODO(bcoe): this means we don't currently serialize source-maps attached // to error instances, only module instances. function appendCJSCache(obj) { - const { Module } = require('internal/modules/cjs/loader'); - Object.keys(Module._cache).forEach((key) => { - const value = cjsSourceMapCache.get(Module._cache[key]); + if (!Module) return; + const cjsModuleCache = ObjectGetValueSafe(Module, '_cache'); + const cjsModules = ObjectKeys(cjsModuleCache); + for (let i = 0; i < cjsModules.length; i++) { + const key = cjsModules[i]; + const module = ObjectGetValueSafe(cjsModuleCache, key); + const value = WeakMapGet(cjsSourceMapCache, module); if (value) { + // This is okay because `obj` has a null prototype. obj[`file://${key}`] = { - lineLengths: value.lineLengths, - data: value.data, - url: value.url + lineLengths: ObjectGetValueSafe(value, 'lineLengths'), + data: ObjectGetValueSafe(value, 'data'), + url: ObjectGetValueSafe(value, 'url') }; } - }); + } } // Attempt to lookup a source map, which is either attached to a file URI, or // keyed on an error instance. function findSourceMap(uri, error) { - const { Module } = require('internal/modules/cjs/loader'); + if (!Module) Module = require('internal/modules/cjs/loader').Module; let sourceMap = cjsSourceMapCache.get(Module._cache[uri]); if (!uri.startsWith('file://')) uri = normalizeReferrerURL(uri); if (sourceMap === undefined) { diff --git a/lib/internal/streams/buffer_list.js b/lib/internal/streams/buffer_list.js index 715d5d201d4df4..5e23f2cf464f6c 100644 --- a/lib/internal/streams/buffer_list.js +++ b/lib/internal/streams/buffer_list.js @@ -48,8 +48,8 @@ module.exports = class BufferList { join(s) { if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; + let p = this.head; + let ret = '' + p.data; while (p = p.next) ret += s + p.data; return ret; @@ -59,8 +59,8 @@ module.exports = class BufferList { if (this.length === 0) return Buffer.alloc(0); const ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; + let p = this.head; + let i = 0; while (p) { ret.set(p.data, i); i += p.data.length; diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 3f1c0f316cd3c6..bb01e800becdf3 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -35,14 +35,14 @@ function eos(stream, opts, callback) { if (!stream.writable) onfinish(); }; - var writableEnded = stream._writableState && stream._writableState.finished; + let writableEnded = stream._writableState && stream._writableState.finished; const onfinish = () => { writable = false; writableEnded = true; if (!readable) callback.call(stream); }; - var readableEnded = stream.readableEnded || + let readableEnded = stream.readableEnded || (stream._readableState && stream._readableState.endEmitted); const onend = () => { readable = false; diff --git a/lib/internal/streams/legacy.js b/lib/internal/streams/legacy.js index 06e48e8b15d839..062eabec3890c0 100644 --- a/lib/internal/streams/legacy.js +++ b/lib/internal/streams/legacy.js @@ -36,7 +36,7 @@ Stream.prototype.pipe = function(dest, options) { source.on('close', onclose); } - var didOnEnd = false; + let didOnEnd = false; function onend() { if (didOnEnd) return; didOnEnd = true; diff --git a/lib/internal/timers.js b/lib/internal/timers.js index bb1888198165fb..4067c2ee0b3165 100644 --- a/lib/internal/timers.js +++ b/lib/internal/timers.js @@ -313,7 +313,7 @@ function insert(item, refed, start) { item._idleStart = start; // Use an existing list if there is one, otherwise we need to make a new one. - var list = timerListMap[msecs]; + let list = timerListMap[msecs]; if (list === undefined) { debug('no %d list was found in insert, creating a new one', msecs); const expiry = start + msecs; @@ -396,7 +396,7 @@ function getTimerCallbacks(runNextTicks) { function processImmediate() { const queue = outstandingQueue.head !== null ? outstandingQueue : immediateQueue; - var immediate = queue.head; + let immediate = queue.head; // Clear the linked list early in case new `setImmediate()` // calls occur while immediate callbacks are executed @@ -482,10 +482,10 @@ function getTimerCallbacks(runNextTicks) { debug('timeout callback %d', msecs); - var diff, timer; let ranAtLeastOneTimer = false; + let timer; while (timer = L.peek(list)) { - diff = now - timer._idleStart; + const diff = now - timer._idleStart; // Check if this loop iteration is too early for the next timer. // This happens if there are more timers scheduled for later in the list. diff --git a/lib/internal/tls.js b/lib/internal/tls.js index 80f6d80e18ccc8..8bf9330352bd20 100644 --- a/lib/internal/tls.js +++ b/lib/internal/tls.js @@ -7,7 +7,7 @@ const { Object } = primordials; function parseCertString(s) { const out = Object.create(null); const parts = s.split('\n'); - for (var i = 0, len = parts.length; i < len; i++) { + for (let i = 0, len = parts.length; i < len; i++) { const sepIndex = parts[i].indexOf('='); if (sepIndex > 0) { const key = parts[i].slice(0, sepIndex); diff --git a/lib/internal/url.js b/lib/internal/url.js index fde643bea370c8..860fa4d7ad01b3 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -165,7 +165,7 @@ class URLSearchParams { // Need to use reflection APIs for full spec compliance. this[searchParams] = []; const keys = Reflect.ownKeys(init); - for (var i = 0; i < keys.length; i++) { + for (let i = 0; i < keys.length; i++) { const key = keys[i]; const desc = Reflect.getOwnPropertyDescriptor(init, key); if (desc !== undefined && desc.enumerable) { @@ -203,7 +203,7 @@ class URLSearchParams { const list = this[searchParams]; const output = []; - for (var i = 0; i < list.length; i += 2) + for (let i = 0; i < list.length; i += 2) output.push(`${innerInspect(list[i])} => ${innerInspect(list[i + 1])}`); const length = output.reduce( @@ -390,7 +390,7 @@ Object.defineProperties(URL.prototype, { ...options }; const ctx = this[context]; - var ret = ctx.scheme; + let ret = ctx.scheme; if (ctx.host !== null) { ret += '//'; const has_username = ctx.username !== ''; @@ -539,7 +539,7 @@ Object.defineProperties(URL.prototype, { configurable: true, get() { const ctx = this[context]; - var ret = ctx.host || ''; + let ret = ctx.host || ''; if (ctx.port !== null) ret += `:${ctx.port}`; return ret; @@ -707,13 +707,13 @@ function initSearchParams(url, init) { // Ref: https://url.spec.whatwg.org/#concept-urlencoded-parser function parseParams(qs) { const out = []; - var pairStart = 0; - var lastPos = 0; - var seenSep = false; - var buf = ''; - var encoded = false; - var encodeCheck = 0; - var i; + let pairStart = 0; + let lastPos = 0; + let seenSep = false; + let buf = ''; + let encoded = false; + let encodeCheck = 0; + let i; for (i = 0; i < qs.length; ++i) { const code = qs.charCodeAt(i); @@ -834,7 +834,7 @@ function serializeParams(array) { const firstEncodedValue = encodeStr(array[1], noEscape, paramHexTable); let output = `${firstEncodedParam}=${firstEncodedValue}`; - for (var i = 2; i < len; i += 2) { + for (let i = 2; i < len; i += 2) { const encodedParam = encodeStr(array[i], noEscape, paramHexTable); const encodedValue = encodeStr(array[i + 1], noEscape, paramHexTable); output += `&${encodedParam}=${encodedValue}`; @@ -876,7 +876,7 @@ function defineIDLClass(proto, classStr, obj) { function merge(out, start, mid, end, lBuffer, rBuffer) { const sizeLeft = mid - start; const sizeRight = end - mid; - var l, r, o; + let l, r, o; for (l = 0; l < sizeLeft; l++) lBuffer[l] = out[start + l]; @@ -926,7 +926,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { const list = this[searchParams]; name = toUSVString(name); - for (var i = 0; i < list.length;) { + for (let i = 0; i < list.length;) { const cur = list[i]; if (cur === name) { list.splice(i, 2); @@ -947,7 +947,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { const list = this[searchParams]; name = toUSVString(name); - for (var i = 0; i < list.length; i += 2) { + for (let i = 0; i < list.length; i += 2) { if (list[i] === name) { return list[i + 1]; } @@ -966,7 +966,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { const list = this[searchParams]; const values = []; name = toUSVString(name); - for (var i = 0; i < list.length; i += 2) { + for (let i = 0; i < list.length; i += 2) { if (list[i] === name) { values.push(list[i + 1]); } @@ -984,7 +984,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { const list = this[searchParams]; name = toUSVString(name); - for (var i = 0; i < list.length; i += 2) { + for (let i = 0; i < list.length; i += 2) { if (list[i] === name) { return true; } @@ -1007,8 +1007,8 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { // If there are any name-value pairs whose name is `name`, in `list`, set // the value of the first such name-value pair to `value` and remove the // others. - var found = false; - for (var i = 0; i < list.length;) { + let found = false; + for (let i = 0; i < list.length;) { const cur = list[i]; if (cur === name) { if (!found) { @@ -1042,10 +1042,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { // 100 is found through testing. // Simple stable in-place insertion sort // Derived from v8/src/js/array.js - for (var i = 2; i < len; i += 2) { - var curKey = a[i]; - var curVal = a[i + 1]; - var j; + for (let i = 2; i < len; i += 2) { + const curKey = a[i]; + const curVal = a[i + 1]; + let j; for (j = i - 2; j >= 0; j -= 2) { if (a[j] > curKey) { a[j + 2] = a[j]; @@ -1061,10 +1061,10 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { // Bottom-up iterative stable merge sort const lBuffer = new Array(len); const rBuffer = new Array(len); - for (var step = 2; step < len; step *= 2) { - for (var start = 0; start < len - 2; start += 2 * step) { - var mid = start + step; - var end = mid + step; + for (let step = 2; step < len; step *= 2) { + for (let start = 0; start < len - 2; start += 2 * step) { + const mid = start + step; + let end = mid + step; end = end < len ? end : len; if (mid > end) continue; @@ -1097,7 +1097,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', { let list = this[searchParams]; - var i = 0; + let i = 0; while (i < list.length) { const key = list[i]; const value = list[i + 1]; @@ -1279,10 +1279,10 @@ const forwardSlashRegEx = /\//g; function getPathFromURLWin32(url) { const hostname = url.hostname; - var pathname = url.pathname; - for (var n = 0; n < pathname.length; n++) { + let pathname = url.pathname; + for (let n = 0; n < pathname.length; n++) { if (pathname[n] === '%') { - var third = pathname.codePointAt(n + 2) | 0x20; + const third = pathname.codePointAt(n + 2) | 0x20; if ((pathname[n + 1] === '2' && third === 102) || // 2f 2F / (pathname[n + 1] === '5' && third === 99)) { // 5c 5C \ throw new ERR_INVALID_FILE_URL_PATH( @@ -1303,8 +1303,8 @@ function getPathFromURLWin32(url) { return `\\\\${domainToUnicode(hostname)}${pathname}`; } else { // Otherwise, it's a local path that requires a drive letter - var letter = pathname.codePointAt(1) | 0x20; - var sep = pathname[2]; + const letter = pathname.codePointAt(1) | 0x20; + const sep = pathname[2]; if (letter < CHAR_LOWERCASE_A || letter > CHAR_LOWERCASE_Z || // a..z A..Z (sep !== ':')) { throw new ERR_INVALID_FILE_URL_PATH('must be absolute'); @@ -1318,9 +1318,9 @@ function getPathFromURLPosix(url) { throw new ERR_INVALID_FILE_URL_HOST(platform); } const pathname = url.pathname; - for (var n = 0; n < pathname.length; n++) { + for (let n = 0; n < pathname.length; n++) { if (pathname[n] === '%') { - var third = pathname.codePointAt(n + 2) | 0x20; + const third = pathname.codePointAt(n + 2) | 0x20; if (pathname[n + 1] === '2' && third === 102) { throw new ERR_INVALID_FILE_URL_PATH( 'must not include encoded / characters' diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index b3256716c38b63..52cd11429e6ac6 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -59,7 +59,7 @@ function areSimilarFloatArrays(a, b) { if (a.byteLength !== b.byteLength) { return false; } - for (var offset = 0; offset < a.byteLength; offset++) { + for (let offset = 0; offset < a.byteLength; offset++) { if (a[offset] !== b[offset]) { return false; } diff --git a/lib/internal/v8_prof_processor.js b/lib/internal/v8_prof_processor.js index a39fbf4743e76f..7a942d3225a2a9 100644 --- a/lib/internal/v8_prof_processor.js +++ b/lib/internal/v8_prof_processor.js @@ -18,7 +18,7 @@ const scriptFiles = [ 'internal/deps/v8/tools/SourceMap', 'internal/deps/v8/tools/tickprocessor-driver' ]; -var script = ''; +let script = ''; scriptFiles.forEach((s) => { script += internalBinding('natives')[s] + '\n'; diff --git a/lib/internal/worker.js b/lib/internal/worker.js index fc6588d527d12b..614f93010515b3 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -2,19 +2,20 @@ /* global SharedArrayBuffer */ -const { Object } = primordials; +const { Math, Object } = primordials; const EventEmitter = require('events'); const assert = require('internal/assert'); const path = require('path'); +const errorCodes = require('internal/errors').codes; const { ERR_WORKER_PATH, ERR_WORKER_UNSERIALIZABLE_ERROR, ERR_WORKER_UNSUPPORTED_EXTENSION, ERR_WORKER_INVALID_EXEC_ARGV, ERR_INVALID_ARG_TYPE, -} = require('internal/errors').codes; +} = errorCodes; const { validateString } = require('internal/validators'); const { getOptionValue } = require('internal/options'); @@ -37,8 +38,13 @@ const { pathToFileURL } = require('url'); const { ownsProcessState, isMainThread, + resourceLimits: resourceLimitsRaw, threadId, Worker: WorkerImpl, + kMaxYoungGenerationSizeMb, + kMaxOldGenerationSizeMb, + kCodeRangeSizeMb, + kTotalResourceLimitCount } = internalBinding('worker'); const kHandle = Symbol('kHandle'); @@ -102,7 +108,8 @@ class Worker extends EventEmitter { const url = options.eval ? null : pathToFileURL(filename); // Set up the C++ handle for the worker, as well as some internal wiring. - this[kHandle] = new WorkerImpl(url, options.execArgv); + this[kHandle] = new WorkerImpl(url, options.execArgv, + parseResourceLimits(options.resourceLimits)); if (this[kHandle].invalidExecArgv) { throw new ERR_WORKER_INVALID_EXEC_ARGV(this[kHandle].invalidExecArgv); } @@ -113,7 +120,7 @@ class Worker extends EventEmitter { } else if (env !== undefined) { this[kHandle].setEnvVars(env); } - this[kHandle].onexit = (code) => this[kOnExit](code); + this[kHandle].onexit = (code, customErr) => this[kOnExit](code, customErr); this[kPort] = this[kHandle].messagePort; this[kPort].on('message', (data) => this[kOnMessage](data)); this[kPort].start(); @@ -157,11 +164,15 @@ class Worker extends EventEmitter { this[kHandle].startThread(); } - [kOnExit](code) { + [kOnExit](code, customErr) { debug(`[${threadId}] hears end event for Worker ${this.threadId}`); drainMessagePort(this[kPublicPort]); drainMessagePort(this[kPort]); this[kDispose](); + if (customErr) { + debug(`[${threadId}] failing with custom error ${customErr}`); + this.emit('error', new errorCodes[customErr]()); + } this.emit('exit', code); this.removeAllListeners(); } @@ -280,6 +291,12 @@ class Worker extends EventEmitter { get stderr() { return this[kParentSideStdio].stderr; } + + get resourceLimits() { + if (this[kHandle] === null) return {}; + + return makeResourceLimits(this[kHandle].getResourceLimits()); + } } function pipeWithoutWarning(source, dest) { @@ -294,10 +311,35 @@ function pipeWithoutWarning(source, dest) { dest._maxListeners = destMaxListeners; } +const resourceLimitsArray = new Float64Array(kTotalResourceLimitCount); +function parseResourceLimits(obj) { + const ret = resourceLimitsArray; + ret.fill(-1); + if (typeof obj !== 'object' || obj === null) return ret; + + if (typeof obj.maxOldGenerationSizeMb === 'number') + ret[kMaxOldGenerationSizeMb] = Math.max(obj.maxOldGenerationSizeMb, 2); + if (typeof obj.maxYoungGenerationSizeMb === 'number') + ret[kMaxYoungGenerationSizeMb] = obj.maxYoungGenerationSizeMb; + if (typeof obj.codeRangeSizeMb === 'number') + ret[kCodeRangeSizeMb] = obj.codeRangeSizeMb; + return ret; +} + +function makeResourceLimits(float64arr) { + return { + maxYoungGenerationSizeMb: float64arr[kMaxYoungGenerationSizeMb], + maxOldGenerationSizeMb: float64arr[kMaxOldGenerationSizeMb], + codeRangeSizeMb: float64arr[kCodeRangeSizeMb] + }; +} + module.exports = { ownsProcessState, isMainThread, SHARE_ENV, + resourceLimits: + !isMainThread ? makeResourceLimits(resourceLimitsRaw) : {}, threadId, Worker, }; diff --git a/lib/net.js b/lib/net.js index c0d2576afc496b..bdb77fdacbd856 100644 --- a/lib/net.js +++ b/lib/net.js @@ -21,7 +21,12 @@ 'use strict'; -const { Object } = primordials; +const { + Object: { + defineProperty: ObjectDefineProperty, + setPrototypeOf: ObjectSetPrototypeOf + } +} = primordials; const EventEmitter = require('events'); const stream = require('stream'); @@ -336,7 +341,7 @@ function Socket(options) { // makeSyncWrite adjusts this value like the original handle would, so // we need to let it do that by turning it into a writable, own // property. - Object.defineProperty(this._handle, 'bytesWritten', { + ObjectDefineProperty(this._handle, 'bytesWritten', { value: 0, writable: true }); } @@ -372,8 +377,8 @@ function Socket(options) { this[kBytesRead] = 0; this[kBytesWritten] = 0; } -Object.setPrototypeOf(Socket.prototype, stream.Duplex.prototype); -Object.setPrototypeOf(Socket, stream.Duplex); +ObjectSetPrototypeOf(Socket.prototype, stream.Duplex.prototype); +ObjectSetPrototypeOf(Socket, stream.Duplex); // Refresh existing timeouts. Socket.prototype._unrefTimer = function _unrefTimer() { @@ -503,13 +508,13 @@ Socket.prototype.address = function() { }; -Object.defineProperty(Socket.prototype, '_connecting', { +ObjectDefineProperty(Socket.prototype, '_connecting', { get: function() { return this.connecting; } }); -Object.defineProperty(Socket.prototype, 'pending', { +ObjectDefineProperty(Socket.prototype, 'pending', { get() { return !this._handle || this.connecting; }, @@ -517,7 +522,7 @@ Object.defineProperty(Socket.prototype, 'pending', { }); -Object.defineProperty(Socket.prototype, 'readyState', { +ObjectDefineProperty(Socket.prototype, 'readyState', { get: function() { if (this.connecting) { return 'opening'; @@ -534,15 +539,15 @@ Object.defineProperty(Socket.prototype, 'readyState', { }); -Object.defineProperty(Socket.prototype, 'bufferSize', { - get: function() { // eslint-disable-line getter-return +ObjectDefineProperty(Socket.prototype, 'bufferSize', { + get: function() { if (this._handle) { return this[kLastWriteQueueSize] + this.writableLength; } } }); -Object.defineProperty(Socket.prototype, kUpdateTimer, { +ObjectDefineProperty(Socket.prototype, kUpdateTimer, { get: function() { return this._unrefTimer; } @@ -690,7 +695,7 @@ Socket.prototype._getpeername = function() { }; function protoGetter(name, callback) { - Object.defineProperty(Socket.prototype, name, { + ObjectDefineProperty(Socket.prototype, name, { configurable: false, enumerable: true, get: callback @@ -1162,7 +1167,7 @@ function Server(options, connectionListener) { this._connections = 0; - Object.defineProperty(this, 'connections', { + ObjectDefineProperty(this, 'connections', { get: deprecate(() => { if (this._usingWorkers) { @@ -1186,8 +1191,8 @@ function Server(options, connectionListener) { this.allowHalfOpen = options.allowHalfOpen || false; this.pauseOnConnect = !!options.pauseOnConnect; } -Object.setPrototypeOf(Server.prototype, EventEmitter.prototype); -Object.setPrototypeOf(Server, EventEmitter); +ObjectSetPrototypeOf(Server.prototype, EventEmitter.prototype); +ObjectSetPrototypeOf(Server, EventEmitter); function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; } @@ -1491,7 +1496,7 @@ function lookupAndListen(self, port, address, backlog, exclusive, flags) { }); } -Object.defineProperty(Server.prototype, 'listening', { +ObjectDefineProperty(Server.prototype, 'listening', { get: function() { return !!this._handle; }, @@ -1648,12 +1653,12 @@ function emitCloseNT(self) { // Legacy alias on the C++ wrapper object. This is not public API, so we may // want to runtime-deprecate it at some point. There's no hurry, though. -Object.defineProperty(TCP.prototype, 'owner', { +ObjectDefineProperty(TCP.prototype, 'owner', { get() { return this[owner_symbol]; }, set(v) { return this[owner_symbol] = v; } }); -Object.defineProperty(Socket.prototype, '_handle', { +ObjectDefineProperty(Socket.prototype, '_handle', { get() { return this[kHandle]; }, set(v) { return this[kHandle] = v; } }); diff --git a/lib/path.js b/lib/path.js index 395fe1f35702c4..c5db4437a52408 100644 --- a/lib/path.js +++ b/lib/path.js @@ -55,7 +55,7 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) { let lastSlash = -1; let dots = 0; let code = 0; - for (var i = 0; i <= path.length; ++i) { + for (let i = 0; i <= path.length; ++i) { if (i < path.length) code = path.charCodeAt(i); else if (isPathSeparator(code)) @@ -132,7 +132,7 @@ const win32 = { let resolvedTail = ''; let resolvedAbsolute = false; - for (var i = args.length - 1; i >= -1; i--) { + for (let i = args.length - 1; i >= -1; i--) { let path; if (i >= 0) { path = args[i]; @@ -370,7 +370,7 @@ const win32 = { let joined; let firstPart; - for (var i = 0; i < args.length; ++i) { + for (let i = 0; i < args.length; ++i) { const arg = args[i]; validateString(arg, 'path'); if (arg.length > 0) { @@ -644,7 +644,7 @@ const win32 = { let end = -1; let matchedSlash = true; - for (var i = len - 1; i >= offset; --i) { + for (let i = len - 1; i >= offset; --i) { if (isPathSeparator(path.charCodeAt(i))) { if (!matchedSlash) { end = i; @@ -669,10 +669,9 @@ const win32 = { if (ext !== undefined) validateString(ext, 'ext'); validateString(path, 'path'); - var start = 0; - var end = -1; - var matchedSlash = true; - var i; + let start = 0; + let end = -1; + let matchedSlash = true; // Check for a drive letter prefix so as not to mistake the following // path separator as an extra separator at the end of the path that can be @@ -686,9 +685,9 @@ const win32 = { if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext === path) return ''; - var extIdx = ext.length - 1; - var firstNonSlashEnd = -1; - for (i = path.length - 1; i >= start; --i) { + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for (let i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); if (isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path @@ -728,7 +727,7 @@ const win32 = { end = path.length; return path.slice(start, end); } - for (i = path.length - 1; i >= start; --i) { + for (let i = path.length - 1; i >= start; --i) { if (isPathSeparator(path.charCodeAt(i))) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now @@ -751,14 +750,14 @@ const win32 = { extname(path) { validateString(path, 'path'); - var start = 0; - var startDot = -1; - var startPart = 0; - var end = -1; - var matchedSlash = true; + let start = 0; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find - var preDotState = 0; + let preDotState = 0; // Check for a drive letter prefix so as not to mistake the following // path separator as an extra separator at the end of the path that can be @@ -770,7 +769,7 @@ const win32 = { start = startPart = 2; } - for (var i = path.length - 1; i >= start; --i) { + for (let i = path.length - 1; i >= start; --i) { const code = path.charCodeAt(i); if (isPathSeparator(code)) { // If we reached a path separator that was not part of a set of path @@ -823,7 +822,7 @@ const win32 = { return ret; const len = path.length; - var rootEnd = 0; + let rootEnd = 0; let code = path.charCodeAt(0); if (len === 1) { @@ -895,15 +894,15 @@ const win32 = { if (rootEnd > 0) ret.root = path.slice(0, rootEnd); - var startDot = -1; - var startPart = rootEnd; - var end = -1; - var matchedSlash = true; - var i = path.length - 1; + let startDot = -1; + let startPart = rootEnd; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find - var preDotState = 0; + let preDotState = 0; // Get non-dir info for (; i >= rootEnd; --i) { @@ -975,7 +974,7 @@ const posix = { let resolvedPath = ''; let resolvedAbsolute = false; - for (var i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { + for (let i = args.length - 1; i >= -1 && !resolvedAbsolute; i--) { const path = i >= 0 ? args[i] : process.cwd(); validateString(path, 'path'); @@ -1035,7 +1034,7 @@ const posix = { if (args.length === 0) return '.'; let joined; - for (var i = 0; i < args.length; ++i) { + for (let i = 0; i < args.length; ++i) { const arg = args[i]; validateString(arg, 'path'); if (arg.length > 0) { @@ -1130,9 +1129,9 @@ const posix = { if (path.length === 0) return '.'; const hasRoot = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - var end = -1; - var matchedSlash = true; - for (var i = path.length - 1; i >= 1; --i) { + let end = -1; + let matchedSlash = true; + for (let i = path.length - 1; i >= 1; --i) { if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { if (!matchedSlash) { end = i; @@ -1156,17 +1155,16 @@ const posix = { validateString(ext, 'ext'); validateString(path, 'path'); - var start = 0; - var end = -1; - var matchedSlash = true; - var i; + let start = 0; + let end = -1; + let matchedSlash = true; if (ext !== undefined && ext.length > 0 && ext.length <= path.length) { if (ext === path) return ''; - var extIdx = ext.length - 1; - var firstNonSlashEnd = -1; - for (i = path.length - 1; i >= 0; --i) { + let extIdx = ext.length - 1; + let firstNonSlashEnd = -1; + for (let i = path.length - 1; i >= 0; --i) { const code = path.charCodeAt(i); if (code === CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path @@ -1206,7 +1204,7 @@ const posix = { end = path.length; return path.slice(start, end); } - for (i = path.length - 1; i >= 0; --i) { + for (let i = path.length - 1; i >= 0; --i) { if (path.charCodeAt(i) === CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path // separators at the end of the string, stop now @@ -1229,14 +1227,14 @@ const posix = { extname(path) { validateString(path, 'path'); - var startDot = -1; - var startPart = 0; - var end = -1; - var matchedSlash = true; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; // Track the state of characters (if any) we see before our first dot and // after any path separator we find - var preDotState = 0; - for (var i = path.length - 1; i >= 0; --i) { + let preDotState = 0; + for (let i = path.length - 1; i >= 0; --i) { const code = path.charCodeAt(i); if (code === CHAR_FORWARD_SLASH) { // If we reached a path separator that was not part of a set of path @@ -1288,22 +1286,22 @@ const posix = { if (path.length === 0) return ret; const isAbsolute = path.charCodeAt(0) === CHAR_FORWARD_SLASH; - var start; + let start; if (isAbsolute) { ret.root = '/'; start = 1; } else { start = 0; } - var startDot = -1; - var startPart = 0; - var end = -1; - var matchedSlash = true; - var i = path.length - 1; + let startDot = -1; + let startPart = 0; + let end = -1; + let matchedSlash = true; + let i = path.length - 1; // Track the state of characters (if any) we see before our first dot and // after any path separator we find - var preDotState = 0; + let preDotState = 0; // Get non-dir info for (; i >= start; --i) { diff --git a/lib/querystring.js b/lib/querystring.js index 9fac6e2627c08b..40f6d3dafb2b56 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -67,15 +67,15 @@ const unhexTable = [ // A safe fast alternative to decodeURIComponent function unescapeBuffer(s, decodeSpaces) { const out = Buffer.allocUnsafe(s.length); - var index = 0; - var outIndex = 0; - var currentChar; - var nextChar; - var hexHigh; - var hexLow; + let index = 0; + let outIndex = 0; + let currentChar; + let nextChar; + let hexHigh; + let hexLow; const maxLength = s.length - 2; // Flag to know if some hex chars have been decoded - var hasHex = false; + let hasHex = false; while (index < s.length) { currentChar = s.charCodeAt(index); if (currentChar === 43 /* '+' */ && decodeSpaces) { @@ -161,27 +161,27 @@ function stringify(obj, sep, eq, options) { sep = sep || '&'; eq = eq || '='; - var encode = QueryString.escape; + let encode = QueryString.escape; if (options && typeof options.encodeURIComponent === 'function') { encode = options.encodeURIComponent; } if (obj !== null && typeof obj === 'object') { - var keys = Object.keys(obj); - var len = keys.length; - var flast = len - 1; - var fields = ''; - for (var i = 0; i < len; ++i) { - var k = keys[i]; - var v = obj[k]; - var ks = encode(stringifyPrimitive(k)); + const keys = Object.keys(obj); + const len = keys.length; + const flast = len - 1; + let fields = ''; + for (let i = 0; i < len; ++i) { + const k = keys[i]; + const v = obj[k]; + let ks = encode(stringifyPrimitive(k)); ks += eq; if (Array.isArray(v)) { - var vlen = v.length; + const vlen = v.length; if (vlen === 0) continue; - var vlast = vlen - 1; - for (var j = 0; j < vlen; ++j) { + const vlast = vlen - 1; + for (let j = 0; j < vlen; ++j) { fields += ks; fields += encode(stringifyPrimitive(v[j])); if (j < vlast) @@ -204,7 +204,7 @@ function charCodes(str) { if (str.length === 0) return []; if (str.length === 1) return [str.charCodeAt(0)]; const ret = new Array(str.length); - for (var i = 0; i < str.length; ++i) + for (let i = 0; i < str.length; ++i) ret[i] = str.charCodeAt(i); return ret; } @@ -244,7 +244,7 @@ function parse(qs, sep, eq, options) { const sepLen = sepCodes.length; const eqLen = eqCodes.length; - var pairs = 1000; + let pairs = 1000; if (options && typeof options.maxKeys === 'number') { // -1 is used in place of a value like Infinity for meaning // "unlimited pairs" because of additional checks V8 (at least as of v5.4) @@ -255,22 +255,22 @@ function parse(qs, sep, eq, options) { pairs = (options.maxKeys > 0 ? options.maxKeys : -1); } - var decode = QueryString.unescape; + let decode = QueryString.unescape; if (options && typeof options.decodeURIComponent === 'function') { decode = options.decodeURIComponent; } const customDecode = (decode !== qsUnescape); - var lastPos = 0; - var sepIdx = 0; - var eqIdx = 0; - var key = ''; - var value = ''; - var keyEncoded = customDecode; - var valEncoded = customDecode; + let lastPos = 0; + let sepIdx = 0; + let eqIdx = 0; + let key = ''; + let value = ''; + let keyEncoded = customDecode; + let valEncoded = customDecode; const plusChar = (customDecode ? '%20' : ' '); - var encodeCheck = 0; - for (var i = 0; i < qs.length; ++i) { + let encodeCheck = 0; + for (let i = 0; i < qs.length; ++i) { const code = qs.charCodeAt(i); // Try matching key/value pair separator (e.g. '&') diff --git a/lib/readline.js b/lib/readline.js index ec89566737db66..13c70fbb8c45c5 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -94,8 +94,8 @@ function Interface(input, output, completer, terminal) { this.escapeCodeTimeout = ESCAPE_CODE_TIMEOUT; EventEmitter.call(this); - var historySize; - var removeHistoryDuplicates = false; + let historySize; + let removeHistoryDuplicates = false; let crlfDelay; let prompt = '> '; @@ -258,10 +258,9 @@ Object.defineProperty(Interface.prototype, 'columns', { configurable: true, enumerable: true, get: function() { - var columns = Infinity; if (this.output && this.output.columns) - columns = this.output.columns; - return columns; + return this.output.columns; + return Infinity; } }); @@ -308,7 +307,7 @@ Interface.prototype.question = function(query, cb) { Interface.prototype._onLine = function(line) { if (this._questionCallback) { - var cb = this._questionCallback; + const cb = this._questionCallback; this._questionCallback = null; this.setPrompt(this._oldPrompt); cb(line); @@ -435,7 +434,7 @@ Interface.prototype._normalWrite = function(b) { if (b === undefined) { return; } - var string = this._decoder.write(b); + let string = this._decoder.write(b); if (this._sawReturnAt && Date.now() - this._sawReturnAt <= this.crlfDelay) { string = string.replace(/^\n/, ''); @@ -453,11 +452,11 @@ Interface.prototype._normalWrite = function(b) { this._sawReturnAt = string.endsWith('\r') ? Date.now() : 0; // Got one or more newlines; process into "line" events - var lines = string.split(lineEnding); + const lines = string.split(lineEnding); // Either '' or (conceivably) the unfinished portion of the next line string = lines.pop(); this._line_buffer = string; - for (var n = 0; n < lines.length; n++) + for (let n = 0; n < lines.length; n++) this._onLine(lines[n]); } else if (string) { // No newlines this time, save what we have for next time @@ -467,8 +466,8 @@ Interface.prototype._normalWrite = function(b) { Interface.prototype._insertString = function(c) { if (this.cursor < this.line.length) { - var beg = this.line.slice(0, this.cursor); - var end = this.line.slice(this.cursor, this.line.length); + const beg = this.line.slice(0, this.cursor); + const end = this.line.slice(this.cursor, this.line.length); this.line = beg + c + end; this.cursor += c.length; this._refreshLine(); @@ -505,16 +504,16 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) { // Apply/show completions. if (lastKeypressWasTab) { self._writeToOutput('\r\n'); - var width = completions.reduce(function completionReducer(a, b) { + const width = completions.reduce(function completionReducer(a, b) { return a.length > b.length ? a : b; }).length + 2; // 2 space padding - var maxColumns = Math.floor(self.columns / width); + let maxColumns = Math.floor(self.columns / width); if (!maxColumns || maxColumns === Infinity) { maxColumns = 1; } - var group = []; - for (var i = 0; i < completions.length; i++) { - var c = completions[i]; + let group = []; + for (let i = 0; i < completions.length; i++) { + const c = completions[i]; if (c === '') { handleGroup(self, group, width, maxColumns); group = []; @@ -526,8 +525,8 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) { } // If there is a common prefix to all matches, then apply that portion. - var f = completions.filter((e) => e); - var prefix = commonPrefix(f); + const f = completions.filter((e) => e); + const prefix = commonPrefix(f); if (prefix.length > completeOn.length) { self._insertString(prefix.slice(completeOn.length)); } @@ -543,16 +542,16 @@ function handleGroup(self, group, width, maxColumns) { return; } const minRows = Math.ceil(group.length / maxColumns); - for (var row = 0; row < minRows; row++) { - for (var col = 0; col < maxColumns; col++) { - var idx = row * maxColumns + col; + for (let row = 0; row < minRows; row++) { + for (let col = 0; col < maxColumns; col++) { + const idx = row * maxColumns + col; if (idx >= group.length) { break; } - var item = group[idx]; + const item = group[idx]; self._writeToOutput(item); if (col < maxColumns - 1) { - for (var s = 0; s < width - item.length; s++) { + for (let s = 0; s < width - item.length; s++) { self._writeToOutput(' '); } } @@ -570,7 +569,7 @@ function commonPrefix(strings) { const sorted = strings.slice().sort(); const min = sorted[0]; const max = sorted[sorted.length - 1]; - for (var i = 0, len = min.length; i < len; i++) { + for (let i = 0, len = min.length; i < len; i++) { if (min[i] !== max[i]) { return min.slice(0, i); } @@ -583,9 +582,9 @@ Interface.prototype._wordLeft = function() { if (this.cursor > 0) { // Reverse the string and match a word near beginning // to avoid quadratic time complexity - var leading = this.line.slice(0, this.cursor); - var reversed = leading.split('').reverse().join(''); - var match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/); + const leading = this.line.slice(0, this.cursor); + const reversed = leading.split('').reverse().join(''); + const match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/); this._moveCursor(-match[0].length); } }; @@ -593,8 +592,8 @@ Interface.prototype._wordLeft = function() { Interface.prototype._wordRight = function() { if (this.cursor < this.line.length) { - var trailing = this.line.slice(this.cursor); - var match = trailing.match(/^(?:\s+|[^\w\s]+|\w+)\s*/); + const trailing = this.line.slice(this.cursor); + const match = trailing.match(/^(?:\s+|[^\w\s]+|\w+)\s*/); this._moveCursor(match[0].length); } }; @@ -643,9 +642,9 @@ Interface.prototype._deleteWordLeft = function() { if (this.cursor > 0) { // Reverse the string and match a word near beginning // to avoid quadratic time complexity - var leading = this.line.slice(0, this.cursor); - var reversed = leading.split('').reverse().join(''); - var match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/); + let leading = this.line.slice(0, this.cursor); + const reversed = leading.split('').reverse().join(''); + const match = reversed.match(/^\s*(?:[^\w\s]+|\w+)?/); leading = leading.slice(0, leading.length - match[0].length); this.line = leading + this.line.slice(this.cursor, this.line.length); this.cursor = leading.length; @@ -656,8 +655,8 @@ Interface.prototype._deleteWordLeft = function() { Interface.prototype._deleteWordRight = function() { if (this.cursor < this.line.length) { - var trailing = this.line.slice(this.cursor); - var match = trailing.match(/^(?:\s+|\W+|\w+)\s*/); + const trailing = this.line.slice(this.cursor); + const match = trailing.match(/^(?:\s+|\W+|\w+)\s*/); this.line = this.line.slice(0, this.cursor) + trailing.slice(match[0].length); this._refreshLine(); @@ -723,13 +722,12 @@ Interface.prototype._historyPrev = function() { // Returns the last character's display position of the given string Interface.prototype._getDisplayPos = function(str) { - var offset = 0; + let offset = 0; const col = this.columns; - var row = 0; - var code; + let row = 0; str = stripVTControlCharacters(str); - for (var i = 0, len = str.length; i < len; i++) { - code = str.codePointAt(i); + for (let i = 0, len = str.length; i < len; i++) { + const code = str.codePointAt(i); if (code >= kUTF16SurrogateThreshold) { // Surrogates. i++; } @@ -761,8 +759,8 @@ Interface.prototype._getCursorPos = function() { const strBeforeCursor = this._prompt + this.line.substring(0, this.cursor); const dispPos = this._getDisplayPos( stripVTControlCharacters(strBeforeCursor)); - var cols = dispPos.cols; - var rows = dispPos.rows; + let cols = dispPos.cols; + let rows = dispPos.rows; // If the cursor is on a full-width character which steps over the line, // move the cursor to the beginning of the next line. if (cols + 1 === columns && @@ -790,8 +788,8 @@ Interface.prototype._moveCursor = function(dx) { // Check if cursors are in the same line if (oldPos.rows === newPos.rows) { - var diffCursor = this.cursor - oldcursor; - var diffWidth; + const diffCursor = this.cursor - oldcursor; + let diffWidth; if (diffCursor < 0) { diffWidth = -getStringWidth( this.line.substring(this.cursor, oldcursor) @@ -1072,8 +1070,8 @@ Interface.prototype._ttyWrite = function(s, key) { default: if (typeof s === 'string' && s) { - var lines = s.split(/\r\n|\n|\r/); - for (var i = 0, len = lines.length; i < len; i++) { + const lines = s.split(/\r\n|\n|\r/); + for (let i = 0, len = lines.length; i < len; i++) { if (i > 0) { this._line(); } @@ -1136,7 +1134,7 @@ function emitKeypressEvents(stream, iface) { function onData(b) { if (stream.listenerCount('keypress') > 0) { - var r = stream[KEYPRESS_DECODER].write(b); + const r = stream[KEYPRESS_DECODER].write(b); if (r) { clearTimeout(timeoutId); @@ -1144,7 +1142,7 @@ function emitKeypressEvents(stream, iface) { iface._sawKeyPress = r.length === 1; } - for (var i = 0; i < r.length; i++) { + for (let i = 0; i < r.length; i++) { if (r[i] === '\t' && typeof r[i + 1] === 'string' && iface) { iface.isCompletionEnabled = false; } diff --git a/lib/repl.js b/lib/repl.js index 88b0f5658489fc..21c0505b85f23d 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -283,11 +283,7 @@ function REPLServer(prompt, } function defaultEval(code, context, file, cb) { - const { getOptionValue } = require('internal/options'); - const experimentalModules = getOptionValue('--experimental-modules'); - const asyncESM = experimentalModules ? - require('internal/process/esm_loader') : - null; + const asyncESM = require('internal/process/esm_loader'); let result, script, wrappedErr; let err = null; @@ -339,9 +335,9 @@ function REPLServer(prompt, script = vm.createScript(code, { filename: file, displayErrors: true, - importModuleDynamically: experimentalModules ? async (specifier) => { + importModuleDynamically: async (specifier) => { return asyncESM.ESMLoader.import(specifier, pwd); - } : undefined + } }); } catch (e) { debug('parse error %j', code, e); diff --git a/lib/string_decoder.js b/lib/string_decoder.js index fec30beb0a15d4..7df50eb0178377 100644 --- a/lib/string_decoder.js +++ b/lib/string_decoder.js @@ -57,7 +57,7 @@ function normalizeEncoding(enc) { } const encodingsMap = {}; -for (var i = 0; i < encodings.length; ++i) +for (let i = 0; i < encodings.length; ++i) encodingsMap[encodings[i]] = i; // StringDecoder provides an interface for efficiently splitting a series of diff --git a/lib/url.js b/lib/url.js index 7a268cd43868a9..fc3863f6ef8a4b 100644 --- a/lib/url.js +++ b/lib/url.js @@ -157,13 +157,13 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { // Copy chrome, IE, opera backslash-handling behavior. // Back slashes before the query string get converted to forward slashes // See: https://code.google.com/p/chromium/issues/detail?id=25916 - var hasHash = false; - var start = -1; - var end = -1; - var rest = ''; - var lastPos = 0; - var i = 0; - for (var inWs = false, split = false; i < url.length; ++i) { + let hasHash = false; + let start = -1; + let end = -1; + let rest = ''; + let lastPos = 0; + let i = 0; + for (let inWs = false, split = false; i < url.length; ++i) { const code = url.charCodeAt(i); // Find first and last non-whitespace characters for trimming @@ -292,9 +292,9 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { // http://a@b@c/ => user:a@b host:c // http://a@b?@c => user:a host:b path:/?@c - var hostEnd = -1; - var atSign = -1; - var nonHost = -1; + let hostEnd = -1; + let atSign = -1; + let nonHost = -1; for (i = 0; i < rest.length; ++i) { switch (rest.charCodeAt(i)) { case CHAR_TAB: @@ -356,11 +356,11 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { if (typeof this.hostname !== 'string') this.hostname = ''; - var hostname = this.hostname; + const hostname = this.hostname; // If hostname begins with [ and ends with ] // assume that it's an IPv6 address. - var ipv6Hostname = hostname.charCodeAt(0) === CHAR_LEFT_SQUARE_BRACKET && + const ipv6Hostname = hostname.charCodeAt(0) === CHAR_LEFT_SQUARE_BRACKET && hostname.charCodeAt(hostname.length - 1) === CHAR_RIGHT_SQUARE_BRACKET; // validate a little. @@ -386,8 +386,8 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { this.hostname = toASCII(this.hostname, true); } - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; + const p = this.port ? ':' + this.port : ''; + const h = this.hostname || ''; this.host = h + p; // strip [ and ] from the hostname @@ -409,8 +409,8 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { rest = autoEscapeStr(rest); } - var questionIdx = -1; - var hashIdx = -1; + let questionIdx = -1; + let hashIdx = -1; for (i = 0; i < rest.length; ++i) { const code = rest.charCodeAt(i); if (code === CHAR_HASH) { @@ -467,7 +467,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) { }; function getHostname(self, rest, hostname) { - for (var i = 0; i < hostname.length; ++i) { + for (let i = 0; i < hostname.length; ++i) { const code = hostname.charCodeAt(i); const isValid = (code >= CHAR_LOWERCASE_A && code <= CHAR_LOWERCASE_Z) || code === CHAR_DOT || @@ -509,11 +509,11 @@ const escapedCodes = [ // Also escape single quotes in case of an XSS attack. // Return the escaped string. function autoEscapeStr(rest) { - var escaped = ''; - var lastEscapedPos = 0; - for (var i = 0; i < rest.length; ++i) { + let escaped = ''; + let lastEscapedPos = 0; + for (let i = 0; i < rest.length; ++i) { // `escaped` contains substring up to the last escaped character. - var escapedChar = escapedCodes[rest.charCodeAt(i)]; + const escapedChar = escapedCodes[rest.charCodeAt(i)]; if (escapedChar) { // Concat if there are ordinary characters in the middle. if (i > lastEscapedPos) @@ -544,7 +544,7 @@ function urlFormat(urlObject, options) { throw new ERR_INVALID_ARG_TYPE('urlObject', ['Object', 'string'], urlObject); } else if (!(urlObject instanceof Url)) { - var format = urlObject[formatSymbol]; + const format = urlObject[formatSymbol]; return format ? format.call(urlObject, options) : Url.prototype.format.call(urlObject); @@ -570,17 +570,17 @@ const noEscapeAuth = [ ]; Url.prototype.format = function format() { - var auth = this.auth || ''; + let auth = this.auth || ''; if (auth) { auth = encodeStr(auth, noEscapeAuth, hexTable); auth += '@'; } - var protocol = this.protocol || ''; - var pathname = this.pathname || ''; - var hash = this.hash || ''; - var host = ''; - var query = ''; + let protocol = this.protocol || ''; + let pathname = this.pathname || ''; + let hash = this.hash || ''; + let host = ''; + let query = ''; if (this.host) { host = auth + this.host; @@ -600,14 +600,14 @@ Url.prototype.format = function format() { query = querystring.stringify(this.query); } - var search = this.search || (query && ('?' + query)) || ''; + let search = this.search || (query && ('?' + query)) || ''; if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58/* : */) protocol += ':'; - var newPathname = ''; - var lastPos = 0; - for (var i = 0; i < pathname.length; ++i) { + let newPathname = ''; + let lastPos = 0; + for (let i = 0; i < pathname.length; ++i) { switch (pathname.charCodeAt(i)) { case CHAR_HASH: if (i - lastPos > 0) @@ -671,15 +671,15 @@ function urlResolveObject(source, relative) { Url.prototype.resolveObject = function resolveObject(relative) { if (typeof relative === 'string') { - var rel = new Url(); + const rel = new Url(); rel.parse(relative, false, true); relative = rel; } const result = new Url(); const tkeys = Object.keys(this); - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; + for (let tk = 0; tk < tkeys.length; tk++) { + const tkey = tkeys[tk]; result[tkey] = this[tkey]; } @@ -696,9 +696,9 @@ Url.prototype.resolveObject = function resolveObject(relative) { // Hrefs like //foo/bar always cut to the protocol. if (relative.slashes && !relative.protocol) { // Take everything except the protocol from relative - var rkeys = Object.keys(relative); - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; + const rkeys = Object.keys(relative); + for (let rk = 0; rk < rkeys.length; rk++) { + const rkey = rkeys[rk]; if (rkey !== 'protocol') result[rkey] = relative[rkey]; } @@ -723,9 +723,9 @@ Url.prototype.resolveObject = function resolveObject(relative) { // because that's known to be hostless. // anything else is assumed to be absolute. if (!slashedProtocol.has(relative.protocol)) { - var keys = Object.keys(relative); - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; + const keys = Object.keys(relative); + for (let v = 0; v < keys.length; v++) { + const k = keys[v]; result[k] = relative[k]; } result.href = result.format(); @@ -754,8 +754,8 @@ Url.prototype.resolveObject = function resolveObject(relative) { result.port = relative.port; // To support http.request if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; + const p = result.pathname || ''; + const s = result.search || ''; result.path = p + s; } result.slashes = result.slashes || relative.slashes; @@ -767,10 +767,10 @@ Url.prototype.resolveObject = function resolveObject(relative) { const isRelAbs = ( relative.host || (relative.pathname && relative.pathname.charAt(0) === '/') ); - var mustEndAbs = (isRelAbs || isSourceAbs || + let mustEndAbs = (isRelAbs || isSourceAbs || (result.host && relative.pathname)); const removeAllDots = mustEndAbs; - var srcPath = (result.pathname && result.pathname.split('/')) || []; + let srcPath = (result.pathname && result.pathname.split('/')) || []; const relPath = (relative.pathname && relative.pathname.split('/')) || []; const noLeadingSlashes = result.protocol && !slashedProtocol.has(result.protocol); @@ -867,15 +867,15 @@ Url.prototype.resolveObject = function resolveObject(relative) { // If a url ENDs in . or .., then it must get a trailing slash. // however, if it ends in anything else non-slashy, // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; + let last = srcPath.slice(-1)[0]; const hasTrailingSlash = ( ((result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..')) || last === ''); // Strip single dots, resolve double dots to parent dir // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length - 1; i >= 0; i--) { + let up = 0; + for (let i = srcPath.length - 1; i >= 0; i--) { last = srcPath[i]; if (last === '.') { spliceOne(srcPath, i); @@ -947,8 +947,8 @@ Url.prototype.resolveObject = function resolveObject(relative) { }; Url.prototype.parseHost = function parseHost() { - var host = this.host; - var port = portPattern.exec(host); + let host = this.host; + let port = portPattern.exec(host); if (port) { port = port[0]; if (port !== ':') { diff --git a/lib/v8.js b/lib/v8.js index 1a8c70c6d75d3f..32c2f3aa1b50ed 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -24,6 +24,7 @@ const { } = internalBinding('serdes'); const assert = require('internal/assert'); const { copy } = internalBinding('buffer'); +const { inspect } = require('internal/util/inspect'); const { FastBuffer } = require('internal/buffer'); const { getValidatedPath } = require('internal/fs/utils'); const { toNamespacedPath } = require('path'); @@ -164,7 +165,7 @@ function getHeapSpaceStatistics() { const buffer = heapSpaceStatisticsBuffer; updateHeapSpaceStatisticsArrayBuffer(); - for (var i = 0; i < kNumberOfHeapSpaces; i++) { + for (let i = 0; i < kNumberOfHeapSpaces; i++) { const propertyOffset = i * kHeapSpaceStatisticsPropertiesCount; heapSpaceStatistics[i] = { space_name: kHeapSpaces[i], @@ -242,7 +243,8 @@ class DefaultSerializer extends Serializer { i = arrayBufferViewTypeToIndex.get(tag); if (i === undefined) { - throw new this._getDataCloneError(`Unknown host object type: ${tag}`); + throw new this._getDataCloneError( + `Unserializable host object: ${inspect(abView)}`); } } this.writeUint32(i); diff --git a/lib/worker_threads.js b/lib/worker_threads.js index bd455edea22e52..4b72bf2711bdcc 100644 --- a/lib/worker_threads.js +++ b/lib/worker_threads.js @@ -3,6 +3,7 @@ const { isMainThread, SHARE_ENV, + resourceLimits, threadId, Worker } = require('internal/worker'); @@ -20,6 +21,7 @@ module.exports = { MessageChannel, moveMessagePortToContext, receiveMessageOnPort, + resourceLimits, threadId, SHARE_ENV, Worker, diff --git a/node.gyp b/node.gyp index 5f8089e617a247..810cea8c241359 100644 --- a/node.gyp +++ b/node.gyp @@ -1,7 +1,6 @@ { 'variables': { 'v8_use_siphash%': 0, - 'v8_use_snapshot%': 1, 'v8_trace_maps%': 0, 'node_use_dtrace%': 'false', 'node_use_etw%': 'false', @@ -91,6 +90,7 @@ 'lib/internal/buffer.js', 'lib/internal/cli_table.js', 'lib/internal/child_process.js', + 'lib/internal/child_process/serialization.js', 'lib/internal/cluster/child.js', 'lib/internal/cluster/master.js', 'lib/internal/cluster/round_robin_handle.js', @@ -145,6 +145,7 @@ 'lib/internal/main/run_main_module.js', 'lib/internal/main/run_third_party_main.js', 'lib/internal/main/worker_thread.js', + 'lib/internal/modules/run_main.js', 'lib/internal/modules/cjs/helpers.js', 'lib/internal/modules/cjs/loader.js', 'lib/internal/modules/esm/loader.js', @@ -564,7 +565,6 @@ 'src/node_zlib.cc', 'src/pipe_wrap.cc', 'src/process_wrap.cc', - 'src/sharedarraybuffer_metadata.cc', 'src/signal_wrap.cc', 'src/spawn_sync.cc', 'src/stream_base.cc', @@ -642,7 +642,6 @@ 'src/pipe_wrap.h', 'src/req_wrap.h', 'src/req_wrap-inl.h', - 'src/sharedarraybuffer_metadata.h', 'src/spawn_sync.h', 'src/stream_base.h', 'src/stream_base-inl.h', @@ -1101,6 +1100,7 @@ 'test/cctest/node_test_fixture.h', 'test/cctest/test_aliased_buffer.cc', 'test/cctest/test_base64.cc', + 'test/cctest/test_base_object_ptr.cc', 'test/cctest/test_node_postmortem_metadata.cc', 'test/cctest/test_environment.cc', 'test/cctest/test_linked_binding.cc', diff --git a/src/aliased_buffer.h b/src/aliased_buffer.h index 5083ae9a1f47b5..b083fb68e69bd2 100644 --- a/src/aliased_buffer.h +++ b/src/aliased_buffer.h @@ -42,7 +42,7 @@ class AliasedBufferBase { // allocate v8 ArrayBuffer v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New( isolate_, size_in_bytes); - buffer_ = static_cast<NativeT*>(ab->GetContents().Data()); + buffer_ = static_cast<NativeT*>(ab->GetBackingStore()->Data()); // allocate v8 TypedArray v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count); @@ -228,7 +228,7 @@ class AliasedBufferBase { isolate_, new_size_in_bytes); // allocate new native buffer - NativeT* new_buffer = static_cast<NativeT*>(ab->GetContents().Data()); + NativeT* new_buffer = static_cast<NativeT*>(ab->GetBackingStore()->Data()); // copy old content memcpy(new_buffer, buffer_, old_size_in_bytes); diff --git a/src/api/callback.cc b/src/api/callback.cc index 6d4e28e1d9070f..355986b981a381 100644 --- a/src/api/callback.cc +++ b/src/api/callback.cc @@ -34,22 +34,25 @@ CallbackScope::~CallbackScope() { delete private_; } -InternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap) +InternalCallbackScope::InternalCallbackScope(AsyncWrap* async_wrap, int flags) : InternalCallbackScope(async_wrap->env(), async_wrap->object(), { async_wrap->get_async_id(), - async_wrap->get_trigger_async_id() }) {} + async_wrap->get_trigger_async_id() }, + flags) {} InternalCallbackScope::InternalCallbackScope(Environment* env, Local<Object> object, const async_context& asyncContext, - ResourceExpectation expect) + int flags) : env_(env), async_context_(asyncContext), object_(object), - callback_scope_(env) { - CHECK_IMPLIES(expect == kRequireResource, !object.IsEmpty()); + skip_hooks_(flags & kSkipAsyncHooks), + skip_task_queues_(flags & kSkipTaskQueues) { + CHECK_IMPLIES(!(flags & kAllowEmptyResource), !object.IsEmpty()); CHECK_NOT_NULL(env); + env->PushAsyncCallbackScope(); if (!env->can_call_into_js()) { failed_ = true; @@ -60,7 +63,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env, // If you hit this assertion, you forgot to enter the v8::Context first. CHECK_EQ(Environment::GetCurrent(env->isolate()), env); - if (asyncContext.async_id != 0) { + if (asyncContext.async_id != 0 && !skip_hooks_) { // No need to check a return value because the application will exit if // an exception occurs. AsyncWrap::EmitBefore(env, asyncContext.async_id); @@ -73,6 +76,7 @@ InternalCallbackScope::InternalCallbackScope(Environment* env, InternalCallbackScope::~InternalCallbackScope() { Close(); + env_->PopAsyncCallbackScope(); } void InternalCallbackScope::Close() { @@ -89,11 +93,11 @@ void InternalCallbackScope::Close() { if (failed_) return; - if (async_context_.async_id != 0) { + if (async_context_.async_id != 0 && !skip_hooks_) { AsyncWrap::EmitAfter(env_, async_context_.async_id); } - if (env_->async_callback_scope_depth() > 1) { + if (env_->async_callback_scope_depth() > 1 || skip_task_queues_) { return; } @@ -101,7 +105,7 @@ void InternalCallbackScope::Close() { if (!env_->can_call_into_js()) return; - OnScopeLeave weakref_cleanup([&]() { env_->RunWeakRefCleanup(); }); + auto weakref_cleanup = OnScopeLeave([&]() { env_->RunWeakRefCleanup(); }); if (!tick_info->has_tick_scheduled()) { MicrotasksScope::PerformCheckpoint(env_->isolate()); diff --git a/src/api/environment.cc b/src/api/environment.cc index 846e4a873da51c..95ef13dfb1f4e6 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -279,6 +279,20 @@ Isolate* NewIsolate(ArrayBufferAllocator* allocator, return NewIsolate(¶ms, event_loop, platform); } +Isolate* NewIsolate(std::shared_ptr<ArrayBufferAllocator> allocator, + uv_loop_t* event_loop, + MultiIsolatePlatform* platform) { + Isolate::CreateParams params; + if (allocator) { + params.array_buffer_allocator = allocator.get(); + } + Isolate* isolate = NewIsolate(¶ms, event_loop, platform); + if (isolate != nullptr && allocator) { + isolate->SetArrayBufferAllocatorShared(std::move(allocator)); + } + return isolate; +} + IsolateData* CreateIsolateData(Isolate* isolate, uv_loop_t* loop, MultiIsolatePlatform* platform, @@ -498,4 +512,32 @@ uv_loop_t* GetCurrentEventLoop(Isolate* isolate) { return env->event_loop(); } +void AddLinkedBinding(Environment* env, const node_module& mod) { + CHECK_NOT_NULL(env); + Mutex::ScopedLock lock(env->extra_linked_bindings_mutex()); + + node_module* prev_head = env->extra_linked_bindings_head(); + env->extra_linked_bindings()->push_back(mod); + if (prev_head != nullptr) + prev_head->nm_link = &env->extra_linked_bindings()->back(); +} + +void AddLinkedBinding(Environment* env, + const char* name, + addon_context_register_func fn, + void* priv) { + node_module mod = { + NODE_MODULE_VERSION, + NM_F_LINKED, + nullptr, // nm_dso_handle + nullptr, // nm_filename + nullptr, // nm_register_func + fn, + name, + priv, + nullptr // nm_link + }; + AddLinkedBinding(env, mod); +} + } // namespace node diff --git a/src/api/hooks.cc b/src/api/hooks.cc index cec58cee00847c..2dd0cc994ea7f2 100644 --- a/src/api/hooks.cc +++ b/src/api/hooks.cc @@ -30,6 +30,8 @@ void AtExit(Environment* env, void (*cb)(void* arg), void* arg) { } void EmitBeforeExit(Environment* env) { + env->RunBeforeExitCallbacks(); + HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); Local<Value> exit_code = env->process_object() diff --git a/src/async_wrap-inl.h b/src/async_wrap-inl.h index 53972493052f5e..e3e48666e4fbd6 100644 --- a/src/async_wrap-inl.h +++ b/src/async_wrap-inl.h @@ -50,20 +50,6 @@ inline double AsyncWrap::get_trigger_async_id() const { } -inline AsyncWrap::AsyncScope::AsyncScope(AsyncWrap* wrap) - : wrap_(wrap) { - Environment* env = wrap->env(); - if (env->async_hooks()->fields()[AsyncHooks::kBefore] == 0) return; - EmitBefore(env, wrap->get_async_id()); -} - -inline AsyncWrap::AsyncScope::~AsyncScope() { - Environment* env = wrap_->env(); - if (env->async_hooks()->fields()[AsyncHooks::kAfter] == 0) return; - EmitAfter(env, wrap_->get_async_id()); -} - - inline v8::MaybeLocal<v8::Value> AsyncWrap::MakeCallback( const v8::Local<v8::String> symbol, int argc, diff --git a/src/async_wrap.h b/src/async_wrap.h index 2651b5a054d554..dd82497a259243 100644 --- a/src/async_wrap.h +++ b/src/async_wrap.h @@ -162,7 +162,6 @@ class AsyncWrap : public BaseObject { inline ProviderType set_provider_type(ProviderType provider); inline double get_async_id() const; - inline double get_trigger_async_id() const; void AsyncReset(v8::Local<v8::Object> resource, @@ -200,18 +199,6 @@ class AsyncWrap : public BaseObject { static v8::Local<v8::Object> GetOwner(Environment* env, v8::Local<v8::Object> obj); - // This is a simplified version of InternalCallbackScope that only runs - // the `before` and `after` hooks. Only use it when not actually calling - // back into JS; otherwise, use InternalCallbackScope. - class AsyncScope { - public: - explicit inline AsyncScope(AsyncWrap* wrap); - ~AsyncScope(); - - private: - AsyncWrap* wrap_ = nullptr; - }; - bool IsDoneInitializing() const override; private: diff --git a/src/base_object-inl.h b/src/base_object-inl.h index af69084f4a5595..f35cd6734edf0b 100644 --- a/src/base_object-inl.h +++ b/src/base_object-inl.h @@ -32,16 +32,25 @@ namespace node { BaseObject::BaseObject(Environment* env, v8::Local<v8::Object> object) - : persistent_handle_(env->isolate(), object), - env_(env) { + : persistent_handle_(env->isolate(), object), env_(env) { CHECK_EQ(false, object.IsEmpty()); CHECK_GT(object->InternalFieldCount(), 0); object->SetAlignedPointerInInternalField(0, static_cast<void*>(this)); - env_->AddCleanupHook(DeleteMe, static_cast<void*>(this)); + env->AddCleanupHook(DeleteMe, static_cast<void*>(this)); + env->modify_base_object_count(1); } BaseObject::~BaseObject() { - RemoveCleanupHook(); + env()->modify_base_object_count(-1); + env()->RemoveCleanupHook(DeleteMe, static_cast<void*>(this)); + + if (UNLIKELY(has_pointer_data())) { + PointerData* metadata = pointer_data(); + CHECK_EQ(metadata->strong_ptr_count, 0); + metadata->self = nullptr; + if (metadata->weak_ptr_count == 0) + delete metadata; + } if (persistent_handle_.IsEmpty()) { // This most likely happened because the weak callback below cleared it. @@ -49,13 +58,14 @@ BaseObject::~BaseObject() { } { - v8::HandleScope handle_scope(env_->isolate()); + v8::HandleScope handle_scope(env()->isolate()); object()->SetAlignedPointerInInternalField(0, nullptr); } } -void BaseObject::RemoveCleanupHook() { - env_->RemoveCleanupHook(DeleteMe, static_cast<void*>(this)); +void BaseObject::Detach() { + CHECK_GT(pointer_data()->strong_ptr_count, 0); + pointer_data()->is_detached = true; } v8::Global<v8::Object>& BaseObject::persistent() { @@ -64,14 +74,14 @@ v8::Global<v8::Object>& BaseObject::persistent() { v8::Local<v8::Object> BaseObject::object() const { - return PersistentToLocal::Default(env_->isolate(), persistent_handle_); + return PersistentToLocal::Default(env()->isolate(), persistent_handle_); } v8::Local<v8::Object> BaseObject::object(v8::Isolate* isolate) const { v8::Local<v8::Object> handle = object(); DCHECK_EQ(handle->CreationContext()->GetIsolate(), isolate); - DCHECK_EQ(env_->isolate(), isolate); + DCHECK_EQ(env()->isolate(), isolate); return handle; } @@ -80,7 +90,6 @@ Environment* BaseObject::env() const { return env_; } - BaseObject* BaseObject::FromJSObject(v8::Local<v8::Object> obj) { CHECK_GT(obj->InternalFieldCount(), 0); return static_cast<BaseObject*>(obj->GetAlignedPointerFromInternalField(0)); @@ -94,20 +103,34 @@ T* BaseObject::FromJSObject(v8::Local<v8::Object> object) { void BaseObject::MakeWeak() { + if (has_pointer_data()) { + pointer_data()->wants_weak_jsobj = true; + if (pointer_data()->strong_ptr_count > 0) return; + } + persistent_handle_.SetWeak( this, [](const v8::WeakCallbackInfo<BaseObject>& data) { - std::unique_ptr<BaseObject> obj(data.GetParameter()); + BaseObject* obj = data.GetParameter(); // Clear the persistent handle so that ~BaseObject() doesn't attempt // to mess with internal fields, since the JS object may have // transitioned into an invalid state. // Refs: https://github.com/nodejs/node/issues/18897 obj->persistent_handle_.Reset(); + CHECK_IMPLIES(obj->has_pointer_data(), + obj->pointer_data()->strong_ptr_count == 0); + obj->OnGCCollect(); }, v8::WeakCallbackType::kParameter); } +void BaseObject::OnGCCollect() { + delete this; +} void BaseObject::ClearWeak() { + if (has_pointer_data()) + pointer_data()->wants_weak_jsobj = false; + persistent_handle_.ClearWeak(); } @@ -141,6 +164,176 @@ void BaseObject::InternalFieldSet(v8::Local<v8::String> property, info.This()->SetInternalField(Field, value); } +bool BaseObject::has_pointer_data() const { + return pointer_data_ != nullptr; +} + +BaseObject::PointerData* BaseObject::pointer_data() { + if (!has_pointer_data()) { + PointerData* metadata = new PointerData(); + metadata->wants_weak_jsobj = persistent_handle_.IsWeak(); + metadata->self = this; + pointer_data_ = metadata; + } + CHECK(has_pointer_data()); + return pointer_data_; +} + +void BaseObject::decrease_refcount() { + CHECK(has_pointer_data()); + PointerData* metadata = pointer_data(); + CHECK_GT(metadata->strong_ptr_count, 0); + unsigned int new_refcount = --metadata->strong_ptr_count; + if (new_refcount == 0) { + if (metadata->is_detached) { + delete this; + } else if (metadata->wants_weak_jsobj && !persistent_handle_.IsEmpty()) { + MakeWeak(); + } + } +} + +void BaseObject::increase_refcount() { + unsigned int prev_refcount = pointer_data()->strong_ptr_count++; + if (prev_refcount == 0 && !persistent_handle_.IsEmpty()) + persistent_handle_.ClearWeak(); +} + +template <typename T, bool kIsWeak> +BaseObject::PointerData* +BaseObjectPtrImpl<T, kIsWeak>::pointer_data() const { + if (kIsWeak) { + return data_.pointer_data; + } else { + if (get_base_object() == nullptr) return nullptr; + return get_base_object()->pointer_data(); + } +} + +template <typename T, bool kIsWeak> +BaseObject* BaseObjectPtrImpl<T, kIsWeak>::get_base_object() const { + if (kIsWeak) { + if (pointer_data() == nullptr) return nullptr; + return pointer_data()->self; + } else { + return data_.target; + } +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::~BaseObjectPtrImpl() { + if (get() == nullptr) return; + if (kIsWeak) { + if (--pointer_data()->weak_ptr_count == 0 && + pointer_data()->self == nullptr) { + delete pointer_data(); + } + } else { + get()->decrease_refcount(); + } +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl() { + data_.target = nullptr; +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(T* target) + : BaseObjectPtrImpl() { + if (target == nullptr) return; + if (kIsWeak) { + data_.pointer_data = target->pointer_data(); + CHECK_NOT_NULL(pointer_data()); + pointer_data()->weak_ptr_count++; + } else { + data_.target = target; + CHECK_NOT_NULL(pointer_data()); + get()->increase_refcount(); + } +} + +template <typename T, bool kIsWeak> +template <typename U, bool kW> +BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl( + const BaseObjectPtrImpl<U, kW>& other) + : BaseObjectPtrImpl(other.get()) {} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(const BaseObjectPtrImpl& other) + : BaseObjectPtrImpl(other.get()) {} + +template <typename T, bool kIsWeak> +template <typename U, bool kW> +BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( + const BaseObjectPtrImpl<U, kW>& other) { + if (other.get() == get()) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(other); +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( + const BaseObjectPtrImpl& other) { + if (other.get() == get()) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(other); +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::BaseObjectPtrImpl(BaseObjectPtrImpl&& other) + : data_(other.data_) { + if (kIsWeak) + other.data_.target = nullptr; + else + other.data_.pointer_data = nullptr; +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>& BaseObjectPtrImpl<T, kIsWeak>::operator=( + BaseObjectPtrImpl&& other) { + if (&other == this) return *this; + this->~BaseObjectPtrImpl(); + return *new (this) BaseObjectPtrImpl(std::move(other)); +} + +template <typename T, bool kIsWeak> +void BaseObjectPtrImpl<T, kIsWeak>::reset(T* ptr) { + *this = BaseObjectPtrImpl(ptr); +} + +template <typename T, bool kIsWeak> +T* BaseObjectPtrImpl<T, kIsWeak>::get() const { + return static_cast<T*>(get_base_object()); +} + +template <typename T, bool kIsWeak> +T& BaseObjectPtrImpl<T, kIsWeak>::operator*() const { + return *get(); +} + +template <typename T, bool kIsWeak> +T* BaseObjectPtrImpl<T, kIsWeak>::operator->() const { + return get(); +} + +template <typename T, bool kIsWeak> +BaseObjectPtrImpl<T, kIsWeak>::operator bool() const { + return get() != nullptr; +} + +template <typename T, typename... Args> +BaseObjectPtr<T> MakeBaseObject(Args&&... args) { + return BaseObjectPtr<T>(new T(std::forward<Args>(args)...)); +} + +template <typename T, typename... Args> +BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args) { + BaseObjectPtr<T> target = MakeBaseObject<T>(std::forward<Args>(args)...); + target->Detach(); + return target; +} + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/base_object.h b/src/base_object.h index 0b202cd3a51324..daf40b7c1eb7b4 100644 --- a/src/base_object.h +++ b/src/base_object.h @@ -31,6 +31,8 @@ namespace node { class Environment; +template <typename T, bool kIsWeak> +class BaseObjectPtrImpl; class BaseObject : public MemoryRetainer { public: @@ -62,10 +64,12 @@ class BaseObject : public MemoryRetainer { static inline T* FromJSObject(v8::Local<v8::Object> object); // Make the `v8::Global` a weak reference and, `delete` this object once - // the JS object has been garbage collected. + // the JS object has been garbage collected and there are no (strong) + // BaseObjectPtr references to it. inline void MakeWeak(); - // Undo `MakeWeak()`, i.e. turn this into a strong reference. + // Undo `MakeWeak()`, i.e. turn this into a strong reference that is a GC + // root and will not be touched by the garbage collector. inline void ClearWeak(); // Utility to create a FunctionTemplate with one internal field (used for @@ -86,11 +90,14 @@ class BaseObject : public MemoryRetainer { // This is a bit of a hack. See the override in async_wrap.cc for details. virtual bool IsDoneInitializing() const; + // Can be used to avoid this object keepling itself alive as a GC root + // indefinitely, for example when this object is owned and deleted by another + // BaseObject once that is torn down. This can only be called when there is + // a BaseObjectPtr to this object. + inline void Detach(); + protected: - // Can be used to avoid the automatic object deletion when the Environment - // exits, for example when this object is owned and deleted by another - // BaseObject at that point. - inline void RemoveCleanupHook(); + virtual inline void OnGCCollect(); private: v8::Local<v8::Object> WrappedObject() const override; @@ -103,12 +110,44 @@ class BaseObject : public MemoryRetainer { // refer to `doc/guides/node-postmortem-support.md` friend int GenDebugSymbols(); friend class CleanupHookCallback; + template <typename T, bool kIsWeak> + friend class BaseObjectPtrImpl; v8::Global<v8::Object> persistent_handle_; + + // Metadata that is associated with this BaseObject if there are BaseObjectPtr + // or BaseObjectWeakPtr references to it. + // This object is deleted when the BaseObject itself is destroyed, and there + // are no weak references to it. + struct PointerData { + // Number of BaseObjectPtr instances that refer to this object. If this + // is non-zero, the BaseObject is always a GC root and will not be destroyed + // during cleanup until the count drops to zero again. + unsigned int strong_ptr_count = 0; + // Number of BaseObjectWeakPtr instances that refer to this object. + unsigned int weak_ptr_count = 0; + // Indicates whether MakeWeak() has been called. + bool wants_weak_jsobj = false; + // Indicates whether Detach() has been called. If that is the case, this + // object will be destryoed once the strong pointer count drops to zero. + bool is_detached = false; + // Reference to the original BaseObject. This is used by weak pointers. + BaseObject* self = nullptr; + }; + + inline bool has_pointer_data() const; + // This creates a PointerData struct if none was associated with this + // BaseObject before. + inline PointerData* pointer_data(); + + // Functions that adjust the strong pointer count. + inline void decrease_refcount(); + inline void increase_refcount(); + Environment* env_; + PointerData* pointer_data_ = nullptr; }; - // Global alias for FromJSObject() to avoid churn. template <typename T> inline T* Unwrap(v8::Local<v8::Object> obj) { @@ -124,6 +163,63 @@ inline T* Unwrap(v8::Local<v8::Object> obj) { return __VA_ARGS__; \ } while (0) +// Implementation of a generic strong or weak pointer to a BaseObject. +// If strong, this will keep the target BaseObject alive regardless of other +// circumstances such das GC or Environment cleanup. +// If weak, destruction behaviour is not affected, but the pointer will be +// reset to nullptr once the BaseObject is destroyed. +// The API matches std::shared_ptr closely. +template <typename T, bool kIsWeak> +class BaseObjectPtrImpl final { + public: + inline BaseObjectPtrImpl(); + inline ~BaseObjectPtrImpl(); + inline explicit BaseObjectPtrImpl(T* target); + + // Copy and move constructors. Note that the templated version is not a copy + // or move constructor in the C++ sense of the word, so an identical + // untemplated version is provided. + template <typename U, bool kW> + inline BaseObjectPtrImpl(const BaseObjectPtrImpl<U, kW>& other); + inline BaseObjectPtrImpl(const BaseObjectPtrImpl& other); + template <typename U, bool kW> + inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl<U, kW>& other); + inline BaseObjectPtrImpl& operator=(const BaseObjectPtrImpl& other); + inline BaseObjectPtrImpl(BaseObjectPtrImpl&& other); + inline BaseObjectPtrImpl& operator=(BaseObjectPtrImpl&& other); + + inline void reset(T* ptr = nullptr); + inline T* get() const; + inline T& operator*() const; + inline T* operator->() const; + inline operator bool() const; + + private: + union { + BaseObject* target; // Used for strong pointers. + BaseObject::PointerData* pointer_data; // Used for weak pointers. + } data_; + + inline BaseObject* get_base_object() const; + inline BaseObject::PointerData* pointer_data() const; +}; + +template <typename T> +using BaseObjectPtr = BaseObjectPtrImpl<T, false>; +template <typename T> +using BaseObjectWeakPtr = BaseObjectPtrImpl<T, true>; + +// Create a BaseObject instance and return a pointer to it. +// This variant leaves the object as a GC root by default. +template <typename T, typename... Args> +inline BaseObjectPtr<T> MakeBaseObject(Args&&... args); +// Create a BaseObject instance and return a pointer to it. +// This variant detaches the object by default, meaning that the caller fully +// owns it, and once the last BaseObjectPtr to it is destroyed, the object +// itself is also destroyed. +template <typename T, typename... Args> +inline BaseObjectPtr<T> MakeDetachedBaseObject(Args&&... args); + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 96062cb48199e3..1fb0f47dd80f08 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -575,10 +575,6 @@ class QueryWrap : public AsyncWrap { : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP), channel_(channel), trace_name_(name) { - // Make sure the channel object stays alive during the query lifetime. - req_wrap_obj->Set(env()->context(), - env()->channel_string(), - channel->object()).Check(); } ~QueryWrap() override { @@ -631,8 +627,6 @@ class QueryWrap : public AsyncWrap { } else { Parse(response_data_->host.get()); } - - delete this; } void* MakeCallbackPointer() { @@ -690,9 +684,13 @@ class QueryWrap : public AsyncWrap { } void QueueResponseCallback(int status) { - env()->SetImmediate([this](Environment*) { + BaseObjectPtr<QueryWrap> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment*) { AfterResponse(); - }, object()); + + // Delete once strong_ref goes out of scope. + Detach(); + }); channel_->set_query_last_ok(status != ARES_ECONNREFUSED); channel_->ModifyActivityQueryCount(-1); @@ -735,7 +733,7 @@ class QueryWrap : public AsyncWrap { UNREACHABLE(); } - ChannelWrap* channel_; + BaseObjectPtr<ChannelWrap> channel_; private: std::unique_ptr<ResponseData> response_data_; diff --git a/src/env-inl.h b/src/env-inl.h index d61ae8f8df1d17..15b5010deb7c90 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -211,14 +211,6 @@ Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { return ContainerOf(&Environment::async_hooks_, hooks); } -inline AsyncCallbackScope::AsyncCallbackScope(Environment* env) : env_(env) { - env_->PushAsyncCallbackScope(); -} - -inline AsyncCallbackScope::~AsyncCallbackScope() { - env_->PopAsyncCallbackScope(); -} - inline size_t Environment::async_callback_scope_depth() const { return async_callback_scope_depth_; } @@ -754,13 +746,9 @@ inline void IsolateData::set_options( } template <typename Fn> -void Environment::CreateImmediate(Fn&& cb, - v8::Local<v8::Object> keep_alive, - bool ref) { +void Environment::CreateImmediate(Fn&& cb, bool ref) { auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>( - std::move(cb), - v8::Global<v8::Object>(isolate(), keep_alive), - ref); + std::move(cb), ref); NativeImmediateCallback* prev_tail = native_immediate_callbacks_tail_; native_immediate_callbacks_tail_ = callback.get(); @@ -773,8 +761,8 @@ void Environment::CreateImmediate(Fn&& cb, } template <typename Fn> -void Environment::SetImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { - CreateImmediate(std::move(cb), keep_alive, true); +void Environment::SetImmediate(Fn&& cb) { + CreateImmediate(std::move(cb), true); if (immediate_info()->ref_count() == 0) ToggleImmediateRef(true); @@ -782,8 +770,8 @@ void Environment::SetImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { } template <typename Fn> -void Environment::SetUnrefImmediate(Fn&& cb, v8::Local<v8::Object> keep_alive) { - CreateImmediate(std::move(cb), keep_alive, false); +void Environment::SetUnrefImmediate(Fn&& cb) { + CreateImmediate(std::move(cb), false); } Environment::NativeImmediateCallback::NativeImmediateCallback(bool refed) @@ -805,10 +793,9 @@ void Environment::NativeImmediateCallback::set_next( template <typename Fn> Environment::NativeImmediateCallbackImpl<Fn>::NativeImmediateCallbackImpl( - Fn&& callback, v8::Global<v8::Object>&& keep_alive, bool refed) + Fn&& callback, bool refed) : NativeImmediateCallback(refed), - callback_(std::move(callback)), - keep_alive_(std::move(keep_alive)) {} + callback_(std::move(callback)) {} template <typename Fn> void Environment::NativeImmediateCallbackImpl<Fn>::Call(Environment* env) { @@ -876,6 +863,19 @@ inline bool Environment::is_stopping() const { return thread_stopper_.is_stopped(); } +inline std::list<node_module>* Environment::extra_linked_bindings() { + return &extra_linked_bindings_; +} + +inline node_module* Environment::extra_linked_bindings_head() { + return extra_linked_bindings_.size() > 0 ? + &extra_linked_bindings_.front() : nullptr; +} + +inline const Mutex& Environment::extra_linked_bindings_mutex() const { + return extra_linked_bindings_mutex_; +} + inline performance::performance_state* Environment::performance_state() { return performance_state_.get(); } @@ -1146,6 +1146,14 @@ void Environment::ForEachBaseObject(T&& iterator) { } } +void Environment::modify_base_object_count(int64_t delta) { + base_object_count_ += delta; +} + +int64_t Environment::base_object_count() const { + return base_object_count_; +} + bool AsyncRequest::is_stopped() const { return stopped_.load(); } diff --git a/src/env.cc b/src/env.cc index ff1868e75ecd5a..5f9a6acb461f97 100644 --- a/src/env.cc +++ b/src/env.cc @@ -431,6 +431,8 @@ Environment::~Environment() { addon.Close(); } } + + CHECK_EQ(base_object_count(), 0); } void Environment::InitializeLibuv(bool start_profiler_idle_notifier) { @@ -637,7 +639,7 @@ void Environment::RunAtExitCallbacks() { } void Environment::AtExit(void (*cb)(void* arg), void* arg) { - at_exit_functions_.push_back(ExitCallback{cb, arg}); + at_exit_functions_.push_front(ExitCallback{cb, arg}); } void Environment::RunAndClearNativeImmediates() { @@ -935,9 +937,10 @@ void Environment::stop_sub_worker_contexts() { } } -#if HAVE_INSPECTOR - -#endif // HAVE_INSPECTOR +Environment* Environment::worker_parent_env() const { + if (worker_context_ == nullptr) return nullptr; + return worker_context_->env(); +} void MemoryTracker::TrackField(const char* edge_name, const CleanupHookCallback& value, @@ -1037,21 +1040,6 @@ char* Environment::Reallocate(char* data, size_t old_size, size_t size) { return new_data; } -void Environment::AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose( - std::shared_ptr<v8::ArrayBuffer::Allocator> allocator) { - if (keep_alive_allocators_ == nullptr) { - MultiIsolatePlatform* platform = isolate_data()->platform(); - CHECK_NOT_NULL(platform); - - keep_alive_allocators_ = new ArrayBufferAllocatorList(); - platform->AddIsolateFinishedCallback(isolate(), [](void* data) { - delete static_cast<ArrayBufferAllocatorList*>(data); - }, static_cast<void*>(keep_alive_allocators_)); - } - - keep_alive_allocators_->insert(allocator); -} - bool Environment::RunWeakRefCleanup() { isolate()->ClearKeptObjects(); @@ -1102,6 +1090,10 @@ AsyncRequest::~AsyncRequest() { // Not really any better place than env.cc at this moment. void BaseObject::DeleteMe(void* data) { BaseObject* self = static_cast<BaseObject*>(data); + if (self->has_pointer_data() && + self->pointer_data()->strong_ptr_count > 0) { + return self->Detach(); + } delete self; } diff --git a/src/env.h b/src/env.h index a649675c7cc902..495d92471a336f 100644 --- a/src/env.h +++ b/src/env.h @@ -151,12 +151,12 @@ constexpr size_t kFsStatsBufferLength = // "node:" prefix to avoid name clashes with third-party code. #define PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(V) \ V(alpn_buffer_private_symbol, "node:alpnBuffer") \ + V(arraybuffer_untransferable_private_symbol, "node:untransferableBuffer") \ V(arrow_message_private_symbol, "node:arrowMessage") \ V(contextify_context_private_symbol, "node:contextify:context") \ V(contextify_global_private_symbol, "node:contextify:global") \ V(decorated_private_symbol, "node:decorated") \ V(napi_wrapper, "node:napi:wrapper") \ - V(sab_lifetimepartner_symbol, "node:sharedArrayBufferLifetimePartner") \ // Symbols are per-isolate primitives but Environment proxies them // for the sake of convenience. @@ -201,6 +201,7 @@ constexpr size_t kFsStatsBufferLength = V(crypto_rsa_pss_string, "rsa-pss") \ V(cwd_string, "cwd") \ V(data_string, "data") \ + V(default_string, "default") \ V(dest_string, "dest") \ V(destroyed_string, "destroyed") \ V(detached_string, "detached") \ @@ -215,8 +216,10 @@ constexpr size_t kFsStatsBufferLength = V(dns_srv_string, "SRV") \ V(dns_txt_string, "TXT") \ V(done_string, "done") \ + V(dot_string, ".") \ V(duration_string, "duration") \ V(emit_warning_string, "emitWarning") \ + V(empty_object_string, "{}") \ V(encoding_string, "encoding") \ V(entries_string, "entries") \ V(entry_type_string, "entryType") \ @@ -278,6 +281,7 @@ constexpr size_t kFsStatsBufferLength = V(netmask_string, "netmask") \ V(next_string, "next") \ V(nistcurve_string, "nistCurve") \ + V(node_string, "node") \ V(nsname_string, "nsname") \ V(ocsp_request_string, "OCSPRequest") \ V(oncertcb_string, "oncertcb") \ @@ -721,20 +725,6 @@ class AsyncHooks : public MemoryRetainer { void grow_async_ids_stack(); }; -class AsyncCallbackScope { - public: - AsyncCallbackScope() = delete; - explicit AsyncCallbackScope(Environment* env); - ~AsyncCallbackScope(); - AsyncCallbackScope(const AsyncCallbackScope&) = delete; - AsyncCallbackScope& operator=(const AsyncCallbackScope&) = delete; - AsyncCallbackScope(AsyncCallbackScope&&) = delete; - AsyncCallbackScope& operator=(AsyncCallbackScope&&) = delete; - - private: - Environment* env_; -}; - class ImmediateInfo : public MemoryRetainer { public: inline AliasedUint32Array& fields(); @@ -874,7 +864,8 @@ class Environment : public MemoryRetainer { #if HAVE_INSPECTOR // If the environment is created for a worker, pass parent_handle and // the ownership if transferred into the Environment. - int InitializeInspector(inspector::ParentInspectorHandle* parent_handle); + int InitializeInspector( + std::unique_ptr<inspector::ParentInspectorHandle> parent_handle); #endif v8::MaybeLocal<v8::Value> BootstrapInternalLoaders(); @@ -1082,11 +1073,15 @@ class Environment : public MemoryRetainer { inline bool owns_inspector() const; inline uint64_t thread_id() const; inline worker::Worker* worker_context() const; + Environment* worker_parent_env() const; inline void set_worker_context(worker::Worker* context); inline void add_sub_worker_context(worker::Worker* context); inline void remove_sub_worker_context(worker::Worker* context); void stop_sub_worker_contexts(); inline bool is_stopping() const; + inline std::list<node_module>* extra_linked_bindings(); + inline node_module* extra_linked_bindings_head(); + inline const Mutex& extra_linked_bindings_mutex() const; inline void ThrowError(const char* errmsg); inline void ThrowTypeError(const char* errmsg); @@ -1189,13 +1184,9 @@ class Environment : public MemoryRetainer { // cb will be called as cb(env) on the next event loop iteration. // keep_alive will be kept alive between now and after the callback has run. template <typename Fn> - inline void SetImmediate(Fn&& cb, - v8::Local<v8::Object> keep_alive = - v8::Local<v8::Object>()); + inline void SetImmediate(Fn&& cb); template <typename Fn> - inline void SetUnrefImmediate(Fn&& cb, - v8::Local<v8::Object> keep_alive = - v8::Local<v8::Object>()); + inline void SetUnrefImmediate(Fn&& cb); // This needs to be available for the JS-land setImmediate(). void ToggleImmediateRef(bool ref); @@ -1222,6 +1213,12 @@ class Environment : public MemoryRetainer { inline AsyncRequest* thread_stopper() { return &thread_stopper_; } + // The BaseObject count is a debugging helper that makes sure that there are + // no memory leaks caused by BaseObjects staying alive longer than expected + // (in particular, no circular BaseObjectPtr references). + inline void modify_base_object_count(int64_t delta); + inline int64_t base_object_count() const; + #if HAVE_INSPECTOR void set_coverage_connection( std::unique_ptr<profiler::V8CoverageConnection> connection); @@ -1258,15 +1255,9 @@ class Environment : public MemoryRetainer { #endif // HAVE_INSPECTOR - // Only available if a MultiIsolatePlatform is in use. - void AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose( - std::shared_ptr<v8::ArrayBuffer::Allocator>); - private: template <typename Fn> - inline void CreateImmediate(Fn&& cb, - v8::Local<v8::Object> keep_alive, - bool ref); + inline void CreateImmediate(Fn&& cb, bool ref); inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>), const char* errmsg); @@ -1382,6 +1373,9 @@ class Environment : public MemoryRetainer { worker::Worker* worker_context_ = nullptr; + std::list<node_module> extra_linked_bindings_; + Mutex extra_linked_bindings_mutex_; + static void RunTimers(uv_timer_t* handle); struct ExitCallback { @@ -1411,14 +1405,11 @@ class Environment : public MemoryRetainer { template <typename Fn> class NativeImmediateCallbackImpl final : public NativeImmediateCallback { public: - NativeImmediateCallbackImpl(Fn&& callback, - v8::Global<v8::Object>&& keep_alive, - bool refed); + NativeImmediateCallbackImpl(Fn&& callback, bool refed); void Call(Environment* env) override; private: Fn callback_; - v8::Global<v8::Object> keep_alive_; }; std::unique_ptr<NativeImmediateCallback> native_immediate_callbacks_head_; @@ -1434,14 +1425,12 @@ class Environment : public MemoryRetainer { uint64_t cleanup_hook_counter_ = 0; bool started_cleanup_ = false; + int64_t base_object_count_ = 0; + // A custom async abstraction (a pair of async handle and a state variable) // Used by embedders to shutdown running Node instance. AsyncRequest thread_stopper_; - typedef std::unordered_set<std::shared_ptr<v8::ArrayBuffer::Allocator>> - ArrayBufferAllocatorList; - ArrayBufferAllocatorList* keep_alive_allocators_ = nullptr; - template <typename T> void ForEachBaseObject(T&& iterator); diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index 888640e9493d8e..198b0456e75751 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -84,14 +84,8 @@ void HandleWrap::Close(Local<Value> close_callback) { } -void HandleWrap::MakeWeak() { - persistent().SetWeak( - this, - [](const v8::WeakCallbackInfo<HandleWrap>& data) { - HandleWrap* handle_wrap = data.GetParameter(); - handle_wrap->persistent().Reset(); - handle_wrap->Close(); - }, v8::WeakCallbackType::kParameter); +void HandleWrap::OnGCCollect() { + Close(); } @@ -116,12 +110,15 @@ HandleWrap::HandleWrap(Environment* env, handle_(handle) { handle_->data = this; HandleScope scope(env->isolate()); + CHECK(env->has_run_bootstrapping_code()); env->handle_wrap_queue()->PushBack(this); } void HandleWrap::OnClose(uv_handle_t* handle) { - std::unique_ptr<HandleWrap> wrap { static_cast<HandleWrap*>(handle->data) }; + BaseObjectPtr<HandleWrap> wrap { static_cast<HandleWrap*>(handle->data) }; + wrap->Detach(); + Environment* env = wrap->env(); HandleScope scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -131,6 +128,7 @@ void HandleWrap::OnClose(uv_handle_t* handle) { wrap->state_ = kClosed; wrap->OnClose(); + wrap->handle_wrap_queue_.Remove(); if (!wrap->persistent().IsEmpty() && wrap->object()->Has(env->context(), env->handle_onclose_symbol()) diff --git a/src/handle_wrap.h b/src/handle_wrap.h index fbcea4ae4487f5..612874aa2efb4f 100644 --- a/src/handle_wrap.h +++ b/src/handle_wrap.h @@ -76,14 +76,13 @@ class HandleWrap : public AsyncWrap { static v8::Local<v8::FunctionTemplate> GetConstructorTemplate( Environment* env); - void MakeWeak(); // This hides BaseObject::MakeWeak() - protected: HandleWrap(Environment* env, v8::Local<v8::Object> object, uv_handle_t* handle, AsyncWrap::ProviderType provider); virtual void OnClose() {} + void OnGCCollect() final; void MarkAsInitialized(); void MarkAsUninitialized(); diff --git a/src/heap_utils.cc b/src/heap_utils.cc index 8391f1de3726c1..b996f78aa4199b 100644 --- a/src/heap_utils.cc +++ b/src/heap_utils.cc @@ -89,14 +89,15 @@ class JSGraph : public EmbedderGraph { MaybeLocal<Array> CreateObject() const { EscapableHandleScope handle_scope(isolate_); Local<Context> context = isolate_->GetCurrentContext(); + Environment* env = Environment::GetCurrent(context); std::unordered_map<Node*, Local<Object>> info_objects; Local<Array> nodes = Array::New(isolate_, nodes_.size()); Local<String> edges_string = FIXED_ONE_BYTE_STRING(isolate_, "edges"); Local<String> is_root_string = FIXED_ONE_BYTE_STRING(isolate_, "isRoot"); - Local<String> name_string = FIXED_ONE_BYTE_STRING(isolate_, "name"); - Local<String> size_string = FIXED_ONE_BYTE_STRING(isolate_, "size"); - Local<String> value_string = FIXED_ONE_BYTE_STRING(isolate_, "value"); + Local<String> name_string = env->name_string(); + Local<String> size_string = env->size_string(); + Local<String> value_string = env->value_string(); Local<String> wraps_string = FIXED_ONE_BYTE_STRING(isolate_, "wraps"); Local<String> to_string = FIXED_ONE_BYTE_STRING(isolate_, "to"); diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 469e0b4f8f335a..f13e68c067529e 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -778,6 +778,13 @@ bool Agent::Start(const std::string& path, StartDebugSignalHandler(); } + AtExit(parent_env_, [](void* env) { + Agent* agent = static_cast<Environment*>(env)->inspector_agent(); + if (agent->IsActive()) { + agent->WaitForDisconnect(); + } + }, parent_env_); + bool wait_for_connect = options.wait_for_connect(); if (parent_handle_) { wait_for_connect = parent_handle_->WaitForConnect(); diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc index b5f63b2b41389d..e0d02d6952a3f9 100644 --- a/src/inspector_profiler.cc +++ b/src/inspector_profiler.cc @@ -4,6 +4,7 @@ #include "diagnosticfilename-inl.h" #include "memory_tracker-inl.h" #include "node_file.h" +#include "node_errors.h" #include "node_internals.h" #include "util-inl.h" #include "v8-inspector.h" @@ -13,6 +14,7 @@ namespace node { namespace profiler { +using errors::TryCatchScope; using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; @@ -219,12 +221,21 @@ void V8CoverageConnection::WriteProfile(Local<String> message) { } // append source-map cache information to coverage object: - Local<Function> source_map_cache_getter = env_->source_map_cache_getter(); Local<Value> source_map_cache_v; - if (!source_map_cache_getter->Call(env()->context(), - Undefined(isolate), 0, nullptr) - .ToLocal(&source_map_cache_v)) { - return; + { + TryCatchScope try_catch(env()); + { + Isolate::AllowJavascriptExecutionScope allow_js_here(isolate); + Local<Function> source_map_cache_getter = env_->source_map_cache_getter(); + if (!source_map_cache_getter->Call( + context, Undefined(isolate), 0, nullptr) + .ToLocal(&source_map_cache_v)) { + return; + } + } + if (try_catch.HasCaught() && !try_catch.HasTerminated()) { + PrintCaughtException(isolate, context, try_catch); + } } // Avoid writing to disk if no source-map data: if (!source_map_cache_v->IsUndefined()) { @@ -351,7 +362,7 @@ void V8HeapProfilerConnection::End() { // For now, we only support coverage profiling, but we may add more // in the future. -void EndStartedProfilers(Environment* env) { +static void EndStartedProfilers(Environment* env) { Debug(env, DebugCategory::INSPECTOR_PROFILER, "EndStartedProfilers\n"); V8ProfilerConnection* connection = env->cpu_profiler_connection(); if (connection != nullptr && !connection->ending()) { @@ -390,6 +401,10 @@ std::string GetCwd(Environment* env) { } void StartProfilers(Environment* env) { + AtExit(env, [](void* env) { + EndStartedProfilers(static_cast<Environment*>(env)); + }, env); + Isolate* isolate = env->isolate(); Local<String> coverage_str = env->env_vars()->Get( isolate, FIXED_ONE_BYTE_STRING(isolate, "NODE_V8_COVERAGE")) diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index 1f5b6c012f7975..6484afaaac629e 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -2562,7 +2562,7 @@ napi_status napi_create_arraybuffer(napi_env env, // Optionally return a pointer to the buffer's data, to avoid another call to // retrieve it. if (data != nullptr) { - *data = buffer->GetContents().Data(); + *data = buffer->GetBackingStore()->Data(); } *result = v8impl::JsValueFromV8LocalValue(buffer); @@ -2581,6 +2581,8 @@ napi_status napi_create_external_arraybuffer(napi_env env, v8::Isolate* isolate = env->isolate; v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, external_data, byte_length); + v8::Maybe<bool> marked = env->mark_arraybuffer_as_untransferable(buffer); + CHECK_MAYBE_NOTHING(env, marked, napi_generic_failure); if (finalize_cb != nullptr) { // Create a self-deleting weak reference that invokes the finalizer @@ -2608,15 +2610,15 @@ napi_status napi_get_arraybuffer_info(napi_env env, v8::Local<v8::Value> value = v8impl::V8LocalValueFromJsValue(arraybuffer); RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_invalid_arg); - v8::ArrayBuffer::Contents contents = - value.As<v8::ArrayBuffer>()->GetContents(); + std::shared_ptr<v8::BackingStore> backing_store = + value.As<v8::ArrayBuffer>()->GetBackingStore(); if (data != nullptr) { - *data = contents.Data(); + *data = backing_store->Data(); } if (byte_length != nullptr) { - *byte_length = contents.ByteLength(); + *byte_length = backing_store->ByteLength(); } return napi_clear_last_error(env); @@ -2747,9 +2749,15 @@ napi_status napi_get_typedarray_info(napi_env env, *length = array->Length(); } - v8::Local<v8::ArrayBuffer> buffer = array->Buffer(); + v8::Local<v8::ArrayBuffer> buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + if (data != nullptr) { - *data = static_cast<uint8_t*>(buffer->GetContents().Data()) + + *data = static_cast<uint8_t*>(buffer->GetBackingStore()->Data()) + array->ByteOffset(); } @@ -2821,9 +2829,15 @@ napi_status napi_get_dataview_info(napi_env env, *byte_length = array->ByteLength(); } - v8::Local<v8::ArrayBuffer> buffer = array->Buffer(); + v8::Local<v8::ArrayBuffer> buffer; + if (data != nullptr || arraybuffer != nullptr) { + // Calling Buffer() may have the side effect of allocating the buffer, + // so only do this when it’s needed. + buffer = array->Buffer(); + } + if (data != nullptr) { - *data = static_cast<uint8_t*>(buffer->GetContents().Data()) + + *data = static_cast<uint8_t*>(buffer->GetBackingStore()->Data()) + array->ByteOffset(); } @@ -3015,6 +3029,7 @@ napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer) { env, value->IsArrayBuffer(), napi_arraybuffer_expected); v8::Local<v8::ArrayBuffer> it = value.As<v8::ArrayBuffer>(); + // TODO(addaleax): Remove the first condition once we have V8 8.0. RETURN_STATUS_IF_FALSE( env, it->IsExternal(), napi_detachable_arraybuffer_expected); RETURN_STATUS_IF_FALSE( diff --git a/src/js_native_api_v8.h b/src/js_native_api_v8.h index 2e0a7a1d6add20..534b09851f8c8e 100644 --- a/src/js_native_api_v8.h +++ b/src/js_native_api_v8.h @@ -39,6 +39,10 @@ struct napi_env__ { inline void Unref() { if ( --refs == 0) delete this; } virtual bool can_call_into_js() const { return true; } + virtual v8::Maybe<bool> mark_arraybuffer_as_untransferable( + v8::Local<v8::ArrayBuffer> ab) const { + return v8::Just(true); + } template <typename T, typename U> void CallIntoModule(T&& call, U&& handle_exception) { diff --git a/src/large_pages/node_large_page.cc b/src/large_pages/node_large_page.cc index 4e2f8fc4410316..68fa178b40b6cd 100644 --- a/src/large_pages/node_large_page.cc +++ b/src/large_pages/node_large_page.cc @@ -333,7 +333,7 @@ MoveTextRegionToLargePages(const text_region& r) { PrintSystemError(errno); return -1; } - OnScopeLeave munmap_on_return([nmem, size]() { + auto munmap_on_return = OnScopeLeave([nmem, size]() { if (-1 == munmap(nmem, size)) PrintSystemError(errno); }); diff --git a/src/memory_tracker-inl.h b/src/memory_tracker-inl.h index da37f72c737607..938aba1a7a8d11 100644 --- a/src/memory_tracker-inl.h +++ b/src/memory_tracker-inl.h @@ -109,6 +109,24 @@ void MemoryTracker::TrackField(const char* edge_name, TrackField(edge_name, value.get(), node_name); } +template <typename T> +void MemoryTracker::TrackField(const char* edge_name, + const std::shared_ptr<T>& value, + const char* node_name) { + if (value.get() == nullptr) { + return; + } + TrackField(edge_name, value.get(), node_name); +} + +template <typename T, bool kIsWeak> +void MemoryTracker::TrackField(const char* edge_name, + const BaseObjectPtrImpl<T, kIsWeak>& value, + const char* node_name) { + if (value.get() == nullptr) return; + TrackField(edge_name, value.get(), node_name); +} + template <typename T, typename Iterator> void MemoryTracker::TrackField(const char* edge_name, const T& value, @@ -206,6 +224,12 @@ void MemoryTracker::TrackField(const char* edge_name, TrackFieldWithSize(edge_name, value.size, "MallocedBuffer"); } +void MemoryTracker::TrackField(const char* edge_name, + const v8::BackingStore* value, + const char* node_name) { + TrackFieldWithSize(edge_name, value->ByteLength(), "BackingStore"); +} + void MemoryTracker::TrackField(const char* name, const uv_buf_t& value, const char* node_name) { diff --git a/src/memory_tracker.h b/src/memory_tracker.h index d22116918afec8..7e39da5ecf6de9 100644 --- a/src/memory_tracker.h +++ b/src/memory_tracker.h @@ -30,6 +30,8 @@ namespace node { class MemoryTracker; class MemoryRetainerNode; +template <typename T, bool kIsWeak> +class BaseObjectPtrImpl; namespace crypto { class NodeBIO; @@ -139,6 +141,16 @@ class MemoryTracker { const std::unique_ptr<T>& value, const char* node_name = nullptr); + template <typename T> + inline void TrackField(const char* edge_name, + const std::shared_ptr<T>& value, + const char* node_name = nullptr); + + template <typename T, bool kIsWeak> + void TrackField(const char* edge_name, + const BaseObjectPtrImpl<T, kIsWeak>& value, + const char* node_name = nullptr); + // For containers, the elements will be graphed as grandchildren nodes // if the container is not empty. // By default, we assume the parent count the stack size of the container @@ -197,6 +209,9 @@ class MemoryTracker { inline void TrackField(const char* edge_name, const MallocedBuffer<T>& value, const char* node_name = nullptr); + inline void TrackField(const char* edge_name, + const v8::BackingStore* value, + const char* node_name = nullptr); // We do not implement CleanupHookCallback as MemoryRetainer // but instead specialize the method here to avoid the cost of // virtual pointers. diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 4c4a1ce863849e..5745cce9e099ab 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -835,10 +835,16 @@ void ThrowExportsInvalid(Environment* env, const std::string& target, const URL& pjson_url, const URL& base) { - const std::string msg = "Cannot resolve package exports target '" + target + - "' matched for '" + subpath + "' in " + pjson_url.ToFilePath() + - ", imported from " + base.ToFilePath(); - node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str()); + if (subpath.length()) { + const std::string msg = "Cannot resolve package exports target '" + target + + "' matched for '" + subpath + "' in " + pjson_url.ToFilePath() + + ", imported from " + base.ToFilePath(); + node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str()); + } else { + const std::string msg = "Cannot resolve package main '" + target + "' in" + + pjson_url.ToFilePath() + ", imported from " + base.ToFilePath(); + node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str()); + } } void ThrowExportsInvalid(Environment* env, @@ -857,13 +863,13 @@ void ThrowExportsInvalid(Environment* env, } } -Maybe<URL> ResolveExportsTarget(Environment* env, - const std::string& target, - const std::string& subpath, - const std::string& match, - const URL& pjson_url, - const URL& base, - bool throw_invalid = true) { +Maybe<URL> ResolveExportsTargetString(Environment* env, + const std::string& target, + const std::string& subpath, + const std::string& match, + const URL& pjson_url, + const URL& base, + bool throw_invalid = true) { if (target.substr(0, 2) != "./") { if (throw_invalid) { ThrowExportsInvalid(env, match, target, pjson_url, base); @@ -901,68 +907,142 @@ Maybe<URL> ResolveExportsTarget(Environment* env, return Just(subpath_resolved); } +Maybe<URL> ResolveExportsTarget(Environment* env, + const URL& pjson_url, + Local<Value> target, + const std::string& subpath, + const std::string& pkg_subpath, + const URL& base, + bool throw_invalid = true) { + Isolate* isolate = env->isolate(); + Local<Context> context = env->context(); + if (target->IsString()) { + Utf8Value target_utf8(isolate, target.As<v8::String>()); + std::string target_str(*target_utf8, target_utf8.length()); + Maybe<URL> resolved = ResolveExportsTargetString(env, target_str, subpath, + pkg_subpath, pjson_url, base, throw_invalid); + if (resolved.IsNothing()) { + return Nothing<URL>(); + } + return FinalizeResolution(env, resolved.FromJust(), base); + } else if (target->IsArray()) { + Local<Array> target_arr = target.As<Array>(); + const uint32_t length = target_arr->Length(); + if (length == 0) { + if (throw_invalid) { + ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); + } + return Nothing<URL>(); + } + for (uint32_t i = 0; i < length; i++) { + auto target_item = target_arr->Get(context, i).ToLocalChecked(); + if (!target_item->IsArray()) { + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, + target_item, subpath, pkg_subpath, base, false); + if (resolved.IsNothing()) continue; + return FinalizeResolution(env, resolved.FromJust(), base); + } + } + if (throw_invalid) { + auto invalid = target_arr->Get(context, length - 1).ToLocalChecked(); + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, invalid, + subpath, pkg_subpath, base, true); + CHECK(resolved.IsNothing()); + } + return Nothing<URL>(); + } else if (target->IsObject()) { + Local<Object> target_obj = target.As<Object>(); + bool matched = false; + Local<Value> conditionalTarget; + if (env->options()->experimental_conditional_exports && + target_obj->HasOwnProperty(context, env->node_string()).FromJust()) { + matched = true; + conditionalTarget = + target_obj->Get(context, env->node_string()).ToLocalChecked(); + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, + conditionalTarget, subpath, pkg_subpath, base, false); + if (!resolved.IsNothing()) { + return resolved; + } + } + if (target_obj->HasOwnProperty(context, env->default_string()).FromJust()) { + matched = true; + conditionalTarget = + target_obj->Get(context, env->default_string()).ToLocalChecked(); + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, + conditionalTarget, subpath, pkg_subpath, base, false); + if (!resolved.IsNothing()) { + return resolved; + } + } + if (matched && throw_invalid) { + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, + conditionalTarget, subpath, pkg_subpath, base, true); + CHECK(resolved.IsNothing()); + return Nothing<URL>(); + } + } + if (throw_invalid) { + ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); + } + return Nothing<URL>(); +} + +Maybe<bool> IsConditionalExportsMainSugar(Environment* env, + Local<Value> exports, + const URL& pjson_url, + const URL& base) { + if (exports->IsString() || exports->IsArray()) return Just(true); + if (!exports->IsObject()) return Just(false); + Local<Context> context = env->context(); + Local<Object> exports_obj = exports.As<Object>(); + Local<Array> keys = + exports_obj->GetOwnPropertyNames(context).ToLocalChecked(); + bool isConditionalSugar = false; + for (uint32_t i = 0; i < keys->Length(); ++i) { + Local<String> key = keys->Get(context, i).ToLocalChecked().As<String>(); + Utf8Value key_utf8(env->isolate(), key); + bool curIsConditionalSugar = key_utf8.length() == 0 || key_utf8[0] != '.'; + if (i == 0) { + isConditionalSugar = curIsConditionalSugar; + } else if (isConditionalSugar != curIsConditionalSugar) { + const std::string msg = "Cannot resolve package exports in " + + pjson_url.ToFilePath() + ", imported from " + base.ToFilePath() + ". " + + "\"exports\" cannot contain some keys starting with '.' and some not." + + " The exports object must either be an object of package subpath keys" + + " or an object of main entry condition name keys only."; + node::THROW_ERR_INVALID_PACKAGE_CONFIG(env, msg.c_str()); + return Nothing<bool>(); + } + } + return Just(isConditionalSugar); +} + Maybe<URL> PackageMainResolve(Environment* env, const URL& pjson_url, const PackageConfig& pcfg, const URL& base) { if (pcfg.exists == Exists::Yes) { Isolate* isolate = env->isolate(); - Local<Context> context = env->context(); + if (!pcfg.exports.IsEmpty()) { Local<Value> exports = pcfg.exports.Get(isolate); - if (exports->IsString() || exports->IsObject() || exports->IsArray()) { - Local<Value> target; - if (!exports->IsObject()) { - target = exports; - } else { - Local<Object> exports_obj = exports.As<Object>(); - Local<String> dot_string = String::NewFromUtf8(env->isolate(), ".", - v8::NewStringType::kNormal).ToLocalChecked(); - target = - exports_obj->Get(env->context(), dot_string).ToLocalChecked(); - } - if (target->IsString()) { - Utf8Value target_utf8(isolate, target.As<v8::String>()); - std::string target(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target, "", ".", - pjson_url, base); - if (resolved.IsNothing()) { - ThrowExportsInvalid(env, ".", target, pjson_url, base); - return Nothing<URL>(); - } - return FinalizeResolution(env, resolved.FromJust(), base); - } else if (target->IsArray()) { - Local<Array> target_arr = target.As<Array>(); - const uint32_t length = target_arr->Length(); - if (length == 0) { - ThrowExportsInvalid(env, ".", target, pjson_url, base); - return Nothing<URL>(); - } - for (uint32_t i = 0; i < length; i++) { - auto target_item = target_arr->Get(context, i).ToLocalChecked(); - if (target_item->IsString()) { - Utf8Value target_utf8(isolate, target_item.As<v8::String>()); - std::string target_str(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target_str, "", - ".", pjson_url, base, false); - if (resolved.IsNothing()) continue; - return FinalizeResolution(env, resolved.FromJust(), base); - } - } - auto invalid = target_arr->Get(context, length - 1).ToLocalChecked(); - if (!invalid->IsString()) { - ThrowExportsInvalid(env, ".", invalid, pjson_url, base); - return Nothing<URL>(); - } - Utf8Value invalid_utf8(isolate, invalid.As<v8::String>()); - std::string invalid_str(*invalid_utf8, invalid_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, invalid_str, "", - ".", pjson_url, base); - CHECK(resolved.IsNothing()); - return Nothing<URL>(); - } else { - ThrowExportsInvalid(env, ".", target, pjson_url, base); - return Nothing<URL>(); + Maybe<bool> isConditionalExportsMainSugar = + IsConditionalExportsMainSugar(env, exports, pjson_url, base); + if (isConditionalExportsMainSugar.IsNothing()) + return Nothing<URL>(); + if (isConditionalExportsMainSugar.FromJust()) { + return ResolveExportsTarget(env, pjson_url, exports, "", "", base, + true); + } else if (exports->IsObject()) { + Local<Object> exports_obj = exports.As<Object>(); + if (exports_obj->HasOwnProperty(env->context(), env->dot_string()) + .FromJust()) { + Local<Value> target = + exports_obj->Get(env->context(), env->dot_string()) + .ToLocalChecked(); + return ResolveExportsTarget(env, pjson_url, target, "", "", base, + true); } } } @@ -1002,7 +1082,11 @@ Maybe<URL> PackageExportsResolve(Environment* env, Isolate* isolate = env->isolate(); Local<Context> context = env->context(); Local<Value> exports = pcfg.exports.Get(isolate); - if (!exports->IsObject()) { + Maybe<bool> isConditionalExportsMainSugar = + IsConditionalExportsMainSugar(env, exports, pjson_url, base); + if (isConditionalExportsMainSugar.IsNothing()) + return Nothing<URL>(); + if (!exports->IsObject() || isConditionalExportsMainSugar.FromJust()) { ThrowExportsNotFound(env, pkg_subpath, pjson_url, base); return Nothing<URL>(); } @@ -1012,49 +1096,12 @@ Maybe<URL> PackageExportsResolve(Environment* env, if (exports_obj->HasOwnProperty(context, subpath).FromJust()) { Local<Value> target = exports_obj->Get(context, subpath).ToLocalChecked(); - if (target->IsString()) { - Utf8Value target_utf8(isolate, target.As<v8::String>()); - std::string target_str(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target_str, "", - pkg_subpath, pjson_url, base); - if (resolved.IsNothing()) { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); - return Nothing<URL>(); - } - return FinalizeResolution(env, resolved.FromJust(), base); - } else if (target->IsArray()) { - Local<Array> target_arr = target.As<Array>(); - const uint32_t length = target_arr->Length(); - if (length == 0) { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); - return Nothing<URL>(); - } - for (uint32_t i = 0; i < length; i++) { - auto target_item = target_arr->Get(context, i).ToLocalChecked(); - if (target_item->IsString()) { - Utf8Value target_utf8(isolate, target_item.As<v8::String>()); - std::string target(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target, "", - pkg_subpath, pjson_url, base, false); - if (resolved.IsNothing()) continue; - return FinalizeResolution(env, resolved.FromJust(), base); - } - } - auto invalid = target_arr->Get(context, length - 1).ToLocalChecked(); - if (!invalid->IsString()) { - ThrowExportsInvalid(env, pkg_subpath, invalid, pjson_url, base); - return Nothing<URL>(); - } - Utf8Value invalid_utf8(isolate, invalid.As<v8::String>()); - std::string invalid_str(*invalid_utf8, invalid_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, invalid_str, "", - pkg_subpath, pjson_url, base); - CHECK(resolved.IsNothing()); - return Nothing<URL>(); - } else { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, target, "", + pkg_subpath, base); + if (resolved.IsNothing()) { return Nothing<URL>(); } + return FinalizeResolution(env, resolved.FromJust(), base); } Local<String> best_match; @@ -1076,49 +1123,13 @@ Maybe<URL> PackageExportsResolve(Environment* env, if (best_match_str.length() > 0) { auto target = exports_obj->Get(context, best_match).ToLocalChecked(); std::string subpath = pkg_subpath.substr(best_match_str.length()); - if (target->IsString()) { - Utf8Value target_utf8(isolate, target.As<v8::String>()); - std::string target(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target, subpath, - pkg_subpath, pjson_url, base); - if (resolved.IsNothing()) { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); - return Nothing<URL>(); - } - return FinalizeResolution(env, URL(subpath, resolved.FromJust()), base); - } else if (target->IsArray()) { - Local<Array> target_arr = target.As<Array>(); - const uint32_t length = target_arr->Length(); - if (length == 0) { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); - return Nothing<URL>(); - } - for (uint32_t i = 0; i < length; i++) { - auto target_item = target_arr->Get(context, i).ToLocalChecked(); - if (target_item->IsString()) { - Utf8Value target_utf8(isolate, target_item.As<v8::String>()); - std::string target_str(*target_utf8, target_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, target_str, subpath, - pkg_subpath, pjson_url, base, false); - if (resolved.IsNothing()) continue; - return FinalizeResolution(env, resolved.FromJust(), base); - } - } - auto invalid = target_arr->Get(context, length - 1).ToLocalChecked(); - if (!invalid->IsString()) { - ThrowExportsInvalid(env, pkg_subpath, invalid, pjson_url, base); - return Nothing<URL>(); - } - Utf8Value invalid_utf8(isolate, invalid.As<v8::String>()); - std::string invalid_str(*invalid_utf8, invalid_utf8.length()); - Maybe<URL> resolved = ResolveExportsTarget(env, invalid_str, subpath, - pkg_subpath, pjson_url, base); - CHECK(resolved.IsNothing()); - return Nothing<URL>(); - } else { - ThrowExportsInvalid(env, pkg_subpath, target, pjson_url, base); + + Maybe<URL> resolved = ResolveExportsTarget(env, pjson_url, target, subpath, + pkg_subpath, base); + if (resolved.IsNothing()) { return Nothing<URL>(); } + return FinalizeResolution(env, resolved.FromJust(), base); } ThrowExportsNotFound(env, pkg_subpath, pjson_url, base); diff --git a/src/node.cc b/src/node.cc index f437ea4be96450..91f07e447f0a6f 100644 --- a/src/node.cc +++ b/src/node.cc @@ -123,8 +123,6 @@ namespace node { using native_module::NativeModuleEnv; -using options_parser::kAllowedInEnvironment; -using options_parser::kDisallowedInEnvironment; using v8::Boolean; using v8::EscapableHandleScope; @@ -162,32 +160,6 @@ bool v8_is_profiling = false; struct V8Platform v8_platform; } // namespace per_process -#ifdef __POSIX__ -static const unsigned kMaxSignal = 32; -#endif - -void WaitForInspectorDisconnect(Environment* env) { -#if HAVE_INSPECTOR - profiler::EndStartedProfilers(env); - - if (env->inspector_agent()->IsActive()) { - // Restore signal dispositions, the app is done and is no longer - // capable of handling signals. -#if defined(__POSIX__) && !defined(NODE_SHARED_MODE) - struct sigaction act; - memset(&act, 0, sizeof(act)); - for (unsigned nr = 1; nr < kMaxSignal; nr += 1) { - if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF) - continue; - act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL; - CHECK_EQ(0, sigaction(nr, &act, nullptr)); - } -#endif - env->inspector_agent()->WaitForDisconnect(); - } -#endif -} - #ifdef __POSIX__ void SignalExit(int signo, siginfo_t* info, void* ucontext) { ResetStdio(); @@ -228,13 +200,12 @@ MaybeLocal<Value> ExecuteBootstrapper(Environment* env, #if HAVE_INSPECTOR int Environment::InitializeInspector( - inspector::ParentInspectorHandle* parent_handle) { + std::unique_ptr<inspector::ParentInspectorHandle> parent_handle) { std::string inspector_path; - if (parent_handle != nullptr) { + if (parent_handle) { DCHECK(!is_main_thread()); inspector_path = parent_handle->url(); - inspector_agent_->SetParentHandle( - std::unique_ptr<inspector::ParentInspectorHandle>(parent_handle)); + inspector_agent_->SetParentHandle(std::move(parent_handle)); } else { inspector_path = argv_.size() > 1 ? argv_[1].c_str() : ""; } @@ -371,7 +342,8 @@ MaybeLocal<Value> Environment::RunBootstrapping() { // Make sure that no request or handle is created during bootstrap - // if necessary those should be done in pre-execution. - // TODO(joyeecheung): print handles/requests before aborting + // Usually, doing so would trigger the checks present in the ReqWrap and + // HandleWrap classes, so this is only a consistency check. CHECK(req_wrap_queue()->IsEmpty()); CHECK(handle_wrap_queue()->IsEmpty()); @@ -406,13 +378,8 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) { ->GetFunction(env->context()) .ToLocalChecked()}; - Local<Value> result; - if (!ExecuteBootstrapper(env, main_script_id, ¶meters, &arguments) - .ToLocal(&result) || - !task_queue::RunNextTicksNative(env)) { - return MaybeLocal<Value>(); - } - return scope.Escape(result); + return scope.EscapeMaybe( + ExecuteBootstrapper(env, main_script_id, ¶meters, &arguments)); } MaybeLocal<Value> StartMainThreadExecution(Environment* env) { @@ -559,6 +526,7 @@ inline void PlatformInit() { CHECK_EQ(err, 0); #endif // HAVE_INSPECTOR + // TODO(addaleax): NODE_SHARED_MODE does not really make sense here. #ifndef NODE_SHARED_MODE // Restore signal dispositions, the parent process may have changed them. struct sigaction act; @@ -709,7 +677,7 @@ void ResetStdio() { int ProcessGlobalArgs(std::vector<std::string>* args, std::vector<std::string>* exec_args, std::vector<std::string>* errors, - bool is_env) { + OptionEnvvarSettings settings) { // Parse a few arguments which are specific to Node. std::vector<std::string> v8_args; @@ -719,7 +687,7 @@ int ProcessGlobalArgs(std::vector<std::string>* args, exec_args, &v8_args, per_process::cli_options.get(), - is_env ? kAllowedInEnvironment : kDisallowedInEnvironment, + settings, errors); if (!errors->empty()) return 9; @@ -881,12 +849,18 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv, return 9; } - const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true); + const int exit_code = ProcessGlobalArgs(&env_argv, + nullptr, + errors, + kAllowedInEnvironment); if (exit_code != 0) return exit_code; } #endif - const int exit_code = ProcessGlobalArgs(argv, exec_argv, errors, false); + const int exit_code = ProcessGlobalArgs(argv, + exec_argv, + errors, + kDisallowedInEnvironment); if (exit_code != 0) return exit_code; // Set the process.title immediately after processing argv if --title is set. diff --git a/src/node.h b/src/node.h index 872e0a811a608b..c80e6266857921 100644 --- a/src/node.h +++ b/src/node.h @@ -225,6 +225,16 @@ NODE_EXTERN void Init(int* argc, int* exec_argc, const char*** exec_argv); +enum OptionEnvvarSettings { + kAllowedInEnvironment, + kDisallowedInEnvironment +}; + +NODE_EXTERN int ProcessGlobalArgs(std::vector<std::string>* args, + std::vector<std::string>* exec_args, + std::vector<std::string>* errors, + OptionEnvvarSettings settings); + class NodeArrayBufferAllocator; // An ArrayBuffer::Allocator class with some Node.js-specific tweaks. If you do @@ -286,13 +296,6 @@ class NODE_EXTERN MultiIsolatePlatform : public v8::Platform { void* data) = 0; }; -// Set up some Node.js-specific defaults for `params`, in particular -// the ArrayBuffer::Allocator if it is provided, memory limits, and -// possibly a code event handler. -NODE_EXTERN void SetIsolateCreateParams(v8::Isolate::CreateParams* params, - ArrayBufferAllocator* allocator - = nullptr); - enum IsolateSettingsFlags { MESSAGE_LISTENER_WITH_ERROR_LEVEL = 1 << 0, DETAILED_SOURCE_POSITIONS_FOR_PROFILING = 1 << 1 @@ -335,6 +338,10 @@ NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator, NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator, struct uv_loop_s* event_loop, MultiIsolatePlatform* platform); +NODE_EXTERN v8::Isolate* NewIsolate( + std::shared_ptr<ArrayBufferAllocator> allocator, + struct uv_loop_s* event_loop, + MultiIsolatePlatform* platform); // Creates a new context with Node.js-specific tweaks. NODE_EXTERN v8::Local<v8::Context> NewContext( @@ -675,10 +682,26 @@ extern "C" NODE_EXTERN void node_module_register(void* mod); v8::Local<v8::Value> module, \ v8::Local<v8::Context> context) +// Allows embedders to add a binding to the current Environment* that can be +// accessed through process._linkedBinding() in the target Environment and all +// Worker threads that it creates. +// In each variant, the registration function needs to be usable at least for +// the time during which the Environment exists. +NODE_EXTERN void AddLinkedBinding(Environment* env, const node_module& mod); +NODE_EXTERN void AddLinkedBinding(Environment* env, + const char* name, + addon_context_register_func fn, + void* priv); + /* Called after the event loop exits but before the VM is disposed. * Callbacks are run in reverse order of registration, i.e. newest first. + * + * You should always use the three-argument variant (or, for addons, + * AddEnvironmentCleanupHook) in order to avoid relying on global state. */ -NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = nullptr); +NODE_DEPRECATED( + "Use the three-argument variant of AtExit() or AddEnvironmentCleanupHook()", + NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = nullptr)); /* Registers a callback with the passed-in Environment instance. The callback * is called after the event loop exits, but before the VM is disposed. @@ -686,7 +709,13 @@ NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = nullptr); */ NODE_EXTERN void AtExit(Environment* env, void (*cb)(void* arg), - void* arg = nullptr); + void* arg); +NODE_DEPRECATED( + "Use the three-argument variant of AtExit() or AddEnvironmentCleanupHook()", + inline void AtExit(Environment* env, + void (*cb)(void* arg)) { + AtExit(env, cb, nullptr); + }) typedef double async_id; struct async_context { diff --git a/src/node_api.cc b/src/node_api.cc index 95664e9c7ace27..8df4559c6cddc6 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -24,6 +24,14 @@ struct node_napi_env__ : public napi_env__ { bool can_call_into_js() const override { return node_env()->can_call_into_js(); } + + v8::Maybe<bool> mark_arraybuffer_as_untransferable( + v8::Local<v8::ArrayBuffer> ab) const override { + return ab->SetPrivate( + context(), + node_env()->arraybuffer_untransferable_private_symbol(), + v8::True(isolate)); + } }; typedef node_napi_env__* node_napi_env; diff --git a/src/node_binding.cc b/src/node_binding.cc index f0a148a495605c..f57ddb54b629ca 100644 --- a/src/node_binding.cc +++ b/src/node_binding.cc @@ -152,7 +152,7 @@ void* wrapped_dlopen(const char* filename, int flags) { Mutex::ScopedLock lock(dlhandles_mutex); uv_fs_t req; - OnScopeLeave cleanup([&]() { uv_fs_req_cleanup(&req); }); + auto cleanup = OnScopeLeave([&]() { uv_fs_req_cleanup(&req); }); int rc = uv_fs_stat(nullptr, &req, filename, nullptr); if (rc != 0) { @@ -484,7 +484,12 @@ void DLOpen(const FunctionCallbackInfo<Value>& args) { mp = dlib->GetSavedModuleFromGlobalHandleMap(); if (mp == nullptr || mp->nm_context_register_func == nullptr) { dlib->Close(); - env->ThrowError("Module did not self-register."); + char errmsg[1024]; + snprintf(errmsg, + sizeof(errmsg), + "Module did not self-register: '%s'.", + *filename); + env->ThrowError(errmsg); return false; } } @@ -552,13 +557,6 @@ inline struct node_module* FindModule(struct node_module* list, return mp; } -node_module* get_internal_module(const char* name) { - return FindModule(modlist_internal, name, NM_F_INTERNAL); -} -node_module* get_linked_module(const char* name) { - return FindModule(modlist_linked, name, NM_F_LINKED); -} - static Local<Object> InitModule(Environment* env, node_module* mod, Local<String> module) { @@ -586,7 +584,7 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) { node::Utf8Value module_v(env->isolate(), module); Local<Object> exports; - node_module* mod = get_internal_module(*module_v); + node_module* mod = FindModule(modlist_internal, *module_v, NM_F_INTERNAL); if (mod != nullptr) { exports = InitModule(env, mod, module); } else if (!strcmp(*module_v, "constants")) { @@ -619,7 +617,20 @@ void GetLinkedBinding(const FunctionCallbackInfo<Value>& args) { Local<String> module_name = args[0].As<String>(); node::Utf8Value module_name_v(env->isolate(), module_name); - node_module* mod = get_linked_module(*module_name_v); + const char* name = *module_name_v; + node_module* mod = nullptr; + + // Iterate from here to the nearest non-Worker Environment to see if there's + // a linked binding defined locally rather than through the global list. + Environment* cur_env = env; + while (mod == nullptr && cur_env != nullptr) { + Mutex::ScopedLock lock(cur_env->extra_linked_bindings_mutex()); + mod = FindModule(cur_env->extra_linked_bindings_head(), name, NM_F_LINKED); + cur_env = cur_env->worker_parent_env(); + } + + if (mod == nullptr) + mod = FindModule(modlist_linked, name, NM_F_LINKED); if (mod == nullptr) { char errmsg[1024]; diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 74684110a965dd..d87d38334add84 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -192,16 +192,13 @@ bool HasInstance(Local<Object> obj) { char* Data(Local<Value> val) { CHECK(val->IsArrayBufferView()); Local<ArrayBufferView> ui = val.As<ArrayBufferView>(); - ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents(); - return static_cast<char*>(ab_c.Data()) + ui->ByteOffset(); + return static_cast<char*>(ui->Buffer()->GetBackingStore()->Data()) + + ui->ByteOffset(); } char* Data(Local<Object> obj) { - CHECK(obj->IsArrayBufferView()); - Local<ArrayBufferView> ui = obj.As<ArrayBufferView>(); - ArrayBuffer::Contents ab_c = ui->Buffer()->GetContents(); - return static_cast<char*>(ab_c.Data()) + ui->ByteOffset(); + return Data(obj.As<Value>()); } @@ -219,10 +216,10 @@ size_t Length(Local<Object> obj) { } -inline MaybeLocal<Uint8Array> New(Environment* env, - Local<ArrayBuffer> ab, - size_t byte_offset, - size_t length) { +MaybeLocal<Uint8Array> New(Environment* env, + Local<ArrayBuffer> ab, + size_t byte_offset, + size_t length) { CHECK(!env->buffer_prototype_object().IsEmpty()); Local<Uint8Array> ui = Uint8Array::New(ab, byte_offset, length); Maybe<bool> mb = @@ -232,6 +229,18 @@ inline MaybeLocal<Uint8Array> New(Environment* env, return ui; } +MaybeLocal<Uint8Array> New(Isolate* isolate, + Local<ArrayBuffer> ab, + size_t byte_offset, + size_t length) { + Environment* env = Environment::GetCurrent(isolate); + if (env == nullptr) { + THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); + return MaybeLocal<Uint8Array>(); + } + return New(env, ab, byte_offset, length); +} + MaybeLocal<Object> New(Isolate* isolate, Local<String> string, @@ -353,10 +362,8 @@ MaybeLocal<Object> New(Isolate* isolate, THROW_ERR_BUFFER_CONTEXT_NOT_AVAILABLE(isolate); return MaybeLocal<Object>(); } - Local<Object> obj; - if (Buffer::New(env, data, length, callback, hint).ToLocal(&obj)) - return handle_scope.Escape(obj); - return Local<Object>(); + return handle_scope.EscapeMaybe( + Buffer::New(env, data, length, callback, hint)); } @@ -374,6 +381,12 @@ MaybeLocal<Object> New(Environment* env, } Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(), data, length); + if (ab->SetPrivate(env->context(), + env->arraybuffer_untransferable_private_symbol(), + True(env->isolate())).IsNothing()) { + callback(data, hint); + return Local<Object>(); + } MaybeLocal<Uint8Array> ui = Buffer::New(env, ab, 0, length); CallbackInfo::New(env->isolate(), ab, callback, data, hint); @@ -1060,13 +1073,13 @@ static void EncodeInto(const FunctionCallbackInfo<Value>& args) { Local<Uint8Array> dest = args[1].As<Uint8Array>(); Local<ArrayBuffer> buf = dest->Buffer(); char* write_result = - static_cast<char*>(buf->GetContents().Data()) + dest->ByteOffset(); + static_cast<char*>(buf->GetBackingStore()->Data()) + dest->ByteOffset(); size_t dest_length = dest->ByteLength(); // results = [ read, written ] Local<Uint32Array> result_arr = args[2].As<Uint32Array>(); uint32_t* results = reinterpret_cast<uint32_t*>( - static_cast<char*>(result_arr->Buffer()->GetContents().Data()) + + static_cast<char*>(result_arr->Buffer()->GetBackingStore()->Data()) + result_arr->ByteOffset()); int nchars; diff --git a/src/node_buffer.h b/src/node_buffer.h index 122afc37709f73..11010017ce0df8 100644 --- a/src/node_buffer.h +++ b/src/node_buffer.h @@ -65,6 +65,12 @@ NODE_EXTERN v8::MaybeLocal<v8::Object> New(v8::Isolate* isolate, char* data, size_t len); +// Creates a Buffer instance over an existing ArrayBuffer. +NODE_EXTERN v8::MaybeLocal<v8::Uint8Array> New(v8::Isolate* isolate, + v8::Local<v8::ArrayBuffer> ab, + size_t byte_offset, + size_t length); + // This is verbose to be explicit with inline commenting static inline bool IsWithinBounds(size_t off, size_t len, size_t max) { // Asking to seek too far into the buffer diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 2d30e0b8038ce4..46a1d7c8ef0691 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -697,8 +697,8 @@ void ContextifyScript::New(const FunctionCallbackInfo<Value>& args) { ScriptCompiler::CachedData* cached_data = nullptr; if (!cached_data_buf.IsEmpty()) { - ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); - uint8_t* data = static_cast<uint8_t*>(contents.Data()); + uint8_t* data = static_cast<uint8_t*>( + cached_data_buf->Buffer()->GetBackingStore()->Data()); cached_data = new ScriptCompiler::CachedData( data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); } @@ -1044,8 +1044,8 @@ void ContextifyContext::CompileFunction( // Read cache from cached data buffer ScriptCompiler::CachedData* cached_data = nullptr; if (!cached_data_buf.IsEmpty()) { - ArrayBuffer::Contents contents = cached_data_buf->Buffer()->GetContents(); - uint8_t* data = static_cast<uint8_t*>(contents.Data()); + uint8_t* data = static_cast<uint8_t*>( + cached_data_buf->Buffer()->GetBackingStore()->Data()); cached_data = new ScriptCompiler::CachedData( data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 20cc52fbff7910..fa85f7855371b5 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4910,6 +4910,9 @@ void CheckThrow(Environment* env, SignBase::Error error) { case SignBase::Error::kSignNotInitialised: return env->ThrowError("Not initialised"); + case SignBase::Error::kSignMalformedSignature: + return env->ThrowError("Malformed signature"); + case SignBase::Error::kSignInit: case SignBase::Error::kSignUpdate: case SignBase::Error::kSignPrivateKey: @@ -5007,6 +5010,89 @@ static int GetDefaultSignPadding(const ManagedEVPPKey& key) { RSA_PKCS1_PADDING; } +static const unsigned int kNoDsaSignature = static_cast<unsigned int>(-1); + +// Returns the maximum size of each of the integers (r, s) of the DSA signature. +static unsigned int GetBytesOfRS(const ManagedEVPPKey& pkey) { + int bits, base_id = EVP_PKEY_base_id(pkey.get()); + + if (base_id == EVP_PKEY_DSA) { + DSA* dsa_key = EVP_PKEY_get0_DSA(pkey.get()); + // Both r and s are computed mod q, so their width is limited by that of q. + bits = BN_num_bits(DSA_get0_q(dsa_key)); + } else if (base_id == EVP_PKEY_EC) { + EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); + const EC_GROUP* ec_group = EC_KEY_get0_group(ec_key); + bits = EC_GROUP_order_bits(ec_group); + } else { + return kNoDsaSignature; + } + + return (bits + 7) / 8; +} + +static AllocatedBuffer ConvertSignatureToP1363(Environment* env, + const ManagedEVPPKey& pkey, + AllocatedBuffer&& signature) { + unsigned int n = GetBytesOfRS(pkey); + if (n == kNoDsaSignature) + return std::move(signature); + + const unsigned char* sig_data = + reinterpret_cast<unsigned char*>(signature.data()); + + ECDSA_SIG* asn1_sig = d2i_ECDSA_SIG(nullptr, &sig_data, signature.size()); + if (asn1_sig == nullptr) + return AllocatedBuffer(); + + AllocatedBuffer buf = env->AllocateManaged(2 * n); + unsigned char* data = reinterpret_cast<unsigned char*>(buf.data()); + + const BIGNUM* r = ECDSA_SIG_get0_r(asn1_sig); + const BIGNUM* s = ECDSA_SIG_get0_s(asn1_sig); + CHECK_EQ(n, BN_bn2binpad(r, data, n)); + CHECK_EQ(n, BN_bn2binpad(s, data + n, n)); + + ECDSA_SIG_free(asn1_sig); + + return buf; +} + +static ByteSource ConvertSignatureToDER( + const ManagedEVPPKey& pkey, + const ArrayBufferViewContents<char>& signature) { + unsigned int n = GetBytesOfRS(pkey); + if (n == kNoDsaSignature) + return ByteSource::Foreign(signature.data(), signature.length()); + + const unsigned char* sig_data = + reinterpret_cast<const unsigned char*>(signature.data()); + + if (signature.length() != 2 * n) + return ByteSource(); + + ECDSA_SIG* asn1_sig = ECDSA_SIG_new(); + CHECK_NOT_NULL(asn1_sig); + BIGNUM* r = BN_new(); + CHECK_NOT_NULL(r); + BIGNUM* s = BN_new(); + CHECK_NOT_NULL(s); + CHECK_EQ(r, BN_bin2bn(sig_data, n, r)); + CHECK_EQ(s, BN_bin2bn(sig_data + n, n, s)); + CHECK_EQ(1, ECDSA_SIG_set0(asn1_sig, r, s)); + + unsigned char* data = nullptr; + int len = i2d_ECDSA_SIG(asn1_sig, &data); + ECDSA_SIG_free(asn1_sig); + + if (len <= 0) + return ByteSource(); + + CHECK_NOT_NULL(data); + + return ByteSource::Allocated(reinterpret_cast<char*>(data), len); +} + static AllocatedBuffer Node_SignFinal(Environment* env, EVPMDPointer&& mdctx, const ManagedEVPPKey& pkey, @@ -5066,7 +5152,8 @@ static inline bool ValidateDSAParameters(EVP_PKEY* key) { Sign::SignResult Sign::SignFinal( const ManagedEVPPKey& pkey, int padding, - const Maybe<int>& salt_len) { + const Maybe<int>& salt_len, + DSASigEnc dsa_sig_enc) { if (!mdctx_) return SignResult(kSignNotInitialised); @@ -5078,6 +5165,10 @@ Sign::SignResult Sign::SignFinal( AllocatedBuffer buffer = Node_SignFinal(env(), std::move(mdctx), pkey, padding, salt_len); Error error = buffer.data() == nullptr ? kSignPrivateKey : kSignOk; + if (error == kSignOk && dsa_sig_enc == kSigEncP1363) { + buffer = ConvertSignatureToP1363(env(), pkey, std::move(buffer)); + CHECK_NOT_NULL(buffer.data()); + } return SignResult(error, std::move(buffer)); } @@ -5105,10 +5196,15 @@ void Sign::SignFinal(const FunctionCallbackInfo<Value>& args) { salt_len = Just<int>(args[offset + 1].As<Int32>()->Value()); } + CHECK(args[offset + 2]->IsInt32()); + DSASigEnc dsa_sig_enc = + static_cast<DSASigEnc>(args[offset + 2].As<Int32>()->Value()); + SignResult ret = sign->SignFinal( key, padding, - salt_len); + salt_len, + dsa_sig_enc); if (ret.error != kSignOk) return sign->CheckThrow(ret.error); @@ -5152,6 +5248,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) { rsa_salt_len = Just<int>(args[offset + 3].As<Int32>()->Value()); } + CHECK(args[offset + 4]->IsInt32()); + DSASigEnc dsa_sig_enc = + static_cast<DSASigEnc>(args[offset + 4].As<Int32>()->Value()); + EVP_PKEY_CTX* pkctx = nullptr; EVPMDPointer mdctx(EVP_MD_CTX_new()); if (!mdctx || @@ -5179,6 +5279,10 @@ void SignOneShot(const FunctionCallbackInfo<Value>& args) { signature.Resize(sig_len); + if (dsa_sig_enc == kSigEncP1363) { + signature = ConvertSignatureToP1363(env, key, std::move(signature)); + } + args.GetReturnValue().Set(signature.ToBuffer().ToLocalChecked()); } @@ -5284,6 +5388,17 @@ void Verify::VerifyFinal(const FunctionCallbackInfo<Value>& args) { salt_len = Just<int>(args[offset + 2].As<Int32>()->Value()); } + CHECK(args[offset + 3]->IsInt32()); + DSASigEnc dsa_sig_enc = + static_cast<DSASigEnc>(args[offset + 3].As<Int32>()->Value()); + + ByteSource signature = ByteSource::Foreign(hbuf.data(), hbuf.length()); + if (dsa_sig_enc == kSigEncP1363) { + signature = ConvertSignatureToDER(pkey, hbuf); + if (signature.get() == nullptr) + return verify->CheckThrow(Error::kSignMalformedSignature); + } + bool verify_result; Error err = verify->VerifyFinal(pkey, hbuf.data(), hbuf.length(), padding, salt_len, &verify_result); @@ -5327,6 +5442,10 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) { rsa_salt_len = Just<int>(args[offset + 4].As<Int32>()->Value()); } + CHECK(args[offset + 5]->IsInt32()); + DSASigEnc dsa_sig_enc = + static_cast<DSASigEnc>(args[offset + 5].As<Int32>()->Value()); + EVP_PKEY_CTX* pkctx = nullptr; EVPMDPointer mdctx(EVP_MD_CTX_new()); if (!mdctx || @@ -5337,11 +5456,18 @@ void VerifyOneShot(const FunctionCallbackInfo<Value>& args) { if (!ApplyRSAOptions(key, pkctx, rsa_padding, rsa_salt_len)) return CheckThrow(env, SignBase::Error::kSignPublicKey); + ByteSource sig_bytes = ByteSource::Foreign(sig.data(), sig.length()); + if (dsa_sig_enc == kSigEncP1363) { + sig_bytes = ConvertSignatureToDER(key, sig); + if (!sig_bytes) + return CheckThrow(env, SignBase::Error::kSignMalformedSignature); + } + bool verify_result; const int r = EVP_DigestVerify( mdctx.get(), - reinterpret_cast<const unsigned char*>(sig.data()), - sig.length(), + reinterpret_cast<const unsigned char*>(sig_bytes.get()), + sig_bytes.size(), reinterpret_cast<const unsigned char*>(data.data()), data.length()); switch (r) { @@ -7129,6 +7255,8 @@ void Initialize(Local<Object> target, NODE_DEFINE_CONSTANT(target, kKeyTypeSecret); NODE_DEFINE_CONSTANT(target, kKeyTypePublic); NODE_DEFINE_CONSTANT(target, kKeyTypePrivate); + NODE_DEFINE_CONSTANT(target, kSigEncDER); + NODE_DEFINE_CONSTANT(target, kSigEncP1363); env->SetMethod(target, "randomBytes", RandomBytes); env->SetMethod(target, "signOneShot", SignOneShot); env->SetMethod(target, "verifyOneShot", VerifyOneShot); diff --git a/src/node_crypto.h b/src/node_crypto.h index 777ba5d302a536..56a9ad3104dbeb 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -326,6 +326,13 @@ class ByteSource { const char* get() const; size_t size() const; + inline operator bool() const { + return data_ != nullptr; + } + + static ByteSource Allocated(char* data, size_t size); + static ByteSource Foreign(const char* data, size_t size); + static ByteSource FromStringOrBuffer(Environment* env, v8::Local<v8::Value> value); @@ -350,9 +357,6 @@ class ByteSource { size_t size_ = 0; ByteSource(const char* data, char* allocated_data, size_t size); - - static ByteSource Allocated(char* data, size_t size); - static ByteSource Foreign(const char* data, size_t size); }; enum PKEncodingType { @@ -628,7 +632,8 @@ class SignBase : public BaseObject { kSignNotInitialised, kSignUpdate, kSignPrivateKey, - kSignPublicKey + kSignPublicKey, + kSignMalformedSignature } Error; SignBase(Environment* env, v8::Local<v8::Object> wrap) @@ -649,6 +654,10 @@ class SignBase : public BaseObject { EVPMDPointer mdctx_; }; +enum DSASigEnc { + kSigEncDER, kSigEncP1363 +}; + class Sign : public SignBase { public: static void Initialize(Environment* env, v8::Local<v8::Object> target); @@ -666,7 +675,8 @@ class Sign : public SignBase { SignResult SignFinal( const ManagedEVPPKey& pkey, int padding, - const v8::Maybe<int>& saltlen); + const v8::Maybe<int>& saltlen, + DSASigEnc dsa_sig_enc); protected: static void New(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/src/node_env_var.cc b/src/node_env_var.cc index c63cb2c37fb3e0..40c0515a3dc2e2 100644 --- a/src/node_env_var.cc +++ b/src/node_env_var.cc @@ -149,7 +149,7 @@ Local<Array> RealEnvStore::Enumerate(Isolate* isolate) const { uv_env_item_t* items; int count; - OnScopeLeave cleanup([&]() { uv_os_free_environ(items, count); }); + auto cleanup = OnScopeLeave([&]() { uv_os_free_environ(items, count); }); CHECK_EQ(uv_os_environ(&items, &count), 0); MaybeStackBuffer<Local<Value>, 256> env_v(count); @@ -272,6 +272,7 @@ Maybe<bool> KVStore::AssignFromObject(Local<Context> context, static void EnvGetter(Local<Name> property, const PropertyCallbackInfo<Value>& info) { Environment* env = Environment::GetCurrent(info); + CHECK(env->has_run_bootstrapping_code()); if (property->IsSymbol()) { return info.GetReturnValue().SetUndefined(); } @@ -287,6 +288,7 @@ static void EnvSetter(Local<Name> property, Local<Value> value, const PropertyCallbackInfo<Value>& info) { Environment* env = Environment::GetCurrent(info); + CHECK(env->has_run_bootstrapping_code()); // calling env->EmitProcessEnvWarning() sets a variable indicating that // warnings have been emitted. It should be called last after other // conditions leading to a warning have been met. @@ -320,6 +322,7 @@ static void EnvSetter(Local<Name> property, static void EnvQuery(Local<Name> property, const PropertyCallbackInfo<Integer>& info) { Environment* env = Environment::GetCurrent(info); + CHECK(env->has_run_bootstrapping_code()); if (property->IsString()) { int32_t rc = env->env_vars()->Query(env->isolate(), property.As<String>()); if (rc != -1) info.GetReturnValue().Set(rc); @@ -329,6 +332,7 @@ static void EnvQuery(Local<Name> property, static void EnvDeleter(Local<Name> property, const PropertyCallbackInfo<Boolean>& info) { Environment* env = Environment::GetCurrent(info); + CHECK(env->has_run_bootstrapping_code()); if (property->IsString()) { env->env_vars()->Delete(env->isolate(), property.As<String>()); } @@ -340,6 +344,7 @@ static void EnvDeleter(Local<Name> property, static void EnvEnumerator(const PropertyCallbackInfo<Array>& info) { Environment* env = Environment::GetCurrent(info); + CHECK(env->has_run_bootstrapping_code()); info.GetReturnValue().Set( env->env_vars()->Enumerate(env->isolate())); diff --git a/src/node_errors.cc b/src/node_errors.cc index ec14746514e420..e094fe4681fc56 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -993,9 +993,7 @@ void TriggerUncaughtException(Isolate* isolate, // Now we are certain that the exception is fatal. ReportFatalException(env, error, message, EnhanceFatalException::kEnhance); -#if HAVE_INSPECTOR - profiler::EndStartedProfilers(env); -#endif + RunAtExit(env); // If the global uncaught exception handler sets process.exitCode, // exit with that code. Otherwise, exit with 1. diff --git a/src/node_file.cc b/src/node_file.cc index 8b6a90989f8d29..48b382986c0bb5 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -18,7 +18,6 @@ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. - #include "node_file.h" #include "aliased_buffer.h" #include "memory_tracker-inl.h" @@ -787,7 +786,7 @@ static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) { size == SearchString(&chars[start], size, "\"main\"") && size == SearchString(&chars[start], size, "\"exports\"") && size == SearchString(&chars[start], size, "\"type\""))) { - return; + args.GetReturnValue().Set(env->empty_object_string()); } else { Local<String> chars_string = String::NewFromUtf8(isolate, diff --git a/src/node_http2.cc b/src/node_http2.cc index f3ef8363e4ebcf..7170907ced1b3e 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -239,7 +239,6 @@ Http2Session::Http2Settings::Http2Settings(Environment* env, : AsyncWrap(env, obj, PROVIDER_HTTP2SETTINGS), session_(session), startTime_(start_time) { - RemoveCleanupHook(); // This object is owned by the Http2Session. Init(); } @@ -658,8 +657,6 @@ Http2Session::Http2Session(Environment* env, Http2Session::~Http2Session() { CHECK_EQ(flags_ & SESSION_STATE_HAS_SCOPE, 0); Debug(this, "freeing nghttp2 session"); - for (const auto& iter : streams_) - iter.second->session_ = nullptr; nghttp2_session_del(session_); CHECK_EQ(current_nghttp2_memory_, 0); } @@ -767,7 +764,7 @@ void Http2Session::Close(uint32_t code, bool socket_closed) { // If there are outstanding pings, those will need to be canceled, do // so on the next iteration of the event loop to avoid calling out into // javascript since this may be called during garbage collection. - while (std::unique_ptr<Http2Ping> ping = PopPing()) { + while (BaseObjectPtr<Http2Ping> ping = PopPing()) { ping->DetachFromSession(); env()->SetImmediate( [ping = std::move(ping)](Environment* env) { @@ -1483,7 +1480,7 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { Local<Value> arg; bool ack = frame->hd.flags & NGHTTP2_FLAG_ACK; if (ack) { - std::unique_ptr<Http2Ping> ping = PopPing(); + BaseObjectPtr<Http2Ping> ping = PopPing(); if (!ping) { // PING Ack is unsolicited. Treat as a connection error. The HTTP/2 @@ -1522,7 +1519,7 @@ void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) { // If this is an acknowledgement, we should have an Http2Settings // object for it. - std::unique_ptr<Http2Settings> settings = PopSettings(); + BaseObjectPtr<Http2Settings> settings = PopSettings(); if (settings) { settings->Done(true); return; @@ -1585,7 +1582,8 @@ void Http2Session::MaybeScheduleWrite() { HandleScope handle_scope(env()->isolate()); Debug(this, "scheduling write"); flags_ |= SESSION_STATE_WRITE_SCHEDULED; - env()->SetImmediate([this](Environment* env) { + BaseObjectPtr<Http2Session> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment* env) { if (session_ == nullptr || !(flags_ & SESSION_STATE_WRITE_SCHEDULED)) { // This can happen e.g. when a stream was reset before this turn // of the event loop, in which case SendPendingData() is called early, @@ -1598,7 +1596,7 @@ void Http2Session::MaybeScheduleWrite() { HandleScope handle_scope(env->isolate()); InternalCallbackScope callback_scope(this); SendPendingData(); - }, object()); + }); } } @@ -1982,12 +1980,11 @@ Http2Stream::~Http2Stream() { nghttp2_rcbuf_decref(header.value); } - if (session_ == nullptr) + if (!session_) return; Debug(this, "tearing down stream"); session_->DecrementCurrentSessionMemory(current_headers_length_); session_->RemoveStream(this); - session_ = nullptr; } std::string Http2Stream::diagnostic_name() const { @@ -2047,7 +2044,8 @@ void Http2Stream::Destroy() { // Wait until the start of the next loop to delete because there // may still be some pending operations queued for this stream. - env()->SetImmediate([this](Environment* env) { + BaseObjectPtr<Http2Stream> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment* env) { // Free any remaining outgoing data chunks here. This should be done // here because it's possible for destroy to have been called while // we still have queued outbound writes. @@ -2061,9 +2059,11 @@ void Http2Stream::Destroy() { // We can destroy the stream now if there are no writes for it // already on the socket. Otherwise, we'll wait for the garbage collector // to take care of cleaning up. - if (session() == nullptr || !session()->HasWritesOnSocketForStream(this)) - delete this; - }, object()); + if (session() == nullptr || !session()->HasWritesOnSocketForStream(this)) { + // Delete once strong_ref goes out of scope. + Detach(); + } + }); statistics_.end_time = uv_hrtime(); session_->statistics_.stream_average_duration = @@ -2189,8 +2189,10 @@ Http2Stream* Http2Stream::SubmitPushPromise(nghttp2_nv* nva, id_, nva, len, nullptr); CHECK_NE(*ret, NGHTTP2_ERR_NOMEM); Http2Stream* stream = nullptr; - if (*ret > 0) - stream = Http2Stream::New(session_, *ret, NGHTTP2_HCAT_HEADERS, options); + if (*ret > 0) { + stream = Http2Stream::New( + session_.get(), *ret, NGHTTP2_HCAT_HEADERS, options); + } return stream; } @@ -2855,7 +2857,8 @@ void Http2Session::Ping(const FunctionCallbackInfo<Value>& args) { if (obj->Set(env->context(), env->ondone_string(), args[1]).IsNothing()) return; - Http2Ping* ping = session->AddPing(std::make_unique<Http2Ping>(session, obj)); + Http2Ping* ping = session->AddPing( + MakeDetachedBaseObject<Http2Ping>(session, obj)); // To prevent abuse, we strictly limit the number of unacknowledged PING // frames that may be sent at any given time. This is configurable in the // Options when creating a Http2Session. @@ -2884,16 +2887,16 @@ void Http2Session::Settings(const FunctionCallbackInfo<Value>& args) { if (obj->Set(env->context(), env->ondone_string(), args[0]).IsNothing()) return; - Http2Session::Http2Settings* settings = session->AddSettings( - std::make_unique<Http2Settings>(session->env(), session, obj, 0)); + Http2Settings* settings = session->AddSettings( + MakeDetachedBaseObject<Http2Settings>(session->env(), session, obj, 0)); if (settings == nullptr) return args.GetReturnValue().Set(false); settings->Send(); args.GetReturnValue().Set(true); } -std::unique_ptr<Http2Session::Http2Ping> Http2Session::PopPing() { - std::unique_ptr<Http2Ping> ping; +BaseObjectPtr<Http2Session::Http2Ping> Http2Session::PopPing() { + BaseObjectPtr<Http2Ping> ping; if (!outstanding_pings_.empty()) { ping = std::move(outstanding_pings_.front()); outstanding_pings_.pop(); @@ -2903,7 +2906,7 @@ std::unique_ptr<Http2Session::Http2Ping> Http2Session::PopPing() { } Http2Session::Http2Ping* Http2Session::AddPing( - std::unique_ptr<Http2Session::Http2Ping> ping) { + BaseObjectPtr<Http2Session::Http2Ping> ping) { if (outstanding_pings_.size() == max_outstanding_pings_) { ping->Done(false); return nullptr; @@ -2914,8 +2917,8 @@ Http2Session::Http2Ping* Http2Session::AddPing( return ptr; } -std::unique_ptr<Http2Session::Http2Settings> Http2Session::PopSettings() { - std::unique_ptr<Http2Settings> settings; +BaseObjectPtr<Http2Session::Http2Settings> Http2Session::PopSettings() { + BaseObjectPtr<Http2Settings> settings; if (!outstanding_settings_.empty()) { settings = std::move(outstanding_settings_.front()); outstanding_settings_.pop(); @@ -2925,7 +2928,7 @@ std::unique_ptr<Http2Session::Http2Settings> Http2Session::PopSettings() { } Http2Session::Http2Settings* Http2Session::AddSettings( - std::unique_ptr<Http2Session::Http2Settings> settings) { + BaseObjectPtr<Http2Session::Http2Settings> settings) { if (outstanding_settings_.size() == max_outstanding_settings_) { settings->Done(false); return nullptr; @@ -2940,7 +2943,6 @@ Http2Session::Http2Ping::Http2Ping(Http2Session* session, Local<Object> obj) : AsyncWrap(session->env(), obj, AsyncWrap::PROVIDER_HTTP2PING), session_(session), startTime_(uv_hrtime()) { - RemoveCleanupHook(); // This object is owned by the Http2Session. } void Http2Session::Http2Ping::Send(const uint8_t* payload) { diff --git a/src/node_http2.h b/src/node_http2.h index 6aeb69fa848827..1444738470f9c7 100644 --- a/src/node_http2.h +++ b/src/node_http2.h @@ -456,8 +456,8 @@ class Http2Stream : public AsyncWrap, nghttp2_stream* operator*(); - Http2Session* session() { return session_; } - const Http2Session* session() const { return session_; } + Http2Session* session() { return session_.get(); } + const Http2Session* session() const { return session_.get(); } void EmitStatistics(); @@ -609,7 +609,7 @@ class Http2Stream : public AsyncWrap, nghttp2_headers_category category, int options); - Http2Session* session_ = nullptr; // The Parent HTTP/2 Session + BaseObjectWeakPtr<Http2Session> session_; // The Parent HTTP/2 Session int32_t id_ = 0; // The Stream Identifier int32_t code_ = NGHTTP2_NO_ERROR; // The RST_STREAM code (if any) int flags_ = NGHTTP2_STREAM_FLAG_NONE; // Internal state flags @@ -822,11 +822,11 @@ class Http2Session : public AsyncWrap, public StreamListener { return env()->event_loop(); } - std::unique_ptr<Http2Ping> PopPing(); - Http2Ping* AddPing(std::unique_ptr<Http2Ping> ping); + BaseObjectPtr<Http2Ping> PopPing(); + Http2Ping* AddPing(BaseObjectPtr<Http2Ping> ping); - std::unique_ptr<Http2Settings> PopSettings(); - Http2Settings* AddSettings(std::unique_ptr<Http2Settings> settings); + BaseObjectPtr<Http2Settings> PopSettings(); + Http2Settings* AddSettings(BaseObjectPtr<Http2Settings> settings); void IncrementCurrentSessionMemory(uint64_t amount) { current_session_memory_ += amount; @@ -1001,10 +1001,10 @@ class Http2Session : public AsyncWrap, public StreamListener { size_t stream_buf_offset_ = 0; size_t max_outstanding_pings_ = DEFAULT_MAX_PINGS; - std::queue<std::unique_ptr<Http2Ping>> outstanding_pings_; + std::queue<BaseObjectPtr<Http2Ping>> outstanding_pings_; size_t max_outstanding_settings_ = DEFAULT_MAX_SETTINGS; - std::queue<std::unique_ptr<Http2Settings>> outstanding_settings_; + std::queue<BaseObjectPtr<Http2Settings>> outstanding_settings_; std::vector<nghttp2_stream_write> outgoing_buffers_; std::vector<uint8_t> outgoing_storage_; diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 33769869992f8f..c6136702c7cb43 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -310,10 +310,13 @@ class Parser : public AsyncWrap, public StreamListener { argv[A_UPGRADE] = Boolean::New(env()->isolate(), parser_.upgrade); - AsyncCallbackScope callback_scope(env()); - - MaybeLocal<Value> head_response = - MakeCallback(cb.As<Function>(), arraysize(argv), argv); + MaybeLocal<Value> head_response; + { + InternalCallbackScope callback_scope( + this, InternalCallbackScope::kSkipTaskQueues); + head_response = cb.As<Function>()->Call( + env()->context(), object(), arraysize(argv), argv); + } int64_t val; @@ -379,9 +382,12 @@ class Parser : public AsyncWrap, public StreamListener { if (!cb->IsFunction()) return 0; - AsyncCallbackScope callback_scope(env()); - - MaybeLocal<Value> r = MakeCallback(cb.As<Function>(), 0, nullptr); + MaybeLocal<Value> r; + { + InternalCallbackScope callback_scope( + this, InternalCallbackScope::kSkipTaskQueues); + r = cb.As<Function>()->Call(env()->context(), object(), 0, nullptr); + } if (r.IsEmpty()) { got_exception_ = true; @@ -580,7 +586,7 @@ class Parser : public AsyncWrap, public StreamListener { // Once we’re done here, either indicate that the HTTP parser buffer // is free for re-use, or free() the data if it didn’t come from there // in the first place. - OnScopeLeave on_scope_leave([&]() { + auto on_scope_leave = OnScopeLeave([&]() { if (buf.base == env()->http_parser_buffer()) env()->set_http_parser_buffer_in_use(false); else diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 162f5fda5d4adb..c68e01e1074a4a 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -95,6 +95,7 @@ using v8::NewStringType; using v8::Object; using v8::ObjectTemplate; using v8::String; +using v8::Uint8Array; using v8::Value; namespace i18n { @@ -216,7 +217,7 @@ class ConverterObject : public BaseObject, Converter { result.AllocateSufficientStorage(limit); UBool flush = (flags & CONVERTER_FLAGS_FLUSH) == CONVERTER_FLAGS_FLUSH; - OnScopeLeave cleanup([&]() { + auto cleanup = OnScopeLeave([&]() { if (flush) { // Reset the converter state. converter->bomSeen_ = false; @@ -227,14 +228,6 @@ class ConverterObject : public BaseObject, Converter { const char* source = input.data(); size_t source_length = input.length(); - if (converter->unicode_ && !converter->ignoreBOM_ && !converter->bomSeen_) { - int32_t bomOffset = 0; - ucnv_detectUnicodeSignature(source, source_length, &bomOffset, &status); - source += bomOffset; - source_length -= bomOffset; - converter->bomSeen_ = true; - } - UChar* target = *result; ucnv_toUnicode(converter->conv, &target, target + (limit * sizeof(UChar)), @@ -242,10 +235,34 @@ class ConverterObject : public BaseObject, Converter { nullptr, flush, &status); if (U_SUCCESS(status)) { - if (limit > 0) + bool omit_initial_bom = false; + if (limit > 0) { result.SetLength(target - &result[0]); + if (result.length() > 0 && + converter->unicode_ && + !converter->ignoreBOM_ && + !converter->bomSeen_) { + // If the very first result in the stream is a BOM, and we are not + // explicitly told to ignore it, then we mark it for discarding. + if (result[0] == 0xFEFF) { + omit_initial_bom = true; + } + converter->bomSeen_ = true; + } + } ret = ToBufferEndian(env, &result); - args.GetReturnValue().Set(ret.ToLocalChecked()); + if (omit_initial_bom && !ret.IsEmpty()) { + // Peform `ret = ret.slice(2)`. + CHECK(ret.ToLocalChecked()->IsUint8Array()); + Local<Uint8Array> orig_ret = ret.ToLocalChecked().As<Uint8Array>(); + ret = Buffer::New(env, + orig_ret->Buffer(), + orig_ret->ByteOffset() + 2, + orig_ret->ByteLength() - 2) + .FromMaybe(Local<Uint8Array>()); + } + if (!ret.IsEmpty()) + args.GetReturnValue().Set(ret.ToLocalChecked()); return; } diff --git a/src/node_internals.h b/src/node_internals.h index 4ec883c8913e45..2bd0ff78da7c33 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -90,7 +90,6 @@ void PrintCaughtException(v8::Isolate* isolate, v8::Local<v8::Context> context, const v8::TryCatch& try_catch); -void WaitForInspectorDisconnect(Environment* env); void ResetStdio(); // Safe to call more than once and from signal handlers. #ifdef __POSIX__ void SignalExit(int signal, siginfo_t* info, void* ucontext); @@ -158,7 +157,11 @@ v8::MaybeLocal<v8::Object> New(Environment* env, char* data, size_t length, bool uses_malloc); - +// Creates a Buffer instance over an existing ArrayBuffer. +v8::MaybeLocal<v8::Uint8Array> New(Environment* env, + v8::Local<v8::ArrayBuffer> ab, + size_t byte_offset, + size_t length); // Construct a Buffer from a MaybeStackBuffer (and also its subclasses like // Utf8Value and TwoByteValue). // If |buf| is invalidated, an empty MaybeLocal is returned, and nothing is @@ -199,14 +202,24 @@ v8::MaybeLocal<v8::Value> InternalMakeCallback( class InternalCallbackScope { public: - // Tell the constructor whether its `object` parameter may be empty or not. - enum ResourceExpectation { kRequireResource, kAllowEmptyResource }; + enum Flags { + kNoFlags = 0, + // Tell the constructor whether its `object` parameter may be empty or not. + kAllowEmptyResource = 1, + // Indicates whether 'before' and 'after' hooks should be skipped. + kSkipAsyncHooks = 2, + // Indicates whether nextTick and microtask queues should be skipped. + // This should only be used when there is no call into JS in this scope. + // (The HTTP parser also uses it for some weird backwards + // compatibility issues, but it shouldn't.) + kSkipTaskQueues = 4 + }; InternalCallbackScope(Environment* env, v8::Local<v8::Object> object, const async_context& asyncContext, - ResourceExpectation expect = kRequireResource); + int flags = kNoFlags); // Utility that can be used by AsyncWrap classes. - explicit InternalCallbackScope(AsyncWrap* async_wrap); + explicit InternalCallbackScope(AsyncWrap* async_wrap, int flags = 0); ~InternalCallbackScope(); void Close(); @@ -217,7 +230,8 @@ class InternalCallbackScope { Environment* env_; async_context async_context_; v8::Local<v8::Object> object_; - AsyncCallbackScope callback_scope_; + bool skip_hooks_; + bool skip_task_queues_; bool failed_ = false; bool pushed_ids_ = false; bool closed_ = false; @@ -303,10 +317,15 @@ void SetIsolateCreateParamsForNode(v8::Isolate::CreateParams* params); #if HAVE_INSPECTOR namespace profiler { void StartProfilers(Environment* env); -void EndStartedProfilers(Environment* env); } #endif // HAVE_INSPECTOR +#ifdef __POSIX__ +static constexpr unsigned kMaxSignal = 32; +#endif + +bool HasSignalJSHandler(int signum); + #ifdef _WIN32 typedef SYSTEMTIME TIME_TYPE; #else // UNIX, OSX diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index 1c1a09280b70d8..eea847725300f0 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -7,6 +7,10 @@ #include <sanitizer/lsan_interface.h> #endif +#if HAVE_INSPECTOR +#include "inspector/worker_inspector.h" // ParentInspectorHandle +#endif + namespace node { using v8::Context; @@ -14,6 +18,7 @@ using v8::HandleScope; using v8::Isolate; using v8::Local; using v8::Locker; +using v8::Object; using v8::SealHandleScope; NodeMainInstance::NodeMainInstance(Isolate* isolate, @@ -111,10 +116,13 @@ int NodeMainInstance::Run() { if (exit_code == 0) { { - AsyncCallbackScope callback_scope(env.get()); - env->async_hooks()->push_async_ids(1, 0); + InternalCallbackScope callback_scope( + env.get(), + Local<Object>(), + { 1, 0 }, + InternalCallbackScope::kAllowEmptyResource | + InternalCallbackScope::kSkipAsyncHooks); LoadEnvironment(env.get()); - env->async_hooks()->pop_async_id(1); } env->set_trace_sync_io(env->options()->trace_sync_io); @@ -132,8 +140,6 @@ int NodeMainInstance::Run() { more = uv_loop_alive(env->event_loop()); if (more && !env->is_stopping()) continue; - env->RunBeforeExitCallbacks(); - if (!uv_loop_alive(env->event_loop())) { EmitBeforeExit(env.get()); } @@ -148,13 +154,26 @@ int NodeMainInstance::Run() { env->set_trace_sync_io(false); exit_code = EmitExit(env.get()); - WaitForInspectorDisconnect(env.get()); } env->set_can_call_into_js(false); env->stop_sub_worker_contexts(); ResetStdio(); env->RunCleanup(); + + // TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really + // make sense here. +#if HAVE_INSPECTOR && defined(__POSIX__) && !defined(NODE_SHARED_MODE) + struct sigaction act; + memset(&act, 0, sizeof(act)); + for (unsigned nr = 1; nr < kMaxSignal; nr += 1) { + if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF) + continue; + act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL; + CHECK_EQ(0, sigaction(nr, &act, nullptr)); + } +#endif + RunAtExit(env.get()); per_process::v8_platform.DrainVMTasks(isolate_); @@ -208,7 +227,7 @@ std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment( // TODO(joyeecheung): when we snapshot the bootstrapped context, // the inspector and diagnostics setup should after after deserialization. #if HAVE_INSPECTOR - *exit_code = env->InitializeInspector(nullptr); + *exit_code = env->InitializeInspector({}); #endif if (*exit_code != 0) { return env; diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 19065fdb7d1be5..65a40db32826aa 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -12,7 +12,7 @@ using node::contextify::ContextifyContext; using v8::Array; using v8::ArrayBuffer; -using v8::ArrayBufferCreationMode; +using v8::BackingStore; using v8::Context; using v8::EscapableHandleScope; using v8::Exception; @@ -123,10 +123,9 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, std::vector<Local<SharedArrayBuffer>> shared_array_buffers; // Attach all transferred SharedArrayBuffers to their new Isolate. for (uint32_t i = 0; i < shared_array_buffers_.size(); ++i) { - Local<SharedArrayBuffer> sab; - if (!shared_array_buffers_[i]->GetSharedArrayBuffer(env, context) - .ToLocal(&sab)) - return MaybeLocal<Value>(); + Local<SharedArrayBuffer> sab = + SharedArrayBuffer::New(env->isolate(), + std::move(shared_array_buffers_[i])); shared_array_buffers.push_back(sab); } shared_array_buffers_.clear(); @@ -141,30 +140,12 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, delegate.deserializer = &deserializer; // Attach all transferred ArrayBuffers to their new Isolate. - for (uint32_t i = 0; i < array_buffer_contents_.size(); ++i) { - if (!env->isolate_data()->uses_node_allocator()) { - // We don't use Node's allocator on the receiving side, so we have - // to create the ArrayBuffer from a copy of the memory. - AllocatedBuffer buf = - env->AllocateManaged(array_buffer_contents_[i].size); - memcpy(buf.data(), - array_buffer_contents_[i].data, - array_buffer_contents_[i].size); - deserializer.TransferArrayBuffer(i, buf.ToArrayBuffer()); - continue; - } - - env->isolate_data()->node_allocator()->RegisterPointer( - array_buffer_contents_[i].data, array_buffer_contents_[i].size); - + for (uint32_t i = 0; i < array_buffers_.size(); ++i) { Local<ArrayBuffer> ab = - ArrayBuffer::New(env->isolate(), - array_buffer_contents_[i].release(), - array_buffer_contents_[i].size, - ArrayBufferCreationMode::kInternalized); + ArrayBuffer::New(env->isolate(), std::move(array_buffers_[i])); deserializer.TransferArrayBuffer(i, ab); } - array_buffer_contents_.clear(); + array_buffers_.clear(); if (deserializer.ReadHeader(context).IsNothing()) return MaybeLocal<Value>(); @@ -173,8 +154,8 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, } void Message::AddSharedArrayBuffer( - const SharedArrayBufferMetadataReference& reference) { - shared_array_buffers_.push_back(reference); + std::shared_ptr<BackingStore> backing_store) { + shared_array_buffers_.emplace_back(std::move(backing_store)); } void Message::AddMessagePort(std::unique_ptr<MessagePortData>&& data) { @@ -249,16 +230,9 @@ class SerializerDelegate : public ValueSerializer::Delegate { } } - auto reference = SharedArrayBufferMetadata::ForSharedArrayBuffer( - env_, - context_, - shared_array_buffer); - if (!reference) { - return Nothing<uint32_t>(); - } seen_shared_array_buffers_.emplace_back( Global<SharedArrayBuffer> { isolate, shared_array_buffer }); - msg_->AddSharedArrayBuffer(reference); + msg_->AddSharedArrayBuffer(shared_array_buffer->GetBackingStore()); return Just(i); } @@ -323,12 +297,25 @@ Maybe<bool> Message::Serialize(Environment* env, // Currently, we support ArrayBuffers and MessagePorts. if (entry->IsArrayBuffer()) { Local<ArrayBuffer> ab = entry.As<ArrayBuffer>(); - // If we cannot render the ArrayBuffer unusable in this Isolate and - // take ownership of its memory, copying the buffer will have to do. - if (!ab->IsDetachable() || ab->IsExternal() || - !env->isolate_data()->uses_node_allocator()) { - continue; + // If we cannot render the ArrayBuffer unusable in this Isolate, + // copying the buffer will have to do. + // Note that we can currently transfer ArrayBuffers even if they were + // not allocated by Node’s ArrayBufferAllocator in the first place, + // because we pass the underlying v8::BackingStore around rather than + // raw data *and* an Isolate with a non-default ArrayBuffer allocator + // is always going to outlive any Workers it creates, and so will its + // allocator along with it. + if (!ab->IsDetachable()) continue; + // See https://github.com/nodejs/node/pull/30339#issuecomment-552225353 + // for details. + bool untransferrable; + if (!ab->HasPrivate( + context, + env->arraybuffer_untransferable_private_symbol()) + .To(&untransferrable)) { + return Nothing<bool>(); } + if (untransferrable) continue; if (std::find(array_buffers.begin(), array_buffers.end(), ab) != array_buffers.end()) { ThrowDataCloneException( @@ -386,18 +373,14 @@ Maybe<bool> Message::Serialize(Environment* env, } for (Local<ArrayBuffer> ab : array_buffers) { - // If serialization succeeded, we want to take ownership of - // (a.k.a. externalize) the underlying memory region and render - // it inaccessible in this Isolate. - ArrayBuffer::Contents contents = ab->Externalize(); + // If serialization succeeded, we render it inaccessible in this Isolate. + std::shared_ptr<BackingStore> backing_store = ab->GetBackingStore(); + // TODO(addaleax): This can/should be dropped once we have V8 8.0. + if (!ab->IsExternal()) + ab->Externalize(backing_store); ab->Detach(); - CHECK(env->isolate_data()->uses_node_allocator()); - env->isolate_data()->node_allocator()->UnregisterPointer( - contents.Data(), contents.ByteLength()); - - array_buffer_contents_.emplace_back(MallocedBuffer<char>{ - static_cast<char*>(contents.Data()), contents.ByteLength()}); + array_buffers_.emplace_back(std::move(backing_store)); } delegate.Finish(); @@ -411,9 +394,8 @@ Maybe<bool> Message::Serialize(Environment* env, } void Message::MemoryInfo(MemoryTracker* tracker) const { - tracker->TrackField("array_buffer_contents", array_buffer_contents_); - tracker->TrackFieldWithSize("shared_array_buffers", - shared_array_buffers_.size() * sizeof(shared_array_buffers_[0])); + tracker->TrackField("array_buffers_", array_buffers_); + tracker->TrackField("shared_array_buffers", shared_array_buffers_); tracker->TrackField("message_ports", message_ports_); } diff --git a/src/node_messaging.h b/src/node_messaging.h index 054521b0563c42..32eedfb34f917b 100644 --- a/src/node_messaging.h +++ b/src/node_messaging.h @@ -5,7 +5,6 @@ #include "env.h" #include "node_mutex.h" -#include "sharedarraybuffer_metadata.h" #include <list> namespace node { @@ -52,7 +51,7 @@ class Message : public MemoryRetainer { // Internal method of Message that is called when a new SharedArrayBuffer // object is encountered in the incoming value's structure. - void AddSharedArrayBuffer(const SharedArrayBufferMetadataReference& ref); + void AddSharedArrayBuffer(std::shared_ptr<v8::BackingStore> backing_store); // Internal method of Message that is called once serialization finishes // and that transfers ownership of `data` to this message. void AddMessagePort(std::unique_ptr<MessagePortData>&& data); @@ -74,8 +73,8 @@ class Message : public MemoryRetainer { private: MallocedBuffer<char> main_message_buf_; - std::vector<MallocedBuffer<char>> array_buffer_contents_; - std::vector<SharedArrayBufferMetadataReference> shared_array_buffers_; + std::vector<std::shared_ptr<v8::BackingStore>> array_buffers_; + std::vector<std::shared_ptr<v8::BackingStore>> shared_array_buffers_; std::vector<std::unique_ptr<MessagePortData>> message_ports_; std::vector<v8::WasmModuleObject::TransferrableModule> wasm_modules_; diff --git a/src/node_options.cc b/src/node_options.cc index 695d7cee6541cc..0bc6730156ce12 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -113,10 +113,6 @@ void PerIsolateOptions::CheckOptions(std::vector<std::string>* errors) { } void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) { - if (!userland_loader.empty() && !experimental_modules) { - errors->push_back("--experimental-loader requires " - "--experimental-modules be enabled"); - } if (has_policy_integrity_string && experimental_policy.empty()) { errors->push_back("--policy-integrity requires " "--experimental-policy be enabled"); @@ -126,30 +122,12 @@ void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) { } if (!module_type.empty()) { - if (!experimental_modules) { - errors->push_back("--input-type requires " - "--experimental-modules to be enabled"); - } if (module_type != "commonjs" && module_type != "module") { errors->push_back("--input-type must be \"module\" or \"commonjs\""); } } - if (experimental_json_modules && !experimental_modules) { - errors->push_back("--experimental-json-modules requires " - "--experimental-modules be enabled"); - } - - if (experimental_wasm_modules && !experimental_modules) { - errors->push_back("--experimental-wasm-modules requires " - "--experimental-modules be enabled"); - } - if (!es_module_specifier_resolution.empty()) { - if (!experimental_modules) { - errors->push_back("--es-module-specifier-resolution requires " - "--experimental-modules be enabled"); - } if (es_module_specifier_resolution != "node" && es_module_specifier_resolution != "explicit") { errors->push_back("invalid value for --es-module-specifier-resolution"); @@ -322,14 +300,15 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { &EnvironmentOptions::experimental_json_modules, kAllowedInEnvironment); AddOption("--experimental-loader", - "(with --experimental-modules) use the specified file as a " - "custom loader", + "use the specified module as a custom loader", &EnvironmentOptions::userland_loader, kAllowedInEnvironment); AddAlias("--loader", "--experimental-loader"); - AddOption("--experimental-modules", - "experimental ES Module support and caching modules", - &EnvironmentOptions::experimental_modules, + AddAlias("--experimental-modules", { "--experimental-conditional-exports", + "--experimental-resolve-self" }); + AddOption("--experimental-conditional-exports", + "experimental support for conditional exports targets", + &EnvironmentOptions::experimental_conditional_exports, kAllowedInEnvironment); AddOption("--experimental-resolve-self", "experimental support for require/import of the current package", @@ -527,6 +506,10 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { AddOption("--napi-modules", "", NoOp{}, kAllowedInEnvironment); + AddOption("--tls-keylog", + "log TLS decryption keys to named file for traffic analysis", + &EnvironmentOptions::tls_keylog, kAllowedInEnvironment); + AddOption("--tls-min-v1.0", "set default TLS minimum to TLSv1.0 (default: TLSv1.2)", &EnvironmentOptions::tls_min_v1_0, @@ -809,7 +792,7 @@ void GetOptions(const FunctionCallbackInfo<Value>& args) { per_process::cli_options->per_isolate = env->isolate_data()->options(); auto original_per_env = per_process::cli_options->per_isolate->per_env; per_process::cli_options->per_isolate->per_env = env->options(); - OnScopeLeave on_scope_leave([&]() { + auto on_scope_leave = OnScopeLeave([&]() { per_process::cli_options->per_isolate->per_env = original_per_env; per_process::cli_options->per_isolate = original_per_isolate; }); diff --git a/src/node_options.h b/src/node_options.h index a4af15e3e00c31..ce0cee5fe56784 100644 --- a/src/node_options.h +++ b/src/node_options.h @@ -101,8 +101,8 @@ class EnvironmentOptions : public Options { public: bool abort_on_uncaught_exception = false; bool enable_source_maps = false; + bool experimental_conditional_exports = false; bool experimental_json_modules = false; - bool experimental_modules = false; bool experimental_resolve_self = false; std::string es_module_specifier_resolution; bool experimental_wasm_modules = false; @@ -161,6 +161,7 @@ class EnvironmentOptions : public Options { bool tls_min_v1_3 = false; bool tls_max_v1_2 = false; bool tls_max_v1_3 = false; + std::string tls_keylog; std::vector<std::string> preload_modules; @@ -247,11 +248,6 @@ HostPort SplitHostPort(const std::string& arg, std::vector<std::string>* errors); void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); -enum OptionEnvvarSettings { - kAllowedInEnvironment, - kDisallowedInEnvironment -}; - enum OptionType { kNoOp, kV8Option, diff --git a/src/node_os.cc b/src/node_os.cc index b6fb305948e234..12a4ec3551a4db 100644 --- a/src/node_os.cc +++ b/src/node_os.cc @@ -171,7 +171,7 @@ static void GetLoadAvg(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 3); Local<ArrayBuffer> ab = array->Buffer(); - double* loadavg = static_cast<double*>(ab->GetContents().Data()); + double* loadavg = static_cast<double*>(ab->GetBackingStore()->Data()); uv_loadavg(loadavg); } @@ -302,7 +302,7 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) { return args.GetReturnValue().SetUndefined(); } - OnScopeLeave free_passwd([&]() { uv_os_free_passwd(&pwd); }); + auto free_passwd = OnScopeLeave([&]() { uv_os_free_passwd(&pwd); }); Local<Value> error; diff --git a/src/node_process.h b/src/node_process.h index 48d5aa704f71e9..5db7b004d6f939 100644 --- a/src/node_process.h +++ b/src/node_process.h @@ -34,15 +34,6 @@ v8::Maybe<bool> ProcessEmitDeprecationWarning(Environment* env, v8::MaybeLocal<v8::Object> CreateProcessObject(Environment* env); void PatchProcessObject(const v8::FunctionCallbackInfo<v8::Value>& args); -namespace task_queue { -// Handle any nextTicks added in the first tick of the program. -// We use the native version here for once so that any microtasks -// created by the main module is then handled from C++, and -// the call stack of the main script does not show up in the async error -// stack trace. -bool RunNextTicksNative(Environment* env); -} // namespace task_queue - } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #endif // SRC_NODE_PROCESS_H_ diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index 3a2c1efd812fca..7efe8efb9b9e6d 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -109,7 +109,7 @@ static void CPUUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 2); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); // Set the Float64Array elements to be user / system values in microseconds. fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec; @@ -148,7 +148,7 @@ static void Hrtime(const FunctionCallbackInfo<Value>& args) { uint64_t t = uv_hrtime(); Local<ArrayBuffer> ab = args[0].As<Uint32Array>()->Buffer(); - uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data()); + uint32_t* fields = static_cast<uint32_t*>(ab->GetBackingStore()->Data()); fields[0] = (t / NANOS_PER_SEC) >> 32; fields[1] = (t / NANOS_PER_SEC) & 0xffffffff; @@ -157,7 +157,7 @@ static void Hrtime(const FunctionCallbackInfo<Value>& args) { static void HrtimeBigInt(const FunctionCallbackInfo<Value>& args) { Local<ArrayBuffer> ab = args[0].As<BigUint64Array>()->Buffer(); - uint64_t* fields = static_cast<uint64_t*>(ab->GetContents().Data()); + uint64_t* fields = static_cast<uint64_t*>(ab->GetBackingStore()->Data()); fields[0] = uv_hrtime(); } @@ -172,11 +172,15 @@ static void Kill(const FunctionCallbackInfo<Value>& args) { if (!args[0]->Int32Value(context).To(&pid)) return; int sig; if (!args[1]->Int32Value(context).To(&sig)) return; - // TODO(joyeecheung): white list the signals? -#if HAVE_INSPECTOR - profiler::EndStartedProfilers(env); -#endif + uv_pid_t own_pid = uv_os_getpid(); + if (sig > 0 && + (pid == 0 || pid == -1 || pid == own_pid || pid == -own_pid) && + !HasSignalJSHandler(sig)) { + // This is most likely going to terminate this process. + // It's not an exact method but it might be close enough. + RunAtExit(env); + } int err = uv_kill(pid, sig); args.GetReturnValue().Set(err); @@ -200,7 +204,7 @@ static void MemoryUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 4); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); fields[0] = rss; fields[1] = v8_heap_stats.total_heap_size(); @@ -297,7 +301,7 @@ static void ResourceUsage(const FunctionCallbackInfo<Value>& args) { Local<Float64Array> array = args[0].As<Float64Array>(); CHECK_EQ(array->Length(), 16); Local<ArrayBuffer> ab = array->Buffer(); - double* fields = static_cast<double*>(ab->GetContents().Data()); + double* fields = static_cast<double*>(ab->GetBackingStore()->Data()); fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec; fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec; @@ -358,7 +362,7 @@ static void DebugProcess(const FunctionCallbackInfo<Value>& args) { LPTHREAD_START_ROUTINE* handler = nullptr; DWORD pid = 0; - OnScopeLeave cleanup([&]() { + auto cleanup = OnScopeLeave([&]() { if (process != nullptr) CloseHandle(process); if (thread != nullptr) CloseHandle(thread); if (handler != nullptr) UnmapViewOfFile(handler); @@ -428,7 +432,7 @@ static void DebugEnd(const FunctionCallbackInfo<Value>& args) { static void ReallyExit(const FunctionCallbackInfo<Value>& args) { Environment* env = Environment::GetCurrent(args); - WaitForInspectorDisconnect(env); + RunAtExit(env); int code = args[0]->Int32Value(env->context()).FromMaybe(0); env->Exit(code); } diff --git a/src/node_process_object.cc b/src/node_process_object.cc index 92124503ab9c5c..a1bf90c8d69fc0 100644 --- a/src/node_process_object.cc +++ b/src/node_process_object.cc @@ -74,7 +74,7 @@ MaybeLocal<Object> CreateProcessObject(Environment* env) { Local<Context> context = env->context(); Local<FunctionTemplate> process_template = FunctionTemplate::New(isolate); - process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "process")); + process_template->SetClassName(env->process_string()); Local<Function> process_ctor; Local<Object> process; if (!process_template->GetFunction(context).ToLocal(&process_ctor) || diff --git a/src/node_root_certs.h b/src/node_root_certs.h index a5032d645202fd..bc08910c77ad4c 100644 --- a/src/node_root_certs.h +++ b/src/node_root_certs.h @@ -574,27 +574,6 @@ "yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K\n" "-----END CERTIFICATE-----", -/* Certplus Class 2 Primary CA */ -"-----BEGIN CERTIFICATE-----\n" -"MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkG\n" -"A1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkg\n" -"Q0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8G\n" -"A1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZI\n" -"hvcNAQEBBQADggEPADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxv\n" -"c0NXYKwzCkTsA18cgCSR5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLR\n" -"YE2+L0ER4/YXJQyLkcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v\n" -"0lPubNCdEgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas\n" -"H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC\n" -"40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNV\n" -"HQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQw\n" -"MC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29tL0NSTC9jbGFzczIuY3JsMA0GCSqG\n" -"SIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5t\n" -"n9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabg\n" -"lZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW\n" -"2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB\n" -"kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7l7+ijrRU\n" -"-----END CERTIFICATE-----", - /* DST Root CA X3 */ "-----BEGIN CERTIFICATE-----\n" "MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYD\n" @@ -904,28 +883,6 @@ "vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==\n" "-----END CERTIFICATE-----", -/* Deutsche Telekom Root CA 2 */ -"-----BEGIN CERTIFICATE-----\n" -"MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UE\n" -"ChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRl\n" -"cjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAw\n" -"WhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVs\n" -"ZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1\n" -"dHNjaGUgVGVsZWtvbSBSb290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\n" -"AQCrC6M14IspFLEUha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1c\n" -"Os7TuKhCQN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr\n" -"rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1\n" -"Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFh\n" -"mHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0G\n" -"A1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB\n" -"/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f7\n" -"6Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSY\n" -"SKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juw\n" -"zTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+\n" -"xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mUCm26OWMo\n" -"hpLzGITY+9HPBVZkVw==\n" -"-----END CERTIFICATE-----", - /* Cybertrust Global Root */ "-----BEGIN CERTIFICATE-----\n" "MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMP\n" diff --git a/src/node_task_queue.cc b/src/node_task_queue.cc index ef1aff6cd4138d..f418a272470e2b 100644 --- a/src/node_task_queue.cc +++ b/src/node_task_queue.cc @@ -41,22 +41,6 @@ static void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) { isolate->EnqueueMicrotask(args[0].As<Function>()); } -// Should be in sync with runNextTicks in internal/process/task_queues.js -bool RunNextTicksNative(Environment* env) { - OnScopeLeave weakref_cleanup([&]() { env->RunWeakRefCleanup(); }); - - TickInfo* tick_info = env->tick_info(); - if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn()) - MicrotasksScope::PerformCheckpoint(env->isolate()); - if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn()) - return true; - - Local<Function> callback = env->tick_callback_function(); - CHECK(!callback.IsEmpty()); - return !callback->Call(env->context(), env->process_object(), 0, nullptr) - .IsEmpty(); -} - static void RunMicrotasks(const FunctionCallbackInfo<Value>& args) { MicrotasksScope::PerformCheckpoint(args.GetIsolate()); } diff --git a/src/node_version.h b/src/node_version.h index ed1d101dc9331d..b756b0c1e071c8 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 13 -#define NODE_MINOR_VERSION 1 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 2 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) diff --git a/src/node_worker.cc b/src/node_worker.cc index af79540631f153..676b70a1fa90c1 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -16,10 +16,12 @@ #include <string> #include <vector> -using node::options_parser::kDisallowedInEnvironment; +using node::kDisallowedInEnvironment; using v8::Array; +using v8::ArrayBuffer; using v8::Boolean; using v8::Context; +using v8::Float64Array; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; @@ -28,26 +30,18 @@ using v8::Isolate; using v8::Local; using v8::Locker; using v8::MaybeLocal; +using v8::Null; using v8::Number; using v8::Object; +using v8::ResourceConstraints; using v8::SealHandleScope; using v8::String; +using v8::TryCatch; using v8::Value; namespace node { namespace worker { -namespace { - -#if HAVE_INSPECTOR -void WaitForWorkerInspectorToStop(Environment* child) { - child->inspector_agent()->WaitForDisconnect(); - child->inspector_agent()->Stop(); -} -#endif - -} // anonymous namespace - Worker::Worker(Environment* env, Local<Object> wrap, const std::string& url, @@ -57,7 +51,6 @@ Worker::Worker(Environment* env, per_isolate_opts_(per_isolate_opts), exec_argv_(exec_argv), platform_(env->isolate_data()->platform()), - array_buffer_allocator_(ArrayBufferAllocator::Create()), start_profiler_idle_notifier_(env->profiler_idle_notifier_started()), thread_id_(Environment::AllocateThreadId()), env_vars_(env->env_vars()) { @@ -101,8 +94,34 @@ bool Worker::is_stopped() const { return stopped_; } -std::shared_ptr<ArrayBufferAllocator> Worker::array_buffer_allocator() { - return array_buffer_allocator_; +void Worker::UpdateResourceConstraints(ResourceConstraints* constraints) { + constraints->set_stack_limit(reinterpret_cast<uint32_t*>(stack_base_)); + + constexpr double kMB = 1024 * 1024; + + if (resource_limits_[kMaxYoungGenerationSizeMb] > 0) { + constraints->set_max_young_generation_size_in_bytes( + resource_limits_[kMaxYoungGenerationSizeMb] * kMB); + } else { + resource_limits_[kMaxYoungGenerationSizeMb] = + constraints->max_young_generation_size_in_bytes() / kMB; + } + + if (resource_limits_[kMaxOldGenerationSizeMb] > 0) { + constraints->set_max_old_generation_size_in_bytes( + resource_limits_[kMaxOldGenerationSizeMb] * kMB); + } else { + resource_limits_[kMaxOldGenerationSizeMb] = + constraints->max_old_generation_size_in_bytes() / kMB; + } + + if (resource_limits_[kCodeRangeSizeMb] > 0) { + constraints->set_code_range_size_in_bytes( + resource_limits_[kCodeRangeSizeMb] * kMB); + } else { + resource_limits_[kCodeRangeSizeMb] = + constraints->code_range_size_in_bytes() / kMB; + } } // This class contains data that is only relevant to the child thread itself, @@ -114,22 +133,36 @@ class WorkerThreadData { : w_(w) { CHECK_EQ(uv_loop_init(&loop_), 0); - Isolate* isolate = NewIsolate( - w->array_buffer_allocator_.get(), - &loop_, - w->platform_); - CHECK_NOT_NULL(isolate); + std::shared_ptr<ArrayBufferAllocator> allocator = + ArrayBufferAllocator::Create(); + Isolate::CreateParams params; + SetIsolateCreateParamsForNode(¶ms); + params.array_buffer_allocator = allocator.get(); + + w->UpdateResourceConstraints(¶ms.constraints); + + Isolate* isolate = Isolate::Allocate(); + if (isolate == nullptr) { + w->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; + return; + } + + w->platform_->RegisterIsolate(isolate, &loop_); + Isolate::Initialize(isolate, params); + SetIsolateUpForNode(isolate); + isolate->SetArrayBufferAllocatorShared(allocator); + + isolate->AddNearHeapLimitCallback(Worker::NearHeapLimit, w); { Locker locker(isolate); Isolate::Scope isolate_scope(isolate); - isolate->SetStackLimit(w_->stack_base_); HandleScope handle_scope(isolate); isolate_data_.reset(CreateIsolateData(isolate, &loop_, w_->platform_, - w->array_buffer_allocator_.get())); + allocator.get())); CHECK(isolate_data_); if (w_->per_isolate_opts_) isolate_data_->set_options(std::move(w_->per_isolate_opts_)); @@ -148,20 +181,22 @@ class WorkerThreadData { w_->isolate_ = nullptr; } - bool platform_finished = false; + if (isolate != nullptr) { + bool platform_finished = false; - isolate_data_.reset(); + isolate_data_.reset(); - w_->platform_->AddIsolateFinishedCallback(isolate, [](void* data) { - *static_cast<bool*>(data) = true; - }, &platform_finished); + w_->platform_->AddIsolateFinishedCallback(isolate, [](void* data) { + *static_cast<bool*>(data) = true; + }, &platform_finished); - isolate->Dispose(); - w_->platform_->UnregisterIsolate(isolate); + isolate->Dispose(); + w_->platform_->UnregisterIsolate(isolate); - // Wait until the platform has cleaned up all relevant resources. - while (!platform_finished) - uv_run(&loop_, UV_RUN_ONCE); + // Wait until the platform has cleaned up all relevant resources. + while (!platform_finished) + uv_run(&loop_, UV_RUN_ONCE); + } CheckedUvLoopClose(&loop_); } @@ -174,6 +209,17 @@ class WorkerThreadData { friend class Worker; }; +size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit, + size_t initial_heap_limit) { + Worker* worker = static_cast<Worker*>(data); + worker->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; + worker->Exit(1); + // Give the current GC some extra leeway to let it finish rather than + // crash hard. We are not going to perform further allocations anyway. + constexpr size_t kExtraHeapAllowance = 16 * 1024 * 1024; + return current_heap_limit + kExtraHeapAllowance; +} + void Worker::Run() { std::string name = "WorkerThread "; name += std::to_string(thread_id_); @@ -185,18 +231,16 @@ void Worker::Run() { Debug(this, "Creating isolate for worker with id %llu", thread_id_); WorkerThreadData data(this); + if (isolate_ == nullptr) return; Debug(this, "Starting worker with id %llu", thread_id_); { Locker locker(isolate_); Isolate::Scope isolate_scope(isolate_); SealHandleScope outer_seal(isolate_); -#if HAVE_INSPECTOR - bool inspector_started = false; -#endif DeleteFnPtr<Environment, FreeEnvironment> env_; - OnScopeLeave cleanup_env([&]() { + auto cleanup_env = OnScopeLeave([&]() { if (!env_) return; env_->set_can_call_into_js(false); Isolate::DisallowJavascriptExecutionScope disallow_js(isolate_, @@ -223,10 +267,6 @@ void Worker::Run() { env_->stop_sub_worker_contexts(); env_->RunCleanup(); RunAtExit(env_.get()); -#if HAVE_INSPECTOR - if (inspector_started) - WaitForWorkerInspectorToStop(env_.get()); -#endif // This call needs to be made while the `Environment` is still alive // because we assume that it is available for async tracking in the @@ -238,7 +278,21 @@ void Worker::Run() { if (is_stopped()) return; { HandleScope handle_scope(isolate_); - Local<Context> context = NewContext(isolate_); + Local<Context> context; + { + // We create the Context object before we have an Environment* in place + // that we could use for error handling. If creation fails due to + // resource constraints, we need something in place to handle it, + // though. + TryCatch try_catch(isolate_); + context = NewContext(isolate_); + if (context.IsEmpty()) { + // TODO(addaleax): Inform the target about the actual underlying + // failure. + custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; + return; + } + } if (is_stopped()) return; CHECK(!context.IsEmpty()); @@ -269,12 +323,16 @@ void Worker::Run() { { env_->InitializeDiagnostics(); #if HAVE_INSPECTOR - env_->InitializeInspector(inspector_parent_handle_.release()); - inspector_started = true; + env_->InitializeInspector(std::move(inspector_parent_handle_)); #endif HandleScope handle_scope(isolate_); - AsyncCallbackScope callback_scope(env_.get()); - env_->async_hooks()->push_async_ids(1, 0); + InternalCallbackScope callback_scope( + env_.get(), + Local<Object>(), + { 1, 0 }, + InternalCallbackScope::kAllowEmptyResource | + InternalCallbackScope::kSkipAsyncHooks); + if (!env_->RunBootstrapping().IsEmpty()) { CreateEnvMessagePort(env_.get()); if (is_stopped()) return; @@ -282,8 +340,6 @@ void Worker::Run() { USE(StartExecution(env_.get(), "internal/main/worker_thread")); } - env_->async_hooks()->pop_async_id(1); - Debug(this, "Loaded environment for worker %llu", thread_id_); } @@ -323,9 +379,6 @@ void Worker::Run() { if (exit_code_ == 0 && !stopped) exit_code_ = exit_code; -#if HAVE_INSPECTOR - profiler::EndStartedProfilers(env_.get()); -#endif Debug(this, "Exiting thread for worker %llu with exit code %d", thread_id_, exit_code_); } @@ -365,8 +418,14 @@ void Worker::JoinThread() { env()->message_port_string(), Undefined(env()->isolate())).Check(); - Local<Value> code = Integer::New(env()->isolate(), exit_code_); - MakeCallback(env()->onexit_string(), 1, &code); + Local<Value> args[] = { + Integer::New(env()->isolate(), exit_code_), + custom_error_ != nullptr ? + OneByteString(env()->isolate(), custom_error_).As<Value>() : + Null(env()->isolate()).As<Value>(), + }; + + MakeCallback(env()->onexit_string(), arraysize(args), args); } // We cleared all libuv handles bound to this Worker above, @@ -400,7 +459,7 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) { std::vector<std::string> exec_argv_out; bool has_explicit_exec_argv = false; - CHECK_EQ(args.Length(), 2); + CHECK_EQ(args.Length(), 3); // Argument might be a string or URL if (!args[0]->IsNullOrUndefined()) { Utf8Value value( @@ -466,7 +525,16 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) { } if (!has_explicit_exec_argv) exec_argv_out = env->exec_argv(); - new Worker(env, args.This(), url, per_isolate_opts, std::move(exec_argv_out)); + + Worker* worker = + new Worker(env, args.This(), url, per_isolate_opts, + std::move(exec_argv_out)); + + CHECK(args[2]->IsFloat64Array()); + Local<Float64Array> limit_info = args[2].As<Float64Array>(); + CHECK_EQ(limit_info->Length(), kTotalResourceLimitCount); + limit_info->CopyContents(worker->resource_limits_, + sizeof(worker->resource_limits_)); } void Worker::CloneParentEnvVars(const FunctionCallbackInfo<Value>& args) { @@ -547,6 +615,20 @@ void Worker::Unref(const FunctionCallbackInfo<Value>& args) { uv_unref(reinterpret_cast<uv_handle_t*>(w->on_thread_finished_.GetHandle())); } +void Worker::GetResourceLimits(const FunctionCallbackInfo<Value>& args) { + Worker* w; + ASSIGN_OR_RETURN_UNWRAP(&w, args.This()); + args.GetReturnValue().Set(w->GetResourceLimits(args.GetIsolate())); +} + +Local<Float64Array> Worker::GetResourceLimits(Isolate* isolate) const { + Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(resource_limits_)); + memcpy(ab->GetBackingStore()->Data(), + resource_limits_, + sizeof(resource_limits_)); + return Float64Array::New(ab, 0, kTotalResourceLimitCount); +} + void Worker::Exit(int code) { Mutex::ScopedLock lock(mutex_); Debug(this, "Worker %llu called Exit(%d)", thread_id_, code); @@ -589,6 +671,7 @@ void InitWorker(Local<Object> target, env->SetProtoMethod(w, "stopThread", Worker::StopThread); env->SetProtoMethod(w, "ref", Worker::Ref); env->SetProtoMethod(w, "unref", Worker::Unref); + env->SetProtoMethod(w, "getResourceLimits", Worker::GetResourceLimits); Local<String> workerString = FIXED_ONE_BYTE_STRING(env->isolate(), "Worker"); @@ -617,6 +700,19 @@ void InitWorker(Local<Object> target, FIXED_ONE_BYTE_STRING(env->isolate(), "ownsProcessState"), Boolean::New(env->isolate(), env->owns_process_state())) .Check(); + + if (!env->is_main_thread()) { + target + ->Set(env->context(), + FIXED_ONE_BYTE_STRING(env->isolate(), "resourceLimits"), + env->worker_context()->GetResourceLimits(env->isolate())) + .Check(); + } + + NODE_DEFINE_CONSTANT(target, kMaxYoungGenerationSizeMb); + NODE_DEFINE_CONSTANT(target, kMaxOldGenerationSizeMb); + NODE_DEFINE_CONSTANT(target, kCodeRangeSizeMb); + NODE_DEFINE_CONSTANT(target, kTotalResourceLimitCount); } } // anonymous namespace diff --git a/src/node_worker.h b/src/node_worker.h index 77f68801e7c247..7b1311734a2a4a 100644 --- a/src/node_worker.h +++ b/src/node_worker.h @@ -12,6 +12,13 @@ namespace worker { class WorkerThreadData; +enum ResourceLimits { + kMaxYoungGenerationSizeMb, + kMaxOldGenerationSizeMb, + kCodeRangeSizeMb, + kTotalResourceLimitCount +}; + // A worker thread, as represented in its parent thread. class Worker : public AsyncWrap { public: @@ -41,7 +48,6 @@ class Worker : public AsyncWrap { SET_SELF_SIZE(Worker) bool is_stopped() const; - std::shared_ptr<ArrayBufferAllocator> array_buffer_allocator(); static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void CloneParentEnvVars( @@ -51,16 +57,20 @@ class Worker : public AsyncWrap { static void StopThread(const v8::FunctionCallbackInfo<v8::Value>& args); static void Ref(const v8::FunctionCallbackInfo<v8::Value>& args); static void Unref(const v8::FunctionCallbackInfo<v8::Value>& args); + static void GetResourceLimits( + const v8::FunctionCallbackInfo<v8::Value>& args); + v8::Local<v8::Float64Array> GetResourceLimits(v8::Isolate* isolate) const; private: void CreateEnvMessagePort(Environment* env); + static size_t NearHeapLimit(void* data, size_t current_heap_limit, + size_t initial_heap_limit); std::shared_ptr<PerIsolateOptions> per_isolate_opts_; std::vector<std::string> exec_argv_; std::vector<std::string> argv_; MultiIsolatePlatform* platform_; - std::shared_ptr<ArrayBufferAllocator> array_buffer_allocator_; v8::Isolate* isolate_ = nullptr; bool start_profiler_idle_notifier_; uv_thread_t tid_; @@ -73,10 +83,15 @@ class Worker : public AsyncWrap { mutable Mutex mutex_; bool thread_joined_ = true; + const char* custom_error_ = nullptr; int exit_code_ = 0; uint64_t thread_id_ = -1; uintptr_t stack_base_ = 0; + // Custom resource constraints: + double resource_limits_[kTotalResourceLimitCount]; + void UpdateResourceConstraints(v8::ResourceConstraints* constraints); + // Full size of the thread's stack. static constexpr size_t kStackSize = 4 * 1024 * 1024; // Stack buffer size that is not available to the JS engine. diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 30fef0ff1d4d57..739e36d69911b2 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -386,7 +386,7 @@ class CompressionStream : public AsyncWrap, public ThreadPoolWork { // v8 land! void AfterThreadPoolWork(int status) override { AllocScope alloc_scope(this); - OnScopeLeave on_scope_leave([&]() { Unref(); }); + auto on_scope_leave = OnScopeLeave([&]() { Unref(); }); write_in_progress_ = false; @@ -590,7 +590,8 @@ class ZlibStream : public CompressionStream<ZlibContext> { CHECK(args[4]->IsUint32Array()); Local<Uint32Array> array = args[4].As<Uint32Array>(); Local<ArrayBuffer> ab = array->Buffer(); - uint32_t* write_result = static_cast<uint32_t*>(ab->GetContents().Data()); + uint32_t* write_result = static_cast<uint32_t*>( + ab->GetBackingStore()->Data()); CHECK(args[5]->IsFunction()); Local<Function> write_js_callback = args[5].As<Function>(); diff --git a/src/req_wrap-inl.h b/src/req_wrap-inl.h index cf89fb58a7f6fc..4fa4d0cf217069 100644 --- a/src/req_wrap-inl.h +++ b/src/req_wrap-inl.h @@ -10,6 +10,7 @@ namespace node { ReqWrapBase::ReqWrapBase(Environment* env) { + CHECK(env->has_run_bootstrapping_code()); env->req_wrap_queue()->PushBack(this); } diff --git a/src/sharedarraybuffer_metadata.cc b/src/sharedarraybuffer_metadata.cc deleted file mode 100644 index fc3bcdf3d3b6b7..00000000000000 --- a/src/sharedarraybuffer_metadata.cc +++ /dev/null @@ -1,175 +0,0 @@ -#include "sharedarraybuffer_metadata.h" - -#include "base_object-inl.h" -#include "memory_tracker-inl.h" -#include "node_errors.h" -#include "node_worker.h" -#include "util-inl.h" - -#include <utility> - -using v8::Context; -using v8::Function; -using v8::FunctionTemplate; -using v8::Local; -using v8::Maybe; -using v8::MaybeLocal; -using v8::Nothing; -using v8::Object; -using v8::SharedArrayBuffer; -using v8::Value; - -namespace node { -namespace worker { - -namespace { - -// Yield a JS constructor for SABLifetimePartner objects in the form of a -// standard API object, that has a single field for containing the raw -// SABLifetimePartner* pointer. -Local<Function> GetSABLifetimePartnerConstructor( - Environment* env, Local<Context> context) { - Local<FunctionTemplate> templ; - templ = env->sab_lifetimepartner_constructor_template(); - if (!templ.IsEmpty()) - return templ->GetFunction(context).ToLocalChecked(); - - templ = BaseObject::MakeLazilyInitializedJSTemplate(env); - templ->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), - "SABLifetimePartner")); - env->set_sab_lifetimepartner_constructor_template(templ); - - return GetSABLifetimePartnerConstructor(env, context); -} - -class SABLifetimePartner : public BaseObject { - public: - SABLifetimePartner(Environment* env, - Local<Object> obj, - SharedArrayBufferMetadataReference r) - : BaseObject(env, obj), - reference(std::move(r)) { - MakeWeak(); - env->AddCleanupHook(CleanupHook, static_cast<void*>(this)); - } - - ~SABLifetimePartner() { - env()->RemoveCleanupHook(CleanupHook, static_cast<void*>(this)); - } - - static void CleanupHook(void* data) { - // There is another cleanup hook attached to this object because it is a - // BaseObject. Cleanup hooks are triggered in reverse order of addition, - // so if this object is destroyed through GC, the destructor removes all - // hooks associated with this object, meaning that this cleanup hook - // only runs at the end of the Environment’s lifetime. - // In that case, V8 still knows about the SharedArrayBuffer and tries to - // free it when the last Isolate with access to it is disposed; for that, - // the ArrayBuffer::Allocator needs to be kept alive longer than this - // object and longer than the Environment instance. - // - // This is a workaround for https://github.com/nodejs/node-v8/issues/115 - // (introduced in V8 7.9) and we should be able to remove it once V8 - // ArrayBuffer::Allocator refactoring/removal is complete. - SABLifetimePartner* self = static_cast<SABLifetimePartner*>(data); - self->env()->AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose( - self->reference->allocator()); - } - - SET_NO_MEMORY_INFO() - SET_MEMORY_INFO_NAME(SABLifetimePartner) - SET_SELF_SIZE(SABLifetimePartner) - - SharedArrayBufferMetadataReference reference; -}; - -} // anonymous namespace - -SharedArrayBufferMetadataReference -SharedArrayBufferMetadata::ForSharedArrayBuffer( - Environment* env, - Local<Context> context, - Local<SharedArrayBuffer> source) { - Local<Value> lifetime_partner; - - if (!source->GetPrivate(context, - env->sab_lifetimepartner_symbol()) - .ToLocal(&lifetime_partner)) { - return nullptr; - } - - if (lifetime_partner->IsObject() && - env->sab_lifetimepartner_constructor_template() - ->HasInstance(lifetime_partner)) { - CHECK(source->IsExternal()); - SABLifetimePartner* partner = - Unwrap<SABLifetimePartner>(lifetime_partner.As<Object>()); - CHECK_NOT_NULL(partner); - return partner->reference; - } - - if (source->IsExternal()) { - // If this is an external SharedArrayBuffer but we do not see a lifetime - // partner object, it was not us who externalized it. In that case, there - // is no way to serialize it, because it's unclear how the memory - // is actually owned. - THROW_ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER(env); - return nullptr; - } - - // If the SharedArrayBuffer is coming from a Worker, we need to make sure - // that the corresponding ArrayBuffer::Allocator lives at least as long as - // the SharedArrayBuffer itself. - worker::Worker* w = env->worker_context(); - std::shared_ptr<v8::ArrayBuffer::Allocator> allocator = - w != nullptr ? w->array_buffer_allocator() : nullptr; - - SharedArrayBuffer::Contents contents = source->Externalize(); - SharedArrayBufferMetadataReference r( - new SharedArrayBufferMetadata(contents, allocator)); - if (r->AssignToSharedArrayBuffer(env, context, source).IsNothing()) - return nullptr; - return r; -} - -Maybe<bool> SharedArrayBufferMetadata::AssignToSharedArrayBuffer( - Environment* env, Local<Context> context, - Local<SharedArrayBuffer> target) { - CHECK(target->IsExternal()); - Local<Function> ctor = GetSABLifetimePartnerConstructor(env, context); - Local<Object> obj; - if (!ctor->NewInstance(context).ToLocal(&obj)) - return Nothing<bool>(); - - new SABLifetimePartner(env, obj, shared_from_this()); - return target->SetPrivate(context, - env->sab_lifetimepartner_symbol(), - obj); -} - -SharedArrayBufferMetadata::SharedArrayBufferMetadata( - const SharedArrayBuffer::Contents& contents, - std::shared_ptr<v8::ArrayBuffer::Allocator> allocator) - : contents_(contents), allocator_(allocator) { } - -SharedArrayBufferMetadata::~SharedArrayBufferMetadata() { - contents_.Deleter()(contents_.Data(), - contents_.ByteLength(), - contents_.DeleterData()); -} - -MaybeLocal<SharedArrayBuffer> SharedArrayBufferMetadata::GetSharedArrayBuffer( - Environment* env, Local<Context> context) { - Local<SharedArrayBuffer> obj = - SharedArrayBuffer::New(env->isolate(), - contents_.Data(), - contents_.ByteLength()); - - if (AssignToSharedArrayBuffer(env, context, obj).IsNothing()) - return MaybeLocal<SharedArrayBuffer>(); - - return obj; -} - -} // namespace worker -} // namespace node diff --git a/src/sharedarraybuffer_metadata.h b/src/sharedarraybuffer_metadata.h deleted file mode 100644 index 4d89f08ee10daf..00000000000000 --- a/src/sharedarraybuffer_metadata.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef SRC_SHAREDARRAYBUFFER_METADATA_H_ -#define SRC_SHAREDARRAYBUFFER_METADATA_H_ - -#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS - -#include "node.h" -#include <memory> - -namespace node { -namespace worker { - -class SharedArrayBufferMetadata; - -// This is an object associated with a SharedArrayBuffer, which keeps track -// of a cross-thread reference count. Once a SharedArrayBuffer is transferred -// for the first time (or is attempted to be transferred), one of these objects -// is created, and the SharedArrayBuffer is moved from internalized mode into -// externalized mode (i.e. the JS engine no longer frees the memory on its own). -// -// This will always be referred to using a std::shared_ptr, since it keeps -// a reference count and is guaranteed to be thread-safe. -typedef std::shared_ptr<SharedArrayBufferMetadata> - SharedArrayBufferMetadataReference; - -class SharedArrayBufferMetadata - : public std::enable_shared_from_this<SharedArrayBufferMetadata> { - public: - static SharedArrayBufferMetadataReference ForSharedArrayBuffer( - Environment* env, - v8::Local<v8::Context> context, - v8::Local<v8::SharedArrayBuffer> source); - ~SharedArrayBufferMetadata(); - - // Create a SharedArrayBuffer object for a specific Environment and Context. - // The created SharedArrayBuffer will be in externalized mode and has - // a hidden object attached to it, during whose lifetime the reference - // count is increased by 1. - v8::MaybeLocal<v8::SharedArrayBuffer> GetSharedArrayBuffer( - Environment* env, v8::Local<v8::Context> context); - std::shared_ptr<v8::ArrayBuffer::Allocator> allocator() const { - return allocator_; - } - - SharedArrayBufferMetadata(SharedArrayBufferMetadata&& other) = delete; - SharedArrayBufferMetadata& operator=( - SharedArrayBufferMetadata&& other) = delete; - SharedArrayBufferMetadata& operator=( - const SharedArrayBufferMetadata&) = delete; - SharedArrayBufferMetadata(const SharedArrayBufferMetadata&) = delete; - - private: - SharedArrayBufferMetadata( - const v8::SharedArrayBuffer::Contents&, - std::shared_ptr<v8::ArrayBuffer::Allocator>); - - // Attach a lifetime tracker object with a reference count to `target`. - v8::Maybe<bool> AssignToSharedArrayBuffer( - Environment* env, - v8::Local<v8::Context> context, - v8::Local<v8::SharedArrayBuffer> target); - - v8::SharedArrayBuffer::Contents contents_; - std::shared_ptr<v8::ArrayBuffer::Allocator> allocator_; -}; - -} // namespace worker -} // namespace node - -#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS - - -#endif // SRC_SHAREDARRAYBUFFER_METADATA_H_ diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index 90b91f35a86c8b..cf67dc590f6d51 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -38,8 +38,13 @@ using v8::Object; using v8::String; using v8::Value; +void DecreaseSignalHandlerCount(int signum); + namespace { +static Mutex handled_signals_mutex; +static std::map<int, int64_t> handled_signals; // Signal -> number of handlers + class SignalWrap : public HandleWrap { public: static void Initialize(Local<Object> target, @@ -85,6 +90,11 @@ class SignalWrap : public HandleWrap { CHECK_EQ(r, 0); } + void Close(v8::Local<v8::Value> close_callback) override { + if (active_) DecreaseSignalHandlerCount(handle_.signum); + HandleWrap::Close(close_callback); + } + static void Start(const FunctionCallbackInfo<Value>& args) { SignalWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); @@ -112,21 +122,49 @@ class SignalWrap : public HandleWrap { wrap->MakeCallback(env->onsignal_string(), 1, &arg); }, signum); + + if (err == 0) { + CHECK(!wrap->active_); + wrap->active_ = true; + Mutex::ScopedLock lock(handled_signals_mutex); + handled_signals[signum]++; + } + args.GetReturnValue().Set(err); } static void Stop(const FunctionCallbackInfo<Value>& args) { SignalWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + + if (wrap->active_) { + wrap->active_ = false; + DecreaseSignalHandlerCount(wrap->handle_.signum); + } + int err = uv_signal_stop(&wrap->handle_); args.GetReturnValue().Set(err); } uv_signal_t handle_; + bool active_ = false; }; } // anonymous namespace + +void DecreaseSignalHandlerCount(int signum) { + Mutex::ScopedLock lock(handled_signals_mutex); + int new_handler_count = --handled_signals[signum]; + CHECK_GE(new_handler_count, 0); + if (new_handler_count == 0) + handled_signals.erase(signum); +} + +bool HasSignalJSHandler(int signum) { + Mutex::ScopedLock lock(handled_signals_mutex); + return handled_signals.find(signum) != handled_signals.end(); +} } // namespace node diff --git a/src/stream_base.cc b/src/stream_base.cc index 52163e2e43fa1f..eaccfc995c745f 100644 --- a/src/stream_base.cc +++ b/src/stream_base.cc @@ -180,12 +180,26 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) { } Local<Object> req_wrap_obj = args[0].As<Object>(); - uv_buf_t buf; buf.base = Buffer::Data(args[1]); buf.len = Buffer::Length(args[1]); - StreamWriteResult res = Write(&buf, 1, nullptr, req_wrap_obj); + uv_stream_t* send_handle = nullptr; + + if (args[2]->IsObject() && IsIPCPipe()) { + Local<Object> send_handle_obj = args[2].As<Object>(); + + HandleWrap* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, send_handle_obj, UV_EINVAL); + send_handle = reinterpret_cast<uv_stream_t*>(wrap->GetHandle()); + // Reference LibuvStreamWrap instance to prevent it from being garbage + // collected before `AfterWrite` is called. + req_wrap_obj->Set(env->context(), + env->handle_string(), + send_handle_obj).Check(); + } + + StreamWriteResult res = Write(&buf, 1, send_handle, req_wrap_obj); SetWriteResult(res); return res.err; diff --git a/src/stream_pipe.cc b/src/stream_pipe.cc index be7fc882ea5c8a..6e339378ceb374 100644 --- a/src/stream_pipe.cc +++ b/src/stream_pipe.cc @@ -71,6 +71,7 @@ void StreamPipe::Unpipe() { // Delay the JS-facing part with SetImmediate, because this might be from // inside the garbage collector, so we can’t run JS here. HandleScope handle_scope(env()->isolate()); + BaseObjectPtr<StreamPipe> strong_ref{this}; env()->SetImmediate([this](Environment* env) { HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -105,7 +106,7 @@ void StreamPipe::Unpipe() { .IsNothing()) { return; } - }, object()); + }); } uv_buf_t StreamPipe::ReadableListener::OnStreamAlloc(size_t suggested_size) { @@ -119,7 +120,6 @@ void StreamPipe::ReadableListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf_) { StreamPipe* pipe = ContainerOf(&StreamPipe::readable_listener_, this); AllocatedBuffer buf(pipe->env(), buf_); - AsyncScope async_scope(pipe); if (nread < 0) { // EOF or error; stop reading and pass the error to the previous listener // (which might end up in JS). @@ -162,7 +162,9 @@ void StreamPipe::WritableListener::OnStreamAfterWrite(WriteWrap* w, StreamPipe* pipe = ContainerOf(&StreamPipe::writable_listener_, this); pipe->is_writing_ = false; if (pipe->is_eof_) { - AsyncScope async_scope(pipe); + HandleScope handle_scope(pipe->env()->isolate()); + InternalCallbackScope callback_scope(pipe, + InternalCallbackScope::kSkipTaskQueues); pipe->ShutdownWritable(); pipe->Unpipe(); return; @@ -206,7 +208,9 @@ void StreamPipe::WritableListener::OnStreamWantsWrite(size_t suggested_size) { pipe->wanted_data_ = suggested_size; if (pipe->is_reading_ || pipe->is_closed_) return; - AsyncScope async_scope(pipe); + HandleScope handle_scope(pipe->env()->isolate()); + InternalCallbackScope callback_scope(pipe, + InternalCallbackScope::kSkipTaskQueues); pipe->is_reading_ = true; pipe->source()->ReadStart(); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 1ec8386fbbb534..21b775401e4571 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -78,7 +78,7 @@ void LibuvStreamWrap::Initialize(Local<Object> target, // - callback // - handle sw->InstanceTemplate()->Set( - FIXED_ONE_BYTE_STRING(env->isolate(), "oncomplete"), + env->oncomplete_string(), v8::Null(env->isolate())); sw->InstanceTemplate()->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "callback"), v8::Null(env->isolate())); diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 2d36c1a2654aa6..4ec6dda6df70d7 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -316,9 +316,10 @@ void TLSWrap::EncOut() { // its not clear if it is always correct. Not calling Done() could block // data flow, so for now continue to call Done(), just do it in the next // tick. - env()->SetImmediate([this](Environment* env) { + BaseObjectPtr<TLSWrap> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment* env) { InvokeQueued(0); - }, object()); + }); } } return; @@ -349,9 +350,10 @@ void TLSWrap::EncOut() { HandleScope handle_scope(env()->isolate()); // Simulate asynchronous finishing, TLS cannot handle this at the moment. - env()->SetImmediate([this](Environment* env) { + BaseObjectPtr<TLSWrap> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment* env) { OnStreamAfterWrite(nullptr, 0); - }, object()); + }); } } @@ -718,9 +720,10 @@ int TLSWrap::DoWrite(WriteWrap* w, StreamWriteResult res = underlying_stream()->Write(bufs, count, send_handle); if (!res.async) { - env()->SetImmediate([this](Environment* env) { + BaseObjectPtr<TLSWrap> strong_ref{this}; + env()->SetImmediate([this, strong_ref](Environment* env) { OnStreamAfterWrite(current_empty_write_, 0); - }, object()); + }); } return 0; } @@ -1141,12 +1144,11 @@ void TLSWrap::Initialize(Local<Object> target, env->SetProtoMethod(t, "getServername", GetServername); env->SetProtoMethod(t, "setServername", SetServername); - env->set_tls_wrap_constructor_function( - t->GetFunction(env->context()).ToLocalChecked()); + Local<Function> fn = t->GetFunction(env->context()).ToLocalChecked(); + + env->set_tls_wrap_constructor_function(fn); - target->Set(env->context(), - tlsWrapString, - t->GetFunction(env->context()).ToLocalChecked()).Check(); + target->Set(env->context(), tlsWrapString, fn).Check(); } } // namespace node diff --git a/src/util-inl.h b/src/util-inl.h index c06a0ae84c88f5..d44ee09fefbb3a 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -514,7 +514,7 @@ void ArrayBufferViewContents<T, S>::Read(v8::Local<v8::ArrayBufferView> abv) { static_assert(sizeof(T) == 1, "Only supports one-byte data at the moment"); length_ = abv->ByteLength(); if (length_ > sizeof(stack_storage_) || abv->HasBuffer()) { - data_ = static_cast<T*>(abv->Buffer()->GetContents().Data()) + + data_ = static_cast<T*>(abv->Buffer()->GetBackingStore()->Data()) + abv->ByteOffset(); } else { abv->CopyContents(stack_storage_, sizeof(stack_storage_)); diff --git a/src/util.h b/src/util.h index c8bb44721f6250..2f6c17fc321a67 100644 --- a/src/util.h +++ b/src/util.h @@ -42,6 +42,12 @@ #include <unordered_map> #include <utility> +#ifdef __GNUC__ +#define MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define MUST_USE_RESULT +#endif + namespace node { // Maybe remove kPathSeparator when cpp17 is ready @@ -482,11 +488,12 @@ class BufferValue : public MaybeStackBuffer<char> { #define SPREAD_BUFFER_ARG(val, name) \ CHECK((val)->IsArrayBufferView()); \ v8::Local<v8::ArrayBufferView> name = (val).As<v8::ArrayBufferView>(); \ - v8::ArrayBuffer::Contents name##_c = name->Buffer()->GetContents(); \ + std::shared_ptr<v8::BackingStore> name##_bs = \ + name->Buffer()->GetBackingStore(); \ const size_t name##_offset = name->ByteOffset(); \ const size_t name##_length = name->ByteLength(); \ char* const name##_data = \ - static_cast<char*>(name##_c.Data()) + name##_offset; \ + static_cast<char*>(name##_bs->Data()) + name##_offset; \ if (name##_length > 0) \ CHECK_NE(name##_data, nullptr); @@ -494,14 +501,37 @@ class BufferValue : public MaybeStackBuffer<char> { // silence a compiler warning about that. template <typename T> inline void USE(T&&) {} -// Run a function when exiting the current scope. -struct OnScopeLeave { - std::function<void()> fn_; +template <typename Fn> +struct OnScopeLeaveImpl { + Fn fn_; + bool active_; + + explicit OnScopeLeaveImpl(Fn&& fn) : fn_(std::move(fn)), active_(true) {} + ~OnScopeLeaveImpl() { if (active_) fn_(); } - explicit OnScopeLeave(std::function<void()> fn) : fn_(std::move(fn)) {} - ~OnScopeLeave() { fn_(); } + OnScopeLeaveImpl(const OnScopeLeaveImpl& other) = delete; + OnScopeLeaveImpl& operator=(const OnScopeLeaveImpl& other) = delete; + OnScopeLeaveImpl(OnScopeLeaveImpl&& other) + : fn_(std::move(other.fn_)), active_(other.active_) { + other.active_ = false; + } + OnScopeLeaveImpl& operator=(OnScopeLeaveImpl&& other) { + if (this == &other) return *this; + this->~OnScopeLeave(); + new (this)OnScopeLeaveImpl(std::move(other)); + return *this; + } }; +// Run a function when exiting the current scope. Used like this: +// auto on_scope_leave = OnScopeLeave([&] { +// // ... run some code ... +// }); +template <typename Fn> +inline MUST_USE_RESULT OnScopeLeaveImpl<Fn> OnScopeLeave(Fn&& fn) { + return OnScopeLeaveImpl<Fn>{std::move(fn)}; +} + // Simple RAII wrapper for contiguous data that uses malloc()/free(). template <typename T> struct MallocedBuffer { @@ -679,12 +709,6 @@ constexpr T RoundUp(T a, T b) { return a % b != 0 ? a + b - (a % b) : a; } -#ifdef __GNUC__ -#define MUST_USE_RESULT __attribute__((warn_unused_result)) -#else -#define MUST_USE_RESULT -#endif - class SlicedArguments : public MaybeStackBuffer<v8::Local<v8::Value>> { public: inline explicit SlicedArguments( diff --git a/src/v8abbr.h b/src/v8abbr.h index 247094c408b3cc..d376f6b1d82ea8 100644 --- a/src/v8abbr.h +++ b/src/v8abbr.h @@ -91,7 +91,8 @@ V8_OFF_HEAP( \ V8DBG_CLASS_SHAREDFUNCTIONINFO__NAME_OR_SCOPE_INFO__OBJECT) #define V8_OFF_SHARED_SCRIPT \ - V8_OFF_HEAP(V8DBG_CLASS_SHAREDFUNCTIONINFO__SCRIPT_OR_DEBUG_INFO__OBJECT) + V8_OFF_HEAP( \ + V8DBG_CLASS_SHAREDFUNCTIONINFO__SCRIPT_OR_DEBUG_INFO__HEAPOBJECT) #define V8_OFF_SHARED_FUNIDENT \ V8_OFF_HEAP( \ V8DBG_CLASS_SHAREDFUNCTIONINFO__NAME_OR_SCOPE_INFO__OBJECT) diff --git a/test/addons/at-exit/binding.cc b/test/addons/at-exit/binding.cc deleted file mode 100644 index 3a27bcd7c30756..00000000000000 --- a/test/addons/at-exit/binding.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include <assert.h> -#include <stdlib.h> -#include <node.h> -#include <v8.h> - -using node::AtExit; -using v8::HandleScope; -using v8::Isolate; -using v8::Local; -using v8::Object; - -#if defined(_MSC_VER) -#pragma section(".CRT$XPU", read) -#define NODE_C_DTOR(fn) \ - NODE_CTOR_PREFIX void __cdecl fn(void); \ - __declspec(dllexport, allocate(".CRT$XPU")) \ - void (__cdecl*fn ## _)(void) = fn; \ - NODE_CTOR_PREFIX void __cdecl fn(void) -#else -#define NODE_C_DTOR(fn) \ - NODE_CTOR_PREFIX void fn(void) __attribute__((destructor)); \ - NODE_CTOR_PREFIX void fn(void) -#endif - -static char cookie[] = "yum yum"; -static int at_exit_cb1_called = 0; -static int at_exit_cb2_called = 0; - -static void at_exit_cb1(void* arg) { - Isolate* isolate = static_cast<Isolate*>(arg); - HandleScope handle_scope(isolate); - Local<Object> obj = Object::New(isolate); - assert(!obj.IsEmpty()); // Assert VM is still alive. - assert(obj->IsObject()); - at_exit_cb1_called++; -} - -static void at_exit_cb2(void* arg) { - assert(arg == static_cast<void*>(cookie)); - at_exit_cb2_called++; -} - -NODE_C_DTOR(sanity_check) { - assert(at_exit_cb1_called == 1); - assert(at_exit_cb2_called == 2); -} - -void init(Local<Object> exports) { - AtExit(at_exit_cb1, exports->GetIsolate()); - AtExit(at_exit_cb2, cookie); - AtExit(at_exit_cb2, cookie); -} - -NODE_MODULE(NODE_GYP_MODULE_NAME, init) diff --git a/test/addons/at-exit/test.js b/test/addons/at-exit/test.js deleted file mode 100644 index 4e2ca810f01c87..00000000000000 --- a/test/addons/at-exit/test.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; -const common = require('../../common'); -require(`./build/${common.buildType}/binding`); diff --git a/test/addons/dlopen-ping-pong/test-worker.js b/test/addons/dlopen-ping-pong/test-worker.js index feba6aa5eb0202..d24bd2df8050f2 100644 --- a/test/addons/dlopen-ping-pong/test-worker.js +++ b/test/addons/dlopen-ping-pong/test-worker.js @@ -16,5 +16,6 @@ require(bindingPath); new Worker(`require(${JSON.stringify(bindingPath)})`, { eval: true }) .on('error', common.mustCall((err) => { assert.strictEqual(err.constructor, Error); - assert.strictEqual(err.message, 'Module did not self-register.'); + assert.strictEqual(err.message, + `Module did not self-register: '${bindingPath}'.`); })); diff --git a/test/addons/dlopen-ping-pong/test.js b/test/addons/dlopen-ping-pong/test.js index c5b8c16493f60f..c3461d8bd269c5 100644 --- a/test/addons/dlopen-ping-pong/test.js +++ b/test/addons/dlopen-ping-pong/test.js @@ -19,5 +19,5 @@ assert.strictEqual(module.exports.ping(), 'pong'); // Check that after the addon is loaded with // process.dlopen() a require() call fails. console.log('require:', `./build/${common.buildType}/binding`); -const re = /^Error: Module did not self-register\.$/; +const re = /^Error: Module did not self-register: '.*[\\/]binding\.node'\.$/; assert.throws(() => require(`./build/${common.buildType}/binding`), re); diff --git a/test/addons/not-a-binding/test.js b/test/addons/not-a-binding/test.js index a0ce2d0629ac1d..4b4e7150ebbca2 100644 --- a/test/addons/not-a-binding/test.js +++ b/test/addons/not-a-binding/test.js @@ -2,5 +2,5 @@ const common = require('../../common'); const assert = require('assert'); -const re = /^Error: Module did not self-register\.$/; +const re = /^Error: Module did not self-register: '.*[\\/]binding\.node'\.$/; assert.throws(() => require(`./build/${common.buildType}/binding`), re); diff --git a/test/addons/openssl-binding/binding.cc b/test/addons/openssl-binding/binding.cc index ecda40f4cb50a3..6cfecc4505421e 100644 --- a/test/addons/openssl-binding/binding.cc +++ b/test/addons/openssl-binding/binding.cc @@ -12,8 +12,8 @@ inline void RandomBytes(const v8::FunctionCallbackInfo<v8::Value>& info) { auto byte_length = view->ByteLength(); assert(view->HasBuffer()); auto buffer = view->Buffer(); - auto contents = buffer->GetContents(); - auto data = static_cast<unsigned char*>(contents.Data()) + byte_offset; + auto contents = buffer->GetBackingStore(); + auto data = static_cast<unsigned char*>(contents->Data()) + byte_offset; assert(RAND_poll()); auto rval = RAND_bytes(data, static_cast<int>(byte_length)); info.GetReturnValue().Set(rval > 0); diff --git a/test/addons/worker-buffer-callback/binding.cc b/test/addons/worker-buffer-callback/binding.cc new file mode 100644 index 00000000000000..a40876ebb523a6 --- /dev/null +++ b/test/addons/worker-buffer-callback/binding.cc @@ -0,0 +1,29 @@ +#include <node.h> +#include <node_buffer.h> +#include <v8.h> + +using v8::Context; +using v8::Isolate; +using v8::Local; +using v8::Object; +using v8::Value; + +char data[] = "hello"; + +void Initialize(Local<Object> exports, + Local<Value> module, + Local<Context> context) { + Isolate* isolate = context->GetIsolate(); + exports->Set(context, + v8::String::NewFromUtf8( + isolate, "buffer", v8::NewStringType::kNormal) + .ToLocalChecked(), + node::Buffer::New( + isolate, + data, + sizeof(data), + [](char* data, void* hint) {}, + nullptr).ToLocalChecked()).Check(); +} + +NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME, Initialize) diff --git a/test/addons/at-exit/binding.gyp b/test/addons/worker-buffer-callback/binding.gyp similarity index 100% rename from test/addons/at-exit/binding.gyp rename to test/addons/worker-buffer-callback/binding.gyp diff --git a/test/addons/worker-buffer-callback/test.js b/test/addons/worker-buffer-callback/test.js new file mode 100644 index 00000000000000..b04984f1576432 --- /dev/null +++ b/test/addons/worker-buffer-callback/test.js @@ -0,0 +1,15 @@ +'use strict'; +const common = require('../../common'); +const assert = require('assert'); +const { MessageChannel } = require('worker_threads'); +const { buffer } = require(`./build/${common.buildType}/binding`); + +// Test that buffers allocated with a free callback through our APIs are not +// transfered. + +const { port1 } = new MessageChannel(); +const origByteLength = buffer.byteLength; +port1.postMessage(buffer, [buffer.buffer]); + +assert.strictEqual(buffer.byteLength, origByteLength); +assert.notStrictEqual(buffer.byteLength, 0); diff --git a/test/addons/zlib-binding/binding.cc b/test/addons/zlib-binding/binding.cc index 0b82de211a8430..abfb0615842594 100644 --- a/test/addons/zlib-binding/binding.cc +++ b/test/addons/zlib-binding/binding.cc @@ -12,8 +12,8 @@ inline void CompressBytes(const v8::FunctionCallbackInfo<v8::Value>& info) { auto byte_length = view->ByteLength(); assert(view->HasBuffer()); auto buffer = view->Buffer(); - auto contents = buffer->GetContents(); - auto data = static_cast<unsigned char*>(contents.Data()) + byte_offset; + auto contents = buffer->GetBackingStore(); + auto data = static_cast<unsigned char*>(contents->Data()) + byte_offset; Bytef buf[1024]; diff --git a/test/benchmark/test-benchmark-cluster.js b/test/benchmark/test-benchmark-cluster.js index d6e3b27ee89f81..26df7ec239a221 100644 --- a/test/benchmark/test-benchmark-cluster.js +++ b/test/benchmark/test-benchmark-cluster.js @@ -4,4 +4,9 @@ require('../common'); const runBenchmark = require('../common/benchmark'); -runBenchmark('cluster', ['n=1', 'payload=string', 'sendsPerBroadcast=1']); +runBenchmark('cluster', [ + 'n=1', + 'payload=string', + 'sendsPerBroadcast=1', + 'serialization=json', +]); diff --git a/test/cctest/node_test_fixture.h b/test/cctest/node_test_fixture.h index f6b80c860c1f58..ac0701d0942666 100644 --- a/test/cctest/node_test_fixture.h +++ b/test/cctest/node_test_fixture.h @@ -105,9 +105,9 @@ class NodeTestFixture : public ::testing::Test { } void TearDown() override { + platform->DrainTasks(isolate_); isolate_->Exit(); isolate_->Dispose(); - platform->DrainTasks(isolate_); platform->UnregisterIsolate(isolate_); isolate_ = nullptr; } diff --git a/test/cctest/test_base_object_ptr.cc b/test/cctest/test_base_object_ptr.cc new file mode 100644 index 00000000000000..18e27edba8cd53 --- /dev/null +++ b/test/cctest/test_base_object_ptr.cc @@ -0,0 +1,176 @@ +#include "gtest/gtest.h" +#include "node.h" +#include "base_object-inl.h" +#include "node_test_fixture.h" + +using node::BaseObject; +using node::BaseObjectPtr; +using node::BaseObjectWeakPtr; +using node::Environment; +using node::MakeBaseObject; +using node::MakeDetachedBaseObject; +using v8::HandleScope; +using v8::Isolate; +using v8::Local; +using v8::Object; + +class BaseObjectPtrTest : public EnvironmentTestFixture {}; + +class DummyBaseObject : public BaseObject { + public: + DummyBaseObject(Environment* env, Local<Object> obj) : BaseObject(env, obj) {} + + static Local<Object> MakeJSObject(Environment* env) { + return BaseObject::MakeLazilyInitializedJSTemplate(env) + ->GetFunction(env->context()).ToLocalChecked() + ->NewInstance(env->context()).ToLocalChecked(); + } + + static BaseObjectPtr<DummyBaseObject> NewDetached(Environment* env) { + Local<Object> obj = MakeJSObject(env); + return MakeDetachedBaseObject<DummyBaseObject>(env, obj); + } + + static BaseObjectPtr<DummyBaseObject> New(Environment* env) { + Local<Object> obj = MakeJSObject(env); + return MakeBaseObject<DummyBaseObject>(env, obj); + } + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(DummyBaseObject) + SET_SELF_SIZE(DummyBaseObject) +}; + +TEST_F(BaseObjectPtrTest, ScopedDetached) { + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + EXPECT_EQ(env->base_object_count(), 0); + { + BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); + EXPECT_EQ(env->base_object_count(), 1); + } + EXPECT_EQ(env->base_object_count(), 0); +} + +TEST_F(BaseObjectPtrTest, ScopedDetachedWithWeak) { + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + BaseObjectWeakPtr<DummyBaseObject> weak_ptr; + + EXPECT_EQ(env->base_object_count(), 0); + { + BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); + weak_ptr = ptr; + EXPECT_EQ(env->base_object_count(), 1); + } + EXPECT_EQ(weak_ptr.get(), nullptr); + EXPECT_EQ(env->base_object_count(), 0); +} + +TEST_F(BaseObjectPtrTest, Undetached) { + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + node::AddEnvironmentCleanupHook(isolate_, [](void* arg) { + EXPECT_EQ(static_cast<Environment*>(arg)->base_object_count(), 0); + }, env); + + BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::New(env); + EXPECT_EQ(env->base_object_count(), 1); +} + +TEST_F(BaseObjectPtrTest, GCWeak) { + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + BaseObjectWeakPtr<DummyBaseObject> weak_ptr; + + { + const HandleScope handle_scope(isolate_); + BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::New(env); + weak_ptr = ptr; + ptr->MakeWeak(); + + EXPECT_EQ(env->base_object_count(), 1); + EXPECT_EQ(weak_ptr.get(), ptr.get()); + EXPECT_EQ(weak_ptr->persistent().IsWeak(), false); + + ptr.reset(); + } + + EXPECT_EQ(env->base_object_count(), 1); + EXPECT_NE(weak_ptr.get(), nullptr); + EXPECT_EQ(weak_ptr->persistent().IsWeak(), true); + + v8::V8::SetFlagsFromString("--expose-gc"); + isolate_->RequestGarbageCollectionForTesting(Isolate::kFullGarbageCollection); + + EXPECT_EQ(env->base_object_count(), 0); + EXPECT_EQ(weak_ptr.get(), nullptr); +} + +TEST_F(BaseObjectPtrTest, Moveable) { + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + BaseObjectPtr<DummyBaseObject> ptr = DummyBaseObject::NewDetached(env); + EXPECT_EQ(env->base_object_count(), 1); + BaseObjectWeakPtr<DummyBaseObject> weak_ptr { ptr }; + EXPECT_EQ(weak_ptr.get(), ptr.get()); + + BaseObjectPtr<DummyBaseObject> ptr2 = std::move(ptr); + EXPECT_EQ(weak_ptr.get(), ptr2.get()); + EXPECT_EQ(ptr.get(), nullptr); + + BaseObjectWeakPtr<DummyBaseObject> weak_ptr2 = std::move(weak_ptr); + EXPECT_EQ(weak_ptr2.get(), ptr2.get()); + EXPECT_EQ(weak_ptr.get(), nullptr); + EXPECT_EQ(env->base_object_count(), 1); + + ptr2.reset(); + + EXPECT_EQ(weak_ptr2.get(), nullptr); + EXPECT_EQ(env->base_object_count(), 0); +} + +TEST_F(BaseObjectPtrTest, NestedClasses) { + class ObjectWithPtr : public BaseObject { + public: + ObjectWithPtr(Environment* env, Local<Object> obj) : BaseObject(env, obj) {} + + BaseObjectPtr<BaseObject> ptr1; + BaseObjectPtr<BaseObject> ptr2; + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(ObjectWithPtr) + SET_SELF_SIZE(ObjectWithPtr) + }; + + const HandleScope handle_scope(isolate_); + const Argv argv; + Env env_{handle_scope, argv}; + Environment* env = *env_; + + node::AddEnvironmentCleanupHook(isolate_, [](void* arg) { + EXPECT_EQ(static_cast<Environment*>(arg)->base_object_count(), 0); + }, env); + + ObjectWithPtr* obj = + new ObjectWithPtr(env, DummyBaseObject::MakeJSObject(env)); + obj->ptr1 = DummyBaseObject::NewDetached(env); + obj->ptr2 = DummyBaseObject::New(env); + + EXPECT_EQ(env->base_object_count(), 3); +} diff --git a/test/cctest/test_environment.cc b/test/cctest/test_environment.cc index aabaeb985bf322..cc9b8e4531f6ef 100644 --- a/test/cctest/test_environment.cc +++ b/test/cctest/test_environment.cc @@ -10,8 +10,14 @@ using node::RunAtExit; static bool called_cb_1 = false; static bool called_cb_2 = false; +static bool called_cb_ordered_1 = false; +static bool called_cb_ordered_2 = false; +static bool called_at_exit_js = false; static void at_exit_callback1(void* arg); static void at_exit_callback2(void* arg); +static void at_exit_callback_ordered1(void* arg); +static void at_exit_callback_ordered2(void* arg); +static void at_exit_js(void* arg); static std::string cb_1_arg; // NOLINT(runtime/string) class EnvironmentTest : public EnvironmentTestFixture { @@ -20,6 +26,8 @@ class EnvironmentTest : public EnvironmentTestFixture { NodeTestFixture::TearDown(); called_cb_1 = false; called_cb_2 = false; + called_cb_ordered_1 = false; + called_cb_ordered_2 = false; } }; @@ -61,6 +69,19 @@ TEST_F(EnvironmentTest, AtExitWithoutEnvironment) { EXPECT_TRUE(called_cb_1); } +TEST_F(EnvironmentTest, AtExitOrder) { + const v8::HandleScope handle_scope(isolate_); + const Argv argv; + Env env {handle_scope, argv}; + + // Test that callbacks are run in reverse order. + AtExit(*env, at_exit_callback_ordered1); + AtExit(*env, at_exit_callback_ordered2); + RunAtExit(*env); + EXPECT_TRUE(called_cb_ordered_1); + EXPECT_TRUE(called_cb_ordered_2); +} + TEST_F(EnvironmentTest, AtExitWithArgument) { const v8::HandleScope handle_scope(isolate_); const Argv argv; @@ -72,6 +93,17 @@ TEST_F(EnvironmentTest, AtExitWithArgument) { EXPECT_EQ(arg, cb_1_arg); } +TEST_F(EnvironmentTest, AtExitRunsJS) { + const v8::HandleScope handle_scope(isolate_); + const Argv argv; + Env env {handle_scope, argv}; + + AtExit(*env, at_exit_js, static_cast<void*>(isolate_)); + EXPECT_FALSE(called_at_exit_js); + RunAtExit(*env); + EXPECT_TRUE(called_at_exit_js); +} + TEST_F(EnvironmentTest, MultipleEnvironmentsPerIsolate) { const v8::HandleScope handle_scope(isolate_); const Argv argv; @@ -134,3 +166,22 @@ static void at_exit_callback1(void* arg) { static void at_exit_callback2(void* arg) { called_cb_2 = true; } + +static void at_exit_callback_ordered1(void* arg) { + EXPECT_TRUE(called_cb_ordered_2); + called_cb_ordered_1 = true; +} + +static void at_exit_callback_ordered2(void* arg) { + EXPECT_FALSE(called_cb_ordered_1); + called_cb_ordered_2 = true; +} + +static void at_exit_js(void* arg) { + v8::Isolate* isolate = static_cast<v8::Isolate*>(arg); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Object> obj = v8::Object::New(isolate); + assert(!obj.IsEmpty()); // Assert VM is still alive. + assert(obj->IsObject()); + called_at_exit_js = true; +} diff --git a/test/cctest/test_linked_binding.cc b/test/cctest/test_linked_binding.cc index 90688655527211..6724402c55aef1 100644 --- a/test/cctest/test_linked_binding.cc +++ b/test/cctest/test_linked_binding.cc @@ -41,3 +41,45 @@ TEST_F(LinkedBindingTest, SimpleTest) { CHECK_NOT_NULL(*utf8val); CHECK_EQ(strcmp(*utf8val, "value"), 0); } + +void InitializeLocalBinding(v8::Local<v8::Object> exports, + v8::Local<v8::Value> module, + v8::Local<v8::Context> context, + void* priv) { + ++*static_cast<int*>(priv); + v8::Isolate* isolate = context->GetIsolate(); + exports->Set( + context, + v8::String::NewFromOneByte(isolate, + reinterpret_cast<const uint8_t*>("key"), + v8::NewStringType::kNormal).ToLocalChecked(), + v8::String::NewFromOneByte(isolate, + reinterpret_cast<const uint8_t*>("value"), + v8::NewStringType::kNormal).ToLocalChecked()) + .FromJust(); +} + +TEST_F(LinkedBindingTest, LocallyDefinedLinkedBindingTest) { + const v8::HandleScope handle_scope(isolate_); + const Argv argv; + Env test_env {handle_scope, argv}; + + int calls = 0; + AddLinkedBinding(*test_env, "local_linked", InitializeLocalBinding, &calls); + + v8::Local<v8::Context> context = isolate_->GetCurrentContext(); + + const char* run_script = + "process._linkedBinding('local_linked').key"; + v8::Local<v8::Script> script = v8::Script::Compile( + context, + v8::String::NewFromOneByte(isolate_, + reinterpret_cast<const uint8_t*>(run_script), + v8::NewStringType::kNormal).ToLocalChecked()) + .ToLocalChecked(); + v8::Local<v8::Value> completion_value = script->Run(context).ToLocalChecked(); + v8::String::Utf8Value utf8val(isolate_, completion_value); + CHECK_NOT_NULL(*utf8val); + CHECK_EQ(strcmp(*utf8val, "value"), 0); + CHECK_EQ(calls, 1); +} diff --git a/test/cctest/test_node_postmortem_metadata.cc b/test/cctest/test_node_postmortem_metadata.cc index f33d40eb5c23fe..3fb67ecbca265e 100644 --- a/test/cctest/test_node_postmortem_metadata.cc +++ b/test/cctest/test_node_postmortem_metadata.cc @@ -93,14 +93,13 @@ TEST_F(DebugSymbolsTest, BaseObjectPersistentHandle) { v8::Local<v8::Object> object = obj_templ->NewInstance(env.context()).ToLocalChecked(); - DummyBaseObject obj(*env, object); + node::BaseObjectPtr<DummyBaseObject> obj = + node::MakeDetachedBaseObject<DummyBaseObject>(*env, object); - auto expected = reinterpret_cast<uintptr_t>(&obj.persistent()); - auto calculated = reinterpret_cast<uintptr_t>(&obj) + + auto expected = reinterpret_cast<uintptr_t>(&obj->persistent()); + auto calculated = reinterpret_cast<uintptr_t>(obj.get()) + nodedbg_offset_BaseObject__persistent_handle___v8_Persistent_v8_Object; EXPECT_EQ(expected, calculated); - - obj.persistent().Reset(); // ~BaseObject() expects an empty handle. } diff --git a/test/common/index.js b/test/common/index.js index 98a26872223cb9..888a1feba37462 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -118,8 +118,9 @@ const enoughTestCpu = Array.isArray(cpus) && const rootDir = isWindows ? 'c:\\' : '/'; -const buildType = process.config.target_defaults.default_configuration; - +const buildType = process.config.target_defaults ? + process.config.target_defaults.default_configuration : + 'Release'; // If env var is set then enable async_hook hooks for all tests. if (process.env.NODE_TEST_WITH_ASYNC_HOOKS) { diff --git a/test/common/index.mjs b/test/common/index.mjs index f747ee327913a5..5ad6ec3c11eadc 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules /* eslint-disable node-core/require-common-first, node-core/required-modules */ import { createRequire } from 'module'; diff --git a/test/internet/test-doctool-versions.js b/test/doctool/test-doctool-versions.js similarity index 100% rename from test/internet/test-doctool-versions.js rename to test/doctool/test-doctool-versions.js diff --git a/test/es-module/test-cjs-esm-warn.js b/test/es-module/test-cjs-esm-warn.js index ec368c73e2ef2d..b1b2e7f434256f 100644 --- a/test/es-module/test-cjs-esm-warn.js +++ b/test/es-module/test-cjs-esm-warn.js @@ -23,10 +23,10 @@ child.stderr.on('data', (data) => { stderr += data; }); child.on('close', common.mustCall((code, signal) => { - assert.strictEqual(code, 0); + assert.strictEqual(code, 1); assert.strictEqual(signal, null); - assert.strictEqual(stderr, `(node:${child.pid}) Warning: ` + + assert.ok(stderr.startsWith(`(node:${child.pid}) Warning: ` + 'require() of ES modules is not supported.\nrequire() of ' + `${required} from ${requiring} ` + 'is an ES module file as it is a .js file whose nearest parent ' + @@ -34,5 +34,7 @@ child.on('close', common.mustCall((code, signal) => { 'files in that package scope as ES modules.\nInstead rename ' + `${basename} to end in .cjs, change the requiring code to use ` + 'import(), or remove "type": "module" from ' + - `${pjson}.\n`); + `${pjson}.\n`)); + assert.ok(stderr.indexOf( + 'Error [ERR_REQUIRE_ESM]: Must use import to load ES Module') !== -1); })); diff --git a/test/es-module/test-esm-basic-imports.mjs b/test/es-module/test-esm-basic-imports.mjs index c21804d78b292b..5009fbadb39657 100644 --- a/test/es-module/test-esm-basic-imports.mjs +++ b/test/es-module/test-esm-basic-imports.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-cjs-load-error-note.mjs b/test/es-module/test-esm-cjs-load-error-note.mjs index ce0d1d796969d7..c0ac9393a8ddd5 100644 --- a/test/es-module/test-esm-cjs-load-error-note.mjs +++ b/test/es-module/test-esm-cjs-load-error-note.mjs @@ -1,5 +1,3 @@ -// Flags: --experimental-modules - import { mustCall } from '../common/index.mjs'; import assert from 'assert'; import fixtures from '../common/fixtures.js'; @@ -20,7 +18,7 @@ const expectedNote = 'To load an ES module, ' + const expectedCode = 1; -const pExport1 = spawn(process.execPath, ['--experimental-modules', Export1]); +const pExport1 = spawn(process.execPath, [Export1]); let pExport1Stderr = ''; pExport1.stderr.setEncoding('utf8'); pExport1.stderr.on('data', (data) => { @@ -33,7 +31,7 @@ pExport1.on('close', mustCall((code) => { })); -const pExport2 = spawn(process.execPath, ['--experimental-modules', Export2]); +const pExport2 = spawn(process.execPath, [Export2]); let pExport2Stderr = ''; pExport2.stderr.setEncoding('utf8'); pExport2.stderr.on('data', (data) => { @@ -44,21 +42,8 @@ pExport2.on('close', mustCall((code) => { assert.ok(pExport2Stderr.includes(expectedNote), `${expectedNote} not found in ${pExport2Stderr}`); })); -// The flag --experimental-modules is not used here -// the note must not be included in the output -const pExport3 = spawn(process.execPath, [Export1]); -let pExport3Stderr = ''; -pExport3.stderr.setEncoding('utf8'); -pExport3.stderr.on('data', (data) => { - pExport3Stderr += data; -}); -pExport3.on('close', mustCall((code) => { - assert.strictEqual(code, expectedCode); - assert.ok(!pExport3Stderr.includes(expectedNote), - `${expectedNote} must not be included in ${pExport3Stderr}`); -})); -const pImport1 = spawn(process.execPath, ['--experimental-modules', Import1]); +const pImport1 = spawn(process.execPath, [Import1]); let pImport1Stderr = ''; pImport1.stderr.setEncoding('utf8'); pImport1.stderr.on('data', (data) => { @@ -71,7 +56,7 @@ pImport1.on('close', mustCall((code) => { })); // Note this test shouldn't include the note -const pImport2 = spawn(process.execPath, ['--experimental-modules', Import2]); +const pImport2 = spawn(process.execPath, [Import2]); let pImport2Stderr = ''; pImport2.stderr.setEncoding('utf8'); pImport2.stderr.on('data', (data) => { @@ -84,7 +69,7 @@ pImport2.on('close', mustCall((code) => { `${expectedNote} must not be included in ${pImport2Stderr}`); })); -const pImport3 = spawn(process.execPath, ['--experimental-modules', Import3]); +const pImport3 = spawn(process.execPath, [Import3]); let pImport3Stderr = ''; pImport3.stderr.setEncoding('utf8'); pImport3.stderr.on('data', (data) => { @@ -97,7 +82,7 @@ pImport3.on('close', mustCall((code) => { })); -const pImport4 = spawn(process.execPath, ['--experimental-modules', Import4]); +const pImport4 = spawn(process.execPath, [Import4]); let pImport4Stderr = ''; pImport4.stderr.setEncoding('utf8'); pImport4.stderr.on('data', (data) => { @@ -110,7 +95,7 @@ pImport4.on('close', mustCall((code) => { })); // Must exit with zero and show note -const pImport5 = spawn(process.execPath, ['--experimental-modules', Import5]); +const pImport5 = spawn(process.execPath, [Import5]); let pImport5Stderr = ''; pImport5.stderr.setEncoding('utf8'); pImport5.stderr.on('data', (data) => { @@ -121,16 +106,3 @@ pImport5.on('close', mustCall((code) => { assert.ok(!pImport5Stderr.includes(expectedNote), `${expectedNote} must not be included in ${pImport5Stderr}`); })); - -// Must exit with zero and not show note -const pImport6 = spawn(process.execPath, [Import1]); -let pImport6Stderr = ''; -pImport6.stderr.setEncoding('utf8'); -pImport6.stderr.on('data', (data) => { - pImport6Stderr += data; -}); -pImport6.on('close', mustCall((code) => { - assert.strictEqual(code, expectedCode); - assert.ok(!pImport6Stderr.includes(expectedNote), - `${expectedNote} must not be included in ${pImport6Stderr}`); -})); diff --git a/test/es-module/test-esm-cjs-main.js b/test/es-module/test-esm-cjs-main.js index 8308308a2dce72..92f4124ccaab8a 100644 --- a/test/es-module/test-esm-cjs-main.js +++ b/test/es-module/test-esm-cjs-main.js @@ -7,12 +7,8 @@ const assert = require('assert'); const entry = fixtures.path('/es-modules/cjs.js'); -const child = spawn(process.execPath, ['--experimental-modules', entry]); -let stderr = ''; +const child = spawn(process.execPath, [entry]); child.stderr.setEncoding('utf8'); -child.stderr.on('data', (data) => { - stderr += data; -}); let stdout = ''; child.stdout.setEncoding('utf8'); child.stdout.on('data', (data) => { @@ -22,6 +18,4 @@ child.on('close', common.mustCall((code, signal) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); assert.strictEqual(stdout, 'executed\n'); - assert.strictEqual(stderr, `(node:${child.pid}) ` + - 'ExperimentalWarning: The ESM module loader is experimental.\n'); })); diff --git a/test/es-module/test-esm-cyclic-dynamic-import.mjs b/test/es-module/test-esm-cyclic-dynamic-import.mjs index 03d405baf3ce9c..6f831470b71853 100644 --- a/test/es-module/test-esm-cyclic-dynamic-import.mjs +++ b/test/es-module/test-esm-cyclic-dynamic-import.mjs @@ -1,3 +1,2 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import('./test-esm-cyclic-dynamic-import.mjs'); diff --git a/test/es-module/test-esm-data-urls.js b/test/es-module/test-esm-data-urls.js index bc781b0363cc44..f2f166b47ee3d8 100644 --- a/test/es-module/test-esm-data-urls.js +++ b/test/es-module/test-esm-data-urls.js @@ -1,4 +1,3 @@ -// Flags: --experimental-modules 'use strict'; const common = require('../common'); const assert = require('assert'); diff --git a/test/es-module/test-esm-default-type.mjs b/test/es-module/test-esm-default-type.mjs new file mode 100644 index 00000000000000..4b758df9166986 --- /dev/null +++ b/test/es-module/test-esm-default-type.mjs @@ -0,0 +1,7 @@ +import '../common/index.mjs'; +import { strictEqual } from 'assert'; + +import asdf from + '../fixtures/es-modules/package-type-module/nested-default-type/module.js'; + +strictEqual(asdf, 'asdf'); diff --git a/test/es-module/test-esm-double-encoding.mjs b/test/es-module/test-esm-double-encoding.mjs index 2edfc8add5d2db..e46249f128203c 100644 --- a/test/es-module/test-esm-double-encoding.mjs +++ b/test/es-module/test-esm-double-encoding.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; // Assert we can import files with `%` in their pathname. diff --git a/test/es-module/test-esm-dynamic-import.js b/test/es-module/test-esm-dynamic-import.js index ca9c99007b5b1b..8a92ac41edbdfd 100644 --- a/test/es-module/test-esm-dynamic-import.js +++ b/test/es-module/test-esm-dynamic-import.js @@ -1,5 +1,3 @@ -// Flags: --experimental-modules - 'use strict'; const common = require('../common'); const assert = require('assert'); diff --git a/test/es-module/test-esm-encoded-path-native.js b/test/es-module/test-esm-encoded-path-native.js index a3106742d9ee8e..b8f5719b6089ee 100644 --- a/test/es-module/test-esm-encoded-path-native.js +++ b/test/es-module/test-esm-encoded-path-native.js @@ -5,7 +5,7 @@ const assert = require('assert'); const { spawn } = require('child_process'); const native = fixtures.path('es-module-url/native.mjs'); -const child = spawn(process.execPath, ['--experimental-modules', native]); +const child = spawn(process.execPath, [native]); child.on('exit', (code) => { assert.strictEqual(code, 1); }); diff --git a/test/es-module/test-esm-encoded-path.mjs b/test/es-module/test-esm-encoded-path.mjs index efb681ef0b4dfe..351cb7eab887b4 100644 --- a/test/es-module/test-esm-encoded-path.mjs +++ b/test/es-module/test-esm-encoded-path.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; // ./test-esm-ok.mjs diff --git a/test/es-module/test-esm-error-cache.js b/test/es-module/test-esm-error-cache.js index 26e0d170ac2e1b..b13e793626876a 100644 --- a/test/es-module/test-esm-error-cache.js +++ b/test/es-module/test-esm-error-cache.js @@ -1,5 +1,3 @@ -// Flags: --experimental-modules - 'use strict'; require('../common'); diff --git a/test/es-module/test-esm-example-loader.js b/test/es-module/test-esm-example-loader.js index 0da1d34d2ad6fc..b85de4e64c4abc 100644 --- a/test/es-module/test-esm-example-loader.js +++ b/test/es-module/test-esm-example-loader.js @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/example-loader.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/example-loader.mjs /* eslint-disable node-core/require-common-first, node-core/required-modules */ import assert from 'assert'; import ok from '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-exports.mjs b/test/es-module/test-esm-exports.mjs index d8c33994188138..a361bafaa83804 100644 --- a/test/es-module/test-esm-exports.mjs +++ b/test/es-module/test-esm-exports.mjs @@ -1,5 +1,4 @@ -// Flags: --experimental-modules --experimental-resolve-self - +// Flags: --experimental-modules import { mustCall } from '../common/index.mjs'; import { ok, deepStrictEqual, strictEqual } from 'assert'; @@ -23,7 +22,16 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; ['pkgexports/fallbackfile', { default: 'asdf' }], // Dot main ['pkgexports', { default: 'asdf' }], + // Conditional split for require + ['pkgexports/condition', isRequire ? { default: 'encoded path' } : + { default: 'asdf' }], + // String exports sugar + ['pkgexports-sugar', { default: 'main' }], + // Conditional object exports sugar + ['pkgexports-sugar2', isRequire ? { default: 'not-exported' } : + { default: 'main' }] ]); + for (const [validSpecifier, expected] of validSpecifiers) { if (validSpecifier === null) continue; @@ -39,6 +47,9 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; // The file exists but isn't exported. The exports is a number which counts // as a non-null value without any properties, just like `{}`. ['pkgexports-number/hidden.js', './hidden.js'], + // Sugar cases still encapsulate + ['pkgexports-sugar/not-exported.js', './not-exported.js'], + ['pkgexports-sugar2/not-exported.js', './not-exported.js'] ]); const invalidExports = new Map([ @@ -79,7 +90,7 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; assertStartsWith(err.message, (isRequire ? 'Package exports' : 'Cannot resolve')); assertIncludes(err.message, isRequire ? - `do not define a valid '${subpath}' subpath` : + `do not define a valid '${subpath}' target` : `matched for '${subpath}'`); })); } @@ -93,11 +104,22 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; 'Cannot find module'); })); - // THe use of %2F escapes in paths fails loading + // The use of %2F escapes in paths fails loading loadFixture('pkgexports/sub/..%2F..%2Fbar.js').catch(mustCall((err) => { strictEqual(err.code, isRequire ? 'ERR_INVALID_FILE_URL_PATH' : 'ERR_MODULE_NOT_FOUND'); })); + + // Sugar conditional exports main mixed failure case + loadFixture('pkgexports-sugar-fail').catch(mustCall((err) => { + strictEqual(err.code, 'ERR_INVALID_PACKAGE_CONFIG'); + assertStartsWith(err.message, (isRequire ? 'Invalid package' : + 'Cannot resolve')); + assertIncludes(err.message, '"exports" cannot contain some keys starting ' + + 'with \'.\' and some not. The exports object must either be an object of ' + + 'package subpath keys or an object of main entry condition name keys ' + + 'only.'); + })); }); const { requireFromInside, importFromInside } = fromInside; @@ -124,6 +146,6 @@ function assertStartsWith(actual, expected) { } function assertIncludes(actual, expected) { - ok(actual.toString().indexOf(expected), + ok(actual.toString().indexOf(expected) !== -1, `${JSON.stringify(actual)} includes ${JSON.stringify(expected)}`); } diff --git a/test/es-module/test-esm-forbidden-globals.mjs b/test/es-module/test-esm-forbidden-globals.mjs index b66f278a8a9bb8..2f1914e48631b5 100644 --- a/test/es-module/test-esm-forbidden-globals.mjs +++ b/test/es-module/test-esm-forbidden-globals.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; // eslint-disable-next-line no-undef diff --git a/test/es-module/test-esm-import-meta.mjs b/test/es-module/test-esm-import-meta.mjs index 54c14a44f5e281..0151177b21c302 100644 --- a/test/es-module/test-esm-import-meta.mjs +++ b/test/es-module/test-esm-import-meta.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-invalid-extension.js b/test/es-module/test-esm-invalid-extension.js index 9e676e57d1b90f..cdf9476b29f864 100644 --- a/test/es-module/test-esm-invalid-extension.js +++ b/test/es-module/test-esm-invalid-extension.js @@ -4,7 +4,7 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const { spawnSync } = require('child_process'); const fixture = fixtures.path('/es-modules/import-invalid-ext.mjs'); -const child = spawnSync(process.execPath, ['--experimental-modules', fixture]); +const child = spawnSync(process.execPath, [fixture]); const errMsg = 'TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension'; assert.strictEqual(child.status, 1); diff --git a/test/es-module/test-esm-json-cache.mjs b/test/es-module/test-esm-json-cache.mjs index d1fee4f444c2c0..d08f852e255a78 100644 --- a/test/es-module/test-esm-json-cache.mjs +++ b/test/es-module/test-esm-json-cache.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-json-modules +// Flags: --experimental-json-modules import '../common/index.mjs'; import { strictEqual, deepStrictEqual } from 'assert'; diff --git a/test/es-module/test-esm-json.mjs b/test/es-module/test-esm-json.mjs index 3d246124a9bdae..9dd33f26b557d1 100644 --- a/test/es-module/test-esm-json.mjs +++ b/test/es-module/test-esm-json.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-json-modules +// Flags: --experimental-json-modules import '../common/index.mjs'; import { strictEqual } from 'assert'; diff --git a/test/es-module/test-esm-live-binding.mjs b/test/es-module/test-esm-live-binding.mjs index 4000a621a2bd04..ff58db31f144a3 100644 --- a/test/es-module/test-esm-live-binding.mjs +++ b/test/es-module/test-esm-live-binding.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; import { syncBuiltinESMExports } from 'module'; diff --git a/test/es-module/test-esm-loader-cache-clearing.js b/test/es-module/test-esm-loader-cache-clearing.js index ec22b6a6bb871e..4b5f36cf37ec3b 100644 --- a/test/es-module/test-esm-loader-cache-clearing.js +++ b/test/es-module/test-esm-loader-cache-clearing.js @@ -1,4 +1,3 @@ -// Flags: --experimental-modules 'use strict'; require('../common'); diff --git a/test/es-module/test-esm-loader-dependency.mjs b/test/es-module/test-esm-loader-dependency.mjs index dadc3bd84ae1d3..54327b478bf462 100644 --- a/test/es-module/test-esm-loader-dependency.mjs +++ b/test/es-module/test-esm-loader-dependency.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-with-dep.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-with-dep.mjs /* eslint-disable node-core/require-common-first, node-core/required-modules */ import '../fixtures/es-modules/test-esm-ok.mjs'; diff --git a/test/es-module/test-esm-loader-invalid-format.mjs b/test/es-module/test-esm-loader-invalid-format.mjs index 9e26d646d479a1..75f5de83805394 100644 --- a/test/es-module/test-esm-loader-invalid-format.mjs +++ b/test/es-module/test-esm-loader-invalid-format.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-format.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-format.mjs import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-loader-invalid-url.mjs b/test/es-module/test-esm-loader-invalid-url.mjs index f42900c58e049c..4007be052dd7c7 100644 --- a/test/es-module/test-esm-loader-invalid-url.mjs +++ b/test/es-module/test-esm-loader-invalid-url.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-url.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-invalid-url.mjs import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs index 5767af7affe1fa..62781c37d48240 100644 --- a/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs +++ b/test/es-module/test-esm-loader-missing-dynamic-instantiate-hook.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/missing-dynamic-instantiate-hook.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/missing-dynamic-instantiate-hook.mjs import { expectsError } from '../common/index.mjs'; import('test').catch(expectsError({ diff --git a/test/es-module/test-esm-loader-modulemap.js b/test/es-module/test-esm-loader-modulemap.js index 70f5a1015907a2..5493c6c47c9643 100644 --- a/test/es-module/test-esm-loader-modulemap.js +++ b/test/es-module/test-esm-loader-modulemap.js @@ -1,5 +1,5 @@ 'use strict'; -// Flags: --expose-internals --experimental-modules +// Flags: --expose-internals // This test ensures that the type checking of ModuleMap throws // errors appropriately diff --git a/test/es-module/test-esm-main-lookup.mjs b/test/es-module/test-esm-main-lookup.mjs index cbc6424dd2ff1c..2023a105e4dc42 100644 --- a/test/es-module/test-esm-main-lookup.mjs +++ b/test/es-module/test-esm-main-lookup.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-named-exports.mjs b/test/es-module/test-esm-named-exports.mjs index 6c8030826970a8..7d8d1080082401 100644 --- a/test/es-module/test-esm-named-exports.mjs +++ b/test/es-module/test-esm-named-exports.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/builtin-named-exports-loader.mjs import '../common/index.mjs'; import { readFile } from 'fs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-namespace.mjs b/test/es-module/test-esm-namespace.mjs index 094a9e972cbbad..9ce0f9686d1668 100644 --- a/test/es-module/test-esm-namespace.mjs +++ b/test/es-module/test-esm-namespace.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import * as fs from 'fs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-no-extension.js b/test/es-module/test-esm-no-extension.js index 81b8e5b4327ad0..392bb5638b0e34 100644 --- a/test/es-module/test-esm-no-extension.js +++ b/test/es-module/test-esm-no-extension.js @@ -10,10 +10,7 @@ const entry = fixtures.path('/es-modules/package-type-module/noext-esm'); // Run a module that does not have extension. // This is to ensure that "type": "module" applies to extensionless files. -const child = spawn(process.execPath, [ - '--experimental-modules', - entry -]); +const child = spawn(process.execPath, [entry]); let stdout = ''; child.stdout.setEncoding('utf8'); diff --git a/test/es-module/test-esm-non-js.js b/test/es-module/test-esm-non-js.js new file mode 100644 index 00000000000000..3e572809bbdf35 --- /dev/null +++ b/test/es-module/test-esm-non-js.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../common'); +const { spawn } = require('child_process'); +const assert = require('assert'); + +const entry = require.resolve('./test-esm-json.mjs'); + +// Verify non-js extensions fail for ESM +const child = spawn(process.execPath, [entry]); + +let stderr = ''; +child.stderr.setEncoding('utf8'); +child.stderr.on('data', (data) => { + stderr += data; +}); +child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 1); + assert.strictEqual(signal, null); + assert.ok(stderr.indexOf('ERR_UNKNOWN_FILE_EXTENSION') !== -1); +})); diff --git a/test/es-module/test-esm-pkgname.mjs b/test/es-module/test-esm-pkgname.mjs index 046a12dd1a12da..06b5d2d104df63 100644 --- a/test/es-module/test-esm-pkgname.mjs +++ b/test/es-module/test-esm-pkgname.mjs @@ -1,5 +1,3 @@ -// Flags: --experimental-modules - import { mustCall } from '../common/index.mjs'; import { strictEqual } from 'assert'; diff --git a/test/es-module/test-esm-preserve-symlinks-main.js b/test/es-module/test-esm-preserve-symlinks-main.js index 239fdddc2e8d79..877066a6a4548e 100644 --- a/test/es-module/test-esm-preserve-symlinks-main.js +++ b/test/es-module/test-esm-preserve-symlinks-main.js @@ -53,5 +53,5 @@ function doTest(flags, done) { // First test the commonjs module loader doTest([], () => { // Now test the new loader - doTest(['--experimental-modules'], () => {}); + doTest([], () => {}); }); diff --git a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs index 1dcae4b8aef4a8..7a538e44c072e0 100644 --- a/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs +++ b/test/es-module/test-esm-preserve-symlinks-not-found-plain.mjs @@ -1,3 +1,3 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs /* eslint-disable node-core/require-common-first, node-core/required-modules */ import './not-found.js'; diff --git a/test/es-module/test-esm-preserve-symlinks-not-found.mjs b/test/es-module/test-esm-preserve-symlinks-not-found.mjs index 68e1b53eeb1d75..722dc467d19273 100644 --- a/test/es-module/test-esm-preserve-symlinks-not-found.mjs +++ b/test/es-module/test-esm-preserve-symlinks-not-found.mjs @@ -1,3 +1,3 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/not-found-assert-loader.mjs /* eslint-disable node-core/require-common-first, node-core/required-modules */ import './not-found.mjs'; diff --git a/test/es-module/test-esm-preserve-symlinks.js b/test/es-module/test-esm-preserve-symlinks.js index 28cba3e7022c1a..a91373b0c05b93 100644 --- a/test/es-module/test-esm-preserve-symlinks.js +++ b/test/es-module/test-esm-preserve-symlinks.js @@ -32,7 +32,7 @@ try { } spawn(process.execPath, - ['--experimental-modules', '--preserve-symlinks', entry], + ['--preserve-symlinks', entry], { stdio: 'inherit' }).on('exit', (code) => { assert.strictEqual(code, 0); }); diff --git a/test/es-module/test-esm-process.mjs b/test/es-module/test-esm-process.mjs index a2b0d31f1efa27..8fa006a304ed2f 100644 --- a/test/es-module/test-esm-process.mjs +++ b/test/es-module/test-esm-process.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; import process from 'process'; diff --git a/test/es-module/test-esm-repl.js b/test/es-module/test-esm-repl.js index daef48d8e1f58b..653927b241694e 100644 --- a/test/es-module/test-esm-repl.js +++ b/test/es-module/test-esm-repl.js @@ -4,7 +4,6 @@ const assert = require('assert'); const { spawn } = require('child_process'); const child = spawn(process.execPath, [ - '--experimental-modules', '--interactive' ]); child.stdin.end(` diff --git a/test/es-module/test-esm-require-cache.mjs b/test/es-module/test-esm-require-cache.mjs index 8c126c39e0eefe..1cfcf8e2a4b416 100644 --- a/test/es-module/test-esm-require-cache.mjs +++ b/test/es-module/test-esm-require-cache.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import { createRequire } from '../common/index.mjs'; import assert from 'assert'; // diff --git a/test/es-module/test-esm-resolve-hook.mjs b/test/es-module/test-esm-resolve-hook.mjs index 00c8e440f42964..39b11e02739d4b 100644 --- a/test/es-module/test-esm-resolve-hook.mjs +++ b/test/es-module/test-esm-resolve-hook.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/js-loader.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/js-loader.mjs /* eslint-disable node-core/require-common-first, node-core/required-modules */ import { namedExport } from '../fixtures/es-module-loaders/js-as-esm.js'; import assert from 'assert'; diff --git a/test/es-module/test-esm-scope-node-modules.mjs b/test/es-module/test-esm-scope-node-modules.mjs index 8358da5c765288..0be4194aeb9b4d 100644 --- a/test/es-module/test-esm-scope-node-modules.mjs +++ b/test/es-module/test-esm-scope-node-modules.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import cjs from '../fixtures/baz.js'; import { message } from '../fixtures/es-modules/message.mjs'; diff --git a/test/es-module/test-esm-shared-loader-dep.mjs b/test/es-module/test-esm-shared-loader-dep.mjs index b02e557d34bc29..e0015bd0c755d7 100644 --- a/test/es-module/test-esm-shared-loader-dep.mjs +++ b/test/es-module/test-esm-shared-loader-dep.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-shared-dep.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-shared-dep.mjs import { createRequire } from '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-shebang.mjs b/test/es-module/test-esm-shebang.mjs index 1d22551bd7a4be..6b77151dd78406 100644 --- a/test/es-module/test-esm-shebang.mjs +++ b/test/es-module/test-esm-shebang.mjs @@ -1,5 +1,4 @@ #! }]) // isn't js -// Flags: --experimental-modules import '../common/index.mjs'; const isJs = true; diff --git a/test/es-module/test-esm-snapshot.mjs b/test/es-module/test-esm-snapshot.mjs index 99767f10e2846e..e2695d20a81747 100644 --- a/test/es-module/test-esm-snapshot.mjs +++ b/test/es-module/test-esm-snapshot.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import '../fixtures/es-modules/esm-snapshot-mutator.js'; import one from '../fixtures/es-modules/esm-snapshot.js'; diff --git a/test/es-module/test-esm-specifiers.mjs b/test/es-module/test-esm-specifiers.mjs index 59d54cbf63dc79..3e7bc181962f4f 100644 --- a/test/es-module/test-esm-specifiers.mjs +++ b/test/es-module/test-esm-specifiers.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --es-module-specifier-resolution=node +// Flags: --es-module-specifier-resolution=node import { mustNotCall } from '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-symlink-main.js b/test/es-module/test-esm-symlink-main.js index 871180f5ccf4bb..48b4d8bbe65daf 100644 --- a/test/es-module/test-esm-symlink-main.js +++ b/test/es-module/test-esm-symlink-main.js @@ -19,7 +19,7 @@ try { } spawn(process.execPath, - ['--experimental-modules', '--preserve-symlinks', symlinkPath], + ['--preserve-symlinks', symlinkPath], { stdio: 'inherit' }).on('exit', (code) => { assert.strictEqual(code, 0); }); diff --git a/test/es-module/test-esm-symlink-type.js b/test/es-module/test-esm-symlink-type.js index 6159ebecd18be4..1f46dce17f2e46 100644 --- a/test/es-module/test-esm-symlink-type.js +++ b/test/es-module/test-esm-symlink-type.js @@ -48,8 +48,8 @@ symlinks.forEach((symlink) => { fs.symlinkSync(symlink.target, mainPath); const flags = [ - '--experimental-modules', - '--experimental-modules --preserve-symlinks-main' + '', + '--preserve-symlinks-main' ]; flags.forEach((nodeOptions) => { const opts = { diff --git a/test/es-module/test-esm-symlink.js b/test/es-module/test-esm-symlink.js index 9b9eb98cd98406..139e6820ed5354 100644 --- a/test/es-module/test-esm-symlink.js +++ b/test/es-module/test-esm-symlink.js @@ -41,7 +41,7 @@ try { common.skip('insufficient privileges for symlinks'); } -spawn(process.execPath, ['--experimental-modules', entry], +spawn(process.execPath, [entry], { stdio: 'inherit' }).on('exit', (code) => { assert.strictEqual(code, 0); }); diff --git a/test/es-module/test-esm-throw-undefined.mjs b/test/es-module/test-esm-throw-undefined.mjs index 4c091e61532640..c4c25fd12d675c 100644 --- a/test/es-module/test-esm-throw-undefined.mjs +++ b/test/es-module/test-esm-throw-undefined.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import assert from 'assert'; diff --git a/test/es-module/test-esm-type-flag-errors.js b/test/es-module/test-esm-type-flag-errors.js index 8725fb62323b75..5d19cedd84a844 100644 --- a/test/es-module/test-esm-type-flag-errors.js +++ b/test/es-module/test-esm-type-flag-errors.js @@ -1,4 +1,3 @@ -// Flags: --experimental-modules 'use strict'; const common = require('../common'); const assert = require('assert'); @@ -32,8 +31,6 @@ try { } function expect(opt = '', inputFile, want, wantsError = false) { - // TODO: Remove when --experimental-modules is unflagged - opt = `--experimental-modules ${opt}`; const argv = [inputFile]; const opts = { env: Object.assign({}, process.env, { NODE_OPTIONS: opt }), diff --git a/test/es-module/test-esm-type-flag.mjs b/test/es-module/test-esm-type-flag.mjs index 8358da5c765288..0be4194aeb9b4d 100644 --- a/test/es-module/test-esm-type-flag.mjs +++ b/test/es-module/test-esm-type-flag.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import cjs from '../fixtures/baz.js'; import { message } from '../fixtures/es-modules/message.mjs'; diff --git a/test/es-module/test-esm-wasm.mjs b/test/es-module/test-esm-wasm.mjs index bcfce797a9cc8b..46df5994afa932 100644 --- a/test/es-module/test-esm-wasm.mjs +++ b/test/es-module/test-esm-wasm.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-wasm-modules +// Flags: --experimental-wasm-modules import '../common/index.mjs'; import { add, addImported } from '../fixtures/es-modules/simple.wasm'; import { state } from '../fixtures/es-modules/wasm-dep.mjs'; diff --git a/test/es-module/test-esm-windows.js b/test/es-module/test-esm-windows.js index 64ba1249a76c06..c4d9ff4cde2c95 100644 --- a/test/es-module/test-esm-windows.js +++ b/test/es-module/test-esm-windows.js @@ -1,6 +1,5 @@ 'use strict'; -// Flags: --experimental-modules // This test ensures that JavaScript file that includes // a reserved Windows word can be loaded as ESM module diff --git a/test/fixtures/es-modules/package-type-module/nested-default-type/module.js b/test/fixtures/es-modules/package-type-module/nested-default-type/module.js new file mode 100644 index 00000000000000..683f2d8ba623a7 --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/nested-default-type/module.js @@ -0,0 +1 @@ +module.exports = 'asdf'; diff --git a/test/fixtures/es-modules/package-type-module/nested-default-type/package.json b/test/fixtures/es-modules/package-type-module/nested-default-type/package.json new file mode 100644 index 00000000000000..0967ef424bce67 --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/nested-default-type/package.json @@ -0,0 +1 @@ +{} diff --git a/test/fixtures/monkey-patch-run-main.js b/test/fixtures/monkey-patch-run-main.js new file mode 100644 index 00000000000000..949a5eca644b45 --- /dev/null +++ b/test/fixtures/monkey-patch-run-main.js @@ -0,0 +1,8 @@ +'use strict'; + +const oldRunMain = require('module').runMain; + +require('module').runMain = function(...args) { + console.log('runMain is monkey patched!'); + oldRunMain(...args); +}; diff --git a/test/fixtures/node_modules/pkgexports-sugar-fail/main.js b/test/fixtures/node_modules/pkgexports-sugar-fail/main.js new file mode 100644 index 00000000000000..dfdd47b877319c --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar-fail/main.js @@ -0,0 +1 @@ +module.exports = 'main'; diff --git a/test/fixtures/node_modules/pkgexports-sugar-fail/not-exported.js b/test/fixtures/node_modules/pkgexports-sugar-fail/not-exported.js new file mode 100644 index 00000000000000..02e146dbe90985 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar-fail/not-exported.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = 'not-exported'; diff --git a/test/fixtures/node_modules/pkgexports-sugar-fail/package.json b/test/fixtures/node_modules/pkgexports-sugar-fail/package.json new file mode 100644 index 00000000000000..0fb05a427a76e2 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar-fail/package.json @@ -0,0 +1,6 @@ +{ + "exports": { + "default": "./main.js", + "./main": "./main.js" + } +} diff --git a/test/fixtures/node_modules/pkgexports-sugar/main.js b/test/fixtures/node_modules/pkgexports-sugar/main.js new file mode 100644 index 00000000000000..dfdd47b877319c --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar/main.js @@ -0,0 +1 @@ +module.exports = 'main'; diff --git a/test/fixtures/node_modules/pkgexports-sugar/not-exported.js b/test/fixtures/node_modules/pkgexports-sugar/not-exported.js new file mode 100644 index 00000000000000..02e146dbe90985 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar/not-exported.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = 'not-exported'; diff --git a/test/fixtures/node_modules/pkgexports-sugar/package.json b/test/fixtures/node_modules/pkgexports-sugar/package.json new file mode 100644 index 00000000000000..5ebad0b4bda380 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar/package.json @@ -0,0 +1,3 @@ +{ + "exports": "./main.js" +} diff --git a/test/fixtures/node_modules/pkgexports-sugar2/main.js b/test/fixtures/node_modules/pkgexports-sugar2/main.js new file mode 100644 index 00000000000000..dfdd47b877319c --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar2/main.js @@ -0,0 +1 @@ +module.exports = 'main'; diff --git a/test/fixtures/node_modules/pkgexports-sugar2/not-exported.js b/test/fixtures/node_modules/pkgexports-sugar2/not-exported.js new file mode 100644 index 00000000000000..02e146dbe90985 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar2/not-exported.js @@ -0,0 +1,3 @@ +'use strict'; + +module.exports = 'not-exported'; diff --git a/test/fixtures/node_modules/pkgexports-sugar2/package.json b/test/fixtures/node_modules/pkgexports-sugar2/package.json new file mode 100644 index 00000000000000..139b06665d85e0 --- /dev/null +++ b/test/fixtures/node_modules/pkgexports-sugar2/package.json @@ -0,0 +1,6 @@ +{ + "exports": { + "require": "./not-exported.js", + "default": "./main.js" + } +} diff --git a/test/fixtures/node_modules/pkgexports/package.json b/test/fixtures/node_modules/pkgexports/package.json index 38e2fc1a5c02f6..37c28cdc1a950f 100644 --- a/test/fixtures/node_modules/pkgexports/package.json +++ b/test/fixtures/node_modules/pkgexports/package.json @@ -1,7 +1,7 @@ { "name": "@pkgexports/name", + "main": "./asdf.js", "exports": { - ".": "./asdf.js", "./hole": "./lib/hole.js", "./space": "./sp%20ce.js", "./valid-cjs": "./asdf.js", @@ -18,6 +18,7 @@ "./fallbackfile": [[], null, {}, "builtin:x", "./asdf.js"], "./nofallback1": [], "./nofallback2": [null, {}, "builtin:x"], - "./nodemodules": "./node_modules/internalpkg/x.js" + "./nodemodules": "./node_modules/internalpkg/x.js", + "./condition": [{ "require": "./sp ce.js" }, "./asdf.js"] } } diff --git a/test/fixtures/source-map/inline-base64-json-error.js b/test/fixtures/source-map/inline-base64-json-error.js new file mode 100644 index 00000000000000..ba87a7208b0fd2 --- /dev/null +++ b/test/fixtures/source-map/inline-base64-json-error.js @@ -0,0 +1,2 @@ +var cov_263bu3eqm8=function(){var path= "./branches.js";var hash="424788076537d051b5bf0e2564aef393124eabc7";var global=new Function("return this")();var gcv="__coverage__";var coverageData={path: "./branches.js",statementMap:{"0":{start:{line:1,column:0},end:{line:7,column:1}},"1":{start:{line:2,column:2},end:{line:2,column:29}},"2":{start:{line:3,column:7},end:{line:7,column:1}},"3":{start:{line:4,column:2},end:{line:4,column:27}},"4":{start:{line:6,column:2},end:{line:6,column:29}},"5":{start:{line:10,column:2},end:{line:16,column:3}},"6":{start:{line:11,column:4},end:{line:11,column:28}},"7":{start:{line:12,column:9},end:{line:16,column:3}},"8":{start:{line:13,column:4},end:{line:13,column:31}},"9":{start:{line:15,column:4},end:{line:15,column:29}},"10":{start:{line:19,column:0},end:{line:19,column:12}},"11":{start:{line:20,column:0},end:{line:20,column:13}}},fnMap:{"0":{name:"branch",decl:{start:{line:9,column:9},end:{line:9,column:15}},loc:{start:{line:9,column:20},end:{line:17,column:1}},line:9}},branchMap:{"0":{loc:{start:{line:1,column:0},end:{line:7,column:1}},type:"if",locations:[{start:{line:1,column:0},end:{line:7,column:1}},{start:{line:1,column:0},end:{line:7,column:1}}],line:1},"1":{loc:{start:{line:3,column:7},end:{line:7,column:1}},type:"if",locations:[{start:{line:3,column:7},end:{line:7,column:1}},{start:{line:3,column:7},end:{line:7,column:1}}],line:3},"2":{loc:{start:{line:10,column:2},end:{line:16,column:3}},type:"if",locations:[{start:{line:10,column:2},end:{line:16,column:3}},{start:{line:10,column:2},end:{line:16,column:3}}],line:10},"3":{loc:{start:{line:12,column:9},end:{line:16,column:3}},type:"if",locations:[{start:{line:12,column:9},end:{line:16,column:3}},{start:{line:12,column:9},end:{line:16,column:3}}],line:12}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0},f:{"0":0},b:{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184",hash:"424788076537d051b5bf0e2564aef393124eabc7"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}return coverage[path]=coverageData;}();cov_263bu3eqm8.s[0]++;if(false){cov_263bu3eqm8.b[0][0]++;cov_263bu3eqm8.s[1]++;console.info('unreachable');}else{cov_263bu3eqm8.b[0][1]++;cov_263bu3eqm8.s[2]++;if(true){cov_263bu3eqm8.b[1][0]++;cov_263bu3eqm8.s[3]++;console.info('reachable');}else{cov_263bu3eqm8.b[1][1]++;cov_263bu3eqm8.s[4]++;console.info('unreachable');}}function branch(a){cov_263bu3eqm8.f[0]++;cov_263bu3eqm8.s[5]++;if(a){cov_263bu3eqm8.b[2][0]++;cov_263bu3eqm8.s[6]++;console.info('a = true');}else{cov_263bu3eqm8.b[2][1]++;cov_263bu3eqm8.s[7]++;if(undefined){cov_263bu3eqm8.b[3][0]++;cov_263bu3eqm8.s[8]++;console.info('unreachable');}else{cov_263bu3eqm8.b[3][1]++;cov_263bu3eqm8.s[9]++;console.info('a = false');}}}cov_263bu3eqm8.s[10]++;branch(true);cov_263bu3eqm8.s[11]++;branch(false); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uOjMsInNvdXJjZXMiOlsiLi9icmFuY2hlcy5qcyJdLCJuYW1lcyI6WyJjb25zb2xlIiwiaW5mbyIsImJyYW5jaCIsImEiLCJ1bmRlZmluZWQiXSwibWFwcGluZ3MiOiJzdUVBQUEsR0FBSSxLQUFKLENBQVcsZ0RBQ1RBLE9BQU8sQ0FBQ0MsSUFBUixDQUFhLGFBQWIsRUFDRCxDQUZELElBRU8sbURBQUksSUFBSixDQUFVLGdEQUNmRCxPQUFPLENBQUNDLElBQVIsQ0FBYSxXQUFiLEVBQ0QsQ0FGTSxJQUVBLGdEQUNMRCxPQUFPLENBQUNDLElBQVIsQ0FBYSxhQUFiLEVBQ0QsRUFFRCxRQUFTQyxDQUFBQSxNQUFULENBQWlCQyxDQUFqQixDQUFvQiw2Q0FDbEIsR0FBSUEsQ0FBSixDQUFPLGdEQUNMSCxPQUFPLENBQUNDLElBQVIsQ0FBYSxVQUFiLEVBQ0QsQ0FGRCxJQUVPLG1EQUFJRyxTQUFKLENBQWUsZ0RBQ3BCSixPQUFPLENBQUNDLElBQVIsQ0FBYSxhQUFiLEVBQ0QsQ0FGTSxJQUVBLGdEQUNMRCxPQUFPLENBQUNDLElBQVIsQ0FBYSxXQUFiLEVBQ0QsRUFDRixDLHVCQUVEQyxNQUFNLENBQUMsSUFBRCxDQUFOLEMsdUJBQ0FBLE1BQU0sQ0FBQyxLQUFELENBQU4iLCJzb3VyY2VzQ29udGVudCI6WyJpZiAoZmFsc2UpIHtcbiAgY29uc29sZS5pbmZvKCd1bnJlYWNoYWJsZScpXG59IGVsc2UgaWYgKHRydWUpIHtcbiAgY29uc29sZS5pbmZvKCdyZWFjaGFibGUnKVxufSBlbHNlIHtcbiAgY29uc29sZS5pbmZvKCd1bnJlYWNoYWJsZScpXG59XG5cbmZ1bmN0aW9uIGJyYW5jaCAoYSkge1xuICBpZiAoYSkge1xuICAgIGNvbnNvbGUuaW5mbygnYSA9IHRydWUnKVxuICB9IGVsc2UgaWYgKHVuZGVmaW5lZCkge1xuICAgIGNvbnNvbGUuaW5mbygndW5yZWFjaGFibGUnKVxuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuaW5mbygnYSA9IGZhbHNlJylcbiAgfVxufVxuXG5icmFuY2godHJ1ZSlcbmJyYW5jaChmYWxzZSlcbiJdfQ== \ No newline at end of file diff --git a/test/fixtures/source-map/inline-base64-type-error.js b/test/fixtures/source-map/inline-base64-type-error.js new file mode 100644 index 00000000000000..2bc77ca54e0e40 --- /dev/null +++ b/test/fixtures/source-map/inline-base64-type-error.js @@ -0,0 +1,2 @@ +var cov_263bu3eqm8=function(){var path= "./branches.js";var hash="424788076537d051b5bf0e2564aef393124eabc7";var global=new Function("return this")();var gcv="__coverage__";var coverageData={path: "./branches.js",statementMap:{"0":{start:{line:1,column:0},end:{line:7,column:1}},"1":{start:{line:2,column:2},end:{line:2,column:29}},"2":{start:{line:3,column:7},end:{line:7,column:1}},"3":{start:{line:4,column:2},end:{line:4,column:27}},"4":{start:{line:6,column:2},end:{line:6,column:29}},"5":{start:{line:10,column:2},end:{line:16,column:3}},"6":{start:{line:11,column:4},end:{line:11,column:28}},"7":{start:{line:12,column:9},end:{line:16,column:3}},"8":{start:{line:13,column:4},end:{line:13,column:31}},"9":{start:{line:15,column:4},end:{line:15,column:29}},"10":{start:{line:19,column:0},end:{line:19,column:12}},"11":{start:{line:20,column:0},end:{line:20,column:13}}},fnMap:{"0":{name:"branch",decl:{start:{line:9,column:9},end:{line:9,column:15}},loc:{start:{line:9,column:20},end:{line:17,column:1}},line:9}},branchMap:{"0":{loc:{start:{line:1,column:0},end:{line:7,column:1}},type:"if",locations:[{start:{line:1,column:0},end:{line:7,column:1}},{start:{line:1,column:0},end:{line:7,column:1}}],line:1},"1":{loc:{start:{line:3,column:7},end:{line:7,column:1}},type:"if",locations:[{start:{line:3,column:7},end:{line:7,column:1}},{start:{line:3,column:7},end:{line:7,column:1}}],line:3},"2":{loc:{start:{line:10,column:2},end:{line:16,column:3}},type:"if",locations:[{start:{line:10,column:2},end:{line:16,column:3}},{start:{line:10,column:2},end:{line:16,column:3}}],line:10},"3":{loc:{start:{line:12,column:9},end:{line:16,column:3}},type:"if",locations:[{start:{line:12,column:9},end:{line:16,column:3}},{start:{line:12,column:9},end:{line:16,column:3}}],line:12}},s:{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0},f:{"0":0},b:{"0":[0,0],"1":[0,0],"2":[0,0],"3":[0,0]},_coverageSchema:"43e27e138ebf9cfc5966b082cf9a028302ed4184",hash:"424788076537d051b5bf0e2564aef393124eabc7"};var coverage=global[gcv]||(global[gcv]={});if(coverage[path]&&coverage[path].hash===hash){return coverage[path];}return coverage[path]=coverageData;}();cov_263bu3eqm8.s[0]++;if(false){cov_263bu3eqm8.b[0][0]++;cov_263bu3eqm8.s[1]++;console.info('unreachable');}else{cov_263bu3eqm8.b[0][1]++;cov_263bu3eqm8.s[2]++;if(true){cov_263bu3eqm8.b[1][0]++;cov_263bu3eqm8.s[3]++;console.info('reachable');}else{cov_263bu3eqm8.b[1][1]++;cov_263bu3eqm8.s[4]++;console.info('unreachable');}}function branch(a){cov_263bu3eqm8.f[0]++;cov_263bu3eqm8.s[5]++;if(a){cov_263bu3eqm8.b[2][0]++;cov_263bu3eqm8.s[6]++;console.info('a = true');}else{cov_263bu3eqm8.b[2][1]++;cov_263bu3eqm8.s[7]++;if(undefined){cov_263bu3eqm8.b[3][0]++;cov_263bu3eqm8.s[8]++;console.info('unreachable');}else{cov_263bu3eqm8.b[3][1]++;cov_263bu3eqm8.s[9]++;console.info('a = false');}}}cov_263bu3eqm8.s[10]++;branch(true);cov_263bu3eqm8.s[11]++;branch(false); +//# sourceMappingURL=data:application/text;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4vYnJhbmNoZXMuanMiXSwibmFtZXMiOlsiY29uc29sZSIsImluZm8iLCJicmFuY2giLCJhIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoic3VFQUFBLEdBQUksS0FBSixDQUFXLGdEQUNUQSxPQUFPLENBQUNDLElBQVIsQ0FBYSxhQUFiLEVBQ0QsQ0FGRCxJQUVPLG1EQUFJLElBQUosQ0FBVSxnREFDZkQsT0FBTyxDQUFDQyxJQUFSLENBQWEsV0FBYixFQUNELENBRk0sSUFFQSxnREFDTEQsT0FBTyxDQUFDQyxJQUFSLENBQWEsYUFBYixFQUNELEVBRUQsUUFBU0MsQ0FBQUEsTUFBVCxDQUFpQkMsQ0FBakIsQ0FBb0IsNkNBQ2xCLEdBQUlBLENBQUosQ0FBTyxnREFDTEgsT0FBTyxDQUFDQyxJQUFSLENBQWEsVUFBYixFQUNELENBRkQsSUFFTyxtREFBSUcsU0FBSixDQUFlLGdEQUNwQkosT0FBTyxDQUFDQyxJQUFSLENBQWEsYUFBYixFQUNELENBRk0sSUFFQSxnREFDTEQsT0FBTyxDQUFDQyxJQUFSLENBQWEsV0FBYixFQUNELEVBQ0YsQyx1QkFFREMsTUFBTSxDQUFDLElBQUQsQ0FBTixDLHVCQUNBQSxNQUFNLENBQUMsS0FBRCxDQUFOIiwic291cmNlc0NvbnRlbnQiOlsiaWYgKGZhbHNlKSB7XG4gIGNvbnNvbGUuaW5mbygndW5yZWFjaGFibGUnKVxufSBlbHNlIGlmICh0cnVlKSB7XG4gIGNvbnNvbGUuaW5mbygncmVhY2hhYmxlJylcbn0gZWxzZSB7XG4gIGNvbnNvbGUuaW5mbygndW5yZWFjaGFibGUnKVxufVxuXG5mdW5jdGlvbiBicmFuY2ggKGEpIHtcbiAgaWYgKGEpIHtcbiAgICBjb25zb2xlLmluZm8oJ2EgPSB0cnVlJylcbiAgfSBlbHNlIGlmICh1bmRlZmluZWQpIHtcbiAgICBjb25zb2xlLmluZm8oJ3VucmVhY2hhYmxlJylcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmluZm8oJ2EgPSBmYWxzZScpXG4gIH1cbn1cblxuYnJhbmNoKHRydWUpXG5icmFuY2goZmFsc2UpXG4iXX0= diff --git a/test/message/async_error_eval_esm.js b/test/message/async_error_eval_esm.js index 33675b5a9db286..0c9b7378d54729 100644 --- a/test/message/async_error_eval_esm.js +++ b/test/message/async_error_eval_esm.js @@ -26,7 +26,6 @@ main(); // --eval ESM { const child = spawnSync(process.execPath, [ - '--experimental-modules', '--input-type', 'module', '-e', diff --git a/test/message/async_error_eval_esm.out b/test/message/async_error_eval_esm.out index 578a9f5c26160e..769fac7a0d408e 100644 --- a/test/message/async_error_eval_esm.out +++ b/test/message/async_error_eval_esm.out @@ -1,7 +1,6 @@ Error: test at one (file:*/[eval1]:2:9) at two (file:*/[eval1]:15:9) - at processTicksAndRejections (internal/process/task_queues.js:*:*) at async three (file:*/[eval1]:18:3) at async four (file:*/[eval1]:22:3) at async main (file:*/[eval1]:28:5) diff --git a/test/message/async_error_sync_esm.mjs b/test/message/async_error_sync_esm.mjs index f16256d7778b81..fdb6a260d1284b 100644 --- a/test/message/async_error_sync_esm.mjs +++ b/test/message/async_error_sync_esm.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import four from '../fixtures/async-error.js'; diff --git a/test/message/async_error_sync_esm.out b/test/message/async_error_sync_esm.out index f34628ef44e52a..6577fff6944723 100644 --- a/test/message/async_error_sync_esm.out +++ b/test/message/async_error_sync_esm.out @@ -4,4 +4,4 @@ Error: test at two (*fixtures*async-error.js:17:9) at async three (*fixtures*async-error.js:20:3) at async four (*fixtures*async-error.js:24:3) - at async main (*message*async_error_sync_esm.mjs:7:5) + at async main (*message*async_error_sync_esm.mjs:6:5) diff --git a/test/message/core_line_numbers.out b/test/message/core_line_numbers.out index 53d3894825b4a4..26f74589532908 100644 --- a/test/message/core_line_numbers.out +++ b/test/message/core_line_numbers.out @@ -10,5 +10,5 @@ RangeError: Invalid input at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* diff --git a/test/message/error_exit.out b/test/message/error_exit.out index a0d848b125b7a6..19cd11304e2a77 100644 --- a/test/message/error_exit.out +++ b/test/message/error_exit.out @@ -12,7 +12,7 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* { generatedMessage: true, code: 'ERR_ASSERTION', diff --git a/test/message/esm_display_syntax_error.mjs b/test/message/esm_display_syntax_error.mjs index 829186725554bf..bda4a7e6ebe3a3 100644 --- a/test/message/esm_display_syntax_error.mjs +++ b/test/message/esm_display_syntax_error.mjs @@ -1,3 +1,2 @@ -// Flags: --experimental-modules 'use strict'; await async () => 0; diff --git a/test/message/esm_display_syntax_error.out b/test/message/esm_display_syntax_error.out index 5e82a1e1ee8f87..778d901129fa95 100644 --- a/test/message/esm_display_syntax_error.out +++ b/test/message/esm_display_syntax_error.out @@ -1,5 +1,5 @@ (node:*) ExperimentalWarning: The ESM module loader is experimental. -file:///*/test/message/esm_display_syntax_error.mjs:3 +file:///*/test/message/esm_display_syntax_error.mjs:2 await async () => 0; ^^^^^ diff --git a/test/message/esm_display_syntax_error_import.mjs b/test/message/esm_display_syntax_error_import.mjs index 4c41b292efd4d6..2173cb2b2e3a71 100644 --- a/test/message/esm_display_syntax_error_import.mjs +++ b/test/message/esm_display_syntax_error_import.mjs @@ -1,4 +1,3 @@ -// Flags: --experimental-modules /* eslint-disable no-unused-vars */ import '../common/index.mjs'; import { diff --git a/test/message/esm_display_syntax_error_import.out b/test/message/esm_display_syntax_error_import.out index a3601d6cb46fab..e39744a049b59b 100644 --- a/test/message/esm_display_syntax_error_import.out +++ b/test/message/esm_display_syntax_error_import.out @@ -1,5 +1,5 @@ (node:*) ExperimentalWarning: The ESM module loader is experimental. -file:///*/test/message/esm_display_syntax_error_import.mjs:6 +file:///*/test/message/esm_display_syntax_error_import.mjs:5 notfound ^^^^^^^^ SyntaxError: The requested module '../fixtures/es-module-loaders/module-named-exports.mjs' does not provide an export named 'notfound' diff --git a/test/message/esm_display_syntax_error_import_module.mjs b/test/message/esm_display_syntax_error_import_module.mjs index 346b3489fd920d..c0345c44fb3fda 100644 --- a/test/message/esm_display_syntax_error_import_module.mjs +++ b/test/message/esm_display_syntax_error_import_module.mjs @@ -1,3 +1,2 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import '../fixtures/es-module-loaders/syntax-error-import.mjs'; diff --git a/test/message/esm_display_syntax_error_module.mjs b/test/message/esm_display_syntax_error_module.mjs index 1f2b87ecd0cb1a..da40a4ead8d3c1 100644 --- a/test/message/esm_display_syntax_error_module.mjs +++ b/test/message/esm_display_syntax_error_module.mjs @@ -1,3 +1,2 @@ -// Flags: --experimental-modules import '../common/index.mjs'; import '../fixtures/es-module-loaders/syntax-error.mjs'; diff --git a/test/message/esm_loader_not_found.mjs b/test/message/esm_loader_not_found.mjs new file mode 100644 index 00000000000000..2b47e5a03ec9e6 --- /dev/null +++ b/test/message/esm_loader_not_found.mjs @@ -0,0 +1,3 @@ +// Flags: --experimental-loader i-dont-exist +import '../common/index.mjs'; +console.log('This should not be printed'); diff --git a/test/message/esm_loader_not_found.out b/test/message/esm_loader_not_found.out new file mode 100644 index 00000000000000..b03b7641af072b --- /dev/null +++ b/test/message/esm_loader_not_found.out @@ -0,0 +1,18 @@ +(node:*) ExperimentalWarning: The ESM module loader is experimental. +(node:*) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time +internal/modules/esm/default_resolve.js:* + let url = moduleWrapResolve(specifier, parentURL); + ^ + +Error: Cannot find package 'i-dont-exist' imported from * + at Loader.resolve [as _resolve] (internal/modules/esm/default_resolve.js:*:*) + at Loader.resolve (internal/modules/esm/loader.js:*:*) + at Loader.getModuleJob (internal/modules/esm/loader.js:*:*) + at Loader.import (internal/modules/esm/loader.js:*:*) + at internal/process/esm_loader.js:*:* + at Object.initializeLoader (internal/process/esm_loader.js:*:*) + at runMainESM (internal/modules/run_main.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) + at internal/main/run_main_module.js:*:* { + code: 'ERR_MODULE_NOT_FOUND' +} diff --git a/test/message/esm_loader_syntax_error.mjs b/test/message/esm_loader_syntax_error.mjs new file mode 100644 index 00000000000000..68cde42e585644 --- /dev/null +++ b/test/message/esm_loader_syntax_error.mjs @@ -0,0 +1,3 @@ +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/syntax-error.mjs +import '../common/index.mjs'; +console.log('This should not be printed'); diff --git a/test/message/esm_loader_syntax_error.out b/test/message/esm_loader_syntax_error.out new file mode 100644 index 00000000000000..9767a9c86c6bc2 --- /dev/null +++ b/test/message/esm_loader_syntax_error.out @@ -0,0 +1,9 @@ +(node:*) ExperimentalWarning: The ESM module loader is experimental. +(node:*) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time +file://*/test/fixtures/es-module-loaders/syntax-error.mjs:2 +await async () => 0; +^^^^^ + +SyntaxError: Unexpected reserved word + at Loader.moduleStrategy (internal/modules/esm/translators.js:*:*) + at async link (internal/modules/esm/module_job.js:*:*) diff --git a/test/message/events_unhandled_error_common_trace.out b/test/message/events_unhandled_error_common_trace.out index 610ea6064ddc00..72dbe47629b94c 100644 --- a/test/message/events_unhandled_error_common_trace.out +++ b/test/message/events_unhandled_error_common_trace.out @@ -10,7 +10,7 @@ Error: foo:bar at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* Emitted 'error' event at: at quux (*events_unhandled_error_common_trace.js:*:*) diff --git a/test/message/events_unhandled_error_nexttick.out b/test/message/events_unhandled_error_nexttick.out index f592d91b52c099..75eb666222f899 100644 --- a/test/message/events_unhandled_error_nexttick.out +++ b/test/message/events_unhandled_error_nexttick.out @@ -8,7 +8,7 @@ Error at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* Emitted 'error' event at: at *events_unhandled_error_nexttick.js:*:* diff --git a/test/message/events_unhandled_error_sameline.out b/test/message/events_unhandled_error_sameline.out index 798061a39bac8b..241412d5a83220 100644 --- a/test/message/events_unhandled_error_sameline.out +++ b/test/message/events_unhandled_error_sameline.out @@ -8,7 +8,7 @@ Error at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* Emitted 'error' event at: at Object.<anonymous> (*events_unhandled_error_sameline.js:*:*) diff --git a/test/message/events_unhandled_error_subclass.out b/test/message/events_unhandled_error_subclass.out index 970533299ac60b..859bd4980eb9b4 100644 --- a/test/message/events_unhandled_error_subclass.out +++ b/test/message/events_unhandled_error_subclass.out @@ -8,7 +8,7 @@ Error at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* Emitted 'error' event on Foo instance at: at Object.<anonymous> (*events_unhandled_error_subclass.js:*:*) diff --git a/test/message/if-error-has-good-stack.out b/test/message/if-error-has-good-stack.out index 87261c451fff1e..24a8f7beb4daaf 100644 --- a/test/message/if-error-has-good-stack.out +++ b/test/message/if-error-has-good-stack.out @@ -15,7 +15,7 @@ AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* { generatedMessage: false, code: 'ERR_ASSERTION', @@ -28,7 +28,7 @@ AssertionError [ERR_ASSERTION]: ifError got unwanted exception: test error at Object.Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) at internal/main/run_main_module.js:*:* expected: null, operator: 'ifError' diff --git a/test/message/stdin_messages.js b/test/message/stdin_messages.js index 66e06282b3b3e2..79475bd4d217b6 100644 --- a/test/message/stdin_messages.js +++ b/test/message/stdin_messages.js @@ -40,8 +40,8 @@ const queue = [ 'with(this){__filename}', '42', 'throw new Error("hello")', - 'var x = 100; y = x;', - 'var ______________________________________________; throw 10' ]; + 'let x = 100; y = x;', + 'let ______________________________________________; throw 10' ]; function go() { const c = queue.shift(); diff --git a/test/message/stdin_messages.out b/test/message/stdin_messages.out index 58bbe110297f8c..72edb0b00b28cd 100644 --- a/test/message/stdin_messages.out +++ b/test/message/stdin_messages.out @@ -48,7 +48,7 @@ Error: hello at endReadableNT (_stream_readable.js:*:*) 100 [stdin]:1 -var x = 100; y = x; +let x = 100; y = x; ^ ReferenceError: y is not defined @@ -64,13 +64,13 @@ ReferenceError: y is not defined at endReadableNT (_stream_readable.js:*:*) [stdin]:1 -var ______________________________________________; throw 10 +let ______________________________________________; throw 10 ^ 10 (Use `node --trace-uncaught ...` to show where the exception was thrown) [stdin]:1 -var ______________________________________________; throw 10 +let ______________________________________________; throw 10 ^ 10 (Use `node --trace-uncaught ...` to show where the exception was thrown) diff --git a/test/message/throw_error_with_getter_throw_traced.out b/test/message/throw_error_with_getter_throw_traced.out index 5ea6aa8e269662..8f89c09b24b26d 100644 --- a/test/message/throw_error_with_getter_throw_traced.out +++ b/test/message/throw_error_with_getter_throw_traced.out @@ -9,4 +9,4 @@ Thrown at: at Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Module._load (internal/modules/cjs/loader.js:*:*) - at Module.runMain (internal/modules/cjs/loader.js:*:*) + at executeUserEntryPoint (internal/modules/run_main.js:*:*) diff --git a/test/message/throw_null_traced.out b/test/message/throw_null_traced.out index 44bc34dcbd7434..887de70ef80335 100644 --- a/test/message/throw_null_traced.out +++ b/test/message/throw_null_traced.out @@ -9,4 +9,4 @@ Thrown at: at Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Module._load (internal/modules/cjs/loader.js:*:*) - at Module.runMain (internal/modules/cjs/loader.js:*:*) + at executeUserEntryPoint (internal/modules/run_main.js:*:*) diff --git a/test/message/throw_undefined_traced.out b/test/message/throw_undefined_traced.out index 070e9a1ec1c104..81e2e20c5ff6e5 100644 --- a/test/message/throw_undefined_traced.out +++ b/test/message/throw_undefined_traced.out @@ -9,4 +9,4 @@ Thrown at: at Module._extensions..js (internal/modules/cjs/loader.js:*:*) at Module.load (internal/modules/cjs/loader.js:*:*) at Module._load (internal/modules/cjs/loader.js:*:*) - at Module.runMain (internal/modules/cjs/loader.js:*:*) + at executeUserEntryPoint (internal/modules/run_main.js:*:*) diff --git a/test/message/undefined_reference_in_new_context.out b/test/message/undefined_reference_in_new_context.out index 9cc5eced7ceaa2..77ff35479b3a0d 100644 --- a/test/message/undefined_reference_in_new_context.out +++ b/test/message/undefined_reference_in_new_context.out @@ -13,4 +13,4 @@ ReferenceError: foo is not defined at *..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*:*) diff --git a/test/message/vm_display_runtime_error.out b/test/message/vm_display_runtime_error.out index 7927510c4152ee..e944f150ad28b6 100644 --- a/test/message/vm_display_runtime_error.out +++ b/test/message/vm_display_runtime_error.out @@ -12,7 +12,7 @@ Error: boo! at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* test.vm:1 throw new Error("spooky!") @@ -27,5 +27,5 @@ Error: spooky! at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* diff --git a/test/message/vm_display_syntax_error.out b/test/message/vm_display_syntax_error.out index 71d4a0ea1311f9..efffe9eb4bc9bc 100644 --- a/test/message/vm_display_syntax_error.out +++ b/test/message/vm_display_syntax_error.out @@ -11,7 +11,7 @@ SyntaxError: Unexpected number at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* test.vm:1 var 5; @@ -25,5 +25,5 @@ SyntaxError: Unexpected number at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* diff --git a/test/message/vm_dont_display_runtime_error.out b/test/message/vm_dont_display_runtime_error.out index 831ec8b6be4eab..1561d13c82ac29 100644 --- a/test/message/vm_dont_display_runtime_error.out +++ b/test/message/vm_dont_display_runtime_error.out @@ -13,5 +13,5 @@ Error: boo! at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* diff --git a/test/message/vm_dont_display_syntax_error.out b/test/message/vm_dont_display_syntax_error.out index 22924e7a6e72e1..5048ad69f5dedb 100644 --- a/test/message/vm_dont_display_syntax_error.out +++ b/test/message/vm_dont_display_syntax_error.out @@ -13,5 +13,5 @@ SyntaxError: Unexpected number at Object.Module._extensions..js (internal/modules/cjs/loader.js:*) at Module.load (internal/modules/cjs/loader.js:*) at Function.Module._load (internal/modules/cjs/loader.js:*) - at Function.Module.runMain (internal/modules/cjs/loader.js:*) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:*) at internal/main/run_main_module.js:*:* diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js index c963630f5d32ab..55a989a9672df6 100644 --- a/test/parallel/test-bootstrap-modules.js +++ b/test/parallel/test-bootstrap-modules.js @@ -46,8 +46,16 @@ const expectedModules = new Set([ 'NativeModule internal/fs/utils', 'NativeModule internal/idna', 'NativeModule internal/linkedlist', + 'NativeModule internal/modules/run_main', 'NativeModule internal/modules/cjs/helpers', 'NativeModule internal/modules/cjs/loader', + 'NativeModule internal/modules/esm/create_dynamic_module', + 'NativeModule internal/modules/esm/default_resolve', + 'NativeModule internal/modules/esm/loader', + 'NativeModule internal/modules/esm/module_job', + 'NativeModule internal/modules/esm/module_map', + 'NativeModule internal/modules/esm/translators', + 'NativeModule internal/process/esm_loader', 'NativeModule internal/options', 'NativeModule internal/priority_queue', 'NativeModule internal/process/execution', @@ -64,6 +72,7 @@ const expectedModules = new Set([ 'NativeModule internal/util/inspect', 'NativeModule internal/util/types', 'NativeModule internal/validators', + 'NativeModule internal/vm/module', 'NativeModule path', 'NativeModule timers', 'NativeModule url', diff --git a/test/parallel/test-child-process-advanced-serialization.js b/test/parallel/test-child-process-advanced-serialization.js new file mode 100644 index 00000000000000..0424f14a060908 --- /dev/null +++ b/test/parallel/test-child-process-advanced-serialization.js @@ -0,0 +1,46 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const child_process = require('child_process'); +const { once } = require('events'); + +if (process.argv[2] !== 'child') { + for (const value of [null, 42, Infinity, 'foo']) { + common.expectsError(() => { + child_process.spawn(process.execPath, [], { serialization: value }); + }, { + code: 'ERR_INVALID_OPT_VALUE', + message: `The value "${value}" is invalid ` + + 'for option "options.serialization"' + }); + } + + (async () => { + const cp = child_process.spawn(process.execPath, [__filename, 'child'], + { + stdio: ['ipc', 'inherit', 'inherit'], + serialization: 'advanced' + }); + + const circular = {}; + circular.circular = circular; + for await (const message of [ + { uint8: new Uint8Array(4) }, + { float64: new Float64Array([ Math.PI ]) }, + { buffer: Buffer.from('Hello!') }, + { map: new Map([{ a: 1 }, { b: 2 }]) }, + { bigInt: 1337n }, + circular, + new Error('Something went wrong'), + new RangeError('Something range-y went wrong'), + ]) { + cp.send(message); + const [ received ] = await once(cp, 'message'); + assert.deepStrictEqual(received, message); + } + + cp.disconnect(); + })().then(common.mustCall()); +} else { + process.on('message', (msg) => process.send(msg)); +} diff --git a/test/parallel/test-cli-eval.js b/test/parallel/test-cli-eval.js index 0d2ea48c06fa39..2cece62a437d52 100644 --- a/test/parallel/test-cli-eval.js +++ b/test/parallel/test-cli-eval.js @@ -234,7 +234,7 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`, // Assert that "42\n" is written to stdout on module eval. -const execOptions = '--experimental-modules --input-type module'; +const execOptions = '--input-type module'; child.exec( `${nodejs} ${execOptions} --eval "console.log(42)"`, common.mustCall((err, stdout) => { diff --git a/test/parallel/test-cli-syntax-piped-bad.js b/test/parallel/test-cli-syntax-piped-bad.js index 5da5f07e57d0ad..abd924848fc417 100644 --- a/test/parallel/test-cli-syntax-piped-bad.js +++ b/test/parallel/test-cli-syntax-piped-bad.js @@ -39,7 +39,7 @@ syntaxArgs.forEach(function(arg) { const stdin = 'export var p = 5; var foo bar;'; const c = spawnSync( node, - ['--experimental-modules', '--input-type=module', '--no-warnings', arg], + ['--input-type=module', '--no-warnings', arg], { encoding: 'utf8', input: stdin } ); diff --git a/test/parallel/test-cli-syntax-piped-good.js b/test/parallel/test-cli-syntax-piped-good.js index 5df5eb1c51d105..43de5d32f40d40 100644 --- a/test/parallel/test-cli-syntax-piped-good.js +++ b/test/parallel/test-cli-syntax-piped-good.js @@ -30,7 +30,7 @@ syntaxArgs.forEach(function(arg) { const stdin = 'export var p = 5; throw new Error("should not get run");'; const c = spawnSync( node, - ['--experimental-modules', '--no-warnings', '--input-type=module', arg], + ['--no-warnings', '--input-type=module', arg], { encoding: 'utf8', input: stdin } ); diff --git a/test/parallel/test-cluster-advanced-serialization.js b/test/parallel/test-cluster-advanced-serialization.js new file mode 100644 index 00000000000000..2144d08f28702b --- /dev/null +++ b/test/parallel/test-cluster-advanced-serialization.js @@ -0,0 +1,22 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cluster = require('cluster'); + +if (cluster.isMaster) { + cluster.settings.serialization = 'advanced'; + const worker = cluster.fork(); + const circular = {}; + circular.circular = circular; + + worker.on('online', common.mustCall(() => { + worker.send(circular); + + worker.on('message', common.mustCall((msg) => { + assert.deepStrictEqual(msg, circular); + worker.kill(); + })); + })); +} else { + process.on('message', (msg) => process.send(msg)); +} diff --git a/test/parallel/test-crypto-key-objects.js b/test/parallel/test-crypto-key-objects.js index 15de241b358fb1..dc995be041ed48 100644 --- a/test/parallel/test-crypto-key-objects.js +++ b/test/parallel/test-crypto-key-objects.js @@ -15,8 +15,10 @@ const { createPrivateKey, KeyObject, randomBytes, + publicDecrypt, publicEncrypt, - privateDecrypt + privateDecrypt, + privateEncrypt } = require('crypto'); const fixtures = require('../common/fixtures'); @@ -156,7 +158,16 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', assert(Buffer.isBuffer(privateDER)); const plaintext = Buffer.from('Hello world', 'utf8'); - const ciphertexts = [ + const testDecryption = (fn, ciphertexts, decryptionKeys) => { + for (const ciphertext of ciphertexts) { + for (const key of decryptionKeys) { + const deciphered = fn(key, ciphertext); + assert.deepStrictEqual(deciphered, plaintext); + } + } + }; + + testDecryption(privateDecrypt, [ // Encrypt using the public key. publicEncrypt(publicKey, plaintext), publicEncrypt({ key: publicKey }, plaintext), @@ -173,20 +184,25 @@ const privateDsa = fixtures.readKey('dsa_private_encrypted_1025.pem', // DER-encoded data only. publicEncrypt({ format: 'der', type: 'pkcs1', key: publicDER }, plaintext), publicEncrypt({ format: 'der', type: 'pkcs1', key: privateDER }, plaintext) - ]; - - const decryptionKeys = [ + ], [ privateKey, { format: 'pem', key: privatePem }, { format: 'der', type: 'pkcs1', key: privateDER } - ]; + ]); - for (const ciphertext of ciphertexts) { - for (const key of decryptionKeys) { - const deciphered = privateDecrypt(key, ciphertext); - assert(plaintext.equals(deciphered)); - } - } + testDecryption(publicDecrypt, [ + privateEncrypt(privateKey, plaintext) + ], [ + // Decrypt using the public key. + publicKey, + { format: 'pem', key: publicPem }, + { format: 'der', type: 'pkcs1', key: publicDER }, + + // Decrypt using the private key. + privateKey, + { format: 'pem', key: privatePem }, + { format: 'der', type: 'pkcs1', key: privateDER } + ]); } { diff --git a/test/parallel/test-crypto-sign-verify.js b/test/parallel/test-crypto-sign-verify.js index 66c7ac7d8014df..a16d25f540e1a8 100644 --- a/test/parallel/test-crypto-sign-verify.js +++ b/test/parallel/test-crypto-sign-verify.js @@ -500,21 +500,91 @@ common.expectsError( }); { - const privKey = fixtures.readKey('ec-key.pem'); const data = Buffer.from('Hello world'); - [ - crypto.createSign('sha1').update(data).sign(privKey), - crypto.sign('sha1', data, privKey) - ].forEach((sig) => { - // Signature length variability due to DER encoding - assert.strictEqual(sig.length >= 68, true); + const keys = [['ec-key.pem', 64], ['dsa_private_1025.pem', 40]]; + + for (const [file, length] of keys) { + const privKey = fixtures.readKey(file); + [ + crypto.createSign('sha1').update(data).sign(privKey), + crypto.sign('sha1', data, privKey), + crypto.sign('sha1', data, { key: privKey, dsaEncoding: 'der' }) + ].forEach((sig) => { + // Signature length variability due to DER encoding + assert(sig.length >= length + 4 && sig.length <= length + 8); + + assert.strictEqual( + crypto.createVerify('sha1').update(data).verify(privKey, sig), + true + ); + assert.strictEqual(crypto.verify('sha1', data, privKey, sig), true); + }); + // Test (EC)DSA signature conversion. + const opts = { key: privKey, dsaEncoding: 'ieee-p1363' }; + let sig = crypto.sign('sha1', data, opts); + // Unlike DER signatures, IEEE P1363 signatures have a predictable length. + assert.strictEqual(sig.length, length); + assert.strictEqual(crypto.verify('sha1', data, opts, sig), true); + + // Test invalid signature lengths. + for (const i of [-2, -1, 1, 2, 4, 8]) { + sig = crypto.randomBytes(length + i); + common.expectsError(() => { + crypto.verify('sha1', data, opts, sig); + }, { + message: 'Malformed signature' + }); + } + } + + // Test verifying externally signed messages. + const extSig = Buffer.from('494c18ab5c8a62a72aea5041966902bcfa229821af2bf65' + + '0b5b4870d1fe6aebeaed9460c62210693b5b0a300033823' + + '33d9529c8abd8c5948940af944828be16c', 'hex'); + for (const ok of [true, false]) { assert.strictEqual( - crypto.createVerify('sha1').update(data).verify(privKey, sig), - true + crypto.verify('sha256', data, { + key: fixtures.readKey('ec-key.pem'), + dsaEncoding: 'ieee-p1363' + }, extSig), + ok ); - assert.strictEqual(crypto.verify('sha1', data, privKey, sig), true); + + extSig[Math.floor(Math.random() * extSig.length)] ^= 1; + } + + // Non-(EC)DSA keys should ignore the option. + const sig = crypto.sign('sha1', data, { + key: keyPem, + dsaEncoding: 'ieee-p1363' }); + assert.strictEqual(crypto.verify('sha1', data, certPem, sig), true); + assert.strictEqual( + crypto.verify('sha1', data, { + key: certPem, + dsaEncoding: 'ieee-p1363' + }, sig), + true + ); + assert.strictEqual( + crypto.verify('sha1', data, { + key: certPem, + dsaEncoding: 'der' + }, sig), + true + ); + + for (const dsaEncoding of ['foo', null, {}, 5, true, NaN]) { + common.expectsError(() => { + crypto.sign('sha1', data, { + key: certPem, + dsaEncoding + }); + }, { + code: 'ERR_INVALID_OPT_VALUE' + }); + } } diff --git a/test/parallel/test-dgram-bind-error-repeat.js b/test/parallel/test-dgram-bind-error-repeat.js new file mode 100644 index 00000000000000..a520d30a519cd2 --- /dev/null +++ b/test/parallel/test-dgram-bind-error-repeat.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +// Regression test for https://github.com/nodejs/node/issues/30209 +// No warning should be emitted when re-trying `.bind()` on UDP sockets +// repeatedly. + +process.on('warning', common.mustNotCall()); + +const reservePortSocket = dgram.createSocket('udp4'); +reservePortSocket.bind(() => { + const { port } = reservePortSocket.address(); + + const newSocket = dgram.createSocket('udp4'); + + let errors = 0; + newSocket.on('error', common.mustCall(() => { + if (++errors < 20) { + newSocket.bind(port, common.mustNotCall()); + } else { + newSocket.close(); + reservePortSocket.close(); + } + }, 20)); + newSocket.bind(port, common.mustNotCall()); +}); diff --git a/test/internet/test-dgram-send-cb-quelches-error.js b/test/parallel/test-dgram-send-cb-quelches-error.js similarity index 86% rename from test/internet/test-dgram-send-cb-quelches-error.js rename to test/parallel/test-dgram-send-cb-quelches-error.js index 946b6bbb455325..106d2870c2fd42 100644 --- a/test/internet/test-dgram-send-cb-quelches-error.js +++ b/test/parallel/test-dgram-send-cb-quelches-error.js @@ -24,11 +24,11 @@ function callbackOnly(err) { assert.ok(err); socket.removeListener('error', onEvent); socket.on('error', mustCall(onError)); - socket.send(buffer, 0, buffer.length, 100, 'dne.example.com'); + socket.send(buffer, 0, buffer.length, 100, 'dne.invalid'); } function onEvent(err) { - assert.fail('Error should not be emitted if there is callback'); + assert.fail(`Error should not be emitted if there is callback: ${err}`); } function onError(err) { diff --git a/test/parallel/test-dns-lookupService.js b/test/parallel/test-dns-lookupService.js index f78e98766063f7..dc04893c28f9fd 100644 --- a/test/parallel/test-dns-lookupService.js +++ b/test/parallel/test-dns-lookupService.js @@ -5,11 +5,17 @@ const assert = require('assert'); const { internalBinding } = require('internal/test/binding'); const cares = internalBinding('cares_wrap'); const { UV_ENOENT } = internalBinding('uv'); -const dns = require('dns'); // Stub `getnameinfo` to *always* error. cares.getnameinfo = () => UV_ENOENT; +// Because dns promises is attached lazily, +// and turn accesses getnameinfo on init +// but this lazy access is triggered by ES named +// instead of lazily itself, we must require +// dns after hooking cares +const dns = require('dns'); + assert.throws( () => dns.lookupService('127.0.0.1', 80, common.mustNotCall()), { diff --git a/test/parallel/test-fs-open.js b/test/parallel/test-fs-open.js index 51cd9ecf319595..e33c4e9331a828 100644 --- a/test/parallel/test-fs-open.js +++ b/test/parallel/test-fs-open.js @@ -29,7 +29,7 @@ let caughtException = false; try { // Should throw ENOENT, not EBADF // see https://github.com/joyent/node/pull/1228 - fs.openSync('/path/to/file/that/does/not/exist', 'r'); + fs.openSync('/8hvftyuncxrt/path/to/file/that/does/not/exist', 'r'); } catch (e) { assert.strictEqual(e.code, 'ENOENT'); caughtException = true; diff --git a/test/parallel/test-fs-opendir.js b/test/parallel/test-fs-opendir.js index 05fded527fe7f1..7ae6186b28518a 100644 --- a/test/parallel/test-fs-opendir.js +++ b/test/parallel/test-fs-opendir.js @@ -33,6 +33,11 @@ const dirclosedError = { code: 'ERR_DIR_CLOSED' }; +const invalidCallbackObj = { + code: 'ERR_INVALID_CALLBACK', + name: 'TypeError' +}; + // Check the opendir Sync version { const dir = fs.opendirSync(testDir); @@ -205,3 +210,19 @@ for (const bufferSize of ['', '1', null]) { assertDirent(dir.readSync()); dir.close(); } + +// Check that when passing a string instead of function - throw an exception +async function doAsyncIterInvalidCallbackTest() { + const dir = await fs.promises.opendir(testDir); + assert.throws(() => dir.close('not function'), invalidCallbackObj); +} +doAsyncIterInvalidCallbackTest().then(common.mustCall()); + +// Check if directory already closed - throw an exception +async function doAsyncIterDirClosedTest() { + const dir = await fs.promises.opendir(testDir); + await dir.close(); + + assert.throws(() => dir.close(), dirclosedError); +} +doAsyncIterDirClosedTest().then(common.mustCall()); diff --git a/test/parallel/test-http-agent-domain-reused-gc.js b/test/parallel/test-http-agent-domain-reused-gc.js new file mode 100644 index 00000000000000..9470b23b472662 --- /dev/null +++ b/test/parallel/test-http-agent-domain-reused-gc.js @@ -0,0 +1,98 @@ +// Flags: --expose-gc --expose-internals +'use strict'; +const common = require('../common'); +const http = require('http'); +const async_hooks = require('async_hooks'); +const makeDuplexPair = require('../common/duplexpair'); + +// Regression test for https://github.com/nodejs/node/issues/30122 +// When a domain is attached to an http Agent’s ReusedHandle object, that +// domain should be kept alive through the ReusedHandle and that in turn +// through the actual underlying handle. + +// Consistency check: There is a ReusedHandle being used, and it emits events. +// We also use this async hook to manually trigger GC just before the domain’s +// own `before` hook runs, in order to reproduce the bug above (the ReusedHandle +// being collected and the domain with it while the handle is still alive). +const checkInitCalled = common.mustCall(); +const checkBeforeCalled = common.mustCallAtLeast(); +let reusedHandleId; +async_hooks.createHook({ + init(id, type, triggerId, resource) { + if (resource.constructor.name === 'ReusedHandle') { + reusedHandleId = id; + checkInitCalled(); + } + }, + before(id) { + if (id === reusedHandleId) { + global.gc(); + checkBeforeCalled(); + } + } +}).enable(); + +// We use a DuplexPair rather than TLS sockets to keep the domain from being +// attached to too many objects that use strong references (timers, the network +// socket handle, etc.) and wrap the client side in a JSStreamSocket so we don’t +// have to implement the whole _handle API ourselves. +const { serverSide, clientSide } = makeDuplexPair(); +const JSStreamSocket = require('internal/js_stream_socket'); +const wrappedClientSide = new JSStreamSocket(clientSide); + +// Consistency check: We use asyncReset exactly once. +wrappedClientSide._handle.asyncReset = + common.mustCall(wrappedClientSide._handle.asyncReset); + +// Dummy server implementation, could be any server for this test... +const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, { + 'Content-Type': 'text/plain' + }); + res.end('Hello, world!'); +}, 2)); +server.emit('connection', serverSide); + +// HTTP Agent that only returns the fake connection. +class TestAgent extends http.Agent { + createConnection = common.mustCall(() => wrappedClientSide) +} +const agent = new TestAgent({ keepAlive: true, maxSockets: 1 }); + +function makeRequest(cb) { + const req = http.request({ agent }, common.mustCall((res) => { + res.resume(); + res.on('end', cb); + })); + req.end(''); +} + +// The actual test starts here: + +const domain = require('domain'); +// Create the domain in question and a dummy “noDomain” domain that we use to +// avoid attaching new async resources to the original domain. +const d = domain.create(); +const noDomain = domain.create(); + +d.run(common.mustCall(() => { + // Create a first request only so that we can get a “re-used” socket later. + makeRequest(common.mustCall(() => { + // Schedule the second request. + setImmediate(common.mustCall(() => { + makeRequest(common.mustCall(() => { + // The `setImmediate()` is run inside of `noDomain` so that it doesn’t + // keep the actual target domain alive unnecessarily. + noDomain.run(common.mustCall(() => { + setImmediate(common.mustCall(() => { + // This emits an async event on the reused socket, so it should + // run the domain’s `before` hooks. + // This should *not* throw an error because the domain was garbage + // collected too early. + serverSide.end(); + })); + })); + })); + })); + })); +})); diff --git a/test/parallel/test-http-dump-req-when-res-ends.js b/test/parallel/test-http-dump-req-when-res-ends.js index 718797fae1fe68..01dbbca1b393fb 100644 --- a/test/parallel/test-http-dump-req-when-res-ends.js +++ b/test/parallel/test-http-dump-req-when-res-ends.js @@ -48,8 +48,12 @@ server.listen(0, mustCall(function() { res.resume(); - // Wait for the response. - res.on('end', function() { + // On some platforms the `'end'` event might not be emitted because the + // socket could be destroyed by the other peer while data is still being + // sent. In this case the 'aborted'` event is emitted instead of `'end'`. + // `'close'` is used here because it is always emitted and does not + // invalidate the test. + res.on('close', function() { server.close(); }); })); diff --git a/test/parallel/test-http-response-cork.js b/test/parallel/test-http-response-cork.js new file mode 100644 index 00000000000000..4c85412c7bfcec --- /dev/null +++ b/test/parallel/test-http-response-cork.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer((req, res) => { + let corked = false; + const originalWrite = res.socket.write; + res.socket.write = common.mustCall((...args) => { + assert.strictEqual(corked, false); + return originalWrite.call(res.socket, ...args); + }, 5); + corked = true; + res.cork(); + assert.strictEqual(res.writableCorked, res.socket.writableCorked); + res.cork(); + assert.strictEqual(res.writableCorked, res.socket.writableCorked); + res.writeHead(200, { 'a-header': 'a-header-value' }); + res.uncork(); + assert.strictEqual(res.writableCorked, res.socket.writableCorked); + corked = false; + res.end('asd'); + assert.strictEqual(res.writableCorked, res.socket.writableCorked); +}); + +server.listen(0, () => { + http.get({ port: server.address().port }, (res) => { + res.on('data', common.mustCall()); + res.on('end', common.mustCall(() => { + server.close(); + })); + }); +}); diff --git a/test/parallel/test-http-set-trailers.js b/test/parallel/test-http-set-trailers.js index 921c456bdaddfd..2197de9b0b229a 100644 --- a/test/parallel/test-http-set-trailers.js +++ b/test/parallel/test-http-set-trailers.js @@ -26,29 +26,18 @@ const http = require('http'); const net = require('net'); const util = require('util'); -let outstanding_reqs = 0; - -const server = http.createServer(function(req, res) { - res.writeHead(200, [['content-type', 'text/plain']]); - res.addTrailers({ 'x-foo': 'bar' }); - res.end('stuff\n'); -}); -server.listen(0); - - // First, we test an HTTP/1.0 request. -server.on('listening', function() { - const c = net.createConnection(this.address().port); - let res_buffer = ''; +function testHttp10(port, callback) { + const c = net.createConnection(port); c.setEncoding('utf8'); - c.on('connect', function() { - outstanding_reqs++; + c.on('connect', () => { c.write('GET / HTTP/1.0\r\n\r\n'); }); - c.on('data', function(chunk) { + let res_buffer = ''; + c.on('data', (chunk) => { res_buffer += chunk; }); @@ -56,61 +45,58 @@ server.on('listening', function() { c.end(); assert.ok( !/x-foo/.test(res_buffer), - `Trailer in HTTP/1.0 response. Response buffer: ${res_buffer}` + `No trailer in HTTP/1.0 response. Response buffer: ${res_buffer}` ); - outstanding_reqs--; - if (outstanding_reqs === 0) { - server.close(); - } + callback(); }); -}); +} // Now, we test an HTTP/1.1 request. -server.on('listening', function() { - const c = net.createConnection(this.address().port); - let res_buffer = ''; - let tid; +function testHttp11(port, callback) { + const c = net.createConnection(port); c.setEncoding('utf8'); + let tid; c.on('connect', function() { - outstanding_reqs++; c.write('GET / HTTP/1.1\r\n\r\n'); tid = setTimeout(common.mustNotCall(), 2000, 'Couldn\'t find last chunk.'); }); + let res_buffer = ''; c.on('data', function(chunk) { res_buffer += chunk; if (/0\r\n/.test(res_buffer)) { // got the end. - outstanding_reqs--; clearTimeout(tid); assert.ok( /0\r\nx-foo: bar\r\n\r\n$/.test(res_buffer), `No trailer in HTTP/1.1 response. Response buffer: ${res_buffer}` ); - if (outstanding_reqs === 0) { - server.close(); - } + callback(); } }); -}); +} // Now, see if the client sees the trailers. -server.on('listening', function() { - http.get({ - port: this.address().port, - path: '/hello', - headers: {} - }, function(res) { +function testClientTrailers(port, callback) { + http.get({ port, path: '/hello', headers: {} }, (res) => { res.on('end', function() { assert.ok('x-foo' in res.trailers, `${util.inspect(res.trailers)} misses the 'x-foo' property`); - outstanding_reqs--; - if (outstanding_reqs === 0) { - server.close(); - } + callback(); }); res.resume(); }); - outstanding_reqs++; +} + +const server = http.createServer((req, res) => { + res.writeHead(200, [['content-type', 'text/plain']]); + res.addTrailers({ 'x-foo': 'bar' }); + res.end('stuff\n'); +}); +server.listen(0, () => { + Promise.all([testHttp10, testHttp11, testClientTrailers] + .map(util.promisify) + .map((f) => f(server.address().port))) + .then(() => server.close()); }); diff --git a/test/parallel/test-http2-createsecureserver-nooptions.js b/test/parallel/test-http2-createsecureserver-nooptions.js deleted file mode 100644 index 22a7562388c75a..00000000000000 --- a/test/parallel/test-http2-createsecureserver-nooptions.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; - -const common = require('../common'); -if (!common.hasCrypto) - common.skip('missing crypto'); - -const assert = require('assert'); -const http2 = require('http2'); - -// Error if options are not passed to createSecureServer -const invalidOptions = [() => {}, 1, 'test', null]; -invalidOptions.forEach((invalidOption) => { - assert.throws( - () => http2.createSecureServer(invalidOption), - { - name: 'TypeError', - code: 'ERR_INVALID_ARG_TYPE', - message: 'The "options" argument must be of type Object. Received ' + - `type ${typeof invalidOption}` - } - ); -}); diff --git a/test/parallel/test-http2-createsecureserver-options.js b/test/parallel/test-http2-createsecureserver-options.js new file mode 100644 index 00000000000000..4ef85a45b5b84b --- /dev/null +++ b/test/parallel/test-http2-createsecureserver-options.js @@ -0,0 +1,35 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const http2 = require('http2'); + +// Error if invalid options are passed to createSecureServer +const invalidOptions = [() => {}, 1, 'test', null, Symbol('test')]; +invalidOptions.forEach((invalidOption) => { + assert.throws( + () => http2.createSecureServer(invalidOption), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "options" argument must be of type Object. Received ' + + `type ${typeof invalidOption}` + } + ); +}); + +// Error if invalid options.settings are passed to createSecureServer +invalidOptions.forEach((invalidSettingsOption) => { + assert.throws( + () => http2.createSecureServer({ settings: invalidSettingsOption }), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "options.settings" property must be of type Object. ' + + `Received type ${typeof invalidSettingsOption}` + } + ); +}); diff --git a/test/parallel/test-http2-createserver-options.js b/test/parallel/test-http2-createserver-options.js new file mode 100644 index 00000000000000..d322506f55e3e0 --- /dev/null +++ b/test/parallel/test-http2-createserver-options.js @@ -0,0 +1,35 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const http2 = require('http2'); + +// Error if invalid options are passed to createServer +const invalidOptions = [1, true, 'test', null, Symbol('test')]; +invalidOptions.forEach((invalidOption) => { + assert.throws( + () => http2.createServer(invalidOption), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "options" argument must be of type Object. Received ' + + `type ${typeof invalidOption}` + } + ); +}); + +// Error if invalid options.settings are passed to createServer +invalidOptions.forEach((invalidSettingsOption) => { + assert.throws( + () => http2.createServer({ settings: invalidSettingsOption }), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "options.settings" property must be of type Object. ' + + `Received type ${typeof invalidSettingsOption}` + } + ); +}); diff --git a/test/parallel/test-https-agent-keylog.js b/test/parallel/test-https-agent-keylog.js new file mode 100644 index 00000000000000..2fc13cbe6d8549 --- /dev/null +++ b/test/parallel/test-https-agent-keylog.js @@ -0,0 +1,44 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const https = require('https'); +const fixtures = require('../common/fixtures'); + +const server = https.createServer({ + key: fixtures.readKey('agent2-key.pem'), + cert: fixtures.readKey('agent2-cert.pem'), + // Amount of keylog events depends on negotiated protocol + // version, so force a specific one: + minVersion: 'TLSv1.3', + maxVersion: 'TLSv1.3', +}, (req, res) => { + res.end('bye'); +}).listen(() => { + https.get({ + port: server.address().port, + rejectUnauthorized: false, + }, (res) => { + res.resume(); + res.on('end', () => { + // Trigger TLS connection reuse + https.get({ + port: server.address().port, + rejectUnauthorized: false, + }, (res) => { + server.close(); + res.resume(); + }); + }); + }); +}); + +const verifyKeylog = (line, tlsSocket) => { + assert(Buffer.isBuffer(line)); + assert.strictEqual(tlsSocket.encrypted, true); +}; +server.on('keylog', common.mustCall(verifyKeylog, 10)); +https.globalAgent.on('keylog', common.mustCall(verifyKeylog, 10)); diff --git a/test/parallel/test-inspector-esm.js b/test/parallel/test-inspector-esm.js index b5f55b68d717ff..f0848d29423d9e 100644 --- a/test/parallel/test-inspector-esm.js +++ b/test/parallel/test-inspector-esm.js @@ -99,8 +99,8 @@ async function testBreakpoint(session) { } async function runTest() { - const child = new NodeInstance(['--inspect-brk=0', '--experimental-modules'], - '', fixtures.path('es-modules/loop.mjs')); + const child = new NodeInstance(['--inspect-brk=0'], '', + fixtures.path('es-modules/loop.mjs')); const session = await child.connectInspectorSession(); await testBreakpointOnStart(session); diff --git a/test/parallel/test-loaders-unknown-builtin-module.mjs b/test/parallel/test-loaders-unknown-builtin-module.mjs index b0b1d400e6904e..464dbeb22a9b31 100644 --- a/test/parallel/test-loaders-unknown-builtin-module.mjs +++ b/test/parallel/test-loaders-unknown-builtin-module.mjs @@ -1,4 +1,4 @@ -// Flags: --experimental-modules --experimental-loader ./test/fixtures/es-module-loaders/loader-unknown-builtin-module.mjs +// Flags: --experimental-loader ./test/fixtures/es-module-loaders/loader-unknown-builtin-module.mjs import { expectsError, mustCall } from '../common/index.mjs'; import assert from 'assert'; diff --git a/test/parallel/test-module-binding.js b/test/parallel/test-module-binding.js index 07c4965f2204f3..d0e122605ddc00 100644 --- a/test/parallel/test-module-binding.js +++ b/test/parallel/test-module-binding.js @@ -8,9 +8,8 @@ const { readFileSync } = require('fs'); const { strictEqual } = require('assert'); strictEqual(internalModuleReadJSON('nosuchfile'), undefined); -strictEqual(internalModuleReadJSON(fixtures.path('empty.txt')), undefined); -strictEqual(internalModuleReadJSON(fixtures.path('empty-with-bom.txt')), - undefined); +strictEqual(internalModuleReadJSON(fixtures.path('empty.txt')), '{}'); +strictEqual(internalModuleReadJSON(fixtures.path('empty-with-bom.txt')), '{}'); { const filename = fixtures.path('require-bin/package.json'); strictEqual(internalModuleReadJSON(filename), readFileSync(filename, 'utf8')); diff --git a/test/parallel/test-module-main-extension-lookup.js b/test/parallel/test-module-main-extension-lookup.js index 9e7eab295e8795..58d78e09b1199e 100644 --- a/test/parallel/test-module-main-extension-lookup.js +++ b/test/parallel/test-module-main-extension-lookup.js @@ -5,7 +5,5 @@ const { execFileSync } = require('child_process'); const node = process.argv[0]; -execFileSync(node, ['--experimental-modules', - fixtures.path('es-modules', 'test-esm-ok.mjs')]); -execFileSync(node, ['--experimental-modules', - fixtures.path('es-modules', 'noext')]); +execFileSync(node, [fixtures.path('es-modules', 'test-esm-ok.mjs')]); +execFileSync(node, [fixtures.path('es-modules', 'noext')]); diff --git a/test/parallel/test-module-main-fail.js b/test/parallel/test-module-main-fail.js index a6457f33b659dd..c66b6f2f7a843f 100644 --- a/test/parallel/test-module-main-fail.js +++ b/test/parallel/test-module-main-fail.js @@ -4,18 +4,15 @@ const assert = require('assert'); const { execFileSync } = require('child_process'); const entryPoints = ['iDoNotExist', 'iDoNotExist.js', 'iDoNotExist.mjs']; -const flags = [[], ['--experimental-modules']]; const node = process.argv[0]; -for (const args of flags) { - for (const entryPoint of entryPoints) { - try { - execFileSync(node, args.concat(entryPoint), { stdio: 'pipe' }); - } catch (e) { - assert(e.toString().match(/Error: Cannot find module/)); - continue; - } - assert.fail('Executing node with inexistent entry point should ' + - `fail. Entry point: ${entryPoint}, Flags: [${args}]`); +for (const entryPoint of entryPoints) { + try { + execFileSync(node, [entryPoint], { stdio: 'pipe' }); + } catch (e) { + assert(e.toString().match(/Error: Cannot find module/)); + continue; } + assert.fail('Executing node with inexistent entry point should ' + + `fail. Entry point: ${entryPoint}`); } diff --git a/test/parallel/test-module-main-preserve-symlinks-fail.js b/test/parallel/test-module-main-preserve-symlinks-fail.js index b46497b625261f..bbaf451c3ce539 100644 --- a/test/parallel/test-module-main-preserve-symlinks-fail.js +++ b/test/parallel/test-module-main-preserve-symlinks-fail.js @@ -4,7 +4,7 @@ const assert = require('assert'); const { execFileSync } = require('child_process'); const entryPoints = ['iDoNotExist', 'iDoNotExist.js', 'iDoNotExist.mjs']; -const flags = [[], ['--experimental-modules', '--preserve-symlinks']]; +const flags = [[], ['--preserve-symlinks']]; const node = process.argv[0]; for (const args of flags) { diff --git a/test/parallel/test-module-run-main-monkey-patch.js b/test/parallel/test-module-run-main-monkey-patch.js new file mode 100644 index 00000000000000..c9f189abb68821 --- /dev/null +++ b/test/parallel/test-module-run-main-monkey-patch.js @@ -0,0 +1,18 @@ +'use strict'; + +// This tests that module.runMain can be monkey patched using --require. +// TODO(joyeecheung): This probably should be deprecated. + +require('../common'); +const { path } = require('../common/fixtures'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +const child = spawnSync(process.execPath, [ + '--require', + path('monkey-patch-run-main.js'), + path('semicolon.js'), +]); + +assert.strictEqual(child.status, 0); +assert(child.stdout.toString().includes('runMain is monkey patched!')); diff --git a/test/parallel/test-readable-large-hwm.js b/test/parallel/test-readable-large-hwm.js new file mode 100644 index 00000000000000..d5bf25bc0e61c1 --- /dev/null +++ b/test/parallel/test-readable-large-hwm.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); + +// Make sure that readable completes +// even when reading larger buffer. +const bufferSize = 10 * 1024 * 1024; +let n = 0; +const r = new Readable({ + read() { + // Try to fill readable buffer piece by piece. + r.push(Buffer.alloc(bufferSize / 10)); + + if (n++ > 10) { + r.push(null); + } + } +}); + +r.on('readable', () => { + while (true) { + const ret = r.read(bufferSize); + if (ret === null) + break; + } +}); +r.on('end', common.mustCall()); diff --git a/test/parallel/test-release-npm.js b/test/parallel/test-release-npm.js index 23d9cb39cea182..412cb0cc64acb7 100644 --- a/test/parallel/test-release-npm.js +++ b/test/parallel/test-release-npm.js @@ -7,12 +7,13 @@ const path = require('path'); const releaseReg = /^v\d+\.\d+\.\d+$/; -if (!releaseReg.test(process.version)) { +// Npm requires crypto support. +if (!releaseReg.test(process.version) || !common.hasCrypto) { common.skip('This test is only for release builds'); } { - // Verify that npm does not print out a warning when executed + // Verify that npm does not print out a warning when executed. const npmCli = path.join(__dirname, '../../deps/npm/bin/npm-cli.js'); const npmExec = child_process.spawnSync(process.execPath, [npmCli]); diff --git a/test/parallel/test-repl-editor.js b/test/parallel/test-repl-editor.js index dbc59742ac28f9..969f6172b3fb70 100644 --- a/test/parallel/test-repl-editor.js +++ b/test/parallel/test-repl-editor.js @@ -49,17 +49,17 @@ const tests = [ event: { ctrl: true, name: 'c' } }, { - input: 'var i = 1;', + input: 'let i = 1;', output: '', event: { ctrl: true, name: 'c' } }, { - input: 'var i = 1;\ni + 3', + input: 'let i = 1;\ni + 3', output: '\n4', event: { ctrl: true, name: 'd' } }, { - input: ' var i = 1;\ni + 3', + input: ' let i = 1;\ni + 3', output: '\n4', event: { ctrl: true, name: 'd' } }, @@ -102,20 +102,20 @@ function testCodeAlignment({ input, cursor = 0, line = '' }) { const codeAlignmentTests = [ { - input: 'var i = 1;\n' + input: 'let i = 1;\n' }, { - input: ' var i = 1;\n', + input: ' let i = 1;\n', cursor: 2, line: ' ' }, { - input: ' var i = 1;\n', + input: ' let i = 1;\n', cursor: 5, line: ' ' }, { - input: ' var i = 1;\n var j = 2\n', + input: ' let i = 1;\n let j = 2\n', cursor: 2, line: ' ' } diff --git a/test/parallel/test-repl-multiline.js b/test/parallel/test-repl-multiline.js index f789c06bf39378..454d5b10192fa5 100644 --- a/test/parallel/test-repl-multiline.js +++ b/test/parallel/test-repl-multiline.js @@ -5,7 +5,7 @@ const assert = require('assert'); const repl = require('repl'); const inputStream = new ArrayStream(); const outputStream = new ArrayStream(); -const input = ['var foo = {', '};', 'foo;']; +const input = ['const foo = {', '};', 'foo;']; let output = ''; outputStream.write = (data) => { output += data.replace('\r', ''); }; diff --git a/test/parallel/test-repl-unexpected-token-recoverable.js b/test/parallel/test-repl-unexpected-token-recoverable.js index 888ee81bd4e62a..2461d8f62bd2c8 100644 --- a/test/parallel/test-repl-unexpected-token-recoverable.js +++ b/test/parallel/test-repl-unexpected-token-recoverable.js @@ -10,7 +10,7 @@ const spawn = require('child_process').spawn; const args = [ '-i' ]; const child = spawn(process.execPath, args); -const input = 'var foo = "bar\\\nbaz"'; +const input = 'const foo = "bar\\\nbaz"'; // Match '...' as well since it marks a multi-line statement const expectOut = /> \.\.\. undefined\n/; diff --git a/test/parallel/test-source-map.js b/test/parallel/test-source-map.js index 2ded13a631dd8c..c14892890cb195 100644 --- a/test/parallel/test-source-map.js +++ b/test/parallel/test-source-map.js @@ -66,7 +66,6 @@ function nextdir() { const coverageDirectory = nextdir(); const output = spawnSync(process.execPath, [ '--no-warnings', - '--experimental-modules', require.resolve('../fixtures/source-map/esm-basic.mjs') ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); assert.strictEqual(output.stderr.toString(), ''); @@ -116,6 +115,38 @@ function nextdir() { ); } +// base64 encoding error does not crash application. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64-type-error.js') + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'inline-base64-type-error.js', + coverageDirectory + ); + + assert.strictEqual(sourceMap.data, null); +} + +// JSON error does not crash application. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64-json-error.js') + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'inline-base64-json-error.js', + coverageDirectory + ); + + assert.strictEqual(sourceMap.data, null); +} + // Does not apply source-map to stack trace if --experimental-modules // is not set. { @@ -185,7 +216,6 @@ function nextdir() { { const output = spawnSync(process.execPath, [ '--enable-source-maps', - '--experimental-modules', require.resolve('../fixtures/source-map/babel-esm.mjs') ]); assert.ok( diff --git a/test/parallel/test-stream-transform-final-sync.js b/test/parallel/test-stream-transform-final-sync.js index 666c1dce9996d1..1942bee1a01e8a 100644 --- a/test/parallel/test-stream-transform-final-sync.js +++ b/test/parallel/test-stream-transform-final-sync.js @@ -7,7 +7,7 @@ let state = 0; /* What you do -var stream = new stream.Transform({ +const stream = new stream.Transform({ transform: function transformCallback(chunk, _, next) { // part 1 this.push(chunk); diff --git a/test/parallel/test-stream-transform-final.js b/test/parallel/test-stream-transform-final.js index 3d6c4563c6e194..53b81cfea224e4 100644 --- a/test/parallel/test-stream-transform-final.js +++ b/test/parallel/test-stream-transform-final.js @@ -7,7 +7,7 @@ let state = 0; /* What you do -var stream = new stream.Transform({ +const stream = new stream.Transform({ transform: function transformCallback(chunk, _, next) { // part 1 this.push(chunk); diff --git a/test/parallel/test-stream-writable-properties.js b/test/parallel/test-stream-writable-properties.js new file mode 100644 index 00000000000000..424bb5871083a2 --- /dev/null +++ b/test/parallel/test-stream-writable-properties.js @@ -0,0 +1,22 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const { Writable } = require('stream'); + +{ + const w = new Writable(); + assert.strictEqual(w.writableCorked, 0); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); + w.cork(); + assert.strictEqual(w.writableCorked, 1); + w.cork(); + assert.strictEqual(w.writableCorked, 2); + w.uncork(); + assert.strictEqual(w.writableCorked, 1); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); + w.uncork(); + assert.strictEqual(w.writableCorked, 0); +} diff --git a/test/parallel/test-tls-close-notify.js b/test/parallel/test-tls-close-notify.js index 808727b12739b2..d7153b87ba7f19 100644 --- a/test/parallel/test-tls-close-notify.js +++ b/test/parallel/test-tls-close-notify.js @@ -35,19 +35,18 @@ const server = tls.createServer({ key: fixtures.readKey('agent1-key.pem'), cert: fixtures.readKey('agent1-cert.pem') }, function(c) { - // Send close-notify without shutting down TCP socket - const req = new ShutdownWrap(); - req.oncomplete = common.mustCall(() => {}); - req.handle = c._handle; - c._handle.shutdown(req); + // Ensure that we receive 'end' event anyway. + c.on('end', common.mustCall(function() { + server.close(); + })); }).listen(0, common.mustCall(function() { const c = tls.connect(this.address().port, { rejectUnauthorized: false }, common.mustCall(function() { - // Ensure that we receive 'end' event anyway - c.on('end', common.mustCall(function() { - c.destroy(); - server.close(); - })); + // Send close-notify without shutting down TCP socket. + const req = new ShutdownWrap(); + req.oncomplete = common.mustCall(() => {}); + req.handle = c._handle; + c._handle.shutdown(req); })); })); diff --git a/test/parallel/test-tls-enable-keylog-cli.js b/test/parallel/test-tls-enable-keylog-cli.js new file mode 100644 index 00000000000000..5d05069b15f87c --- /dev/null +++ b/test/parallel/test-tls-enable-keylog-cli.js @@ -0,0 +1,57 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); + +// Test --tls-keylog CLI flag. + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const { fork } = require('child_process'); + +if (process.argv[2] === 'test') + return test(); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +const file = path.resolve(tmpdir.path, 'keylog.log'); + +const child = fork(__filename, ['test'], { + execArgv: ['--tls-keylog=' + file] +}); + +child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + const log = fs.readFileSync(file, 'utf8'); + assert(/SECRET/.test(log)); +})); + +function test() { + const { + connect, keys + } = require(fixtures.path('tls-connect')); + + connect({ + client: { + checkServerIdentity: (servername, cert) => { }, + ca: `${keys.agent1.cert}\n${keys.agent6.ca}`, + }, + server: { + cert: keys.agent6.cert, + key: keys.agent6.key + }, + }, common.mustCall((err, pair, cleanup) => { + if (pair.server.err) { + console.trace('server', pair.server.err); + } + if (pair.client.err) { + console.trace('client', pair.client.err); + } + assert.ifError(pair.server.err); + assert.ifError(pair.client.err); + + return cleanup(); + })); +} diff --git a/test/parallel/test-tls-keylog-tlsv13.js b/test/parallel/test-tls-keylog-tlsv13.js index 0f6556451d013e..f26dece2f427f2 100644 --- a/test/parallel/test-tls-keylog-tlsv13.js +++ b/test/parallel/test-tls-keylog-tlsv13.js @@ -21,9 +21,13 @@ const server = tls.createServer({ rejectUnauthorized: false, }); - const verifyBuffer = (line) => assert(Buffer.isBuffer(line)); - server.on('keylog', common.mustCall(verifyBuffer, 5)); - client.on('keylog', common.mustCall(verifyBuffer, 5)); + server.on('keylog', common.mustCall((line, tlsSocket) => { + assert(Buffer.isBuffer(line)); + assert.strictEqual(tlsSocket.encrypted, true); + }, 5)); + client.on('keylog', common.mustCall((line) => { + assert(Buffer.isBuffer(line)); + }, 5)); client.once('secureConnect', () => { server.close(); diff --git a/test/parallel/test-trace-events-async-hooks-dynamic.js b/test/parallel/test-trace-events-async-hooks-dynamic.js index 318f94b182c5c1..9cb0d41c5494c6 100644 --- a/test/parallel/test-trace-events-async-hooks-dynamic.js +++ b/test/parallel/test-trace-events-async-hooks-dynamic.js @@ -29,10 +29,10 @@ const proc = cp.spawnSync( ['-e', enable + code ], { cwd: tmpdir.path, - env: Object.assign({}, process.env, { - 'NODE_DEBUG_NATIVE': 'tracing', - 'NODE_DEBUG': 'tracing' - }) + env: { ...process.env, + 'NODE_DEBUG_NATIVE': 'tracing', + 'NODE_DEBUG': 'tracing' + } }); console.log('process exit with signal:', proc.signal); diff --git a/test/parallel/test-trace-events-async-hooks-worker.js b/test/parallel/test-trace-events-async-hooks-worker.js index 338f0f9c09e534..153ef301873151 100644 --- a/test/parallel/test-trace-events-async-hooks-worker.js +++ b/test/parallel/test-trace-events-async-hooks-worker.js @@ -36,10 +36,10 @@ const proc = cp.spawnSync( [ '--trace-event-categories', 'node.async_hooks', '-e', worker ], { cwd: tmpdir.path, - env: Object.assign({}, process.env, { - 'NODE_DEBUG_NATIVE': 'tracing', - 'NODE_DEBUG': 'tracing' - }) + env: { ...process.env, + 'NODE_DEBUG_NATIVE': 'tracing', + 'NODE_DEBUG': 'tracing' + } }); console.log('process exit with signal:', proc.signal); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index fc0bb345da95ce..e7804eec2f2bc0 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -1366,7 +1366,7 @@ if (typeof Symbol !== 'undefined') { const arr = new Array(101).fill(); const obj = { a: { a: { a: { a: 1 } } } }; - const oldOptions = Object.assign({}, util.inspect.defaultOptions); + const oldOptions = { ...util.inspect.defaultOptions }; // Set single option through property assignment. util.inspect.defaultOptions.maxArrayLength = null; diff --git a/test/parallel/test-v8-serdes.js b/test/parallel/test-v8-serdes.js index 58b919066ea990..a992ba42ce46bf 100644 --- a/test/parallel/test-v8-serdes.js +++ b/test/parallel/test-v8-serdes.js @@ -156,8 +156,10 @@ const deserializerTypeError = } { - assert.throws(() => v8.serialize(hostObject), - /^Error: Unknown host object type: \[object .*\]$/); + assert.throws(() => v8.serialize(hostObject), { + constructor: Error, + message: 'Unserializable host object: JSStream {}' + }); } { diff --git a/test/parallel/test-vm-function-declaration.js b/test/parallel/test-vm-function-declaration.js index 6405babfa78148..766e5ec78b10ea 100644 --- a/test/parallel/test-vm-function-declaration.js +++ b/test/parallel/test-vm-function-declaration.js @@ -28,17 +28,22 @@ const o = vm.createContext({ console }); // Function declaration and expression should both be copied to the // sandboxed context. -let code = 'var a = function() {};\n'; +let code = 'let a = function() {};\n'; code += 'function b(){}\n'; +code += 'var c = function() {};\n'; +code += 'var d = () => {};\n'; +code += 'let e = () => {};\n'; // Grab the global b function as the completion value, to ensure that // we are getting the global function, and not some other thing code += '(function(){return this})().b;\n'; const res = vm.runInContext(code, o, 'test'); - assert.strictEqual(typeof res, 'function'); assert.strictEqual(res.name, 'b'); -assert.strictEqual(typeof o.a, 'function'); +assert.strictEqual(typeof o.a, 'undefined'); assert.strictEqual(typeof o.b, 'function'); +assert.strictEqual(typeof o.c, 'function'); +assert.strictEqual(typeof o.d, 'function'); +assert.strictEqual(typeof o.e, 'undefined'); assert.strictEqual(res, o.b); diff --git a/test/parallel/test-vm-module-dynamic-import.js b/test/parallel/test-vm-module-dynamic-import.js index 897d9f27d73376..70229b3897874b 100644 --- a/test/parallel/test-vm-module-dynamic-import.js +++ b/test/parallel/test-vm-module-dynamic-import.js @@ -1,6 +1,6 @@ 'use strict'; -// Flags: --experimental-vm-modules --experimental-modules +// Flags: --experimental-vm-modules const common = require('../common'); diff --git a/test/parallel/test-vm-module-link.js b/test/parallel/test-vm-module-link.js index 9678d1373785be..56443e3e1a73bc 100644 --- a/test/parallel/test-vm-module-link.js +++ b/test/parallel/test-vm-module-link.js @@ -97,11 +97,11 @@ async function circular2() { `, './a.mjs': ` export * from './b.mjs'; - export var fromA; + export let fromA; `, './b.mjs': ` export * from './a.mjs'; - export var fromB; + export let fromB; ` }; const moduleMap = new Map(); diff --git a/test/parallel/test-whatwg-url-custom-properties.js b/test/parallel/test-whatwg-url-custom-properties.js index 1fbc3ab6238ea3..23742a8e7493e2 100644 --- a/test/parallel/test-whatwg-url-custom-properties.js +++ b/test/parallel/test-whatwg-url-custom-properties.js @@ -152,7 +152,7 @@ assert.strictEqual(url.searchParams, oldParams); // contains the Symbols that Node uses for brand checking, but not the data // properties, which are getters. Verify that urlToOptions() can handle such // a case. - const copiedUrlObj = Object.assign({}, urlObj); + const copiedUrlObj = { ...urlObj }; const copiedOpts = urlToOptions(copiedUrlObj); assert.strictEqual(copiedOpts instanceof URL, false); assert.strictEqual(copiedOpts.protocol, undefined); diff --git a/test/parallel/test-worker-esm-exit.js b/test/parallel/test-worker-esm-exit.js index c0b9d874895725..184106936536db 100644 --- a/test/parallel/test-worker-esm-exit.js +++ b/test/parallel/test-worker-esm-exit.js @@ -4,7 +4,6 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); const { Worker } = require('worker_threads'); -const w = new Worker(fixtures.path('es-modules/import-process-exit.mjs'), - { execArgv: ['--experimental-modules'] }); +const w = new Worker(fixtures.path('es-modules/import-process-exit.mjs')); w.on('error', common.mustNotCall()); w.on('exit', (code) => assert.strictEqual(code, 42)); diff --git a/test/parallel/test-worker-esm-missing-main.js b/test/parallel/test-worker-esm-missing-main.js index 8f4cfb0fe7fa9b..07bfb6a0276cd5 100644 --- a/test/parallel/test-worker-esm-missing-main.js +++ b/test/parallel/test-worker-esm-missing-main.js @@ -8,7 +8,7 @@ const tmpdir = require('../common/tmpdir'); tmpdir.refresh(); const missing = path.join(tmpdir.path, 'does-not-exist.js'); -const worker = new Worker(missing, { execArgv: ['--experimental-modules'] }); +const worker = new Worker(missing); worker.on('error', common.mustCall((err) => { // eslint-disable-next-line node-core/no-unescaped-regexp-dot diff --git a/test/parallel/test-worker-esmodule.js b/test/parallel/test-worker-esmodule.js index 33788c1422ce84..e7f9bd7aea6c8a 100644 --- a/test/parallel/test-worker-esmodule.js +++ b/test/parallel/test-worker-esmodule.js @@ -1,4 +1,3 @@ -// Flags: --experimental-modules 'use strict'; const common = require('../common'); const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-worker-mjs-workerdata.js b/test/parallel/test-worker-mjs-workerdata.js index c107730ea4bba2..b0a65e2e805c1e 100644 --- a/test/parallel/test-worker-mjs-workerdata.js +++ b/test/parallel/test-worker-mjs-workerdata.js @@ -7,8 +7,7 @@ const { Worker } = require('worker_threads'); const workerData = 'Hello from main thread'; const worker = new Worker(fixtures.path('worker-data.mjs'), { - workerData, - execArgv: ['--experimental-modules'] + workerData }); worker.on('message', common.mustCall((message) => { diff --git a/test/parallel/test-worker-resource-limits.js b/test/parallel/test-worker-resource-limits.js new file mode 100644 index 00000000000000..2d4ebbc0ce6011 --- /dev/null +++ b/test/parallel/test-worker-resource-limits.js @@ -0,0 +1,58 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const v8 = require('v8'); +const { Worker, resourceLimits, isMainThread } = require('worker_threads'); + +if (isMainThread) { + assert.deepStrictEqual(resourceLimits, {}); +} + +const testResourceLimits = { + maxOldGenerationSizeMb: 16, + maxYoungGenerationSizeMb: 4, + codeRangeSizeMb: 16, +}; + +// Do not use isMainThread so that this test itself can be run inside a Worker. +if (!process.env.HAS_STARTED_WORKER) { + process.env.HAS_STARTED_WORKER = 1; + const w = new Worker(__filename, { resourceLimits: testResourceLimits }); + assert.deepStrictEqual(w.resourceLimits, testResourceLimits); + w.on('exit', common.mustCall((code) => { + assert.strictEqual(code, 1); + assert.deepStrictEqual(w.resourceLimits, {}); + })); + w.on('error', common.expectsError({ + code: 'ERR_WORKER_OUT_OF_MEMORY', + message: 'Worker terminated due to reaching memory limit' + })); + return; +} + +assert.deepStrictEqual(resourceLimits, testResourceLimits); +const array = []; +while (true) { + // Leave 10 % wiggle room here. + const usedMB = v8.getHeapStatistics().used_heap_size / 1024 / 1024; + assert(usedMB < resourceLimits.maxOldGenerationSizeMb * 1.1); + + let seenSpaces = 0; + for (const { space_name, space_size } of v8.getHeapSpaceStatistics()) { + if (space_name === 'new_space') { + seenSpaces++; + assert( + space_size / 1024 / 1024 < resourceLimits.maxYoungGenerationSizeMb * 2); + } else if (space_name === 'old_space') { + seenSpaces++; + assert(space_size / 1024 / 1024 < resourceLimits.maxOldGenerationSizeMb); + } else if (space_name === 'code_space') { + seenSpaces++; + assert(space_size / 1024 / 1024 < resourceLimits.codeRangeSizeMb); + } + } + assert.strictEqual(seenSpaces, 3); + + for (let i = 0; i < 100; i++) + array.push([array]); +} diff --git a/test/parallel/test-worker-terminate-source-map.js b/test/parallel/test-worker-terminate-source-map.js new file mode 100644 index 00000000000000..d88a4c68366865 --- /dev/null +++ b/test/parallel/test-worker-terminate-source-map.js @@ -0,0 +1,40 @@ +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); + +// Attempts to test that the source map JS code run on process shutdown +// does not call any user-defined JS code. + +const { Worker, workerData, parentPort } = require('worker_threads'); + +if (!workerData) { + tmpdir.refresh(); + process.env.NODE_V8_COVERAGE = tmpdir.path; + + // Count the number of some calls that should not be made. + const callCount = new Int32Array(new SharedArrayBuffer(4)); + const w = new Worker(__filename, { workerData: { callCount } }); + w.on('message', common.mustCall(() => w.terminate())); + w.on('exit', common.mustCall(() => { + assert.strictEqual(callCount[0], 0); + })); + return; +} + +const { callCount } = workerData; + +function increaseCallCount() { callCount[0]++; } + +// Increase the call count when a forbidden method is called. +Object.getPrototypeOf((new Map()).entries()).next = increaseCallCount; +Map.prototype.entries = increaseCallCount; +Object.keys = increaseCallCount; +Object.create = increaseCallCount; +Object.hasOwnProperty = increaseCallCount; +Object.defineProperty(Object.prototype, 'value', { + get: increaseCallCount, + set: increaseCallCount +}); + +parentPort.postMessage('done'); diff --git a/test/sequential/test-async-wrap-getasyncid.js b/test/sequential/test-async-wrap-getasyncid.js index cc823cc17fa706..7e9f77cd7a4cc2 100644 --- a/test/sequential/test-async-wrap-getasyncid.js +++ b/test/sequential/test-async-wrap-getasyncid.js @@ -8,7 +8,7 @@ const fs = require('fs'); const v8 = require('v8'); const fsPromises = fs.promises; const net = require('net'); -const providers = Object.assign({}, internalBinding('async_wrap').Providers); +const providers = { ...internalBinding('async_wrap').Providers }; const fixtures = require('../common/fixtures'); const tmpdir = require('../common/tmpdir'); const { getSystemErrorName } = require('util'); diff --git a/test/sequential/test-inspector-open.js b/test/sequential/test-inspector-open.js index a0d2eaf1f3415a..967ebe49bfb764 100644 --- a/test/sequential/test-inspector-open.js +++ b/test/sequential/test-inspector-open.js @@ -14,7 +14,7 @@ if (process.env.BE_CHILD) return beChild(); const child = fork(__filename, - { env: Object.assign({}, process.env, { BE_CHILD: 1 }) }); + { env: { ...process.env, BE_CHILD: 1 } }); child.once('message', common.mustCall((msg) => { assert.strictEqual(msg.cmd, 'started'); diff --git a/test/sequential/test-inspector-port-cluster.js b/test/sequential/test-inspector-port-cluster.js index 7b541eb156e0cd..7579f51deeb598 100644 --- a/test/sequential/test-inspector-port-cluster.js +++ b/test/sequential/test-inspector-port-cluster.js @@ -328,11 +328,11 @@ function workerProcessMain() { function spawnMaster({ execArgv, workers, clusterSettings = {} }) { return new Promise((resolve) => { childProcess.fork(__filename, { - env: Object.assign({}, process.env, { - workers: JSON.stringify(workers), - clusterSettings: JSON.stringify(clusterSettings), - testProcess: true - }), + env: { ...process.env, + workers: JSON.stringify(workers), + clusterSettings: JSON.stringify(clusterSettings), + testProcess: true + }, execArgv: execArgv.concat(['--expose-internals']) }).on('exit', common.mustCall((code, signal) => { checkExitCode(code, signal); diff --git a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js index c2275b570ca08e..46c1f6d1a5885c 100644 --- a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js +++ b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js @@ -37,5 +37,5 @@ process.on('exit', () => { const bytesPerChunk = (process.memoryUsage().rss - baseRSS) / receivedChunks.length; // We should always have less than one page (usually ~ 4 kB) per chunk. - assert(bytesPerChunk < 600, `measured ${bytesPerChunk} bytes per chunk`); + assert(bytesPerChunk < 650, `measured ${bytesPerChunk} bytes per chunk`); }); diff --git a/test/tools/test-js2c.py b/test/tools/test_js2c.py similarity index 100% rename from test/tools/test-js2c.py rename to test/tools/test_js2c.py diff --git a/test/v8-updates/test-postmortem-metadata.js b/test/v8-updates/test-postmortem-metadata.js index 4a0667a97f9d00..0891e62251db87 100644 --- a/test/v8-updates/test-postmortem-metadata.js +++ b/test/v8-updates/test-postmortem-metadata.js @@ -102,7 +102,7 @@ function getExpectedSymbols() { 'v8dbg_class_UncompiledData__inferred_name__String', 'v8dbg_class_SharedFunctionInfo__internal_formal_parameter_count__uint16_t', 'v8dbg_class_SharedFunctionInfo__name_or_scope_info__Object', - 'v8dbg_class_SharedFunctionInfo__script_or_debug_info__Object', + 'v8dbg_class_SharedFunctionInfo__script_or_debug_info__HeapObject', 'v8dbg_class_UncompiledData__start_position__int32_t', 'v8dbg_class_SlicedString__offset_offset__int', 'v8dbg_class_SlicedString__parent__String', @@ -162,7 +162,7 @@ function getExpectedSymbols() { 'v8dbg_type_JSGlobalObject__JS_GLOBAL_OBJECT_TYPE', 'v8dbg_type_JSGlobalProxy__JS_GLOBAL_PROXY_TYPE', 'v8dbg_type_JSObject__JS_OBJECT_TYPE', - 'v8dbg_type_JSRegExp__JS_REGEXP_TYPE', + 'v8dbg_type_JSRegExp__JS_REG_EXP_TYPE', 'v8dbg_type_JSTypedArray__JS_TYPED_ARRAY_TYPE', 'v8dbg_type_Map__MAP_TYPE', 'v8dbg_type_Oddball__ODDBALL_TYPE', diff --git a/test/wpt/status/encoding.json b/test/wpt/status/encoding.json index 088eed802f0fe7..b51dde2aaee479 100644 --- a/test/wpt/status/encoding.json +++ b/test/wpt/status/encoding.json @@ -22,10 +22,7 @@ "fail": "iso-2022-jp decoder state handling bug: https://encoding.spec.whatwg.org/#iso-2022-jp-decoder" }, "textdecoder-byte-order-marks.any.js": { - "fail": "Mismatching BOM should not be ignored" - }, - "textdecoder-copy.any.js": { - "fail": "Should not have output BOM: https://encoding.spec.whatwg.org/#concept-td-serialize" + "requires": ["small-icu"] }, "textdecoder-fatal-single-byte.any.js": { "requires": ["full-icu"], diff --git a/tools/certdata.txt b/tools/certdata.txt index 3466f6ee40ed90..3a44db293df268 100644 --- a/tools/certdata.txt +++ b/tools/certdata.txt @@ -13,19 +13,21 @@ # # Certificates # -# -- Attribute -- -- type -- -- value -- -# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -# CKA_TOKEN CK_BBOOL CK_TRUE -# CKA_PRIVATE CK_BBOOL CK_FALSE -# CKA_MODIFIABLE CK_BBOOL CK_FALSE -# CKA_LABEL UTF8 (varies) -# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -# CKA_SUBJECT DER+base64 (varies) -# CKA_ID byte array (varies) -# CKA_ISSUER DER+base64 (varies) -# CKA_SERIAL_NUMBER DER+base64 (varies) -# CKA_VALUE DER+base64 (varies) -# CKA_NSS_EMAIL ASCII7 (unused here) +# -- Attribute -- -- type -- -- value -- +# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +# CKA_TOKEN CK_BBOOL CK_TRUE +# CKA_PRIVATE CK_BBOOL CK_FALSE +# CKA_MODIFIABLE CK_BBOOL CK_FALSE +# CKA_LABEL UTF8 (varies) +# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +# CKA_SUBJECT DER+base64 (varies) +# CKA_ID byte array (varies) +# CKA_ISSUER DER+base64 (varies) +# CKA_SERIAL_NUMBER DER+base64 (varies) +# CKA_VALUE DER+base64 (varies) +# CKA_NSS_EMAIL ASCII7 (unused here) +# CKA_NSS_SERVER_DISTRUST_AFTER DER+base64 (varies) +# CKA_NSS_EMAIL_DISTRUST_AFTER DER+base64 (varies) # # Trust # @@ -164,6 +166,8 @@ CKA_VALUE MULTILINE_OCTAL \125\342\374\110\311\051\046\151\340 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GlobalSign Root CA" # Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE @@ -298,6 +302,8 @@ CKA_VALUE MULTILINE_OCTAL \152\374\176\102\070\100\144\022\367\236\201\341\223\056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GlobalSign Root CA - R2" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2 @@ -454,6 +460,8 @@ CKA_VALUE MULTILINE_OCTAL \113\336\006\226\161\054\362\333\266\037\244\357\077\356 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Verisign Class 1 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 1 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -619,6 +627,8 @@ CKA_VALUE MULTILINE_OCTAL \311\130\020\371\252\357\132\266\317\113\113\337\052 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Verisign Class 2 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 2 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -784,6 +794,8 @@ CKA_VALUE MULTILINE_OCTAL \153\271\012\172\116\117\113\204\356\113\361\175\335\021 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Verisign Class 3 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -1059,6 +1071,8 @@ CKA_VALUE MULTILINE_OCTAL \174\136\232\166\351\131\220\305\174\203\065\021\145\121 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Entrust.net Premium 2048 Secure Server CA" # Issuer: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net @@ -1197,6 +1211,8 @@ CKA_VALUE MULTILINE_OCTAL \347\201\035\031\303\044\102\352\143\071\251 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Baltimore CyberTrust Root" # Issuer: CN=Baltimore CyberTrust Root,OU=CyberTrust,O=Baltimore,C=IE @@ -1341,6 +1357,8 @@ CKA_VALUE MULTILINE_OCTAL \065\341\035\026\034\320\274\053\216\326\161\331 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AddTrust Low-Value Services Root" # Issuer: CN=AddTrust Class 1 CA Root,OU=AddTrust TTP Network,O=AddTrust AB,C=SE @@ -1490,6 +1508,8 @@ CKA_VALUE MULTILINE_OCTAL \027\132\173\320\274\307\217\116\206\004 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AddTrust External Root" # Issuer: CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE @@ -1654,6 +1674,8 @@ CKA_VALUE MULTILINE_OCTAL \036\177\132\264\074 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Entrust Root Certification Authority" # Issuer: CN=Entrust Root Certification Authority,OU="(c) 2006 Entrust, Inc.",OU=www.entrust.net/CPS is incorporated by reference,O="Entrust, Inc.",C=US @@ -1788,6 +1810,8 @@ CKA_VALUE MULTILINE_OCTAL \302\005\146\200\241\313\346\063 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Global CA" # Issuer: CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US @@ -1948,6 +1972,8 @@ CKA_VALUE MULTILINE_OCTAL \244\346\216\330\371\051\110\212\316\163\376\054 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Universal CA" # Issuer: CN=GeoTrust Universal CA,O=GeoTrust Inc.,C=US @@ -2108,6 +2134,8 @@ CKA_VALUE MULTILINE_OCTAL \362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Universal CA 2" # Issuer: CN=GeoTrust Universal CA 2,O=GeoTrust Inc.,C=US @@ -2228,6 +2256,8 @@ CKA_VALUE MULTILINE_OCTAL \350\140\052\233\205\112\100\363\153\212\044\354\006\026\054\163 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Certum Root CA" # Issuer: CN=Certum CA,O=Unizeto Sp. z o.o.,C=PL @@ -2374,6 +2404,8 @@ CKA_VALUE MULTILINE_OCTAL \225\351\066\226\230\156 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Comodo AAA Services root" # Issuer: CN=AAA Certificate Services,O=Comodo CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -2552,6 +2584,8 @@ CKA_VALUE MULTILINE_OCTAL \112\164\066\371 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "QuoVadis Root CA" # Issuer: CN=QuoVadis Root Certification Authority,OU=Root Certification Authority,O=QuoVadis Limited,C=BM @@ -2721,6 +2755,8 @@ CKA_VALUE MULTILINE_OCTAL \020\005\145\325\202\020\352\302\061\315\056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "QuoVadis Root CA 2" # Issuer: CN=QuoVadis Root CA 2,O=QuoVadis Limited,C=BM @@ -2901,6 +2937,8 @@ CKA_VALUE MULTILINE_OCTAL \332 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "QuoVadis Root CA 3" # Issuer: CN=QuoVadis Root CA 3,O=QuoVadis Limited,C=BM @@ -3030,6 +3068,8 @@ CKA_VALUE MULTILINE_OCTAL \057\317\246\356\311\160\042\024\275\375\276\154\013\003 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Security Communication Root CA" # Issuer: OU=Security Communication RootCA1,O=SECOM Trust.net,C=JP @@ -3153,6 +3193,8 @@ CKA_VALUE MULTILINE_OCTAL \160\254\337\114 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Sonera Class 2 Root CA" # Issuer: CN=Sonera Class2 CA,O=Sonera,C=FI @@ -3188,177 +3230,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -# -# Certificate "UTN USERFirst Email Root CA" -# -# Issuer: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:44:be:0c:8b:50:00:24:b4:11:d3:36:25:25:67:c9:89 -# Subject: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Not Valid Before: Fri Jul 09 17:28:50 1999 -# Not Valid After : Tue Jul 09 17:36:58 2019 -# Fingerprint (MD5): D7:34:3D:EF:1D:27:09:28:E1:31:02:5B:13:2B:DD:F7 -# Fingerprint (SHA1): B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "UTN USERFirst Email Root CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125 -\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164 -\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151 -\154 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125 -\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164 -\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151 -\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\104\276\014\213\120\000\044\264\021\323\066\045\045\147 -\311\211 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\242\060\202\003\212\240\003\002\001\002\002\020\104 -\276\014\213\120\000\044\264\021\323\066\045\045\147\311\211\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\201 -\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061\013 -\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025\006 -\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145\040 -\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025\124 -\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145\164 -\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030\150 -\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164\162 -\165\163\164\056\143\157\155\061\066\060\064\006\003\125\004\003 -\023\055\125\124\116\055\125\123\105\122\106\151\162\163\164\055 -\103\154\151\145\156\164\040\101\165\164\150\145\156\164\151\143 -\141\164\151\157\156\040\141\156\144\040\105\155\141\151\154\060 -\036\027\015\071\071\060\067\060\071\061\067\062\070\065\060\132 -\027\015\061\071\060\067\060\071\061\067\063\066\065\070\132\060 -\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060\025 -\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153\145 -\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023\025 -\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116\145 -\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023\030 -\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162\164 -\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125\004 -\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163\164 -\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164\151 -\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151\154 -\060\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001 -\001\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001 -\000\262\071\205\244\362\175\253\101\073\142\106\067\256\315\301 -\140\165\274\071\145\371\112\032\107\242\271\314\110\314\152\230 -\325\115\065\031\271\244\102\345\316\111\342\212\057\036\174\322 -\061\007\307\116\264\203\144\235\056\051\325\242\144\304\205\275 -\205\121\065\171\244\116\150\220\173\034\172\244\222\250\027\362 -\230\025\362\223\314\311\244\062\225\273\014\117\060\275\230\240 -\013\213\345\156\033\242\106\372\170\274\242\157\253\131\136\245 -\057\317\312\332\155\252\057\353\254\241\263\152\252\267\056\147 -\065\213\171\341\036\151\210\342\346\106\315\240\245\352\276\013 -\316\166\072\172\016\233\352\374\332\047\133\075\163\037\042\346 -\110\141\306\114\363\151\261\250\056\033\266\324\061\040\054\274 -\202\212\216\244\016\245\327\211\103\374\026\132\257\035\161\327 -\021\131\332\272\207\015\257\372\363\341\302\360\244\305\147\214 -\326\326\124\072\336\012\244\272\003\167\263\145\310\375\036\323 -\164\142\252\030\312\150\223\036\241\205\176\365\107\145\313\370 -\115\127\050\164\322\064\377\060\266\356\366\142\060\024\214\054 -\353\002\003\001\000\001\243\201\271\060\201\266\060\013\006\003 -\125\035\017\004\004\003\002\001\306\060\017\006\003\125\035\023 -\001\001\377\004\005\060\003\001\001\377\060\035\006\003\125\035 -\016\004\026\004\024\211\202\147\175\304\235\046\160\000\113\264 -\120\110\174\336\075\256\004\156\175\060\130\006\003\125\035\037 -\004\121\060\117\060\115\240\113\240\111\206\107\150\164\164\160 -\072\057\057\143\162\154\056\165\163\145\162\164\162\165\163\164 -\056\143\157\155\057\125\124\116\055\125\123\105\122\106\151\162 -\163\164\055\103\154\151\145\156\164\101\165\164\150\145\156\164 -\151\143\141\164\151\157\156\141\156\144\105\155\141\151\154\056 -\143\162\154\060\035\006\003\125\035\045\004\026\060\024\006\010 -\053\006\001\005\005\007\003\002\006\010\053\006\001\005\005\007 -\003\004\060\015\006\011\052\206\110\206\367\015\001\001\005\005 -\000\003\202\001\001\000\261\155\141\135\246\032\177\174\253\112 -\344\060\374\123\157\045\044\306\312\355\342\061\134\053\016\356 -\356\141\125\157\004\076\317\071\336\305\033\111\224\344\353\040 -\114\264\346\236\120\056\162\331\215\365\252\243\263\112\332\126 -\034\140\227\200\334\202\242\255\112\275\212\053\377\013\011\264 -\306\327\040\004\105\344\315\200\001\272\272\053\156\316\252\327 -\222\376\344\257\353\364\046\035\026\052\177\154\060\225\067\057 -\063\022\254\177\335\307\321\021\214\121\230\262\320\243\221\320 -\255\366\237\236\203\223\036\035\102\270\106\257\153\146\360\233 -\177\352\343\003\002\345\002\121\301\252\325\065\235\162\100\003 -\211\272\061\035\305\020\150\122\236\337\242\205\305\134\010\246 -\170\346\123\117\261\350\267\323\024\236\223\246\303\144\343\254 -\176\161\315\274\237\351\003\033\314\373\351\254\061\301\257\174 -\025\164\002\231\303\262\107\246\302\062\141\327\307\157\110\044 -\121\047\241\325\207\125\362\173\217\230\075\026\236\356\165\266 -\370\320\216\362\363\306\256\050\133\247\360\363\066\027\374\303 -\005\323\312\003\112\124 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "UTN USERFirst Email Root CA" -# Issuer: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Serial Number:44:be:0c:8b:50:00:24:b4:11:d3:36:25:25:67:c9:89 -# Subject: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US -# Not Valid Before: Fri Jul 09 17:28:50 1999 -# Not Valid After : Tue Jul 09 17:36:58 2019 -# Fingerprint (MD5): D7:34:3D:EF:1D:27:09:28:E1:31:02:5B:13:2B:DD:F7 -# Fingerprint (SHA1): B1:72:B1:A5:6D:95:F9:1F:E5:02:87:E1:4D:37:EA:6A:44:63:76:8A -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "UTN USERFirst Email Root CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\261\162\261\245\155\225\371\037\345\002\207\341\115\067\352\152 -\104\143\166\212 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\327\064\075\357\035\047\011\050\341\061\002\133\023\053\335\367 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\256\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\013\060\011\006\003\125\004\010\023\002\125\124\061\027\060 -\025\006\003\125\004\007\023\016\123\141\154\164\040\114\141\153 -\145\040\103\151\164\171\061\036\060\034\006\003\125\004\012\023 -\025\124\150\145\040\125\123\105\122\124\122\125\123\124\040\116 -\145\164\167\157\162\153\061\041\060\037\006\003\125\004\013\023 -\030\150\164\164\160\072\057\057\167\167\167\056\165\163\145\162 -\164\162\165\163\164\056\143\157\155\061\066\060\064\006\003\125 -\004\003\023\055\125\124\116\055\125\123\105\122\106\151\162\163 -\164\055\103\154\151\145\156\164\040\101\165\164\150\145\156\164 -\151\143\141\164\151\157\156\040\141\156\144\040\105\155\141\151 -\154 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\104\276\014\213\120\000\044\264\021\323\066\045\045\147 -\311\211 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "Camerfirma Chambers of Commerce Root" # @@ -3481,6 +3352,8 @@ CKA_VALUE MULTILINE_OCTAL \334 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Camerfirma Chambers of Commerce Root" # Issuer: CN=Chambers of Commerce Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU @@ -3641,6 +3514,8 @@ CKA_VALUE MULTILINE_OCTAL \166\135\165\220\032\365\046\217\360 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Camerfirma Global Chambersign Root" # Issuer: CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU @@ -3794,6 +3669,8 @@ CKA_VALUE MULTILINE_OCTAL \264\003\045\274 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "XRamp Global CA Root" # Issuer: CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US @@ -3941,6 +3818,8 @@ CKA_VALUE MULTILINE_OCTAL \177\333\275\237 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Go Daddy Class 2 CA" # Issuer: OU=Go Daddy Class 2 Certification Authority,O="The Go Daddy Group, Inc.",C=US @@ -4086,6 +3965,8 @@ CKA_VALUE MULTILINE_OCTAL \037\027\224 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Starfield Class 2 CA" # Issuer: OU=Starfield Class 2 Certification Authority,O="Starfield Technologies, Inc.",C=US @@ -4250,6 +4131,8 @@ CKA_VALUE MULTILINE_OCTAL \245\206\054\174\364\022 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Taiwan GRCA" # Issuer: O=Government Root Certification Authority,C=TW @@ -4389,6 +4272,8 @@ CKA_VALUE MULTILINE_OCTAL \346\120\262\247\372\012\105\057\242\360\362 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "DigiCert Assured ID Root CA" # Issuer: CN=DigiCert Assured ID Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -4530,6 +4415,8 @@ CKA_VALUE MULTILINE_OCTAL \225\155\336 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "DigiCert Global Root CA" # Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -4672,6 +4559,8 @@ CKA_VALUE MULTILINE_OCTAL \370\351\056\023\243\167\350\037\112 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "DigiCert High Assurance EV Root CA" # Issuer: CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -4711,136 +4600,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -# -# Certificate "Certplus Class 2 Primary CA" -# -# Issuer: CN=Class 2 Primary CA,O=Certplus,C=FR -# Serial Number:00:85:bd:4b:f3:d8:da:e3:69:f6:94:d7:5f:c3:a5:44:23 -# Subject: CN=Class 2 Primary CA,O=Certplus,C=FR -# Not Valid Before: Wed Jul 07 17:05:00 1999 -# Not Valid After : Sat Jul 06 23:59:59 2019 -# Fingerprint (MD5): 88:2C:8C:52:B8:A2:3C:F3:F7:BB:03:EA:AE:AC:42:0B -# Fingerprint (SHA1): 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Certplus Class 2 Primary CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154 -\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141 -\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154 -\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141 -\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\205\275\113\363\330\332\343\151\366\224\327\137\303 -\245\104\043 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\222\060\202\002\172\240\003\002\001\002\002\021\000 -\205\275\113\363\330\332\343\151\366\224\327\137\303\245\104\043 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061\021 -\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154\165 -\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141\163 -\163\040\062\040\120\162\151\155\141\162\171\040\103\101\060\036 -\027\015\071\071\060\067\060\067\061\067\060\065\060\060\132\027 -\015\061\071\060\067\060\066\062\063\065\071\065\071\132\060\075 -\061\013\060\011\006\003\125\004\006\023\002\106\122\061\021\060 -\017\006\003\125\004\012\023\010\103\145\162\164\160\154\165\163 -\061\033\060\031\006\003\125\004\003\023\022\103\154\141\163\163 -\040\062\040\120\162\151\155\141\162\171\040\103\101\060\202\001 -\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000 -\003\202\001\017\000\060\202\001\012\002\202\001\001\000\334\120 -\226\320\022\370\065\322\010\170\172\266\122\160\375\157\356\317 -\271\021\313\135\167\341\354\351\176\004\215\326\314\157\163\103 -\127\140\254\063\012\104\354\003\137\034\200\044\221\345\250\221 -\126\022\202\367\340\053\364\333\256\141\056\211\020\215\153\154 -\272\263\002\275\325\066\305\110\067\043\342\360\132\067\122\063 -\027\022\342\321\140\115\276\057\101\021\343\366\027\045\014\213 -\221\300\033\231\173\231\126\015\257\356\322\274\107\127\343\171 -\111\173\064\211\047\044\204\336\261\354\351\130\116\376\116\337 -\132\276\101\255\254\010\305\030\016\357\322\123\356\154\320\235 -\022\001\023\215\334\200\142\367\225\251\104\210\112\161\116\140 -\125\236\333\043\031\171\126\007\014\077\143\013\134\260\342\276 -\176\025\374\224\063\130\101\070\164\304\341\217\213\337\046\254 -\037\265\213\073\267\103\131\153\260\044\246\155\220\213\304\162 -\352\135\063\230\267\313\336\136\173\357\224\361\033\076\312\311 -\041\301\305\230\002\252\242\366\133\167\233\365\176\226\125\064 -\034\147\151\300\361\102\343\107\254\374\050\034\146\125\002\003 -\001\000\001\243\201\214\060\201\211\060\017\006\003\125\035\023 -\004\010\060\006\001\001\377\002\001\012\060\013\006\003\125\035 -\017\004\004\003\002\001\006\060\035\006\003\125\035\016\004\026 -\004\024\343\163\055\337\313\016\050\014\336\335\263\244\312\171 -\270\216\273\350\060\211\060\021\006\011\140\206\110\001\206\370 -\102\001\001\004\004\003\002\001\006\060\067\006\003\125\035\037 -\004\060\060\056\060\054\240\052\240\050\206\046\150\164\164\160 -\072\057\057\167\167\167\056\143\145\162\164\160\154\165\163\056 -\143\157\155\057\103\122\114\057\143\154\141\163\163\062\056\143 -\162\154\060\015\006\011\052\206\110\206\367\015\001\001\005\005 -\000\003\202\001\001\000\247\124\317\210\104\031\313\337\324\177 -\000\337\126\063\142\265\367\121\001\220\353\303\077\321\210\104 -\351\044\135\357\347\024\275\040\267\232\074\000\376\155\237\333 -\220\334\327\364\142\326\213\160\135\347\345\004\110\251\150\174 -\311\361\102\363\154\177\305\172\174\035\121\210\272\322\012\076 -\047\135\336\055\121\116\323\023\144\151\344\056\343\323\347\233 -\011\231\246\340\225\233\316\032\327\177\276\074\316\122\263\021 -\025\301\017\027\315\003\273\234\045\025\272\242\166\211\374\006 -\361\030\320\223\113\016\174\202\267\245\364\366\137\376\355\100 -\246\235\204\164\071\271\334\036\205\026\332\051\033\206\043\000 -\311\273\211\176\156\200\210\036\057\024\264\003\044\250\062\157 -\003\232\107\054\060\276\126\306\247\102\002\160\033\352\100\330 -\272\005\003\160\007\244\226\377\375\110\063\012\341\334\245\201 -\220\233\115\335\175\347\347\262\315\134\310\152\225\370\245\366 -\215\304\135\170\010\276\173\006\326\111\317\031\066\120\043\056 -\010\346\236\005\115\107\030\325\026\351\261\326\266\020\325\273 -\227\277\242\216\264\124 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "Certplus Class 2 Primary CA" -# Issuer: CN=Class 2 Primary CA,O=Certplus,C=FR -# Serial Number:00:85:bd:4b:f3:d8:da:e3:69:f6:94:d7:5f:c3:a5:44:23 -# Subject: CN=Class 2 Primary CA,O=Certplus,C=FR -# Not Valid Before: Wed Jul 07 17:05:00 1999 -# Not Valid After : Sat Jul 06 23:59:59 2019 -# Fingerprint (MD5): 88:2C:8C:52:B8:A2:3C:F3:F7:BB:03:EA:AE:AC:42:0B -# Fingerprint (SHA1): 74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Certplus Class 2 Primary CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\164\040\164\101\162\234\335\222\354\171\061\330\043\020\215\302 -\201\222\342\273 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\210\054\214\122\270\242\074\363\367\273\003\352\256\254\102\013 -END -CKA_ISSUER MULTILINE_OCTAL -\060\075\061\013\060\011\006\003\125\004\006\023\002\106\122\061 -\021\060\017\006\003\125\004\012\023\010\103\145\162\164\160\154 -\165\163\061\033\060\031\006\003\125\004\003\023\022\103\154\141 -\163\163\040\062\040\120\162\151\155\141\162\171\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\205\275\113\363\330\332\343\151\366\224\327\137\303 -\245\104\043 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "DST Root CA X3" # @@ -4932,6 +4691,8 @@ CKA_VALUE MULTILINE_OCTAL \013\004\216\007\333\051\266\012\356\235\202\065\065\020 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "DST Root CA X3" # Issuer: CN=DST Root CA X3,O=Digital Signature Trust Co. @@ -5099,6 +4860,8 @@ CKA_VALUE MULTILINE_OCTAL \205\206\171\145\322 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "SwissSign Platinum CA - G2" # Issuer: CN=SwissSign Platinum CA - G2,O=SwissSign AG,C=CH @@ -5264,6 +5027,8 @@ CKA_VALUE MULTILINE_OCTAL \111\044\133\311\260\320\127\301\372\076\172\341\227\311 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "SwissSign Gold CA - G2" # Issuer: CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH @@ -5430,6 +5195,8 @@ CKA_VALUE MULTILINE_OCTAL \156 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "SwissSign Silver CA - G2" # Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH @@ -5562,6 +5329,8 @@ CKA_VALUE MULTILINE_OCTAL \253\022\350\263\336\132\345\240\174\350\017\042\035\132\351\131 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Primary Certification Authority" # Issuer: CN=GeoTrust Primary Certification Authority,O=GeoTrust Inc.,C=US @@ -5717,6 +5486,8 @@ CKA_VALUE MULTILINE_OCTAL \215\126\214\150 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "thawte Primary Root CA" # Issuer: CN=thawte Primary Root CA,OU="(c) 2006 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US @@ -5892,6 +5663,8 @@ CKA_VALUE MULTILINE_OCTAL \254\021\326\250\355\143\152 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G5" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -6035,6 +5808,8 @@ CKA_VALUE MULTILINE_OCTAL \113\035\236\054\302\270\150\274\355\002\356\061 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "SecureTrust CA" # Issuer: CN=SecureTrust CA,O=SecureTrust Corporation,C=US @@ -6170,6 +5945,8 @@ CKA_VALUE MULTILINE_OCTAL \117\043\037\332\154\254\037\104\341\335\043\170\121\133\307\026 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Secure Global CA" # Issuer: CN=Secure Global CA,O=SecureTrust Corporation,C=US @@ -6320,6 +6097,8 @@ CKA_VALUE MULTILINE_OCTAL \145 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "COMODO Certification Authority" # Issuer: CN=COMODO Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -6466,6 +6245,8 @@ CKA_VALUE MULTILINE_OCTAL \244\140\114\260\125\240\240\173\127\262 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Network Solutions Certificate Authority" # Issuer: CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US @@ -6592,6 +6373,8 @@ CKA_VALUE MULTILINE_OCTAL \334\335\363\377\035\054\072\026\127\331\222\071\326 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "COMODO ECC Certification Authority" # Issuer: CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -6743,6 +6526,8 @@ CKA_VALUE MULTILINE_OCTAL \374\276\337\012\015 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "OISTE WISeKey Global Root GA CA" # Issuer: CN=OISTE WISeKey Global Root GA CA,OU=OISTE Foundation Endorsed,OU=Copyright (c) 2005,O=WISeKey,C=CH @@ -6878,6 +6663,8 @@ CKA_VALUE MULTILINE_OCTAL \300\226\130\057\352\273\106\327\273\344\331\056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Certigna" # Issuer: CN=Certigna,O=Dhimyotis,C=FR @@ -6913,147 +6700,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -# -# Certificate "Deutsche Telekom Root CA 2" -# -# Issuer: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE -# Serial Number: 38 (0x26) -# Subject: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE -# Not Valid Before: Fri Jul 09 12:11:00 1999 -# Not Valid After : Tue Jul 09 23:59:00 2019 -# Fingerprint (MD5): 74:01:4A:91:B1:08:C4:58:CE:47:CD:F0:DD:11:53:08 -# Fingerprint (SHA1): 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Deutsche Telekom Root CA 2" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061 -\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143 -\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060 -\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145 -\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043 -\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150 -\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103 -\101\040\062 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061 -\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143 -\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060 -\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145 -\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043 -\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150 -\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103 -\101\040\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\046 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\237\060\202\002\207\240\003\002\001\002\002\001\046 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061\034 -\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143\150 -\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060\035 -\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145\143 -\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043\060 -\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150\145 -\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103\101 -\040\062\060\036\027\015\071\071\060\067\060\071\061\062\061\061 -\060\060\132\027\015\061\071\060\067\060\071\062\063\065\071\060 -\060\132\060\161\061\013\060\011\006\003\125\004\006\023\002\104 -\105\061\034\060\032\006\003\125\004\012\023\023\104\145\165\164 -\163\143\150\145\040\124\145\154\145\153\157\155\040\101\107\061 -\037\060\035\006\003\125\004\013\023\026\124\055\124\145\154\145 -\123\145\143\040\124\162\165\163\164\040\103\145\156\164\145\162 -\061\043\060\041\006\003\125\004\003\023\032\104\145\165\164\163 -\143\150\145\040\124\145\154\145\153\157\155\040\122\157\157\164 -\040\103\101\040\062\060\202\001\042\060\015\006\011\052\206\110 -\206\367\015\001\001\001\005\000\003\202\001\017\000\060\202\001 -\012\002\202\001\001\000\253\013\243\065\340\213\051\024\261\024 -\205\257\074\020\344\071\157\065\135\112\256\335\352\141\215\225 -\111\364\157\144\243\032\140\146\244\251\100\042\204\331\324\245 -\345\170\223\016\150\001\255\271\115\134\072\316\323\270\250\102 -\100\337\317\243\272\202\131\152\222\033\254\034\232\332\010\053 -\045\047\371\151\043\107\361\340\353\054\172\233\365\023\002\320 -\176\064\174\302\236\074\000\131\253\365\332\014\365\062\074\053 -\254\120\332\326\303\336\203\224\312\250\014\231\062\016\010\110 -\126\133\152\373\332\341\130\130\001\111\137\162\101\074\025\006 -\001\216\135\255\252\270\223\264\315\236\353\247\350\152\055\122 -\064\333\072\357\134\165\121\332\333\363\061\371\356\161\230\062 -\304\124\025\104\014\371\233\125\355\255\337\030\010\240\243\206 -\212\111\356\123\005\217\031\114\325\336\130\171\233\322\152\034 -\102\253\305\325\247\317\150\017\226\344\341\141\230\166\141\310 -\221\174\326\076\000\342\221\120\207\341\235\012\346\255\227\322 -\035\306\072\175\313\274\332\003\064\325\216\133\001\365\152\007 -\267\026\266\156\112\177\002\003\001\000\001\243\102\060\100\060 -\035\006\003\125\035\016\004\026\004\024\061\303\171\033\272\365 -\123\327\027\340\211\172\055\027\154\012\263\053\235\063\060\017 -\006\003\125\035\023\004\010\060\006\001\001\377\002\001\005\060 -\016\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060 -\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003\202 -\001\001\000\224\144\131\255\071\144\347\051\353\023\376\132\303 -\213\023\127\310\004\044\360\164\167\300\140\343\147\373\351\211 -\246\203\277\226\202\174\156\324\303\075\357\236\200\156\273\051 -\264\230\172\261\073\124\353\071\027\107\176\032\216\013\374\037 -\061\131\061\004\262\316\027\363\054\307\142\066\125\342\042\330 -\211\125\264\230\110\252\144\372\326\034\066\330\104\170\132\132 -\043\072\127\227\365\172\060\117\256\237\152\114\113\053\216\240 -\003\343\076\340\251\324\322\173\322\263\250\342\162\074\255\236 -\377\200\131\344\233\105\264\366\073\260\315\071\031\230\062\345 -\352\041\141\220\344\061\041\216\064\261\367\057\065\112\205\020 -\332\347\212\067\041\276\131\143\340\362\205\210\061\123\324\124 -\024\205\160\171\364\056\006\167\047\165\057\037\270\212\371\376 -\305\272\330\066\344\203\354\347\145\267\277\143\132\363\106\257 -\201\224\067\324\101\214\326\043\326\036\317\365\150\033\104\143 -\242\132\272\247\065\131\241\345\160\005\233\016\043\127\231\224 -\012\155\272\071\143\050\206\222\363\030\204\330\373\321\317\005 -\126\144\127 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for Certificate "Deutsche Telekom Root CA 2" -# Issuer: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE -# Serial Number: 38 (0x26) -# Subject: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE -# Not Valid Before: Fri Jul 09 12:11:00 1999 -# Not Valid After : Tue Jul 09 23:59:00 2019 -# Fingerprint (MD5): 74:01:4A:91:B1:08:C4:58:CE:47:CD:F0:DD:11:53:08 -# Fingerprint (SHA1): 85:A4:08:C0:9C:19:3E:5D:51:58:7D:CD:D6:13:30:FD:8C:DE:37:BF -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Deutsche Telekom Root CA 2" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\205\244\010\300\234\031\076\135\121\130\175\315\326\023\060\375 -\214\336\067\277 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\164\001\112\221\261\010\304\130\316\107\315\360\335\021\123\010 -END -CKA_ISSUER MULTILINE_OCTAL -\060\161\061\013\060\011\006\003\125\004\006\023\002\104\105\061 -\034\060\032\006\003\125\004\012\023\023\104\145\165\164\163\143 -\150\145\040\124\145\154\145\153\157\155\040\101\107\061\037\060 -\035\006\003\125\004\013\023\026\124\055\124\145\154\145\123\145 -\143\040\124\162\165\163\164\040\103\145\156\164\145\162\061\043 -\060\041\006\003\125\004\003\023\032\104\145\165\164\163\143\150 -\145\040\124\145\154\145\153\157\155\040\122\157\157\164\040\103 -\101\040\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\046 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "Cybertrust Global Root" # @@ -7148,6 +6794,8 @@ CKA_VALUE MULTILINE_OCTAL \246\210\070\316\125 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Cybertrust Global Root" # Issuer: CN=Cybertrust Global Root,O="Cybertrust, Inc" @@ -7315,6 +6963,8 @@ CKA_VALUE MULTILINE_OCTAL \201\370\021\234 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "ePKI Root Certification Authority" # Issuer: OU=ePKI Root Certification Authority,O="Chunghwa Telecom Co., Ltd.",C=TW @@ -7440,6 +7090,8 @@ CKA_VALUE MULTILINE_OCTAL \366\356\260\132\116\111\104\124\130\137\102\203 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "certSIGN ROOT CA" # Issuer: OU=certSIGN ROOT CA,O=certSIGN,C=RO @@ -7588,6 +7240,8 @@ CKA_VALUE MULTILINE_OCTAL \021\055 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Primary Certification Authority - G3" # Issuer: CN=GeoTrust Primary Certification Authority - G3,OU=(c) 2008 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US @@ -7717,6 +7371,8 @@ CKA_VALUE MULTILINE_OCTAL \367\130\077\056\162\002\127\243\217\241\024\056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "thawte Primary Root CA - G2" # Issuer: CN=thawte Primary Root CA - G2,OU="(c) 2007 thawte, Inc. - For authorized use only",O="thawte, Inc.",C=US @@ -7877,6 +7533,8 @@ CKA_VALUE MULTILINE_OCTAL \061\324\100\032\142\064\066\077\065\001\256\254\143\240 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "thawte Primary Root CA - G3" # Issuer: CN=thawte Primary Root CA - G3,OU="(c) 2008 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US @@ -8013,6 +7671,8 @@ CKA_VALUE MULTILINE_OCTAL \017\212 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GeoTrust Primary Certification Authority - G2" # Issuer: CN=GeoTrust Primary Certification Authority - G2,OU=(c) 2007 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US @@ -8183,6 +7843,8 @@ CKA_VALUE MULTILINE_OCTAL \354\315\202\141\361\070\346\117\227\230\052\132\215 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "VeriSign Universal Root Certification Authority" # Issuer: CN=VeriSign Universal Root Certification Authority,OU="(c) 2008 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -8338,6 +8000,8 @@ CKA_VALUE MULTILINE_OCTAL \055\247\330\206\052\335\056\020 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G4" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4,OU="(c) 2007 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -8498,6 +8162,8 @@ CKA_VALUE MULTILINE_OCTAL \330\316\304\143\165\077\131\107\261 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "NetLock Arany (Class Gold) Főtanúsítvány" # Issuer: CN=NetLock Arany (Class Gold) F..tan..s..tv..ny,OU=Tan..s..tv..nykiad..k (Certification Services),O=NetLock Kft.,L=Budapest,C=HU @@ -8672,6 +8338,8 @@ CKA_VALUE MULTILINE_OCTAL \370\161\012\334\271\374\175\062\140\346\353\257\212\001 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Staat der Nederlanden Root CA - G2" # Issuer: CN=Staat der Nederlanden Root CA - G2,O=Staat der Nederlanden,C=NL @@ -8798,6 +8466,8 @@ CKA_VALUE MULTILINE_OCTAL \002\153\331\132 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Hongkong Post Root CA 1" # Issuer: CN=Hongkong Post Root CA 1,O=Hongkong Post,C=HK @@ -8929,6 +8599,8 @@ CKA_VALUE MULTILINE_OCTAL \362 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "SecureSign RootCA11" # Issuer: CN=SecureSign RootCA11,O="Japan Certification Services, Inc.",C=JP @@ -9076,6 +8748,8 @@ CKA_VALUE MULTILINE_OCTAL \202\042\055\172\124\253\160\303\175\042\145\202\160\226 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Microsec e-Szigno Root CA 2009" # Issuer: E=info@e-szigno.hu,CN=Microsec e-Szigno Root CA 2009,O=Microsec Ltd.,L=Budapest,C=HU @@ -9208,6 +8882,8 @@ CKA_VALUE MULTILINE_OCTAL \130\077\137 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "GlobalSign Root CA - R3" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R3 @@ -9381,6 +9057,8 @@ CKA_VALUE MULTILINE_OCTAL \156\117\022\176\012\074\235\225 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Autoridad de Certificacion Firmaprofesional CIF A62634068" # Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068,C=ES @@ -9550,6 +9228,8 @@ CKA_VALUE MULTILINE_OCTAL \333\374\046\210\307 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Izenpe.com" # Issuer: CN=Izenpe.com,O=IZENPE S.A.,C=ES @@ -9755,6 +9435,8 @@ CKA_VALUE MULTILINE_OCTAL \167\110\320 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Chambers of Commerce Root - 2008" # Issuer: CN=Chambers of Commerce Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU @@ -9964,6 +9646,8 @@ CKA_VALUE MULTILINE_OCTAL \351\233\256\325\124\300\164\200\321\013\102\237\301 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Global Chambersign Root - 2008" # Issuer: CN=Global Chambersign Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU @@ -10112,6 +9796,8 @@ CKA_VALUE MULTILINE_OCTAL \342\342\104\276\134\367\352\034\365 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Go Daddy Root Certificate Authority - G2" # Issuer: CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -10262,6 +9948,8 @@ CKA_VALUE MULTILINE_OCTAL \364 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Starfield Root Certificate Authority - G2" # Issuer: CN=Starfield Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -10414,6 +10102,8 @@ CKA_VALUE MULTILINE_OCTAL \261\050\272 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Starfield Services Root Certificate Authority - G2" # Issuer: CN=Starfield Services Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -10545,6 +10235,8 @@ CKA_VALUE MULTILINE_OCTAL \007\072\027\144\265\004\265\043\041\231\012\225\073\227\174\357 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AffirmTrust Commercial" # Issuer: CN=AffirmTrust Commercial,O=AffirmTrust,C=US @@ -10671,6 +10363,8 @@ CKA_VALUE MULTILINE_OCTAL \355\132\000\124\205\034\026\066\222\014\134\372\246\255\277\333 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AffirmTrust Networking" # Issuer: CN=AffirmTrust Networking,O=AffirmTrust,C=US @@ -10829,6 +10523,8 @@ CKA_VALUE MULTILINE_OCTAL \051\340\266\270\011\150\031\034\030\103 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AffirmTrust Premium" # Issuer: CN=AffirmTrust Premium,O=AffirmTrust,C=US @@ -10935,6 +10631,8 @@ CKA_VALUE MULTILINE_OCTAL \214\171 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "AffirmTrust Premium ECC" # Issuer: CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US @@ -11074,6 +10772,8 @@ CKA_VALUE MULTILINE_OCTAL \326\267\064\365\176\316\071\232\331\070\361\121\367\117\054 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Certum Trusted Network CA" # Issuer: CN=Certum Trusted Network CA,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL @@ -11210,6 +10910,8 @@ CKA_VALUE MULTILINE_OCTAL \274\060\376\173\016\063\220\373\355\322\024\221\037\007\257 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "TWCA Root Certification Authority" # Issuer: CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW @@ -11693,6 +11395,8 @@ CKA_VALUE MULTILINE_OCTAL \201\050\174\247\175\047\353\000\256\215\067 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Security Communication RootCA2" # Issuer: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP @@ -11876,6 +11580,8 @@ CKA_VALUE MULTILINE_OCTAL \371\210\075\176\270\157\156\003\344\102 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "EC-ACC" # Issuer: CN=EC-ACC,OU=Jerarquia Entitats de Certificacio Catalanes,OU=Vegeu https://www.catcert.net/verarrel (c)03,OU=Serveis Publics de Certificacio,O=Agencia Catalana de Certificacio (NIF Q-0801176-I),C=ES @@ -12039,6 +11745,8 @@ CKA_VALUE MULTILINE_OCTAL \113\321\047\327\270 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for Certificate "Hellenic Academic and Research Institutions RootCA 2011" # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR @@ -12275,6 +11983,8 @@ CKA_VALUE MULTILINE_OCTAL \216\362\024\212\314\351\265\174\373\154\235\014\245\341\226 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Actalis Authentication Root CA" # Issuer: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT @@ -12406,6 +12116,8 @@ CKA_VALUE MULTILINE_OCTAL \145\353\127\331\363\127\226\273\110\315\201 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Trustis FPS Root CA" # Issuer: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB @@ -12566,6 +12278,8 @@ CKA_VALUE MULTILINE_OCTAL \327\201\011\361\311\307\046\015\254\230\026\126\240 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Buypass Class 2 Root CA" # Issuer: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO @@ -12725,6 +12439,8 @@ CKA_VALUE MULTILINE_OCTAL \061\356\006\274\163\277\023\142\012\237\307\271\227 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Buypass Class 3 Root CA" # Issuer: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO @@ -12867,6 +12583,8 @@ CKA_VALUE MULTILINE_OCTAL \116\223\303\244\124\024\133 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "T-TeleSec GlobalRoot Class 3" # Issuer: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE @@ -13016,6 +12734,8 @@ CKA_VALUE MULTILINE_OCTAL \307\314\165\301\226\305\235 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "EE Certification Centre Root CA" # Issuer: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE @@ -13229,6 +12949,8 @@ CKA_VALUE MULTILINE_OCTAL \164\145\327\134\376\243\342 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "D-TRUST Root Class 3 CA 2 2009" # Issuer: CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE @@ -13373,6 +13095,8 @@ CKA_VALUE MULTILINE_OCTAL \352\237\026\361\054\124\265 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "D-TRUST Root Class 3 CA 2 EV 2009" # Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009,O=D-Trust GmbH,C=DE @@ -13410,181 +13134,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE -# -# Certificate "Swisscom Root CA 2" -# -# Issuer: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch -# Serial Number:1e:9e:28:e8:48:f2:e5:ef:c3:7c:4a:1e:5a:18:67:b6 -# Subject: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch -# Not Valid Before: Fri Jun 24 08:38:14 2011 -# Not Valid After : Wed Jun 25 07:38:14 2031 -# Fingerprint (MD5): 5B:04:69:EC:A5:83:94:63:18:A7:86:D0:E4:F2:6E:19 -# Fingerprint (SHA1): 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Swisscom Root CA 2" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 -\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 -\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 -\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 -\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 -\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 -\164\040\103\101\040\062 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 -\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 -\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 -\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 -\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 -\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 -\164\040\103\101\040\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\036\236\050\350\110\362\345\357\303\174\112\036\132\030 -\147\266 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\036 -\236\050\350\110\362\345\357\303\174\112\036\132\030\147\266\060 -\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\144 -\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060 -\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155 -\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164 -\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123 -\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003 -\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040 -\103\101\040\062\060\036\027\015\061\061\060\066\062\064\060\070 -\063\070\061\064\132\027\015\063\061\060\066\062\065\060\067\063 -\070\061\064\132\060\144\061\013\060\011\006\003\125\004\006\023 -\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167 -\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023 -\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151 -\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060 -\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155 -\040\122\157\157\164\040\103\101\040\062\060\202\002\042\060\015 -\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 -\017\000\060\202\002\012\002\202\002\001\000\225\102\116\204\235 -\121\346\323\011\350\162\132\043\151\333\170\160\216\026\361\053 -\217\015\003\316\223\314\056\000\010\173\253\063\214\364\351\100 -\346\027\114\253\236\270\107\024\062\167\062\335\050\014\336\030 -\113\137\166\237\370\071\073\374\116\211\330\174\305\147\357\253 -\322\271\064\137\153\072\363\144\066\316\302\260\317\023\150\312 -\310\313\353\265\342\075\056\041\337\352\054\324\340\371\160\226 -\114\377\152\130\230\267\027\344\033\122\345\176\007\000\035\137 -\332\346\076\225\004\267\151\210\071\241\101\140\045\141\113\225 -\071\150\142\034\261\013\005\211\300\066\202\024\041\077\256\333 -\241\375\274\157\034\140\206\266\123\224\111\271\053\106\305\117 -\000\053\277\241\273\313\077\340\307\127\034\127\350\326\151\370 -\301\044\122\235\210\125\335\302\207\056\164\043\320\024\375\052 -\107\132\273\246\235\375\224\344\321\212\245\137\206\143\166\205 -\313\257\377\111\050\374\200\355\114\171\322\273\344\300\357\001 -\356\120\101\010\065\043\160\053\251\026\264\214\156\205\351\266 -\021\317\061\335\123\046\033\337\055\132\112\002\100\374\304\300 -\266\351\061\032\010\050\345\140\303\037\304\220\216\020\142\140 -\104\015\354\012\276\125\030\161\054\245\364\262\274\025\142\377 -\034\343\276\035\332\036\127\263\074\176\315\202\035\221\343\113 -\353\054\122\064\260\212\375\022\116\226\260\353\160\177\236\071 -\367\146\102\261\253\254\122\332\166\100\127\173\052\275\350\156 -\003\262\013\200\205\210\235\014\307\302\167\260\232\232\127\364 -\270\372\023\134\150\223\072\147\244\227\320\033\231\267\206\062 -\113\140\330\316\357\320\014\177\225\237\157\207\117\207\212\216 -\137\010\174\252\133\374\132\276\241\221\237\125\175\116\260\013 -\151\314\260\224\250\247\207\362\323\112\120\334\137\162\260\026 -\165\036\313\264\030\142\232\260\247\071\252\233\237\146\330\215 -\246\154\226\025\343\346\362\370\361\203\142\154\273\125\351\141 -\223\243\075\365\261\127\213\117\043\260\233\345\224\152\057\337 -\214\337\225\121\051\140\241\013\051\344\134\125\130\267\250\374 -\231\356\045\115\114\016\263\323\114\217\204\350\051\017\375\020 -\124\002\205\310\371\345\303\213\317\347\017\002\003\001\000\001 -\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377 -\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060 -\024\060\022\006\007\140\205\164\001\123\002\001\006\007\140\205 -\164\001\123\002\001\060\022\006\003\125\035\023\001\001\377\004 -\010\060\006\001\001\377\002\001\007\060\035\006\003\125\035\016 -\004\026\004\024\115\046\040\042\211\113\323\325\244\012\241\157 -\336\342\022\201\305\361\074\056\060\037\006\003\125\035\043\004 -\030\060\026\200\024\115\046\040\042\211\113\323\325\244\012\241 -\157\336\342\022\201\305\361\074\056\060\015\006\011\052\206\110 -\206\367\015\001\001\013\005\000\003\202\002\001\000\062\012\262 -\244\033\313\175\276\202\127\211\271\152\177\363\364\301\056\021 -\175\270\031\076\171\267\250\250\162\067\146\233\032\355\254\023 -\073\016\277\142\360\234\337\236\173\241\123\110\016\101\172\312 -\040\247\027\033\266\170\354\100\221\363\102\255\020\303\134\357 -\377\140\131\177\315\205\243\213\075\110\034\045\002\074\147\175 -\365\062\351\057\060\345\175\245\172\070\320\363\146\052\146\036 -\215\063\203\212\157\174\156\250\132\165\232\270\327\332\130\110 -\104\107\250\114\372\114\111\012\112\302\022\067\250\100\014\303 -\310\341\320\127\015\227\062\225\307\072\237\227\323\127\370\013 -\336\345\162\363\243\333\377\265\330\131\262\163\335\115\052\161 -\262\272\111\365\313\034\325\365\171\310\231\263\374\301\114\164 -\343\264\275\051\067\025\004\050\036\336\105\106\160\354\257\272 -\170\016\212\052\316\000\171\334\300\137\031\147\054\153\113\357 -\150\150\013\103\343\254\301\142\011\357\246\335\145\141\240\257 -\204\125\110\221\122\034\306\045\221\052\320\301\042\043\141\131 -\257\105\021\205\035\001\044\064\217\317\263\377\027\162\040\023 -\302\200\252\041\054\161\071\016\320\217\134\301\323\321\216\042 -\162\106\114\035\226\256\117\161\261\341\005\051\226\131\364\273 -\236\165\075\317\015\067\015\142\333\046\214\143\251\043\337\147 -\006\074\174\072\332\064\102\341\146\264\106\004\336\306\226\230 -\017\113\110\172\044\062\165\221\237\254\367\150\351\052\271\125 -\145\316\135\141\323\047\160\330\067\376\237\271\257\240\056\126 -\267\243\145\121\355\073\253\024\277\114\121\003\350\137\212\005 -\233\356\212\156\234\357\277\150\372\310\332\013\343\102\311\320 -\027\024\234\267\112\340\257\223\047\041\125\046\265\144\057\215 -\361\377\246\100\005\205\005\134\312\007\031\134\013\023\050\114 -\130\177\302\245\357\105\332\140\323\256\145\141\235\123\203\164 -\302\256\362\134\302\026\355\222\076\204\076\163\140\210\274\166 -\364\054\317\320\175\175\323\270\136\321\221\022\020\351\315\335 -\312\045\343\325\355\231\057\276\165\201\113\044\371\105\106\224 -\311\051\041\123\234\046\105\252\023\027\344\347\315\170\342\071 -\301\053\022\236\246\236\033\305\346\016\331\061\331 -END -CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE - -# Trust for "Swisscom Root CA 2" -# Issuer: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch -# Serial Number:1e:9e:28:e8:48:f2:e5:ef:c3:7c:4a:1e:5a:18:67:b6 -# Subject: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch -# Not Valid Before: Fri Jun 24 08:38:14 2011 -# Not Valid After : Wed Jun 25 07:38:14 2031 -# Fingerprint (MD5): 5B:04:69:EC:A5:83:94:63:18:A7:86:D0:E4:F2:6E:19 -# Fingerprint (SHA1): 77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Swisscom Root CA 2" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\167\107\117\306\060\344\017\114\107\144\077\204\272\270\306\225 -\112\212\101\354 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\133\004\151\354\245\203\224\143\030\247\206\320\344\362\156\031 -END -CKA_ISSUER MULTILINE_OCTAL -\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 -\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 -\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 -\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 -\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 -\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 -\164\040\103\101\040\062 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\020\036\236\050\350\110\362\345\357\303\174\112\036\132\030 -\147\266 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - # # Certificate "CA Disig Root R2" # @@ -13711,6 +13260,8 @@ CKA_VALUE MULTILINE_OCTAL \363\154\033\165\106\243\345\112\027\351\244\327\013 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "CA Disig Root R2" # Issuer: CN=CA Disig Root R2,O=Disig a.s.,L=Bratislava,C=SK @@ -13911,6 +13462,8 @@ CKA_VALUE MULTILINE_OCTAL \125\064\106\052\213\206\073 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "ACCVRAIZ1" # Issuer: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1 @@ -14071,6 +13624,8 @@ CKA_VALUE MULTILINE_OCTAL \053\006\320\004\315 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TWCA Global Root CA" # Issuer: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW @@ -14228,6 +13783,8 @@ CKA_VALUE MULTILINE_OCTAL \245\240\314\277\323\366\165\244\165\226\155\126 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TeliaSonera Root CA v1" # Issuer: CN=TeliaSonera Root CA v1,O=TeliaSonera @@ -14416,6 +13973,8 @@ CKA_VALUE MULTILINE_OCTAL \243\253\157\134\035\266\176\350\263\202\064\355\006\134\044 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "E-Tugra Certification Authority" # Issuer: CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tu..ra EBG Bili..im Teknolojileri ve Hizmetleri A....,L=Ankara,C=TR @@ -14565,6 +14124,8 @@ CKA_VALUE MULTILINE_OCTAL \005\047\216\023\241\156\302 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "T-TeleSec GlobalRoot Class 2" # Issuer: CN=T-TeleSec GlobalRoot Class 2,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE @@ -14696,6 +14257,8 @@ CKA_VALUE MULTILINE_OCTAL \035\362\376\011\021\260\360\207\173\247\235 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Atos TrustedRoot 2011" # Issuer: C=DE,O=Atos,CN=Atos TrustedRoot 2011 @@ -14856,6 +14419,8 @@ CKA_VALUE MULTILINE_OCTAL \063\140\345\303 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "QuoVadis Root CA 1 G3" # Issuer: CN=QuoVadis Root CA 1 G3,O=QuoVadis Limited,C=BM @@ -15018,6 +14583,8 @@ CKA_VALUE MULTILINE_OCTAL \203\336\177\214 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "QuoVadis Root CA 2 G3" # Issuer: CN=QuoVadis Root CA 2 G3,O=QuoVadis Limited,C=BM @@ -15180,6 +14747,8 @@ CKA_VALUE MULTILINE_OCTAL \130\371\230\364 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "QuoVadis Root CA 3 G3" # Issuer: CN=QuoVadis Root CA 3 G3,O=QuoVadis Limited,C=BM @@ -15317,6 +14886,8 @@ CKA_VALUE MULTILINE_OCTAL \042\023\163\154\317\046\365\212\051\347 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "DigiCert Assured ID Root G2" # Issuer: CN=DigiCert Assured ID Root G2,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -15435,6 +15006,8 @@ CKA_VALUE MULTILINE_OCTAL \352\226\143\152\145\105\222\225\001\264 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "DigiCert Assured ID Root G3" # Issuer: CN=DigiCert Assured ID Root G3,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -15574,6 +15147,8 @@ CKA_VALUE MULTILINE_OCTAL \062\266 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "DigiCert Global Root G2" # Issuer: CN=DigiCert Global Root G2,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -15692,6 +15267,8 @@ CKA_VALUE MULTILINE_OCTAL \263\047\027 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "DigiCert Global Root G3" # Issuer: CN=DigiCert Global Root G3,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -15863,6 +15440,8 @@ CKA_VALUE MULTILINE_OCTAL \317\363\146\176 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "DigiCert Trusted Root G4" # Issuer: CN=DigiCert Trusted Root G4,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -16042,6 +15621,8 @@ CKA_VALUE MULTILINE_OCTAL \065\123\205\006\112\135\237\255\273\033\137\164 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "COMODO RSA Certification Authority" # Issuer: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -16224,6 +15805,8 @@ CKA_VALUE MULTILINE_OCTAL \250\375 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "USERTrust RSA Certification Authority" # Issuer: CN=USERTrust RSA Certification Authority,O=The USERTRUST Network,L=Jersey City,ST=New Jersey,C=US @@ -16353,6 +15936,8 @@ CKA_VALUE MULTILINE_OCTAL \127\152\030 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "USERTrust ECC Certification Authority" # Issuer: CN=USERTrust ECC Certification Authority,O=The USERTRUST Network,L=Jersey City,ST=New Jersey,C=US @@ -16465,6 +16050,8 @@ CKA_VALUE MULTILINE_OCTAL \173\013\370\237\204 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GlobalSign ECC Root CA - R4" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign ECC Root CA - R4 @@ -16578,6 +16165,8 @@ CKA_VALUE MULTILINE_OCTAL \220\067 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GlobalSign ECC Root CA - R5" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign ECC Root CA - R5 @@ -16743,6 +16332,8 @@ CKA_VALUE MULTILINE_OCTAL \367\200\173\041\147\047\060\131 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Staat der Nederlanden Root CA - G3" # Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL @@ -16907,6 +16498,8 @@ CKA_VALUE MULTILINE_OCTAL \356\354\327\056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Staat der Nederlanden EV Root CA" # Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL @@ -17069,6 +16662,8 @@ CKA_VALUE MULTILINE_OCTAL \272\204\156\207 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "IdenTrust Commercial Root CA 1" # Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US @@ -17231,6 +16826,8 @@ CKA_VALUE MULTILINE_OCTAL \267\254\266\255\267\312\076\001\357\234 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "IdenTrust Public Sector Root CA 1" # Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US @@ -17390,6 +16987,8 @@ CKA_VALUE MULTILINE_OCTAL \105\366 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Entrust Root Certification Authority - G2" # Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US @@ -17535,6 +17134,8 @@ CKA_VALUE MULTILINE_OCTAL \231\267\046\101\133\045\140\256\320\110\032\356\006 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Entrust Root Certification Authority - EC1" # Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US @@ -17708,6 +17309,8 @@ CKA_VALUE MULTILINE_OCTAL \056 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "CFCA EV ROOT" # Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN @@ -17847,6 +17450,8 @@ CKA_VALUE MULTILINE_OCTAL \065\255\201\307\116\161\272\210\023 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "OISTE WISeKey Global Root GB CA" # Issuer: CN=OISTE WISeKey Global Root GB CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH @@ -17982,6 +17587,8 @@ CKA_VALUE MULTILINE_OCTAL \326\040\036\343\163\267 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "SZAFIR ROOT CA2" # Issuer: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL @@ -18160,6 +17767,8 @@ CKA_VALUE MULTILINE_OCTAL \016\265\271\276\044\217 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Certum Trusted Network CA 2" # Issuer: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL @@ -18347,6 +17956,8 @@ CKA_VALUE MULTILINE_OCTAL \276\157\152\247\365\054\102\355\062\255\266\041\236\276\274 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Hellenic Academic and Research Institutions RootCA 2015" # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR @@ -18483,6 +18094,8 @@ CKA_VALUE MULTILINE_OCTAL \342\174\352\002\130\042\221 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Hellenic Academic and Research Institutions ECC RootCA 2015" # Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR @@ -18652,6 +18265,8 @@ CKA_VALUE MULTILINE_OCTAL \376\216\036\127\242\315\100\235\176\142\042\332\336\030\047 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "ISRG Root X1" # Issuer: CN=ISRG Root X1,O=Internet Security Research Group,C=US @@ -18815,6 +18430,8 @@ CKA_VALUE MULTILINE_OCTAL \072\117\110\366\213\266\263 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "AC RAIZ FNMT-RCM" # Issuer: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES @@ -18940,6 +18557,8 @@ CKA_VALUE MULTILINE_OCTAL \304\220\276\361\271 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Amazon Root CA 1" # Issuer: CN=Amazon Root CA 1,O=Amazon,C=US @@ -19097,6 +18716,8 @@ CKA_VALUE MULTILINE_OCTAL \340\373\011\140\154 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Amazon Root CA 2" # Issuer: CN=Amazon Root CA 2,O=Amazon,C=US @@ -19197,6 +18818,8 @@ CKA_VALUE MULTILINE_OCTAL \143\044\110\034\337\060\175\325\150\073 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Amazon Root CA 3" # Issuer: CN=Amazon Root CA 3,O=Amazon,C=US @@ -19301,6 +18924,8 @@ CKA_VALUE MULTILINE_OCTAL \012\166\324\245\274\020 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Amazon Root CA 4" # Issuer: CN=Amazon Root CA 4,O=Amazon,C=US @@ -19468,6 +19093,8 @@ CKA_VALUE MULTILINE_OCTAL \045\307\043\200\203\012\353 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "LuxTrust Global Root 2" # Issuer: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU @@ -19617,6 +19244,8 @@ CKA_VALUE MULTILINE_OCTAL \322\063\340\377\275\321\124\071\051\017 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Symantec Class 1 Public Primary Certification Authority - G6" # Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -19771,6 +19400,8 @@ CKA_VALUE MULTILINE_OCTAL \157\374\132\344\202\125\131\257\061\251 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Symantec Class 2 Public Primary Certification Authority - G6" # Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -19904,6 +19535,8 @@ CKA_VALUE MULTILINE_OCTAL \362\014\105\111\071\277\231\004\034\323\020\240 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Symantec Class 1 Public Primary Certification Authority - G4" # Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -20037,6 +19670,8 @@ CKA_VALUE MULTILINE_OCTAL \051\246\330\107\331\240\226\030\333\362\105\263 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Symantec Class 2 Public Primary Certification Authority - G4" # Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -20182,6 +19817,8 @@ CKA_VALUE MULTILINE_OCTAL \137\134 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "D-TRUST Root CA 3 2013" # Issuer: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE @@ -20344,6 +19981,8 @@ CKA_VALUE MULTILINE_OCTAL \237\042\136\242\017\241\343 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" # Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR @@ -20519,6 +20158,8 @@ CKA_VALUE MULTILINE_OCTAL \250\267\101\154\007\335\275\074\206\227\057\322 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GDCA TrustAUTH R5 ROOT" # Issuer: CN=GDCA TrustAUTH R5 ROOT,O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.",C=CN @@ -20674,6 +20315,8 @@ CKA_VALUE MULTILINE_OCTAL \132\171\054\031 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TrustCor RootCert CA-1" # Issuer: CN=TrustCor RootCert CA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA @@ -20865,6 +20508,8 @@ CKA_VALUE MULTILINE_OCTAL \326\354\011 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TrustCor RootCert CA-2" # Issuer: CN=TrustCor RootCert CA-2,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA @@ -21021,6 +20666,8 @@ CKA_VALUE MULTILINE_OCTAL \264\237\327\346 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "TrustCor ECA-1" # Issuer: CN=TrustCor ECA-1,OU=TrustCor Certificate Authority,O=TrustCor Systems S. de R.L.,L=Panama City,ST=Panama,C=PA @@ -21200,6 +20847,8 @@ CKA_VALUE MULTILINE_OCTAL \271 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "SSL.com Root Certification Authority RSA" # Issuer: CN=SSL.com Root Certification Authority RSA,O=SSL Corporation,L=Houston,ST=Texas,C=US @@ -21324,6 +20973,8 @@ CKA_VALUE MULTILINE_OCTAL \145 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "SSL.com Root Certification Authority ECC" # Issuer: CN=SSL.com Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US @@ -21503,6 +21154,8 @@ CKA_VALUE MULTILINE_OCTAL \040\022\215\264\254\127\261\105\143\241\254\166\251\302\373 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "SSL.com EV Root Certification Authority RSA R2" # Issuer: CN=SSL.com EV Root Certification Authority RSA R2,O=SSL Corporation,L=Houston,ST=Texas,C=US @@ -21630,6 +21283,8 @@ CKA_VALUE MULTILINE_OCTAL \371\007\340\142\232\214\134\112 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "SSL.com EV Root Certification Authority ECC" # Issuer: CN=SSL.com EV Root Certification Authority ECC,O=SSL Corporation,L=Houston,ST=Texas,C=US @@ -21796,6 +21451,8 @@ CKA_VALUE MULTILINE_OCTAL \147\203\005\132\311\244\020 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GlobalSign Root CA - R6" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R6 @@ -21913,6 +21570,8 @@ CKA_VALUE MULTILINE_OCTAL \242\355\357\173\260\200\117\130\017\113\123\071\275 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "OISTE WISeKey Global Root GC CA" # Issuer: CN=OISTE WISeKey Global Root GC CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH @@ -22076,6 +21735,8 @@ CKA_VALUE MULTILINE_OCTAL \361\306\143\107\125\034\272\245\010\121\165\246\110\045 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GTS Root R1" # Issuer: CN=GTS Root R1,O=Google Trust Services LLC,C=US @@ -22237,6 +21898,8 @@ CKA_VALUE MULTILINE_OCTAL \267\375\054\010\122\117\202\335\243\360\324\206\011\002 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GTS Root R2" # Issuer: CN=GTS Root R2,O=Google Trust Services LLC,C=US @@ -22345,6 +22008,8 @@ CKA_VALUE MULTILINE_OCTAL \232\051\252\226\323\203\043\311\244\173\141\263\314\002\350\135 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GTS Root R3" # Issuer: CN=GTS Root R3,O=Google Trust Services LLC,C=US @@ -22453,6 +22118,8 @@ CKA_VALUE MULTILINE_OCTAL \161\314\362\260\115\326\376\231\310\224\251\165\242\343 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "GTS Root R4" # Issuer: CN=GTS Root R4,O=Google Trust Services LLC,C=US @@ -22611,6 +22278,8 @@ CKA_VALUE MULTILINE_OCTAL \120\037\212\373\006\365\302\031\360\320 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "UCA Global G2 Root" # Issuer: CN=UCA Global G2 Root,O=UniTrust,C=CN @@ -22771,6 +22440,8 @@ CKA_VALUE MULTILINE_OCTAL \177\275\145\040\262\311\301\053\166\030\166\237\126\261 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "UCA Extended Validation Root" # Issuer: CN=UCA Extended Validation Root,O=UniTrust,C=CN @@ -22950,6 +22621,8 @@ CKA_VALUE MULTILINE_OCTAL \045\124\377\242\332\117\212\141\071\136\256\075\112\214\275 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Certigna Root CA" # Issuer: CN=Certigna Root CA,OU=0002 48146308100036,O=Dhimyotis,C=FR @@ -23087,6 +22760,8 @@ CKA_VALUE MULTILINE_OCTAL \210\336\272\314\037\200\176\112 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "emSign Root CA - G1" # Issuer: CN=emSign Root CA - G1,O=eMudhra Technologies Limited,OU=emSign PKI,C=IN @@ -23204,6 +22879,8 @@ CKA_VALUE MULTILINE_OCTAL \054\243 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "emSign ECC Root CA - G3" # Issuer: CN=emSign ECC Root CA - G3,O=eMudhra Technologies Limited,OU=emSign PKI,C=IN @@ -23337,6 +23014,8 @@ CKA_VALUE MULTILINE_OCTAL \361\337\312\276\203\015\102 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "emSign Root CA - C1" # Issuer: CN=emSign Root CA - C1,O=eMudhra Inc,OU=emSign PKI,C=US @@ -23448,6 +23127,8 @@ CKA_VALUE MULTILINE_OCTAL \276\201\007\125\060\120\040\024\365\127\070\012\250\061\121 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "emSign ECC Root CA - C3" # Issuer: CN=emSign ECC Root CA - C3,O=eMudhra Inc,OU=emSign PKI,C=US @@ -23623,6 +23304,8 @@ CKA_VALUE MULTILINE_OCTAL \232\233\364 END CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE +CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE +CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE # Trust for "Hongkong Post Root CA 3" # Issuer: CN=Hongkong Post Root CA 3,O=Hongkong Post,L=Hong Kong,ST=Hong Kong,C=HK diff --git a/tools/check-imports.py b/tools/check-imports.py index b71b4a9271dfc4..51b4e63aa03903 100755 --- a/tools/check-imports.py +++ b/tools/check-imports.py @@ -2,6 +2,7 @@ from __future__ import print_function import glob +import io import re import sys @@ -15,7 +16,7 @@ def do_exist(file_name, lines, imported): def is_valid(file_name): - with open(file_name) as source_file: + with io.open(file_name, encoding='utf-8') as source_file: lines = [line.strip() for line in source_file] usings, importeds, line_numbers, valid = [], [], [], True diff --git a/tools/doc/versions.js b/tools/doc/versions.js index 854329bd9a8a02..7a4e2c3ff76b1a 100644 --- a/tools/doc/versions.js +++ b/tools/doc/versions.js @@ -1,21 +1,33 @@ 'use strict'; +const { readFileSync } = require('fs'); +const path = require('path'); +const srcRoot = path.join(__dirname, '..', '..'); + let _versions; +const isRelease = () => { + const re = /#define NODE_VERSION_IS_RELEASE 0/; + const file = path.join(srcRoot, 'src', 'node_version.h'); + return !re.test(readFileSync(file, { encoding: 'utf8' })); +}; + const getUrl = (url) => { return new Promise((resolve, reject) => { const https = require('https'); - const request = https.get(url, (response) => { + const request = https.get(url, { timeout: 5000 }, (response) => { if (response.statusCode !== 200) { reject(new Error( `Failed to get ${url}, status code ${response.statusCode}`)); } response.setEncoding('utf8'); let body = ''; + response.on('aborted', () => reject()); response.on('data', (data) => body += data); response.on('end', () => resolve(body)); }); request.on('error', (err) => reject(err)); + request.on('timeout', () => request.abort()); }); }; @@ -27,10 +39,23 @@ module.exports = { // The CHANGELOG.md on release branches may not reference newer semver // majors of Node.js so fetch and parse the version from the master branch. - const githubContentUrl = 'https://raw.githubusercontent.com/nodejs/node/'; - const changelog = await getUrl(`${githubContentUrl}/master/CHANGELOG.md`); + const url = + 'https://raw.githubusercontent.com/nodejs/node/master/CHANGELOG.md'; + let changelog; + try { + changelog = await getUrl(url); + } catch (e) { + // Fail if this is a release build, otherwise fallback to local files. + if (isRelease()) { + throw e; + } else { + const file = path.join(srcRoot, 'CHANGELOG.md'); + console.warn(`Unable to retrieve ${url}. Falling back to ${file}.`); + changelog = readFileSync(file, { encoding: 'utf8' }); + } + } const ltsRE = /Long Term Support/i; - const versionRE = /\* \[Node\.js ([0-9.]+)\][^-—]+[-—]\s*(.*)\n/g; + const versionRE = /\* \[Node\.js ([0-9.]+)\][^-—]+[-—]\s*(.*)\r?\n/g; _versions = []; let match; while ((match = versionRE.exec(changelog)) != null) { diff --git a/tools/gyp/pylib/gyp/MSVSSettings_test.py b/tools/gyp/pylib/gyp/MSVSSettings_test.py index bf6ea6b802ff91..245478c8dae4ed 100755 --- a/tools/gyp/pylib/gyp/MSVSSettings_test.py +++ b/tools/gyp/pylib/gyp/MSVSSettings_test.py @@ -6,15 +6,19 @@ """Unit tests for the MSVSSettings.py file.""" -import StringIO import unittest import gyp.MSVSSettings as MSVSSettings +try: + from StringIO import StringIO # Python 2 +except ImportError: + from io import StringIO # Python 3 + class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def _ExpectedWarnings(self, expected): """Compares recorded lines to expected warnings.""" diff --git a/tools/gyp/pylib/gyp/common.py b/tools/gyp/pylib/gyp/common.py index e5ebcd9c9f2f06..351800ee25e23e 100644 --- a/tools/gyp/pylib/gyp/common.py +++ b/tools/gyp/pylib/gyp/common.py @@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import collections import errno import filecmp import os.path @@ -10,6 +9,11 @@ import tempfile import sys +try: + from collections.abc import MutableSet +except ImportError: + from collections import MutableSet + # A minimal memoizing decorator. It'll blow up if the args aren't immutable, # among other "problems". @@ -493,7 +497,7 @@ def uniquer(seq, idfun=None): # Based on http://code.activestate.com/recipes/576694/. -class OrderedSet(collections.MutableSet): +class OrderedSet(MutableSet): def __init__(self, iterable=None): self.end = end = [] end += [None, end, end] # sentinel node for doubly linked list diff --git a/tools/gyp/pylib/gyp/easy_xml_test.py b/tools/gyp/pylib/gyp/easy_xml_test.py index df64354982c01d..664b538a58db60 100755 --- a/tools/gyp/pylib/gyp/easy_xml_test.py +++ b/tools/gyp/pylib/gyp/easy_xml_test.py @@ -8,13 +8,17 @@ import gyp.easy_xml as easy_xml import unittest -import StringIO + +try: + from StringIO import StringIO # Python 2 +except ImportError: + from io import StringIO # Python 3 class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def test_EasyXml_simple(self): self.assertEqual( diff --git a/tools/gyp/pylib/gyp/generator/msvs_test.py b/tools/gyp/pylib/gyp/generator/msvs_test.py index c0b021df502bfa..1b0cdd17201d5b 100755 --- a/tools/gyp/pylib/gyp/generator/msvs_test.py +++ b/tools/gyp/pylib/gyp/generator/msvs_test.py @@ -7,13 +7,17 @@ import gyp.generator.msvs as msvs import unittest -import StringIO + +try: + from StringIO import StringIO # Python 2 +except ImportError: + from io import StringIO # Python 3 class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def test_GetLibraries(self): self.assertEqual( diff --git a/tools/gyp/pylib/gyp/generator/ninja_test.py b/tools/gyp/pylib/gyp/generator/ninja_test.py index 1767b2f45a04ca..c8adc251c97d50 100644 --- a/tools/gyp/pylib/gyp/generator/ninja_test.py +++ b/tools/gyp/pylib/gyp/generator/ninja_test.py @@ -6,11 +6,10 @@ """ Unit tests for the ninja.py file. """ -import gyp.generator.ninja as ninja -import unittest -import StringIO import sys -import TestCommon +import unittest + +import gyp.generator.ninja as ninja class TestPrefixesAndSuffixes(unittest.TestCase): diff --git a/tools/gyp/pylib/gyp/mac_tool.py b/tools/gyp/pylib/gyp/mac_tool.py index e1faa5679f90a2..c4c4a6df130404 100755 --- a/tools/gyp/pylib/gyp/mac_tool.py +++ b/tools/gyp/pylib/gyp/mac_tool.py @@ -24,6 +24,8 @@ import sys import tempfile +PY3 = bytes != str + def main(args): executor = MacTool() @@ -263,6 +265,8 @@ def ExecFilterLibtool(self, *cmd_list): env['ZERO_AR_DATE'] = '1' libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env) _, err = libtoolout.communicate() + if PY3: + err = err.decode('utf-8') for line in err.splitlines(): if not libtool_re.match(line) and not libtool_re5.match(line): print(line, file=sys.stderr) diff --git a/tools/gyp/pylib/gyp/xcode_emulation.py b/tools/gyp/pylib/gyp/xcode_emulation.py index 9a58df4782af7e..905bec7be34ba8 100644 --- a/tools/gyp/pylib/gyp/xcode_emulation.py +++ b/tools/gyp/pylib/gyp/xcode_emulation.py @@ -20,6 +20,8 @@ import tempfile from gyp.common import GypError +PY3 = bytes != str + # Populated lazily by XcodeVersion, for efficiency, and to fix an issue when # "xcodebuild" is called too quickly (it has been found to return incorrect # version number). @@ -498,7 +500,7 @@ def _GetSdkVersionInfoItem(self, sdk, infoitem): # most sensible route and should still do the right thing. try: return GetStdoutQuiet(['xcrun', '--sdk', sdk, infoitem]) - except: + except GypError: pass def _SdkRoot(self, configname): @@ -928,7 +930,8 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): # extensions and provide loader and main function. # These flags reflect the compilation options used by xcode to compile # extensions. - if XcodeVersion() < '0900': + xcode_version, _ = XcodeVersion() + if xcode_version < '0900': ldflags.append('-lpkstart') ldflags.append(sdk_root + '/System/Library/PrivateFrameworks/PlugInKit.framework/PlugInKit') @@ -1204,8 +1207,8 @@ def GetExtraPlistItems(self, configname=None): cache = {} cache['BuildMachineOSBuild'] = self._BuildMachineOSBuild() - xcode, xcode_build = XcodeVersion() - cache['DTXcode'] = xcode + xcode_version, xcode_build = XcodeVersion() + cache['DTXcode'] = xcode_version cache['DTXcodeBuild'] = xcode_build compiler = self.xcode_settings[configname].get('GCC_VERSION') if compiler is not None: @@ -1216,10 +1219,10 @@ def GetExtraPlistItems(self, configname=None): sdk_root = self._DefaultSdkRoot() sdk_version = self._GetSdkVersionInfoItem(sdk_root, '--show-sdk-version') cache['DTSDKName'] = sdk_root + (sdk_version or '') - if xcode >= '0720': + if xcode_version >= '0720': cache['DTSDKBuild'] = self._GetSdkVersionInfoItem( sdk_root, '--show-sdk-build-version') - elif xcode >= '0430': + elif xcode_version >= '0430': cache['DTSDKBuild'] = sdk_version else: cache['DTSDKBuild'] = cache['BuildMachineOSBuild'] @@ -1254,7 +1257,7 @@ def _DefaultSdkRoot(self): project, then the environment variable was empty. Starting with this version, Xcode uses the name of the newest SDK installed. """ - xcode_version, xcode_build = XcodeVersion() + xcode_version, _ = XcodeVersion() if xcode_version < '0500': return '' default_sdk_path = self._XcodeSdkPath('') @@ -1263,7 +1266,7 @@ def _DefaultSdkRoot(self): return default_sdk_root try: all_sdks = GetStdout(['xcodebuild', '-showsdks']) - except: + except GypError: # If xcodebuild fails, there will be no valid SDKs return '' for line in all_sdks.splitlines(): @@ -1391,10 +1394,12 @@ def XcodeVersion(): # Xcode 3.2.6 # Component versions: DevToolsCore-1809.0; DevToolsSupport-1806.0 # BuildVersion: 10M2518 - # Convert that to '0463', '4H1503'. + # Convert that to ('0463', '4H1503') or ('0326', '10M2518'). global XCODE_VERSION_CACHE if XCODE_VERSION_CACHE: return XCODE_VERSION_CACHE + version = "" + build = "" try: version_list = GetStdoutQuiet(['xcodebuild', '-version']).splitlines() # In some circumstances xcodebuild exits 0 but doesn't return @@ -1404,21 +1409,16 @@ def XcodeVersion(): # checking that version. if len(version_list) < 2: raise GypError("xcodebuild returned unexpected results") - except: - version = CLTVersion() - if version: - version = re.match(r'(\d+\.\d+\.?\d*)', version).groups()[0] - else: + version = version_list[0].split()[-1] # Last word on first line + build = version_list[-1].split()[-1] # Last word on last line + except GypError: # Xcode not installed so look for XCode Command Line Tools + version = CLTVersion() # macOS Catalina returns 11.0.0.0.1.1567737322 + if not version: raise GypError("No Xcode or CLT version detected!") - # The CLT has no build information, so we return an empty string. - version_list = [version, ''] - version = version_list[0] - build = version_list[-1] - # Be careful to convert "4.2" to "0420": - version = version.split()[-1].replace('.', '') - version = (version + '0' * (3 - len(version))).zfill(4) - if build: - build = build.split()[-1] + # Be careful to convert "4.2.3" to "0423" and "11.0.0" to "1100": + version = version.split(".")[:3] # Just major, minor, micro + version[0] = version[0].zfill(2) # Add a leading zero if major is one digit + version = ("".join(version) + "00")[:4] # Limit to exactly four characters XCODE_VERSION_CACHE = (version, build) return XCODE_VERSION_CACHE @@ -1442,7 +1442,7 @@ def CLTVersion(): try: output = GetStdout(['/usr/sbin/pkgutil', '--pkg-info', key]) return re.search(regex, output).groupdict()['version'] - except: + except GypError: continue @@ -1453,6 +1453,8 @@ def GetStdoutQuiet(cmdlist): job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = job.communicate()[0] + if PY3: + out = out.decode("utf-8") if job.returncode != 0: raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) return out.rstrip('\n') @@ -1463,6 +1465,8 @@ def GetStdout(cmdlist): Raises |GypError| if the command return with a non-zero return code.""" job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) out = job.communicate()[0] + if PY3: + out = out.decode("utf-8") if job.returncode != 0: sys.stderr.write(out + '\n') raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) @@ -1674,7 +1678,8 @@ def _GetXcodeEnv(xcode_settings, built_products_dir, srcroot, configuration, install_name_base = xcode_settings.GetInstallNameBase() if install_name_base: env['DYLIB_INSTALL_NAME_BASE'] = install_name_base - if XcodeVersion() >= '0500' and not env.get('SDKROOT'): + xcode_version, _ = XcodeVersion() + if xcode_version >= '0500' and not env.get('SDKROOT'): sdk_root = xcode_settings._SdkRoot(configuration) if not sdk_root: sdk_root = xcode_settings._XcodeSdkPath('') diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi index 602d6063f36173..aa8ae2874b3142 100644 --- a/tools/v8_gypfiles/features.gypi +++ b/tools/v8_gypfiles/features.gypi @@ -198,10 +198,6 @@ # Variables from v8.gni - # Enable the snapshot feature, for fast context creation. - # http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html - 'v8_use_snapshot%': 1, - # Enable ECMAScript Internationalization API. Enabling this feature will # add a dependency on the ICU library. 'v8_enable_i18n_support%': 1, @@ -287,13 +283,8 @@ # ['v8_enable_handle_zapping==1', { # 'defines': ['ENABLE_HANDLE_ZAPPING',], # }], - ['v8_use_snapshot==1', { - 'defines': ['V8_USE_SNAPSHOT',], - 'conditions': [ - ['v8_enable_snapshot_native_code_counters==1', { - 'defines': ['V8_SNAPSHOT_NATIVE_CODE_COUNTERS',], - }], - ], + ['v8_enable_snapshot_native_code_counters==1', { + 'defines': ['V8_SNAPSHOT_NATIVE_CODE_COUNTERS',], }], ['v8_enable_single_generation==1', { 'defines': ['V8_ENABLE_SINGLE_GENERATION',], diff --git a/tools/v8_gypfiles/v8.gyp b/tools/v8_gypfiles/v8.gyp index 0ecfc7e94518ef..e569fb7d30147e 100644 --- a/tools/v8_gypfiles/v8.gyp +++ b/tools/v8_gypfiles/v8.gyp @@ -59,9 +59,13 @@ "<(V8_ROOT)/src/builtins/proxy-set-prototype-of.tq", "<(V8_ROOT)/src/builtins/proxy.tq", "<(V8_ROOT)/src/builtins/reflect.tq", + "<(V8_ROOT)/src/builtins/regexp-exec.tq", + "<(V8_ROOT)/src/builtins/regexp-match-all.tq", "<(V8_ROOT)/src/builtins/regexp-match.tq", "<(V8_ROOT)/src/builtins/regexp-replace.tq", + "<(V8_ROOT)/src/builtins/regexp-search.tq", "<(V8_ROOT)/src/builtins/regexp-source.tq", + "<(V8_ROOT)/src/builtins/regexp-split.tq", "<(V8_ROOT)/src/builtins/regexp-test.tq", "<(V8_ROOT)/src/builtins/regexp.tq", "<(V8_ROOT)/src/builtins/string.tq", @@ -104,6 +108,13 @@ ], }, 'includes': ['toolchain.gypi', 'features.gypi'], + 'target_defaults': { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'AdditionalOptions': ['/utf-8'] + } + }, + }, 'targets': [ { 'target_name': 'run_torque', @@ -131,6 +142,7 @@ ], 'outputs': [ '<(torque_output_root)/torque-generated/builtin-definitions-tq.h', + '<(torque_output_root)/torque-generated/interface-descriptors-tq.inc', '<(torque_output_root)/torque-generated/field-offsets-tq.h', '<(torque_output_root)/torque-generated/class-verifiers-tq.cc', '<(torque_output_root)/torque-generated/class-verifiers-tq.h', @@ -271,16 +283,7 @@ 'type': 'none', 'toolsets': ['target'], 'hard_dependency': 1, - 'conditions': [ - # The dependency on v8_base should come from a transitive - # dependency however the Android toolchain requires libv8_base.a - # to appear before libv8_snapshot.a so it's listed explicitly. - ['v8_use_snapshot==1', { - 'dependencies': ['v8_base', 'v8_snapshot'], - }, { - 'dependencies': ['v8_base', 'v8_init', 'v8_nosnapshot'], - }], - ] + 'dependencies': ['v8_base', 'v8_snapshot'], }, # v8_maybe_snapshot { 'target_name': 'v8_init', @@ -1488,7 +1491,6 @@ 'v8_enable_i18n_support=<(v8_enable_i18n_support)', 'v8_enable_verify_predictable=<(v8_enable_verify_predictable)', 'v8_target_cpu=<(v8_target_arch)', - 'v8_use_snapshot=<(v8_use_snapshot)', 'v8_use_siphash=<(v8_use_siphash)', 'v8_enable_embedded_builtins=<(v8_enable_embedded_builtins)', 'v8_enable_verify_csa=<(v8_enable_verify_csa)', @@ -1526,9 +1528,66 @@ 'toolsets': ['host', 'target'], }], ], + 'dependencies': ['run_torque'], 'variables': { 'heapobject_files': [ - '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/BUILD.gn" "\\"postmortem-metadata.*?sources = ")', + '<(V8_ROOT)/src/objects/objects.h', + '<(V8_ROOT)/src/objects/objects-inl.h', + '<(V8_ROOT)/src/objects/allocation-site-inl.h', + '<(V8_ROOT)/src/objects/allocation-site.h', + '<(V8_ROOT)/src/objects/cell-inl.h', + '<(V8_ROOT)/src/objects/cell.h', + '<(V8_ROOT)/src/objects/code-inl.h', + '<(V8_ROOT)/src/objects/code.h', + '<(V8_ROOT)/src/objects/data-handler.h', + '<(V8_ROOT)/src/objects/data-handler-inl.h', + '<(V8_ROOT)/src/objects/descriptor-array.h', + '<(V8_ROOT)/src/objects/descriptor-array-inl.h', + '<(V8_ROOT)/src/objects/feedback-cell.h', + '<(V8_ROOT)/src/objects/feedback-cell-inl.h', + '<(V8_ROOT)/src/objects/fixed-array-inl.h', + '<(V8_ROOT)/src/objects/fixed-array.h', + '<(V8_ROOT)/src/objects/heap-number-inl.h', + '<(V8_ROOT)/src/objects/heap-number.h', + '<(V8_ROOT)/src/objects/heap-object-inl.h', + '<(V8_ROOT)/src/objects/heap-object.h', + '<(V8_ROOT)/src/objects/instance-type.h', + '<(V8_ROOT)/src/objects/js-array-inl.h', + '<(V8_ROOT)/src/objects/js-array.h', + '<(V8_ROOT)/src/objects/js-array-buffer-inl.h', + '<(V8_ROOT)/src/objects/js-array-buffer.h', + '<(V8_ROOT)/src/objects/js-objects-inl.h', + '<(V8_ROOT)/src/objects/js-objects.h', + '<(V8_ROOT)/src/objects/js-promise-inl.h', + '<(V8_ROOT)/src/objects/js-promise.h', + '<(V8_ROOT)/src/objects/js-regexp-inl.h', + '<(V8_ROOT)/src/objects/js-regexp.cc', + '<(V8_ROOT)/src/objects/js-regexp.h', + '<(V8_ROOT)/src/objects/js-regexp-string-iterator-inl.h', + '<(V8_ROOT)/src/objects/js-regexp-string-iterator.h', + '<(V8_ROOT)/src/objects/map.h', + '<(V8_ROOT)/src/objects/map.cc', + '<(V8_ROOT)/src/objects/map-inl.h', + '<(V8_ROOT)/src/objects/js-objects.cc', + '<(V8_ROOT)/src/objects/name.h', + '<(V8_ROOT)/src/objects/name-inl.h', + '<(V8_ROOT)/src/objects/oddball-inl.h', + '<(V8_ROOT)/src/objects/oddball.h', + '<(V8_ROOT)/src/objects/primitive-heap-object.h', + '<(V8_ROOT)/src/objects/primitive-heap-object-inl.h', + '<(V8_ROOT)/src/objects/scope-info.h', + '<(V8_ROOT)/src/objects/script.h', + '<(V8_ROOT)/src/objects/script-inl.h', + '<(V8_ROOT)/src/objects/shared-function-info.h', + '<(V8_ROOT)/src/objects/shared-function-info-inl.h', + '<(V8_ROOT)/src/objects/string.cc', + '<(V8_ROOT)/src/objects/string.h', + '<(V8_ROOT)/src/objects/string-comparator.cc', + '<(V8_ROOT)/src/objects/string-comparator.h', + '<(V8_ROOT)/src/objects/string-inl.h', + '<(V8_ROOT)/src/objects/struct.h', + '<(V8_ROOT)/src/objects/struct-inl.h', + '<(torque_output_root)/torque-generated/instance-types-tq.h', ], }, 'actions': [